[libvirt] [PATCH 0/7] Fix ejecting of network backed cdroms via virsh

It turned out that not only virsh was broken ... Peter Krempa (7): virsh: domain: Don't use vshPrepareDiskXML for creating XML to detach disk virsh: domain: Add --print-xml flag for command change-media virsh: domain: Fix the change-media command qemu: hotplug: Use checker function to check if disk is empty qemu: driver: Fix cold-update of removable storage devices util: storage: Fix check for empty storage device conf: disk: Simplify checking if source definition was parsed src/conf/domain_conf.c | 12 ++-- src/qemu/qemu_driver.c | 16 ++--- src/qemu/qemu_hotplug.c | 2 +- src/util/virstoragefile.c | 4 ++ tools/virsh-domain.c | 171 ++++++++++++++++++++++++---------------------- tools/virsh.pod | 7 +- 6 files changed, 112 insertions(+), 100 deletions(-) -- 2.2.2

Since cmdDetachDisk() calls into vshPrepareDiskXML() with type == VSH_PREPARE_DISK_XML_NONE && source == NULL this would result into skipping all the checks and effectively turn the function into a XML formatter. This patch changes the code to use the formatter directly so that the function can be refactored in a easier way. --- tools/virsh-domain.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/tools/virsh-domain.c b/tools/virsh-domain.c index 1a364bb..8bc0512 100644 --- a/tools/virsh-domain.c +++ b/tools/virsh-domain.c @@ -11365,9 +11365,10 @@ cmdDetachDisk(vshControl *ctl, const vshCmd *cmd) if (!(disk_node = vshFindDisk(doc, target, VSH_FIND_DISK_NORMAL))) goto cleanup; - if (!(disk_xml = vshPrepareDiskXML(disk_node, NULL, NULL, - VSH_PREPARE_DISK_XML_NONE))) + if (!(disk_xml = virXMLNodeToString(NULL, disk_node))) { + vshSaveLibvirtError(); goto cleanup; + } if (flags != 0 || current) ret = virDomainDetachDeviceFlags(dom, disk_xml, flags); -- 2.2.2

