On 17.02.2016 14:40, 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(a)virtuozzo.com>
---
src/storage/storage_backend.c | 100 ++++++++++++++++++++++++++++++++++++++-
src/storage/storage_backend.h | 8 ++++
src/storage/storage_backend_fs.c | 2 +
3 files changed, 109 insertions(+), 1 deletion(-)
diff --git a/src/storage/storage_backend.c b/src/storage/storage_backend.c
index c07b642..d70642e 100644
--- a/src/storage/storage_backend.c
+++ b/src/storage/storage_backend.c
@@ -773,6 +773,103 @@ virStorageBackendCreateExecCommand(virStoragePoolObjPtr pool,
return ret;
}
+/* Set up directory for ploop volume. If function fails,
+ * volume won't be created.
+ */
+
+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,
you need to change indent back to function level from ternary operator
+ vol->target.perms->gid,
+ 0)) < 0) {
+ return -1;
+ }
+ return 0;
+}
+
+int virStorageBackendCreatePloop(virConnectPtr conn ATTRIBUTE_UNUSED,
+ virStoragePoolObjPtr pool,
+ virStorageVolDefPtr vol,
+ virStorageVolDefPtr inputvol,
+ unsigned int flags)
+{
+ int ret = -1;
+ char *size = NULL;
+ char *path = NULL;
+ virCommandPtr cmd = NULL;
+ char *create_tool = NULL;
+
+ virCheckFlags(0, -1);
+
+ create_tool = virFindFileInPath("ploop");
+ if (!create_tool && !inputvol) {
+ virReportError(VIR_ERR_INTERNAL_ERROR,
+ "%s", _("unable to find ploop, please install
"
+ "ploop tools"));
+ 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 "
+ "ploop init"));
+ return -1;
+ }
+
+ if (vol->target.backingStore != NULL) {
+ virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
+ _("copy-on-write ploop volumes are not yet
supported"));
+ return -1;
+ }
+
+ if (!inputvol) {
+ if (virVolCreateDirForPloop(pool, vol) < 0) {
+ virReportError(VIR_ERR_INTERNAL_ERROR,
+ "%s", _("error creating directory for ploop
volume"));
indentation
+ return -1;
+ }
+ if (virAsprintf(&path, "%s/root.hds", vol->target.path) <
0)
+ return -1;
you don't remove created dir on this return path
+
+ if (virAsprintf(&size, "%lluM",
VIR_DIV_UP(vol->target.capacity,
+ (1024 * 1024))) < 0) {
+ goto cleanup;
+ }
use virCommandAddArgFormat instead of series of virAsprintf
+
+ cmd = virCommandNewArgList(create_tool, "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);
if target directory exists you will not get what you want. I think
best would be to create dir before branching.
+ }
+ ret = virCommandRun(cmd, NULL);
+ if (ret < 0)
+ virFileDeleteTree(vol->target.path);
+
+ cleanup:
+
+ virCommandFree(cmd);
+ VIR_FREE(size);
+ VIR_FREE(path);
+ VIR_FREE(create_tool);
+ return ret;
+}
+
enum {
QEMU_IMG_BACKING_FORMAT_NONE = 0,
QEMU_IMG_BACKING_FORMAT_FLAG,
@@ -1280,7 +1377,8 @@ virStorageBackendGetBuildVolFromFunction(virStorageVolDefPtr vol,
vol->target.format != VIR_STORAGE_FILE_RAW) ||
(inputvol->type == VIR_STORAGE_VOL_FILE &&
inputvol->target.format != VIR_STORAGE_FILE_RAW)) {
-
+ if (vol->target.format == VIR_STORAGE_FILE_PLOOP)
+ return virStorageBackendCreatePloop;
if ((tool_type = virStorageBackendFindFSImageTool(NULL)) < 0) {
virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
_("creation of non-raw file images is "
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 692c9ff..80c7e9e 100644
--- a/src/storage/storage_backend_fs.c
+++ b/src/storage/storage_backend_fs.c
@@ -1177,6 +1177,8 @@ _virStorageBackendFileSystemVolBuild(virConnectPtr conn,
create_func = virStorageBackendCreateRaw;
} else if (vol->target.format == VIR_STORAGE_FILE_DIR) {
create_func = createFileDir;
+ } else if (vol->target.format == VIR_STORAGE_FILE_PLOOP) {
+ create_func = virStorageBackendCreatePloop;
} else if ((tool_type = virStorageBackendFindFSImageTool(NULL)) != -1) {
create_func = virStorageBackendFSImageToolTypeToFunc(tool_type);