On 05.02.2016 19:23, Olga Krishtal wrote:
These callbacks let us to create ploop volumes in directory pools.
If a ploop volume was created via buildVol callback, then this volume
is an empty ploop device with DiskDescriptor.xml.
If the volume was created via .buildFrom - then its content is the
same as input volume.

Ploop volume consists of ploop image file and a corresponding
DiskDescriptor.xml file.

Signed-off-by: Olga Krishtal <okrishtal@virtuozzo.com>
---
 src/storage/storage_backend.c    | 90 ++++++++++++++++++++++++++++++++++++++++
 src/storage/storage_backend.h    |  8 ++++
 src/storage/storage_backend_fs.c |  4 +-
 3 files changed, 101 insertions(+), 1 deletion(-)

diff --git a/src/storage/storage_backend.c b/src/storage/storage_backend.c
index c07b642..96bd3fc 100644
--- a/src/storage/storage_backend.c
+++ b/src/storage/storage_backend.c
@@ -773,6 +773,94 @@ virStorageBackendCreateExecCommand(virStoragePoolObjPtr pool,
     return ret;
 }
 
+/* Set up directory for ploop volume. If function fails,
+* volume won't be created.
+*/
Add space before "*". They should be in one line.
+
+static int
+virVolCreateDirForPloop(virStoragePoolObjPtr pool ATTRIBUTE_UNUSED,
+                        virStorageVolDefPtr vol)
+{
+    int err;
+    if ((err = virDirCreate(vol->target.path,
+                           (vol->target.perms->mode == (mode_t) -1 ?
+                           VIR_STORAGE_DEFAULT_VOL_PERM_MODE:
+                           vol->target.perms->mode),
+                           vol->target.perms->uid,
+                           vol->target.perms->gid,
+                           0)) < 0) {
+        return -1;
+    }
+    return 1;
+}
+
Maybe return 0?  Otherwise this function always fails. see src/storage/storage_backend.c line 835

 if (!inputvol) {
        if (!virVolCreateDirForPloop(pool, vol)) {
            virReportError(VIR_ERR_INTERNAL_ERROR,
                    "%s", _("error creating directory for ploop "
                    "ploop init"));
            return -1;
        }
+int virStorageBackendCreatePloop(virConnectPtr conn ATTRIBUTE_UNUSED,
+                           virStoragePoolObjPtr pool,
+                           virStorageVolDefPtr vol,
+                           virStorageVolDefPtr inputvol,
+                           unsigned int flags)
+{
+    int ret = 0;
+    char *size = NULL;
+    char *path = NULL;
+    virCommandPtr cmd = NULL;
+
+    virCheckFlags(0, -1);
+    if (vol->target.format != VIR_STORAGE_FILE_PLOOP) {
+        virReportError(VIR_ERR_INTERNAL_ERROR,
+                       _("unsupported storage vol type %d"),
+                       vol->target.format);
+        return -1;
+    }
+    if (inputvol && inputvol->target.format != VIR_STORAGE_FILE_PLOOP) {
+        virReportError(VIR_ERR_INTERNAL_ERROR,
+                       _("unsupported input storage vol type %d"),
+                       inputvol->target.format);
+        return -1;
+    }
+
+    if (vol->target.encryption != NULL) {
+        virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
+                       "%s", _("encrypted ploop volumes are not supported with"));
+        return -1;
+    }
+
+    if (vol->target.backingStore != NULL) {
+        virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
+                _("copy-on-write ploop is not yet supported"));
+        return -1;
+    }
+
+    if (!inputvol) {
+        if (!virVolCreateDirForPloop(pool, vol)) {
 check ret code like < 0
+            virReportError(VIR_ERR_INTERNAL_ERROR,
+                    "%s", _("error creating directory for ploop "
+                    "ploop init"));
+            return -1;
+        }
+        if (virAsprintf(&path, "%s/%s", vol->target.path, "root.hds") < 0)
+            return -1;
+
+        if (virAsprintf(&size, "%lluM", VIR_DIV_UP(vol->target.capacity, (1024*1024))) < 0) {
+            ret = -1;
+            goto cleanup;
+        }
+
+        cmd = virCommandNewArgList("ploop", "init", "-s", size, "-t", "ext4", path, NULL);
+    } else {
+        vol->target.capacity = inputvol->target.capacity;
+        cmd = virCommandNewArgList("cp", "-r", inputvol->target.path, vol->target.path, NULL);
+    }
+    ret = virCommandRun(cmd, NULL);
+
+ cleanup:
+
+    virCommandFree(cmd);
+    VIR_FREE(size);
+    VIR_FREE(path);
+    return ret;
+}
+
 enum {
     QEMU_IMG_BACKING_FORMAT_NONE = 0,
     QEMU_IMG_BACKING_FORMAT_FLAG,
@@ -1293,6 +1381,8 @@ virStorageBackendGetBuildVolFromFunction(virStorageVolDefPtr vol,
 
     if (vol->type == VIR_STORAGE_VOL_BLOCK)
         return virStorageBackendCreateBlockFrom;
+    if (vol->type == VIR_STORAGE_VOL_PLOOP)
+        return virStorageBackendCreatePloop;
     else
         return virStorageBackendCreateRaw;
 }
diff --git a/src/storage/storage_backend.h b/src/storage/storage_backend.h
index 20e6079..852d6ed 100644
--- a/src/storage/storage_backend.h
+++ b/src/storage/storage_backend.h
@@ -108,6 +108,14 @@ int virStorageBackendCreateRaw(virConnectPtr conn,
                                virStorageVolDefPtr vol,
                                virStorageVolDefPtr inputvol,
                                unsigned int flags);
+
+int virStorageBackendCreatePloop(virConnectPtr conn,
+                                 virStoragePoolObjPtr pool,
+                                 virStorageVolDefPtr vol,
+                                 virStorageVolDefPtr inputvol,
+                                 unsigned int flags);
+
+
 virStorageBackendBuildVolFrom
 virStorageBackendGetBuildVolFromFunction(virStorageVolDefPtr vol,
                                          virStorageVolDefPtr inputvol);
diff --git a/src/storage/storage_backend_fs.c b/src/storage/storage_backend_fs.c
index 525e45c..3487545 100644
--- a/src/storage/storage_backend_fs.c
+++ b/src/storage/storage_backend_fs.c
@@ -1179,7 +1179,9 @@ _virStorageBackendFileSystemVolBuild(virConnectPtr conn,
         create_func = virStorageBackendCreateRaw;
     } else if (vol->target.format == VIR_STORAGE_FILE_DIR) {
         create_func = createFileDir;
-    } else if ((tool_type = virStorageBackendFindFSImageTool(NULL)) != -1) {
+    } else if (vol->target.format == VIR_STORAGE_FILE_PLOOP) {
+        create_func = virStorageBackendCreatePloop;
+    }else if ((tool_type = virStorageBackendFindFSImageTool(NULL)) != -1) {
add space before "else if"
         create_func = virStorageBackendFSImageToolTypeToFunc(tool_type);
 
         if (!create_func)