[libvirt] [PATCH v3 9/9] pvs: implement VM creation

Dmitry Guryanov dguryanov at parallels.com
Thu Apr 19 16:06:05 UTC 2012


To create a new VM in PVS we should issue "prlctl create" command,
and give path to the directory, where VM should be created. VM's
storage will be in that directory later. So in this first version
find out location of first VM's hard disk and create VM there.

Signed-off-by: Dmitry Guryanov <dguryanov at parallels.com>
---
 src/pvs/pvs_driver.c  |   78 ++++++++++++++++++++++++++++++++++++++++++++++++-
 src/pvs/pvs_driver.h  |    4 ++
 src/pvs/pvs_storage.c |    6 +---
 3 files changed, 82 insertions(+), 6 deletions(-)

diff --git a/src/pvs/pvs_driver.c b/src/pvs/pvs_driver.c
index 68dca1a..ff438f0 100644
--- a/src/pvs/pvs_driver.c
+++ b/src/pvs/pvs_driver.c
@@ -1098,6 +1098,74 @@ pvsApplyChanges(virDomainObjPtr dom, virDomainDefPtr newdef)
     return 0;
 }
 
+static int
+pvsCreateVm(virConnectPtr conn, virDomainDefPtr def)
+{
+    pvsConnPtr privconn = conn->privateData;
+    int i;
+    virStorageVolDefPtr privvol = NULL;
+    virStoragePoolObjPtr pool = NULL;
+    virStorageVolPtr vol = NULL;
+    char uuidstr[VIR_UUID_STRING_BUFLEN];
+
+    for (i = 0; i < def->ndisks; i++) {
+        if (def->disks[i]->device != VIR_DOMAIN_DISK_DEVICE_DISK)
+            continue;
+
+        vol = pvsStorageVolumeLookupByPathLocked(conn, def->disks[i]->src);
+        if (!vol) {
+            pvsError(VIR_ERR_INVALID_ARG,
+                     _("Can't find volume with path '%s'"),
+                     def->disks[i]->src);
+            return -1;
+        }
+        break;
+    }
+
+    if (!vol) {
+        pvsError(VIR_ERR_INVALID_ARG,
+                 _("Can't create VM without hard disks"));
+        return -1;
+    }
+
+    pool = virStoragePoolObjFindByName(&privconn->pools, vol->pool);
+    if (!pool) {
+        pvsError(VIR_ERR_INVALID_ARG,
+                 _("Can't find storage pool with name '%s'"),
+                 vol->pool);
+        goto error;
+    }
+
+    privvol = virStorageVolDefFindByPath(pool, def->disks[i]->src);
+    if (!privvol) {
+        pvsError(VIR_ERR_INVALID_ARG,
+                 _("Can't find storage volume definition for path '%s'"),
+                 def->disks[i]->src);
+        goto error2;
+    }
+
+    virUUIDFormat(def->uuid, uuidstr);
+
+    if (pvsCmdRun(PRLCTL, "create", def->name, "--dst",
+                  pool->def->target.path, "--no-hdd",
+                  "--uuid", uuidstr, NULL) < 0)
+        goto error2;
+
+    if (pvsCmdRun(PRLCTL, "set", def->name, "--vnc-mode", "auto", NULL) < 0)
+        goto error2;
+
+    virStoragePoolObjUnlock(pool);
+    virUnrefStorageVol(vol);
+
+    return 0;
+
+  error2:
+    virStoragePoolObjUnlock(pool);
+  error:
+    virUnrefStorageVol(vol);
+    return -1;
+}
+
 static virDomainPtr
 pvsDomainDefineXML(virConnectPtr conn, const char *xml)
 {
@@ -1134,8 +1202,16 @@ pvsDomainDefineXML(virConnectPtr conn, const char *xml)
 
         def = NULL;
     } else {
-        pvsError(VIR_ERR_NO_SUPPORT, _("Not implemented yet"));
+        if (pvsCreateVm(conn, def))
             goto cleanup;
+        if (pvsLoadDomains(privconn, def->name))
+            goto cleanup;
+        dom = virDomainFindByName(&privconn->domains, def->name);
+        if (!dom) {
+            pvsError(VIR_ERR_INTERNAL_ERROR,
+                     _("Domain is not defined after creation"));
+            goto cleanup;
+        }
     }
 
     event = virDomainEventNewFromObj(dom,
diff --git a/src/pvs/pvs_driver.h b/src/pvs/pvs_driver.h
index 40ab546..63f3ad1 100644
--- a/src/pvs/pvs_driver.h
+++ b/src/pvs/pvs_driver.h
@@ -67,5 +67,9 @@ int pvsCmdRun(const char *binary, ...);
 char * pvsAddFileExt(const char *path, const char *ext);
 void pvsDriverLock(pvsConnPtr driver);
 void pvsDriverUnlock(pvsConnPtr driver);
+virStorageVolPtr pvsStorageVolumeLookupByPathLocked(virConnectPtr
+                                                           conn,
+                                                           const char
+                                                           *path);
 
 #endif
diff --git a/src/pvs/pvs_storage.c b/src/pvs/pvs_storage.c
index fc1e2c8..75928b4 100644
--- a/src/pvs/pvs_storage.c
+++ b/src/pvs/pvs_storage.c
@@ -41,10 +41,6 @@ static virStorageVolDefPtr pvsStorageVolumeDefine(virStoragePoolObjPtr pool,
                                                   const char *xmldesc,
                                                   const char *xmlfile,
                                                   bool is_new);
-static virStorageVolPtr pvsStorageVolumeLookupByPathLocked(virConnectPtr
-                                                           conn,
-                                                           const char
-                                                           *path);
 static virStorageVolPtr pvsStorageVolumeLookupByPath(virConnectPtr conn,
                                                      const char *path);
 static int pvsStoragePoolGetAlloc(virStoragePoolDefPtr def);
@@ -941,7 +937,7 @@ pvsStorageVolumeLookupByKey(virConnectPtr conn, const char *key)
     return ret;
 }
 
-static virStorageVolPtr
+virStorageVolPtr
 pvsStorageVolumeLookupByPathLocked(virConnectPtr conn, const char *path)
 {
     pvsConnPtr privconn = conn->privateData;
-- 
1.7.1




More information about the libvir-list mailing list