[libvirt] [PATCH] qemu: add bootindex for usb-host and usb-redir devices
by Ján Tomko
Allow bootindex to be specified for redirected USB devices and host USB
devices.
Bug: https://bugzilla.redhat.com/show_bug.cgi?id=805414
---
Bootindex for these devices is supported since QEMU 1.1.0 (or commit 65bb3a5c)
but the actual booting from usb-host devices is broken since a844ed84
(before 1.2.0).
I haven't tested it with usb-redir yet.
---
docs/schemas/domaincommon.rng | 3 +++
src/conf/domain_conf.h | 4 ++--
src/qemu/qemu_capabilities.c | 10 ++++++++++
src/qemu/qemu_capabilities.h | 2 ++
src/qemu/qemu_command.c | 37 ++++++++++++++++++++++++++++++-------
5 files changed, 47 insertions(+), 9 deletions(-)
diff --git a/docs/schemas/domaincommon.rng b/docs/schemas/domaincommon.rng
index 2beb035..02ad477 100644
--- a/docs/schemas/domaincommon.rng
+++ b/docs/schemas/domaincommon.rng
@@ -2779,6 +2779,9 @@
<optional>
<ref name="address"/>
</optional>
+ <optional>
+ <ref name="deviceBoot"/>
+ </optional>
</element>
</define>
<define name="redirfilter">
diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h
index 6539281..091879e 100644
--- a/src/conf/domain_conf.h
+++ b/src/conf/domain_conf.h
@@ -279,8 +279,8 @@ struct _virDomainDeviceInfo {
* devices. */
int rombar; /* enum virDomainPciRombarMode */
char *romfile;
- /* bootIndex is only user for disk, network interface, and
- * hostdev devices. */
+ /* bootIndex is only used for disk, network interface, hostdev
+ * and redirdev devices */
int bootIndex;
};
diff --git a/src/qemu/qemu_capabilities.c b/src/qemu/qemu_capabilities.c
index 5ce93f2..6ce2638 100644
--- a/src/qemu/qemu_capabilities.c
+++ b/src/qemu/qemu_capabilities.c
@@ -191,6 +191,8 @@ VIR_ENUM_IMPL(qemuCaps, QEMU_CAPS_LAST,
"vnc",
"drive-mirror", /* 115 */
+ "usb-redir.bootindex",
+ "usb-host.bootindex",
);
struct _qemuCaps {
@@ -1325,6 +1327,11 @@ static struct qemuCapsStringFlags qemuCapsObjectPropsPixx4PM[] = {
static struct qemuCapsStringFlags qemuCapsObjectPropsUsbRedir[] = {
{ "filter", QEMU_CAPS_USB_REDIR_FILTER },
+ { "bootindex", QEMU_CAPS_USB_REDIR_BOOTINDEX },
+};
+
+static struct qemuCapsStringFlags qemuCapsObjectPropsUsbHost[] = {
+ { "bootindex", QEMU_CAPS_USB_HOST_BOOTINDEX },
};
struct qemuCapsObjectTypeProps {
@@ -1350,6 +1357,8 @@ static struct qemuCapsObjectTypeProps qemuCapsObjectProps[] = {
ARRAY_CARDINALITY(qemuCapsObjectPropsPixx4PM) },
{ "usb-redir", qemuCapsObjectPropsUsbRedir,
ARRAY_CARDINALITY(qemuCapsObjectPropsUsbRedir) },
+ { "usb-host", qemuCapsObjectPropsUsbHost,
+ ARRAY_CARDINALITY(qemuCapsObjectPropsUsbHost) },
};
@@ -1545,6 +1554,7 @@ qemuCapsExtractDeviceStr(const char *qemu,
"-device", "PIIX4_PM,?",
"-device", "usb-redir,?",
"-device", "ide-drive,?",
+ "-device", "usb-host,?",
NULL);
/* qemu -help goes to stdout, but qemu -device ? goes to stderr. */
virCommandSetErrorBuffer(cmd, &output);
diff --git a/src/qemu/qemu_capabilities.h b/src/qemu/qemu_capabilities.h
index fb88aa1..751b3ec 100644
--- a/src/qemu/qemu_capabilities.h
+++ b/src/qemu/qemu_capabilities.h
@@ -153,6 +153,8 @@ enum qemuCapsFlags {
QEMU_CAPS_BLOCK_COMMIT = 113, /* block-commit */
QEMU_CAPS_VNC = 114, /* Is -vnc available? */
QEMU_CAPS_DRIVE_MIRROR = 115, /* drive-mirror monitor command */
+ QEMU_CAPS_USB_REDIR_BOOTINDEX = 116, /* usb-redir.bootindex */
+ QEMU_CAPS_USB_HOST_BOOTINDEX = 117, /* usb-host.bootindex */
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 440fd62..93079f3 100644
--- a/src/qemu/qemu_command.c
+++ b/src/qemu/qemu_command.c
@@ -3504,6 +3504,16 @@ qemuBuildRedirdevDevStr(virDomainDefPtr def,
}
}
+ if (dev->info.bootIndex) {
+ if (!qemuCapsGet(caps, QEMU_CAPS_USB_REDIR_BOOTINDEX)) {
+ virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
+ _("USB redirection booting is not "
+ "supported by this version of QEMU"));
+ goto error;
+ }
+ virBufferAsprintf(&buf, ",bootindex=%d", dev->info.bootIndex);
+ }
+
if (qemuBuildDeviceAddressStr(&buf, &dev->info, caps) < 0)
goto error;
@@ -3540,6 +3550,8 @@ qemuBuildUSBHostdevDevStr(virDomainHostdevDefPtr dev,
dev->source.subsys.u.usb.device);
}
virBufferAsprintf(&buf, ",id=%s", dev->info->alias);
+ if (dev->info->bootIndex)
+ virBufferAsprintf(&buf, ",bootindex=%d", dev->info->bootIndex);
if (qemuBuildDeviceAddressStr(&buf, dev->info, caps) < 0)
goto error;
@@ -6439,16 +6451,27 @@ qemuBuildCommandLine(virConnectPtr conn,
if (hostdev->info->bootIndex) {
if (hostdev->mode != VIR_DOMAIN_HOSTDEV_MODE_SUBSYS ||
- hostdev->source.subsys.type != VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_PCI) {
+ (hostdev->source.subsys.type != VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_PCI &&
+ hostdev->source.subsys.type != VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_USB)) {
virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
_("booting from assigned devices is only"
- " supported for PCI devices"));
- goto error;
- } else if (!qemuCapsGet(caps, QEMU_CAPS_PCI_BOOTINDEX)) {
- virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
- _("booting from assigned PCI devices is not"
- " supported with this version of qemu"));
+ " supported for PCI and USB devices"));
goto error;
+ } else {
+ if (hostdev->source.subsys.type == VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_PCI &&
+ !qemuCapsGet(caps, QEMU_CAPS_PCI_BOOTINDEX)) {
+ virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
+ _("booting from assigned PCI devices is not"
+ " supported with this version of qemu"));
+ goto error;
+ }
+ if (hostdev->source.subsys.type == VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_USB &&
+ !qemuCapsGet(caps, QEMU_CAPS_USB_HOST_BOOTINDEX)) {
+ virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
+ _("booting from assigned USB devices is not"
+ " supported with this version of qemu"));
+ goto error;
+ }
}
}
--
1.7.8.6
12 years, 6 months
[libvirt] RFC: xml-snapshot-data out-of-sync to .qcow2 data
by Philipp Hahn
Hello Eric, hello List,
As QEMU stores the snapshot data inside the qcow2 files, modifing them
directly might bring libvirts snapshot data out-of-sync. In my case a user
replaced a qcow2 with a new file re-using the old name. libvirt still thinks
that the snapshots are valid, while in reality the data is missing:
> # virsh snapshot-revert snap-test foo
> error: internal error Child process (/usr/bin/qemu-img snapshot -a
foo /var/lib/libvirt/images/snap-test.qcow2) status unexpected: exit status 1
What would fix this scenario would be a validation mechanism within libvirt,
which walks all snapshots and checks, if each referenced qcow2 file actually
has the required snaphot data and mark the snapshot as invalid otherwise.
This would require an addition to the xml data to add such a flag.
Or I could tell my users again not to re-use names still used by older
snapshots, but that doesn't work as you see ;-)
Comments?
Sincerely
Philipp
--
Philipp Hahn Open Source Software Engineer hahn(a)univention.de
Univention GmbH be open. fon: +49 421 22 232- 0
Mary-Somerville-Str.1 D-28359 Bremen fax: +49 421 22 232-99
http://www.univention.de/
12 years, 6 months
[libvirt] [PATCH] virsh: fix uninitialized variable in cmdSnapshotEdit
by Ján Tomko
If the domain can't be looked up, name is used unitialized after the
cleanup label.
Found by coverity.
---
tools/virsh-snapshot.c | 4 ++--
1 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/tools/virsh-snapshot.c b/tools/virsh-snapshot.c
index 4281109..0bd9583 100644
--- a/tools/virsh-snapshot.c
+++ b/tools/virsh-snapshot.c
@@ -459,7 +459,7 @@ cmdSnapshotEdit(vshControl *ctl, const vshCmd *cmd)
virDomainPtr dom = NULL;
virDomainSnapshotPtr snapshot = NULL;
virDomainSnapshotPtr edited = NULL;
- const char *name;
+ const char *name = NULL;
const char *edited_name;
bool ret = false;
unsigned int getxml_flags = VIR_DOMAIN_XML_SECURE;
@@ -532,7 +532,7 @@ cmdSnapshotEdit(vshControl *ctl, const vshCmd *cmd)
ret = true;
cleanup:
- if (!ret)
+ if (!ret && name)
vshError(ctl, _("Failed to update %s"), name);
if (edited)
virDomainSnapshotFree(edited);
--
1.7.8.6
12 years, 6 months
[libvirt] [PATCH v3] qemu: Allow the user to specify vendor and product for disk
by Osier Yang
QEMU supports setting vendor and product strings for disk since
1.2.0 (only scsi-disk, scsi-hd, scsi-cd support it), this patch
exposes it with new XML elements <vendor> and <product> of disk
device.
---
docs/formatdomain.html.in | 12 +++++
docs/schemas/domaincommon.rng | 14 ++++++
src/conf/domain_conf.c | 44 ++++++++++++++++++++
src/conf/domain_conf.h | 2 +
src/libvirt_private.syms | 1 +
src/qemu/qemu_command.c | 29 +++++++++++++
src/util/util.c | 12 +++++
src/util/util.h | 2 +
...qemuxml2argv-disk-scsi-disk-vpd-build-error.xml | 35 ++++++++++++++++
.../qemuxml2argv-disk-scsi-disk-vpd.args | 13 ++++++
.../qemuxml2argv-disk-scsi-disk-vpd.xml | 38 +++++++++++++++++
tests/qemuxml2argvtest.c | 8 ++++
tests/qemuxml2xmltest.c | 2 +
13 files changed, 212 insertions(+), 0 deletions(-)
create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-disk-scsi-disk-vpd-build-error.xml
create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-disk-scsi-disk-vpd.args
create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-disk-scsi-disk-vpd.xml
diff --git a/docs/formatdomain.html.in b/docs/formatdomain.html.in
index c8da33d..a5a7418 100644
--- a/docs/formatdomain.html.in
+++ b/docs/formatdomain.html.in
@@ -1657,6 +1657,18 @@
of 16 hexadecimal digits.
<span class='since'>Since 0.10.1</span>
</dd>
+ <dt><code>vendor</code></dt>
+ <dd>If present, this element specifies the vendor of a virtual hard
+ disk or CD-ROM device. It must not be longer than 8 alphanumeric
+ characters.
+ <span class='since'>Since 1.0.1</span>
+ </dd>
+ <dt><code>product</code></dt>
+ <dd>If present, this element specifies the product of a virtual hard
+ disk or CD-ROM device. It must not be longer than 16 alphanumeric
+ characters.
+ <span class='since'>Since 1.0.1</span>
+ </dd>
<dt><code>host</code></dt>
<dd>The <code>host</code> element has two attributes "name" and "port",
which specify the hostname and the port number. The meaning of this
diff --git a/docs/schemas/domaincommon.rng b/docs/schemas/domaincommon.rng
index 02ad477..fe8158b 100644
--- a/docs/schemas/domaincommon.rng
+++ b/docs/schemas/domaincommon.rng
@@ -905,6 +905,20 @@
<ref name="wwn"/>
</element>
</optional>
+ <optional>
+ <element name="vendor">
+ <data type='string'>
+ <param name='pattern'>[a-zA-Z0-9]{0,8}</param>
+ </data>
+ </element>
+ </optional>
+ <optional>
+ <element name="product">
+ <data type='string'>
+ <param name='pattern'>[a-zA-Z0-9]{0,16}</param>
+ </data>
+ </element>
+ </optional>
</interleave>
</define>
<define name="snapshot">
diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
index 99f03a9..702758f 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -979,6 +979,8 @@ void virDomainDiskDefFree(virDomainDiskDefPtr def)
VIR_FREE(def->mirror);
VIR_FREE(def->auth.username);
VIR_FREE(def->wwn);
+ VIR_FREE(def->vendor);
+ VIR_FREE(def->product);
if (def->auth.secretType == VIR_DOMAIN_DISK_SECRET_TYPE_USAGE)
VIR_FREE(def->auth.secret.usage);
virStorageEncryptionFree(def->encryption);
@@ -3498,6 +3500,8 @@ cleanup:
goto cleanup;
}
+#define VENDOR_LEN 8
+#define PRODUCT_LEN 16
/* Parse the XML definition for a disk
* @param node XML nodeset to parse for disk definition
@@ -3550,6 +3554,8 @@ virDomainDiskDefParseXML(virCapsPtr caps,
char *logical_block_size = NULL;
char *physical_block_size = NULL;
char *wwn = NULL;
+ char *vendor = NULL;
+ char *product = NULL;
if (VIR_ALLOC(def) < 0) {
virReportOOMError();
@@ -3888,6 +3894,36 @@ virDomainDiskDefParseXML(virCapsPtr caps,
if (!virValidateWWN(wwn))
goto error;
+ } else if (!vendor &&
+ xmlStrEqual(cur->name, BAD_CAST "vendor")) {
+ vendor = (char *)xmlNodeGetContent(cur);
+
+ if (strlen(vendor) > VENDOR_LEN) {
+ virReportError(VIR_ERR_XML_ERROR, "%s",
+ _("disk vendor is more than 8 characters"));
+ goto error;
+ }
+
+ if (!virStrIsAlnum(vendor)) {
+ virReportError(VIR_ERR_XML_ERROR, "%s",
+ _("disk vendor is not alphanumeric string"));
+ goto error;
+ }
+ } else if (!product &&
+ xmlStrEqual(cur->name, BAD_CAST "product")) {
+ product = (char *)xmlNodeGetContent(cur);
+
+ if (strlen(vendor) > PRODUCT_LEN) {
+ virReportError(VIR_ERR_XML_ERROR, "%s",
+ _("disk product is more than 16 characters"));
+ goto error;
+ }
+
+ if (!virStrIsAlnum(product)) {
+ virReportError(VIR_ERR_XML_ERROR, "%s",
+ _("disk product is not alphanumeric string"));
+ goto error;
+ }
} else if (xmlStrEqual(cur->name, BAD_CAST "boot")) {
/* boot is parsed as part of virDomainDeviceInfoParseXML */
}
@@ -4184,6 +4220,10 @@ virDomainDiskDefParseXML(virCapsPtr caps,
serial = NULL;
def->wwn = wwn;
wwn = NULL;
+ def->vendor = vendor;
+ vendor = NULL;
+ def->product = product;
+ product = NULL;
if (driverType) {
def->format = virStorageFileFormatTypeFromString(driverType);
@@ -4257,6 +4297,8 @@ cleanup:
VIR_FREE(logical_block_size);
VIR_FREE(physical_block_size);
VIR_FREE(wwn);
+ VIR_FREE(vendor);
+ VIR_FREE(product);
ctxt->node = save_ctxt;
return def;
@@ -12094,6 +12136,8 @@ virDomainDiskDefFormat(virBufferPtr buf,
virBufferAddLit(buf, " <transient/>\n");
virBufferEscapeString(buf, " <serial>%s</serial>\n", def->serial);
virBufferEscapeString(buf, " <wwn>%s</wwn>\n", def->wwn);
+ virBufferEscapeString(buf, " <vendor>%s</vendor>\n", def->vendor);
+ virBufferEscapeString(buf, " <product>%s</product>\n", def->product);
if (def->encryption) {
virBufferAdjustIndent(buf, 6);
if (virStorageEncryptionFormat(buf, def->encryption) < 0)
diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h
index 091879e..51609ba 100644
--- a/src/conf/domain_conf.h
+++ b/src/conf/domain_conf.h
@@ -591,6 +591,8 @@ struct _virDomainDiskDef {
char *serial;
char *wwn;
+ char *vendor;
+ char *product;
int cachemode;
int error_policy; /* enum virDomainDiskErrorPolicy */
int rerror_policy; /* enum virDomainDiskErrorPolicy */
diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
index 5a07139..02e30a8 100644
--- a/src/libvirt_private.syms
+++ b/src/libvirt_private.syms
@@ -1279,6 +1279,7 @@ virSetUIDGID;
virSkipSpaces;
virSkipSpacesAndBackslash;
virSkipSpacesBackwards;
+virStrIsAlnum;
virStrToDouble;
virStrToLong_i;
virStrToLong_l;
diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c
index 22bb209..7a249d4 100644
--- a/src/qemu/qemu_command.c
+++ b/src/qemu/qemu_command.c
@@ -2428,6 +2428,13 @@ qemuBuildDriveDevStr(virDomainDefPtr def,
}
}
+ if ((disk->vendor || disk->product) &&
+ disk->bus != VIR_DOMAIN_DISK_BUS_SCSI) {
+ virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
+ _("Only scsi disk supports vendor and product"));
+ goto error;
+ }
+
if (disk->device == VIR_DOMAIN_DISK_DEVICE_LUN) {
/* make sure that both the bus and the qemu binary support
* type='lun' (SG_IO).
@@ -2455,6 +2462,11 @@ qemuBuildDriveDevStr(virDomainDefPtr def,
_("Setting wwn is not supported for lun device"));
goto error;
}
+ if (disk->vendor || disk->product) {
+ virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
+ _("Setting vendor or product is not supported for lun device"));
+ goto error;
+ }
}
switch (disk->bus) {
@@ -2504,6 +2516,17 @@ qemuBuildDriveDevStr(virDomainDefPtr def,
goto error;
}
+ /* Properties wwn, vendor and product were introduced in the
+ * same QEMU release (1.2.0).
+ */
+ if ((disk->vendor || disk->product) &&
+ !qemuCapsGet(caps, QEMU_CAPS_SCSI_DISK_WWN)) {
+ virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
+ _("Setting vendor or product for scsi disk is not "
+ "supported by this QEMU"));
+ goto error;
+ }
+
controllerModel =
virDomainDiskFindControllerModel(def, disk,
VIR_DOMAIN_CONTROLLER_TYPE_SCSI);
@@ -2649,6 +2672,12 @@ qemuBuildDriveDevStr(virDomainDefPtr def,
if (disk->wwn)
virBufferAsprintf(&opt, ",wwn=%s", disk->wwn);
+ if (disk->vendor)
+ virBufferAsprintf(&opt, ",vendor=%s", disk->vendor);
+
+ if (disk->product)
+ virBufferAsprintf(&opt, ",product=%s", disk->product);
+
if (virBufferError(&opt)) {
virReportOOMError();
goto error;
diff --git a/src/util/util.c b/src/util/util.c
index 75b18c1..73f06ec 100644
--- a/src/util/util.c
+++ b/src/util/util.c
@@ -3114,3 +3114,15 @@ virValidateWWN(const char *wwn) {
return true;
}
+
+bool
+virStrIsAlnum(const char *str)
+{
+ int i;
+
+ for (i = 0; str[i]; i++)
+ if (!c_isalnum(str[i]))
+ return false;
+
+ return true;
+}
diff --git a/src/util/util.h b/src/util/util.h
index 4316ab1..ae1fa9e 100644
--- a/src/util/util.h
+++ b/src/util/util.h
@@ -280,4 +280,6 @@ bool virIsDevMapperDevice(const char *dev_name) ATTRIBUTE_NONNULL(1);
bool virValidateWWN(const char *wwn);
+bool virStrIsAlnum(const char *str);
+
#endif /* __VIR_UTIL_H__ */
diff --git a/tests/qemuxml2argvdata/qemuxml2argv-disk-scsi-disk-vpd-build-error.xml b/tests/qemuxml2argvdata/qemuxml2argv-disk-scsi-disk-vpd-build-error.xml
new file mode 100644
index 0000000..ca68275
--- /dev/null
+++ b/tests/qemuxml2argvdata/qemuxml2argv-disk-scsi-disk-vpd-build-error.xml
@@ -0,0 +1,35 @@
+<domain type='qemu'>
+ <name>QEMUGuest1</name>
+ <uuid>c7a5fdbd-edaf-9455-926a-d65c16db1809</uuid>
+ <memory unit='KiB'>219136</memory>
+ <currentMemory unit='KiB'>219136</currentMemory>
+ <vcpu placement='static'>1</vcpu>
+ <os>
+ <type arch='i686' machine='pc'>hvm</type>
+ <boot dev='hd'/>
+ </os>
+ <clock offset='utc'/>
+ <on_poweroff>destroy</on_poweroff>
+ <on_reboot>restart</on_reboot>
+ <on_crash>destroy</on_crash>
+ <devices>
+ <emulator>/usr/bin/qemu</emulator>
+ <disk type='block' device='cdrom'>
+ <source dev='/dev/HostVG/QEMUGuest1'/>
+ <target dev='sda' bus='virtio'/>
+ <vendor>SEAGATE</vendor>
+ <product>ST3146707LC</product>
+ </disk>
+ <disk type='block' device='disk'>
+ <source dev='/dev/HostVG/QEMUGuest2'/>
+ <target dev='sdb' bus='scsi'/>
+ <vendor>SEAGATE</vendor>
+ <product>ST3567807GD</product>
+ <address type='drive' controller='0' bus='0' target='0' unit='0'/>
+ </disk>
+ <controller type='usb' index='0'/>
+ <controller type='scsi' index='0' model='virtio-scsi'/>
+ <controller type='scsi' index='1' model='lsilogic'/>
+ <memballoon model='virtio'/>
+ </devices>
+</domain>
diff --git a/tests/qemuxml2argvdata/qemuxml2argv-disk-scsi-disk-vpd.args b/tests/qemuxml2argvdata/qemuxml2argv-disk-scsi-disk-vpd.args
new file mode 100644
index 0000000..f5c1999
--- /dev/null
+++ b/tests/qemuxml2argvdata/qemuxml2argv-disk-scsi-disk-vpd.args
@@ -0,0 +1,13 @@
+LC_ALL=C PATH=/bin HOME=/home/test USER=test LOGNAME=test \
+/usr/bin/qemu -S -M pc -m 214 -smp 1 -nographic -nodefconfig -nodefaults \
+-monitor unix:/tmp/test-monitor,server,nowait -no-acpi -boot c \
+-device virtio-scsi-pci,id=scsi0,bus=pci.0,addr=0x3 \
+-device lsi,id=scsi1,bus=pci.0,addr=0x4 \
+-usb \
+-drive file=/dev/HostVG/QEMUGuest1,if=none,id=drive-scsi0-0-0-0 \
+-device scsi-cd,bus=scsi0.0,channel=0,scsi-id=0,lun=0,drive=drive-scsi0-0-0-0,\
+id=scsi0-0-0-0,vendor=SEAGATE,product=ST3146707LC \
+-drive file=/dev/HostVG/QEMUGuest2,if=none,id=drive-scsi1-0-0 \
+-device scsi-hd,bus=scsi1.0,scsi-id=0,drive=drive-scsi1-0-0,\
+id=scsi1-0-0,vendor=SEAGATE,product=ST3567807GD \
+-device virtio-balloon-pci,id=balloon0,bus=pci.0,addr=0x5
diff --git a/tests/qemuxml2argvdata/qemuxml2argv-disk-scsi-disk-vpd.xml b/tests/qemuxml2argvdata/qemuxml2argv-disk-scsi-disk-vpd.xml
new file mode 100644
index 0000000..96786e3
--- /dev/null
+++ b/tests/qemuxml2argvdata/qemuxml2argv-disk-scsi-disk-vpd.xml
@@ -0,0 +1,38 @@
+<domain type='qemu'>
+ <name>QEMUGuest1</name>
+ <uuid>c7a5fdbd-edaf-9455-926a-d65c16db1809</uuid>
+ <memory unit='KiB'>219136</memory>
+ <currentMemory unit='KiB'>219136</currentMemory>
+ <vcpu placement='static'>1</vcpu>
+ <os>
+ <type arch='i686' machine='pc'>hvm</type>
+ <boot dev='hd'/>
+ </os>
+ <clock offset='utc'/>
+ <on_poweroff>destroy</on_poweroff>
+ <on_reboot>restart</on_reboot>
+ <on_crash>destroy</on_crash>
+ <devices>
+ <emulator>/usr/bin/qemu</emulator>
+ <disk type='block' device='cdrom'>
+ <source dev='/dev/HostVG/QEMUGuest1'/>
+ <target dev='sda' bus='scsi'/>
+ <readonly/>
+ <vendor>SEAGATE</vendor>
+ <product>ST3146707LC</product>
+ <address type='drive' controller='0' bus='0' target='0' unit='0'/>
+ </disk>
+ <disk type='block' device='disk'>
+ <source dev='/dev/HostVG/QEMUGuest2'/>
+ <target dev='sdb' bus='scsi'/>
+ <readonly/>
+ <vendor>SEAGATE</vendor>
+ <product>ST3567807GD</product>
+ <address type='drive' controller='1' bus='0' target='0' unit='0'/>
+ </disk>
+ <controller type='usb' index='0'/>
+ <controller type='scsi' index='0' model='virtio-scsi'/>
+ <controller type='scsi' index='1' model='lsilogic'/>
+ <memballoon model='virtio'/>
+ </devices>
+</domain>
diff --git a/tests/qemuxml2argvtest.c b/tests/qemuxml2argvtest.c
index 48e09ab..8f98882 100644
--- a/tests/qemuxml2argvtest.c
+++ b/tests/qemuxml2argvtest.c
@@ -505,6 +505,14 @@ mymain(void)
QEMU_CAPS_DRIVE, QEMU_CAPS_DEVICE, QEMU_CAPS_NODEFCONFIG,
QEMU_CAPS_SCSI_CD, QEMU_CAPS_SCSI_LSI, QEMU_CAPS_VIRTIO_SCSI_PCI,
QEMU_CAPS_SCSI_DISK_WWN);
+ DO_TEST("disk-scsi-disk-vpd",
+ QEMU_CAPS_DRIVE, QEMU_CAPS_DEVICE, QEMU_CAPS_NODEFCONFIG,
+ QEMU_CAPS_SCSI_CD, QEMU_CAPS_SCSI_LSI, QEMU_CAPS_VIRTIO_SCSI_PCI,
+ QEMU_CAPS_SCSI_DISK_WWN);
+ DO_TEST_FAILURE("disk-scsi-disk-vpd-build-error",
+ QEMU_CAPS_DRIVE, QEMU_CAPS_DEVICE, QEMU_CAPS_NODEFCONFIG,
+ QEMU_CAPS_SCSI_CD, QEMU_CAPS_SCSI_LSI, QEMU_CAPS_VIRTIO_SCSI_PCI,
+ QEMU_CAPS_SCSI_DISK_WWN);
DO_TEST("disk-scsi-vscsi",
QEMU_CAPS_DRIVE, QEMU_CAPS_DEVICE, QEMU_CAPS_NODEFCONFIG);
DO_TEST("disk-scsi-virtio-scsi",
diff --git a/tests/qemuxml2xmltest.c b/tests/qemuxml2xmltest.c
index 1d366f1..88ef050 100644
--- a/tests/qemuxml2xmltest.c
+++ b/tests/qemuxml2xmltest.c
@@ -239,6 +239,8 @@ mymain(void)
DO_TEST("seclabel-none");
DO_TEST("numad-static-vcpu-no-numatune");
+ DO_TEST("disk-scsi-disk-vpd");
+
/* These tests generate different XML */
DO_TEST_DIFFERENT("balloon-device-auto");
DO_TEST_DIFFERENT("channel-virtio-auto");
--
1.7.7.6
12 years, 6 months
[libvirt] [PATCH] beautify code indent in qemu migration
by liguang
Signed-off-by: liguang <lig.fnst(a)cn.fujitsu.com>
---
src/qemu/qemu_migration.c | 18 ++++++------------
1 files changed, 6 insertions(+), 12 deletions(-)
diff --git a/src/qemu/qemu_migration.c b/src/qemu/qemu_migration.c
index 716365f..0e00cac 100644
--- a/src/qemu/qemu_migration.c
+++ b/src/qemu/qemu_migration.c
@@ -692,12 +692,10 @@ qemuMigrationCookieXMLFormat(struct qemud_driver *driver,
qemuMigrationCookieFlagTypeToString(i));
}
- if ((mig->flags & QEMU_MIGRATION_COOKIE_GRAPHICS) &&
- mig->graphics)
+ if ((mig->flags & QEMU_MIGRATION_COOKIE_GRAPHICS) && mig->graphics)
qemuMigrationCookieGraphicsXMLFormat(buf, mig->graphics);
- if ((mig->flags & QEMU_MIGRATION_COOKIE_LOCKSTATE) &&
- mig->lockState) {
+ if ((mig->flags & QEMU_MIGRATION_COOKIE_LOCKSTATE) && mig->lockState) {
virBufferAsprintf(buf, " <lockstate driver='%s'>\n",
mig->lockDriver);
virBufferAsprintf(buf, " <leases>%s</leases>\n",
@@ -705,8 +703,7 @@ qemuMigrationCookieXMLFormat(struct qemud_driver *driver,
virBufferAddLit(buf, " </lockstate>\n");
}
- if ((mig->flags & QEMU_MIGRATION_COOKIE_PERSISTENT) &&
- mig->persistent) {
+ if ((mig->flags & QEMU_MIGRATION_COOKIE_PERSISTENT) && mig->persistent) {
virBufferAdjustIndent(buf, 2);
if (qemuDomainDefFormatBuf(driver,
mig->persistent,
@@ -790,7 +787,6 @@ qemuMigrationCookieGraphicsXMLParse(xmlXPathContextPtr ctxt)
/* Optional */
grap->tlsSubject = virXPathString("string(./graphics/cert[@info='subject']/@value)", ctxt);
-
return grap;
no_memory:
@@ -821,7 +817,7 @@ qemuMigrationCookieNetworkXMLParse(xmlXPathContextPtr ctxt)
}
optr->nnets = n;
- if (VIR_ALLOC_N(optr->net, optr->nnets) <0)
+ if (VIR_ALLOC_N(optr->net, optr->nnets) < 0)
goto no_memory;
for (i = 0; i < n; i++) {
@@ -1137,8 +1133,7 @@ qemuMigrationEatCookie(struct qemud_driver *driver,
qemuMigrationCookiePtr mig = NULL;
/* Parse & validate incoming cookie (if any) */
- if (cookiein && cookieinlen &&
- cookiein[cookieinlen-1] != '\0') {
+ if (cookiein && cookieinlen && cookiein[cookieinlen-1] != '\0') {
virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
_("Migration cookie was not NULL terminated"));
goto error;
@@ -1204,8 +1199,7 @@ qemuMigrationIsAllowed(struct qemud_driver *driver, virDomainObjPtr vm,
"%s", _("domain is marked for auto destroy"));
return false;
}
- if ((nsnapshots = virDomainSnapshotObjListNum(vm->snapshots, NULL,
- 0))) {
+ if ((nsnapshots = virDomainSnapshotObjListNum(vm->snapshots, NULL, 0))) {
virReportError(VIR_ERR_OPERATION_INVALID,
_("cannot migrate domain with %d snapshots"),
nsnapshots);
--
1.7.1
12 years, 6 months
[libvirt] [PATCH][thinner] beautify code indent in qemu migration
by liguang
Signed-off-by: liguang <lig.fnst(a)cn.fujitsu.com>
---
src/qemu/qemu_migration.c | 3 +--
1 files changed, 1 insertions(+), 2 deletions(-)
diff --git a/src/qemu/qemu_migration.c b/src/qemu/qemu_migration.c
index 9e7ee4f..7a4142c 100644
--- a/src/qemu/qemu_migration.c
+++ b/src/qemu/qemu_migration.c
@@ -790,7 +790,6 @@ qemuMigrationCookieGraphicsXMLParse(xmlXPathContextPtr ctxt)
/* Optional */
grap->tlsSubject = virXPathString("string(./graphics/cert[@info='subject']/@value)", ctxt);
-
return grap;
no_memory:
@@ -821,7 +820,7 @@ qemuMigrationCookieNetworkXMLParse(xmlXPathContextPtr ctxt)
}
optr->nnets = n;
- if (VIR_ALLOC_N(optr->net, optr->nnets) <0)
+ if (VIR_ALLOC_N(optr->net, optr->nnets) < 0)
goto no_memory;
for (i = 0; i < n; i++) {
--
1.7.1
12 years, 6 months
[libvirt] [test-API][PATCH] Fix a problem in cpu_affinity
by Wayne Sun
int() with base 16 will cause problem when cpu number bigger than
10, so change it as default with base 10.
Signed-off-by: Wayne Sun <gsun(a)redhat.com>
---
repos/domain/cpu_affinity.py | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/repos/domain/cpu_affinity.py b/repos/domain/cpu_affinity.py
index ee585e6..e710968 100644
--- a/repos/domain/cpu_affinity.py
+++ b/repos/domain/cpu_affinity.py
@@ -151,7 +151,7 @@ def vcpu_affinity_check(domain_name, vcpu, expected_pinned_cpu, hypervisor):
task_list = output.split('\n')[1:]
vcpu_task = task_list[int(vcpu)]
- actual_pinned_cpu = int(vcpu_task.split('\t')[1], 16)
+ actual_pinned_cpu = int(vcpu_task.split('\t')[1])
elif 'el5' in host_kernel_version:
cmd_get_task_list = "grep Cpus_allowed /proc/%s/task/*/status" % pid
status, output = commands.getstatusoutput(cmd_get_task_list)
--
1.7.1
12 years, 6 months
[libvirt] [PATCH] virsh: save: report an error if XML file can't be read
by Ján Tomko
Bug: https://bugzilla.redhat.com/show_bug.cgi?id=876868
---
tools/virsh-domain.c | 4 +++-
1 files changed, 3 insertions(+), 1 deletions(-)
diff --git a/tools/virsh-domain.c b/tools/virsh-domain.c
index 86ed4d3..df38618 100644
--- a/tools/virsh-domain.c
+++ b/tools/virsh-domain.c
@@ -2945,8 +2945,10 @@ doSave(void *opaque)
goto out;
if (xmlfile &&
- virFileReadAll(xmlfile, 8192, &xml) < 0)
+ virFileReadAll(xmlfile, 8192, &xml) < 0) {
+ vshReportError(ctl);
goto out;
+ }
if (((flags || xml)
? virDomainSaveFlags(dom, to, xml, flags)
--
1.7.8.6
12 years, 6 months
[libvirt] [PATCH v2] sanlock: Retry after EINPROGRESS
by Michal Privoznik
It may take some time for sanlock to add a lockspace. And if user
restart libvirtd service meanwhile, the fresh daemon can fail adding
the same lockspace with EINPROGRESS. Recent sanlock has
sanlock_inq_lockspace() function which should block until lockspace
changes state. If we are building against older sanlock we should
retry a few times before claiming an error. This issue can be easily
reproduced:
for i in {1..1000} ; do echo $i; service libvirtd restart; sleep 2; done
20
Stopping libvirtd daemon: [FAILED]
Starting libvirtd daemon: [ OK ]
21
Stopping libvirtd daemon: [ OK ]
Starting libvirtd daemon: [ OK ]
22
Stopping libvirtd daemon: [ OK ]
Starting libvirtd daemon: [ OK ]
error : virLockManagerSanlockSetupLockspace:334 : Unable to add
lockspace /var/lib/libvirt/sanlock/__LIBVIRT__DISKS__: Operation now in
progress
---
diff to v1:
-after IRC discussion with sanlock devel I've found this API
so whe ought use it whenever possible.
configure.ac | 7 +++++++
src/locking/lock_driver_sanlock.c | 35 ++++++++++++++++++++++++++++++++---
2 files changed, 39 insertions(+), 3 deletions(-)
diff --git a/configure.ac b/configure.ac
index 9108ea8..849d787 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1223,6 +1223,13 @@ if test "x$with_sanlock" != "xno"; then
AC_DEFINE_UNQUOTED([HAVE_SANLOCK_KILLPATH], 1,
[whether Sanlock supports sanlock_killpath])
fi
+
+ AC_CHECK_LIB([sanlock_client], [sanlock_inq_lockspace],
+ [sanlock_inq_lockspace=yes], [sanlock_inq_lockspace=no])
+ if test "x$sanlock_inq_lockspace" = "xyes" ; then
+ AC_DEFINE_UNQUOTED([HAVE_SANLOCK_INQ_LOCKSPACE], 1,
+ [whether sanlock supports sanlock_inq_lockspace])
+ fi
fi
fi
AM_CONDITIONAL([HAVE_SANLOCK], [test "x$with_sanlock" = "xyes"])
diff --git a/src/locking/lock_driver_sanlock.c b/src/locking/lock_driver_sanlock.c
index d24f3d6..430e11e 100644
--- a/src/locking/lock_driver_sanlock.c
+++ b/src/locking/lock_driver_sanlock.c
@@ -184,6 +184,11 @@ static int virLockManagerSanlockLoadConfig(const char *configFile)
return 0;
}
+/* How much ms sleep before retrying to add a lockspace? */
+#define LOCKSPACE_SLEEP 100
+/* How many times try adding a lockspace? */
+#define LOCKSPACE_RETRIES 10
+
static int virLockManagerSanlockSetupLockspace(void)
{
int fd = -1;
@@ -192,6 +197,9 @@ static int virLockManagerSanlockSetupLockspace(void)
struct sanlk_lockspace ls;
char *path = NULL;
char *dir = NULL;
+#ifndef HAVE_SANLOCK_INQ_LOCKSPACE
+ int retries = LOCKSPACE_RETRIES;
+#endif
if (virAsprintf(&path, "%s/%s",
driver->autoDiskLeasePath,
@@ -318,11 +326,32 @@ static int virLockManagerSanlockSetupLockspace(void)
}
ls.host_id = driver->hostID;
- /* Stage 2: Try to register the lockspace with the daemon.
- * If the lockspace is already registered, we should get EEXIST back
- * in which case we can just carry on with life
+ /* Stage 2: Try to register the lockspace with the daemon. If the lockspace
+ * is already registered, we should get EEXIST back in which case we can
+ * just carry on with life. If EINPROGRESS is returned, we have two options:
+ * either call a sanlock API that blocks us until lockspace changes state,
+ * or we can fallback to polling.
*/
+#ifndef HAVE_SANLOCK_INQ_LOCKSPACE
+retry:
+#endif
if ((rv = sanlock_add_lockspace(&ls, 0)) < 0) {
+ if (-rv == EINPROGRESS) {
+#ifdef HAVE_SANLOCK_INQ_LOCKSPACE
+ /* we have this function which blocks until lockspace change the
+ * state. It returns 0 if lockspace has been added, -ENOENT if it
+ * hasn't. XXX should we goto retry? */
+ VIR_DEBUG("Inquiring lockspace");
+ rv = sanlock_inq_lockspace(&ls, SANLK_INQ_WAIT);
+#else
+ /* fall back to polling */
+ if (retries--) {
+ usleep(LOCKSPACE_SLEEP * 1000);
+ VIR_DEBUG("Retrying to add lockspace (left %d)", retries);
+ goto retry;
+ }
+#endif
+ }
if (-rv != EEXIST) {
if (rv <= -200)
virReportError(VIR_ERR_INTERNAL_ERROR,
--
1.7.8.6
12 years, 6 months
[libvirt] [libvirt-glib 1/2] Fix glib version check for g_type_init
by Christophe Fergeau
g_type_init has been deprecated in glib 2.35, not 2.34. With versions
older than 2.35, we have to call it or we'll get a runtime failure.
---
libvirt-gconfig/libvirt-gconfig-compat.h | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/libvirt-gconfig/libvirt-gconfig-compat.h b/libvirt-gconfig/libvirt-gconfig-compat.h
index 85a420d..3719896 100644
--- a/libvirt-gconfig/libvirt-gconfig-compat.h
+++ b/libvirt-gconfig/libvirt-gconfig-compat.h
@@ -25,7 +25,7 @@
#include <glib-object.h>
-#if GLIB_CHECK_VERSION(2, 34, 0)
+#if GLIB_CHECK_VERSION(2, 35, 0)
#define g_type_init()
#endif
--
1.8.0
12 years, 6 months