[libvirt] [PATCH v3 11/13] parallels: add support of disks creation

Dmitry Guryanov dguryanov at parallels.com
Wed Nov 28 09:30:33 UTC 2012


Implement creation of new disks - if a new disk found
in configuration, find a volume by disk path and
actually create a disk image by issuing prlctl command.
If it's successfully finished - remove the file with volume
definition.

Signed-off-by: Dmitry Guryanov <dguryanov at parallels.com>
---
 src/parallels/parallels_driver.c |  107 +++++++++++++++++++++++++++++++++----
 1 files changed, 95 insertions(+), 12 deletions(-)

diff --git a/src/parallels/parallels_driver.c b/src/parallels/parallels_driver.c
index 967f545..fe034f6 100644
--- a/src/parallels/parallels_driver.c
+++ b/src/parallels/parallels_driver.c
@@ -1499,18 +1499,88 @@ parallelsApplyVideoParams(parallelsDomObjPtr pdom,
     return 0;
 }
 
-static int
-parallelsApplyDisksParams(parallelsDomObjPtr pdom,
-                          virDomainDiskDefPtr *olddisks, int nold,
-                          virDomainDiskDefPtr *newdisks, int nnew)
+static int parallelsAddHddByVolume(parallelsDomObjPtr pdom,
+                                   virDomainDiskDefPtr disk,
+                                   virStoragePoolObjPtr pool,
+                                   virStorageVolDefPtr voldef)
 {
-    /* TODO: allow creating and removing disks */
-    if (nold != nnew) {
-        virReportError(VIR_ERR_ARGUMENT_UNSUPPORTED, "%s",
-                       _("Adding and removing disks is not supported"));
+    int ret = -1;
+    virCommandPtr cmd = virCommandNewArgList(PRLCTL, "set", pdom->uuid,
+                                             "--device-add", "hdd", NULL);
+    virCommandAddArgFormat(cmd, "--size=%lluM", voldef->capacity >> 20);
+
+    const char *strbus;
+
+    if (!(strbus = parallelsGetDiskBusName(disk->bus))) {
+        virReportError(VIR_ERR_ARGUMENT_UNSUPPORTED,
+                       _("Invalid disk bus: %d"), disk->bus);
+        goto cleanup;
+    }
+
+    virCommandAddArgFormat(cmd, "--iface=%s", strbus);
+
+    if (disk->info.type == VIR_DOMAIN_DEVICE_ADDRESS_TYPE_DRIVE)
+        virCommandAddArgFormat(cmd, "--position=%d",
+                               disk->info.addr.drive.target);
+
+    if (virCommandRun(cmd, NULL))
+        goto cleanup;
+
+    if (parallelsStorageVolumeDefRemove(pool, voldef))
+        goto cleanup;
+
+    ret = 0;
+cleanup:
+    virCommandFree(cmd);
+    return ret;
+}
+
+static int parallelsAddHdd(virConnectPtr conn,
+                           parallelsDomObjPtr pdom,
+                           virDomainDiskDefPtr disk)
+{
+    parallelsConnPtr privconn = conn->privateData;
+    virStorageVolDefPtr voldef = NULL;
+    virStoragePoolObjPtr pool = NULL;
+    virStorageVolPtr vol = NULL;
+    int ret = -1;
+
+    if (!(vol = parallelsStorageVolumeLookupByPathLocked(conn, disk->src))) {
+        virReportError(VIR_ERR_INVALID_ARG,
+                       _("Can't find volume with path '%s'"), disk->src);
         return -1;
     }
 
+    pool = virStoragePoolObjFindByName(&privconn->pools, vol->pool);
+    if (!pool) {
+        virReportError(VIR_ERR_INVALID_ARG,
+                       _("Can't find storage pool with name '%s'"),
+                       vol->pool);
+        goto cleanup;
+    }
+
+    voldef = virStorageVolDefFindByPath(pool, disk->src);
+    if (!voldef) {
+        virReportError(VIR_ERR_INVALID_ARG,
+                       _("Can't find storage volume definition for path '%s'"),
+                       disk->src);
+        goto cleanup;
+    }
+
+    ret = parallelsAddHddByVolume(pdom, disk, pool, voldef);
+
+cleanup:
+    if (pool)
+        virStoragePoolObjUnlock(pool);
+    virObjectUnref(vol);
+    return ret;
+}
+
+static int
+parallelsApplyDisksParams(virConnectPtr conn, parallelsDomObjPtr pdom,
+                          virDomainDiskDefPtr *olddisks, int nold,
+                          virDomainDiskDefPtr *newdisks, int nnew)
+{
     for (int i = 0; i < nold; i++) {
         virDomainDiskDefPtr newdisk = NULL;
         virDomainDiskDefPtr olddisk = olddisks[i];
@@ -1544,7 +1614,7 @@ parallelsApplyDisksParams(parallelsDomObjPtr pdom,
 
             if (!(strbus = parallelsGetDiskBusName(newdisk->bus))) {
                 virReportError(VIR_ERR_ARGUMENT_UNSUPPORTED,
-                               _("Unsupported disk bus: %d", newdisk->bus));
+                               _("Unsupported disk bus: %d"), newdisk->bus);
                 return -1;
             }
 
@@ -1557,11 +1627,24 @@ parallelsApplyDisksParams(parallelsDomObjPtr pdom,
         }
     }
 
+    for (int i = 0; i < nnew; i++) {
+        virDomainDiskDefPtr newdisk = newdisks[i];
+        bool found = false;
+        for (int j = 0; j < nold; j++)
+            if (STREQ_NULLABLE(olddisks[j]->dst, newdisk->dst))
+                found = true;
+        if (found)
+            continue;
+
+        if (parallelsAddHdd(conn, pdom, newdisk))
+            return -1;
+    }
+
     return 0;
 }
 
 static int
-parallelsApplyChanges(virDomainObjPtr dom, virDomainDefPtr new)
+parallelsApplyChanges(virConnectPtr conn, virDomainObjPtr dom, virDomainDefPtr new)
 {
     char buf[32];
 
@@ -1794,7 +1877,7 @@ parallelsApplyChanges(virDomainObjPtr dom, virDomainDefPtr new)
     if (parallelsApplyVideoParams(pdom, old->videos, old->nvideos,
                                    new->videos, new->nvideos) < 0)
         return -1;
-    if (parallelsApplyDisksParams(pdom, old->disks, old->ndisks,
+    if (parallelsApplyDisksParams(conn, pdom, old->disks, old->ndisks,
                                   new->disks, new->ndisks) < 0)
         return -1;
 
@@ -1928,7 +2011,7 @@ parallelsDomainDefineXML(virConnectPtr conn, const char *xml)
 
     if (dupVM == 1) {
         olddom = virDomainFindByUUID(&privconn->domains, def->uuid);
-        if (parallelsApplyChanges(olddom, def) < 0) {
+        if (parallelsApplyChanges(conn, olddom, def) < 0) {
             virDomainObjUnlock(olddom);
             goto cleanup;
         }
-- 
1.7.7.6




More information about the libvir-list mailing list