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 raw.
Signed-off-by: Olga Krishtal <okrishtal(a)virtuozzo.com>
---
configure.ac | 31 +++++++++++
docs/schemas/storagepool.rng | 29 ++++++++++
include/libvirt/libvirt-storage.h | 1 +
src/conf/storage_conf.c | 16 +++++-
src/conf/storage_conf.h | 4 +-
src/storage/storage_backend.c | 3 +
src/storage/storage_backend_fs.c | 112 +++++++++++++++++++++++++++++++++++++-
src/storage/storage_backend_fs.h | 3 +
src/storage/storage_driver.c | 2 +
tools/virsh-pool.c | 2 +
tools/virsh.c | 3 +
11 files changed, 203 insertions(+), 3 deletions(-)
diff --git a/configure.ac b/configure.ac
index 2c81c95..2ee8b8c 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1692,6 +1692,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-vstorage],
+ [AS_HELP_STRING([--with-storage-vstorage],
+ [with VZ backend for the storage driver @<:@default=check@:>@])],
+ [],[with_storage_vstorage=check])
if test "$with_libvirtd" = "no"; then
with_storage_dir=no
@@ -1705,6 +1709,7 @@ if test "$with_libvirtd" = "no"; then
with_storage_sheepdog=no
with_storage_gluster=no
with_storage_zfs=no
+ with_storage_vstorage=no
fi
if test "$with_storage_dir" = "yes" ; then
AC_DEFINE_UNQUOTED([WITH_STORAGE_DIR], 1, [whether directory backend for storage driver
is enabled])
@@ -1963,6 +1968,31 @@ if test "$with_storage_fs" = "yes" ||
fi
fi
+if test "$with_storage_vstorage" = "yes" || test
"$with_storage_vstorage" = "check"; then
+ AC_PATH_PROG([VSTORAGE], [vstorage], [], [$PATH:/sbin:/usr/bin])
+ AC_PATH_PROG([VSTORAGE_MOUNT], [vstorage-mount], [], [$PATH:/sbin/usr/bin])
+ if test "$with_storage_vstorage" = "yes"; then
+ if test -z "$VSTORAGE" ; then AC_MSG_ERROR([We need vstorage tools for
virtuozzo storage driver]); fi
+ if test -z "$VSTORAGE_MOUNT" ; then AC_MSG_ERROR([We need vstorage mount
tool for virtuozzo storage driver]); fi
+ if test "$with_storage_fs" = "no"; then AC_MSG_ERROR([We need fs
backend for vstorage pool]); fi
+ else
+ if test -z "$VSTORAGE" ; then with_storage_vstorage=no; fi
+ if test -z "$VSTORAGE" ; then with_storage_vstorage=no; fi
+ if test "$with_storage_fs"= "no"; then with_storage_vstorage=no;
fi
+
+ if test "$with_storage_vstorage" = "check" ; then
with_storage_vstorage=yes ; fi
+ fi
+ if test "$with_storage_vstorage" = "yes"; then
+ AC_DEFINE_UNQUOTED([WITH_STORAGE_VSTORAGE], 1, [whether virtuozzo storage backend
for storage driver is enabled])
+ AC_DEFINE_UNQUOTED([VSTORAGE], ["$VSTORAGE"], [Location or name of
vstorage program])
+ AC_DEFINE_UNQUOTED([VSTORAGE_MOUNT], ["$VSTORAGE_MOUNT"], [Location or
name of vstorage-mount program])
+ AC_DEFINE_UNQUOTED([with_storage_fs], ["$VSTORAGE_MOUNT"], [must be on])
+ fi
+
+ if test "$with_storage_vstorage" = "check" ; then
with_storage_vstorage=yes ; fi
+fi
+AM_CONDITIONAL([WITH_STORAGE_VSTORAGE], [test "$with_storage_vstorage" =
"yes"])
+
LIBPARTED_CFLAGS=
LIBPARTED_LIBS=
if test "$with_storage_disk" = "yes" ||
@@ -2759,6 +2789,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([Vstorage: $with_storage_vstorage])
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..8ad5616 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='poolvstorage'/>
</choice>
</element>
</define>
@@ -173,6 +174,18 @@
</interleave>
</define>
+ <define name='poolvstorage'>
+ <attribute name='type'>
+ <value>vz</value>
+ </attribute>
+ <interleave>
+ <ref name='commonmetadata'/>
+ <ref name='sizing'/>
+ <ref name='sourcevstorage'/>
+ <ref name='target'/>
+ </interleave>
+ </define>
+
<define name='sourceinfovendor'>
<interleave>
<optional>
@@ -609,6 +622,22 @@
</element>
</define>
+ <define name='clustername'>
+ <interleave>
+ <element name='name'>
+ <ref name='genericName'/>
+ </element>
+ </interleave>
+ </define>
+
+ <define name='sourcevstorage'>
+ <element name='source'>
+ <interleave>
+ <ref name='clustername'/>
+ </interleave>
+ </element>
+ </define>
+
<define name='IscsiQualifiedName'>
<data type='string'>
<param
name="pattern">iqn\.[0-9]{4}-(0[1-9]|1[0-2])\.[a-zA-Z0-9\.\-]+(:.+)?</param>
diff --git a/include/libvirt/libvirt-storage.h b/include/libvirt/libvirt-storage.h
index 0974f6e..28babf7 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_VSTORAGE = 1 << 18,
} virConnectListAllStoragePoolsFlags;
int virConnectListAllStoragePools(virConnectPtr conn,
diff --git a/src/conf/storage_conf.c b/src/conf/storage_conf.c
index 05a1a49..e3c8ac1 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",
"vstorage")
VIR_ENUM_IMPL(virStoragePoolFormatFileSystem,
VIR_STORAGE_POOL_FS_LAST,
@@ -274,6 +274,16 @@ static virStoragePoolTypeInfo poolTypeInfo[] = {
.defaultFormat = VIR_STORAGE_FILE_RAW,
},
},
+ {.poolType = VIR_STORAGE_POOL_VSTORAGE,
+ .poolOptions = {
+ .flags = VIR_STORAGE_POOL_SOURCE_NAME,
+ },
+ .volOptions = {
+ .defaultFormat = VIR_STORAGE_FILE_RAW,
+ .formatFromString = virStorageVolumeFormatFromString,
+ .formatToString = virStorageFileFormatTypeToString,
+ },
+ },
};
@@ -2588,6 +2598,10 @@ virStoragePoolSourceFindDuplicate(virConnectPtr conn,
/* Only one mpath pool is valid per host */
matchpool = pool;
break;
+ case VIR_STORAGE_POOL_VSTORAGE:
+ if (STREQ(pool->def->source.name, def->source.name))
+ 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 185ae5e..bf33b5f 100644
--- a/src/conf/storage_conf.h
+++ b/src/conf/storage_conf.h
@@ -95,6 +95,7 @@ typedef enum {
VIR_STORAGE_POOL_SHEEPDOG, /* Sheepdog device */
VIR_STORAGE_POOL_GLUSTER, /* Gluster device */
VIR_STORAGE_POOL_ZFS, /* ZFS */
+ VIR_STORAGE_POOL_VSTORAGE, /* Virtuozzo Storage */
VIR_STORAGE_POOL_LAST,
} virStoragePoolType;
@@ -545,7 +546,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_VSTORAGE)
# 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 97f6ffe..181d3f5 100644
--- a/src/storage/storage_backend.c
+++ b/src/storage/storage_backend.c
@@ -135,6 +135,9 @@ static virStorageBackendPtr backends[] = {
#if WITH_STORAGE_ZFS
&virStorageBackendZFS,
#endif
+#if WITH_STORAGE_VSTORAGE
+ &virStorageBackendVstorage,
+#endif
NULL
};
diff --git a/src/storage/storage_backend_fs.c b/src/storage/storage_backend_fs.c
index 0a12ecb..b89b3ae 100644
--- a/src/storage/storage_backend_fs.c
+++ b/src/storage/storage_backend_fs.c
@@ -371,7 +371,13 @@ virStorageBackendFileSystemIsValid(virStoragePoolObjPtr pool)
"%s", _("missing source path"));
return -1;
}
- } else {
+ } else if (pool->def->type == VIR_STORAGE_POOL_VSTORAGE) {
+ if (!pool->def->source.name) {
+ virReportError(VIR_ERR_INTERNAL_ERROR,
+ "%s", _("missing source cluster name"));
+ return -1;
+ }
+ } else{
if (pool->def->source.ndevice != 1) {
if (pool->def->source.ndevice == 0)
virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
@@ -411,6 +417,9 @@ virStorageBackendFileSystemGetPoolSource(virStoragePoolObjPtr pool)
pool->def->source.dir) < 0)
return NULL;
}
+ } else if (pool->def->type == VIR_STORAGE_POOL_VSTORAGE) {
+ if (virAsprintf(&src, "vstorage://%s",
pool->def->source.name) < 0)
+ return NULL;
} else {
if (VIR_STRDUP(src, pool->def->source.devices[0].path) < 0)
return NULL;
@@ -546,7 +555,9 @@ virStorageBackendFileSystemMount(virStoragePoolObjPtr pool)
VIR_FREE(src);
return ret;
}
+#endif /* WITH_STORAGE_FS */
+#if WITH_STORAGE_FS
/**
* @pool storage pool to unmount
*
@@ -1654,3 +1665,102 @@ virStorageFileBackend virStorageFileBackendDir = {
};
#endif /* WITH_STORAGE_FS */
+
+#if WITH_STORAGE_VSTORAGE
+static int
+virStorageBackendVzStart(virConnectPtr conn ATTRIBUTE_UNUSED,
+ virStoragePoolObjPtr pool)
+{
+ int ret = -1;
+ virCommandPtr cmd = NULL;
+
+ cmd = virCommandNewArgList(VSTORAGE_MOUNT, "-c",
pool->def->source.name,
+ pool->def->target.path, NULL);
+ if (virCommandRun(cmd, NULL) < 0)
+ goto cleanup;
+ ret = 0;
+
+ cleanup:
+ virCommandFree(cmd);
+ return ret;
+}
+
+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 = NULL;
+ size_t clusters_num = 0;
+ size_t i = 0;
+ virStoragePoolSourceList vzcluster_list = {
+ .type = VIR_STORAGE_POOL_VSTORAGE,
+ .nsources = 0,
+ .sources = NULL
+ };
+
+ virCheckFlags(0, NULL);
+
+ cmd = virCommandNewArgList(VSTORAGE, "discover", NULL);
+ virCommandSetOutputBuffer(cmd, &buf);
+
+ if (virCommandRun(cmd, NULL) < 0)
+ goto cleanup;
+
+ if (!(clusters = virStringSplitCount(buf, "\n", 0, &clusters_num)))
+ goto cleanup;
+
+ if (clusters_num > 0) {
+ vzcluster_list.nsources = clusters_num - 1;
+
+ if (VIR_ALLOC_N(vzcluster_list.sources, vzcluster_list.nsources) < 0)
+ goto cleanup;
+
+ for (; i < vzcluster_list.nsources; i++) {
+ if (VIR_ALLOC(vzcluster_list.sources[i].devices) < 0)
+ goto cleanup;
+ if (VIR_STRDUP(vzcluster_list.sources[i].name, clusters[i]) < 0)
+ goto cleanup;
+ }
+ }
+
+ if (!(ret = virStoragePoolSourceListFormat(&vzcluster_list)))
+ goto cleanup;
+
+ cleanup:
+ for (i = 0; i < vzcluster_list.nsources; i++) {
+ virStoragePoolSourceClear(&vzcluster_list.sources[i]);
+ VIR_FREE(clusters[i]);
+ }
+ VIR_FREE(vzcluster_list.sources);
+ VIR_FREE(buf);
+ virCommandFree(cmd);
+ return ret;
+
+}
+virStorageBackend virStorageBackendVstorage = {
+ .type = VIR_STORAGE_POOL_VSTORAGE,
+
+ .startPool = virStorageBackendVzStart,
+ .checkPool = virStorageBackendFileSystemCheck,
+ .stopPool = virStorageBackendFileSystemStop,
+ .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_VSTORAGE */
diff --git a/src/storage/storage_backend_fs.h b/src/storage/storage_backend_fs.h
index 347ea9b..23cff66 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_VSTORAGE
+extern virStorageBackend virStorageBackendVstorage;
+#endif
typedef enum {
FILESYSTEM_PROBE_FOUND,
diff --git a/src/storage/storage_driver.c b/src/storage/storage_driver.c
index cb9d578..3b6c7b4 100644
--- a/src/storage/storage_driver.c
+++ b/src/storage/storage_driver.c
@@ -1618,6 +1618,7 @@ storageVolLookupByPath(virConnectPtr conn,
case VIR_STORAGE_POOL_ISCSI:
case VIR_STORAGE_POOL_SCSI:
case VIR_STORAGE_POOL_MPATH:
+ case VIR_STORAGE_POOL_VSTORAGE:
stable_path = virStorageBackendStablePath(pool,
cleanpath,
false);
@@ -3485,6 +3486,7 @@ virStorageTranslateDiskSourcePool(virConnectPtr conn,
case VIR_STORAGE_POOL_DISK:
case VIR_STORAGE_POOL_SCSI:
case VIR_STORAGE_POOL_ZFS:
+ case VIR_STORAGE_POOL_VSTORAGE:
if (!(def->src->path = virStorageVolGetPath(vol)))
goto cleanup;
diff --git a/tools/virsh-pool.c b/tools/virsh-pool.c
index 6045331..6ea2424 100644
--- a/tools/virsh-pool.c
+++ b/tools/virsh-pool.c
@@ -1166,6 +1166,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_VSTORAGE:
+ flags |= VIR_CONNECT_LIST_STORAGE_POOLS_VSTORAGE;
case VIR_STORAGE_POOL_LAST:
break;
}
diff --git a/tools/virsh.c b/tools/virsh.c
index 5dc482d..61c8e2f 100644
--- a/tools/virsh.c
+++ b/tools/virsh.c
@@ -682,6 +682,9 @@ virshShowVersion(vshControl *ctl ATTRIBUTE_UNUSED)
#ifdef WITH_STORAGE_ZFS
vshPrint(ctl, " ZFS");
#endif
+#ifdef WITH_STORAGE_VSTORAGE
+ vshPrint(ctl, " Vstorage");
+#endif
vshPrint(ctl, "\n");
vshPrint(ctl, "%s", _(" Miscellaneous:"));
--
1.8.3.1