[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