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