[libvirt] [PATCH rfc 0/1] storage: vzstorage storage pool

In-Reply-To: This is first draft, that supports vzstorage in storage pools.i Virtuozzo Storage is a fault-tolerant distributed storage system, optimized for virtualization workloads. Vzstorage pool supports the same volume formats as directory, nfs, etc. In terms of volume management - there is no difference between these pools. You can find more information here: https://openvz.org/Virtuozzo_Storage XML: <pool type='vz'> <name>vz7_pool</name> <uuid>b27a72b5-a92e-4e58-a172-a80ba73b30fe</uuid> <capacity unit='bytes'>0</capacity> <allocation unit='bytes'>0</allocation> <available unit='bytes'>0</available> <source> <host name='127.0.0.2'/> <device path='vz7-vzstorage'/> <dir path='/pool1'/> </source> <target> <path>/vz7-vzstorage</path> </target> </pool> To compile libvirt with vz pool support use key --with-storage-vz I need some help to resolve some problems: - how to detect that pool is alredy mounted. - when we show pool sources do we need to show folders that may reside on vzstorage - I am not quite sure that we need host name in xml. I will be glad to here your opinion.

This patch supports pool and volume management within Virtuozzo Storage. Virtuozzo Storage is a highly-available distributed software defined storage with built-in replication and disaster recovery. From client's point of view it looks like network attached storage (NFS or GlusterFS). More information about vzstorage can be found here: https://openvz.org/Virtuozzo_Storage It supports the same volume formats as directory, nfs, etc. Default format is ploop. Signed-off-by: Olga Krishtal <okrishtal@virtuozzo.com> --- configure.ac | 28 +++++ docs/schemas/storagepool.rng | 13 +++ include/libvirt/libvirt-storage.h | 1 + src/Makefile.am | 7 +- src/conf/storage_conf.c | 19 ++- src/conf/storage_conf.h | 4 +- src/storage/storage_backend.c | 4 +- src/storage/storage_backend_fs.c | 235 +++++++++++++++++++++++++++++++++++++- src/storage/storage_backend_fs.h | 3 + src/storage/storage_driver.c | 2 + tools/virsh-pool.c | 2 + tools/virsh.c | 3 + 12 files changed, 311 insertions(+), 10 deletions(-) diff --git a/configure.ac b/configure.ac index 1eb19ee..d6c14eb 100644 --- a/configure.ac +++ b/configure.ac @@ -1739,6 +1739,10 @@ AC_ARG_WITH([storage-zfs], [AS_HELP_STRING([--with-storage-zfs], [with ZFS backend for the storage driver @<:@default=check@:>@])], [],[with_storage_zfs=check]) +AC_ARG_WITH([storage-vz], + [AS_HELP_STRING([--with-storage-vz], + [with VZ backend for the storage driver @<:@default=check@:>@])], + [],[with_storage_vz=check]) if test "$with_libvirtd" = "no"; then with_storage_dir=no @@ -1752,6 +1756,7 @@ if test "$with_libvirtd" = "no"; then with_storage_sheepdog=no with_storage_gluster=no with_storage_zfs=no + with_storage_vz=no fi if test "$with_storage_dir" = "yes" ; then AC_DEFINE_UNQUOTED([WITH_STORAGE_DIR], 1, [whether directory backend for storage driver is enabled]) @@ -2007,6 +2012,28 @@ if test "$with_storage_fs" = "yes" || fi fi +if test "$with_storage_vz" = "yes" || test "$with_storage_vz" = "check"; then + AC_PATH_PROG([VZSTORAGE], [pstorage], [], [$PATH:/sbin:/usr/bin]) + AC_PATH_PROG([VZMOUNT], [pstorage-mount], [], [$PATH:/sbin/usr/bin]) + if test "$with_storage_vz" = "yes"; then + if test -z "$VZSTORAGE" ; then AC_MSG_ERROR([We need vzstorage tools for VZ storage driver]); fi + if test -z "$VZMOUNT" ; then AC_MSG_ERROR([We need vzstorage mount tool for VZ storage driver]); fi + else + if test -z "$VZSTORAGE" ; then with_storage_vz=no; fi + if test -z "$VZSTORAGE" ; then with_storage_vz=no; fi + + if test "$with_storage_vz" = "check" ; then with_storage_vz=yes ; fi + fi + if test "$with_storage_vz" = "yes"; then + AC_DEFINE_UNQUOTED([WITH_STORAGE_VZ], 1, [whether VZ backend for storage driver is enabled]) + AC_DEFINE_UNQUOTED([VZSTORAGE], ["$VZSTORAGE"], [Location or name of vzstorage program]) + AC_DEFINE_UNQUOTED([VZMOUNT], ["$VZMOUNT"], [Location or name of vzstorage mount program]) + fi + + if test "$with_storage_vz" = "check" ; then with_storage_vz=yes ; fi +fi +AM_CONDITIONAL([WITH_STORAGE_VZ], [test "$with_storage_vz" = "yes"]) + LIBPARTED_CFLAGS= LIBPARTED_LIBS= if test "$with_storage_disk" = "yes" || @@ -2812,6 +2839,7 @@ AC_MSG_NOTICE([ RBD: $with_storage_rbd]) AC_MSG_NOTICE([Sheepdog: $with_storage_sheepdog]) AC_MSG_NOTICE([ Gluster: $with_storage_gluster]) AC_MSG_NOTICE([ ZFS: $with_storage_zfs]) +AC_MSG_NOTICE([ VZ: $with_storage_vz]) AC_MSG_NOTICE([]) AC_MSG_NOTICE([Security Drivers]) AC_MSG_NOTICE([]) diff --git a/docs/schemas/storagepool.rng b/docs/schemas/storagepool.rng index 49d212f..b9bef7d 100644 --- a/docs/schemas/storagepool.rng +++ b/docs/schemas/storagepool.rng @@ -24,6 +24,7 @@ <ref name='poolsheepdog'/> <ref name='poolgluster'/> <ref name='poolzfs'/> + <ref name='poolvz'/> </choice> </element> </define> @@ -173,6 +174,18 @@ </interleave> </define> + <define name='poolvz'> + <attribute name='type'> + <value>vz</value> + </attribute> + <interleave> + <ref name='commonmetadata'/> + <ref name='sizing'/> + <ref name='sourceclustervz'/> + <ref name='target'/> + </interleave> + </define> + <define name='sourceinfovendor'> <interleave> <optional> diff --git a/include/libvirt/libvirt-storage.h b/include/libvirt/libvirt-storage.h index 57a26c4..0dd47b0 100644 --- a/include/libvirt/libvirt-storage.h +++ b/include/libvirt/libvirt-storage.h @@ -232,6 +232,7 @@ typedef enum { VIR_CONNECT_LIST_STORAGE_POOLS_SHEEPDOG = 1 << 15, VIR_CONNECT_LIST_STORAGE_POOLS_GLUSTER = 1 << 16, VIR_CONNECT_LIST_STORAGE_POOLS_ZFS = 1 << 17, + VIR_CONNECT_LIST_STORAGE_POOLS_VZ = 1 << 18, } virConnectListAllStoragePoolsFlags; int virConnectListAllStoragePools(virConnectPtr conn, diff --git a/src/Makefile.am b/src/Makefile.am index eda0365..0909618 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -978,6 +978,7 @@ STORAGE_DRIVER_GLUSTER_SOURCES = \ STORAGE_DRIVER_ZFS_SOURCES = \ storage/storage_backend_zfs.h storage/storage_backend_zfs.c + STORAGE_HELPER_DISK_SOURCES = \ storage/parthelper.c @@ -1670,6 +1671,10 @@ if WITH_STORAGE_ZFS libvirt_driver_storage_impl_la_SOURCES += $(STORAGE_DRIVER_ZFS_SOURCES) endif WITH_STORAGE_ZFS +if WITH_STORAGE_VZ +libvirt_driver_storage_impl_la_SOURCES += $(STORAGE_DRIVER_VZ_SOURCES) +endif WITH_STORAGE_VZ + if WITH_NODE_DEVICES # Needed to keep automake quiet about conditionals if WITH_DRIVER_MODULES @@ -1880,7 +1885,7 @@ EXTRA_DIST += \ $(STORAGE_DRIVER_SHEEPDOG_SOURCES) \ $(STORAGE_DRIVER_GLUSTER_SOURCES) \ $(STORAGE_DRIVER_ZFS_SOURCES) \ - $(NODE_DEVICE_DRIVER_SOURCES) \ + $(NODE_DEVICE_DRIVER_SOURCES) \ $(NODE_DEVICE_DRIVER_HAL_SOURCES) \ $(NODE_DEVICE_DRIVER_UDEV_SOURCES) \ $(NWFILTER_DRIVER_SOURCES) \ diff --git a/src/conf/storage_conf.c b/src/conf/storage_conf.c index daf8f99..b8ff3c5 100644 --- a/src/conf/storage_conf.c +++ b/src/conf/storage_conf.c @@ -60,7 +60,7 @@ VIR_ENUM_IMPL(virStoragePool, "dir", "fs", "netfs", "logical", "disk", "iscsi", "scsi", "mpath", "rbd", - "sheepdog", "gluster", "zfs") + "sheepdog", "gluster", "zfs", "vz") VIR_ENUM_IMPL(virStoragePoolFormatFileSystem, VIR_STORAGE_POOL_FS_LAST, @@ -274,6 +274,18 @@ static virStoragePoolTypeInfo poolTypeInfo[] = { .defaultFormat = VIR_STORAGE_FILE_RAW, }, }, + {.poolType = VIR_STORAGE_POOL_VZ, + .poolOptions = { + .flags = (VIR_STORAGE_POOL_SOURCE_HOST | + VIR_STORAGE_POOL_SOURCE_DEVICE | + VIR_STORAGE_POOL_SOURCE_DIR), + }, + .volOptions = { + .defaultFormat = VIR_STORAGE_FILE_PLOOP, + .formatFromString = virStorageVolumeFormatFromString, + .formatToString = virStorageFileFormatTypeToString, + }, + }, }; @@ -2595,6 +2607,11 @@ virStoragePoolSourceFindDuplicate(virConnectPtr conn, /* Only one mpath pool is valid per host */ matchpool = pool; break; + case VIR_STORAGE_POOL_VZ: + if (virStoragePoolSourceMatchSingleHost(&pool->def->source, + &def->source)) + matchpool = pool; + break; case VIR_STORAGE_POOL_RBD: case VIR_STORAGE_POOL_LAST: break; diff --git a/src/conf/storage_conf.h b/src/conf/storage_conf.h index 31b45be..f8086dd 100644 --- a/src/conf/storage_conf.h +++ b/src/conf/storage_conf.h @@ -94,6 +94,7 @@ typedef enum { VIR_STORAGE_POOL_SHEEPDOG, /* Sheepdog device */ VIR_STORAGE_POOL_GLUSTER, /* Gluster device */ VIR_STORAGE_POOL_ZFS, /* ZFS */ + VIR_STORAGE_POOL_VZ, /* vzstorage */ VIR_STORAGE_POOL_LAST, } virStoragePoolType; @@ -541,7 +542,8 @@ VIR_ENUM_DECL(virStoragePartedFs) VIR_CONNECT_LIST_STORAGE_POOLS_RBD | \ VIR_CONNECT_LIST_STORAGE_POOLS_SHEEPDOG | \ VIR_CONNECT_LIST_STORAGE_POOLS_GLUSTER | \ - VIR_CONNECT_LIST_STORAGE_POOLS_ZFS) + VIR_CONNECT_LIST_STORAGE_POOLS_ZFS | \ + VIR_CONNECT_LIST_STORAGE_POOLS_VZ) # define VIR_CONNECT_LIST_STORAGE_POOLS_FILTERS_ALL \ (VIR_CONNECT_LIST_STORAGE_POOLS_FILTERS_ACTIVE | \ diff --git a/src/storage/storage_backend.c b/src/storage/storage_backend.c index 372f5b1..d47a76a 100644 --- a/src/storage/storage_backend.c +++ b/src/storage/storage_backend.c @@ -95,7 +95,6 @@ #if WITH_STORAGE_ZFS # include "storage_backend_zfs.h" #endif - #define VIR_FROM_THIS VIR_FROM_STORAGE VIR_LOG_INIT("storage.storage_backend"); @@ -135,6 +134,9 @@ static virStorageBackendPtr backends[] = { #if WITH_STORAGE_ZFS &virStorageBackendZFS, #endif +#if WITH_STORAGE_VZ + &virStorageBackendVz, +#endif NULL }; diff --git a/src/storage/storage_backend_fs.c b/src/storage/storage_backend_fs.c index 5e57366..5754be8 100644 --- a/src/storage/storage_backend_fs.c +++ b/src/storage/storage_backend_fs.c @@ -397,7 +397,7 @@ virStorageBackendFileSystemGetPoolSource(virStoragePoolObjPtr pool) { char *src = NULL; - if (pool->def->type == VIR_STORAGE_POOL_NETFS) { + if (pool->def->type == VIR_STORAGE_POOL_NETFS || pool->def->type == VIR_STORAGE_POOL_VZ) { if (pool->def->source.format == VIR_STORAGE_POOL_NETFS_CIFS) { if (virAsprintf(&src, "//%s/%s", pool->def->source.hosts[0].name, @@ -826,6 +826,14 @@ virStorageBackendFileSystemBuild(virConnectPtr conn ATTRIBUTE_UNUSED, mode_t mode; bool needs_create_as_uid; unsigned int dir_create_flags; + char *target_path = pool->def->target.path; + char *path = NULL; + + if (pool->def->type == VIR_STORAGE_POOL_VZ) { + path = virStringReplace(pool->def->target.path, + pool->def->source.dir, "\0"); + target_path = path; + } virCheckFlags(VIR_STORAGE_POOL_BUILD_OVERWRITE | VIR_STORAGE_POOL_BUILD_NO_OVERWRITE, ret); @@ -834,7 +842,7 @@ virStorageBackendFileSystemBuild(virConnectPtr conn ATTRIBUTE_UNUSED, VIR_STORAGE_POOL_BUILD_NO_OVERWRITE, error); - if (VIR_STRDUP(parent, pool->def->target.path) < 0) + if (VIR_STRDUP(parent, target_path) < 0) goto error; if (!(p = strrchr(parent, '/'))) { virReportError(VIR_ERR_INVALID_ARG, @@ -859,7 +867,7 @@ virStorageBackendFileSystemBuild(virConnectPtr conn ATTRIBUTE_UNUSED, mode = pool->def->target.perms.mode; if (mode == (mode_t) -1 && - (needs_create_as_uid || !virFileExists(pool->def->target.path))) + (needs_create_as_uid || !virFileExists(target_path))) mode = VIR_STORAGE_DEFAULT_POOL_PERM_MODE; if (needs_create_as_uid) dir_create_flags |= VIR_DIR_CREATE_AS_UID; @@ -867,7 +875,7 @@ virStorageBackendFileSystemBuild(virConnectPtr conn ATTRIBUTE_UNUSED, /* Now create the final dir in the path with the uid/gid/mode * requested in the config. If the dir already exists, just set * the perms. */ - if (virDirCreate(pool->def->target.path, + if (virDirCreate(target_path, mode, pool->def->target.perms.uid, pool->def->target.perms.gid, @@ -882,6 +890,7 @@ virStorageBackendFileSystemBuild(virConnectPtr conn ATTRIBUTE_UNUSED, error: VIR_FREE(parent); + VIR_FREE(path); return ret; } @@ -1068,14 +1077,23 @@ virStorageBackendFileSystemDelete(virConnectPtr conn ATTRIBUTE_UNUSED, virStoragePoolObjPtr pool, unsigned int flags) { + char *path = NULL; + char *target_path = pool->def->target.path; + virCheckFlags(0, -1); /* XXX delete all vols first ? */ - if (rmdir(pool->def->target.path) < 0) { + if (pool->def->type == VIR_STORAGE_POOL_VZ) { + path = virStringReplace(pool->def->target.path, + pool->def->source.dir, "\0"); + target_path = path; + } + + if (rmdir(target_path) < 0) { virReportSystemError(errno, _("failed to remove pool '%s'"), - pool->def->target.path); + target_path); return -1; } @@ -1651,3 +1669,208 @@ virStorageFileBackend virStorageFileBackendDir = { }; #endif /* WITH_STORAGE_FS */ + +#if WITH_STORAGE_VZ + +static int +virStorageBackendVzStart(virConnectPtr conn ATTRIBUTE_UNUSED, + virStoragePoolObjPtr pool) +{ + int ret = -1; + virCommandPtr cmd = NULL; + char *logfile = NULL; + char *path = NULL; + char *target_path = pool->def->target.path; + char *unmounted = NULL; + + if (pool->def->source.dir) { + path = virStringReplace(pool->def->target.path, + pool->def->source.dir, "\0"); + target_path = path; + } + + if (virAsprintf(&logfile, "/var/log/pstorage/vz7-vzstorage/" + "%s-pstorage-mount.log.gz", + pool->def->name) < 0) + goto cleanup; + + if (virAsprintf(&unmounted, "/var/log/pstorage/vz7-vzstorage/" + "%s-pstorage-umounted.log.gz", + pool->def->name) < 0) + goto cleanup; + + if (virFileExists(unmounted)) { + cmd = virCommandNewArgList("mv", unmounted, logfile, NULL); + if (virCommandRun(cmd, NULL) < 0) + goto cleanup; + virCommandFree(cmd); + } + + cmd = virCommandNewArgList(VZMOUNT, "-c", pool->def->source.devices[0].path, + target_path, "-l", logfile, NULL); + + if (virCommandRun(cmd, NULL) < 0) + goto cleanup; + ret = 0; + + cleanup: + VIR_FREE(path); + VIR_FREE(logfile); + VIR_FREE(unmounted); + virCommandFree(cmd); + return ret; +} + +static int +virStorageBackendVzCheck(virStoragePoolObjPtr pool, + bool *active) +{ + char *logfile = NULL; + + if (virAsprintf(&logfile, "/var/log/pstorage/vz7-vzstorage/" + "%s-pstorage-mount.log.gz", + pool->def->name) < 0) + return -1; + + *active = virFileExists(logfile); + + VIR_FREE(logfile); + return 0; +} + +static int +virStorageBackendVzStop(virConnectPtr conn ATTRIBUTE_UNUSED, + virStoragePoolObjPtr pool) +{ + int ret = -1; + virCommandPtr cmd = NULL; + char *path = NULL; + char *target_path = pool->def->target.path; + char *logfile = NULL; + char *unmounted; + if (pool->def->source.dir) { + path = virStringReplace(pool->def->target.path, + pool->def->source.dir, "\0"); + target_path = path; + } + + if (virAsprintf(&logfile, "/var/log/pstorage/vz7-vzstorage/" + "%s-pstorage-mount.log.gz", + pool->def->name) < 0) + goto cleanup; + + if (virAsprintf(&unmounted, "/var/log/pstorage/vz7-vzstorage/" + "%s-pstorage-umounted.log.gz", + pool->def->name) < 0) + goto cleanup; + + if (virFileExists(logfile)) { + cmd = virCommandNewArgList("mv", logfile, unmounted, NULL); + if (virCommandRun(cmd, NULL) < 0) + goto cleanup; + virCommandFree(cmd); + } + + cmd = virCommandNewArgList(UMOUNT, target_path, NULL); + if (virCommandRun(cmd, NULL) < 0) + goto cleanup; + + ret = 0; + + cleanup: + VIR_FREE(path); + VIR_FREE(logfile); + VIR_FREE(unmounted); + virCommandFree(cmd); + return ret; +} + +struct _virVzDiscoverState { + const char *host; + virStoragePoolSourceList list; +}; + +typedef struct _virVzDiscoverState virVzDiscoverState; + +static char* +virStorageBackendVzfindPoolSources(virConnectPtr conn ATTRIBUTE_UNUSED, + const char *srcSpec ATTRIBUTE_UNUSED, + unsigned int flags) +{ + + virCommandPtr cmd = NULL; + char *buf = NULL; + char *ret = NULL; + char **clusters; + size_t clusters_num = 0; + size_t i = 0; + + virVzDiscoverState vz = { + .host = NULL, + .list = { + .type = VIR_STORAGE_POOL_VZ, + .nsources = 0, + .sources = NULL + } + }; + + virCheckFlags(0, NULL); + cmd = virCommandNewArgList(VZSTORAGE, "discover", NULL); + virCommandSetOutputBuffer(cmd, &buf); + + if (virCommandRun(cmd, NULL) < 0) + goto cleanup; + if (!buf) + goto cleanup; + + if (!(clusters = virStringSplitCount(buf, "\n", 0, &clusters_num))) + goto cleanup; + + vz.list.nsources = clusters_num - 1; + + if (VIR_ALLOC_N(vz.list.sources, vz.list.nsources) < 0) + goto cleanup; + + for (; i < vz.list.nsources; i++) { + if (VIR_ALLOC(vz.list.sources[i].devices) < 0) + goto cleanup; + vz.list.sources[i].ndevice = 1; + if (VIR_STRDUP(vz.list.sources[i].devices->path, clusters[i]) < 0) + goto cleanup; + } + + if (!(ret = virStoragePoolSourceListFormat(&vz.list))) + goto cleanup; + + cleanup: + for (i = 0; i < vz.list.nsources; i++) + virStoragePoolSourceClear(&vz.list.sources[i]); + VIR_FREE(vz.list.sources); + VIR_FREE(buf); + virCommandFree(cmd); + return ret; + +} + +virStorageBackend virStorageBackendVz = { + .type = VIR_STORAGE_POOL_VZ, + + .startPool = virStorageBackendVzStart, + .checkPool = virStorageBackendVzCheck, + .stopPool = virStorageBackendVzStop, + .findPoolSources = virStorageBackendVzfindPoolSources, + .buildPool = virStorageBackendFileSystemBuild, + .deletePool = virStorageBackendFileSystemDelete, + .refreshPool = virStorageBackendFileSystemRefresh, + .buildVol = virStorageBackendFileSystemVolBuild, + .buildVolFrom = virStorageBackendFileSystemVolBuildFrom, + .createVol = virStorageBackendFileSystemVolCreate, + .refreshVol = virStorageBackendFileSystemVolRefresh, + .deleteVol = virStorageBackendFileSystemVolDelete, + .resizeVol = virStorageBackendFileSystemVolResize, + .uploadVol = virStorageBackendVolUploadLocal, + .downloadVol = virStorageBackendVolDownloadLocal, + .wipeVol = virStorageBackendVolWipeLocal, + +}; +#endif /* WITH_STORAGE_VZ */ diff --git a/src/storage/storage_backend_fs.h b/src/storage/storage_backend_fs.h index 347ea9b..f557639 100644 --- a/src/storage/storage_backend_fs.h +++ b/src/storage/storage_backend_fs.h @@ -30,6 +30,9 @@ extern virStorageBackend virStorageBackendFileSystem; extern virStorageBackend virStorageBackendNetFileSystem; # endif +#if WITH_STORAGE_VZ +extern virStorageBackend virStorageBackendVz; +#endif typedef enum { FILESYSTEM_PROBE_FOUND, diff --git a/src/storage/storage_driver.c b/src/storage/storage_driver.c index 9999c2c..c691e05 100644 --- a/src/storage/storage_driver.c +++ b/src/storage/storage_driver.c @@ -1563,6 +1563,7 @@ storageVolLookupByPath(virConnectPtr conn, case VIR_STORAGE_POOL_ISCSI: case VIR_STORAGE_POOL_SCSI: case VIR_STORAGE_POOL_MPATH: + case VIR_STORAGE_POOL_VZ: stable_path = virStorageBackendStablePath(pool, cleanpath, false); @@ -3373,6 +3374,7 @@ virStorageTranslateDiskSourcePool(virConnectPtr conn, case VIR_STORAGE_POOL_DISK: case VIR_STORAGE_POOL_SCSI: case VIR_STORAGE_POOL_ZFS: + case VIR_STORAGE_POOL_VZ: if (!(def->src->path = virStorageVolGetPath(vol))) goto cleanup; diff --git a/tools/virsh-pool.c b/tools/virsh-pool.c index f9299e2..2ac74fe 100644 --- a/tools/virsh-pool.c +++ b/tools/virsh-pool.c @@ -1165,6 +1165,8 @@ cmdPoolList(vshControl *ctl, const vshCmd *cmd ATTRIBUTE_UNUSED) case VIR_STORAGE_POOL_ZFS: flags |= VIR_CONNECT_LIST_STORAGE_POOLS_ZFS; break; + case VIR_STORAGE_POOL_VZ: + flags |= VIR_CONNECT_LIST_STORAGE_POOLS_VZ; case VIR_STORAGE_POOL_LAST: break; } diff --git a/tools/virsh.c b/tools/virsh.c index fe33839..e8428fb 100644 --- a/tools/virsh.c +++ b/tools/virsh.c @@ -666,6 +666,9 @@ virshShowVersion(vshControl *ctl ATTRIBUTE_UNUSED) #ifdef WITH_STORAGE_ZFS vshPrint(ctl, " ZFS"); #endif +#ifdef WITH_STORAGE_VZ + vshPrint(ctl, " VZ"); +#endif vshPrint(ctl, "\n"); vshPrint(ctl, "%s", _(" Miscellaneous:")); -- 1.8.3.1

