QEMU supports to set 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 | 10 +++++ src/conf/domain_conf.c | 42 ++++++++++++++++++++ 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-parse-error.xml | 36 +++++++++++++++++ .../qemuxml2argv-disk-scsi-disk-vpd.args | 13 ++++++ .../qemuxml2argv-disk-scsi-disk-vpd.xml | 36 +++++++++++++++++ tests/qemuxml2argvtest.c | 12 ++++++ 13 files changed, 242 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-parse-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 2beb035..ed7d1d0 100644 --- a/docs/schemas/domaincommon.rng +++ b/docs/schemas/domaincommon.rng @@ -905,6 +905,16 @@ <ref name="wwn"/> </element> </optional> + <optional> + <element name="vendor"> + <text/> + </element> + </optional> + <optional> + <element name="product"> + <text/> + </element> + </optional> </interleave> </define> <define name="snapshot"> diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c index 99f03a9..e2f729e 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 (!virStrIsAlpha(vendor)) { + virReportError(VIR_ERR_XML_ERROR, "%s", + _("disk vendor is not alphanemuric 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 (!virStrIsAlpha(product)) { + virReportError(VIR_ERR_XML_ERROR, "%s", + _("disk product is not alphanemuric 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; diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h index 6539281..c7c1ca6 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..3bcdf68 100644 --- a/src/libvirt_private.syms +++ b/src/libvirt_private.syms @@ -1279,6 +1279,7 @@ virSetUIDGID; virSkipSpaces; virSkipSpacesAndBackslash; virSkipSpacesBackwards; +virStrIsAlpha; virStrToDouble; virStrToLong_i; virStrToLong_l; diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c index 1e96982..ec2bbd8 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..26a22c4 100644 --- a/src/util/util.c +++ b/src/util/util.c @@ -3114,3 +3114,15 @@ virValidateWWN(const char *wwn) { return true; } + +bool +virStrIsAlpha(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..64e047c 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 virStrIsAlpha(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..6ed363b --- /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'/> + <address type='drive' controller='0' bus='0' target='0' unit='0'/> + <vendor>SEAGATE</vendor> + <product>ST3567807GD</product> + </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-parse-error.xml b/tests/qemuxml2argvdata/qemuxml2argv-disk-scsi-disk-vpd-parse-error.xml new file mode 100644 index 0000000..b2b127d --- /dev/null +++ b/tests/qemuxml2argvdata/qemuxml2argv-disk-scsi-disk-vpd-parse-error.xml @@ -0,0 +1,36 @@ +<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'/> + <address type='drive' controller='0' bus='0' target='1' unit='0'/> + <vendor>SEAGATE1111</vendor> + <product>ST_3146707LC</product> + </disk> + <disk type='block' device='disk'> + <source dev='/dev/HostVG/QEMUGuest2'/> + <target dev='sdb' bus='scsi'/> + <address type='drive' controller='0' bus='0' target='0' unit='0'/> + <vendor>SEAGATE</vendor> + <product>ST3567807GD</product> + </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..4aefb7f --- /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-1-0 \ +-device scsi-cd,bus=scsi0.0,channel=0,scsi-id=1,lun=0,drive=drive-scsi0-0-1-0,\ +id=scsi0-0-1-0,vendor=SEAGATE,product=ST3146707LC \ +-drive file=/dev/HostVG/QEMUGuest2,if=none,id=drive-scsi0-0-0-0 \ +-device scsi-hd,bus=scsi0.0,channel=0,scsi-id=0,lun=0,drive=drive-scsi0-0-0-0,\ +id=scsi0-0-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..4918e37 --- /dev/null +++ b/tests/qemuxml2argvdata/qemuxml2argv-disk-scsi-disk-vpd.xml @@ -0,0 +1,36 @@ +<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'/> + <address type='drive' controller='0' bus='0' target='1' unit='0'/> + <vendor>SEAGATE</vendor> + <product>ST3146707LC</product> + </disk> + <disk type='block' device='disk'> + <source dev='/dev/HostVG/QEMUGuest2'/> + <target dev='sdb' bus='scsi'/> + <address type='drive' controller='0' bus='0' target='0' unit='0'/> + <vendor>SEAGATE</vendor> + <product>ST3567807GD</product> + </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..651351b 100644 --- a/tests/qemuxml2argvtest.c +++ b/tests/qemuxml2argvtest.c @@ -505,6 +505,18 @@ 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_PARSE_ERROR("disk-scsi-disk-vpd-parse-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_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", -- 1.7.7.6 -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list