On 09.02.2016 16:52, Olga Krishtal wrote: > 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 > > Signed-off-by: Olga Krishtal <okrishtal@xxxxxxxxxxxxx> > --- > src/storage/storage_backend.c | 90 ++++++++++++++++++++++++++--------- > src/storage/storage_backend.h | 2 +- > src/storage/storage_backend_fs.c | 6 ++- > src/storage/storage_backend_logical.c | 2 +- > src/util/virstoragefile.c | 8 +++- > 5 files changed, 81 insertions(+), 27 deletions(-) > > diff --git a/src/storage/storage_backend.c b/src/storage/storage_backend.c > index 21dd96d..0c31f32 100644 > --- a/src/storage/storage_backend.c > +++ b/src/storage/storage_backend.c > @@ -1584,6 +1584,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 > @@ -1592,29 +1611,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)) { > @@ -1633,6 +1658,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 > @@ -1729,6 +1766,7 @@ virStorageBackendVolOpen(const char *path, struct stat *sb, > return -1; > } > > + VIR_FREE(ploop_path); > return fd; > } I don't think this function is a good place to detect volume format. It is basically just a wrapper for virFileOpenAs and its function get an fd for a volume. Adding "root.hds" here would be enough. virStorageFileGetMetadataInternal?? looks like place that could detect ploops by directory structure. > > @@ -1756,8 +1794,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; > > @@ -1772,7 +1812,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; > } > @@ -1780,18 +1820,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); > 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; > @@ -1811,6 +1856,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 c2d148d..c340c69 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; > 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 }, this is not true, we have not "ploop" magic. > > /* All formats with a backing store probe below here */ > [VIR_STORAGE_FILE_COW] = { > -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list