[libvirt] [PATCH 7/7] storage:dir: adapts .refreshVol .refreshPool for ploop volumes

Maxim Nestratov mnestratov at virtuozzo.com
Mon Feb 8 17:28:07 UTC 2016


08.02.2016 16:04, Olga Krishtal пишет:
> To update information about ploop volumes inside the a single pool we need
> to be sure that it is the ploop directory and not some other directory.
> Ploop volume directory obligatory contains root.hds - image file and disk
> descriptor - DiskDescriptor.xml. If path to a volume is a path to some
> directory, we check the existance of this files.
>
> The capacity of a ploop volume is obtained via offset
> in the header file:
> https://openvz.org/Ploop/format

ACK, except minor comment inline

>
> Signed-off-by: Olga Krishtal <okrishtal at virtuozzo.com>
> ---
>   src/storage/storage_backend.c         | 90 ++++++++++++++++++++++++++---------
>   src/storage/storage_backend.h         |  2 +-
>   src/storage/storage_backend_fs.c      |  8 +++-
>   src/storage/storage_backend_logical.c |  2 +-
>   src/util/virstoragefile.c             |  8 +++-
>   5 files changed, 83 insertions(+), 27 deletions(-)
>
> diff --git a/src/storage/storage_backend.c b/src/storage/storage_backend.c
> index 582bb5c..528e8e0 100644
> --- a/src/storage/storage_backend.c
> +++ b/src/storage/storage_backend.c
> @@ -1575,6 +1575,25 @@ virStorageBackendDetectBlockVolFormatFD(virStorageSourcePtr target,
>       return 0;
>   }
>   
> +static bool virStorageBackendIsPloopDir(char *path)
> +{
> +    char *file = NULL;
> +    bool ret = false;
> +
> +    if (virAsprintf(&file, "%s/%s", path, "root.hds") < 0)
> +        return ret;
> +    if (!virFileExists(file))
> +        goto cleanup;
> +    VIR_FREE(file);
> +    if (virAsprintf(&file, "%s/%s", path, "DiskDescriptor.xml") < 0)
> +        goto cleanup;
> +    if (!virFileExists(file))
> +        goto cleanup;
> +    ret = true;
> + cleanup:
> +    VIR_FREE(file);
> +    return ret;
> +}
>   
>   /*
>    * Allows caller to silently ignore files with improper mode
> @@ -1583,29 +1602,35 @@ virStorageBackendDetectBlockVolFormatFD(virStorageSourcePtr target,
>    * return -2 if file mode is unexpected or the volume is a dangling
>    * symbolic link.
>    */
> +
> +#define FAILED_STAT(path, ret) { \
> +    if (errno == ENOENT) { \
> +        if (noerror) { \
> +            VIR_WARN("ignoring missing file '%s'", path);\
> +            ret = -2; \
> +        } \
> +        virReportError(VIR_ERR_NO_STORAGE_VOL, \
> +            _("no storage vol with matching path '%s'"), path); \
> +            ret = -1; \
> +    } \
> +    virReportSystemError(errno, \
> +             _("cannot stat file '%s'"), path);\
> +    ret = -1;\
> +}
> +
>   int
> -virStorageBackendVolOpen(const char *path, struct stat *sb,
> +virStorageBackendVolOpen(virStorageSourcePtr target, struct stat *sb,
>                            unsigned int flags)
>   {
> -    int fd, mode = 0;
> -    char *base = last_component(path);
> +    int fd, mode = 0, ret = 0;
> +    char *base = last_component(target->path);
>       bool noerror = (flags & VIR_STORAGE_VOL_OPEN_NOERROR);
> +    char *path = target->path;
> +    char *ploop_path = NULL;
>   
>       if (lstat(path, sb) < 0) {
> -        if (errno == ENOENT) {
> -            if (noerror) {
> -                VIR_WARN("ignoring missing file '%s'", path);
> -                return -2;
> -            }
> -            virReportError(VIR_ERR_NO_STORAGE_VOL,
> -                           _("no storage vol with matching path '%s'"),
> -                           path);
> -            return -1;
> -        }
> -        virReportSystemError(errno,
> -                             _("cannot stat file '%s'"),
> -                             path);
> -        return -1;
> +        FAILED_STAT(path, ret);
> +        return ret;
>       }
>   
>       if (S_ISFIFO(sb->st_mode)) {
> @@ -1624,6 +1649,18 @@ virStorageBackendVolOpen(const char *path, struct stat *sb,
>           virReportError(VIR_ERR_INTERNAL_ERROR,
>                          _("Volume path '%s' is a socket"), path);
>           return -1;
> +    } else if (S_ISDIR(sb->st_mode)) {
> +        if (virStorageBackendIsPloopDir(path)) {
> +            if (virAsprintf(&ploop_path, "%s/%s", target->path, "root.hds") < 0)
> +                return -1;
> +            path = ploop_path;
> +            target->format = VIR_STORAGE_FILE_PLOOP;
> +            if (lstat(path, sb) < 0) {
> +                FAILED_STAT(path, ret);
> +                VIR_FREE(ploop_path);
> +                return ret;
> +            }
> +        }
>       }
>   
>       /* O_NONBLOCK should only matter during open() for fifos and
> @@ -1720,6 +1757,7 @@ virStorageBackendVolOpen(const char *path, struct stat *sb,
>           return -1;
>       }
>   
> +    VIR_FREE(ploop_path);
>       return fd;
>   }
>   
> @@ -1747,8 +1785,10 @@ virStorageBackendUpdateVolTargetInfo(virStorageSourcePtr target,
>       virStorageSourcePtr meta = NULL;
>       char *buf = NULL;
>       ssize_t len = VIR_STORAGE_MAX_HEADER;
> +    char *path = NULL;
> +    char *target_path = target->path;
>   
> -    if ((ret = virStorageBackendVolOpen(target->path, &sb, openflags)) < 0)
> +    if ((ret = virStorageBackendVolOpen(target, &sb, openflags)) < -1)
>           goto cleanup;
>       fd = ret;
>   
> @@ -1763,7 +1803,7 @@ virStorageBackendUpdateVolTargetInfo(virStorageSourcePtr target,
>           }
>   
>           if (lseek(fd, 0, SEEK_SET) == (off_t)-1) {
> -            virReportSystemError(errno, _("cannot seek to start of '%s'"), target->path);
> +            virReportSystemError(errno, _("cannot seek to start of '%s'"), target_path);
>               ret = -1;
>               goto cleanup;
>           }
> @@ -1771,18 +1811,23 @@ virStorageBackendUpdateVolTargetInfo(virStorageSourcePtr target,
>           if ((len = virFileReadHeaderFD(fd, len, &buf)) < 0) {
>               if (readflags & VIR_STORAGE_VOL_READ_NOERROR) {
>                   VIR_WARN("ignoring failed header read for '%s'",
> -                         target->path);
> +                         target_path);
>                   ret = -2;
>               } else {
>                   virReportSystemError(errno,
>                                        _("cannot read header '%s'"),
> -                                     target->path);
> +                                     target_path);

I'm not sure these changes are necessary

>                   ret = -1;
>               }
>               goto cleanup;
>           }
>   
> -        if (!(meta = virStorageFileGetMetadataFromBuf(target->path, buf, len, target->format,
> +        if (target->format == VIR_STORAGE_FILE_PLOOP) {
> +            if (virAsprintf(&path, "%s/%s", target->path, "root.hds") < 0)
> +                return -1;
> +            target_path = path;
> +        }
> +        if (!(meta = virStorageFileGetMetadataFromBuf(target_path, buf, len, target->format,
>                                                         NULL))) {
>               ret = -1;
>               goto cleanup;
> @@ -1802,6 +1847,7 @@ virStorageBackendUpdateVolTargetInfo(virStorageSourcePtr target,
>       virStorageSourceFree(meta);
>       VIR_FORCE_CLOSE(fd);
>       VIR_FREE(buf);
> +    VIR_FREE(path);
>       return ret;
>   }
>   
> diff --git a/src/storage/storage_backend.h b/src/storage/storage_backend.h
> index 1de8dfe..7dca559 100644
> --- a/src/storage/storage_backend.h
> +++ b/src/storage/storage_backend.h
> @@ -206,7 +206,7 @@ enum {
>   # define VIR_STORAGE_VOL_OPEN_DEFAULT (VIR_STORAGE_VOL_OPEN_REG      |\
>                                          VIR_STORAGE_VOL_OPEN_BLOCK)
>   
> -int virStorageBackendVolOpen(const char *path, struct stat *sb,
> +int virStorageBackendVolOpen(virStorageSourcePtr target, struct stat *sb,
>                                unsigned int flags)
>       ATTRIBUTE_RETURN_CHECK
>       ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2);
> diff --git a/src/storage/storage_backend_fs.c b/src/storage/storage_backend_fs.c
> index 2ec828b..84e4c4a 100644
> --- a/src/storage/storage_backend_fs.c
> +++ b/src/storage/storage_backend_fs.c
> @@ -75,7 +75,7 @@ virStorageBackendProbeTarget(virStorageSourcePtr target,
>       if (encryption)
>           *encryption = NULL;
>   
> -    if ((rc = virStorageBackendVolOpen(target->path, &sb,
> +    if ((rc = virStorageBackendVolOpen(target, &sb,
>                                          VIR_STORAGE_VOL_FS_PROBE_FLAGS)) < 0)
>           return rc; /* Take care to propagate rc, it is not always -1 */
>       fd = rc;
> @@ -83,6 +83,10 @@ virStorageBackendProbeTarget(virStorageSourcePtr target,
>       if (virStorageBackendUpdateVolTargetInfoFD(target, fd, &sb) < 0)
>           goto cleanup;
>   
> +    if (target->format == VIR_STORAGE_FILE_PLOOP) {
> +        ret = 0;
> +        goto cleanup;
> +    }
>       if (S_ISDIR(sb.st_mode)) {
>           target->format = VIR_STORAGE_FILE_DIR;
>           ret = 0;
> @@ -948,6 +952,8 @@ virStorageBackendFileSystemRefresh(virConnectPtr conn ATTRIBUTE_UNUSED,
>           /* directory based volume */
>           if (vol->target.format == VIR_STORAGE_FILE_DIR)
>               vol->type = VIR_STORAGE_VOL_DIR;
> +        if (vol->target.format == VIR_STORAGE_FILE_PLOOP)
> +            vol->type = VIR_STORAGE_VOL_PLOOP;
>   
>           if (vol->target.backingStore) {
>               ignore_value(virStorageBackendUpdateVolTargetInfo(vol->target.backingStore,
> diff --git a/src/storage/storage_backend_logical.c b/src/storage/storage_backend_logical.c
> index ba26223..aaace5b 100644
> --- a/src/storage/storage_backend_logical.c
> +++ b/src/storage/storage_backend_logical.c
> @@ -955,7 +955,7 @@ virStorageBackendLogicalCreateVol(virConnectPtr conn,
>       virCommandFree(cmd);
>       cmd = NULL;
>   
> -    if ((fd = virStorageBackendVolOpen(vol->target.path, &sb,
> +    if ((fd = virStorageBackendVolOpen(&vol->target, &sb,
>                                          VIR_STORAGE_VOL_OPEN_DEFAULT)) < 0)
>           goto error;
>   
> diff --git a/src/util/virstoragefile.c b/src/util/virstoragefile.c
> index 101070f..d92da30 100644
> --- a/src/util/virstoragefile.c
> +++ b/src/util/virstoragefile.c
> @@ -184,6 +184,10 @@ qedGetBackingStore(char **, int *, const char *, size_t);
>   #define QED_F_BACKING_FILE 0x01
>   #define QED_F_BACKING_FORMAT_NO_PROBE 0x04
>   
> +/* Location of ploop image size in the header file *
> + * https://openvz.org/Ploop/format */
> +#define PLOOP_IMAGE_SIZE_OFFSET 36
> +#define PLOOP_SIZE_MULTIPLIER 512
>   
>   static struct FileTypeInfo const fileTypeInfo[] = {
>       [VIR_STORAGE_FILE_NONE] = { 0, NULL, NULL, LV_LITTLE_ENDIAN,
> @@ -236,8 +240,8 @@ static struct FileTypeInfo const fileTypeInfo[] = {
>                                  -1, {0}, 0, 0, 0, 0, NULL, NULL },
>       [VIR_STORAGE_FILE_VHD] = { 0, NULL, NULL, LV_LITTLE_ENDIAN,
>                                  -1, {0}, 0, 0, 0, 0, NULL, NULL },
> -    [VIR_STORAGE_FILE_PLOOP] = { 0, NULL, NULL, LV_LITTLE_ENDIAN,
> -                               -1, {0}, 0, 0, 0, 0, NULL, NULL },
> +    [VIR_STORAGE_FILE_PLOOP] = { 0, "ploop", NULL, LV_LITTLE_ENDIAN,
> +                               -1, {0}, PLOOP_IMAGE_SIZE_OFFSET, 0, PLOOP_SIZE_MULTIPLIER, 0, NULL, NULL },
>   
>       /* All formats with a backing store probe below here */
>       [VIR_STORAGE_FILE_COW] = {




More information about the libvir-list mailing list