[libvirt] [PATCH] qemu: Add option to enable/disable IOEventFD feature
by Michal Privoznik
This feature allows QEMU to achieve higher throughput, but is available
only in recent versions. It is accessible via ioeventfd attribute
with accepting values 'on', 'off'. Only experienced users needs to set
this, because QEMU defaults to 'on', meaning higher performance.
Translates into virtio-{blk|net}-pci.ioeventfd option.
---
docs/formatdomain.html.in | 15 ++++++++++++-
docs/schemas/domain.rng | 14 +++++++++++++
src/conf/domain_conf.c | 44 +++++++++++++++++++++++++++++++++++++++++-
src/conf/domain_conf.h | 12 +++++++++++
src/libvirt_private.syms | 2 +
src/qemu/qemu_capabilities.c | 2 +
src/qemu/qemu_capabilities.h | 1 +
src/qemu/qemu_command.c | 23 +++++++++++++++++++++
tests/qemuhelptest.c | 3 +-
9 files changed, 112 insertions(+), 4 deletions(-)
diff --git a/docs/formatdomain.html.in b/docs/formatdomain.html.in
index a055b38..409b26a 100644
--- a/docs/formatdomain.html.in
+++ b/docs/formatdomain.html.in
@@ -751,7 +751,7 @@
</disk>
...
<disk type='network'>
- <driver name="qemu" type="raw" io="threads"/>
+ <driver name="qemu" type="raw" io="threads" ioeventfd="on"/>
<source protocol="sheepdog" name="image_name">
<host name="hostname" port="7000"/>
</source>
@@ -835,6 +835,11 @@
policies on I/O; qemu guests support "threads" and
"native". <span class="since">Since 0.8.8</span>
</li>
+ <li>
+ The optional <code>ioeventfd</code> attribute enables or disables
+ IOEventFD feature for virtqueue notify. The value can be either
+ 'on' or 'off'.
+ <span class="since">Since 0.9.0 (QEMU and KVM only)</span>
</ul>
</dd>
<dt><code>boot</code></dt>
@@ -1458,7 +1463,7 @@ qemu-kvm -net nic,model=? /dev/null
<source network='default'/>
<target dev='vnet1'/>
<model type='virtio'/>
- <b><driver name='vhost' txmode='iothread'/></b>
+ <b><driver name='vhost' txmode='iothread' ioeventfd='on'/></b>
</interface>
</devices>
...</pre>
@@ -1509,6 +1514,12 @@ qemu-kvm -net nic,model=? /dev/null
<b>In general you should leave this option alone, unless you
are very certain you know what you are doing.</b>
</dd>
+ <dt><code>ioeventfd</code><code></dt>
+ <dd>
+ This optional attribute allows users to enable or disable IOeventFD
+ feature for virtqueue notify. The value can be either 'on' or 'off'.
+ <span class="since">Since 0.9.0 (QEMU and KVM only)</span>
+ </dd>
</dl>
<h5><a name="elementsNICSTargetOverride">Overriding the target element</a></h5>
diff --git a/docs/schemas/domain.rng b/docs/schemas/domain.rng
index 7163c6e..c3e8e15 100644
--- a/docs/schemas/domain.rng
+++ b/docs/schemas/domain.rng
@@ -735,6 +735,9 @@
<optional>
<ref name="driverIO"/>
</optional>
+ <optional>
+ <ref name="ioeventfd"/>
+ </optional>
<empty/>
</element>
</define>
@@ -774,6 +777,14 @@
</choice>
</attribute>
</define>
+ <define name="ioeventfd">
+ <attribute name="ioeventfd">
+ <choice>
+ <value>on</value>
+ <value>off</value>
+ </choice>
+ </attribute>
+ </define>
<define name="controller">
<element name="controller">
<choice>
@@ -1074,6 +1085,9 @@
</choice>
</attribute>
</optional>
+ <optional>
+ <ref name="ioeventfd"/>
+ </optional>
<empty/>
</element>
</optional>
diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
index 0e7aeb5..2aca162 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -155,6 +155,11 @@ VIR_ENUM_IMPL(virDomainDiskIo, VIR_DOMAIN_DISK_IO_LAST,
"native",
"threads")
+VIR_ENUM_IMPL(virDomainVirtioEventFd, VIR_DOMAIN_VIRTIO_EVENT_FD_LAST,
+ "default",
+ "on",
+ "off")
+
VIR_ENUM_IMPL(virDomainController, VIR_DOMAIN_CONTROLLER_TYPE_LAST,
"ide",
"fdc",
@@ -1829,6 +1834,7 @@ virDomainDiskDefParseXML(virCapsPtr caps,
char *cachetag = NULL;
char *error_policy = NULL;
char *iotag = NULL;
+ char *ioeventfd = NULL;
char *devaddr = NULL;
virStorageEncryptionPtr encryption = NULL;
char *serial = NULL;
@@ -1944,6 +1950,7 @@ virDomainDiskDefParseXML(virCapsPtr caps,
cachetag = virXMLPropString(cur, "cache");
error_policy = virXMLPropString(cur, "error_policy");
iotag = virXMLPropString(cur, "io");
+ ioeventfd = virXMLPropString(cur, "ioeventfd");
} else if (xmlStrEqual(cur->name, BAD_CAST "readonly")) {
def->readonly = 1;
} else if (xmlStrEqual(cur->name, BAD_CAST "shareable")) {
@@ -2080,6 +2087,18 @@ virDomainDiskDefParseXML(virCapsPtr caps,
}
}
+ if (ioeventfd) {
+ int i;
+ if ((i = virDomainVirtioEventFdTypeFromString(ioeventfd)) <= 0) {
+ virDomainReportError(VIR_ERR_CONFIG_UNSUPPORTED,
+ _("unknown disk ioeventfd mode '%s'"),
+ ioeventfd);
+ goto error;
+ }
+ def->ioeventfd = i;
+ }
+
+
if (devaddr) {
if (virDomainParseLegacyDeviceAddress(devaddr,
&def->info.addr.pci) < 0) {
@@ -2142,6 +2161,7 @@ cleanup:
VIR_FREE(cachetag);
VIR_FREE(error_policy);
VIR_FREE(iotag);
+ VIR_FREE(ioeventfd);
VIR_FREE(devaddr);
VIR_FREE(serial);
virStorageEncryptionFree(encryption);
@@ -2529,6 +2549,7 @@ virDomainNetDefParseXML(virCapsPtr caps,
char *model = NULL;
char *backend = NULL;
char *txmode = NULL;
+ char *ioeventfd = NULL;
char *filter = NULL;
char *internal = NULL;
char *devaddr = NULL;
@@ -2618,6 +2639,7 @@ virDomainNetDefParseXML(virCapsPtr caps,
} else if (xmlStrEqual (cur->name, BAD_CAST "driver")) {
backend = virXMLPropString(cur, "name");
txmode = virXMLPropString(cur, "txmode");
+ ioeventfd = virXMLPropString(cur, "ioeventfd");
} else if (xmlStrEqual (cur->name, BAD_CAST "filterref")) {
filter = virXMLPropString(cur, "filter");
VIR_FREE(filterparams);
@@ -2834,6 +2856,17 @@ virDomainNetDefParseXML(virCapsPtr caps,
}
def->driver.virtio.txmode = m;
}
+ if (ioeventfd != NULL) {
+ int i;
+ if ((i = virDomainVirtioEventFdTypeFromString(ioeventfd)) <= 0) {
+ virDomainReportError(VIR_ERR_CONFIG_UNSUPPORTED,
+ _("unknown interface <driver "
+ "ioeventfd='%s'> has been specified"),
+ ioeventfd);
+ goto error;
+ }
+ def->driver.virtio.ioeventfd = i;
+ }
}
if (filter != NULL) {
@@ -2873,6 +2906,7 @@ cleanup:
VIR_FREE(model);
VIR_FREE(backend);
VIR_FREE(txmode);
+ VIR_FREE(ioeventfd);
VIR_FREE(filter);
VIR_FREE(type);
VIR_FREE(internal);
@@ -6910,6 +6944,7 @@ virDomainDiskDefFormat(virBufferPtr buf,
const char *cachemode = virDomainDiskCacheTypeToString(def->cachemode);
const char *error_policy = virDomainDiskErrorPolicyTypeToString(def->error_policy);
const char *iomode = virDomainDiskIoTypeToString(def->iomode);
+ const char *ioeventfd = virDomainVirtioEventFdTypeToString(def->ioeventfd);
if (!type) {
virDomainReportError(VIR_ERR_INTERNAL_ERROR,
@@ -6941,7 +6976,8 @@ virDomainDiskDefFormat(virBufferPtr buf,
" <disk type='%s' device='%s'>\n",
type, device);
- if (def->driverName || def->driverType || def->cachemode) {
+ if (def->driverName || def->driverType || def->cachemode ||
+ def->ioeventfd) {
virBufferVSprintf(buf, " <driver");
if (def->driverName)
virBufferVSprintf(buf, " name='%s'", def->driverName);
@@ -6953,6 +6989,8 @@ virDomainDiskDefFormat(virBufferPtr buf,
virBufferVSprintf(buf, " error_policy='%s'", error_policy);
if (def->iomode)
virBufferVSprintf(buf, " io='%s'", iomode);
+ if (def->ioeventfd)
+ virBufferVSprintf(buf, " ioeventfd='%s'", ioeventfd);
virBufferVSprintf(buf, "/>\n");
}
@@ -7243,6 +7281,10 @@ virDomainNetDefFormat(virBufferPtr buf,
virBufferVSprintf(buf, " txmode='%s'",
virDomainNetVirtioTxModeTypeToString(def->driver.virtio.txmode));
}
+ if (def->driver.virtio.ioeventfd) {
+ virBufferVSprintf(buf, " ioeventfd='%s'",
+ virDomainVirtioEventFdTypeToString(def->driver.virtio.ioeventfd));
+ }
virBufferAddLit(buf, "/>\n");
}
}
diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h
index 6ea30b9..42ca601 100644
--- a/src/conf/domain_conf.h
+++ b/src/conf/domain_conf.h
@@ -197,6 +197,15 @@ enum virDomainDiskIo {
VIR_DOMAIN_DISK_IO_LAST
};
+enum virDomainVirtioEventFd {
+ VIR_DOMAIN_VIRTIO_EVENT_FD_DEFAULT = 0,
+ VIR_DOMAIN_VIRTIO_EVENT_FD_ON,
+ VIR_DOMAIN_VIRTIO_EVENT_FD_OFF,
+
+ VIR_DOMAIN_VIRTIO_EVENT_FD_LAST
+};
+
+
/* Stores the virtual disk configuration */
typedef struct _virDomainDiskDef virDomainDiskDef;
typedef virDomainDiskDef *virDomainDiskDefPtr;
@@ -216,6 +225,7 @@ struct _virDomainDiskDef {
int error_policy;
int bootIndex;
int iomode;
+ enum virDomainVirtioEventFd ioeventfd;
unsigned int readonly : 1;
unsigned int shared : 1;
virDomainDeviceInfo info;
@@ -351,6 +361,7 @@ struct _virDomainNetDef {
struct {
enum virDomainNetBackendType name; /* which driver backend to use */
enum virDomainNetVirtioTxModeType txmode;
+ enum virDomainVirtioEventFd ioeventfd;
} virtio;
} driver;
union {
@@ -1439,6 +1450,7 @@ VIR_ENUM_DECL(virDomainDiskCache)
VIR_ENUM_DECL(virDomainDiskErrorPolicy)
VIR_ENUM_DECL(virDomainDiskProtocol)
VIR_ENUM_DECL(virDomainDiskIo)
+VIR_ENUM_DECL(virDomainVirtioEventFd)
VIR_ENUM_DECL(virDomainController)
VIR_ENUM_DECL(virDomainControllerModel)
VIR_ENUM_DECL(virDomainFS)
diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
index 3d53287..1bd90a1 100644
--- a/src/libvirt_private.syms
+++ b/src/libvirt_private.syms
@@ -338,6 +338,8 @@ virDomainVideoDefaultType;
virDomainVideoTypeFromString;
virDomainVideoTypeToString;
virDomainVirtTypeToString;
+virDomainVirtioEventFdTypeFromString;
+virDomainVirtioEventFdTypeToString;
virDomainWatchdogActionTypeFromString;
virDomainWatchdogActionTypeToString;
virDomainWatchdogModelTypeFromString;
diff --git a/src/qemu/qemu_capabilities.c b/src/qemu/qemu_capabilities.c
index 63486cc..6e8aa50 100644
--- a/src/qemu/qemu_capabilities.c
+++ b/src/qemu/qemu_capabilities.c
@@ -1124,6 +1124,8 @@ qemuCapsParseDeviceStr(const char *str, virBitmapPtr flags)
qemuCapsSet(flags, QEMU_CAPS_VIRTIO_TX_ALG);
if (strstr(str, "name \"qxl-vga\""))
qemuCapsSet(flags, QEMU_CAPS_DEVICE_QXL_VGA);
+ if (strstr(str, "virtio-blk-pci.ioeventfd"))
+ qemuCapsSet(flags, QEMU_CAPS_VIRTIO_IOEVENTFD);
return 0;
}
diff --git a/src/qemu/qemu_capabilities.h b/src/qemu/qemu_capabilities.h
index 68c5958..400d73c 100644
--- a/src/qemu/qemu_capabilities.h
+++ b/src/qemu/qemu_capabilities.h
@@ -95,6 +95,7 @@ enum qemuCapsFlags {
QEMU_CAPS_DEVICE_SPICEVMC = 57, /* older -device spicevmc*/
QEMU_CAPS_VIRTIO_TX_ALG = 58, /* -device virtio-net-pci,tx=string */
QEMU_CAPS_DEVICE_QXL_VGA = 59, /* Is the primary and vga campatible qxl device named qxl-vga? */
+ QEMU_CAPS_VIRTIO_IOEVENTFD = 60, /* IOEventFD feature: virtio-{net|blk}-pci.ioeventfd=on/off */
QEMU_CAPS_LAST, /* this must always be the last item */
};
diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c
index 2205ed1..41b4fdd 100644
--- a/src/qemu/qemu_command.c
+++ b/src/qemu/qemu_command.c
@@ -1169,6 +1169,26 @@ qemuBuildDeviceAddressStr(virBufferPtr buf,
return 0;
}
+static int
+qemuBuildIoEventFdStr(virBufferPtr buf,
+ enum virDomainVirtioEventFd use,
+ virBitmapPtr qemuCaps)
+{
+ if (qemuCapsGet(qemuCaps, QEMU_CAPS_VIRTIO_IOEVENTFD)) {
+ switch (use) {
+ case VIR_DOMAIN_VIRTIO_EVENT_FD_ON:
+ case VIR_DOMAIN_VIRTIO_EVENT_FD_OFF:
+ virBufferVSprintf(buf, ",ioeventfd=%s",
+ virDomainVirtioEventFdTypeToString(use));
+ break;
+ default:
+ /* In other cases (_DEFAULT, _LAST) we don't
+ * want to add anything */
+ break;
+ }
+ }
+ return 0;
+}
#define QEMU_SERIAL_PARAM_ACCEPTED_CHARS \
"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-_"
@@ -1434,6 +1454,7 @@ qemuBuildDriveDevStr(virDomainDiskDefPtr disk,
break;
case VIR_DOMAIN_DISK_BUS_VIRTIO:
virBufferAddLit(&opt, "virtio-blk-pci");
+ qemuBuildIoEventFdStr(&opt, disk->ioeventfd, qemuCaps);
qemuBuildDeviceAddressStr(&opt, &disk->info, qemuCaps);
break;
case VIR_DOMAIN_DISK_BUS_USB:
@@ -1656,6 +1677,8 @@ qemuBuildNicDevStr(virDomainNetDefPtr net,
goto error;
}
}
+ if(usingVirtio)
+ qemuBuildIoEventFdStr(&buf, net->driver.virtio.ioeventfd, qemuCaps);
if (vlan == -1)
virBufferVSprintf(&buf, ",netdev=host%s", net->info.alias);
else
diff --git a/tests/qemuhelptest.c b/tests/qemuhelptest.c
index c86c578..776acf5 100644
--- a/tests/qemuhelptest.c
+++ b/tests/qemuhelptest.c
@@ -490,7 +490,8 @@ mymain(int argc, char **argv)
QEMU_CAPS_CCID_PASSTHRU,
QEMU_CAPS_CHARDEV_SPICEVMC,
QEMU_CAPS_DEVICE_QXL_VGA,
- QEMU_CAPS_VIRTIO_TX_ALG);
+ QEMU_CAPS_VIRTIO_TX_ALG,
+ QEMU_CAPS_VIRTIO_IOEVENTFD);
return ret == 0 ? EXIT_SUCCESS : EXIT_FAILURE;
}
--
1.7.4.4
13 years, 8 months
[libvirt] [PATCH] esx: Fix dynamic dispatch for CastFromAnyType functions
by Matthias Bolte
This was broken by the refactoring in ac1e6586ec75. It resulted in a
segfault for 'virsh vol-dumpxml' and related volume functions.
Before the refactoring all users of the ESX_VI__TEMPLATE__DISPATCH
macro dispatched on the item type, as the item is the input to all those
functions.
Commit ac1e6586ec75 made the dynamically dispatched CastFromAnyType
functions use this macro too, but this functions dispatched on the
actual type of the AnyType object. The item is the output of the
CastFromAnyType functions.
This difference was missed in the refactoring, making CastFromAnyType
functions dereferencing the item pointer that is NULL at the time of
the dispatch.
---
src/esx/esx_vi_types.c | 12 ++++++------
1 files changed, 6 insertions(+), 6 deletions(-)
diff --git a/src/esx/esx_vi_types.c b/src/esx/esx_vi_types.c
index dd83954..6a2d5cf 100644
--- a/src/esx/esx_vi_types.c
+++ b/src/esx/esx_vi_types.c
@@ -533,8 +533,8 @@
* Macros to implement dynamic dispatched functions
*/
-#define ESX_VI__TEMPLATE__DISPATCH(__type, _dispatch, _error_return) \
- switch (item->_type) { \
+#define ESX_VI__TEMPLATE__DISPATCH(_object, __type, _dispatch, _error_return) \
+ switch ((_object)->_type) { \
_dispatch \
\
case esxVI_Type_##__type: \
@@ -543,7 +543,7 @@
default: \
ESX_VI_ERROR(VIR_ERR_INTERNAL_ERROR, \
_("Call to %s for unexpected type '%s'"), __FUNCTION__, \
- esxVI_Type_ToString(item->_type)); \
+ esxVI_Type_ToString((_object)->_type)); \
return _error_return; \
}
@@ -585,7 +585,7 @@
#define ESX_VI__TEMPLATE__DYNAMIC_FREE(__type, _dispatch, _body) \
ESX_VI__TEMPLATE__FREE(__type, \
- ESX_VI__TEMPLATE__DISPATCH(__type, _dispatch, /* nothing */) \
+ ESX_VI__TEMPLATE__DISPATCH(item, __type, _dispatch, /* nothing */) \
_body)
@@ -618,14 +618,14 @@
#define ESX_VI__TEMPLATE__DYNAMIC_CAST_FROM_ANY_TYPE(__type, _dispatch) \
ESX_VI__TEMPLATE__CAST_FROM_ANY_TYPE_EXTRA(__type, esxVI_##__type, \
- ESX_VI__TEMPLATE__DISPATCH(__type, _dispatch, -1), \
+ ESX_VI__TEMPLATE__DISPATCH(anyType, __type, _dispatch, -1), \
/* nothing */)
#define ESX_VI__TEMPLATE__DYNAMIC_SERIALIZE(__type, _dispatch, _serialize) \
ESX_VI__TEMPLATE__SERIALIZE_EXTRA(__type, \
- ESX_VI__TEMPLATE__DISPATCH(__type, _dispatch, -1), \
+ ESX_VI__TEMPLATE__DISPATCH(item, __type, _dispatch, -1), \
_serialize)
--
1.7.0.4
13 years, 8 months
[libvirt] [PATCH] Move call to virReportOOMError into virFileBuildPath
by Matthias Bolte
Suggested by Daniel P. Berrange
---
src/conf/nwfilter_conf.c | 5 +----
src/conf/storage_conf.c | 7 +------
src/util/util.c | 2 ++
src/xen/xen_inotify.c | 1 -
src/xen/xm_internal.c | 5 +----
5 files changed, 5 insertions(+), 15 deletions(-)
diff --git a/src/conf/nwfilter_conf.c b/src/conf/nwfilter_conf.c
index 327fab3..09dc32b 100644
--- a/src/conf/nwfilter_conf.c
+++ b/src/conf/nwfilter_conf.c
@@ -2588,10 +2588,8 @@ virNWFilterLoadAllConfigs(virConnectPtr conn,
if (!virFileHasSuffix(entry->d_name, ".xml"))
continue;
- if (!(path = virFileBuildPath(configDir, entry->d_name, NULL))) {
- virReportOOMError();
+ if (!(path = virFileBuildPath(configDir, entry->d_name, NULL)))
continue;
- }
nwfilter = virNWFilterObjLoad(conn, nwfilters, entry->d_name, path);
if (nwfilter)
@@ -2627,7 +2625,6 @@ virNWFilterObjSaveDef(virNWFilterDriverStatePtr driver,
if (!(nwfilter->configFile = virFileBuildPath(driver->configDir,
def->name, ".xml"))) {
- virReportOOMError();
return -1;
}
}
diff --git a/src/conf/storage_conf.c b/src/conf/storage_conf.c
index 5a069f5..116898d 100644
--- a/src/conf/storage_conf.c
+++ b/src/conf/storage_conf.c
@@ -1483,14 +1483,11 @@ virStoragePoolLoadAllConfigs(virStoragePoolObjListPtr pools,
if (!virFileHasSuffix(entry->d_name, ".xml"))
continue;
- if (!(path = virFileBuildPath(configDir, entry->d_name, NULL))) {
- virReportOOMError();
+ if (!(path = virFileBuildPath(configDir, entry->d_name, NULL)))
continue;
- }
if (!(autostartLink = virFileBuildPath(autostartDir, entry->d_name,
NULL))) {
- virReportOOMError();
VIR_FREE(path);
continue;
}
@@ -1529,13 +1526,11 @@ virStoragePoolObjSaveDef(virStorageDriverStatePtr driver,
if (!(pool->configFile = virFileBuildPath(driver->configDir,
def->name, ".xml"))) {
- virReportOOMError();
return -1;
}
if (!(pool->autostartLink = virFileBuildPath(driver->autostartDir,
def->name, ".xml"))) {
- virReportOOMError();
VIR_FREE(pool->configFile);
return -1;
}
diff --git a/src/util/util.c b/src/util/util.c
index d4d2610..3948b01 100644
--- a/src/util/util.c
+++ b/src/util/util.c
@@ -1851,10 +1851,12 @@ virFileBuildPath(const char *dir, const char *name, const char *ext)
if (ext == NULL) {
if (virAsprintf(&path, "%s/%s", dir, name) < 0) {
+ virReportOOMError();
return NULL;
}
} else {
if (virAsprintf(&path, "%s/%s%s", dir, name, ext) < 0) {
+ virReportOOMError();
return NULL;
}
}
diff --git a/src/xen/xen_inotify.c b/src/xen/xen_inotify.c
index d809c45..9dde72c 100644
--- a/src/xen/xen_inotify.c
+++ b/src/xen/xen_inotify.c
@@ -415,7 +415,6 @@ xenInotifyOpen(virConnectPtr conn,
/* Build the full file path */
if (!(path = virFileBuildPath(priv->configDir, ent->d_name, NULL))) {
- virReportOOMError();
closedir(dh);
return -1;
}
diff --git a/src/xen/xm_internal.c b/src/xen/xm_internal.c
index db47a02..f9f52b5 100644
--- a/src/xen/xm_internal.c
+++ b/src/xen/xm_internal.c
@@ -388,7 +388,6 @@ int xenXMConfigCacheRefresh (virConnectPtr conn) {
/* Build the full file path */
if (!(path = virFileBuildPath(priv->configDir, ent->d_name, NULL))) {
- virReportOOMError();
closedir(dh);
return -1;
}
@@ -1134,10 +1133,8 @@ virDomainPtr xenXMDomainDefineXML(virConnectPtr conn, const char *xml)
entry = NULL;
}
- if (!(filename = virFileBuildPath(priv->configDir, def->name, NULL))) {
- virReportOOMError();
+ if (!(filename = virFileBuildPath(priv->configDir, def->name, NULL)))
goto error;
- }
if (xenXMConfigSaveFile(conn, filename, def) < 0)
goto error;
--
1.7.0.4
13 years, 8 months
[libvirt] Entering devel freeze tomorrow
by Daniel Veillard
Well I initially suggested to enter freeze the last week-end but
I had a serious backlog and let a few day pass. What I suggest is
enter freeze tomorrow morning (my time, i.e. very early) at which point
I will make a first candidate release tarball for testing. Then the
target for the actually release might be Wed 4 or Thu 5 depending on
how things turns out.
If there is patches for new features that people want in but didn't
get the ACK, please raise them again quickly today so we can try to
review them and push in time for 0.9.1, otherwise, that will be
0.9.2 in a month,
thanks !
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/
13 years, 8 months
[libvirt] [PATCH] free buf->content when vsnprintf() failed
by Wen Congyang
When buf->error is 1, we do not return buf->content in the function
virBufferContentAndReset(). So we should free buf->content when
vsnprintf() failed.
---
src/util/buf.c | 6 ++++++
1 files changed, 6 insertions(+), 0 deletions(-)
diff --git a/src/util/buf.c b/src/util/buf.c
index 7557ad1..fdb7660 100644
--- a/src/util/buf.c
+++ b/src/util/buf.c
@@ -241,6 +241,9 @@ virBufferVSprintf(const virBufferPtr buf, const char *format, ...)
size = buf->size - buf->use;
if ((count = vsnprintf(&buf->content[buf->use],
size, format, argptr)) < 0) {
+ VIR_FREE(buf->content);
+ buf->size = 0;
+ buf->use = 0;
buf->error = 1;
goto err;
}
@@ -259,6 +262,9 @@ virBufferVSprintf(const virBufferPtr buf, const char *format, ...)
size = buf->size - buf->use;
if ((count = vsnprintf(&buf->content[buf->use],
size, format, argptr)) < 0) {
+ VIR_FREE(buf->content);
+ buf->size = 0;
+ buf->use = 0;
buf->error = 1;
goto err;
}
--
1.7.1
13 years, 8 months
[libvirt] [PATCHv2 0/6] Add virNodeGetCpuTime() API
by Minoru Usui
Hi,
This is v2 of virNodeGetCpuTime() API.
It returns cpu utilization or
cumulative cpu time of the node from /proc/stat since node boots up.
This patch only supports linux host.
Changes
v1->v2
- Change user I/F like virDomainGetMemoryStats()
- It can return either cpu utilization or cumulative cpu time of the node
depends on each driver.
Minoru Usui (6):
[v2 1/6] virNodeGetCPUTime: Expose new API
[v2 2/6] virNodeGetCPUTime: Define internal driver API
[v2 3/6] virNodeGetCPUTime: Implement public API
[v2 4/6] virNodeGetCPUTime: Implement remote protocol
[v2 5/6] virNodeGetCPUTime: Implement virsh support
[v2 6/6] virNodeGetCPUTime: Implement linux support
daemon/remote.c | 48 +++++++++++++++++
daemon/remote_dispatch_args.h | 1 +
daemon/remote_dispatch_prototypes.h | 8 +++
daemon/remote_dispatch_ret.h | 1 +
daemon/remote_dispatch_table.h | 5 ++
include/libvirt/libvirt.h.in | 64 +++++++++++++++++++++++
src/driver.h | 8 +++
src/esx/esx_driver.c | 1 +
src/libvirt.c | 70 +++++++++++++++++++++++++
src/libvirt_private.syms | 1 +
src/libvirt_public.syms | 5 ++
src/libxl/libxl_driver.c | 1 +
src/lxc/lxc_driver.c | 1 +
src/nodeinfo.c | 78 ++++++++++++++++++++++++++++
src/nodeinfo.h | 5 ++-
src/openvz/openvz_driver.c | 1 +
src/phyp/phyp_driver.c | 1 +
src/qemu/qemu_driver.c | 1 +
src/remote/remote_driver.c | 38 ++++++++++++++
src/remote/remote_protocol.c | 33 ++++++++++++
src/remote/remote_protocol.h | 28 ++++++++++
src/remote/remote_protocol.x | 20 +++++++-
src/remote_protocol-structs | 14 +++++
src/test/test_driver.c | 1 +
src/uml/uml_driver.c | 1 +
src/vbox/vbox_tmpl.c | 1 +
src/vmware/vmware_driver.c | 1 +
src/xen/xen_driver.c | 1 +
src/xenapi/xenapi_driver.c | 1 +
tools/virsh.c | 96 +++++++++++++++++++++++++++++++++++
tools/virsh.pod | 4 ++
31 files changed, 537 insertions(+), 2 deletions(-)
--
Minoru Usui <usui(a)mxm.nes.nec.co.jp>
13 years, 8 months
[libvirt] [PATCH] daemon: Don't try to free an unsigned int in error paths
by Matthias Bolte
---
daemon/remote.c | 8 ++++----
1 files changed, 4 insertions(+), 4 deletions(-)
diff --git a/daemon/remote.c b/daemon/remote.c
index 54fef64..1c98bba 100644
--- a/daemon/remote.c
+++ b/daemon/remote.c
@@ -3681,7 +3681,7 @@ remoteDispatchListNetworks(struct qemud_server *server ATTRIBUTE_UNUSED,
cleanup:
if (rv < 0) {
remoteDispatchError(rerr);
- VIR_FREE(ret->names.names_len);
+ VIR_FREE(ret->names.names_val);
}
return rv;
}
@@ -4200,7 +4200,7 @@ remoteDispatchListInterfaces(struct qemud_server *server ATTRIBUTE_UNUSED,
cleanup:
if (rv < 0) {
remoteDispatchError(rerr);
- VIR_FREE(ret->names.names_len);
+ VIR_FREE(ret->names.names_val);
}
return rv;
}
@@ -4275,7 +4275,7 @@ remoteDispatchListDefinedInterfaces(struct qemud_server *server ATTRIBUTE_UNUSED
cleanup:
if (rv < 0) {
remoteDispatchError(rerr);
- VIR_FREE(ret->names.names_len);
+ VIR_FREE(ret->names.names_val);
}
return rv;
}
@@ -8544,7 +8544,7 @@ remoteDispatchListNwfilters(struct qemud_server *server ATTRIBUTE_UNUSED,
cleanup:
if (rv < 0) {
remoteDispatchError(rerr);
- VIR_FREE(ret->names.names_len);
+ VIR_FREE(ret->names.names_val);
}
return rv;
}
--
1.7.0.4
13 years, 8 months
[libvirt] [PATCH] build: use gnulib passfd for simpler SCM_RIGHTS code
by Eric Blake
* bootstrap.conf (gnulib_modules): Add passfd.
* src/util/util.c (virFileOpenAs): Simplify.
---
It's always nice to shove the maintenance burden onto gnulib.
bootstrap.conf | 1 +
src/util/util.c | 38 ++++++++------------------------------
2 files changed, 9 insertions(+), 30 deletions(-)
diff --git a/bootstrap.conf b/bootstrap.conf
index 293f86e..3b3a90f 100644
--- a/bootstrap.conf
+++ b/bootstrap.conf
@@ -52,6 +52,7 @@ mkstemps
mktempd
netdb
nonblocking
+passfd
perror
physmem
pipe-posix
diff --git a/src/util/util.c b/src/util/util.c
index d4d2610..de4e3b3 100644
--- a/src/util/util.c
+++ b/src/util/util.c
@@ -78,6 +78,7 @@
#include "files.h"
#include "command.h"
#include "nonblocking.h"
+#include "passfd.h"
#ifndef NSIG
# define NSIG 32
@@ -1480,11 +1481,6 @@ virFileOpenAs(const char *path, int openflags, mode_t mode,
int waitret, status, ret = 0;
int fd = -1;
int pair[2] = { -1, -1 };
- struct msghdr msg;
- struct cmsghdr *cmsg;
- char buf[CMSG_SPACE(sizeof(fd))];
- char dummy = 0;
- struct iovec iov;
int forkRet;
if ((!(flags & VIR_FILE_OPEN_AS_UID))
@@ -1506,18 +1502,6 @@ virFileOpenAs(const char *path, int openflags, mode_t mode,
return ret;
}
- memset(&msg, 0, sizeof(msg));
- iov.iov_base = &dummy;
- iov.iov_len = 1;
- msg.msg_iov = &iov;
- msg.msg_iovlen = 1;
- msg.msg_control = buf;
- msg.msg_controllen = sizeof(buf);
- cmsg = CMSG_FIRSTHDR(&msg);
- cmsg->cmsg_level = SOL_SOCKET;
- cmsg->cmsg_type = SCM_RIGHTS;
- cmsg->cmsg_len = CMSG_LEN(sizeof(fd));
-
forkRet = virFork(&pid);
if (pid < 0) {
@@ -1529,26 +1513,20 @@ virFileOpenAs(const char *path, int openflags, mode_t mode,
VIR_FORCE_CLOSE(pair[1]);
do {
- ret = recvmsg(pair[0], &msg, 0);
+ ret = recvfd(pair[0], 0);
} while (ret < 0 && errno == EINTR);
- if (ret < 0) {
+ if (ret < 0 && errno != EACCES) {
ret = -errno;
VIR_FORCE_CLOSE(pair[0]);
while ((waitret = waitpid(pid, NULL, 0) == -1)
&& (errno == EINTR));
goto parenterror;
+ } else {
+ fd = ret;
}
VIR_FORCE_CLOSE(pair[0]);
- /* See if fd was transferred. */
- cmsg = CMSG_FIRSTHDR(&msg);
- if (cmsg && cmsg->cmsg_len == CMSG_LEN(sizeof(fd)) &&
- cmsg->cmsg_level == SOL_SOCKET &&
- cmsg->cmsg_type == SCM_RIGHTS) {
- memcpy(&fd, CMSG_DATA(cmsg), sizeof(fd));
- }
-
/* wait for child to complete, and retrieve its exit code */
while ((waitret = waitpid(pid, &status, 0) == -1)
&& (errno == EINTR));
@@ -1557,12 +1535,14 @@ virFileOpenAs(const char *path, int openflags, mode_t mode,
virReportSystemError(errno,
_("failed to wait for child creating '%s'"),
path);
+ VIR_FORCE_CLOSE(fd);
goto parenterror;
}
if (!WIFEXITED(status) || (ret = -WEXITSTATUS(status)) == -EACCES ||
fd == -1) {
/* fall back to the simpler method, which works better in
* some cases */
+ VIR_FORCE_CLOSE(fd);
return virFileOpenAsNoFork(path, openflags, mode, uid, gid, flags);
}
if (!ret)
@@ -1627,10 +1607,9 @@ parenterror:
path, mode);
goto childerror;
}
- memcpy(CMSG_DATA(cmsg), &fd, sizeof(fd));
do {
- ret = sendmsg(pair[1], &msg, 0);
+ ret = sendfd(pair[1], fd);
} while (ret < 0 && errno == EINTR);
if (ret < 0) {
@@ -1638,7 +1617,6 @@ parenterror:
goto childerror;
}
- ret = 0;
childerror:
/* ret tracks -errno on failure, but exit value must be positive.
* If the child exits with EACCES, then the parent tries again. */
--
1.7.1
13 years, 8 months
[libvirt] libvirt and redis
by B Gordon
Is there interest in teaching libvirt to store configs in a DB? I'd
like to talk out what's desirable in the scope and design with someone
who knows libvirt.
My eventual goal is to synchronize config between multiple libvirtds
using Redis. I've been playing with a prototype that abstracts config
writing and reading into handlers that can be selected at run time or
from libvirtd.conf. This was to get me some familiarity--please tell
me what aspects I should change to suit the rest of libvirt.
The high-level, emphasizing the more questionable aspects:
* "conf drivers" that cargo-cult the jargon used in "drivers" a bit
even though they (currently) aren't quite a fit with the way current
ones are used.
* One global conf driver, because it needs to be accessed in other
state drivers when a connection is not currently present in the API.
* conf drivers present a file system-like key/value API to the rest of
libvirt to minimize disruption. They receive an XML string to store
and must be able to list the keys in a given "directory". Retrieval
is done by passing an optional callback to xml.c that it will use
instead of xmlCtxtReadFile().
* Keys should probably not include the full sysconfdir path, and
many other ways the prototype is too FS-like.
* With a relational DB, API calls to store each type of libvirt struct
might make more sense than formatted XML strings. I have not tried to
do this and vaguely hope that working with XML in a relational DB
would be acceptable or that those calls could be added later. Using
the DB's native XML handling might better for abstraction, actually.
* The conf driver needs a way to receive parameters from
libvirtd.conf. URI parsing? Some other key-value format?
As a low-level example, here's my (current, expected to change based
on feedback!) conversion of domain_conf.c:
diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
index b6aaf33..0c7bb3c 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -47,6 +47,7 @@
#include "storage_file.h"
#include "files.h"
#include "bitmap.h"
+#include "conf_driver.h"
#define VIR_FROM_THIS VIR_FROM_DOMAIN
@@ -6158,7 +6159,7 @@ virDomainDefParse(const char *xmlStr,
xmlDocPtr xml;
virDomainDefPtr def = NULL;
- if ((xml = virXMLParse(filename, xmlStr, "domain.xml"))) {
+ if ((xml = virConfParse(filename, xmlStr, "domain.xml"))) {
def = virDomainDefParseNode(caps, xml,
xmlDocGetRootElement(xml), flags);
xmlFreeDoc(xml);
}
@@ -6245,7 +6246,7 @@ virDomainObjPtr virDomainObjParseFile(virCapsPtr
caps,
xmlDocPtr xml;
virDomainObjPtr obj = NULL;
- if ((xml = virXMLParseFile(filename))) {
+ if ((xml = virConfParse(filename, NULL, filename))) {
obj = virDomainObjParseNode(caps, xml,
xmlDocGetRootElement(xml));
xmlFreeDoc(xml);
}
@@ -8324,46 +8325,26 @@ int virDomainSaveXML(const char *configDir,
const char *xml)
{
char *configFile = NULL;
- int fd = -1, ret = -1;
- size_t towrite;
+ int ret = -1;
+ int err;
if ((configFile = virDomainConfigFile(configDir, def->name)) ==
NULL)
goto cleanup;
- if (virFileMakePath(configDir)) {
- virReportSystemError(errno,
+ if ((err = virConfMakePath(configDir, 0))) {
+ virReportSystemError(err,
_("cannot create config directory '%s'"),
configDir);
goto cleanup;
}
- if ((fd = open(configFile,
- O_WRONLY | O_CREAT | O_TRUNC,
- S_IRUSR | S_IWUSR )) < 0) {
- virReportSystemError(errno,
- _("cannot create config file '%s'"),
- configFile);
- goto cleanup;
- }
-
- towrite = strlen(xml);
- if (safewrite(fd, xml, towrite) < 0) {
- virReportSystemError(errno,
- _("cannot write config file '%s'"),
- configFile);
- goto cleanup;
- }
-
- if (VIR_CLOSE(fd) < 0) {
- virReportSystemError(errno,
- _("cannot save config file '%s'"),
- configFile);
+ if (virConfSave(configFile, xml, 0) < 0) {
goto cleanup;
}
ret = 0;
+
cleanup:
- VIR_FORCE_CLOSE(fd);
VIR_FREE(configFile);
return ret;
@@ -8441,7 +8422,7 @@ static virDomainObjPtr
virDomainLoadConfig(virCapsPtr caps,
if ((autostartLink = virDomainConfigFile(autostartDir, name)) ==
NULL)
goto error;
- if ((autostart = virFileLinkPointsTo(autostartLink, configFile)) <
0)
+ if ((autostart = virConfLinkPointsTo(autostartLink, configFile, 0))
< 0)
goto error;
if (!(dom = virDomainAssignDef(caps, doms, def, false)))
@@ -8514,12 +8495,12 @@ int virDomainLoadAllConfigs(virCapsPtr caps,
virDomainLoadConfigNotify notify,
void *opaque)
{
- DIR *dir;
- struct dirent *entry;
+ virConfDirPtr dir;
+ virConfDirEntryPtr entry;
VIR_INFO("Scanning for configs in %s", configDir);
- if (!(dir = opendir(configDir))) {
+ if (!(dir = virConfOpenDir(configDir, 0))) {
if (errno == ENOENT)
return 0;
virReportSystemError(errno,
@@ -8528,23 +8509,17 @@ int virDomainLoadAllConfigs(virCapsPtr caps,
return -1;
}
- while ((entry = readdir(dir))) {
+ while ((entry = virConfReadDir(dir, 0))) {
virDomainObjPtr dom;
- if (entry->d_name[0] == '.')
- continue;
-
- if (!virFileStripSuffix(entry->d_name, ".xml"))
- continue;
-
/* NB: ignoring errors, so one malformed config doesn't
kill the whole process */
- VIR_INFO("Loading config file '%s.xml'", entry->d_name);
+ VIR_INFO("Loading config file '%s.xml'", entry->name);
if (liveStatus)
dom = virDomainLoadStatus(caps,
doms,
configDir,
- entry->d_name,
+ entry->name,
notify,
opaque);
else
@@ -8552,7 +8527,7 @@ int virDomainLoadAllConfigs(virCapsPtr caps,
doms,
configDir,
autostartDir,
- entry->d_name,
+ entry->name,
notify,
opaque);
if (dom) {
@@ -8562,7 +8537,7 @@ int virDomainLoadAllConfigs(virCapsPtr caps,
}
}
- closedir(dir);
+ virConfCloseDir(dir, 0);
return 0;
}
@@ -8580,9 +8555,9 @@ int virDomainDeleteConfig(const char *configDir,
goto cleanup;
/* Not fatal if this doesn't work */
- unlink(autostartLink);
+ virConfDeletePath(autostartLink, 0);
- if (unlink(configFile) < 0 &&
+ if (virConfDeletePath(autostartLink, 0) < 0 &&
errno != ENOENT) {
virReportSystemError(errno,
_("cannot remove config %s"),
@@ -8863,7 +8838,7 @@ virDomainSnapshotDefPtr
virDomainSnapshotDefParseString(const char *xmlStr,
char *creation = NULL, *state = NULL;
struct timeval tv;
- xml = virXMLParse(NULL, xmlStr, "domainsnapshot.xml");
+ xml = virXMLParseString(xmlStr, "domainsnapshot.xml");
if (!xml) {
virDomainReportError(VIR_ERR_XML_ERROR,
"%s",_("failed to parse snapshot xml
document"));
--
http://www.fastmail.fm - Choose from over 50 domains or use your own
13 years, 8 months