[libvirt] [PATCH 3/3] virsh: fix change-media bug on disk block type and support volume type

Guannan Ren gren at redhat.com
Mon May 27 12:55:03 UTC 2013


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




More information about the libvir-list mailing list