[libvirt] virDomain::Restore
by Tóth Zoltán
Hi!
I need virDomain::Restore function from python.
dom = conn.listDomainsID()
for id in dom:
domain = conn.lookupByID(id)
print dir(domain)
['ID', 'OSType', 'UUID', 'UUIDString', 'XMLDesc', '__del__', '__doc__',
'__init__', '__module__', '_conn', '_o', 'abortJob', 'attachDevice',
'attachDeviceFlags', 'autostart', 'blkioParameters', 'blockInfo',
'blockPeek', 'blockStats', 'connect', 'coreDump', 'create',
'createWithFlags', 'destroy', 'detachDevice', 'detachDeviceFlags',
'hasCurrentSnapshot', 'hasManagedSaveImage', 'info', 'injectNMI',
'interfaceStats', 'isActive', 'isPersistent', 'isUpdated', 'jobInfo',
'managedSave', 'managedSaveRemove', 'maxMemory', 'maxVcpus',
'memoryParameters', 'memoryPeek', 'memoryStats', 'migrate', 'migrate2',
'migrateSetMaxDowntime', 'migrateSetMaxSpeed', 'migrateToURI',
'migrateToURI2', 'name', 'openConsole', 'pinVcpu', 'reboot', 'resume',
'revertToSnapshot', 'save', 'schedulerParameters',
'schedulerParametersFlags', 'schedulerType', 'screenshot',
'setAutostart', 'setBlkioParameters', 'setMaxMemory', 'setMemory',
'setMemoryFlags', 'setMemoryParameters', 'setSchedulerParameters',
'setSchedulerParametersFlags', 'setVcpus', 'setVcpusFlags', 'shutdown',
'snapshotCreateXML', 'snapshotCurrent', 'snapshotListNames',
'snapshotLookupByName', 'snapshotNum', 'state', 'suspend', 'undefine',
'updateDeviceFlags', 'vcpus', 'vcpusFlags']
Where is restore?
Thx
--
Zoli
12 years, 6 months
[libvirt] [libvirt-glib] Check arguments to public GVirConfigObject methods
by Christophe Fergeau
GVirConfigObject public methods don't have g_return_if_fail checks
on their arguments. It happens that GNOME Boxes tries to call
gvir_config_object_to_xml with a NULL GVirConfigObject causing a
crash https://bugzilla.gnome.org/show_bug.cgi?id=676308
While GNOME Boxes needs to be fixed not to pass an invalid value
to gvir_config_object_to_xml, it's better if libvirt-gconfig sanity
checks the argument it is passed by the caller before using them.
---
libvirt-gconfig/libvirt-gconfig-object.c | 14 +++++++++++---
1 file changed, 11 insertions(+), 3 deletions(-)
diff --git a/libvirt-gconfig/libvirt-gconfig-object.c b/libvirt-gconfig/libvirt-gconfig-object.c
index 8286bcb..1474393 100644
--- a/libvirt-gconfig/libvirt-gconfig-object.c
+++ b/libvirt-gconfig/libvirt-gconfig-object.c
@@ -191,11 +191,16 @@ static void gvir_config_object_init(GVirConfigObject *conn)
void gvir_config_object_validate(GVirConfigObject *config,
GError **err)
{
- GVirConfigObjectPrivate *priv = config->priv;
+ GVirConfigObjectPrivate *priv;
xmlRelaxNGParserCtxtPtr rngParser = NULL;
xmlRelaxNGPtr rng = NULL;
xmlRelaxNGValidCtxtPtr rngValid = NULL;
+ g_return_if_fail(GVIR_CONFIG_IS_OBJECT(config));
+ g_return_if_fail(err == NULL || *err == NULL);
+
+ priv = config->priv;
+
xmlSetGenericErrorFunc(NULL, gvir_xml_generic_error_nop);
xmlSetStructuredErrorFunc(NULL, gvir_xml_structured_error_nop);
@@ -256,13 +261,16 @@ void gvir_config_object_validate(GVirConfigObject *config,
gchar *gvir_config_object_to_xml(GVirConfigObject *config)
{
+ g_return_val_if_fail(GVIR_CONFIG_IS_OBJECT(config), NULL);
+
return gvir_config_xml_node_to_string(config->priv->node);
}
const gchar *gvir_config_object_get_schema(GVirConfigObject *config)
{
- GVirConfigObjectPrivate *priv = config->priv;
- return priv->schema;
+ g_return_val_if_fail(GVIR_CONFIG_IS_OBJECT(config), NULL);
+
+ return config->priv->schema;
}
/* FIXME: will we always have one xmlNode per GConfig object? */
--
1.7.10.1
12 years, 6 months
[libvirt] [libvirt-glib] Debian, symbol versioning & ABI breakage
by Christophe Fergeau
Hey,
http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=673430 has recently been
brought to my attention. The Debian gnome-boxes package was failing to
startup because it had been compiled against an older libvirt-glib version
than the one that was installed on the system.
So far, we have broken the ABI for each libvirt-glib release, and done that
by changing the version of all symbols in libvirt-g*.syms. This works well
on Fedora where rpm adds requires like
libvirt-gobject-1.0.so.0(LIBVIRT_GOBJECT_0.0.8)(64bit) when building the
package, thus preventing using gnome-boxes with an older/newer libvirt-glib
build than the one it was compiled against.
However, debian doesn't seem to take into account symbol versioning at all
in their package dependencies, and rely on the library soname changing to
detect ABI breakage.
In short, the way we've handled ABI breakage so far is unnice to Debian ;)
In my opinion, we should be aiming to make libvirt-glib ABI stable soon, so
this issue shouldn't happen again soon, but I'm mentioning it for future
reference ;)
Christophe
12 years, 6 months
[libvirt] [PATCH V4] nwfilter: Add support for ipset
by Stefan Berger
This patch adds support for the recent ipset iptables extension
to libvirt's nwfilter subsystem. Ipset allows to maintain 'sets'
of IP addresses, ports and other packet parameters and allows for
faster lookup (in the order of O(1) vs. O(n)) and rule evaluation
to achieve higher throughput than what can be achieved with
individual iptables rules.
On the command line iptables supports ipset using
iptables ... -m set --match-set <ipset name> <flags> -j ...
where 'ipset name' is the name of a previously created ipset and
flags is a comma-separated list of up to 6 flags. Flags use 'src' and 'dst'
for selecting IP addresses, ports etc. from the source or
destination part of a packet. So a concrete example may look like this:
iptables -A INPUT -m set --match-set test src,src -j ACCEPT
Since ipset management is quite complex, the idea was to leave ipset
management outside of libvirt but still allow users to reference an ipset.
The user would have to make sure the ipset is available once the VM is
started so that the iptables rule(s) referencing the ipset can be created.
Using XML to describe an ipset in an nwfilter rule would then look as
follows:
<rule action='accept' direction='in'>
<all ipset='test' ipsetflags='src,src'/>
</rule>
The two parameters on the command line are also the two distinct XML
attributes
'ipset' and 'ipsetflags'.
FYI: Here is the man page for ipset:
https://ipset.netfilter.org/ipset.man.html
Regards,
Stefan
---
v4:
- followed Eric's review comments
v3:
- use DATATYPE_IPSETNAME for the name of the ipset
- adapted documentation for 0.9.12
v2:
- split ipset description into ipset and ipsetflags attribute
- improved on documentation
---
docs/formatnwfilter.html.in | 65 ++++++++++++++
docs/schemas/nwfilter.rng | 23 +++++
src/conf/nwfilter_conf.c | 136
+++++++++++++++++++++++++++++-
src/conf/nwfilter_conf.h | 14 ++-
src/nwfilter/nwfilter_ebiptables_driver.c | 79 ++++++++++++++++-
tests/nwfilterxml2xmlin/ipset-test.xml | 24 +++++
tests/nwfilterxml2xmlout/ipset-test.xml | 24 +++++
tests/nwfilterxml2xmltest.c | 2
8 files changed, 362 insertions(+), 5 deletions(-)
Index: libvirt-acl/src/conf/nwfilter_conf.c
===================================================================
--- libvirt-acl.orig/src/conf/nwfilter_conf.c
+++ libvirt-acl/src/conf/nwfilter_conf.c
@@ -183,6 +183,8 @@ static const char dstportstart_str[] = "
static const char dstportend_str[] = "dstportend";
static const char dscp_str[] = "dscp";
static const char state_str[] = "state";
+static const char ipset_str[] = "ipset";
+static const char ipsetflags_str[] = "ipsetflags";
#define SRCMACADDR srcmacaddr_str
#define SRCMACMASK srcmacmask_str
@@ -206,6 +208,8 @@ static const char state_str[] = "
#define DSTPORTEND dstportend_str
#define DSCP dscp_str
#define STATE state_str
+#define IPSET ipset_str
+#define IPSETFLAGS ipsetflags_str
/**
@@ -980,6 +984,97 @@ tcpFlagsFormatter(virBufferPtr buf,
return true;
}
+static bool
+ipsetValidator(enum attrDatatype datatype ATTRIBUTE_UNUSED, union data
*val,
+ virNWFilterRuleDefPtr nwf ATTRIBUTE_UNUSED,
+ nwItemDesc *item)
+{
+ const char *errmsg = NULL;
+
+ if (virStrcpy(item->u.ipset.setname, val->c,
+ sizeof(item->u.ipset.setname)) == NULL) {
+ errmsg = _("ipset name is too long");
+ goto arg_err_exit;
+ }
+
+ if (item->u.ipset.setname[strspn(item->u.ipset.setname,
+ VALID_IPSETNAME)] != 0) {
+ errmsg = _("ipset name contains invalid characters");
+ goto arg_err_exit;
+ }
+
+ return true;
+
+arg_err_exit:
+ virNWFilterReportError(VIR_ERR_INVALID_ARG,
+ "%s", errmsg);
+ return false;
+}
+
+static bool
+ipsetFormatter(virBufferPtr buf,
+ virNWFilterRuleDefPtr nwf ATTRIBUTE_UNUSED,
+ nwItemDesc *item)
+{
+ virBufferAdd(buf, item->u.ipset.setname, -1);
+
+ return true;
+}
+
+static bool
+ipsetFlagsValidator(enum attrDatatype datatype ATTRIBUTE_UNUSED, union
data *val,
+ virNWFilterRuleDefPtr nwf ATTRIBUTE_UNUSED,
nwItemDesc *item)
+{
+ const char *errmsg = NULL;
+ size_t idx = 0;
+
+ item->u.ipset.numFlags = 0;
+ item->u.ipset.flags = 0;
+
+ errmsg = _("malformed ipset flags");
+
+ while (item->u.ipset.numFlags < 6) {
+ if (STRCASEEQLEN(&val->c[idx], "src", 3)) {
+ item->u.ipset.flags |= (1 << item->u.ipset.numFlags);
+ } else if (!STRCASEEQLEN(&val->c[idx], "dst", 3)) {
+ goto arg_err_exit;
+ }
+ item->u.ipset.numFlags++;
+ idx += 3;
+ if (val->c[idx] != ',')
+ break;
+ idx++;
+ }
+
+ if (val->c[idx] != '\0')
+ goto arg_err_exit;
+
+ return true;
+
+arg_err_exit:
+ virNWFilterReportError(VIR_ERR_INVALID_ARG,
+ "%s", errmsg);
+ return false;
+}
+
+static bool
+ipsetFlagsFormatter(virBufferPtr buf,
+ virNWFilterRuleDefPtr nwf ATTRIBUTE_UNUSED,
+ nwItemDesc *item)
+{
+ uint8_t ctr;
+
+ for (ctr = 0; ctr < item->u.ipset.numFlags; ctr++) {
+ if (ctr != 0)
+ virBufferAddLit(buf, ",");
+ if ((item->u.ipset.flags & (1 << ctr)))
+ virBufferAddLit(buf, "src");
+ else
+ virBufferAddLit(buf, "dst");
+ }
+
+ return true;
+}
#define COMMON_MAC_PROPS(STRUCT) \
{\
@@ -1411,6 +1506,20 @@ static const virXMLAttr2Struct ipv6Attri
.dataIdx = offsetof(virNWFilterRuleDef,
p.STRUCT.ipHdr.dataState),\
.validator = stateValidator,\
.formatter = stateFormatter,\
+ },\
+ {\
+ .name = IPSET,\
+ .datatype = DATATYPE_IPSETNAME,\
+ .dataIdx = offsetof(virNWFilterRuleDef, p.STRUCT.ipHdr.dataIPSet),\
+ .validator = ipsetValidator,\
+ .formatter = ipsetFormatter,\
+ },\
+ {\
+ .name = IPSETFLAGS,\
+ .datatype = DATATYPE_IPSETFLAGS,\
+ .dataIdx = offsetof(virNWFilterRuleDef,
p.STRUCT.ipHdr.dataIPSetFlags),\
+ .validator = ipsetFlagsValidator,\
+ .formatter = ipsetFlagsFormatter,\
}
#define COMMON_PORT_PROPS(STRUCT) \
@@ -1853,6 +1962,8 @@ virNWFilterRuleDetailsParse(xmlNodePtr n
break;
case DATATYPE_STRING:
+ case DATATYPE_IPSETFLAGS:
+ case DATATYPE_IPSETNAME:
if (!validator) {
/* not supported */
rc = -1;
@@ -1964,6 +2075,19 @@ err_exit:
goto cleanup;
}
+static void
+virNWFilterRuleDefFixupIPSet(ipHdrDataDefPtr ipHdr)
+{
+ if (HAS_ENTRY_ITEM(&ipHdr->dataIPSet) &&
+ !HAS_ENTRY_ITEM(&ipHdr->dataIPSetFlags)) {
+ ipHdr->dataIPSetFlags.flags = NWFILTER_ENTRY_ITEM_FLAG_EXISTS;
+ ipHdr->dataIPSetFlags.u.ipset.numFlags = 1;
+ ipHdr->dataIPSetFlags.u.ipset.flags = 1;
+ } else {
+ ipHdr->dataIPSet.flags = 0;
+ ipHdr->dataIPSetFlags.flags = 0;
+ }
+}
static void
virNWFilterRuleDefFixup(virNWFilterRuleDefPtr rule)
@@ -2017,6 +2141,7 @@ virNWFilterRuleDefFixup(virNWFilterRuleD
rule->p.ipHdrFilter.ipHdr.dataSrcIPAddr);
COPY_NEG_SIGN(rule->p.ipHdrFilter.ipHdr.dataDstIPMask,
rule->p.ipHdrFilter.ipHdr.dataDstIPAddr);
+ virNWFilterRuleDefFixupIPSet(&rule->p.ipHdrFilter.ipHdr);
break;
case VIR_NWFILTER_RULE_PROTOCOL_IPV6:
@@ -2024,6 +2149,7 @@ virNWFilterRuleDefFixup(virNWFilterRuleD
rule->p.ipv6HdrFilter.ipHdr.dataSrcIPAddr);
COPY_NEG_SIGN(rule->p.ipv6HdrFilter.ipHdr.dataDstIPMask,
rule->p.ipv6HdrFilter.ipHdr.dataDstIPAddr);
+ virNWFilterRuleDefFixupIPSet(&rule->p.ipv6HdrFilter.ipHdr);
break;
case VIR_NWFILTER_RULE_PROTOCOL_ARP:
@@ -2047,6 +2173,7 @@ virNWFilterRuleDefFixup(virNWFilterRuleD
rule->p.tcpHdrFilter.portData.dataSrcPortStart);
COPY_NEG_SIGN(rule->p.tcpHdrFilter.portData.dataDstPortEnd,
rule->p.tcpHdrFilter.portData.dataSrcPortStart);
+ virNWFilterRuleDefFixupIPSet(&rule->p.tcpHdrFilter.ipHdr);
break;
case VIR_NWFILTER_RULE_PROTOCOL_UDP:
@@ -2065,6 +2192,7 @@ virNWFilterRuleDefFixup(virNWFilterRuleD
rule->p.udpHdrFilter.portData.dataSrcPortStart);
COPY_NEG_SIGN(rule->p.udpHdrFilter.portData.dataDstPortEnd,
rule->p.udpHdrFilter.portData.dataSrcPortStart);
+ virNWFilterRuleDefFixupIPSet(&rule->p.udpHdrFilter.ipHdr);
break;
case VIR_NWFILTER_RULE_PROTOCOL_UDPLITE:
@@ -2077,6 +2205,7 @@ virNWFilterRuleDefFixup(virNWFilterRuleD
rule->p.udpliteHdrFilter.ipHdr.dataSrcIPFrom);
COPY_NEG_SIGN(rule->p.udpliteHdrFilter.ipHdr.dataDstIPTo,
rule->p.udpliteHdrFilter.ipHdr.dataDstIPFrom);
+ virNWFilterRuleDefFixupIPSet(&rule->p.udpliteHdrFilter.ipHdr);
break;
case VIR_NWFILTER_RULE_PROTOCOL_ESP:
@@ -2089,6 +2218,7 @@ virNWFilterRuleDefFixup(virNWFilterRuleD
rule->p.espHdrFilter.ipHdr.dataSrcIPFrom);
COPY_NEG_SIGN(rule->p.espHdrFilter.ipHdr.dataDstIPTo,
rule->p.espHdrFilter.ipHdr.dataDstIPFrom);
+ virNWFilterRuleDefFixupIPSet(&rule->p.espHdrFilter.ipHdr);
break;
case VIR_NWFILTER_RULE_PROTOCOL_AH:
@@ -2101,6 +2231,7 @@ virNWFilterRuleDefFixup(virNWFilterRuleD
rule->p.ahHdrFilter.ipHdr.dataSrcIPFrom);
COPY_NEG_SIGN(rule->p.ahHdrFilter.ipHdr.dataDstIPTo,
rule->p.ahHdrFilter.ipHdr.dataDstIPFrom);
+ virNWFilterRuleDefFixupIPSet(&rule->p.ahHdrFilter.ipHdr);
break;
case VIR_NWFILTER_RULE_PROTOCOL_SCTP:
@@ -2119,6 +2250,7 @@ virNWFilterRuleDefFixup(virNWFilterRuleD
rule->p.sctpHdrFilter.portData.dataSrcPortStart);
COPY_NEG_SIGN(rule->p.sctpHdrFilter.portData.dataDstPortEnd,
rule->p.sctpHdrFilter.portData.dataSrcPortStart);
+ virNWFilterRuleDefFixupIPSet(&rule->p.sctpHdrFilter.ipHdr);
break;
case VIR_NWFILTER_RULE_PROTOCOL_ICMP:
@@ -2133,6 +2265,7 @@ virNWFilterRuleDefFixup(virNWFilterRuleD
rule->p.icmpHdrFilter.ipHdr.dataDstIPFrom);
COPY_NEG_SIGN(rule->p.icmpHdrFilter.dataICMPCode,
rule->p.icmpHdrFilter.dataICMPType);
+ virNWFilterRuleDefFixupIPSet(&rule->p.icmpHdrFilter.ipHdr);
break;
case VIR_NWFILTER_RULE_PROTOCOL_ALL:
@@ -2156,6 +2289,7 @@ virNWFilterRuleDefFixup(virNWFilterRuleD
rule->p.igmpHdrFilter.ipHdr.dataSrcIPFrom);
COPY_NEG_SIGN(rule->p.igmpHdrFilter.ipHdr.dataDstIPTo,
rule->p.igmpHdrFilter.ipHdr.dataDstIPFrom);
+ virNWFilterRuleDefFixupIPSet(&rule->p.igmpHdrFilter.ipHdr);
break;
case VIR_NWFILTER_RULE_PROTOCOL_LAST:
@@ -3120,7 +3254,7 @@ virNWFilterRuleDefDetailsFormat(virBuffe
virBufferAsprintf(buf, " %s='",
att[i].name);
- if (att[i].formatter) {
+ if (att[i].formatter && !(flags &
NWFILTER_ENTRY_ITEM_FLAG_HAS_VAR)) {
if (!att[i].formatter(buf, def, item)) {
virNWFilterReportError(VIR_ERR_INTERNAL_ERROR,
_("formatter for %s %s
reported error"),
Index: libvirt-acl/src/conf/nwfilter_conf.h
===================================================================
--- libvirt-acl.orig/src/conf/nwfilter_conf.h
+++ libvirt-acl/src/conf/nwfilter_conf.h
@@ -79,6 +79,7 @@ enum virNWFilterEntryItemFlags {
# define MAX_COMMENT_LENGTH 256
+# define MAX_IPSET_NAME_LENGTH 32 /* incl. terminating '\0' */
# define HAS_ENTRY_ITEM(data) \
(((data)->flags) & NWFILTER_ENTRY_ITEM_FLAG_EXISTS)
@@ -103,8 +104,10 @@ enum attrDatatype {
DATATYPE_BOOLEAN = (1 << 12),
DATATYPE_UINT32 = (1 << 13),
DATATYPE_UINT32_HEX = (1 << 14),
+ DATATYPE_IPSETNAME = (1 << 15),
+ DATATYPE_IPSETFLAGS = (1 << 16),
- DATATYPE_LAST = (1 << 15),
+ DATATYPE_LAST = (1 << 17),
};
# define NWFILTER_MAC_BGA "01:80:c2:00:00:00"
@@ -136,9 +139,16 @@ struct _nwItemDesc {
uint8_t mask;
uint8_t flags;
} tcpFlags;
+ struct {
+ char setname[MAX_IPSET_NAME_LENGTH];
+ uint8_t numFlags;
+ uint8_t flags;
+ } ipset;
} u;
};
+# define VALID_IPSETNAME \
+ "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_.:-+ "
typedef struct _ethHdrDataDef ethHdrDataDef;
typedef ethHdrDataDef *ethHdrDataDefPtr;
@@ -232,6 +242,8 @@ struct _ipHdrDataDef {
nwItemDesc dataState;
nwItemDesc dataConnlimitAbove;
nwItemDesc dataComment;
+ nwItemDesc dataIPSet;
+ nwItemDesc dataIPSetFlags;
};
Index: libvirt-acl/src/nwfilter/nwfilter_ebiptables_driver.c
===================================================================
--- libvirt-acl.orig/src/nwfilter/nwfilter_ebiptables_driver.c
+++ libvirt-acl/src/nwfilter/nwfilter_ebiptables_driver.c
@@ -256,10 +256,13 @@ static int
_printDataType(virNWFilterVarCombIterPtr vars,
char *buf, int bufsize,
nwItemDescPtr item,
- bool asHex)
+ bool asHex, bool directionIn)
{
int done;
char *data;
+ uint8_t ctr;
+ virBuffer vb = VIR_BUFFER_INITIALIZER;
+ char *flags;
if (printVar(vars, buf, bufsize, item, &done) < 0)
return -1;
@@ -346,6 +349,48 @@ _printDataType(virNWFilterVarCombIterPtr
}
break;
+ case DATATYPE_IPSETNAME:
+ if (virStrcpy(buf, item->u.ipset.setname, bufsize) == NULL) {
+ virNWFilterReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+ _("Buffer to small for ipset name"));
+ return -1;
+ }
+ break;
+
+ case DATATYPE_IPSETFLAGS:
+ for (ctr = 0; ctr < item->u.ipset.numFlags; ctr++) {
+ if (ctr != 0)
+ virBufferAddLit(&vb, ",");
+ if ((item->u.ipset.flags & (1 << ctr))) {
+ if (directionIn)
+ virBufferAddLit(&vb, "dst");
+ else
+ virBufferAddLit(&vb, "src");
+ } else {
+ if (directionIn)
+ virBufferAddLit(&vb, "src");
+ else
+ virBufferAddLit(&vb, "dst");
+ }
+ }
+
+ if (virBufferError(&vb)) {
+ virReportOOMError();
+ virBufferFreeAndReset(&vb);
+ return -1;
+ }
+
+ flags = virBufferContentAndReset(&vb);
+
+ if (snprintf(buf, bufsize, "%s", flags) >= bufsize) {
+ virNWFilterReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+ _("Buffer too small for IPSETFLAGS
type"));
+ VIR_FREE(flags);
+ return -1;
+ }
+ VIR_FREE(flags);
+ break;
+
default:
virNWFilterReportError(VIR_ERR_INTERNAL_ERROR,
_("Unhandled datatype %x"),
item->datatype);
@@ -362,16 +407,23 @@ printDataType(virNWFilterVarCombIterPtr
char *buf, int bufsize,
nwItemDescPtr item)
{
- return _printDataType(vars, buf, bufsize, item, 0);
+ return _printDataType(vars, buf, bufsize, item, 0, 0);
}
+static int
+printDataTypeDirection(virNWFilterVarCombIterPtr vars,
+ char *buf, int bufsize,
+ nwItemDescPtr item, bool directionIn)
+{
+ return _printDataType(vars, buf, bufsize, item, 0, directionIn);
+}
static int
printDataTypeAsHex(virNWFilterVarCombIterPtr vars,
char *buf, int bufsize,
nwItemDescPtr item)
{
- return _printDataType(vars, buf, bufsize, item, 1);
+ return _printDataType(vars, buf, bufsize, item, 1, 0);
}
@@ -927,6 +979,7 @@ iptablesHandleIpHdr(virBufferPtr buf,
char ipaddr[INET6_ADDRSTRLEN],
number[MAX(INT_BUFSIZE_BOUND(uint32_t),
INT_BUFSIZE_BOUND(int))];
+ char str[MAX_IPSET_NAME_LENGTH];
const char *src = "--source";
const char *dst = "--destination";
const char *srcrange = "--src-range";
@@ -938,6 +991,26 @@ iptablesHandleIpHdr(virBufferPtr buf,
dstrange = "--src-range";
}
+ if (HAS_ENTRY_ITEM(&ipHdr->dataIPSet) &&
+ HAS_ENTRY_ITEM(&ipHdr->dataIPSetFlags)) {
+
+ if (printDataType(vars,
+ str, sizeof(str),
+ &ipHdr->dataIPSet) < 0)
+ goto err_exit;
+
+ virBufferAsprintf(afterStateMatch,
+ " -m set --match-set \"%s\" ",
+ str);
+
+ if (printDataTypeDirection(vars,
+ str, sizeof(str),
+ &ipHdr->dataIPSetFlags, directionIn) < 0)
+ goto err_exit;
+
+ virBufferAdd(afterStateMatch, str, -1);
+ }
+
if (HAS_ENTRY_ITEM(&ipHdr->dataSrcIPAddr)) {
if (printDataType(vars,
Index: libvirt-acl/docs/schemas/nwfilter.rng
===================================================================
--- libvirt-acl.orig/docs/schemas/nwfilter.rng
+++ libvirt-acl/docs/schemas/nwfilter.rng
@@ -485,6 +485,14 @@
<ref name="stateflags-type"/>
</attribute>
</optional>
+ <optional>
+ <attribute name="ipset">
+ <ref name="ipset-name-type"/>
+ </attribute>
+ <attribute name="ipsetflags">
+ <ref name="ipset-flags-type"/>
+ </attribute>
+ </optional>
</interleave>
</define>
@@ -1060,4 +1068,19 @@
<param
name="pattern">((SYN|ACK|URG|PSH|FIN|RST)(,(SYN|ACK|URG|PSH|FIN|RST))*|ALL|NONE)/((SYN|ACK|URG|PSH|FIN|RST)(,(SYN|ACK|URG|PSH|FIN|RST))*|ALL|NONE)</param>
</data>
</define>
+
+ <define name='ipset-name-type'>
+ <choice>
+ <ref name="variable-name-type"/>
+ <data type="string">
+ <param name="pattern">[a-zA-Z0-9_\.:\-\+ ]{1,31}</param>
+ </data>
+ </choice>
+ </define>
+
+ <define name='ipset-flags-type'>
+ <data type="string">
+ <param name="pattern">(src|dst)(,(src|dst)){0,5}</param>
+ </data>
+ </define>
</grammar>
Index: libvirt-acl/tests/nwfilterxml2xmlin/ipset-test.xml
===================================================================
--- /dev/null
+++ libvirt-acl/tests/nwfilterxml2xmlin/ipset-test.xml
@@ -0,0 +1,24 @@
+<filter name='testcase' chain='root'>
+ <uuid>5c6d49af-b071-6127-b4ec-6f8ed4b55335</uuid>
+ <rule action='accept' direction='out'>
+ <all ipset='test' ipsetflags='src,dst' />
+ </rule>
+ <rule action='accept' direction='in'>
+ <all state='NONE' ipset='test' ipsetflags='src,dst' comment='in+NONE'/>
+ </rule>
+ <rule action='accept' direction='out'>
+ <all state='NONE' ipset='test' ipsetflags='src,dst' comment='out+NONE'/>
+ </rule>
+ <rule action='accept' direction='in'>
+ <all ipset='test' ipsetflags='SRC,DST,SRC' />
+ </rule>
+ <rule action='accept' direction='in'>
+ <all ipset='test:_.-+' ipsetflags='SRC,dSt,SRC' />
+ </rule>
+ <rule action='accept' direction='in'>
+ <all ipset='$IPSETNAME' ipsetflags='src,dst' />
+ </rule>
+ <rule action='accept' direction='inout'>
+ <all ipset='$IPSETNAME' ipsetflags='src,dst' comment='inout'/>
+ </rule>
+</filter>
Index: libvirt-acl/tests/nwfilterxml2xmlout/ipset-test.xml
===================================================================
--- /dev/null
+++ libvirt-acl/tests/nwfilterxml2xmlout/ipset-test.xml
@@ -0,0 +1,24 @@
+<filter name='testcase' chain='root'>
+ <uuid>5c6d49af-b071-6127-b4ec-6f8ed4b55335</uuid>
+ <rule action='accept' direction='out' priority='500'>
+ <all ipset='test' ipsetflags='src,dst'/>
+ </rule>
+ <rule action='accept' direction='in' priority='500'>
+ <all state='NONE' ipset='test' ipsetflags='src,dst' comment='in+NONE'/>
+ </rule>
+ <rule action='accept' direction='out' priority='500'>
+ <all state='NONE' ipset='test' ipsetflags='src,dst' comment='out+NONE'/>
+ </rule>
+ <rule action='accept' direction='in' priority='500'>
+ <all ipset='test' ipsetflags='src,dst,src'/>
+ </rule>
+ <rule action='accept' direction='in' priority='500'>
+ <all ipset='test:_.-+' ipsetflags='src,dst,src'/>
+ </rule>
+ <rule action='accept' direction='in' priority='500'>
+ <all ipset='$IPSETNAME' ipsetflags='src,dst'/>
+ </rule>
+ <rule action='accept' direction='inout' priority='500'>
+ <all ipset='$IPSETNAME' ipsetflags='src,dst' comment='inout'/>
+ </rule>
+</filter>
Index: libvirt-acl/tests/nwfilterxml2xmltest.c
===================================================================
--- libvirt-acl.orig/tests/nwfilterxml2xmltest.c
+++ libvirt-acl/tests/nwfilterxml2xmltest.c
@@ -157,6 +157,8 @@ mymain(void)
DO_TEST("iter-test2", false);
DO_TEST("iter-test3", false);
+ DO_TEST("ipset-test", false);
+
return ret==0 ? EXIT_SUCCESS : EXIT_FAILURE;
}
Index: libvirt-acl/docs/formatnwfilter.html.in
===================================================================
--- libvirt-acl.orig/docs/formatnwfilter.html.in
+++ libvirt-acl/docs/formatnwfilter.html.in
@@ -528,6 +528,11 @@
<li>IPV6_MASK: IPv6 mask in numbers format (FFFF:FFFF:FC00::) or CIDR
mask (0-128)</li>
<li>STRING: A string</li>
<li>BOOLEAN: 'true', 'yes', '1' or 'false', 'no', '0'</li>
+ <li>IPSETFLAGS: The source and destination flags of the ipset described
+ by up to 6 'src' or 'dst' elements selecting features from either
+ the source or destination part of the packet header; example:
+ src,src,dst. The number of 'selectors' to provide here depends
+ on the type of ipset that is referenced.</li>
</ul>
<p>
<br/><br/>
@@ -1169,6 +1174,16 @@
<td>STRING</td>
<td>TCP-only: format of mask/flags with mask and flags each being a
comma separated list of SYN,ACK,URG,PSH,FIN,RST or NONE or ALL</td>
</tr>
+ <tr>
+ <td>ipset <span class="since">(Since 0.9.13)</span></td>
+ <td>STRING</td>
+ <td>The name of an IPSet managed outside of libvirt</td>
+ </tr>
+ <tr>
+ <td>ipsetflags <span class="since">(Since 0.9.13)</span></td>
+ <td>IPSETFLAGS</td>
+ <td>flags for the IPSet; requires ipset attribute</td>
+ </tr>
</table>
<p>
<br/><br/>
@@ -1269,6 +1284,16 @@
<td>STRING</td>
<td>comma separated list of NEW,ESTABLISHED,RELATED,INVALID or NONE</td>
</tr>
+ <tr>
+ <td>ipset <span class="since">(Since 0.9.13)</span></td>
+ <td>STRING</td>
+ <td>The name of an IPSet managed outside of libvirt</td>
+ </tr>
+ <tr>
+ <td>ipsetflags <span class="since">(Since 0.9.13)</span></td>
+ <td>IPSETFLAGS</td>
+ <td>flags for the IPSet; requires ipset attribute</td>
+ </tr>
</table>
<p>
<br/><br/>
@@ -1358,6 +1383,16 @@
<td>STRING</td>
<td>comma separated list of NEW,ESTABLISHED,RELATED,INVALID or NONE</td>
</tr>
+ <tr>
+ <td>ipset <span class="since">(Since 0.9.13)</span></td>
+ <td>STRING</td>
+ <td>The name of an IPSet managed outside of libvirt</td>
+ </tr>
+ <tr>
+ <td>ipsetflags <span class="since">(Since 0.9.13)</span></td>
+ <td>IPSETFLAGS</td>
+ <td>flags for the IPSet; requires ipset attribute</td>
+ </tr>
</table>
<p>
<br/><br/>
@@ -1459,6 +1494,16 @@
<td>STRING</td>
<td>TCP-only: format of mask/flags with mask and flags each being a
comma separated list of SYN,ACK,URG,PSH,FIN,RST or NONE or ALL</td>
</tr>
+ <tr>
+ <td>ipset <span class="since">(Since 0.9.13)</span></td>
+ <td>STRING</td>
+ <td>The name of an IPSet managed outside of libvirt</td>
+ </tr>
+ <tr>
+ <td>ipsetflags <span class="since">(Since 0.9.13)</span></td>
+ <td>IPSETFLAGS</td>
+ <td>flags for the IPSet; requires ipset attribute</td>
+ </tr>
</table>
<p>
<br/><br/>
@@ -1545,6 +1590,16 @@
<td>STRING</td>
<td>comma separated list of NEW,ESTABLISHED,RELATED,INVALID or NONE</td>
</tr>
+ <tr>
+ <td>ipset <span class="since">(Since 0.9.13)</span></td>
+ <td>STRING</td>
+ <td>The name of an IPSet managed outside of libvirt</td>
+ </tr>
+ <tr>
+ <td>ipsetflags <span class="since">(Since 0.9.13)</span></td>
+ <td>IPSETFLAGS</td>
+ <td>flags for the IPSet; requires ipset attribute</td>
+ </tr>
</table>
<p>
<br/><br/>
@@ -1619,6 +1674,16 @@
<td>STRING</td>
<td>comma separated list of NEW,ESTABLISHED,RELATED,INVALID or NONE</td>
</tr>
+ <tr>
+ <td>ipset <span class="since">(Since 0.9.13)</span></td>
+ <td>STRING</td>
+ <td>The name of an IPSet managed outside of libvirt</td>
+ </tr>
+ <tr>
+ <td>ipsetflags <span class="since">(Since 0.9.13)</span></td>
+ <td>IPSETFLAGS</td>
+ <td>flags for the IPSet; requires ipset attribute</td>
+ </tr>
</table>
<p>
<br/><br/>
12 years, 6 months
[libvirt] [PATCHv2 0/4] Filesystem limits for containers
by Guido Günther
Hi,
the following patches are a second stab at filesystem limits for
containers. With these patches space limits in openvz containers are
printed in the domain config as:
<filesystem type='template' accessmode='passthrough'>
<source name='debian'/>
<target dir='/'/>
<space_hard_limit unit="MiB">1153024</space_hard_limit>
<space_soft_limit unit="MiB">1048576</space_soft_limit>
</filesystem>
The can also be set from the domain xml. I left out inode limits for now
since the unit "Bytes" wouldn't fit there well and I didnt' get around
to update the unit parsing code yet. Changes since last time:
* Leave out inode handling for now
* Prefix space limits with space_ - I picked that instead of size since
"df" talks about space as well and OpenVZ terms the variable
diskspace
* Document details about hard and soft limits.
* Update schema
* Also set quota when reading domain xml
This isn't meant for 0.9.12.
Guido Günther (4):
Introduce filesystem limits to virDomainFSDef
openvz: support file system quota reporting
openvz: add quota argument when creating container
Use virParseScaledValue in virDomainParseMemory
docs/formatdomain.html.in | 12 +++
docs/schemas/domaincommon.rng | 12 +++
src/conf/domain_conf.c | 125 ++++++++++++++++-------
src/conf/domain_conf.h | 2 +
src/openvz/openvz_conf.c | 16 +++
src/openvz/openvz_driver.c | 54 +++++++++-
tests/domainschemadata/domain-openvz-simple.xml | 2 +
7 files changed, 186 insertions(+), 37 deletions(-)
--
1.7.10
12 years, 6 months
[libvirt] [PATCH libvirt 1/8] qemu: test CAPS_HDA_MICRO
by Marc-André Lureau
---
src/qemu/qemu_capabilities.c | 5 +++++
src/qemu/qemu_capabilities.h | 1 +
tests/qemuhelptest.c | 3 ++-
3 files changed, 8 insertions(+), 1 deletion(-)
diff --git a/src/qemu/qemu_capabilities.c b/src/qemu/qemu_capabilities.c
index a3c87d1..b410648 100644
--- a/src/qemu/qemu_capabilities.c
+++ b/src/qemu/qemu_capabilities.c
@@ -162,6 +162,9 @@ VIR_ENUM_IMPL(qemuCaps, QEMU_CAPS_LAST,
"scsi-cd",
"ide-cd",
"no-user-config",
+
+ "hda-micro", /* 95 */
+
);
struct qemu_feature_flags {
@@ -1397,6 +1400,8 @@ qemuCapsParseDeviceStr(const char *str, virBitmapPtr flags)
/* Which devices exist. */
if (strstr(str, "name \"hda-duplex\""))
qemuCapsSet(flags, QEMU_CAPS_HDA_DUPLEX);
+ if (strstr(str, "name \"hda-micro\""))
+ qemuCapsSet(flags, QEMU_CAPS_HDA_MICRO);
if (strstr(str, "name \"ccid-card-emulated\""))
qemuCapsSet(flags, QEMU_CAPS_CCID_EMULATED);
if (strstr(str, "name \"ccid-card-passthru\""))
diff --git a/src/qemu/qemu_capabilities.h b/src/qemu/qemu_capabilities.h
index 0e0899e..64831e2 100644
--- a/src/qemu/qemu_capabilities.h
+++ b/src/qemu/qemu_capabilities.h
@@ -130,6 +130,7 @@ enum qemuCapsFlags {
QEMU_CAPS_SCSI_CD = 92, /* -device scsi-cd */
QEMU_CAPS_IDE_CD = 93, /* -device ide-cd */
QEMU_CAPS_NO_USER_CONFIG = 94, /* -no-user-config */
+ QEMU_CAPS_HDA_MICRO = 95, /* -device hda-micro */
QEMU_CAPS_LAST, /* this must always be the last item */
};
diff --git a/tests/qemuhelptest.c b/tests/qemuhelptest.c
index 57d1859..46cc973 100644
--- a/tests/qemuhelptest.c
+++ b/tests/qemuhelptest.c
@@ -752,7 +752,8 @@ mymain(void)
QEMU_CAPS_SCSI_BLOCK,
QEMU_CAPS_SCSI_CD,
QEMU_CAPS_IDE_CD,
- QEMU_CAPS_NO_USER_CONFIG);
+ QEMU_CAPS_NO_USER_CONFIG,
+ QEMU_CAPS_HDA_MICRO);
return ret == 0 ? EXIT_SUCCESS : EXIT_FAILURE;
}
--
1.7.10.1
12 years, 6 months
[libvirt] [PATCH] build: fix virnetlink on glibc 2.11
by Eric Blake
We were being lazy - virnetlink.c was getting uint32_t as a
side-effect from glibc 2.14's <unistd.h>, but older glibc 2.11
does not provide uint32_t from <unistd.h>. In fact, POSIX states
that <unistd.h> need only provide intptr_t, not all of <stdint.h>,
so the bug really is ours. Reported by Jonathan Alescio.
* src/util/virnetlink.h: Include <stdint.h>.
---
Pushing under the build-breaker rule.
src/util/virnetlink.h | 2 ++
1 files changed, 2 insertions(+), 0 deletions(-)
diff --git a/src/util/virnetlink.h b/src/util/virnetlink.h
index bafe8ca..8ec27c9 100644
--- a/src/util/virnetlink.h
+++ b/src/util/virnetlink.h
@@ -23,6 +23,8 @@
# include "config.h"
# include "internal.h"
+# include <stdint.h>
+
# if defined(__linux__) && defined(HAVE_LIBNL)
# include <netlink/msg.h>
--
1.7.7.6
12 years, 6 months
[libvirt] [PATCHv5 0/2] support vcpu_time in qemu
by Eric Blake
This is my enhancements to Hu's series. If it still works for
his testing, then I'm ready to push it.
I also think we should port virDomainGetCPUStats to LXC; at least the
overall statistics are available since LXC sets up a cgroup, although
I'm not quite as sure whether vcpu statistics are possible.
Hu Tao (2):
Add a new param 'vcpu_time' to virDomainGetCPUStats
Adds support to param 'vcpu_time' in qemu_driver.
include/libvirt/libvirt.h.in | 10 +++-
src/qemu/qemu_driver.c | 123 ++++++++++++++++++++++++++++++++++++++---
src/util/cgroup.c | 4 +-
tools/virsh.c | 14 +++--
4 files changed, 134 insertions(+), 17 deletions(-)
--
1.7.7.6
12 years, 6 months
[libvirt] How to use a Virtio-serial port
by Pankaj Rawat
Hi all,
I want to use virtio-serial
For this I changes my guest xml
<channel type='pty'>
<target type='virtio' name='arbitrary.virtio.serial.port.name'/>
</channel>
This create a virtio port in guest as follow
# ls -l /dev/virtio-ports/
lrwxrwxrwx. 1 root root 11 May 15 02:59 arbitrary.virtio.serial.port.name -> ../vport0p1
Now I want to use this port
What type of application use this port for communication and how can I use it ?
Regards
Pankaj Rawat
DISCLAIMER:
-----------------------------------------------------------------------------------------------------------------------
The contents of this e-mail and any attachment(s) are confidential and
intended
for the named recipient(s) only.
It shall not attach any liability on the originator or NECHCL or its
affiliates. Any views or opinions presented in
this email are solely those of the author and may not necessarily reflect the
opinions of NECHCL or its affiliates.
Any form of reproduction, dissemination, copying, disclosure, modification,
distribution and / or publication of
this message without the prior written consent of the author of this e-mail is
strictly prohibited. If you have
received this email in error please delete it and notify the sender
immediately. .
-----------------------------------------------------------------------------------------------------------------------
12 years, 6 months
[libvirt] Report of tsan first testing with libvirt(d)
by Daniel Veillard
Tsan is a heavilly reworked version of helgrind the
data race detector based on Valgrind (at least for linux)
It is developped by Google and described/available there:
http://code.google.com/p/data-race-test/wiki/ThreadSanitizer
as libvirt code is highly threaded I though that we should try
testing it. Helgrind used to not be very practicable but Google
suggest they significantly speed up the process and decreased the
number of false positive.
I tried to build it from source, but it failed in some ways
by not finding the i386/686 libraries build when run on my x86_64,
could be related to differences in distribution, they use only
Ubuntu, and I tested on Fedora 16, I didn't tried to really solve the
issue at that point.
One of the problem of such a configuration is that the program doesn't
have what could be specific Fedora exception lists for valgrind.
So I grabbed the prebuilt version tsan-r4363-amd64-linux-self-contained.sh
(it's a self extracting binary in shell script) from
http://build.chromium.org/p/client.tsan/binaries/
renamid tsan.sh and installed it in my path, works fine...
I did a first test run with libxml2 code I know very well and
the result were good, i.e. it pointed out a data race I know about
and raised another one about some global data initialization,
so fairly positive from my POV.
Then I instrumented libvirt daemon for 0.9.12 release, launched it
as root from command line as a tsan argument:
/tmp/tsan.sh --trace-children=no /usr/sbin/libvirtd
and then played with virt-manager to exercise it a bit.
At first I tried to use --log-file=tsan.log option to collect
the logs but the logfile got corrupted so the following is
just cut and paste from the output
One of the ouput raised frequently is:
----------------------------------------------------------------------
==5838== WARNING: Possible data race during write of size 4 at 0x34723B3BD0: {{{
==5838== T1 (L{L17, L125}):
==5838== #0 ptmalloc_unlock_all2 /lib64/libc-2.14.90.so
==5838== #1 fork /lib64/libc-2.14.90.so
==5838== #2 virFork /usr/src/debug/libvirt-0.9.12/src/util/command.c:268
==5838== #3 virExecWithHook.constprop.5 /usr/src/debug/libvirt-0.9.12/src/util/command.c:489
==5838== #4 virCommandRunAsync /usr/src/debug/libvirt-0.9.12/src/util/command.c:2177
==5838== #5 virCommandRun /usr/src/debug/libvirt-0.9.12/src/util/command.c:1970
==5838== #6 qemuCapsExtractVersionInfo /usr/src/debug/libvirt-0.9.12/src/qemu/qemu_capabilities.c:1379
==5838== #7 qemuCapsExtractVersion /usr/src/debug/libvirt-0.9.12/src/qemu/qemu_capabilities.c:1568
==5838== #8 qemudGetVersion /usr/src/debug/libvirt-0.9.12/src/qemu/qemu_driver.c:1320
==5838== #9 virConnectGetVersion /usr/src/debug/libvirt-0.9.12/src/libvirt.c:1640
==5838== #10 remoteDispatchGetVersionHelper /usr/src/debug/libvirt-0.9.12/daemon/remote_dispatch.h:6862
==5838== #11 virNetServerProgramDispatch /usr/src/debug/libvirt-0.9.12/src/rpc/virnetserverprogram.c:416
==5838== Concurrent read(s) happened at (OR AFTER) these points:
==5838== T11 (L{}):
==5838== #0 arena_thread_freeres /lib64/libc-2.14.90.so
==5838== #1 __libc_thread_freeres /lib64/libc-2.14.90.so
==5838== #2 start_thread /lib64/libpthread-2.14.90.so
==5838== Address 0x34723B3BD0 is 0 bytes inside data symbol "list_lock"
==5838== Locks involved in this report (reporting last lock sites): {L17, L125}
==5838== L17 (0x5339B00)
==5838== #0 pthread_mutex_lock /mnt/data/build/slave/full_linux_build/build/tsan/ts_valgrind_intercepts.c:935
==5838== #1 virFork /usr/src/debug/libvirt-0.9.12/src/util/command.c:266
==5838== #2 virExecWithHook.constprop.5 /usr/src/debug/libvirt-0.9.12/src/util/command.c:489
==5838== #3 virCommandRunAsync /usr/src/debug/libvirt-0.9.12/src/util/command.c:2177
==5838== #4 virCommandRun /usr/src/debug/libvirt-0.9.12/src/util/command.c:1970
==5838== #5 qemuCapsExtractVersionInfo /usr/src/debug/libvirt-0.9.12/src/qemu/qemu_capabilities.c:1379
==5838== #6 qemuCapsExtractVersion /usr/src/debug/libvirt-0.9.12/src/qemu/qemu_capabilities.c:1568
==5838== #7 qemudGetVersion /usr/src/debug/libvirt-0.9.12/src/qemu/qemu_driver.c:1320
==5838== #8 virConnectGetVersion /usr/src/debug/libvirt-0.9.12/src/libvirt.c:1640
==5838== #9 remoteDispatchGetVersionHelper /usr/src/debug/libvirt-0.9.12/daemon/remote_dispatch.h:6862
==5838== #10 virNetServerProgramDispatch /usr/src/debug/libvirt-0.9.12/src/rpc/virnetserverprogram.c:416
==5838== #11 virNetServerHandleJob /usr/src/debug/libvirt-0.9.12/src/rpc/virnetserver.c:161
==5838== L125 (0x4C0A0A00)
==5838== #0 pthread_mutex_lock /mnt/data/build/slave/full_linux_build/build/tsan/ts_valgrind_intercepts.c:935
==5838== #1 qemudGetVersion /usr/src/debug/libvirt-0.9.12/src/qemu/qemu_driver.c:1319
==5838== #2 virConnectGetVersion /usr/src/debug/libvirt-0.9.12/src/libvirt.c:1640
==5838== #3 remoteDispatchGetVersionHelper /usr/src/debug/libvirt-0.9.12/daemon/remote_dispatch.h:6862
==5838== #4 virNetServerProgramDispatch /usr/src/debug/libvirt-0.9.12/src/rpc/virnetserverprogram.c:416
==5838== #5 virNetServerHandleJob /usr/src/debug/libvirt-0.9.12/src/rpc/virnetserver.c:161
==5838== #6 virThreadPoolWorker /usr/src/debug/libvirt-0.9.12/src/util/threadpool.c:144
==5838== #7 virThreadHelper /usr/src/debug/libvirt-0.9.12/src/util/threads-pthread.c:161
==5838== Race verifier data: 0x347207CF98,0x347215D6BB
==5838== }}}
I don't know what "Race verifier data" means but it seems that we do
*pid = fork(); in the main thread and that another thread is accessing
without synchronization. The probram properly report that 2 locks are
held at that point, the virLogLock() and qemuDriverLock() and give full
stack trace on where those locks were taken. That's convenient but
I could not really spot where the second thread did the access, I suspect
that's somehow related to libpthread considering the minimal stack trace
of the second thread T11 ...
Unfortunately, it seems that each time we fork we hit one or two
issue like that (which could be false positive), and tend to fill logs
relatively fast :-\
I however found out a couple of issues not related to libpthread:
==5733== WARNING: Possible data race during write of size 1 at 0x34723B6B14: {{{
==5733== T5 (L{}):
==5733== #0 Replace_memcpy /mnt/data/build/slave/full_linux_build/build/tsan/ts_replace.h:113
==5733== #1 __GI_memcpy /mnt/data/build/slave/full_linux_build/build/tsan/ts_valgrind_intercepts.c:2359
==5733== #2 xdrmem_getbytes /lib64/libc-2.14.90.so
==5733== #3 xdr_string /lib64/libc-2.14.90.so
==5733== #4 xdr_remote_nonnull_string /usr/src/debug/libvirt-0.9.12/daemon/../src/remote/remote_protocol.c:31
==5733== #5 xdr_remote_nonnull_domain /usr/src/debug/libvirt-0.9.12/daemon/../src/remote/remote_protocol.c:58
==5733== #6 xdr_remote_domain_get_info_args /usr/src/debug/libvirt-0.9.12/daemon/../src/remote/remote_protocol.c:1390
==5733== #7 virNetMessageDecodePayload /usr/src/debug/libvirt-0.9.12/src/rpc/virnetmessage.c:382
==5733== #8 virNetServerProgramDispatch /usr/src/debug/libvirt-0.9.12/src/rpc/virnetserverprogram.c:403
==5733== #9 virNetServerHandleJob /usr/src/debug/libvirt-0.9.12/src/rpc/virnetserver.c:161
==5733== #10 virThreadPoolWorker /usr/src/debug/libvirt-0.9.12/src/util/threadpool.c:144
==5733== #11 virThreadHelper /usr/src/debug/libvirt-0.9.12/src/util/threads-pthread.c:161
==5733== Concurrent write(s) happened at (OR AFTER) these points:
==5733== T2 (L{}):
==5733== #0 xdrmem_getbytes /lib64/libc-2.14.90.so
==5733== #1 xdr_string /lib64/libc-2.14.90.so
==5733== #2 xdr_remote_nonnull_string /usr/src/debug/libvirt-0.9.12/daemon/../src/remote/remote_protocol.c:31
==5733== #3 xdr_remote_nonnull_domain /usr/src/debug/libvirt-0.9.12/daemon/../src/remote/remote_protocol.c:58
==5733== #4 xdr_remote_domain_get_xml_desc_args /usr/src/debug/libvirt-0.9.12/daemon/../src/remote/remote_protocol.c:1532
==5733== #5 virNetMessageDecodePayload /usr/src/debug/libvirt-0.9.12/src/rpc/virnetmessage.c:382
==5733== #6 virNetServerProgramDispatch /usr/src/debug/libvirt-0.9.12/src/rpc/virnetserverprogram.c:403
==5733== #7 virNetServerHandleJob /usr/src/debug/libvirt-0.9.12/src/rpc/virnetserver.c:161
==5733== #8 virThreadPoolWorker /usr/src/debug/libvirt-0.9.12/src/util/threadpool.c:144
==5733== #9 virThreadHelper /usr/src/debug/libvirt-0.9.12/src/util/threads-pthread.c:161
==5733== Address 0x34723B6B14 is 0 bytes inside data symbol "crud.6424"
==5733== Race verifier data: 0x4A091CE,0x347212579D
==5733== }}}
that one could potentially be nasty, it seems that 2 threads decoding
rpc payload in parallel hit an unsynchronized write access in
the xdr routine for xdr_remote_nonnull_string() . I didn't had the
debuginfo for glibc installed when I ran it so I don't have the
exact informations at the top of the stacks
The other one raised is actually something I had initially found
with the first run on libxml2 so it's relatively consistent:
==5733== WARNING: Possible data race during read of size 4 at 0x34723B10B4: {{{
==5733== T1 (L{L173}):
==5733== #0 random_r /lib64/libc-2.14.90.so
==5733== #1 random /lib64/libc-2.14.90.so
==5733== #2 rand /lib64/libc-2.14.90.so
==5733== #3 xmlDictCreate /usr/src/debug/libxml2-2.8.0/dict.c:491
==5733== #4 xmlInitParserCtxt /usr/src/debug/libxml2-2.8.0/parserInternals.c:1620
==5733== #5 xmlNewParserCtxt /usr/src/debug/libxml2-2.8.0/parserInternals.c:1874
==5733== #6 xmlCreateURLParserCtxt /usr/src/debug/libxml2-2.8.0/parser.c:13546
==5733== #7 xmlReadFile /usr/src/debug/libxml2-2.8.0/parser.c:14713
==5733== #8 xmlRelaxNGParse /usr/src/debug/libxml2-2.8.0/relaxng.c:7480
==5733== #9 (no symbols) /usr/lib64/libnetcf.so.1.4.0
==5733== #10 ncf_init /usr/lib64/libnetcf.so.1.4.0
==5733== #11 interfaceOpenInterface /usr/src/debug/libvirt-0.9.12/src/interface/netcf_driver.c:144
==5733== Concurrent write(s) happened at (OR AFTER) these points:
==5733== T10 (L{L156}):
==5733== #0 random_r /lib64/libc-2.14.90.so
==5733== #1 random /lib64/libc-2.14.90.so
==5733== #2 rand /lib64/libc-2.14.90.so
==5733== #3 xmlHashCreate /usr/src/debug/libxml2-2.8.0/hash.c:193
==5733== #4 xmlRelaxNGCheckRules /usr/src/debug/libxml2-2.8.0/relaxng.c:4125
==5733== #5 xmlRelaxNGCheckRules /usr/src/debug/libxml2-2.8.0/relaxng.c:6380
==5733== #6 xmlRelaxNGCheckRules /usr/src/debug/libxml2-2.8.0/relaxng.c:6523
==5733== #7 xmlRelaxNGCheckRules /usr/src/debug/libxml2-2.8.0/relaxng.c:6319
==5733== #8 xmlRelaxNGCheckRules /usr/src/debug/libxml2-2.8.0/relaxng.c:6520
==5733== #9 xmlRelaxNGCheckRules /usr/src/debug/libxml2-2.8.0/relaxng.c:6523
==5733== Address 0x34723B10B4 is 20 bytes inside data symbol "randtbl"
==5733== Locks involved in this report (reporting last lock sites): {L156, L173}
==5733== L156 (0x402E790)
==5733== #0 pthread_mutex_lock /mnt/data/build/slave/full_linux_build/build/tsan/ts_valgrind_intercepts.c:935
==5733== #1 remoteDispatchOpenHelper /usr/src/debug/libvirt-0.9.12/daemon/remote.c:683
==5733== #2 virNetServerProgramDispatch /usr/src/debug/libvirt-0.9.12/src/rpc/virnetserverprogram.c:416
==5733== #3 virNetServerHandleJob /usr/src/debug/libvirt-0.9.12/src/rpc/virnetserver.c:161
==5733== #4 virThreadPoolWorker /usr/src/debug/libvirt-0.9.12/src/util/threadpool.c:144
==5733== #5 virThreadHelper /usr/src/debug/libvirt-0.9.12/src/util/threads-pthread.c:161
==5733== L173 (0x402F420)
==5733== #0 pthread_mutex_lock /mnt/data/build/slave/full_linux_build/build/tsan/ts_valgrind_intercepts.c:935
==5733== #1 remoteDispatchOpenHelper /usr/src/debug/libvirt-0.9.12/daemon/remote.c:683
==5733== #2 virNetServerProgramDispatch /usr/src/debug/libvirt-0.9.12/src/rpc/virnetserverprogram.c:416
==5733== #3 virNetServerHandleJob /usr/src/debug/libvirt-0.9.12/src/rpc/virnetserver.c:161
==5733== #4 virThreadPoolWorker /usr/src/debug/libvirt-0.9.12/src/util/threadpool.c:144
==5733== #5 virThreadHelper /usr/src/debug/libvirt-0.9.12/src/util/threads-pthread.c:161
==5733== Race verifier data: 0x347203A572,0x347203A565
==5733== }}}
I didn't know that netcf was doing Relax-NG validation on-the-fly :)
and hit another in libxml2 though libvirt/netcf/libxslt/libxml2
call:
==5733== WARNING: Possible data race during read of size 4 at 0x34723B10B4: {{{
==5733== T1 (L{L173}):
==5733== #0 random_r /lib64/libc-2.14.90.so
==5733== #1 random /lib64/libc-2.14.90.so
==5733== #2 rand /lib64/libc-2.14.90.so
==5733== #3 xmlDictCreate /usr/src/debug/libxml2-2.8.0/dict.c:491
==5733== #4 xmlInitParserCtxt /usr/src/debug/libxml2-2.8.0/parserInternals.c:1620
==5733== #5 xmlNewParserCtxt /usr/src/debug/libxml2-2.8.0/parserInternals.c:1874
==5733== #6 xmlCreateURLParserCtxt /usr/src/debug/libxml2-2.8.0/parser.c:13546
==5733== #7 xmlReadFile /usr/src/debug/libxml2-2.8.0/parser.c:14713
==5733== #8 xmlRelaxNGParse /usr/src/debug/libxml2-2.8.0/relaxng.c:7480
==5733== #9 (no symbols) /usr/lib64/libnetcf.so.1.4.0
==5733== #10 ncf_init /usr/lib64/libnetcf.so.1.4.0
==5733== #11 interfaceOpenInterface /usr/src/debug/libvirt-0.9.12/src/interface/netcf_driver.c:144
==5733== Concurrent write(s) happened at (OR AFTER) these points:
==5733== T10 (L{L156}):
==5733== #0 random_r /lib64/libc-2.14.90.so
==5733== #1 random /lib64/libc-2.14.90.so
==5733== #2 rand /lib64/libc-2.14.90.so
==5733== #3 xmlHashCreate /usr/src/debug/libxml2-2.8.0/hash.c:193
==5733== #4 xmlRelaxNGCheckRules /usr/src/debug/libxml2-2.8.0/relaxng.c:4125
==5733== #5 xmlRelaxNGCheckRules /usr/src/debug/libxml2-2.8.0/relaxng.c:6380
==5733== #6 xmlRelaxNGCheckRules /usr/src/debug/libxml2-2.8.0/relaxng.c:6523
==5733== #7 xmlRelaxNGCheckRules /usr/src/debug/libxml2-2.8.0/relaxng.c:6319
==5733== #8 xmlRelaxNGCheckRules /usr/src/debug/libxml2-2.8.0/relaxng.c:6520
==5733== #9 xmlRelaxNGCheckRules /usr/src/debug/libxml2-2.8.0/relaxng.c:6523
==5733== Address 0x34723B10B4 is 20 bytes inside data symbol "randtbl"
==5733== Locks involved in this report (reporting last lock sites): {L156, L173}
Looks like another libxml2 bug calling rand, I should use rand_r() instead
if available.
I also ran virsh itself under tsan for a few functions, but that didn't
raise any issue.
So except for the parallel xdr_remote_nonnull_string() issue
I don't think there is anything I can report at this point for libvirt
code itself.
The slowdown of tsan is acceptable, virt-manager is a clearly a bit
less responsive when connecting of doing libvirt operations but it
is really usable, and that's IMHO the main point of my testing,
it's not hard (though it would be better if packaged for Fedora)
and the results are interesting but a bit heavy since the same issue
can pop-up all the time like for fork().
I guess it would be interesting to try out qemu-kvm with it though
it may turn unbearably slow, but it's worth testing !
Daniel
--
Daniel Veillard | libxml Gnome XML XSLT toolkit http://xmlsoft.org/
daniel(a)veillard.com | Rpmfind RPM search engine http://rpmfind.net/
http://veillard.com/ | virtualization library http://libvirt.org/
12 years, 6 months