https://bugzilla.redhat.com/show_bug.cgi?id=1434451 It comes handy for management application to be able to have a per-device label so that it can uniquely identify devices it cares about. The advantage of this approach is that we don't have to generate aliases at define time (non trivial amount of work and problems). The only thing we do is parse the user supplied UUID and format it back. For instance: <disk type='block' device='disk'> <driver name='qemu' type='raw'/> <source dev='/dev/HostVG/QEMUGuest1'/> <target dev='hda' bus='ide'/> <uuid>1efaf08b-9317-4b0f-b227-912e4bd9f483</uuid> <address type='drive' controller='0' bus='0' target='0' unit='0'/> </disk> Signed-off-by: Michal Privoznik <mprivozn@xxxxxxxxxx> --- This is just a very basic implementation. If I get a green light on this, I can implement the feature further, i.e. allow device lookup on the UUID. For instance: virsh domiftune fedora $UUID $bandwidth docs/formatdomain.html.in | 21 +++++++++++++++ docs/schemas/domaincommon.rng | 21 ++++++++++----- src/conf/device_conf.c | 1 + src/conf/device_conf.h | 1 + src/conf/domain_conf.c | 25 +++++++++++++++++ tests/genericxml2xmlindata/generic-device-uuid.xml | 31 ++++++++++++++++++++++ tests/genericxml2xmltest.c | 1 + 7 files changed, 95 insertions(+), 6 deletions(-) create mode 100644 tests/genericxml2xmlindata/generic-device-uuid.xml diff --git a/docs/formatdomain.html.in b/docs/formatdomain.html.in index 5dcf2fedb..b4b2751fd 100644 --- a/docs/formatdomain.html.in +++ b/docs/formatdomain.html.in @@ -3512,6 +3512,27 @@ </dd> </dl> + <p> + To help management applications identify devices they care about, devices + have an optional <code><uuid/></code> sub-element which can hold + UUID label generated by the management application. For instance: + </p> + +<pre> + <disk type='block' device='disk'> + <driver name='qemu' type='raw'/> + <source dev='/dev/HostVG/QEMUGuest1'/> + <target dev='hda' bus='ide'/> + <uuid>2d0ad0dc-3eaa-4295-9d62-3e531197ed7a</uuid> + <address type='drive' controller='0' bus='0' target='0' unit='0'/> + </disk> +</pre> + + <p> + The <code><uuid/></code> is available + <span class="since">since 3.9.0</span>. + </p> + <h4><a id="elementsVirtio">Virtio-related options</a></h4> <p> diff --git a/docs/schemas/domaincommon.rng b/docs/schemas/domaincommon.rng index bac371ea3..61d8430bb 100644 --- a/docs/schemas/domaincommon.rng +++ b/docs/schemas/domaincommon.rng @@ -5863,12 +5863,21 @@ </data> </define> <define name='alias'> - <element name='alias'> - <attribute name='name'> - <ref name='aliasName'/> - </attribute> - </element> - <empty/> + <interleave> + <optional> + <element name='alias'> + <attribute name='name'> + <ref name='aliasName'/> + </attribute> + <empty/> + </element> + </optional> + <optional> + <element name='uuid'> + <ref name="UUID"/> + </element> + </optional> + </interleave> </define> <define name="panic"> <element name="panic"> diff --git a/src/conf/device_conf.c b/src/conf/device_conf.c index d69f94fad..a732731eb 100644 --- a/src/conf/device_conf.c +++ b/src/conf/device_conf.c @@ -57,6 +57,7 @@ void virDomainDeviceInfoClear(virDomainDeviceInfoPtr info) { VIR_FREE(info->alias); + VIR_FREE(info->uuid); memset(&info->addr, 0, sizeof(info->addr)); info->type = VIR_DOMAIN_DEVICE_ADDRESS_TYPE_NONE; VIR_FREE(info->romfile); diff --git a/src/conf/device_conf.h b/src/conf/device_conf.h index f87d6f1fc..f80017291 100644 --- a/src/conf/device_conf.h +++ b/src/conf/device_conf.h @@ -135,6 +135,7 @@ typedef struct _virDomainDeviceInfo virDomainDeviceInfo; typedef virDomainDeviceInfo *virDomainDeviceInfoPtr; struct _virDomainDeviceInfo { char *alias; + unsigned char *uuid; /* user defined UUID for the device, might be NULL */ int type; /* virDomainDeviceAddressType */ union { virPCIDeviceAddress pci; diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c index 67095114c..2ea26dd9f 100644 --- a/src/conf/domain_conf.c +++ b/src/conf/domain_conf.c @@ -5764,11 +5764,18 @@ virDomainDeviceInfoFormat(virBufferPtr buf, virBufferAddLit(buf, "/>\n"); } + if (info->alias && !(flags & VIR_DOMAIN_DEF_FORMAT_INACTIVE)) { virBufferAsprintf(buf, "<alias name='%s'/>\n", info->alias); } + if (info->uuid) { + char uuidstr[VIR_UUID_STRING_BUFLEN]; + virUUIDFormat(info->uuid, uuidstr); + virBufferAsprintf(buf, "<uuid>%s</uuid>\n", uuidstr); + } + if (info->mastertype == VIR_DOMAIN_CONTROLLER_MASTER_USB) { virBufferAsprintf(buf, "<master startport='%d'/>\n", info->master.usb.startport); @@ -6403,10 +6410,12 @@ virDomainDeviceInfoParseXML(xmlNodePtr node, xmlNodePtr address = NULL; xmlNodePtr master = NULL; xmlNodePtr alias = NULL; + xmlNodePtr uuid = NULL; xmlNodePtr boot = NULL; xmlNodePtr rom = NULL; char *type = NULL; char *rombar = NULL; + char *uuidstr = NULL; int ret = -1; virDomainDeviceInfoClear(info); @@ -6418,6 +6427,9 @@ virDomainDeviceInfoParseXML(xmlNodePtr node, !(flags & VIR_DOMAIN_DEF_PARSE_INACTIVE) && virXMLNodeNameEqual(cur, "alias")) { alias = cur; + } else if (uuid == NULL && + virXMLNodeNameEqual(cur, "uuid")) { + uuid = cur; } else if (address == NULL && virXMLNodeNameEqual(cur, "address")) { address = cur; @@ -6440,6 +6452,18 @@ virDomainDeviceInfoParseXML(xmlNodePtr node, if (alias) info->alias = virXMLPropString(alias, "name"); + if (uuid && + (uuidstr = virXMLNodeContentString(uuid))) { + if (VIR_ALLOC_N(info->uuid, VIR_UUID_BUFLEN) < 0) + goto cleanup; + + if (virUUIDParse(uuidstr, info->uuid) < 0) { + virReportError(VIR_ERR_INTERNAL_ERROR, + "%s", _("malformed uuid element")); + goto cleanup; + } + } + if (master) { info->mastertype = VIR_DOMAIN_CONTROLLER_MASTER_USB; if (virDomainDeviceUSBMasterParseXML(master, &info->master.usb) < 0) @@ -6472,6 +6496,7 @@ virDomainDeviceInfoParseXML(xmlNodePtr node, virDomainDeviceInfoClear(info); VIR_FREE(type); VIR_FREE(rombar); + VIR_FREE(uuidstr); return ret; } diff --git a/tests/genericxml2xmlindata/generic-device-uuid.xml b/tests/genericxml2xmlindata/generic-device-uuid.xml new file mode 100644 index 000000000..6deac5f9c --- /dev/null +++ b/tests/genericxml2xmlindata/generic-device-uuid.xml @@ -0,0 +1,31 @@ +<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-system-i686</emulator> + <disk type='block' device='disk'> + <driver name='qemu' type='raw'/> + <source dev='/dev/HostVG/QEMUGuest1'/> + <target dev='hda' bus='ide'/> + <uuid>2d0ad0dc-3eaa-4295-9d62-3e531197ed7a</uuid> + <address type='drive' controller='0' bus='0' target='0' unit='0'/> + </disk> + <controller type='usb' index='0'> + <uuid>4d21cdd8-ab68-4964-a879-9b9198f9f097</uuid> + </controller> + <controller type='ide' index='0'/> + <controller type='pci' index='0' model='pci-root'/> + <memballoon model='none'/> + </devices> +</domain> diff --git a/tests/genericxml2xmltest.c b/tests/genericxml2xmltest.c index 0377a05e9..e0665aa25 100644 --- a/tests/genericxml2xmltest.c +++ b/tests/genericxml2xmltest.c @@ -130,6 +130,7 @@ mymain(void) DO_TEST_FULL("chardev-reconnect-invalid-mode", 0, false, TEST_COMPARE_DOM_XML2XML_RESULT_FAIL_PARSE); + DO_TEST("device-uuid"); virObjectUnref(caps); virObjectUnref(xmlopt); -- 2.13.5 -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list