]> git.ipfire.org Git - thirdparty/libvirt.git/commitdiff
vz: support filesystem type volume
authorOlga Krishtal <okrishtal@virtuozzo.com>
Thu, 14 Jul 2016 13:52:41 +0000 (16:52 +0300)
committerMaxim Nestratov <mnestratov@virtuozzo.com>
Mon, 18 Jul 2016 20:39:57 +0000 (23:39 +0300)
Vz containers are able to use ploop volumes from storage pools
to work upon.

To use filesystem type volume, pool name and volume name should be
specifaed in <source> :
   <filesystem type='volume' accessmode='passthrough'>
      <driver type='ploop' format='ploop'/>
      <source pool='guest_images' volume='TEST_POOL_CT'/>
      <target dir='/'/>
   </filesystem>

The information about pool and volume is stored in ct dom configuration:
<StorageURL>libvirt://localhost/pool_name/vol_name</StorageURL>
and can be easily obtained via PrlVmDevHd_GetStorageURL sdk call.

The only shorcoming: if storage pool is moved somewhere the ct
should be redefined in order to refresh the information aboot path
to root.hdd

Signed-off-by: Olga Krishtal <okrishtal@virtuozzo.com>
src/storage/storage_driver.c
src/vz/vz_driver.c
src/vz/vz_sdk.c
src/vz/vz_sdk.h

