* docs/schemas/domain.rng: Add <serial> element to disks * src/domain_conf.h, src/domain_conf.c: XML parsing and formatting for disk serial numbers * src/qemu_conf.c: Set serial number when launching guests * tests/qemuxml2argvdata/qemuxml2argv-disk-drive-shared.args, tests/qemuxml2argvdata/qemuxml2argv-disk-drive-shared.xml: Add serial number to XML test --- docs/schemas/domain.rng | 10 ++++++++ src/domain_conf.c | 11 ++++++++ src/domain_conf.h | 1 + src/qemu_conf.c | 25 ++++++++++++++++++++ src/qemu_conf.h | 1 + tests/qemuhelptest.c | 3 ++ .../qemuxml2argv-disk-drive-shared.args | 2 +- .../qemuxml2argv-disk-drive-shared.xml | 1 + tests/qemuxml2argvtest.c | 2 +- 9 files changed, 54 insertions(+), 2 deletions(-) diff --git a/docs/schemas/domain.rng b/docs/schemas/domain.rng index f857301..16f35e4 100644 --- a/docs/schemas/domain.rng +++ b/docs/schemas/domain.rng @@ -336,6 +336,11 @@ <empty/> </element> </optional> + <optional> + <element name="serial"> + <ref name="diskSerial"/> + </element> + </optional> </define> <!-- A disk description can be either of type file or block @@ -1135,6 +1140,11 @@ <param name="pattern">[A-Za-z0-9_\.\+\-&:/]+</param> </data> </define> + <define name="diskSerial"> + <data type="string"> + <param name="pattern">[A-Za-z0-9_\.\+\-]+</param> + </data> + </define> <define name="genericName"> <data type="string"> <param name="pattern">[a-zA-Z0-9_\+\-]+</param> diff --git a/src/domain_conf.c b/src/domain_conf.c index 1d2cc7c..654f753 100644 --- a/src/domain_conf.c +++ b/src/domain_conf.c @@ -284,6 +284,7 @@ void virDomainDiskDefFree(virDomainDiskDefPtr def) if (!def) return; + VIR_FREE(def->serial); VIR_FREE(def->src); VIR_FREE(def->dst); VIR_FREE(def->driverName); @@ -661,6 +662,7 @@ virDomainDiskDefParseXML(virConnectPtr conn, char *bus = NULL; char *cachetag = NULL; char *devaddr = NULL; + char *serial = NULL; if (VIR_ALLOC(def) < 0) { virReportOOMError(conn); @@ -718,6 +720,9 @@ virDomainDiskDefParseXML(virConnectPtr conn, } else if ((flags & VIR_DOMAIN_XML_INTERNAL_STATUS) && xmlStrEqual(cur->name, BAD_CAST "state")) { devaddr = virXMLPropString(cur, "devaddr"); + } else if ((serial == NULL) && + (xmlStrEqual(cur->name, BAD_CAST "serial"))) { + serial = (char *)xmlNodeGetContent(cur); } } cur = cur->next; @@ -836,6 +841,8 @@ virDomainDiskDefParseXML(virConnectPtr conn, driverName = NULL; def->driverType = driverType; driverType = NULL; + def->serial = serial; + serial = NULL; cleanup: VIR_FREE(bus); @@ -847,6 +854,7 @@ cleanup: VIR_FREE(driverName); VIR_FREE(cachetag); VIR_FREE(devaddr); + VIR_FREE(serial); return def; @@ -3519,6 +3527,9 @@ virDomainDiskDefFormat(virConnectPtr conn, virBufferAddLit(buf, " <readonly/>\n"); if (def->shared) virBufferAddLit(buf, " <shareable/>\n"); + if (def->serial) + virBufferEscapeString(buf, " <serial>%s</serial>\n", + def->serial); if (flags & VIR_DOMAIN_XML_INTERNAL_STATUS) { virBufferAddLit(buf, " <state"); diff --git a/src/domain_conf.h b/src/domain_conf.h index 44302be..7bad5e7 100644 --- a/src/domain_conf.h +++ b/src/domain_conf.h @@ -109,6 +109,7 @@ struct _virDomainDiskDef { char *dst; char *driverName; char *driverType; + char *serial; int cachemode; unsigned int readonly : 1; unsigned int shared : 1; diff --git a/src/qemu_conf.c b/src/qemu_conf.c index 22f5edd..381f281 100644 --- a/src/qemu_conf.c +++ b/src/qemu_conf.c @@ -782,6 +782,8 @@ static unsigned int qemudComputeCmdFlags(const char *help, flags |= QEMUD_CMD_FLAG_VGA; if (strstr(help, "boot=on")) flags |= QEMUD_CMD_FLAG_DRIVE_BOOT; + if (strstr(help, "serial=s")) + flags |= QEMUD_CMD_FLAG_DRIVE_SERIAL; if (strstr(help, "-pcidevice")) flags |= QEMUD_CMD_FLAG_PCIDEVICE; @@ -1375,6 +1377,23 @@ static int qemudBuildCommandLineChrDevStr(virDomainChrDefPtr dev, return 0; } +#define QEMU_SERIAL_PARAM_ACCEPTED_CHARS \ + "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-_" + +static int +qemuSafeSerialParamValue(virConnectPtr conn, + const char *value) +{ + if (strspn(value, QEMU_SERIAL_PARAM_ACCEPTED_CHARS) != strlen (value)) { + qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR, + _("driver serial '%s' contains unsafe characters"), + value); + return -1; + } + + return 0; +} + /* * Constructs a argv suitable for launching qemu with config defined * for a given virtual machine. @@ -1754,6 +1773,12 @@ int qemudBuildCommandLine(virConnectPtr conn, if (disk->driverType && qemuCmdFlags & QEMUD_CMD_FLAG_DRIVE_FORMAT) virBufferVSprintf(&opt, ",format=%s", disk->driverType); + if (disk->serial && + (qemuCmdFlags & QEMUD_CMD_FLAG_DRIVE_SERIAL)) { + if (qemuSafeSerialParamValue(conn, disk->serial) < 0) + goto error; + virBufferVSprintf(&opt, ",serial=%s", disk->serial); + } if (disk->cachemode) { const char *mode = diff --git a/src/qemu_conf.h b/src/qemu_conf.h index a126dac..dcfacb9 100644 --- a/src/qemu_conf.h +++ b/src/qemu_conf.h @@ -67,6 +67,7 @@ enum qemud_cmd_flags { QEMUD_CMD_FLAG_HOST_NET_ADD = QEMUD_CMD_FLAG_0_10, /* host_net_add monitor command */ QEMUD_CMD_FLAG_PCIDEVICE = (1 << 17), /* PCI device assignment only supported by qemu-kvm */ + QEMUD_CMD_FLAG_DRIVE_SERIAL = (1 << 18), /* -driver serial= available */ }; /* Main driver state */ diff --git a/tests/qemuhelptest.c b/tests/qemuhelptest.c index ad2045f..e21f4c4 100644 --- a/tests/qemuhelptest.c +++ b/tests/qemuhelptest.c @@ -118,6 +118,7 @@ mymain(int argc, char **argv) QEMUD_CMD_FLAG_MIGRATE_QEMU_EXEC | QEMUD_CMD_FLAG_DRIVE_CACHE_V2 | QEMUD_CMD_FLAG_DRIVE_FORMAT | + QEMUD_CMD_FLAG_DRIVE_SERIAL | QEMUD_CMD_FLAG_VGA | QEMUD_CMD_FLAG_0_10, 10005, 0, 0); @@ -134,6 +135,7 @@ mymain(int argc, char **argv) QEMUD_CMD_FLAG_DRIVE_CACHE_V2 | QEMUD_CMD_FLAG_KVM | QEMUD_CMD_FLAG_DRIVE_FORMAT | + QEMUD_CMD_FLAG_DRIVE_SERIAL | QEMUD_CMD_FLAG_VGA | QEMUD_CMD_FLAG_0_10 | QEMUD_CMD_FLAG_PCIDEVICE, @@ -151,6 +153,7 @@ mymain(int argc, char **argv) QEMUD_CMD_FLAG_DRIVE_CACHE_V2 | QEMUD_CMD_FLAG_KVM | QEMUD_CMD_FLAG_DRIVE_FORMAT | + QEMUD_CMD_FLAG_DRIVE_SERIAL | QEMUD_CMD_FLAG_VGA | QEMUD_CMD_FLAG_0_10 | QEMUD_CMD_FLAG_PCIDEVICE, diff --git a/tests/qemuxml2argvdata/qemuxml2argv-disk-drive-shared.args b/tests/qemuxml2argvdata/qemuxml2argv-disk-drive-shared.args index 611cd33..07cbe0e 100644 --- a/tests/qemuxml2argvdata/qemuxml2argv-disk-drive-shared.args +++ b/tests/qemuxml2argvdata/qemuxml2argv-disk-drive-shared.args @@ -1 +1 @@ -LC_ALL=C PATH=/bin HOME=/home/test USER=test LOGNAME=test /usr/bin/qemu -S -M pc -m 214 -smp 1 -nographic -monitor unix:/tmp/test-monitor,server,nowait -no-acpi -boot c -drive file=/dev/HostVG/QEMUGuest1,if=ide,index=0,format=qcow2,cache=off -drive file=/dev/HostVG/QEMUGuest2,if=ide,media=cdrom,index=2,format=raw -net none -serial none -parallel none -usb +LC_ALL=C PATH=/bin HOME=/home/test USER=test LOGNAME=test /usr/bin/qemu -S -M pc -m 214 -smp 1 -nographic -monitor unix:/tmp/test-monitor,server,nowait -no-acpi -boot c -drive file=/dev/HostVG/QEMUGuest1,if=ide,index=0,format=qcow2,serial=XYZXYZXYZYXXYZYZYXYZY,cache=off -drive file=/dev/HostVG/QEMUGuest2,if=ide,media=cdrom,index=2,format=raw -net none -serial none -parallel none -usb diff --git a/tests/qemuxml2argvdata/qemuxml2argv-disk-drive-shared.xml b/tests/qemuxml2argvdata/qemuxml2argv-disk-drive-shared.xml index b386315..c4e4734 100644 --- a/tests/qemuxml2argvdata/qemuxml2argv-disk-drive-shared.xml +++ b/tests/qemuxml2argvdata/qemuxml2argv-disk-drive-shared.xml @@ -19,6 +19,7 @@ <source dev='/dev/HostVG/QEMUGuest1'/> <target dev='hda' bus='ide'/> <shareable/> + <serial>XYZXYZXYZYXXYZYZYXYZY</serial> </disk> <disk type='block' device='cdrom'> <driver name='qemu' type='raw'/> diff --git a/tests/qemuxml2argvtest.c b/tests/qemuxml2argvtest.c index 6f25e7d..f27a056 100644 --- a/tests/qemuxml2argvtest.c +++ b/tests/qemuxml2argvtest.c @@ -204,7 +204,7 @@ mymain(int argc, char **argv) DO_TEST("disk-drive-fmt-qcow", QEMUD_CMD_FLAG_DRIVE | QEMUD_CMD_FLAG_DRIVE_BOOT | QEMUD_CMD_FLAG_DRIVE_FORMAT); DO_TEST("disk-drive-shared", QEMUD_CMD_FLAG_DRIVE | - QEMUD_CMD_FLAG_DRIVE_FORMAT); + QEMUD_CMD_FLAG_DRIVE_FORMAT | QEMUD_CMD_FLAG_DRIVE_SERIAL); DO_TEST("disk-drive-cache-v1-wt", QEMUD_CMD_FLAG_DRIVE | QEMUD_CMD_FLAG_DRIVE_FORMAT); DO_TEST("disk-drive-cache-v1-wb", QEMUD_CMD_FLAG_DRIVE | -- 1.6.2.5 -- Libvir-list mailing list Libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list