[libvirt] [PATCH 1/6] storage:dir: .buildVol and .buildVolFrom callbacks for ploop

Nikolay Shirokovskiy nshirokovskiy at virtuozzo.com
Wed Feb 17 14:29:00 UTC 2016



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 at 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);
>  
> 




More information about the libvir-list mailing list