index cb9d5784d6b558bf6a019184a8b459218dd93dda..dedc5c65ca648ce852d260f07e16152562bcff73 100644 (file)
@@ -3509,6 +3509,10 @@ virStorageTranslateDiskSourcePool(virConnectPtr conn,
             def->src->srcpool->actualtype = VIR_STORAGE_TYPE_BLOCK;
             break;
 
+        case VIR_STORAGE_VOL_PLOOP:
+            def->src->srcpool->actualtype = VIR_STORAGE_TYPE_FILE;
+            break;
+
         case VIR_STORAGE_VOL_NETWORK:
         case VIR_STORAGE_VOL_NETDIR:
             virReportError(VIR_ERR_INTERNAL_ERROR,
index 46798fd286c0a41890f546821106360361710f3d..ce358e78f1028af58ee71bb700975d67a47d0a77 100644 (file)
@@ -762,7 +762,7 @@ vzDomainDefineXMLFlags(virConnectPtr conn, const char *xml, unsigned int flags)
             if (prlsdkCreateVm(driver, def))
                 goto cleanup;
         } else if (def->os.type == VIR_DOMAIN_OSTYPE_EXE) {
-            if (prlsdkCreateCt(driver, def))
+            if (prlsdkCreateCt(conn, def))
                 goto cleanup;
         } else {
             virReportError(VIR_ERR_INVALID_ARG,
index 895199299608df89e6485caf89d0f2f2e914dfd2..be164e29cd7f00cdf8850d14b90ec8e3e719fa33 100644 (file)
@@ -33,6 +33,7 @@
 #include "virtime.h"
 #include "virhostcpu.h"
 
+#include "storage/storage_driver.h"
 #include "vz_sdk.h"
 
 #define VIR_FROM_THIS VIR_FROM_PARALLELS
@@ -660,6 +661,8 @@ prlsdkGetFSInfo(PRL_HANDLE prldisk,
 {
     char *buf = NULL;
     int ret = -1;
+    char **matches = NULL;
+    virURIPtr uri = NULL;
 
     fs->type = VIR_DOMAIN_FS_TYPE_FILE;
     fs->fsdriver = VIR_DOMAIN_FS_DRIVER_TYPE_PLOOP;
@@ -670,12 +673,51 @@ prlsdkGetFSInfo(PRL_HANDLE prldisk,
     fs->readonly = false;
     fs->symlinksResolved = false;
 
-    if (!(buf = prlsdkGetStringParamVar(PrlVmDev_GetImagePath, prldisk)))
+    if (!(buf = prlsdkGetStringParamVar(PrlVmDevHd_GetStorageURL, prldisk)))
         goto cleanup;
 
-    fs->src->path = buf;
-    buf = NULL;
+    if (!virStringIsEmpty(buf)) {
+        if (!(uri = virURIParse(buf)))
+            goto cleanup;
+        if (STRNEQ("libvirt", uri->scheme)) {
+            virReportError(VIR_ERR_INTERNAL_ERROR,
+                           _("Unknown uri scheme: '%s'"),
+                           uri->scheme);
+            goto cleanup;
+        }
+
+        if (!(matches = virStringSplitCount(uri->path, "/", 0, NULL)) ||
+            !matches[0]) {
+            virReportError(VIR_ERR_INTERNAL_ERROR,
+                           _("splitting StorageUrl failed %s"), uri->path);
+            goto cleanup;
+        }
+        if (!matches[1]) {
+            virReportError(VIR_ERR_INTERNAL_ERROR,
+                           _("can't identify pool in uri %s "), uri->path);
+            goto cleanup;
+        }
+        if (!matches[2]) {
+            virReportError(VIR_ERR_INTERNAL_ERROR,
+                           _("can't identify volume in uri %s"), uri->path);
+            goto cleanup;
+        }
+        fs->type = VIR_DOMAIN_FS_TYPE_VOLUME;
+        if (VIR_ALLOC(fs->src->srcpool) < 0)
+            goto cleanup;
+        if (VIR_STRDUP(fs->src->srcpool->pool, matches[1]) < 0)
+            goto cleanup;
+        if (VIR_STRDUP(fs->src->srcpool->volume, matches[2]) < 0)
+            goto cleanup;
+        VIR_FREE(buf);
+    } else {
+        fs->type = VIR_DOMAIN_FS_TYPE_FILE;
+        if (!(buf = prlsdkGetStringParamVar(PrlVmDev_GetImagePath, prldisk)))
+            goto cleanup;
 
+        fs->src->path = buf;
+        buf = NULL;
+    }
     if (!(buf = prlsdkGetStringParamVar(PrlVmDevHd_GetMountPoint, prldisk)))
         goto cleanup;
 
@@ -686,6 +728,7 @@ prlsdkGetFSInfo(PRL_HANDLE prldisk,
 
  cleanup:
     VIR_FREE(buf);
+    virStringFreeList(matches);
     return ret;
 }
 
@@ -2706,10 +2749,11 @@ static int prlsdkCheckNetUnsupportedParams(virDomainNetDefPtr net)
 
 static int prlsdkCheckFSUnsupportedParams(virDomainFSDefPtr fs)
 {
-    if (fs->type != VIR_DOMAIN_FS_TYPE_FILE) {
+    if (fs->type != VIR_DOMAIN_FS_TYPE_FILE &&
+        fs->type != VIR_DOMAIN_FS_TYPE_VOLUME) {
         virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
-                       _("Only file based filesystems are "
-                         "supported by vz driver."));
+                       _("Only file based or volume based filesystems "
+                         "are supported by vz driver."));
         return -1;
     }
 
@@ -3525,6 +3569,7 @@ prlsdkAddFS(PRL_HANDLE sdkdom, virDomainFSDefPtr fs)
     PRL_RESULT pret;
     PRL_HANDLE sdkdisk = PRL_INVALID_HANDLE;
     int ret = -1;
+    char *storage = NULL;
 
     if (fs->type == VIR_DOMAIN_FS_TYPE_TEMPLATE)
         return 0;
@@ -3535,6 +3580,14 @@ prlsdkAddFS(PRL_HANDLE sdkdom, virDomainFSDefPtr fs)
     pret = PrlVmCfg_CreateVmDev(sdkdom, PDE_HARD_DISK, &sdkdisk);
     prlsdkCheckRetGoto(pret, cleanup);
 
+    if (fs->type == VIR_DOMAIN_FS_TYPE_VOLUME) {
+        if (virAsprintf(&storage, "libvirt://localhost/%s/%s", fs->src->srcpool->pool,
+                        fs->src->srcpool->volume) < 0)
+            goto cleanup;
+        pret = PrlVmDevHd_SetStorageURL(sdkdisk, storage);
+        prlsdkCheckRetGoto(pret, cleanup);
+    }
+
     pret = PrlVmDev_SetEnabled(sdkdisk, 1);
     prlsdkCheckRetGoto(pret, cleanup);
 
@@ -3559,6 +3612,7 @@ prlsdkAddFS(PRL_HANDLE sdkdom, virDomainFSDefPtr fs)
     ret = 0;
 
  cleanup:
+    VIR_FREE(storage);
     PrlHandle_Free(sdkdisk);
     return ret;
 }
@@ -3859,8 +3913,52 @@ prlsdkCreateVm(vzDriverPtr driver, virDomainDefPtr def)
     return ret;
 }
 
+static int
+virStorageTranslatePoolLocal(virConnectPtr conn, virStorageSourcePtr src)
+{
+
+    virStoragePoolPtr pool = NULL;
+    virStorageVolPtr vol = NULL;
+    virStorageVolInfo info;
+    int ret = -1;
+
+    if (!(pool = virStoragePoolLookupByName(conn, src->srcpool->pool)))
+        return -1;
+    if (virStoragePoolIsActive(pool) != 1) {
+        virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
+                       _("storage pool '%s' containing volume '%s' "
+                         "is not active"), src->srcpool->pool,
+                       src->srcpool->volume);
+        goto cleanup;
+    }
+
+    if (!(vol = virStorageVolLookupByName(pool, src->srcpool->volume)))
+        goto cleanup;
+
+    if (virStorageVolGetInfo(vol, &info) < 0)
+        goto cleanup;
+
+    if (info.type != VIR_STORAGE_VOL_PLOOP) {
+        virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
+                       _("Unsupported volume format '%s'"),
+                       virStorageVolTypeToString(info.type));
+        goto cleanup;
+    }
+
+    if (!(src->path = virStorageVolGetPath(vol)))
+        goto cleanup;
+
+    ret = 0;
+
+ cleanup:
+    virObjectUnref(pool);
+    virObjectUnref(vol);
+    return ret;
+}
+
+
 int
-prlsdkCreateCt(vzDriverPtr driver, virDomainDefPtr def)
+prlsdkCreateCt(virConnectPtr conn, virDomainDefPtr def)
 {
     PRL_HANDLE sdkdom = PRL_INVALID_HANDLE;
     PRL_GET_VM_CONFIG_PARAM_DATA confParam;
@@ -3868,6 +3966,8 @@ prlsdkCreateCt(vzDriverPtr driver, virDomainDefPtr def)
     PRL_HANDLE result = PRL_INVALID_HANDLE;
     PRL_RESULT pret;
     PRL_UINT32 flags;
+    vzConnPtr privconn = conn->privateData;
+    vzDriverPtr driver = privconn->driver;
     int ret = -1;
     int useTemplate = 0;
     size_t i;
@@ -3880,6 +3980,11 @@ prlsdkCreateCt(vzDriverPtr driver, virDomainDefPtr def)
         }
         if (def->fss[i]->type == VIR_DOMAIN_FS_TYPE_TEMPLATE)
             useTemplate = 1;
+        if (def->fss[i]->type == VIR_DOMAIN_FS_TYPE_VOLUME) {
+            if (virStorageTranslatePoolLocal(conn, def->fss[i]->src) < 0)
+                goto cleanup;
+        }
+
     }
 
     if (useTemplate && def->nfss > 1) {
index 1ea0be9175d0c7297ed5e4c6e6cf83113ac9983d..2d75f9590cd9722ca2c6f4a7ce7ca32d195e68dd 100644 (file)
@@ -57,7 +57,7 @@ prlsdkApplyConfig(vzDriverPtr driver,
                   virDomainObjPtr dom,
                   virDomainDefPtr new);
 int prlsdkCreateVm(vzDriverPtr driver, virDomainDefPtr def);
-int prlsdkCreateCt(vzDriverPtr driver, virDomainDefPtr def);
+int prlsdkCreateCt(virConnectPtr conn, virDomainDefPtr def);
 int
 prlsdkUnregisterDomain(vzDriverPtr driver, virDomainObjPtr dom, unsigned int flags);
 int