[libvirt] [PATCH v2] sanlock: Introduce 'user' and 'group' conf variables
by Michal Privoznik
through which user set under what permissions does sanlock
daemon run so libvirt will set the same permissions for
files exposed to it.
---
diff to v1:
-update spec file so sanlock dir is installed with root:sanlock
iff group sanlock exists
docs/locking.html.in | 22 +++++++++
libvirt.spec.in | 7 +++
src/locking/libvirt_sanlock.aug | 2 +
src/locking/lock_driver_sanlock.c | 76 ++++++++++++++++++++++++++++++-
src/locking/sanlock.conf | 11 ++++-
src/locking/test_libvirt_sanlock.aug.in | 2 +
6 files changed, 118 insertions(+), 2 deletions(-)
diff --git a/docs/locking.html.in b/docs/locking.html.in
index 6d7b517..19dd6a3 100644
--- a/docs/locking.html.in
+++ b/docs/locking.html.in
@@ -121,6 +121,28 @@
</pre>
<p>
+ If your sanlock daemon happen to run under non-root
+ privileges, you need to tell this to libvirt so it
+ chowns created files correctly. This can be done by
+ setting <code>user</code> and/or <code>group</code>
+ variables in the configuration file. Accepted values
+ range is specified in description to the same
+ variables in <code>/etc/libvirt/qemu.conf</code>. For
+ example:
+ </p>
+
+ <pre>
+ augtool -s set /files/etc/libvirt/qemu-sanlock.conf/user sanlock
+ augtool -s set /files/etc/libvirt/qemu-sanlock.conf/group sanlock
+ </pre>
+
+ <p>
+ But remember, that if this is NFS share, you need a
+ no_root_squash-ed one for chown (and chmod possibly)
+ to succeed.
+ </p>
+
+ <p>
In terms of storage requirements, if the filesystem
uses 512 byte sectors, you need to allow for <code>1MB</code>
of storage for each guest disk. So if you have a network
diff --git a/libvirt.spec.in b/libvirt.spec.in
index ebebfab..edc43af 100644
--- a/libvirt.spec.in
+++ b/libvirt.spec.in
@@ -1568,6 +1568,13 @@ fi
/bin/systemctl try-restart libvirt-guests.service >/dev/null 2>&1 || :
%endif
+%pre lock-sanlock
+if $(getent group sanlock > /dev/null; echo $?) == 0
+ chmod 0770 %{_localstatedir}/lib/libvirt/sanlock
+ chown root:sanlock %{_localstatedir}/lib/libvirt/sanlock
+endif
+
+
%files
%defattr(-, root, root)
diff --git a/src/locking/libvirt_sanlock.aug b/src/locking/libvirt_sanlock.aug
index d65b002..a78a444 100644
--- a/src/locking/libvirt_sanlock.aug
+++ b/src/locking/libvirt_sanlock.aug
@@ -22,6 +22,8 @@ module Libvirt_sanlock =
| int_entry "host_id"
| bool_entry "require_lease_for_disks"
| bool_entry "ignore_readonly_and_shared_disks"
+ | str_entry "user"
+ | str_entry "group"
let comment = [ label "#comment" . del /#[ \t]*/ "# " . store /([^ \t\n][^\n]*)?/ . del /\n/ "\n" ]
let empty = [ label "#empty" . eol ]
diff --git a/src/locking/lock_driver_sanlock.c b/src/locking/lock_driver_sanlock.c
index 4682701..d988a6d 100644
--- a/src/locking/lock_driver_sanlock.c
+++ b/src/locking/lock_driver_sanlock.c
@@ -71,6 +71,10 @@ struct _virLockManagerSanlockDriver {
int hostID;
bool autoDiskLease;
char *autoDiskLeasePath;
+
+ /* under which permissions does sanlock run */
+ uid_t user;
+ gid_t group;
};
static virLockManagerSanlockDriver *driver = NULL;
@@ -94,6 +98,7 @@ static int virLockManagerSanlockLoadConfig(const char *configFile)
{
virConfPtr conf;
virConfValuePtr p;
+ char *tmp;
if (access(configFile, R_OK) == -1) {
if (errno != ENOENT) {
@@ -142,6 +147,39 @@ static int virLockManagerSanlockLoadConfig(const char *configFile)
else
driver->requireLeaseForDisks = !driver->autoDiskLease;
+ p = virConfGetValue(conf, "user");
+ CHECK_TYPE("user", VIR_CONF_STRING);
+ if (p) {
+ if (!(tmp = strdup(p->str))) {
+ virReportOOMError();
+ virConfFree(conf);
+ return -1;
+ }
+
+ if (virGetUserID(tmp, &driver->user) < 0) {
+ VIR_FREE(tmp);
+ virConfFree(conf);
+ return -1;
+ }
+ VIR_FREE(tmp);
+ }
+
+ p = virConfGetValue (conf, "group");
+ CHECK_TYPE ("group", VIR_CONF_STRING);
+ if (p) {
+ if (!(tmp = strdup(p->str))) {
+ virReportOOMError();
+ virConfFree(conf);
+ return -1;
+ }
+ if (virGetGroupID(tmp, &driver->group) < 0) {
+ VIR_FREE(tmp);
+ virConfFree(conf);
+ return -1;
+ }
+ VIR_FREE(tmp);
+ }
+
virConfFree(conf);
return 0;
}
@@ -177,6 +215,7 @@ static int virLockManagerSanlockSetupLockspace(void)
* space allocated for it and is initialized with lease
*/
if (stat(path, &st) < 0) {
+ int perms = 0600;
VIR_DEBUG("Lockspace %s does not yet exist", path);
if (!(dir = mdir_name(path))) {
@@ -191,7 +230,10 @@ static int virLockManagerSanlockSetupLockspace(void)
goto error;
}
- if ((fd = open(path, O_WRONLY|O_CREAT|O_EXCL, 0600)) < 0) {
+ if (driver->group != -1)
+ perms |= 0060;
+
+ if ((fd = open(path, O_WRONLY|O_CREAT|O_EXCL, perms)) < 0) {
if (errno != EEXIST) {
virReportSystemError(errno,
_("Unable to create lockspace %s"),
@@ -200,6 +242,17 @@ static int virLockManagerSanlockSetupLockspace(void)
}
VIR_DEBUG("Someone else just created lockspace %s", path);
} else {
+ /* chown() the path to make sure sanlock can access it */
+ if ((driver->user != -1 || driver->group != -1) &&
+ (fchown(fd, driver->user, driver->group) < 0)) {
+ virReportSystemError(errno,
+ _("cannot chown '%s' to (%u, %u)"),
+ path,
+ (unsigned int) driver->user,
+ (unsigned int) driver->group);
+ goto error_unlink;
+ }
+
if ((rv = sanlock_align(&ls.host_id_disk)) < 0) {
if (rv <= -200)
virReportError(VIR_ERR_INTERNAL_ERROR,
@@ -242,6 +295,26 @@ static int virLockManagerSanlockSetupLockspace(void)
}
VIR_DEBUG("Lockspace %s has been initialized", path);
}
+ } else if (S_ISREG(st.st_mode)) {
+ /* okay, the lease file exists. Check the permissions */
+ if (((driver->user != -1 && driver->user != st.st_uid) ||
+ (driver->group != -1 && driver->group != st.st_gid)) &&
+ (chown(path, driver->user, driver->group) < 0)) {
+ virReportSystemError(errno,
+ _("cannot chown '%s' to (%u, %u)"),
+ path,
+ (unsigned int) driver->user,
+ (unsigned int) driver->group);
+ goto error;
+ }
+
+ if ((driver->group != -1 && (st.st_mode & 0060) != 0060) &&
+ chmod(path, 0660) < 0) {
+ virReportSystemError(errno,
+ _("cannot chmod '%s' to 0660"),
+ path);
+ goto error;
+ }
}
ls.host_id = driver->hostID;
@@ -299,6 +372,7 @@ static int virLockManagerSanlockInit(unsigned int version,
driver->requireLeaseForDisks = true;
driver->hostID = 0;
driver->autoDiskLease = false;
+ driver->user = driver->group = -1;
if (!(driver->autoDiskLeasePath = strdup(LOCALSTATEDIR "/lib/libvirt/sanlock"))) {
VIR_FREE(driver);
virReportOOMError();
diff --git a/src/locking/sanlock.conf b/src/locking/sanlock.conf
index efc35ee..40ece65 100644
--- a/src/locking/sanlock.conf
+++ b/src/locking/sanlock.conf
@@ -29,7 +29,8 @@
#
# Recommendation is to just mount this default location as
# an NFS volume. Uncomment this, if you would prefer the mount
-# point to be somewhere else.
+# point to be somewhere else. Moreover, please make sure
+# sanlock daemon can access the specified path.
#
#disk_lease_dir = "/var/lib/libvirt/sanlock"
@@ -52,3 +53,11 @@
# to enabled, otherwise it defaults to disabled.
#
#require_lease_for_disks = 1
+
+#
+# The combination of user and group under which the sanlock
+# daemon runs. Libvirt will chown created files (like
+# content of disk_lease_dir) to make sure sanlock daemon can
+# access them. Accepted values are described in qemu.conf.
+#user = "root"
+#group = "root"
diff --git a/src/locking/test_libvirt_sanlock.aug.in b/src/locking/test_libvirt_sanlock.aug.in
index 288f329..ef98ea6 100644
--- a/src/locking/test_libvirt_sanlock.aug.in
+++ b/src/locking/test_libvirt_sanlock.aug.in
@@ -6,3 +6,5 @@ module Test_libvirt_sanlock =
{ "disk_lease_dir" = "/var/lib/libvirt/sanlock" }
{ "host_id" = "1" }
{ "require_lease_for_disks" = "1" }
+{ "user" = "root" }
+{ "group" = "root" }
--
1.7.8.6
12 years
[libvirt] [PATCH 0/2] qemu: Fix <address/> is ignored for USB disks
by Vladislav Bogdanov
This is a follow-up to https://bugzilla.redhat.com/show_bug.cgi?id=861309
If one has USB disks configured for domain with explicit <address/>, libvirtd
ignores that node when building qemu command line. So, disk is connected to
the first free USB port implicitly by qemu.
That breaks other USB devices which have explicit <address/> - ports they
should be connected to may be already occupied by disks.
With first patch applied, if one has USB disk connected to the USB hub, qemu
fails to start, because it does not know anything about hubs yet (when parsing disks).
That's why second patch is needed.
Vladislav Bogdanov (2):
qemu: Do not ignore address for USB disks
qemu: pass -usb and usb hubs earlier, so USB disks with static
address are handled properly
12 years
[libvirt] can not create "qcow2" format volume by Java library.
by zhijun liu
hi,all,
when I use Java library to create volume ,specified format "qcow2",but when
I check it use qemu-img info ,it show format is "raw".。
I think it a bug,can you fix it .. thanks very much.
the java library version:0.4.8
libvirt version:0.9.8
12 years
[libvirt] [PATCH] esx: Fix connection to ESX 5.1
by Martin Kletzander
After separating 5.x and 5.1 versions of ESX, we forgot to add 5.1
into the list of allowed connections, so connections to 5.1 fail since
v1.0.0-rc1-5-g1e7cd39
---
src/esx/esx_driver.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/src/esx/esx_driver.c b/src/esx/esx_driver.c
index 8d13829..2aa6978 100644
--- a/src/esx/esx_driver.c
+++ b/src/esx/esx_driver.c
@@ -718,6 +718,7 @@ esxConnectToHost(virConnectPtr conn,
priv->host->productVersion != esxVI_ProductVersion_ESX41 &&
priv->host->productVersion != esxVI_ProductVersion_ESX4x &&
priv->host->productVersion != esxVI_ProductVersion_ESX50 &&
+ priv->host->productVersion != esxVI_ProductVersion_ESX51 &&
priv->host->productVersion != esxVI_ProductVersion_ESX5x) {
virReportError(VIR_ERR_INTERNAL_ERROR,
_("%s is neither an ESX 3.5, 4.x nor 5.x host"),
@@ -847,6 +848,7 @@ esxConnectToVCenter(virConnectPtr conn,
priv->vCenter->productVersion != esxVI_ProductVersion_VPX41 &&
priv->vCenter->productVersion != esxVI_ProductVersion_VPX4x &&
priv->vCenter->productVersion != esxVI_ProductVersion_VPX50 &&
+ priv->vCenter->productVersion != esxVI_ProductVersion_VPX51 &&
priv->vCenter->productVersion != esxVI_ProductVersion_VPX5x) {
virReportError(VIR_ERR_INTERNAL_ERROR,
_("%s is neither a vCenter 2.5, 4.x nor 5.x server"),
--
1.7.12.4
12 years
[libvirt] [PATCH] Added QEMU support for IVSHMEM devices
by Shawn Furrow
*Created at Virginia Tech's Systems Software Research Group
This patch adds the XML schema and implementation for IVSHMEM device driver
support. Currently it defaults to using interrupts. A sample IVSHMEM entry
in the VM's XML file is:
<ivshmem id='nahanni' size='16834' path='/tmp/'/>
---
docs/schemas/domaincommon.rng | 17 +++++
src/conf/domain_conf.c | 152 ++++++++++++++++++++++++++++++++++++++++-
src/conf/domain_conf.h | 16 ++++-
src/qemu/qemu_command.c | 75 ++++++++++++++++++++
src/qemu/qemu_command.h | 6 ++
5 files changed, 264 insertions(+), 2 deletions(-)
diff --git a/docs/schemas/domaincommon.rng b/docs/schemas/domaincommon.rng
index f47fdad..ddf8eb1 100644
--- a/docs/schemas/domaincommon.rng
+++ b/docs/schemas/domaincommon.rng
@@ -2576,6 +2576,23 @@
</optional>
</element>
</define>
+ <define name="ivshmem">
+ <element name="ivshmem">
+ <attribute name="id">
+ <ref name="deviceName">
+ </attribute>
+ <optional>
+ <attribute name="size">
+ <ref name="memoryKB">
+ </attribute>
+ </optional>
+ <optional>
+ <attribute name="path">
+ <ref name="filePath">
+ </attribute>
+ </optional>
+ </element>
+ </define>
<define name="parallel">
<element name="parallel">
<ref name="qemucdev"/>
diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
index 4aa08d0..0cd2f98 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -156,7 +156,8 @@ VIR_ENUM_IMPL(virDomainDevice, VIR_DOMAIN_DEVICE_LAST,
"redirdev",
"smartcard",
"chr",
- "memballoon")
+ "memballoon",
+ "ivshmem")
VIR_ENUM_IMPL(virDomainDeviceAddress, VIR_DOMAIN_DEVICE_ADDRESS_TYPE_LAST,
"none",
@@ -1374,6 +1375,16 @@ void virDomainMemballoonDefFree(virDomainMemballoonDefPtr def)
VIR_FREE(def);
}
+void virDomainIvshmemDefFree(virDomainIvshmemDefPtr def)
+{
+ if (!def)
+ return;
+
+ virDomainDeviceInfoClear(&def->info);
+
+ VIR_FREE(def);
+}
+
void virDomainWatchdogDefFree(virDomainWatchdogDefPtr def)
{
if (!def)
@@ -1707,6 +1718,8 @@ void virDomainDefFree(virDomainDefPtr def)
virDomainMemballoonDefFree(def->memballoon);
+ virDomainIvshmemDefFree(dev->ivshmem);
+
for (i = 0; i < def->nseclabels; i++)
virSecurityLabelDefFree(def->seclabels[i]);
VIR_FREE(def->seclabels);
@@ -2136,6 +2149,12 @@ int virDomainDeviceInfoIterate(virDomainDefPtr def,
if (cb(def, &device, &def->memballoon->info, opaque) < 0)
return -1;
}
+ if (def->ivshmem) {
+ device.type = VIR_DOMAIN_DEVICE_IVSHMEM;
+ device.data.ivshmem = def->ivshmem;
+ if (cb(def, &device, &def->ivshmem->info, opaque) < 0)
+ return -1;
+ }
device.type = VIR_DOMAIN_DEVICE_HUB;
for (i = 0; i < def->nhubs ; i++) {
device.data.hub = def->hubs[i];
@@ -6935,6 +6954,69 @@ error:
goto cleanup;
}
+static virDomainIvshmemDefPtr
+virDomainIvshmemDefParseXML(const xmlNodePtr node,
+ unsigned int flags)
+{
+ char *id = NULL;
+ char *size = NULL;
+ char *path = NULL;
+ virDomainIvshmemDefPtr def;
+
+ if (VIR_ALLOC(def) < 0) {
+ virReportOOMError();
+ return NULL;
+ }
+
+ id = virXMLPropString(node, "id");
+ VIR_DEBUG("ivshmem: id = '%s'", id);
+ virReportError(VIR_ERR_INTERNAL_ERROR,
+ _("ivshmem id=' %s'"), id);
+ if (id == NULL) {
+ virReportError(VIR_ERR_INTERNAL_ERROR,
+ _("ERROR: ivshmem, id not defined' %s'"), id);
+ goto error;
+ }
+
+ def->id = id;
+ size = virXMLPropString(node, "size");
+ virReportError(VIR_ERR_INTERNAL_ERROR,
+ _("ivshmem size=' %s'"), size);
+
+ VIR_DEBUG("ivshmem: size = '%s'", size);
+ if (size) {
+ if (virStrToLong_i(size, NULL, 10, &def->size) < 0) {
+ virReportError(VIR_ERR_INTERNAL_ERROR,
+ _("cannot parse ivshmem size %s"), size);
+ VIR_FREE(size);
+ goto error;
+ }
+ } else {
+ def->size = 16834;
+ }
+
+ path = virXMLPropString(node, "path");
+ VIR_DEBUG("ivshmem: path = '%s'", path);
+ if (path == NULL) {
+ virReportError(VIR_ERR_INTERNAL_ERROR,
+ _("ERROR: ivshmem, path not defined' %s'"), path);
+ goto error;
+ }
+ def->path = path;
+
+ if (virDomainDeviceInfoParseXML(node, NULL, &def->info, flags) < 0)
+ goto error;
+
+cleanup:
+ VIR_FREE(size);
+ return def;
+
+error:
+ virDomainIvshmemDefFree(def);
+ def = NULL;
+ goto cleanup;
+}
+
static virSysinfoDefPtr
virSysinfoParseXML(const xmlNodePtr node,
xmlXPathContextPtr ctxt)
@@ -9742,6 +9824,28 @@ static virDomainDefPtr virDomainDefParseXML(virCapsPtr caps,
}
}
+ /* analysis of the ivshmem devices */
+ def->ivshmem = NULL;
+ if ((n = virXPathNodeSet("./devices/ivshmem", ctxt, &nodes)) < 0) {
+ goto error;
+ }
+
+ if (n > 0) {
+ virDomainIvshmemDefPtr ivshmem =
+ virDomainIvshmemDefParseXML(nodes[0], flags);
+ if (!ivshmem)
+ goto error;
+
+ def->ivshmem = ivshmem;
+ VIR_FREE(nodes);
+ } else if (def->virtType != VIR_DOMAIN_VIRT_QEMU) {
+ /* TODO: currently ivshmem only on QEMU */
+ virDomainIvshmemDefPtr ivshmem;
+ if (VIR_ALLOC(ivshmem) < 0)
+ goto no_memory;
+ def->ivshmem = 0;
+ }
+
/* analysis of the hub devices */
if ((n = virXPathNodeSet("./devices/hub", ctxt, &nodes)) < 0) {
goto error;
@@ -12673,6 +12777,49 @@ virDomainMemballoonDefFormat(virBufferPtr buf,
return 0;
}
+
+static int
+virDomainIvshmemDefFormat(virBufferPtr buf,
+ virDomainIvshmemDefPtr def,
+ unsigned int flags)
+{
+ const char *id = def->id;
+ const char *path = def->path;
+
+ if (!id) {
+ virReportError(VIR_ERR_INTERNAL_ERROR,
+ _("unexpected ivshmem id = %s"), def->id);
+ return -1;
+ }
+ if (!def->size) {
+ virReportError(VIR_ERR_INTERNAL_ERROR,
+ _("unexpected ivshmem size = %d"), def->size);
+ return -1;
+ }
+
+ if (!path) {
+ virReportError(VIR_ERR_INTERNAL_ERROR,
+ _("unexpected ivshmem id = %s"), def->path);
+ return -1;
+ }
+
+ virBufferAsprintf(buf, " <ivshmem id='%s'", id);
+ virBufferAsprintf(buf, " size='%d'", def->size);
+ virBufferAsprintf(buf, " path='%s'", path);
+
+ if (virDomainDeviceInfoIsSet(&def->info, flags)) {
+ virBufferAddLit(buf, ">\n");
+ if (virDomainDeviceInfoFormat(buf, &def->info, flags) < 0)
+ return -1;
+ virBufferAddLit(buf, " </ivshmem>\n");
+ } else {
+ virBufferAddLit(buf, "/>\n");
+ }
+
+ return 0;
+}
+
+
static int
virDomainSysinfoDefFormat(virBufferPtr buf,
virSysinfoDefPtr def)
@@ -13828,6 +13975,9 @@ virDomainDefFormatInternal(virDomainDefPtr def,
if (def->memballoon)
virDomainMemballoonDefFormat(buf, def->memballoon, flags);
+ if (def->ivshmem)
+ virDomainIvshmemDefFormat(buf, def->ivshmem, flags);
+
virBufferAddLit(buf, " </devices>\n");
virBufferAdjustIndent(buf, 2);
diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h
index 1a61318..78bdf84 100644
--- a/src/conf/domain_conf.h
+++ b/src/conf/domain_conf.h
@@ -114,6 +114,9 @@ typedef virDomainSnapshotObj *virDomainSnapshotObjPtr;
typedef struct _virDomainSnapshotObjList virDomainSnapshotObjList;
typedef virDomainSnapshotObjList *virDomainSnapshotObjListPtr;
+typedef struct _virDomainIvshmemDef virDomainIvshmemDef;
+typedef virDomainIvshmemDef *virDomainIvshmemDefPtr;
+
/* Flags for the 'type' field in virDomainDeviceDef */
typedef enum {
VIR_DOMAIN_DEVICE_NONE = 0,
@@ -133,6 +136,7 @@ typedef enum {
VIR_DOMAIN_DEVICE_SMARTCARD,
VIR_DOMAIN_DEVICE_CHR,
VIR_DOMAIN_DEVICE_MEMBALLOON,
+ VIR_DOMAIN_DEVICE_IVSHMEM,
VIR_DOMAIN_DEVICE_LAST
} virDomainDeviceType;
@@ -157,7 +161,8 @@ struct _virDomainDeviceDef {
virDomainRedirdevDefPtr redirdev;
virDomainSmartcardDefPtr smartcard;
virDomainChrDefPtr chr;
- virDomainMemballoonDefPtr memballoon;
+ virDomainMemballoonDefPtr memballoon,
+ virDomainIvshmemDefPtr ivshmem;
} data;
};
@@ -1344,6 +1349,12 @@ struct _virDomainMemballoonDef {
virDomainDeviceInfo info;
};
+struct _virDomainIvshmemDef {
+ char *id;
+ int size;
+ char *path;
+ virDomainDeviceInfo info;
+};
enum virDomainSmbiosMode {
VIR_DOMAIN_SMBIOS_NONE,
@@ -1752,6 +1763,7 @@ struct _virDomainDef {
/* Only 1 */
virDomainWatchdogDefPtr watchdog;
virDomainMemballoonDefPtr memballoon;
+ virDomainIvshmemDefPtr ivshmem;
virCPUDefPtr cpu;
virSysinfoDefPtr sysinfo;
virDomainRedirFilterDefPtr redirfilter;
@@ -1859,6 +1871,7 @@ int virDomainChrSourceDefCopy(virDomainChrSourceDefPtr src,
void virDomainSoundCodecDefFree(virDomainSoundCodecDefPtr def);
void virDomainSoundDefFree(virDomainSoundDefPtr def);
void virDomainMemballoonDefFree(virDomainMemballoonDefPtr def);
+void virDomainIvshmemDefFree(virDomainIvshmemDefPtr def);
void virDomainWatchdogDefFree(virDomainWatchdogDefPtr def);
void virDomainVideoDefFree(virDomainVideoDefPtr def);
virDomainHostdevDefPtr virDomainHostdevDefAlloc(void);
@@ -2194,6 +2207,7 @@ VIR_ENUM_DECL(virDomainSoundCodec)
VIR_ENUM_DECL(virDomainSoundModel)
VIR_ENUM_DECL(virDomainMemDump)
VIR_ENUM_DECL(virDomainMemballoonModel)
+VIR_ENUM_DECL(virDomainIvshmemModel)
VIR_ENUM_DECL(virDomainSmbiosMode)
VIR_ENUM_DECL(virDomainWatchdogModel)
VIR_ENUM_DECL(virDomainWatchdogAction)
diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c
index e7bb88e..6c66075 100644
--- a/src/qemu/qemu_command.c
+++ b/src/qemu/qemu_command.c
@@ -770,6 +770,10 @@ qemuAssignDeviceAliases(virDomainDefPtr def, qemuCapsPtr caps)
if (virAsprintf(&def->memballoon->info.alias, "balloon%d", 0) < 0)
goto no_memory;
}
+ if (def->ivshmem) {
+ if (virAsprintf(&def->ivshmem->info.alias, "ivshmem%d", 0) < 0)
+ goto no_memory;
+ }
return 0;
@@ -3245,6 +3249,58 @@ error:
return NULL;
}
+//adds the options for the "-device" portion of QEMU command line for ivshmem
+char *
+qemuBuildIvshmemDevStr(virDomainIvshmemDefPtr dev,
+ qemuCapsPtr caps)
+{
+virBuffer buf = VIR_BUFFER_INITIALIZER;
+
+ virBufferAddLit(&buf, "ivshmem");
+ virBufferAsprintf(&buf, ",chardev=%s", dev->id);
+ virBufferAsprintf(&buf, ",size=%dm", dev->size/1024);
+ virBufferAsprintf(&buf, ",ioeventfd=on");
+ virBufferAsprintf(&buf, ",vectors=8");
+ //virBufferAsprintf(&buf, ",shm=%s", dev->id);
+ if (qemuBuildDeviceAddressStr(&buf, &dev->info, caps) < 0)
+ goto error;
+
+ if (virBufferError(&buf)) {
+ virReportOOMError();
+ goto error;
+ }
+
+ return virBufferContentAndReset(&buf);
+
+error:
+ virBufferFreeAndReset(&buf);
+ return NULL;
+}
+
+//adds the options for the "-chardev" portion of QEMU command line for ivshmem
+char *
+qemuBuildIvshmemCharDevStr(virDomainIvshmemDefPtr dev,
+ qemuCapsPtr caps)
+{
+virBuffer buf = VIR_BUFFER_INITIALIZER;
+
+ virBufferAddLit(&buf, "socket");
+ virBufferAsprintf(&buf, ",id=%s", dev->id);
+ virBufferAsprintf(&buf, ",path=%s%s", dev->path,dev->id);
+ if (qemuBuildDeviceAddressStr(&buf, &dev->info, caps) < 0)
+ goto error;
+
+ if (virBufferError(&buf)) {
+ virReportOOMError();
+ goto error;
+ }
+
+ return virBufferContentAndReset(&buf);
+
+error:
+ virBufferFreeAndReset(&buf);
+ return NULL;
+}
char *
qemuBuildUSBInputDevStr(virDomainInputDefPtr dev,
@@ -6582,6 +6638,25 @@ qemuBuildCommandLine(virConnectPtr conn,
}
}
+ // adds ivshmem QEMU command line entries
+ if ((def->ivshmem) && (def->ivshmem->id != NULL)) {
+ char *optstr;
+ virCommandAddArg(cmd, "-chardev");
+ optstr = qemuBuildIvshmemCharDevStr(def->ivshmem, caps);
+ if (!optstr)
+ goto error;
+ virCommandAddArg(cmd, optstr);
+
+ optstr = NULL;
+
+ virCommandAddArg(cmd, "-device");
+ optstr = qemuBuildIvshmemDevStr(def->ivshmem, caps);
+ if (!optstr)
+ goto error;
+ virCommandAddArg(cmd, optstr);
+ VIR_FREE(optstr);
+ }
+
if (snapshot)
virCommandAddArgList(cmd, "-loadvm", snapshot->def->name, NULL);
diff --git a/src/qemu/qemu_command.h b/src/qemu/qemu_command.h
index 939833d..80e7565 100644
--- a/src/qemu/qemu_command.h
+++ b/src/qemu/qemu_command.h
@@ -118,6 +118,12 @@ char * qemuBuildWatchdogDevStr(virDomainWatchdogDefPtr dev,
char * qemuBuildMemballoonDevStr(virDomainMemballoonDefPtr dev,
qemuCapsPtr caps);
+char * qemuBuildIvshmemDevStr(virDomainIvshmemDefPtr dev,
+ qemuCapsPtr caps);
+
+char * qemuBuildIvshmemCharDevStr(virDomainIvshmemDefPtr dev,
+ qemuCapsPtr caps);
+
char * qemuBuildUSBInputDevStr(virDomainInputDefPtr dev,
qemuCapsPtr caps);
--
1.7.0.4
12 years
[libvirt] [PATCH v2] helper of copy-storage-* features
by liguang
help to create disk images copy-storage-* required,
try to do non-shared migration without bothering to
create disk images at target by hand.
consider this situation:
1. non-shared migration
virsh migrate --copy-storage-all ...
2. migration fails
3. create disk images required
qemu-img create ...
4 migration run smoothly
so, try do remove step 2, 3, 4
this kind of usage had been discussed before,
http://www.redhat.com/archives/libvir-list/2011-December/msg00451.html
maybe there're some flaws:
- It did not handle more about complete situations
suggested by Daniel P. Berrange,
https://www.redhat.com/archives/libvir-list/2012-October/msg00407.html
but may try to take care of them later.
so, now only normal disk image files be handled.
- for creation of disk images, size was setting as 0xffffffff boldly,
hope it can consolidate qemu, haven't constructed a comfortable
idea to solve it.
v2:
1. handle disk encrytion case
2. check kvm-img & qemu-img
3. set disk image size to 0xfffffffK bytes blindly
Signed-off-by: liguang <lig.fnst(a)cn.fujitsu.com>
---
src/qemu/qemu_migration.c | 112 ++++++++++++++++++++++++++++++++++++++++++++-
1 files changed, 110 insertions(+), 2 deletions(-)
diff --git a/src/qemu/qemu_migration.c b/src/qemu/qemu_migration.c
index db69a0a..55eb98e 100644
--- a/src/qemu/qemu_migration.c
+++ b/src/qemu/qemu_migration.c
@@ -49,6 +49,7 @@
#include "storage_file.h"
#include "viruri.h"
#include "hooks.h"
+#include "dirname.h"
#define VIR_FROM_THIS VIR_FROM_QEMU
@@ -70,6 +71,7 @@ enum qemuMigrationCookieFlags {
QEMU_MIGRATION_COOKIE_FLAG_GRAPHICS,
QEMU_MIGRATION_COOKIE_FLAG_LOCKSTATE,
QEMU_MIGRATION_COOKIE_FLAG_PERSISTENT,
+ QEMU_MIGRATION_COOKIE_FLAG_COPYSTORAGE,
QEMU_MIGRATION_COOKIE_FLAG_LAST
};
@@ -77,12 +79,13 @@ enum qemuMigrationCookieFlags {
VIR_ENUM_DECL(qemuMigrationCookieFlag);
VIR_ENUM_IMPL(qemuMigrationCookieFlag,
QEMU_MIGRATION_COOKIE_FLAG_LAST,
- "graphics", "lockstate", "persistent");
+ "graphics", "lockstate", "persistent", "copystorage");
enum qemuMigrationCookieFeatures {
QEMU_MIGRATION_COOKIE_GRAPHICS = (1 << QEMU_MIGRATION_COOKIE_FLAG_GRAPHICS),
QEMU_MIGRATION_COOKIE_LOCKSTATE = (1 << QEMU_MIGRATION_COOKIE_FLAG_LOCKSTATE),
QEMU_MIGRATION_COOKIE_PERSISTENT = (1 << QEMU_MIGRATION_COOKIE_FLAG_PERSISTENT),
+ QEMU_MIGRATION_COOKIE_COPYSTORAGE = (1 << QEMU_MIGRATION_COOKIE_FLAG_COPYSTORAGE),
};
typedef struct _qemuMigrationCookieGraphics qemuMigrationCookieGraphics;
@@ -439,6 +442,9 @@ qemuMigrationCookieXMLFormat(struct qemud_driver *driver,
virBufferAdjustIndent(buf, -2);
}
+ if (mig->flags & QEMU_MIGRATION_COOKIE_COPYSTORAGE)
+ virBufferAsprintf(buf, " <copystorage/>\n");
+
virBufferAddLit(buf, "</qemu-migration>\n");
return 0;
}
@@ -662,6 +668,11 @@ qemuMigrationCookieXMLParse(qemuMigrationCookiePtr mig,
VIR_FREE(nodes);
}
+ if ((flags & QEMU_MIGRATION_COOKIE_COPYSTORAGE)) {
+ if (virXPathBoolean("count(./copystorage) > 0", ctxt))
+ mig->flags |= QEMU_MIGRATION_COOKIE_COPYSTORAGE;
+ }
+
return 0;
error:
@@ -721,6 +732,9 @@ qemuMigrationBakeCookie(qemuMigrationCookiePtr mig,
qemuMigrationCookieAddPersistent(mig, dom) < 0)
return -1;
+ if (flags & QEMU_MIGRATION_COOKIE_COPYSTORAGE)
+ mig->flags |= QEMU_MIGRATION_COOKIE_COPYSTORAGE;
+
if (!(*cookieout = qemuMigrationCookieXMLFormatStr(driver, mig)))
return -1;
@@ -1168,6 +1182,14 @@ char *qemuMigrationBegin(struct qemud_driver *driver,
QEMU_MIGRATION_COOKIE_LOCKSTATE) < 0)
goto cleanup;
+ if (flags & (VIR_MIGRATE_NON_SHARED_DISK |
+ VIR_MIGRATE_NON_SHARED_INC)) {
+ if (qemuMigrationBakeCookie(mig, driver, vm,
+ cookieout, cookieoutlen,
+ QEMU_MIGRATION_COOKIE_COPYSTORAGE) < 0)
+ goto cleanup;
+ }
+
if (xmlin) {
if (!(def = virDomainDefParseString(driver->caps, xmlin,
QEMU_EXPECTED_VIRT_TYPES,
@@ -1215,6 +1237,79 @@ qemuMigrationPrepareCleanup(struct qemud_driver *driver,
qemuDomainObjDiscardAsyncJob(driver, vm);
}
+/*
+ if gen_del is 1, find out disk images migration required,
+ so try to generate them at target,
+ if gen_del is 0, delete disk images generated before.
+*/
+static int qemuMigrationHandleDiskFiles(virDomainDefPtr def, int gen_del)
+{
+ char *tmp_dir = NULL, *outbuf = NULL;
+ char *size = _("0xffffffffK"), *img_tool;
+ virCommandPtr cmd = NULL;
+ int i, ret = -1;
+
+ if (!def->ndisks)
+ return 0;
+
+ img_tool = virFindFileInPath("kvm-img");
+ if (!img_tool)
+ img_tool = virFindFileInPath("qemu-img");
+ if (!img_tool) {
+ virReportError(VIR_ERR_INTERNAL_ERROR,
+ "%s", _("unable to find kvm-img or qemu-img"));
+ return -1;
+ }
+
+ for (i = 0; i < def->ndisks; i++) {
+ if (STRNEQ(def->disks[i]->driverName, "qemu"))
+ continue;
+ if (def->disks[i]->src == NULL)
+ continue;
+ if (def->disks[i]->driverType == NULL)
+ continue;
+ if (virFileExists(def->disks[i]->src) && gen_del)
+ continue;
+ if (!gen_del && !virFileExists(def->disks[i]->src))
+ continue;
+ if ((tmp_dir = mdir_name(def->disks[i]->src)) == NULL)
+ continue;
+ if (!virFileExists(tmp_dir))
+ if (virFileMakePath(tmp_dir) < 0)
+ continue;
+ if (gen_del) {
+ cmd = virCommandNewArgList(img_tool, "create", "-f",
+ def->disks[i]->driverType, def->disks[i]->src,
+ size, NULL);
+ if (def->disks[i]->encryption)
+ virCommandAddArgList(cmd, "-o", "encryption=on", NULL);
+ virCommandSetOutputBuffer(cmd, &outbuf);
+ if (virCommandRun(cmd, NULL) < 0) {
+ virReportSystemError(errno, "%s", outbuf);
+ goto cleanup;
+ }
+ } else {
+ if (unlink(def->disks[i]->src) < 0) {
+ virReportError(errno, "%s", _("fail to unlink disk image file"));
+ goto cleanup;
+ }
+ }
+ virCommandFree(cmd);
+ VIR_FREE(tmp_dir);
+ VIR_FREE(outbuf);
+ }
+
+ ret = 0;
+
+cleanup:
+ if (ret < 0) {
+ virCommandFree(cmd);
+ VIR_FREE(tmp_dir);
+ VIR_FREE(outbuf);
+ }
+ return ret;
+}
+
static int
qemuMigrationPrepareAny(struct qemud_driver *driver,
virConnectPtr dconn,
@@ -1308,6 +1403,15 @@ qemuMigrationPrepareAny(struct qemud_driver *driver,
/* virDomainAssignDef already set the error */
goto cleanup;
}
+
+ if (!(mig = qemuMigrationEatCookie(driver, vm, cookiein, cookieinlen,
+ QEMU_MIGRATION_COOKIE_COPYSTORAGE)))
+ goto cleanup;
+
+ if (mig->flags & QEMU_MIGRATION_COOKIE_COPYSTORAGE)
+ if (qemuMigrationHandleDiskFiles(def, 1) < 0)
+ goto cleanup;
+
def = NULL;
priv = vm->privateData;
priv->origname = origname;
@@ -2929,7 +3033,7 @@ qemuMigrationFinish(struct qemud_driver *driver,
int newVM = 1;
qemuMigrationCookiePtr mig = NULL;
virErrorPtr orig_err = NULL;
- int cookie_flags = 0;
+ int cookie_flags = 0, migration_status = 0;
qemuDomainObjPrivatePtr priv = vm->privateData;
VIR_DEBUG("driver=%p, dconn=%p, vm=%p, cookiein=%s, cookieinlen=%d, "
@@ -3088,7 +3192,11 @@ qemuMigrationFinish(struct qemud_driver *driver,
if (qemuMigrationBakeCookie(mig, driver, vm, cookieout, cookieoutlen, 0) < 0)
VIR_WARN("Unable to encode migration cookie");
+ migration_status = 1;
+
endjob:
+ if (!migration_status)
+ qemuMigrationHandleDiskFiles(vm->def, 0);
if (qemuMigrationJobFinish(driver, vm) == 0) {
vm = NULL;
} else if (!vm->persistent && !virDomainObjIsActive(vm)) {
--
1.7.1
12 years
[libvirt] Need help of guest lifecycle control
by Zhimou Peng
Hi,
I have a question about guest lifecycle control, many content of element not works, i don't know if i use it in a wrong way.
#virsh shutdown aaa
<on_poweroff>destroy</on_poweroff>
Domain aaa shut off and not power up again. -----> expect
<on_poweroff>restart</on_poweroff>
should power up again but not. -----> not expect
<on_poweroff>preserve</on_poweroff>
guest poweroff, nothing happend. ----> how to use it ?
<on_poweroff>rename-restart</on_poweroff>
guest poweroff, and should boot up again with newname? but it's only powered off. --->not expect
-------------------------------------------------------------------------------------
#virsh reboot aaa
<on_reboot>destroy</on_reboot>
guest not boot up again. it works.
<on_reboot>restart</on_reboot>
guest boot up again. it works.
<on_reboot>preserve</on_reboot>
guest poweroff, nothing happend. -----> how to use it ?
<on_reboot>rename-restart</on_reboot>
guest poweroff, and should boot up again with newname. but it's only powered off. --->not expect
--------------------------------------------------------------------------------------
<on_crash>xxxxxxx</on_crash> --->qemu not support this yet, right? https://bugzilla.redhat.com/show_bug.cgi?id=833530
zhpeng
BR
12 years
[libvirt] [PATCH] build: place attributes in correct location
by Eric Blake
Ever since commit eefb881, ATTRIBUTE_NONNULL has been a no-op under
gcc (since it tends to cause more bugs than it cures given gcc's
current lame implementation of the macro). However, the macro is
still useful to Coverity and other static-analysis tools, but only
if we use it correctly. Gcc (and thus Coverity) accepts function
declarations with attributes at the end, but function bodies must
attach attributes to the return type. That is, these are valid:
void foo(void *arg) ATTRIBUTE_NONNULL(1);
void ATTRIBUTE_NONNULL(1) foo(void *arg);
void ATTRIBUTE_NONNULL(1) foo(void *arg) {}
but this is not:
void foo(void *arg) ATTRIBUTE_NONNULL(1) {}
Bug introduced in commit 80533ca, with these symptoms:
nodeinfo.c:206: error: expected ',' or ';' before '{' token
cc1: warning: unrecognized command line option "-Wno-suggest-attribute=const"
cc1: warning: unrecognized command line option "-Wno-suggest-attribute=pure"
make[3]: *** [libvirt_driver_la-nodeinfo.lo] Error 1
* src/nodeinfo.c (virNodeParseNode): Fix syntax error when
non-null attribute is in use.
---
Pushing under the build-breaker rule.
src/nodeinfo.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/src/nodeinfo.c b/src/nodeinfo.c
index d8b71dd..35c5f96 100644
--- a/src/nodeinfo.c
+++ b/src/nodeinfo.c
@@ -202,9 +202,9 @@ CPU_COUNT(cpu_set_t *set)
/* parses a node entry, returning number of processors in the node and
* filling arguments */
static int
+ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2)
+ATTRIBUTE_NONNULL(3) ATTRIBUTE_NONNULL(4)
virNodeParseNode(const char *node, int *sockets, int *cores, int *threads)
- ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2)
- ATTRIBUTE_NONNULL(3) ATTRIBUTE_NONNULL(4)
{
int ret = -1;
int processors = 0;
--
1.7.11.7
12 years
[libvirt] [PATCHv2] xml: print uuids or shell-escaped names in the warning
by Ján Tomko
In the XML warning, this prints uuids for domain names with special
characters in them and shell-escaped names for other elements (like
snapshosts and networks) with special names.
---
When saving snapshots, the domain name is appended to the
"snapshot-edit" command, so using a domain name that needs escaping
would lead to something that can't be just fed to the shell as it would
glue them together.
diff to xml: shell-escape domain name in comment:
- Domain names don't get escaped, UUIDs are preferred.
- The command gets escaped too.
diff to v1: don't try to use CDATA (it doesn't belong there)
---
src/conf/domain_conf.c | 6 +++-
src/libvirt_private.syms | 2 +
src/qemu/qemu_domain.c | 3 +-
src/util/buf.c | 66 ++++++++++++++++++++++++++++++++++++++++++++++
src/util/buf.h | 1 +
src/util/xml.c | 62 ++++++++++++++++++++++---------------------
src/util/xml.h | 1 +
7 files changed, 109 insertions(+), 32 deletions(-)
diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
index 0933c08..a8cadeb 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -14252,6 +14252,7 @@ int virDomainSaveXML(const char *configDir,
virDomainDefPtr def,
const char *xml)
{
+ char uuidstr[VIR_UUID_STRING_BUFLEN];
char *configFile = NULL;
int ret = -1;
@@ -14265,7 +14266,10 @@ int virDomainSaveXML(const char *configDir,
goto cleanup;
}
- ret = virXMLSaveFile(configFile, def->name, "edit", xml);
+ virUUIDFormat(def->uuid, uuidstr);
+ ret = virXMLSaveFile(configFile,
+ virXMLPickShellSafeComment(def->name,uuidstr), "edit",
+ xml);
cleanup:
VIR_FREE(configFile);
diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
index 699c9a3..b17ef88 100644
--- a/src/libvirt_private.syms
+++ b/src/libvirt_private.syms
@@ -37,6 +37,7 @@ virBufferError;
virBufferEscape;
virBufferEscapeSexpr;
virBufferEscapeShell;
+virBufferEscapeShellXMLComment;
virBufferEscapeString;
virBufferFreeAndReset;
virBufferGetIndent;
@@ -1816,6 +1817,7 @@ virURIParse;
# xml.h
virXMLChildElementCount;
virXMLParseHelper;
+virXMLPickShellSafeComment;
virXMLPropString;
virXMLSaveFile;
virXPathBoolean;
diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c
index 4e6a5e9..e4ef7e6 100644
--- a/src/qemu/qemu_domain.c
+++ b/src/qemu/qemu_domain.c
@@ -1622,7 +1622,8 @@ qemuDomainSnapshotWriteMetadata(virDomainObjPtr vm,
goto cleanup;
}
- if (virAsprintf(&tmp, "snapshot-edit %s", vm->def->name) < 0) {
+ if (virAsprintf(&tmp, "snapshot-edit %s",
+ virXMLPickShellSafeComment(vm->def->name, uuidstr)) < 0) {
virReportOOMError();
goto cleanup;
}
diff --git a/src/util/buf.c b/src/util/buf.c
index 030dc97..a326465 100644
--- a/src/util/buf.c
+++ b/src/util/buf.c
@@ -623,6 +623,72 @@ virBufferEscapeShell(virBufferPtr buf, const char *str)
}
/**
+ * virBufferEscapeShellXMLComment:
+ * @buf: the buffer to append to
+ * @str: an unquoted string
+ *
+ * Quotes a string so that the shell (/bin/sh) will interpret the
+ * quoted string to mean str. Auto indentation may be applied.
+ * It also escapes any "--" so that the string can be used in XML comments.
+ */
+void virBufferEscapeShellXMLComment(virBufferPtr buf, const char *str)
+{
+ int len;
+ char *escaped, *out;
+ const char *cur;
+ char prev = '\0';
+
+ if ((buf == NULL) || (str == NULL))
+ return;
+
+ if (buf->error)
+ return;
+
+ /* Only quote if str includes shell metacharacters. */
+ if (*str && !strpbrk(str, "\r\t\n !\"#$&'()*;<>?[\\]^`{|}~") &&
+ !strstr(str, "--")) {
+ virBufferAdd(buf, str, -1);
+ return;
+ }
+
+ if (*str) {
+ len = strlen(str);
+ if (xalloc_oversized(4, len) ||
+ VIR_ALLOC_N(escaped, 4 * len + 3) < 0) {
+ virBufferSetError(buf, errno);
+ return;
+ }
+ } else {
+ virBufferAddChar(buf, '\'');
+ return;
+ }
+
+ cur = str;
+ out = escaped;
+
+ *out++ = '\'';
+ while (*cur != 0) {
+ if (*cur == '\'') {
+ *out++ = '\'';
+ /* Replace literal ' with a close ', a \', and a open ' */
+ *out++ = '\\';
+ *out++ = '\'';
+ } else if (prev == '-' && *cur == '-') {
+ /* Replace -- with -''- */
+ *out++ = '\'';
+ *out++ = '\'';
+ }
+ prev = *cur;
+ *out++ = *cur++;
+ }
+ *out++ = '\'';
+ *out = 0;
+
+ virBufferAdd(buf, escaped, -1);
+ VIR_FREE(escaped);
+}
+
+/**
* virBufferStrcat:
* @buf: the buffer to append to
* @...: the variable list of strings, the last argument must be NULL
diff --git a/src/util/buf.h b/src/util/buf.h
index c3a498d..25e31fd 100644
--- a/src/util/buf.h
+++ b/src/util/buf.h
@@ -69,6 +69,7 @@ void virBufferEscapeString(virBufferPtr buf, const char *format,
void virBufferEscapeSexpr(virBufferPtr buf, const char *format,
const char *str);
void virBufferEscapeShell(virBufferPtr buf, const char *str);
+void virBufferEscapeShellXMLComment(virBufferPtr buf, const char *str);
void virBufferURIEncodeString(virBufferPtr buf, const char *str);
# define virBufferAddLit(buf_, literal_string_) \
diff --git a/src/util/xml.c b/src/util/xml.c
index f3dc256..01507a9 100644
--- a/src/util/xml.c
+++ b/src/util/xml.c
@@ -780,49 +780,51 @@ error:
goto cleanup;
}
+const char *virXMLPickShellSafeComment(const char *str1, const char *str2)
+{
+ if(str1 && !strpbrk(str1, "\r\t\n !\"#$&'()*;<>?[\\]^`{|}~") &&
+ !strstr(str1, "--"))
+ return str1;
+ if(str2 && !strpbrk(str2, "\r\t\n !\"#$&'()*;<>?[\\]^`{|}~") &&
+ !strstr(str2, "--"))
+ return str2;
+ return NULL;
+}
static int virXMLEmitWarning(int fd,
const char *name,
const char *cmd)
{
+ virBuffer buf = VIR_BUFFER_INITIALIZER;
+ char *str = NULL;
size_t len;
- const char *prologue = "<!--\n\
-WARNING: THIS IS AN AUTO-GENERATED FILE. CHANGES TO IT ARE LIKELY TO BE \n\
-OVERWRITTEN AND LOST. Changes to this xml configuration should be made using:\n\
- virsh ";
- const char *epilogue = "\n\
-or other application using the libvirt API.\n\
--->\n\n";
if (fd < 0 || !name || !cmd) {
errno = EINVAL;
return -1;
}
- len = strlen(prologue);
- if (safewrite(fd, prologue, len) != len)
- return -1;
-
- len = strlen(cmd);
- if (safewrite(fd, cmd, len) != len)
- return -1;
-
- /* Omit the domain name if it contains a double hyphen
- * because they aren't allowed in XML comments */
- if (!strstr(name, "--")) {
- if (safewrite(fd, " ", 1) != 1)
- return -1;
-
- len = strlen(name);
- if (safewrite(fd, name, len) != len)
- return -1;
- }
-
- len = strlen(epilogue);
- if (safewrite(fd, epilogue, len) != len)
- return -1;
+ virBufferAddLit(&buf, "<!--\n"
+"WARNING: THIS IS AN AUTO-GENERATED FILE. CHANGES TO IT ARE LIKELY TO BE\n"
+"OVERWRITTEN AND LOST. Changes to this xml configuration should be made using:\n"
+" virsh ");
+ virBufferEscapeShellXMLComment(&buf, cmd);
+ virBufferAddChar(&buf,' ');
+ virBufferEscapeShellXMLComment(&buf, name);
+ virBufferAddLit(&buf, "\n"
+"or other application using the libvirt API.\n"
+"-->\n\n");
+
+ str = virBufferContentAndReset(&buf);
+ len = strlen(str);
+ if (str)
+ if (safewrite(fd, str, len) == len) {
+ VIR_FREE(str);
+ return 0;
+ }
- return 0;
+ VIR_FREE(str);
+ return -1;
}
diff --git a/src/util/xml.h b/src/util/xml.h
index a3750fa..c3b05df 100644
--- a/src/util/xml.h
+++ b/src/util/xml.h
@@ -61,6 +61,7 @@ xmlDocPtr virXMLParseHelper(int domcode,
const char *url,
xmlXPathContextPtr *pctxt);
+const char *virXMLPickShellSafeComment(const char *str1, const char *str2);
/**
* virXMLParse:
* @filename: file to parse, or NULL for string parsing
--
1.7.8.6
12 years
[libvirt] [PATCH] build: fix linking with systemtap probes
by Eric Blake
Commit 34e8f63a3 altered virfile.o to drag in additional symbols,
which in turn led to pulling in other .o files and eventually causing
a link failure when systemtap probes are enabled, such as:
./.libs/libvirt_util.a(libvirt_util_la-event_poll.o): In function `virEventPollRunOnce':
/home/dummy/libvirt/src/util/event_poll.c:614: undefined reference to `libvirt_event_poll_run_semaphore'
./.libs/libvirt_util.a(libvirt_util_la-event_poll.o):(.note.stapsdt+0x24): undefined reference to `libvirt_event_poll_add_handle_semaphore'
Even though libvirt_iohelper and libvirt_parthelper don't directly
use the portion of virfile.o that drags in probing, it was easier
to satisfy the linker and get the build back up, than to figure out
whether it is even possible or worth trying to disentangle the mess.
* src/Makefile.am (libvirt_iohelper_LDADD)
(libvirt_parthelper_LDADD): Use libvirt_probes.lo when needed.
---
Pushing under the build-breaker rule, in response to:
https://www.redhat.com/archives/libvir-list/2012-October/msg01679.html
src/Makefile.am | 6 ++++++
1 file changed, 6 insertions(+)
diff --git a/src/Makefile.am b/src/Makefile.am
index 187663f..1f32263 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -1631,6 +1631,9 @@ libvirt_iohelper_LDFLAGS = $(WARN_LDFLAGS) $(AM_LDFLAGS)
libvirt_iohelper_LDADD = \
libvirt_util.la \
../gnulib/lib/libgnu.la
+if WITH_DTRACE_PROBES
+libvirt_iohelper_LDADD += libvirt_probes.lo
+endif
libvirt_iohelper_CFLAGS = $(AM_CFLAGS)
endif
@@ -1645,6 +1648,9 @@ libvirt_parthelper_LDADD = \
$(LIBPARTED_LIBS) \
libvirt_util.la \
../gnulib/lib/libgnu.la
+if WITH_DTRACE_PROBES
+libvirt_parthelper_LDADD += libvirt_probes.lo
+endif
libvirt_parthelper_CFLAGS = $(LIBPARTED_CFLAGS) $(AM_CFLAGS)
endif
--
1.7.11.7
12 years