Re: [libvirt] [PATCH 2/7] storage:dir: .buildVol and .buildVolFrom callbacks for ploop
On Mon, Apr 11, 2016 at 07:16:20PM +0300, Olga Krishtal wrote: > These callbacks let us to create ploop volumes in dir, fs and etc. 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 similar to > input volume content. > > Signed-off-by: Olga Krishtal > --- > src/storage/storage_backend.c| 78 > > src/storage/storage_backend.h| 8 + > src/storage/storage_backend_fs.c | 2 ++ > 3 files changed, 88 insertions(+) > > diff --git a/src/storage/storage_backend.c b/src/storage/storage_backend.c > index 231eccf..d109980 100644 > --- a/src/storage/storage_backend.c > +++ b/src/storage/storage_backend.c > @@ -773,6 +773,81 @@ virStorageBackendCreateExecCommand(virStoragePoolObjPtr > pool, > return ret; > } > > +/* Create ploop directory with ploop image and DiskDescriptor.xml > + * if function fails to create image file the directory will be deleted.*/ > +int > +virStorageBackendCreatePloop(virConnectPtr conn ATTRIBUTE_UNUSED, > + virStoragePoolObjPtr pool ATTRIBUTE_UNUSED, > + virStorageVolDefPtr vol, > + virStorageVolDefPtr inputvol, > + unsigned int flags) > +{ > +int ret = -1; > +virCommandPtr cmd = NULL; > +char *create_tool = NULL; > + > +virCheckFlags(0, -1); > + > +if (inputvol && inputvol->target.format != VIR_STORAGE_FILE_PLOOP) { > +virReportError(VIR_ERR_INTERNAL_ERROR, > + _("unsupported input storage vol type %d"), > + inputvol->target.format); > +goto cleanup; > +} > + > +if (vol->target.encryption != NULL) { > +virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", > + _("encrypted ploop volumes are not supported with " > + "ploop init")); > +goto cleanup; > +} > + > +if (vol->target.backingStore != NULL) { > +virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", > + _("copy-on-write ploop volumes are not yet > supported")); > +goto cleanup; > +} > + > +create_tool = virFindFileInPath("ploop"); > +if (!create_tool && !inputvol) { > +virReportError(VIR_ERR_INTERNAL_ERROR, > + "%s", _("unable to find ploop, please install " > + "ploop tools")); > +return ret; > +} > + All the errors above can just 'return -1;', there is nothing to clean up. > +if (!inputvol) { > +if ((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) { > +virReportError(VIR_ERR_INTERNAL_ERROR, "%s", > + _("error creating directory for ploop volume")); > +goto cleanup; > +} > +cmd = virCommandNewArgList(create_tool, "init", "-s", NULL); > +virCommandAddArgFormat(cmd, "%lluM", VIR_DIV_UP(vol->target.capacity, > +(1024 * 1024))); > +virCommandAddArgList(cmd, "-t", "ext4", NULL); > +virCommandAddArgFormat(cmd, "%s/root.hds", vol->target.path); > + > +} 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(create_tool); > +if (ret < 0) > +virFileDeleteTree(vol->target.path); virDirCreate cleans up after itself if it fails - we don't need to delete it in this case. > +return ret; > +} > + > enum { > QEMU_IMG_BACKING_FORMAT_NONE = 0, > QEMU_IMG_BACKING_FORMAT_FLAG, > @@ -1291,6 +1366,9 @@ > virStorageBackendGetBuildVolFromFunction(virStorageVolDefPtr vol, > return virStorageBackendFSImageToolTypeToFunc(tool_type); > } > > +if (vol->type == VIR_STORAGE_VOL_PLOOP && > +inputvol->type == VIR_STORAGE_VOL_PLOOP) After removing the inputvol->type check, libvirt will output the nicer error message in virStorageBackendCreatePloop if it has a different type. > +return virStorageBackendCreatePloop; > if (vol->type == VIR_STORAGE_VOL_BLOCK) > return virStorageBackendCreateBlockFrom; > else I have squashed the following changes in: Jan diff --git a/src/storage/storage_backend.c b/src/storage/storage_backend.c index d109980..6a035a2 100644 --- a/src/storage/sto
[libvirt] [PATCH 2/7] storage:dir: .buildVol and .buildVolFrom callbacks for ploop
These callbacks let us to create ploop volumes in dir, fs and etc. 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 similar to input volume content. Signed-off-by: Olga Krishtal --- src/storage/storage_backend.c| 78 src/storage/storage_backend.h| 8 + src/storage/storage_backend_fs.c | 2 ++ 3 files changed, 88 insertions(+) diff --git a/src/storage/storage_backend.c b/src/storage/storage_backend.c index 231eccf..d109980 100644 --- a/src/storage/storage_backend.c +++ b/src/storage/storage_backend.c @@ -773,6 +773,81 @@ virStorageBackendCreateExecCommand(virStoragePoolObjPtr pool, return ret; } +/* Create ploop directory with ploop image and DiskDescriptor.xml + * if function fails to create image file the directory will be deleted.*/ +int +virStorageBackendCreatePloop(virConnectPtr conn ATTRIBUTE_UNUSED, + virStoragePoolObjPtr pool ATTRIBUTE_UNUSED, + virStorageVolDefPtr vol, + virStorageVolDefPtr inputvol, + unsigned int flags) +{ +int ret = -1; +virCommandPtr cmd = NULL; +char *create_tool = NULL; + +virCheckFlags(0, -1); + +if (inputvol && inputvol->target.format != VIR_STORAGE_FILE_PLOOP) { +virReportError(VIR_ERR_INTERNAL_ERROR, + _("unsupported input storage vol type %d"), + inputvol->target.format); +goto cleanup; +} + +if (vol->target.encryption != NULL) { +virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", + _("encrypted ploop volumes are not supported with " + "ploop init")); +goto cleanup; +} + +if (vol->target.backingStore != NULL) { +virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", + _("copy-on-write ploop volumes are not yet supported")); +goto cleanup; +} + +create_tool = virFindFileInPath("ploop"); +if (!create_tool && !inputvol) { +virReportError(VIR_ERR_INTERNAL_ERROR, + "%s", _("unable to find ploop, please install " + "ploop tools")); +return ret; +} + +if (!inputvol) { +if ((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) { +virReportError(VIR_ERR_INTERNAL_ERROR, "%s", + _("error creating directory for ploop volume")); +goto cleanup; +} +cmd = virCommandNewArgList(create_tool, "init", "-s", NULL); +virCommandAddArgFormat(cmd, "%lluM", VIR_DIV_UP(vol->target.capacity, +(1024 * 1024))); +virCommandAddArgList(cmd, "-t", "ext4", NULL); +virCommandAddArgFormat(cmd, "%s/root.hds", vol->target.path); + +} 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(create_tool); +if (ret < 0) +virFileDeleteTree(vol->target.path); +return ret; +} + enum { QEMU_IMG_BACKING_FORMAT_NONE = 0, QEMU_IMG_BACKING_FORMAT_FLAG, @@ -1291,6 +1366,9 @@ virStorageBackendGetBuildVolFromFunction(virStorageVolDefPtr vol, return virStorageBackendFSImageToolTypeToFunc(tool_type); } +if (vol->type == VIR_STORAGE_VOL_PLOOP && +inputvol->type == VIR_STORAGE_VOL_PLOOP) +return virStorageBackendCreatePloop; if (vol->type == VIR_STORAGE_VOL_BLOCK) return virStorageBackendCreateBlockFrom; else 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 virStorageBackendGetBuildVolFro
[libvirt] [PATCH 2/7] storage:dir: .buildVol and .buildVolFrom callbacks for ploop
These callbacks let us to create ploop volumes in dir, fs and etc. 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 similar to input volume content. Signed-off-by: Olga Krishtal --- src/storage/storage_backend.c| 78 src/storage/storage_backend.h| 8 + src/storage/storage_backend_fs.c | 2 ++ 3 files changed, 88 insertions(+) diff --git a/src/storage/storage_backend.c b/src/storage/storage_backend.c index 231eccf..d109980 100644 --- a/src/storage/storage_backend.c +++ b/src/storage/storage_backend.c @@ -773,6 +773,81 @@ virStorageBackendCreateExecCommand(virStoragePoolObjPtr pool, return ret; } +/* Create ploop directory with ploop image and DiskDescriptor.xml + * if function fails to create image file the directory will be deleted.*/ +int +virStorageBackendCreatePloop(virConnectPtr conn ATTRIBUTE_UNUSED, + virStoragePoolObjPtr pool ATTRIBUTE_UNUSED, + virStorageVolDefPtr vol, + virStorageVolDefPtr inputvol, + unsigned int flags) +{ +int ret = -1; +virCommandPtr cmd = NULL; +char *create_tool = NULL; + +virCheckFlags(0, -1); + +if (inputvol && inputvol->target.format != VIR_STORAGE_FILE_PLOOP) { +virReportError(VIR_ERR_INTERNAL_ERROR, + _("unsupported input storage vol type %d"), + inputvol->target.format); +goto cleanup; +} + +if (vol->target.encryption != NULL) { +virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", + _("encrypted ploop volumes are not supported with " + "ploop init")); +goto cleanup; +} + +if (vol->target.backingStore != NULL) { +virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", + _("copy-on-write ploop volumes are not yet supported")); +goto cleanup; +} + +create_tool = virFindFileInPath("ploop"); +if (!create_tool && !inputvol) { +virReportError(VIR_ERR_INTERNAL_ERROR, + "%s", _("unable to find ploop, please install " + "ploop tools")); +return ret; +} + +if (!inputvol) { +if ((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) { +virReportError(VIR_ERR_INTERNAL_ERROR, "%s", + _("error creating directory for ploop volume")); +goto cleanup; +} +cmd = virCommandNewArgList(create_tool, "init", "-s", NULL); +virCommandAddArgFormat(cmd, "%lluM", VIR_DIV_UP(vol->target.capacity, +(1024 * 1024))); +virCommandAddArgList(cmd, "-t", "ext4", NULL); +virCommandAddArgFormat(cmd, "%s/root.hds", vol->target.path); + +} 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(create_tool); +if (ret < 0) +virFileDeleteTree(vol->target.path); +return ret; +} + enum { QEMU_IMG_BACKING_FORMAT_NONE = 0, QEMU_IMG_BACKING_FORMAT_FLAG, @@ -1291,6 +1366,9 @@ virStorageBackendGetBuildVolFromFunction(virStorageVolDefPtr vol, return virStorageBackendFSImageToolTypeToFunc(tool_type); } +if (vol->type == VIR_STORAGE_VOL_PLOOP && +inputvol->type == VIR_STORAGE_VOL_PLOOP) +return virStorageBackendCreatePloop; if (vol->type == VIR_STORAGE_VOL_BLOCK) return virStorageBackendCreateBlockFrom; else 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 virStorageBackendGetBuildVolFro
Re: [libvirt] [PATCH 2/7] storage:dir: .buildVol and .buildVolFrom callbacks for ploop
08.02.2016 16:04, Olga Krishtal пишет: 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 --- src/storage/storage_backend.c| 90 src/storage/storage_backend.h| 8 src/storage/storage_backend_fs.c | 2 + 3 files changed, 100 insertions(+) diff --git a/src/storage/storage_backend.c b/src/storage/storage_backend.c index c07b642..6bd4618 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. + */ + +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 0; +} + +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")); looks like an uncompleted phrase +return -1; +} + +if (vol->target.backingStore != NULL) { +virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", +_("copy-on-write ploop is not yet supported")); s/ploop is not/ploop volumes are not +return -1; +} + +if (!inputvol) { +if (virVolCreateDirForPloop(pool, vol) < 0) { +virReportError(VIR_ERR_INTERNAL_ERROR, +"%s", _("error creating directory for ploop " +"ploop init")); s/ploop ploop init/ploop volume +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, + virStorageVolDef
[libvirt] [PATCH 2/7] storage:dir: .buildVol and .buildVolFrom callbacks for ploop
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 --- src/storage/storage_backend.c| 90 src/storage/storage_backend.h| 8 src/storage/storage_backend_fs.c | 2 + 3 files changed, 100 insertions(+) diff --git a/src/storage/storage_backend.c b/src/storage/storage_backend.c index c07b642..6bd4618 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. + */ + +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 0; +} + +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) < 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 virStorageBa
Re: [libvirt] [PATCH 2/7] storage:dir: .buildVol and .buildVolFrom callbacks for ploop
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 --- 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,
[libvirt] [PATCH 2/7] storage:dir: .buildVol and .buildVolFrom callbacks for ploop
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 --- 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. +*/ + +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; +} + +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)) { +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 v