On 16.05.2016 10:25, Olga Krishtal wrote:
This patch supports pool and volume management within Virtuozzo Storage. Virtuozzo Storage is a highly-available distributed software defined storage with built-in replication and disaster recovery. From client's point of view it looks like network attached storage (NFS or GlusterFS). More information about vzstorage can be found here: https://openvz.org/Virtuozzo_Storage It supports the same volume formats as directory, nfs, etc. Default format is ploop.
Signed-off-by: Olga Krishtal <okrishtal@virtuozzo.com> --- configure.ac | 28 +++++ docs/schemas/storagepool.rng | 13 +++ include/libvirt/libvirt-storage.h | 1 + src/Makefile.am | 7 +- src/conf/storage_conf.c | 19 ++- src/conf/storage_conf.h | 4 +- src/storage/storage_backend.c | 4 +- src/storage/storage_backend_fs.c | 235 +++++++++++++++++++++++++++++++++++++- src/storage/storage_backend_fs.h | 3 + src/storage/storage_driver.c | 2 + tools/virsh-pool.c | 2 + tools/virsh.c | 3 + 12 files changed, 311 insertions(+), 10 deletions(-)
diff --git a/configure.ac b/configure.ac index 1eb19ee..d6c14eb 100644 --- a/configure.ac +++ b/configure.ac @@ -1739,6 +1739,10 @@ AC_ARG_WITH([storage-zfs], [AS_HELP_STRING([--with-storage-zfs], [with ZFS backend for the storage driver @<:@default=check@:>@])], [],[with_storage_zfs=check]) +AC_ARG_WITH([storage-vz], + [AS_HELP_STRING([--with-storage-vz], + [with VZ backend for the storage driver @<:@default=check@:>@])], + [],[with_storage_vz=check])
if test "$with_libvirtd" = "no"; then with_storage_dir=no @@ -1752,6 +1756,7 @@ if test "$with_libvirtd" = "no"; then with_storage_sheepdog=no with_storage_gluster=no with_storage_zfs=no + with_storage_vz=no fi if test "$with_storage_dir" = "yes" ; then AC_DEFINE_UNQUOTED([WITH_STORAGE_DIR], 1, [whether directory backend for storage driver is enabled]) @@ -2007,6 +2012,28 @@ if test "$with_storage_fs" = "yes" || fi fi
+if test "$with_storage_vz" = "yes" || test "$with_storage_vz" = "check"; then + AC_PATH_PROG([VZSTORAGE], [pstorage], [], [$PATH:/sbin:/usr/bin]) + AC_PATH_PROG([VZMOUNT], [pstorage-mount], [], [$PATH:/sbin/usr/bin])
let's have define name close to binary like PSTORAGE_MOUNT also we have prefixes vz.., p.. in patch itself and v..(at least in current vz7 distro). Let's choose one. I guess we should follow distro path and choose v.. names.
+ if test "$with_storage_vz" = "yes"; then + if test -z "$VZSTORAGE" ; then AC_MSG_ERROR([We need vzstorage tools for VZ storage driver]); fi + if test -z "$VZMOUNT" ; then AC_MSG_ERROR([We need vzstorage mount tool for VZ storage driver]); fi + else + if test -z "$VZSTORAGE" ; then with_storage_vz=no; fi + if test -z "$VZSTORAGE" ; then with_storage_vz=no; fi + + if test "$with_storage_vz" = "check" ; then with_storage_vz=yes ; fi + fi + if test "$with_storage_vz" = "yes"; then + AC_DEFINE_UNQUOTED([WITH_STORAGE_VZ], 1, [whether VZ backend for storage driver is enabled]) + AC_DEFINE_UNQUOTED([VZSTORAGE], ["$VZSTORAGE"], [Location or name of vzstorage program]) + AC_DEFINE_UNQUOTED([VZMOUNT], ["$VZMOUNT"], [Location or name of vzstorage mount program]) + fi + + if test "$with_storage_vz" = "check" ; then with_storage_vz=yes ; fi +fi +AM_CONDITIONAL([WITH_STORAGE_VZ], [test "$with_storage_vz" = "yes"]) + LIBPARTED_CFLAGS= LIBPARTED_LIBS= if test "$with_storage_disk" = "yes" || @@ -2812,6 +2839,7 @@ AC_MSG_NOTICE([ RBD: $with_storage_rbd]) AC_MSG_NOTICE([Sheepdog: $with_storage_sheepdog]) AC_MSG_NOTICE([ Gluster: $with_storage_gluster]) AC_MSG_NOTICE([ ZFS: $with_storage_zfs]) +AC_MSG_NOTICE([ VZ: $with_storage_vz]) AC_MSG_NOTICE([]) AC_MSG_NOTICE([Security Drivers]) AC_MSG_NOTICE([]) diff --git a/docs/schemas/storagepool.rng b/docs/schemas/storagepool.rng index 49d212f..b9bef7d 100644 --- a/docs/schemas/storagepool.rng +++ b/docs/schemas/storagepool.rng @@ -24,6 +24,7 @@ <ref name='poolsheepdog'/> <ref name='poolgluster'/> <ref name='poolzfs'/> + <ref name='poolvz'/> </choice> </element> </define> @@ -173,6 +174,18 @@ </interleave> </define>
+ <define name='poolvz'> + <attribute name='type'> + <value>vz</value> + </attribute> + <interleave> + <ref name='commonmetadata'/> + <ref name='sizing'/> + <ref name='sourceclustervz'/>
you need to define sourceclustervz i suggest sourcevz name, it is simplier, we don't use 'cluster' anywhere else
+ <ref name='target'/> + </interleave> + </define> + <define name='sourceinfovendor'> <interleave> <optional> diff --git a/include/libvirt/libvirt-storage.h b/include/libvirt/libvirt-storage.h index 57a26c4..0dd47b0 100644 --- a/include/libvirt/libvirt-storage.h +++ b/include/libvirt/libvirt-storage.h @@ -232,6 +232,7 @@ typedef enum { VIR_CONNECT_LIST_STORAGE_POOLS_SHEEPDOG = 1 << 15, VIR_CONNECT_LIST_STORAGE_POOLS_GLUSTER = 1 << 16, VIR_CONNECT_LIST_STORAGE_POOLS_ZFS = 1 << 17, + VIR_CONNECT_LIST_STORAGE_POOLS_VZ = 1 << 18, } virConnectListAllStoragePoolsFlags;
int virConnectListAllStoragePools(virConnectPtr conn, diff --git a/src/Makefile.am b/src/Makefile.am index eda0365..0909618 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -978,6 +978,7 @@ STORAGE_DRIVER_GLUSTER_SOURCES = \ STORAGE_DRIVER_ZFS_SOURCES = \ storage/storage_backend_zfs.h storage/storage_backend_zfs.c
+ STORAGE_HELPER_DISK_SOURCES = \ storage/parthelper.c
@@ -1670,6 +1671,10 @@ if WITH_STORAGE_ZFS libvirt_driver_storage_impl_la_SOURCES += $(STORAGE_DRIVER_ZFS_SOURCES) endif WITH_STORAGE_ZFS
we don't add any extra sources
+if WITH_STORAGE_VZ +libvirt_driver_storage_impl_la_SOURCES += $(STORAGE_DRIVER_VZ_SOURCES) +endif WITH_STORAGE_VZ + if WITH_NODE_DEVICES # Needed to keep automake quiet about conditionals if WITH_DRIVER_MODULES @@ -1880,7 +1885,7 @@ EXTRA_DIST += \ $(STORAGE_DRIVER_SHEEPDOG_SOURCES) \ $(STORAGE_DRIVER_GLUSTER_SOURCES) \ $(STORAGE_DRIVER_ZFS_SOURCES) \ - $(NODE_DEVICE_DRIVER_SOURCES) \ + $(NODE_DEVICE_DRIVER_SOURCES) \
accidental
$(NODE_DEVICE_DRIVER_HAL_SOURCES) \ $(NODE_DEVICE_DRIVER_UDEV_SOURCES) \ $(NWFILTER_DRIVER_SOURCES) \ diff --git a/src/conf/storage_conf.c b/src/conf/storage_conf.c index daf8f99..b8ff3c5 100644 --- a/src/conf/storage_conf.c +++ b/src/conf/storage_conf.c @@ -60,7 +60,7 @@ VIR_ENUM_IMPL(virStoragePool, "dir", "fs", "netfs", "logical", "disk", "iscsi", "scsi", "mpath", "rbd", - "sheepdog", "gluster", "zfs") + "sheepdog", "gluster", "zfs", "vz")
VIR_ENUM_IMPL(virStoragePoolFormatFileSystem, VIR_STORAGE_POOL_FS_LAST, @@ -274,6 +274,18 @@ static virStoragePoolTypeInfo poolTypeInfo[] = { .defaultFormat = VIR_STORAGE_FILE_RAW, }, }, + {.poolType = VIR_STORAGE_POOL_VZ, + .poolOptions = { + .flags = (VIR_STORAGE_POOL_SOURCE_HOST | + VIR_STORAGE_POOL_SOURCE_DEVICE | + VIR_STORAGE_POOL_SOURCE_DIR),
we need only name
+ }, + .volOptions = { + .defaultFormat = VIR_STORAGE_FILE_PLOOP,
auto probably
+ .formatFromString = virStorageVolumeFormatFromString, + .formatToString = virStorageFileFormatTypeToString, + }, + }, };
@@ -2595,6 +2607,11 @@ virStoragePoolSourceFindDuplicate(virConnectPtr conn, /* Only one mpath pool is valid per host */ matchpool = pool; break; + case VIR_STORAGE_POOL_VZ: + if (virStoragePoolSourceMatchSingleHost(&pool->def->source, + &def->source)) + matchpool = pool;
we need to check if cluster names match
+ break; case VIR_STORAGE_POOL_RBD: case VIR_STORAGE_POOL_LAST: break; diff --git a/src/conf/storage_conf.h b/src/conf/storage_conf.h index 31b45be..f8086dd 100644 --- a/src/conf/storage_conf.h +++ b/src/conf/storage_conf.h @@ -94,6 +94,7 @@ typedef enum { VIR_STORAGE_POOL_SHEEPDOG, /* Sheepdog device */ VIR_STORAGE_POOL_GLUSTER, /* Gluster device */ VIR_STORAGE_POOL_ZFS, /* ZFS */ + VIR_STORAGE_POOL_VZ, /* vzstorage */
VIR_STORAGE_POOL_LAST, } virStoragePoolType; @@ -541,7 +542,8 @@ VIR_ENUM_DECL(virStoragePartedFs) VIR_CONNECT_LIST_STORAGE_POOLS_RBD | \ VIR_CONNECT_LIST_STORAGE_POOLS_SHEEPDOG | \ VIR_CONNECT_LIST_STORAGE_POOLS_GLUSTER | \ - VIR_CONNECT_LIST_STORAGE_POOLS_ZFS) + VIR_CONNECT_LIST_STORAGE_POOLS_ZFS | \ + VIR_CONNECT_LIST_STORAGE_POOLS_VZ)
# define VIR_CONNECT_LIST_STORAGE_POOLS_FILTERS_ALL \ (VIR_CONNECT_LIST_STORAGE_POOLS_FILTERS_ACTIVE | \ diff --git a/src/storage/storage_backend.c b/src/storage/storage_backend.c index 372f5b1..d47a76a 100644 --- a/src/storage/storage_backend.c +++ b/src/storage/storage_backend.c @@ -95,7 +95,6 @@ #if WITH_STORAGE_ZFS # include "storage_backend_zfs.h" #endif - #define VIR_FROM_THIS VIR_FROM_STORAGE
VIR_LOG_INIT("storage.storage_backend"); @@ -135,6 +134,9 @@ static virStorageBackendPtr backends[] = { #if WITH_STORAGE_ZFS &virStorageBackendZFS, #endif +#if WITH_STORAGE_VZ + &virStorageBackendVz, +#endif NULL };
diff --git a/src/storage/storage_backend_fs.c b/src/storage/storage_backend_fs.c index 5e57366..5754be8 100644 --- a/src/storage/storage_backend_fs.c +++ b/src/storage/storage_backend_fs.c @@ -397,7 +397,7 @@ virStorageBackendFileSystemGetPoolSource(virStoragePoolObjPtr pool) { char *src = NULL;
- if (pool->def->type == VIR_STORAGE_POOL_NETFS) { + if (pool->def->type == VIR_STORAGE_POOL_NETFS || pool->def->type == VIR_STORAGE_POOL_VZ) {
looks like we don't use this
if (pool->def->source.format == VIR_STORAGE_POOL_NETFS_CIFS) { if (virAsprintf(&src, "//%s/%s", pool->def->source.hosts[0].name, @@ -826,6 +826,14 @@ virStorageBackendFileSystemBuild(virConnectPtr conn ATTRIBUTE_UNUSED, mode_t mode; bool needs_create_as_uid; unsigned int dir_create_flags; + char *target_path = pool->def->target.path; + char *path = NULL; + + if (pool->def->type == VIR_STORAGE_POOL_VZ) { + path = virStringReplace(pool->def->target.path, + pool->def->source.dir, "\0"); + target_path = path; + }
i don't think we need changes in this function
virCheckFlags(VIR_STORAGE_POOL_BUILD_OVERWRITE | VIR_STORAGE_POOL_BUILD_NO_OVERWRITE, ret); @@ -834,7 +842,7 @@ virStorageBackendFileSystemBuild(virConnectPtr conn ATTRIBUTE_UNUSED, VIR_STORAGE_POOL_BUILD_NO_OVERWRITE, error);
- if (VIR_STRDUP(parent, pool->def->target.path) < 0) + if (VIR_STRDUP(parent, target_path) < 0) goto error; if (!(p = strrchr(parent, '/'))) { virReportError(VIR_ERR_INVALID_ARG, @@ -859,7 +867,7 @@ virStorageBackendFileSystemBuild(virConnectPtr conn ATTRIBUTE_UNUSED, mode = pool->def->target.perms.mode;
if (mode == (mode_t) -1 && - (needs_create_as_uid || !virFileExists(pool->def->target.path))) + (needs_create_as_uid || !virFileExists(target_path))) mode = VIR_STORAGE_DEFAULT_POOL_PERM_MODE; if (needs_create_as_uid) dir_create_flags |= VIR_DIR_CREATE_AS_UID; @@ -867,7 +875,7 @@ virStorageBackendFileSystemBuild(virConnectPtr conn ATTRIBUTE_UNUSED, /* Now create the final dir in the path with the uid/gid/mode * requested in the config. If the dir already exists, just set * the perms. */ - if (virDirCreate(pool->def->target.path, + if (virDirCreate(target_path, mode, pool->def->target.perms.uid, pool->def->target.perms.gid, @@ -882,6 +890,7 @@ virStorageBackendFileSystemBuild(virConnectPtr conn ATTRIBUTE_UNUSED,
error: VIR_FREE(parent); + VIR_FREE(path); return ret; }
@@ -1068,14 +1077,23 @@ virStorageBackendFileSystemDelete(virConnectPtr conn ATTRIBUTE_UNUSED, virStoragePoolObjPtr pool, unsigned int flags) { + char *path = NULL; + char *target_path = pool->def->target.path; + virCheckFlags(0, -1);
/* XXX delete all vols first ? */
- if (rmdir(pool->def->target.path) < 0) { + if (pool->def->type == VIR_STORAGE_POOL_VZ) { + path = virStringReplace(pool->def->target.path, + pool->def->source.dir, "\0"); + target_path = path; + } + + if (rmdir(target_path) < 0) { virReportSystemError(errno, _("failed to remove pool '%s'"), - pool->def->target.path); + target_path);
and in this function too, they already do what we need to - create/delete target dirs.
return -1; }
@@ -1651,3 +1669,208 @@ virStorageFileBackend virStorageFileBackendDir = { };
#endif /* WITH_STORAGE_FS */ + +#if WITH_STORAGE_VZ + +static int +virStorageBackendVzStart(virConnectPtr conn ATTRIBUTE_UNUSED, + virStoragePoolObjPtr pool) +{ + int ret = -1; + virCommandPtr cmd = NULL; + char *logfile = NULL; + char *path = NULL; + char *target_path = pool->def->target.path; + char *unmounted = NULL; + + if (pool->def->source.dir) { + path = virStringReplace(pool->def->target.path, + pool->def->source.dir, "\0"); + target_path = path; + } + + if (virAsprintf(&logfile, "/var/log/pstorage/vz7-vzstorage/" + "%s-pstorage-mount.log.gz", + pool->def->name) < 0) + goto cleanup; + + if (virAsprintf(&unmounted, "/var/log/pstorage/vz7-vzstorage/" + "%s-pstorage-umounted.log.gz", + pool->def->name) < 0) + goto cleanup; + + if (virFileExists(unmounted)) { + cmd = virCommandNewArgList("mv", unmounted, logfile, NULL); + if (virCommandRun(cmd, NULL) < 0) + goto cleanup; + virCommandFree(cmd); + }
i don't think hardcoding log paths in driver is a good idea ...
+ + cmd = virCommandNewArgList(VZMOUNT, "-c", pool->def->source.devices[0].path, + target_path, "-l", logfile, NULL); + + if (virCommandRun(cmd, NULL) < 0) + goto cleanup; + ret = 0; + + cleanup: + VIR_FREE(path); + VIR_FREE(logfile); + VIR_FREE(unmounted); + virCommandFree(cmd); + return ret; +}
looks like start/stop for vz functionality can be done thru extra branching in existing virStorageBackendFileSystemStart/Stop functions. All we need is just mount/umount.
+ +static int +virStorageBackendVzCheck(virStoragePoolObjPtr pool, + bool *active) +{ + char *logfile = NULL; + + if (virAsprintf(&logfile, "/var/log/pstorage/vz7-vzstorage/" + "%s-pstorage-mount.log.gz", + pool->def->name) < 0) + return -1; + + *active = virFileExists(logfile); + + VIR_FREE(logfile); + return 0; +}
i would use the same function as netfs because vstorage is active in current implementation if it is just mounted. Adding extra manipulation with logs only to check if pool is active is not necessary.
+ +static int +virStorageBackendVzStop(virConnectPtr conn ATTRIBUTE_UNUSED, + virStoragePoolObjPtr pool) +{ + int ret = -1; + virCommandPtr cmd = NULL; + char *path = NULL; + char *target_path = pool->def->target.path; + char *logfile = NULL; + char *unmounted; + if (pool->def->source.dir) { + path = virStringReplace(pool->def->target.path, + pool->def->source.dir, "\0"); + target_path = path; + } + + if (virAsprintf(&logfile, "/var/log/pstorage/vz7-vzstorage/" + "%s-pstorage-mount.log.gz", + pool->def->name) < 0) + goto cleanup; + + if (virAsprintf(&unmounted, "/var/log/pstorage/vz7-vzstorage/" + "%s-pstorage-umounted.log.gz", + pool->def->name) < 0) + goto cleanup; + + if (virFileExists(logfile)) { + cmd = virCommandNewArgList("mv", logfile, unmounted, NULL); + if (virCommandRun(cmd, NULL) < 0) + goto cleanup; + virCommandFree(cmd); + } + + cmd = virCommandNewArgList(UMOUNT, target_path, NULL); + if (virCommandRun(cmd, NULL) < 0) + goto cleanup; + + ret = 0; + + cleanup: + VIR_FREE(path); + VIR_FREE(logfile); + VIR_FREE(unmounted); + virCommandFree(cmd); + return ret; +} + +struct _virVzDiscoverState { + const char *host; + virStoragePoolSourceList list; +}; + +typedef struct _virVzDiscoverState virVzDiscoverState; + +static char* +virStorageBackendVzfindPoolSources(virConnectPtr conn ATTRIBUTE_UNUSED, + const char *srcSpec ATTRIBUTE_UNUSED, + unsigned int flags) +{ + + virCommandPtr cmd = NULL; + char *buf = NULL; + char *ret = NULL; + char **clusters; + size_t clusters_num = 0; + size_t i = 0; + + virVzDiscoverState vz = { + .host = NULL,
host is not used anywhere
+ .list = { + .type = VIR_STORAGE_POOL_VZ, + .nsources = 0, + .sources = NULL + } + };
this structure is not used anywhere else
+ + virCheckFlags(0, NULL);
we need to check that srcSpec is NULL or empty string or something like that ...
+ cmd = virCommandNewArgList(VZSTORAGE, "discover", NULL); + virCommandSetOutputBuffer(cmd, &buf); + + if (virCommandRun(cmd, NULL) < 0) + goto cleanup; + if (!buf) + goto cleanup;
Probably excessive check
+ + if (!(clusters = virStringSplitCount(buf, "\n", 0, &clusters_num))) + goto cleanup; + + vz.list.nsources = clusters_num - 1;
what if clusters_num == 0 ?
+ + if (VIR_ALLOC_N(vz.list.sources, vz.list.nsources) < 0) + goto cleanup; + + for (; i < vz.list.nsources; i++) { + if (VIR_ALLOC(vz.list.sources[i].devices) < 0) + goto cleanup; + vz.list.sources[i].ndevice = 1; + if (VIR_STRDUP(vz.list.sources[i].devices->path, clusters[i]) < 0) + goto cleanup;
as suggested for vzstorage source description only name field need to be set
+ } + + if (!(ret = virStoragePoolSourceListFormat(&vz.list))) + goto cleanup; + + cleanup: + for (i = 0; i < vz.list.nsources; i++) + virStoragePoolSourceClear(&vz.list.sources[i]); + VIR_FREE(vz.list.sources); + VIR_FREE(buf); + virCommandFree(cmd);
clean clusters too
+ return ret; + +} + +virStorageBackend virStorageBackendVz = { + .type = VIR_STORAGE_POOL_VZ, + + .startPool = virStorageBackendVzStart, + .checkPool = virStorageBackendVzCheck, + .stopPool = virStorageBackendVzStop, + .findPoolSources = virStorageBackendVzfindPoolSources, + .buildPool = virStorageBackendFileSystemBuild, + .deletePool = virStorageBackendFileSystemDelete, + .refreshPool = virStorageBackendFileSystemRefresh, + .buildVol = virStorageBackendFileSystemVolBuild, + .buildVolFrom = virStorageBackendFileSystemVolBuildFrom, + .createVol = virStorageBackendFileSystemVolCreate, + .refreshVol = virStorageBackendFileSystemVolRefresh, + .deleteVol = virStorageBackendFileSystemVolDelete, + .resizeVol = virStorageBackendFileSystemVolResize, + .uploadVol = virStorageBackendVolUploadLocal, + .downloadVol = virStorageBackendVolDownloadLocal, + .wipeVol = virStorageBackendVolWipeLocal, + +}; +#endif /* WITH_STORAGE_VZ */ diff --git a/src/storage/storage_backend_fs.h b/src/storage/storage_backend_fs.h index 347ea9b..f557639 100644 --- a/src/storage/storage_backend_fs.h +++ b/src/storage/storage_backend_fs.h @@ -30,6 +30,9 @@ extern virStorageBackend virStorageBackendFileSystem; extern virStorageBackend virStorageBackendNetFileSystem; # endif +#if WITH_STORAGE_VZ +extern virStorageBackend virStorageBackendVz; +#endif
typedef enum { FILESYSTEM_PROBE_FOUND, diff --git a/src/storage/storage_driver.c b/src/storage/storage_driver.c index 9999c2c..c691e05 100644 --- a/src/storage/storage_driver.c +++ b/src/storage/storage_driver.c @@ -1563,6 +1563,7 @@ storageVolLookupByPath(virConnectPtr conn, case VIR_STORAGE_POOL_ISCSI: case VIR_STORAGE_POOL_SCSI: case VIR_STORAGE_POOL_MPATH: + case VIR_STORAGE_POOL_VZ: stable_path = virStorageBackendStablePath(pool, cleanpath, false); @@ -3373,6 +3374,7 @@ virStorageTranslateDiskSourcePool(virConnectPtr conn, case VIR_STORAGE_POOL_DISK: case VIR_STORAGE_POOL_SCSI: case VIR_STORAGE_POOL_ZFS: + case VIR_STORAGE_POOL_VZ: if (!(def->src->path = virStorageVolGetPath(vol))) goto cleanup;
diff --git a/tools/virsh-pool.c b/tools/virsh-pool.c index f9299e2..2ac74fe 100644 --- a/tools/virsh-pool.c +++ b/tools/virsh-pool.c @@ -1165,6 +1165,8 @@ cmdPoolList(vshControl *ctl, const vshCmd *cmd ATTRIBUTE_UNUSED) case VIR_STORAGE_POOL_ZFS: flags |= VIR_CONNECT_LIST_STORAGE_POOLS_ZFS; break; + case VIR_STORAGE_POOL_VZ: + flags |= VIR_CONNECT_LIST_STORAGE_POOLS_VZ; case VIR_STORAGE_POOL_LAST: break; } diff --git a/tools/virsh.c b/tools/virsh.c index fe33839..e8428fb 100644 --- a/tools/virsh.c +++ b/tools/virsh.c @@ -666,6 +666,9 @@ virshShowVersion(vshControl *ctl ATTRIBUTE_UNUSED) #ifdef WITH_STORAGE_ZFS vshPrint(ctl, " ZFS"); #endif +#ifdef WITH_STORAGE_VZ + vshPrint(ctl, " VZ"); +#endif
i would print "vzstorage". Looks like define should be WITH_STORAGE_VZSTORAGE too.
vshPrint(ctl, "\n");
vshPrint(ctl, "%s", _(" Miscellaneous:"));

On 16.05.2016 10:25, Olga Krishtal wrote:
In-Reply-To:
This is first draft, that supports vzstorage in storage pools.i Virtuozzo Storage is a fault-tolerant distributed storage system, optimized for virtualization workloads. Vzstorage pool supports the same volume formats as directory, nfs, etc. In terms of volume management - there is no difference between these pools. You can find more information here: https://openvz.org/Virtuozzo_Storage XML: <pool type='vz'> <name>vz7_pool</name> <uuid>b27a72b5-a92e-4e58-a172-a80ba73b30fe</uuid> <capacity unit='bytes'>0</capacity> <allocation unit='bytes'>0</allocation> <available unit='bytes'>0</available> <source> <host name='127.0.0.2'/> <device path='vz7-vzstorage'/> <dir path='/pool1'/>
we need only cluster_name to mount vzstorage so i would put next under <source>: <name>cluster_name</name>
</source> <target> <path>/vz7-vzstorage</path> </target> </pool> To compile libvirt with vz pool support use key --with-storage-vz
I need some help to resolve some problems: - how to detect that pool is alredy mounted. - when we show pool sources do we need to show folders that may reside on vzstorage - I am not quite sure that we need host name in xml.
I will be glad to here your opinion.
participants (2)
-
Nikolay Shirokovskiy
-
Olga Krishtal