diff --git a/src/storage/storage_backend.c b/src/storage/storage_backend.c index 3a5a7ea813712d8dff4703df53e8e88a7c64aae5..8953068c3cfb429da9c7e2cfb037e8cbc5294de6 100644 --- a/src/storage/storage_backend.c +++ b/src/storage/storage_backend.c @@ -1703,6 +1703,56 @@ virStorageBackendVolOpen(const char *path, struct stat *sb, return fd; } +/* virStorageIsPloop function checks whether given directory is ploop volume's + * directory. + */ +bool +virStorageBackendIsPloopDir(char *path) +{ + bool ret = false; + char *root = NULL; + char *desc = NULL; + if (virAsprintf(&root, "%s/root.hds", path) < 0) + return ret; + if (!virFileExists(root)) + goto cleanup; + if (virAsprintf(&desc, "%s/DiskDescriptor.xml", path) < 0) + goto cleanup; + if (!virFileExists(desc)) + goto cleanup; + + ret = true; + cleanup: + VIR_FREE(root); + VIR_FREE(desc); + return ret; +} + +/* In case of ploop volumes, path to volume is the path to the ploop + * directory. To get information about allocation, header information + * and etc. we need to perform virStorageBackendVolOpen and + * virStorageBackendUpdateVolTargetFd once again. + */ +int +virStorageBackendRedoPloopUpdate(virStorageSourcePtr target, struct stat *sb, + int *fd, unsigned int flags) +{ + char *path = NULL; + int ret = -1; + + if (virAsprintf(&path, "%s/root.hds", target->path) < 0) + return -1; + VIR_FORCE_CLOSE(*fd); + if ((*fd = virStorageBackendVolOpen(path, sb, flags)) < 0) + goto cleanup; + ret = virStorageBackendUpdateVolTargetInfoFD(target, *fd, sb); + + cleanup: + + VIR_FREE(path); + return ret; +} + /* * virStorageBackendUpdateVolTargetInfo * @target: target definition ptr of volume to update @@ -1738,8 +1788,15 @@ virStorageBackendUpdateVolTargetInfo(virStorageSourcePtr target, if (target->type == VIR_STORAGE_VOL_FILE && target->format != VIR_STORAGE_FILE_NONE) { if (S_ISDIR(sb.st_mode)) { - ret = 0; - goto cleanup; + if (virStorageBackendIsPloopDir(target->path)) { + if ((ret = virStorageBackendRedoPloopUpdate(target, &sb, &fd, + openflags)) < 0) + goto cleanup; + target->format = VIR_STORAGE_FILE_PLOOP; + } else { + ret = 0; + goto cleanup; + } } if (lseek(fd, 0, SEEK_SET) == (off_t)-1) { diff --git a/src/storage/storage_backend.h b/src/storage/storage_backend.h index 73f2bfadd34721d8cfc7275dfb50d1350c647d51..a1e39c5b9ac8358b0924f29bdf7c4fdb4112dd60 100644 --- a/src/storage/storage_backend.h +++ b/src/storage/storage_backend.h @@ -118,6 +118,11 @@ int virStorageBackendCreatePloop(virConnectPtr conn, int virStoragePloopResize(virStorageVolDefPtr vol, unsigned long long capacity); +int virStorageBackendRedoPloopUpdate(virStorageSourcePtr target, + struct stat *sb, int *fd, + unsigned int flags); +bool virStorageBackendIsPloopDir(char *path); + virStorageBackendBuildVolFrom virStorageBackendGetBuildVolFromFunction(virStorageVolDefPtr vol, virStorageVolDefPtr inputvol); diff --git a/src/storage/storage_backend_fs.c b/src/storage/storage_backend_fs.c index 03f14e4553ad8aa3ad672ec489026499ed20da67..b114b7675ce78b2f4fd7e983d8610c2834569b81 100644 --- a/src/storage/storage_backend_fs.c +++ b/src/storage/storage_backend_fs.c @@ -84,9 +84,15 @@ virStorageBackendProbeTarget(virStorageSourcePtr target, goto cleanup; if (S_ISDIR(sb.st_mode)) { - target->format = VIR_STORAGE_FILE_DIR; - ret = 0; - goto cleanup; + if (virStorageBackendIsPloopDir(target->path)) { + if (virStorageBackendRedoPloopUpdate(target, &sb, &fd, + VIR_STORAGE_VOL_FS_PROBE_FLAGS) < 0) + goto cleanup; + } else { + target->format = VIR_STORAGE_FILE_DIR; + ret = 0; + goto cleanup; + } } if (!(meta = virStorageFileGetMetadataFromFD(target->path, @@ -949,6 +955,9 @@ virStorageBackendFileSystemRefresh(virConnectPtr conn ATTRIBUTE_UNUSED, 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, false, diff --git a/src/util/virstoragefile.c b/src/util/virstoragefile.c index 49b174588ab871438ea7fe3d0c05e138cac16348..05ac2546bdcd9499c42ec4c98309f0c835024203 100644 --- a/src/util/virstoragefile.c +++ b/src/util/virstoragefile.c @@ -184,6 +184,8 @@ qedGetBackingStore(char **, int *, const char *, size_t); #define QED_F_BACKING_FILE 0x01 #define QED_F_BACKING_FORMAT_NO_PROBE 0x04 +#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 +238,9 @@ 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, "WithouFreSpacExt", NULL, LV_LITTLE_ENDIAN, + -2, {0}, PLOOP_IMAGE_SIZE_OFFSET, 0, + PLOOP_SIZE_MULTIPLIER, -1, NULL, NULL }, /* All formats with a backing store probe below here */ [VIR_STORAGE_FILE_COW] = {