Resolves:https://bugzilla.redhat.com/show_bug.cgi?id=923053 When cdrom is block type, the virsh change-media failed to insert source info because virsh uses "<source block='/dev/sdb'/>" while the correct name of the attribute for block disks is "dev". Correct XML: <disk type='block' device='cdrom'> <driver name='qemu' type='raw'/> <source dev='/dev/sdb'/> <target dev='vdb' bus='virtio'/> <readonly/> </disk> And, this patch supports cdrom with volume type for change-media command For example: '/var/lib/libvirt/images/boot.iso' is a volume path of 'boot.iso' volume on 'default' pool Virsh command: virsh change-media rhel6qcow2 vdb /var/lib/libvirt/images/boot.iso The updated disk XML: <disk type='volume' device='cdrom'> <driver name='qemu' type='raw'/> <source pool='default' volume='boot.iso'/> <target dev='vdb' bus='virtio'/> <readonly/> </disk> --- tools/virsh-domain.c | 57 ++++++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 51 insertions(+), 6 deletions(-) diff --git a/tools/virsh-domain.c b/tools/virsh-domain.c index 0402aef..e096270 100644 --- a/tools/virsh-domain.c +++ b/tools/virsh-domain.c @@ -9594,13 +9594,58 @@ typedef enum { VSH_PREPARE_DISK_XML_UPDATE, } vshPrepareDiskXMLType; +static xmlNodePtr +vshPrepareDiskXMLNode(virConnectPtr conn, + const char *disk_type, + const char *source) +{ + xmlNodePtr node; + node = xmlNewNode(NULL, BAD_CAST "source"); + + if (STREQ(disk_type, "volume")) { + virStoragePoolPtr pool; + virStorageVolPtr vol; + vol = virStorageVolLookupByPath(conn, source); + + if (vol == NULL) { + vshError(NULL, _("failed to get vol '%s'"), source); + goto error; + } + + pool = virStoragePoolLookupByVolume(vol); + if (pool == NULL) { + vshError(NULL, "%s", _("failed to get parent pool")); + virStorageVolFree(vol); + goto error; + } + + xmlNewProp(node, BAD_CAST "pool", BAD_CAST virStoragePoolGetName(pool)); + xmlNewProp(node, BAD_CAST "volume", BAD_CAST virStorageVolGetName(vol)); + + virStoragePoolFree(pool); + virStorageVolFree(vol); + + } else if (STREQ(disk_type, "block")) { + xmlNewProp(node, BAD_CAST "dev",BAD_CAST source); + } else { + xmlNewProp(node, BAD_CAST disk_type, BAD_CAST source); + } + + return node; + +error: + xmlFreeNode(node); + return NULL; +} + /* Helper function to prepare disk XML. Could be used for disk * detaching, media changing(ejecting, inserting, updating) * for changeable disk. Returns the processed XML as string on * success, or NULL on failure. Caller must free the result. */ static char * -vshPrepareDiskXML(xmlNodePtr disk_node, +vshPrepareDiskXML(vshControl *ctl, + xmlNodePtr disk_node, const char *source, const char *path, int type) @@ -9646,9 +9691,9 @@ vshPrepareDiskXML(xmlNodePtr disk_node, } if (source) { - new_node = xmlNewNode(NULL, BAD_CAST "source"); - xmlNewProp(new_node, (const xmlChar *)disk_type, - (const xmlChar *)source); + new_node = vshPrepareDiskXMLNode(ctl->conn, disk_type, source); + if (new_node == NULL) + goto error; xmlAddChild(disk_node, new_node); } else if (type == VSH_PREPARE_DISK_XML_INSERT) { vshError(NULL, _("No source is specified for inserting media")); @@ -9793,7 +9838,7 @@ 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, + if (!(disk_xml = vshPrepareDiskXML(ctl, disk_node, NULL, NULL, VSH_PREPARE_DISK_XML_NONE))) goto cleanup; @@ -10012,7 +10057,7 @@ 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 = vshPrepareDiskXML(ctl, disk_node, source, path, prepare_type))) goto cleanup; if (virDomainUpdateDeviceFlags(dom, disk_xml, flags) != 0) { -- 1.8.1.4 -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list