Allow printing the XML that would be used mostly for debugging purposes. --- tools/virsh-domain.c | 17 +++++++++++++---- tools/virsh.pod | 3 +++ 2 files changed, 16 insertions(+), 4 deletions(-) diff --git a/tools/virsh-domain.c b/tools/virsh-domain.c index 8bc0512..23d0b63 100644 --- a/tools/virsh-domain.c +++ b/tools/virsh-domain.c @@ -12274,6 +12274,10 @@ static const vshCmdOptDef opts_change_media[] = { .type = VSH_OT_BOOL, .help = N_("force media changing") }, + {.name = "print-xml", + .type = VSH_OT_BOOL, + .help = N_("print XML document rather than change media") + }, {.name = NULL} }; @@ -12354,12 +12358,17 @@ cmdChangeMedia(vshControl *ctl, const vshCmd *cmd) if (!(disk_xml = vshPrepareDiskXML(disk_node, source, path, prepare_type))) goto cleanup; - if (virDomainUpdateDeviceFlags(dom, disk_xml, flags) != 0) { - vshError(ctl, _("Failed to complete action %s on media"), action); - goto cleanup; + if (vshCommandOptBool(cmd, "print-xml")) { + vshPrint(ctl, "%s", disk_xml); + } else { + if (virDomainUpdateDeviceFlags(dom, disk_xml, flags) != 0) { + vshError(ctl, _("Failed to complete action %s on media"), action); + goto cleanup; + } + + vshPrint(ctl, _("succeeded to complete action %s on media\n"), action); } - vshPrint(ctl, _("succeeded to complete action %s on media\n"), action); ret = true; cleanup: diff --git a/tools/virsh.pod b/tools/virsh.pod index 714de34..7d43f6f 100644 --- a/tools/virsh.pod +++ b/tools/virsh.pod @@ -2581,6 +2581,7 @@ expected. =item B<change-media> I<domain> I<path> [I<--eject>] [I<--insert>] [I<--update>] [I<source>] [I<--force>] [[I<--live>] [I<--config>] | [I<--current>]] +[I<--print-xml>] Change media of CDROM or floppy drive. I<path> can be the fully-qualified path or the unique target name (<target dev='hdc'>) of the disk device. I<source> @@ -2604,6 +2605,8 @@ the hypervisor's implementation. Both I<--live> and I<--config> flags may be given, but I<--current> is exclusive. If no flag is specified, behavior is different depending on hypervisor. +If I<--print-xml> is specified the XML that would be used to change media is +printed instead of changing the media. =back -- 2.2.2

On 12.03.2015 18:09, Peter Krempa wrote:
Allow printing the XML that would be used mostly for debugging purposes. --- tools/virsh-domain.c | 17 +++++++++++++---- tools/virsh.pod | 3 +++ 2 files changed, 16 insertions(+), 4 deletions(-)
diff --git a/tools/virsh-domain.c b/tools/virsh-domain.c index 8bc0512..23d0b63 100644 --- a/tools/virsh-domain.c +++ b/tools/virsh-domain.c @@ -12274,6 +12274,10 @@ static const vshCmdOptDef opts_change_media[] = { .type = VSH_OT_BOOL, .help = N_("force media changing") }, + {.name = "print-xml", + .type = VSH_OT_BOOL, + .help = N_("print XML document rather than change media") + }, {.name = NULL} };
@@ -12354,12 +12358,17 @@ cmdChangeMedia(vshControl *ctl, const vshCmd *cmd) if (!(disk_xml = vshPrepareDiskXML(disk_node, source, path, prepare_type))) goto cleanup;
- if (virDomainUpdateDeviceFlags(dom, disk_xml, flags) != 0) { - vshError(ctl, _("Failed to complete action %s on media"), action); - goto cleanup; + if (vshCommandOptBool(cmd, "print-xml")) { + vshPrint(ctl, "%s", disk_xml); + } else { + if (virDomainUpdateDeviceFlags(dom, disk_xml, flags) != 0) { + vshError(ctl, _("Failed to complete action %s on media"), action); + goto cleanup; + } + + vshPrint(ctl, _("succeeded to complete action %s on media\n"), action); }
- vshPrint(ctl, _("succeeded to complete action %s on media\n"), action); ret = true;
cleanup: diff --git a/tools/virsh.pod b/tools/virsh.pod index 714de34..7d43f6f 100644 --- a/tools/virsh.pod +++ b/tools/virsh.pod @@ -2581,6 +2581,7 @@ expected.
=item B<change-media> I<domain> I<path> [I<--eject>] [I<--insert>] [I<--update>] [I<source>] [I<--force>] [[I<--live>] [I<--config>] | [I<--current>]] +[I<--print-xml>]
Change media of CDROM or floppy drive. I<path> can be the fully-qualified path or the unique target name (<target dev='hdc'>) of the disk device. I<source> @@ -2604,6 +2605,8 @@ the hypervisor's implementation. Both I<--live> and I<--config> flags may be given, but I<--current> is exclusive. If no flag is specified, behavior is different depending on hypervisor. +If I<--print-xml> is specified the XML that would be used to change media is +printed instead of changing the media.
s/specified/specified,/ Michal

The command did not modify the disk type and thus didn't allow to change media from a file image to a block backed image or vice versa. In addition when operating on a network backed removable devices the command would replace the while <source> subelement with an invalid one. This patch adds the --block option that allows to specify that the new image is block backed and assumes that without that option all images are file backed. Since network backends were always mangled it should not cause problems. --- tools/virsh-domain.c | 149 ++++++++++++++++++++++++++------------------------- tools/virsh.pod | 6 ++- 2 files changed, 79 insertions(+), 76 deletions(-) diff --git a/tools/virsh-domain.c b/tools/virsh-domain.c index 23d0b63..cf9bd65 100644 --- a/tools/virsh-domain.c +++ b/tools/virsh-domain.c @@ -11177,11 +11177,10 @@ vshFindDisk(const char *doc, } typedef enum { - VSH_PREPARE_DISK_XML_NONE = 0, - VSH_PREPARE_DISK_XML_EJECT, - VSH_PREPARE_DISK_XML_INSERT, - VSH_PREPARE_DISK_XML_UPDATE, -} vshPrepareDiskXMLType; + VSH_UPDATE_DISK_XML_EJECT, + VSH_UPDATE_DISK_XML_INSERT, + VSH_UPDATE_DISK_XML_UPDATE, +} vshUpdateDiskXMLType; /* Helper function to prepare disk XML. Could be used for disk * detaching, media changing(ejecting, inserting, updating) @@ -11189,15 +11188,14 @@ typedef enum { * success, or NULL on failure. Caller must free the result. */ static char * -vshPrepareDiskXML(xmlNodePtr disk_node, - const char *source, - const char *path, - int type) +vshUpdateDiskXML(xmlNodePtr disk_node, + const char *new_source, + bool source_block, + const char *target, + vshUpdateDiskXMLType type) { - xmlNodePtr cur = NULL; - char *disk_type = NULL; + xmlNodePtr source = NULL; char *device_type = NULL; - xmlNodePtr new_node = NULL; char *ret = NULL; if (!disk_node) @@ -11205,62 +11203,64 @@ vshPrepareDiskXML(xmlNodePtr disk_node, device_type = virXMLPropString(disk_node, "device"); - if (STREQ_NULLABLE(device_type, "cdrom") || - STREQ_NULLABLE(device_type, "floppy")) { - bool has_source = false; - disk_type = virXMLPropString(disk_node, "type"); + if (!(STREQ_NULLABLE(device_type, "cdrom") || + STREQ_NULLABLE(device_type, "floppy"))) { + vshError(NULL, _("The disk device '%s' is not removable"), target); + goto cleanup; + } - cur = disk_node->children; - while (cur != NULL) { - if (cur->type == XML_ELEMENT_NODE && - xmlStrEqual(cur->name, BAD_CAST "source")) { - has_source = true; - break; - } - cur = cur->next; + /* find the current source subelement */ + for (source = disk_node->children; source; source = source->next) { + if (source->type == XML_ELEMENT_NODE && + xmlStrEqual(source->name, BAD_CAST "source")) + break; + } + + if (type == VSH_UPDATE_DISK_XML_EJECT) { + if (!source) { + vshError(NULL, _("The disk device '%s' doesn't have media"), target); + goto cleanup; } - if (!has_source) { - if (type == VSH_PREPARE_DISK_XML_EJECT) { - vshError(NULL, _("The disk device '%s' doesn't have media"), - path); - goto cleanup; - } + /* forcibly switch to empty file cdrom */ + source_block = false; + new_source = NULL; + } else if (!new_source) { + vshError(NULL, _("New disk media source was not specified")); + goto cleanup; + } - if (source) { - new_node = xmlNewNode(NULL, BAD_CAST "source"); - if (STREQ(disk_type, "block")) - xmlNewProp(new_node, BAD_CAST "dev", BAD_CAST source); - else - xmlNewProp(new_node, BAD_CAST disk_type, BAD_CAST source); - xmlAddChild(disk_node, new_node); - } else if (type == VSH_PREPARE_DISK_XML_INSERT) { - vshError(NULL, _("No source is specified for inserting media")); - goto cleanup; - } else if (type == VSH_PREPARE_DISK_XML_UPDATE) { - vshError(NULL, _("No source is specified for updating media")); - goto cleanup; - } - } + if (type == VSH_UPDATE_DISK_XML_INSERT && source) { + vshError(NULL, _("The disk device '%s' already has media"), target); + goto cleanup; + } - if (has_source) { - if (type == VSH_PREPARE_DISK_XML_INSERT) { - vshError(NULL, _("The disk device '%s' already has media"), - path); - goto cleanup; - } + /* remove current source */ + if (source) { + xmlUnlinkNode(source); + xmlFreeNode(source); + source = NULL; + } - /* Remove the source if it tends to eject/update media. */ - xmlUnlinkNode(cur); - xmlFreeNode(cur); + /* set the correct disk type */ + if (source_block) + xmlSetProp(disk_node, BAD_CAST "type", BAD_CAST "block"); + else + xmlSetProp(disk_node, BAD_CAST "type", BAD_CAST "file"); - if (source && (type == VSH_PREPARE_DISK_XML_UPDATE)) { - new_node = xmlNewNode(NULL, BAD_CAST "source"); - xmlNewProp(new_node, (const xmlChar *)disk_type, - (const xmlChar *)source); - xmlAddChild(disk_node, new_node); - } + if (new_source) { + /* create new source subelement */ + if (!(source = xmlNewNode(NULL, BAD_CAST "source"))) { + vshError(NULL, _("Failed to allocate new source node")); + goto cleanup; } + + if (source_block) + xmlNewProp(source, BAD_CAST "dev", BAD_CAST new_source); + else + xmlNewProp(source, BAD_CAST "file", BAD_CAST new_source); + + xmlAddChild(disk_node, source); } if (!(ret = virXMLNodeToString(NULL, disk_node))) { @@ -11270,7 +11270,6 @@ vshPrepareDiskXML(xmlNodePtr disk_node, cleanup: VIR_FREE(device_type); - VIR_FREE(disk_type); return ret; } @@ -12278,6 +12277,10 @@ static const vshCmdOptDef opts_change_media[] = { .type = VSH_OT_BOOL, .help = N_("print XML document rather than change media") }, + {.name = "block", + .type = VSH_OT_BOOL, + .help = N_("source media is a block device") + }, {.name = NULL} }; @@ -12291,7 +12294,7 @@ cmdChangeMedia(vshControl *ctl, const vshCmd *cmd) xmlNodePtr disk_node = NULL; char *disk_xml = NULL; bool ret = false; - int prepare_type = 0; + vshUpdateDiskXMLType update_type; const char *action = NULL; bool config = vshCommandOptBool(cmd, "config"); bool live = vshCommandOptBool(cmd, "live"); @@ -12300,24 +12303,27 @@ cmdChangeMedia(vshControl *ctl, const vshCmd *cmd) bool eject = vshCommandOptBool(cmd, "eject"); bool insert = vshCommandOptBool(cmd, "insert"); bool update = vshCommandOptBool(cmd, "update"); + bool block = vshCommandOptBool(cmd, "block"); unsigned int flags = VIR_DOMAIN_AFFECT_CURRENT; VSH_EXCLUSIVE_OPTIONS_VAR(eject, insert); VSH_EXCLUSIVE_OPTIONS_VAR(eject, update); VSH_EXCLUSIVE_OPTIONS_VAR(insert, update); + VSH_EXCLUSIVE_OPTIONS_VAR(eject, block); + if (eject) { - prepare_type = VSH_PREPARE_DISK_XML_EJECT; + update_type = VSH_UPDATE_DISK_XML_EJECT; action = "eject"; } if (insert) { - prepare_type = VSH_PREPARE_DISK_XML_INSERT; + update_type = VSH_UPDATE_DISK_XML_INSERT; action = "insert"; } if (update || (!eject && !insert)) { - prepare_type = VSH_PREPARE_DISK_XML_UPDATE; + update_type = VSH_UPDATE_DISK_XML_UPDATE; action = "update"; } @@ -12332,7 +12338,7 @@ cmdChangeMedia(vshControl *ctl, const vshCmd *cmd) flags |= VIR_DOMAIN_DEVICE_MODIFY_FORCE; if (!(dom = vshCommandOptDomain(ctl, cmd, NULL))) - goto cleanup; + return false; if (vshCommandOptStringReq(ctl, cmd, "path", &path) < 0) goto cleanup; @@ -12340,11 +12346,6 @@ cmdChangeMedia(vshControl *ctl, const vshCmd *cmd) if (vshCommandOptStringReq(ctl, cmd, "source", &source) < 0) goto cleanup; - if (insert && !source) { - vshError(ctl, "%s", _("No disk source specified for inserting")); - goto cleanup; - } - if (flags & VIR_DOMAIN_AFFECT_CONFIG) doc = virDomainGetXMLDesc(dom, VIR_DOMAIN_XML_INACTIVE); else @@ -12355,7 +12356,8 @@ cmdChangeMedia(vshControl *ctl, const vshCmd *cmd) if (!(disk_node = vshFindDisk(doc, path, VSH_FIND_DISK_CHANGEABLE))) goto cleanup; - if (!(disk_xml = vshPrepareDiskXML(disk_node, source, path, prepare_type))) + if (!(disk_xml = vshUpdateDiskXML(disk_node, source, block, path, + update_type))) goto cleanup; if (vshCommandOptBool(cmd, "print-xml")) { @@ -12375,8 +12377,7 @@ cmdChangeMedia(vshControl *ctl, const vshCmd *cmd) VIR_FREE(doc); xmlFreeNode(disk_node); VIR_FREE(disk_xml); - if (dom) - virDomainFree(dom); + virDomainFree(dom); return ret; } diff --git a/tools/virsh.pod b/tools/virsh.pod index 7d43f6f..ede1226 100644 --- a/tools/virsh.pod +++ b/tools/virsh.pod @@ -2581,11 +2581,13 @@ expected. =item B<change-media> I<domain> I<path> [I<--eject>] [I<--insert>] [I<--update>] [I<source>] [I<--force>] [[I<--live>] [I<--config>] | [I<--current>]] -[I<--print-xml>] +[I<--print-xml>] [I<--block>] Change media of CDROM or floppy drive. I<path> can be the fully-qualified path or the unique target name (<target dev='hdc'>) of the disk device. I<source> -specifies the path of the media to be inserted or updated. +specifies the path of the media to be inserted or updated. Flag I<--block> +allows to set the backing type in case a block device is used as media for the +CDROM or floppy drive instead of a file. I<--eject> indicates the media will be ejected. I<--insert> indicates the media will be inserted. I<source> must be specified. -- 2.2.2

--- src/qemu/qemu_hotplug.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/qemu/qemu_hotplug.c b/src/qemu/qemu_hotplug.c index 6ad48f7..29e0fe3 100644 --- a/src/qemu/qemu_hotplug.c +++ b/src/qemu/qemu_hotplug.c @@ -222,7 +222,7 @@ qemuDomainChangeEjectableMedia(virQEMUDriverPtr driver, goto error; } - if (!virStorageSourceIsLocalStorage(newsrc) || newsrc->path) { + if (!virStorageSourceIsEmpty(newsrc)) { if (qemuGetDriveSourceString(newsrc, conn, &sourcestr) < 0) goto error; -- 2.2.2

Only selected fields from the disk source were copied when cold updating source in a CDROM drive. When such drive was backed by a network file this resulted into corruption of the definition: <disk type='network' device='cdrom'> <driver name='qemu' type='raw' cache='none'/> <source protocol='gluster' name='gluster-vol1(null)'> <host name='localhost'/> </source> <target dev='vdc' bus='virtio'/> <readonly/> <address type='pci' domain='0x0000' bus='0x00' slot='0x0a' function='0x0'/> </disk> Update the whole source instead of cherry-picking elements. Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1166024 --- src/qemu/qemu_driver.c | 16 ++++------------ 1 file changed, 4 insertions(+), 12 deletions(-) diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c index b3263ac..0062f36 100644 --- a/src/qemu/qemu_driver.c +++ b/src/qemu/qemu_driver.c @@ -8010,19 +8010,11 @@ qemuDomainUpdateDeviceConfig(virQEMUCapsPtr qemuCaps, * Update 'orig' * We allow updating src/type//driverType/cachemode/ */ - VIR_FREE(orig->src->path); - orig->src->path = disk->src->path; - orig->src->type = disk->src->type; orig->cachemode = disk->cachemode; - if (disk->src->driverName) { - VIR_FREE(orig->src->driverName); - orig->src->driverName = disk->src->driverName; - disk->src->driverName = NULL; - } - if (disk->src->format) - orig->src->format = disk->src->format; - disk->src->path = NULL; - orig->startupPolicy = disk->startupPolicy; + + virStorageSourceFree(orig->src); + orig->src = disk->src; + disk->src = NULL; break; case VIR_DOMAIN_DEVICE_GRAPHICS: -- 2.2.2

If the storage device type is parsed as network our parser still allows it to omit the <source> element. The empty drive check would not trigger on such device as it expects that every network storage source is valid. Use VIR_STORAGE_NET_PROTOCOL_NONE as a marker that the storage source is empty. --- src/util/virstoragefile.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/util/virstoragefile.c b/src/util/virstoragefile.c index 78a7a9f..96be02e 100644 --- a/src/util/virstoragefile.c +++ b/src/util/virstoragefile.c @@ -1989,6 +1989,10 @@ virStorageSourceIsEmpty(virStorageSourcePtr src) if (src->type == VIR_STORAGE_TYPE_NONE) return true; + if (src->type == VIR_STORAGE_TYPE_NETWORK && + src->protocol == VIR_STORAGE_NET_PROTOCOL_NONE) + return true; + return false; } -- 2.2.2

Previously we had to check for 3 fields to see if the source was filled. Repurpose one of the variables as a boolean flag and use it instead of combining multiple sources. For the condition that checks that only CDROM/FLOPPY drives can be empty we can use the virStorageSourceIsEmpty() helper. --- src/conf/domain_conf.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c index 127fc91..dee3a00 100644 --- a/src/conf/domain_conf.c +++ b/src/conf/domain_conf.c @@ -5901,7 +5901,7 @@ virDomainDiskDefParseXML(virDomainXMLOptionPtr xmlopt, char *sgio = NULL; char *driverName = NULL; char *driverType = NULL; - const char *source = NULL; + bool source = false; char *target = NULL; char *trans = NULL; char *bus = NULL; @@ -5965,13 +5965,13 @@ virDomainDiskDefParseXML(virDomainXMLOptionPtr xmlopt, cur = node->children; while (cur != NULL) { if (cur->type == XML_ELEMENT_NODE) { - if (!source && !def->src->hosts && !def->src->srcpool && - xmlStrEqual(cur->name, BAD_CAST "source")) { + if (!source && xmlStrEqual(cur->name, BAD_CAST "source")) { sourceNode = cur; if (virDomainDiskSourceParse(cur, ctxt, def->src) < 0) goto error; - source = def->src->path; + + source = true; if (def->src->type == VIR_STORAGE_TYPE_NETWORK) { if (def->src->protocol == VIR_STORAGE_NET_PROTOCOL_ISCSI) @@ -6398,7 +6398,7 @@ virDomainDiskDefParseXML(virDomainXMLOptionPtr xmlopt, /* Only CDROM and Floppy devices are allowed missing source path * to indicate no media present. LUN is for raw access CD-ROMs * that are not attached to a physical device presently */ - if (source == NULL && def->src->hosts == NULL && !def->src->srcpool && + if (virStorageSourceIsEmpty(def->src) && (def->device == VIR_DOMAIN_DISK_DEVICE_DISK || (flags & VIR_DOMAIN_DEF_PARSE_DISK_SOURCE))) { virReportError(VIR_ERR_NO_SOURCE, @@ -6430,7 +6430,7 @@ virDomainDiskDefParseXML(virDomainXMLOptionPtr xmlopt, virReportError(VIR_ERR_NO_TARGET, "%s", tmp); VIR_FREE(tmp); } else { - virReportError(VIR_ERR_NO_TARGET, source ? "%s" : NULL, source); + virReportError(VIR_ERR_NO_TARGET, def->src->path ? "%s" : NULL, def->src->path); } goto error; } -- 2.2.2

On Thu, Mar 12, 2015 at 18:09:52 +0100, Peter Krempa wrote:
It turned out that not only virsh was broken ...
Peter Krempa (7): virsh: domain: Don't use vshPrepareDiskXML for creating XML to detach disk virsh: domain: Add --print-xml flag for command change-media virsh: domain: Fix the change-media command qemu: hotplug: Use checker function to check if disk is empty qemu: driver: Fix cold-update of removable storage devices util: storage: Fix check for empty storage device conf: disk: Simplify checking if source definition was parsed
Ping? anyone willing to review? Peter

On 12.03.2015 18:09, Peter Krempa wrote:
It turned out that not only virsh was broken ...
Peter Krempa (7): virsh: domain: Don't use vshPrepareDiskXML for creating XML to detach disk virsh: domain: Add --print-xml flag for command change-media virsh: domain: Fix the change-media command qemu: hotplug: Use checker function to check if disk is empty qemu: driver: Fix cold-update of removable storage devices util: storage: Fix check for empty storage device conf: disk: Simplify checking if source definition was parsed
src/conf/domain_conf.c | 12 ++-- src/qemu/qemu_driver.c | 16 ++--- src/qemu/qemu_hotplug.c | 2 +- src/util/virstoragefile.c | 4 ++ tools/virsh-domain.c | 171 ++++++++++++++++++++++++---------------------- tools/virsh.pod | 7 +- 6 files changed, 112 insertions(+), 100 deletions(-)
ACK series. Michal

On Tue, Mar 17, 2015 at 16:45:43 +0100, Michal Privoznik wrote:
On 12.03.2015 18:09, Peter Krempa wrote:
It turned out that not only virsh was broken ...
Peter Krempa (7): virsh: domain: Don't use vshPrepareDiskXML for creating XML to detach disk virsh: domain: Add --print-xml flag for command change-media virsh: domain: Fix the change-media command qemu: hotplug: Use checker function to check if disk is empty qemu: driver: Fix cold-update of removable storage devices util: storage: Fix check for empty storage device conf: disk: Simplify checking if source definition was parsed
src/conf/domain_conf.c | 12 ++-- src/qemu/qemu_driver.c | 16 ++--- src/qemu/qemu_hotplug.c | 2 +- src/util/virstoragefile.c | 4 ++ tools/virsh-domain.c | 171 ++++++++++++++++++++++++---------------------- tools/virsh.pod | 7 +- 6 files changed, 112 insertions(+), 100 deletions(-)
ACK series.
Thanks, I've fixed the missing comma and pushed the series. Peter
participants (2)
-
Michal Privoznik
-
Peter Krempa