[libvirt] [PATCH] Fix potential events deadlock when unref'ing virConnectPtr
by Daniel P. Berrange
From: "Daniel P. Berrange" <berrange(a)redhat.com>
When the last reference to a virConnectPtr is released by
libvirtd, it was possible for a deadlock to occur in the
virDomainEventState functions. The virDomainEventStatePtr
holds a reference on virConnectPtr for each registered
callback. When removing a callback, the virUnrefConnect
function is run. If this causes the last reference on the
virConnectPtr to be released, then virReleaseConnect can
be run, which in turns calls qemudClose. This function has
a call to virDomainEventStateDeregisterConn which is intended
to remove all callbacks associated with the virConnectPtr
instance.
Since each callback associated with a virConnectPtr holds a
reference on virConnectPtr, it is impossible for the qemudClose
method to be invoked while any callbacks are still registered.
Thus the call to virDomainEventStateDeregisterConn must in fact
be a no-op. Thus it is possible to just remove all trace of
virDomainEventStateDeregisterConn and avoid the deadlock.
* src/conf/domain_event.c, src/conf/domain_event.h,
src/libvirt_private.syms: Delete virDomainEventStateDeregisterConn
* src/libxl/libxl_driver.c, src/lxc/lxc_driver.c,
src/qemu/qemu_driver.c, src/uml/uml_driver.c: Remove
calls to virDomainEventStateDeregisterConn
---
src/conf/domain_event.c | 61 ----------------------------------------------
src/conf/domain_event.h | 4 ---
src/libvirt_private.syms | 1 -
src/libxl/libxl_driver.c | 4 ---
src/lxc/lxc_driver.c | 2 --
src/qemu/qemu_driver.c | 2 --
src/uml/uml_driver.c | 2 --
7 files changed, 76 deletions(-)
diff --git a/src/conf/domain_event.c b/src/conf/domain_event.c
index 923c58d..4ecc413 100644
--- a/src/conf/domain_event.c
+++ b/src/conf/domain_event.c
@@ -248,45 +248,6 @@ virDomainEventCallbackListRemoveID(virConnectPtr conn,
}
-/**
- * virDomainEventCallbackListRemoveConn:
- * @conn: pointer to the connection
- * @cbList: the list
- *
- * Internal function to remove all of a given connection's callback
- * from a virDomainEventCallbackListPtr
- */
-static int
-virDomainEventCallbackListRemoveConn(virConnectPtr conn,
- virDomainEventCallbackListPtr cbList)
-{
- int old_count = cbList->count;
- int i;
- for (i = 0 ; i < cbList->count ; i++) {
- if (cbList->callbacks[i]->conn == conn) {
- virFreeCallback freecb = cbList->callbacks[i]->freecb;
- if (freecb)
- (*freecb)(cbList->callbacks[i]->opaque);
- virUnrefConnect(cbList->callbacks[i]->conn);
- VIR_FREE(cbList->callbacks[i]);
-
- if (i < (cbList->count - 1))
- memmove(cbList->callbacks + i,
- cbList->callbacks + i + 1,
- sizeof(*(cbList->callbacks)) *
- (cbList->count - (i + 1)));
- cbList->count--;
- i--;
- }
- }
- if (cbList->count < old_count &&
- VIR_REALLOC_N(cbList->callbacks, cbList->count) < 0) {
- ; /* Failure to reduce memory allocation isn't fatal */
- }
- return 0;
-}
-
-
static int
virDomainEventCallbackListMarkDelete(virConnectPtr conn,
virDomainEventCallbackListPtr cbList,
@@ -1608,28 +1569,6 @@ virDomainEventStateDeregisterID(virConnectPtr conn,
/**
- * virDomainEventStateDeregisterConn:
- * @conn: connection to associate with callbacks
- * @state: domain event state
- *
- * Remove all callbacks from @state associated with the
- * connection @conn
- *
- * Returns 0 on success, -1 on error
- */
-int
-virDomainEventStateDeregisterConn(virConnectPtr conn,
- virDomainEventStatePtr state)
-{
- int ret;
- virDomainEventStateLock(state);
- ret = virDomainEventCallbackListRemoveConn(conn, state->callbacks);
- virDomainEventStateUnlock(state);
- return ret;
-}
-
-
-/**
* virDomainEventStateEventID:
* @conn: connection associated with the callback
* @state: domain event state
diff --git a/src/conf/domain_event.h b/src/conf/domain_event.h
index f7776c7..d381aec 100644
--- a/src/conf/domain_event.h
+++ b/src/conf/domain_event.h
@@ -161,10 +161,6 @@ virDomainEventStateDeregisterID(virConnectPtr conn,
int callbackID)
ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2);
int
-virDomainEventStateDeregisterConn(virConnectPtr conn,
- virDomainEventStatePtr state)
- ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2);
-int
virDomainEventStateEventID(virConnectPtr conn,
virDomainEventStatePtr state,
int callbackID)
diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
index f5c2184..6c907c4 100644
--- a/src/libvirt_private.syms
+++ b/src/libvirt_private.syms
@@ -522,7 +522,6 @@ virDomainEventRebootNewFromDom;
virDomainEventRebootNewFromObj;
virDomainEventStateDeregister;
virDomainEventStateDeregisterID;
-virDomainEventStateDeregisterConn;
virDomainEventStateEventID;
virDomainEventStateRegister;
virDomainEventStateRegisterID;
diff --git a/src/libxl/libxl_driver.c b/src/libxl/libxl_driver.c
index 45bf1f8..fc90d16 100644
--- a/src/libxl/libxl_driver.c
+++ b/src/libxl/libxl_driver.c
@@ -1081,10 +1081,6 @@ libxlClose(virConnectPtr conn ATTRIBUTE_UNUSED)
{
libxlDriverPrivatePtr driver = conn->privateData;
- libxlDriverLock(driver);
- virDomainEventStateDeregisterConn(conn,
- driver->domainEventState);
- libxlDriverUnlock(driver);
conn->privateData = NULL;
return 0;
}
diff --git a/src/lxc/lxc_driver.c b/src/lxc/lxc_driver.c
index 4cccd53..9aea556 100644
--- a/src/lxc/lxc_driver.c
+++ b/src/lxc/lxc_driver.c
@@ -178,8 +178,6 @@ static int lxcClose(virConnectPtr conn)
lxc_driver_t *driver = conn->privateData;
lxcDriverLock(driver);
- virDomainEventStateDeregisterConn(conn,
- driver->domainEventState);
lxcProcessAutoDestroyRun(driver, conn);
lxcDriverUnlock(driver);
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index efbc421..39b27b1 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -962,8 +962,6 @@ static int qemudClose(virConnectPtr conn) {
/* Get rid of callbacks registered for this conn */
qemuDriverLock(driver);
- virDomainEventStateDeregisterConn(conn,
- driver->domainEventState);
qemuDriverCloseCallbackRunAll(driver, conn);
qemuDriverUnlock(driver);
diff --git a/src/uml/uml_driver.c b/src/uml/uml_driver.c
index 8a39d73..65f9cbc 100644
--- a/src/uml/uml_driver.c
+++ b/src/uml/uml_driver.c
@@ -1188,8 +1188,6 @@ static int umlClose(virConnectPtr conn) {
struct uml_driver *driver = conn->privateData;
umlDriverLock(driver);
- virDomainEventStateDeregisterConn(conn,
- driver->domainEventState);
umlProcessAutoDestroyRun(driver, conn);
umlDriverUnlock(driver);
--
1.7.10.1
12 years, 11 months
[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, 11 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, 11 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, 11 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, 11 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, 11 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, 11 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, 11 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, 11 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, 12 months