You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
686 lines
26 KiB
Diff
686 lines
26 KiB
Diff
commit 4e74c622884e2585b2cfcdf322fbd2bff6de41ca
|
|
Author: Vitaliy Filippov <vitalif@yourcmc.ru>
|
|
Date: Fri Jul 9 01:31:57 2021 +0300
|
|
|
|
Add Vitastor support
|
|
|
|
diff --git a/docs/schemas/domaincommon.rng b/docs/schemas/domaincommon.rng
|
|
index 7dc419b..875433b 100644
|
|
--- a/docs/schemas/domaincommon.rng
|
|
+++ b/docs/schemas/domaincommon.rng
|
|
@@ -1827,6 +1827,35 @@
|
|
</element>
|
|
</define>
|
|
|
|
+ <define name="diskSourceNetworkProtocolVitastor">
|
|
+ <element name="source">
|
|
+ <interleave>
|
|
+ <attribute name="protocol">
|
|
+ <value>vitastor</value>
|
|
+ </attribute>
|
|
+ <ref name="diskSourceCommon"/>
|
|
+ <optional>
|
|
+ <attribute name="name"/>
|
|
+ </optional>
|
|
+ <optional>
|
|
+ <attribute name="query"/>
|
|
+ </optional>
|
|
+ <zeroOrMore>
|
|
+ <ref name="diskSourceNetworkHost"/>
|
|
+ </zeroOrMore>
|
|
+ <optional>
|
|
+ <element name="config">
|
|
+ <attribute name="file">
|
|
+ <ref name="absFilePath"/>
|
|
+ </attribute>
|
|
+ <empty/>
|
|
+ </element>
|
|
+ </optional>
|
|
+ <empty/>
|
|
+ </interleave>
|
|
+ </element>
|
|
+ </define>
|
|
+
|
|
<define name="diskSourceNetworkProtocolISCSI">
|
|
<element name="source">
|
|
<attribute name="protocol">
|
|
@@ -2083,6 +2112,7 @@
|
|
<ref name="diskSourceNetworkProtocolSimple"/>
|
|
<ref name="diskSourceNetworkProtocolVxHS"/>
|
|
<ref name="diskSourceNetworkProtocolNFS"/>
|
|
+ <ref name="diskSourceNetworkProtocolVitastor"/>
|
|
</choice>
|
|
</define>
|
|
|
|
diff --git a/include/libvirt/libvirt-storage.h b/include/libvirt/libvirt-storage.h
|
|
index 089e1e0..d7e7ef4 100644
|
|
--- a/include/libvirt/libvirt-storage.h
|
|
+++ b/include/libvirt/libvirt-storage.h
|
|
@@ -245,6 +245,7 @@ typedef enum {
|
|
VIR_CONNECT_LIST_STORAGE_POOLS_ZFS = 1 << 17,
|
|
VIR_CONNECT_LIST_STORAGE_POOLS_VSTORAGE = 1 << 18,
|
|
VIR_CONNECT_LIST_STORAGE_POOLS_ISCSI_DIRECT = 1 << 19,
|
|
+ VIR_CONNECT_LIST_STORAGE_POOLS_VITASTOR = 1 << 20,
|
|
} virConnectListAllStoragePoolsFlags;
|
|
|
|
int virConnectListAllStoragePools(virConnectPtr conn,
|
|
diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
|
|
index 01b7187..645c758 100644
|
|
--- a/src/conf/domain_conf.c
|
|
+++ b/src/conf/domain_conf.c
|
|
@@ -5230,8 +5230,7 @@ virDomainDiskDefPostParse(virDomainDiskDefPtr disk,
|
|
const virDomainDef *def,
|
|
virDomainXMLOptionPtr xmlopt)
|
|
{
|
|
- /* internal snapshots and config files are currently supported
|
|
- * only with rbd: */
|
|
+ /* internal snapshots are currently supported only with rbd: */
|
|
if (virStorageSourceGetActualType(disk->src) != VIR_STORAGE_TYPE_NETWORK &&
|
|
disk->src->protocol != VIR_STORAGE_NET_PROTOCOL_RBD) {
|
|
if (disk->src->snapshot) {
|
|
@@ -5240,11 +5239,15 @@ virDomainDiskDefPostParse(virDomainDiskDefPtr disk,
|
|
"only with 'rbd' disks"));
|
|
return -1;
|
|
}
|
|
-
|
|
+ }
|
|
+ /* config files are currently supported only with rbd and vitastor: */
|
|
+ if (virStorageSourceGetActualType(disk->src) != VIR_STORAGE_TYPE_NETWORK &&
|
|
+ disk->src->protocol != VIR_STORAGE_NET_PROTOCOL_RBD &&
|
|
+ disk->src->protocol != VIR_STORAGE_NET_PROTOCOL_VITASTOR) {
|
|
if (disk->src->configFile) {
|
|
virReportError(VIR_ERR_XML_ERROR, "%s",
|
|
_("<config> element is currently supported "
|
|
- "only with 'rbd' disks"));
|
|
+ "only with 'rbd' and 'vitastor' disks"));
|
|
return -1;
|
|
}
|
|
}
|
|
@@ -8261,7 +8264,8 @@ virDomainDiskSourceNetworkParse(xmlNodePtr node,
|
|
src->configFile = virXPathString("string(./config/@file)", ctxt);
|
|
|
|
if (src->protocol == VIR_STORAGE_NET_PROTOCOL_HTTP ||
|
|
- src->protocol == VIR_STORAGE_NET_PROTOCOL_HTTPS)
|
|
+ src->protocol == VIR_STORAGE_NET_PROTOCOL_HTTPS ||
|
|
+ src->protocol == VIR_STORAGE_NET_PROTOCOL_VITASTOR)
|
|
src->query = virXMLPropString(node, "query");
|
|
|
|
if (virDomainStorageNetworkParseHosts(node, ctxt, &src->hosts, &src->nhosts) < 0)
|
|
@@ -31392,6 +31396,7 @@ virDomainStorageSourceTranslateSourcePool(virStorageSourcePtr src,
|
|
|
|
case VIR_STORAGE_POOL_MPATH:
|
|
case VIR_STORAGE_POOL_RBD:
|
|
+ case VIR_STORAGE_POOL_VITASTOR:
|
|
case VIR_STORAGE_POOL_SHEEPDOG:
|
|
case VIR_STORAGE_POOL_GLUSTER:
|
|
case VIR_STORAGE_POOL_LAST:
|
|
diff --git a/src/conf/storage_conf.c b/src/conf/storage_conf.c
|
|
index 0c50529..fe97574 100644
|
|
--- a/src/conf/storage_conf.c
|
|
+++ b/src/conf/storage_conf.c
|
|
@@ -60,7 +60,7 @@ VIR_ENUM_IMPL(virStoragePool,
|
|
"logical", "disk", "iscsi",
|
|
"iscsi-direct", "scsi", "mpath",
|
|
"rbd", "sheepdog", "gluster",
|
|
- "zfs", "vstorage",
|
|
+ "zfs", "vstorage", "vitastor",
|
|
);
|
|
|
|
VIR_ENUM_IMPL(virStoragePoolFormatFileSystem,
|
|
@@ -249,6 +249,18 @@ static virStoragePoolTypeInfo poolTypeInfo[] = {
|
|
.formatToString = virStorageFileFormatTypeToString,
|
|
}
|
|
},
|
|
+ {.poolType = VIR_STORAGE_POOL_VITASTOR,
|
|
+ .poolOptions = {
|
|
+ .flags = (VIR_STORAGE_POOL_SOURCE_HOST |
|
|
+ VIR_STORAGE_POOL_SOURCE_NETWORK |
|
|
+ VIR_STORAGE_POOL_SOURCE_NAME),
|
|
+ },
|
|
+ .volOptions = {
|
|
+ .defaultFormat = VIR_STORAGE_FILE_RAW,
|
|
+ .formatFromString = virStorageVolumeFormatFromString,
|
|
+ .formatToString = virStorageFileFormatTypeToString,
|
|
+ }
|
|
+ },
|
|
{.poolType = VIR_STORAGE_POOL_SHEEPDOG,
|
|
.poolOptions = {
|
|
.flags = (VIR_STORAGE_POOL_SOURCE_HOST |
|
|
@@ -551,6 +563,11 @@ virStoragePoolDefParseSource(xmlXPathContextPtr ctxt,
|
|
_("element 'name' is mandatory for RBD pool"));
|
|
goto cleanup;
|
|
}
|
|
+ if (pool_type == VIR_STORAGE_POOL_VITASTOR && source->name == NULL) {
|
|
+ virReportError(VIR_ERR_XML_ERROR, "%s",
|
|
+ _("element 'name' is mandatory for Vitastor pool"));
|
|
+ return -1;
|
|
+ }
|
|
|
|
if (options->formatFromString) {
|
|
g_autofree char *format = NULL;
|
|
@@ -1217,6 +1234,7 @@ virStoragePoolDefFormatBuf(virBufferPtr buf,
|
|
/* RBD, Sheepdog, Gluster and Iscsi-direct devices are not local block devs nor
|
|
* files, so they don't have a target */
|
|
if (def->type != VIR_STORAGE_POOL_RBD &&
|
|
+ def->type != VIR_STORAGE_POOL_VITASTOR &&
|
|
def->type != VIR_STORAGE_POOL_SHEEPDOG &&
|
|
def->type != VIR_STORAGE_POOL_GLUSTER &&
|
|
def->type != VIR_STORAGE_POOL_ISCSI_DIRECT) {
|
|
diff --git a/src/conf/storage_conf.h b/src/conf/storage_conf.h
|
|
index ffd406e..8868a05 100644
|
|
--- a/src/conf/storage_conf.h
|
|
+++ b/src/conf/storage_conf.h
|
|
@@ -110,6 +110,7 @@ typedef enum {
|
|
VIR_STORAGE_POOL_GLUSTER, /* Gluster device */
|
|
VIR_STORAGE_POOL_ZFS, /* ZFS */
|
|
VIR_STORAGE_POOL_VSTORAGE, /* Virtuozzo Storage */
|
|
+ VIR_STORAGE_POOL_VITASTOR, /* Vitastor */
|
|
|
|
VIR_STORAGE_POOL_LAST,
|
|
} virStoragePoolType;
|
|
@@ -474,6 +475,7 @@ VIR_ENUM_DECL(virStoragePartedFs);
|
|
VIR_CONNECT_LIST_STORAGE_POOLS_SCSI | \
|
|
VIR_CONNECT_LIST_STORAGE_POOLS_MPATH | \
|
|
VIR_CONNECT_LIST_STORAGE_POOLS_RBD | \
|
|
+ VIR_CONNECT_LIST_STORAGE_POOLS_VITASTOR | \
|
|
VIR_CONNECT_LIST_STORAGE_POOLS_SHEEPDOG | \
|
|
VIR_CONNECT_LIST_STORAGE_POOLS_GLUSTER | \
|
|
VIR_CONNECT_LIST_STORAGE_POOLS_ZFS | \
|
|
diff --git a/src/conf/virstorageobj.c b/src/conf/virstorageobj.c
|
|
index 9fe8b3f..bf595b0 100644
|
|
--- a/src/conf/virstorageobj.c
|
|
+++ b/src/conf/virstorageobj.c
|
|
@@ -1491,6 +1491,7 @@ virStoragePoolObjSourceFindDuplicateCb(const void *payload,
|
|
return 1;
|
|
break;
|
|
|
|
+ case VIR_STORAGE_POOL_VITASTOR:
|
|
case VIR_STORAGE_POOL_RBD:
|
|
case VIR_STORAGE_POOL_LAST:
|
|
break;
|
|
@@ -1990,6 +1991,8 @@ virStoragePoolObjMatch(virStoragePoolObjPtr obj,
|
|
(obj->def->type == VIR_STORAGE_POOL_MPATH)) ||
|
|
(MATCH(VIR_CONNECT_LIST_STORAGE_POOLS_RBD) &&
|
|
(obj->def->type == VIR_STORAGE_POOL_RBD)) ||
|
|
+ (MATCH(VIR_CONNECT_LIST_STORAGE_POOLS_VITASTOR) &&
|
|
+ (obj->def->type == VIR_STORAGE_POOL_VITASTOR)) ||
|
|
(MATCH(VIR_CONNECT_LIST_STORAGE_POOLS_SHEEPDOG) &&
|
|
(obj->def->type == VIR_STORAGE_POOL_SHEEPDOG)) ||
|
|
(MATCH(VIR_CONNECT_LIST_STORAGE_POOLS_GLUSTER) &&
|
|
diff --git a/src/libvirt-storage.c b/src/libvirt-storage.c
|
|
index 2a7cdca..f756be1 100644
|
|
--- a/src/libvirt-storage.c
|
|
+++ b/src/libvirt-storage.c
|
|
@@ -92,6 +92,7 @@ virStoragePoolGetConnect(virStoragePoolPtr pool)
|
|
* VIR_CONNECT_LIST_STORAGE_POOLS_SCSI
|
|
* VIR_CONNECT_LIST_STORAGE_POOLS_MPATH
|
|
* VIR_CONNECT_LIST_STORAGE_POOLS_RBD
|
|
+ * VIR_CONNECT_LIST_STORAGE_POOLS_VITASTOR
|
|
* VIR_CONNECT_LIST_STORAGE_POOLS_SHEEPDOG
|
|
* VIR_CONNECT_LIST_STORAGE_POOLS_GLUSTER
|
|
* VIR_CONNECT_LIST_STORAGE_POOLS_ZFS
|
|
diff --git a/src/libxl/libxl_conf.c b/src/libxl/libxl_conf.c
|
|
index 6a8ae27..a735bc6 100644
|
|
--- a/src/libxl/libxl_conf.c
|
|
+++ b/src/libxl/libxl_conf.c
|
|
@@ -942,6 +942,7 @@ libxlMakeNetworkDiskSrcStr(virStorageSourcePtr src,
|
|
case VIR_STORAGE_NET_PROTOCOL_SSH:
|
|
case VIR_STORAGE_NET_PROTOCOL_VXHS:
|
|
case VIR_STORAGE_NET_PROTOCOL_NFS:
|
|
+ case VIR_STORAGE_NET_PROTOCOL_VITASTOR:
|
|
case VIR_STORAGE_NET_PROTOCOL_LAST:
|
|
case VIR_STORAGE_NET_PROTOCOL_NONE:
|
|
virReportError(VIR_ERR_NO_SUPPORT,
|
|
diff --git a/src/libxl/xen_xl.c b/src/libxl/xen_xl.c
|
|
index 17b93d0..c5a0084 100644
|
|
--- a/src/libxl/xen_xl.c
|
|
+++ b/src/libxl/xen_xl.c
|
|
@@ -1601,6 +1601,7 @@ xenFormatXLDiskSrcNet(virStorageSourcePtr src)
|
|
case VIR_STORAGE_NET_PROTOCOL_SSH:
|
|
case VIR_STORAGE_NET_PROTOCOL_VXHS:
|
|
case VIR_STORAGE_NET_PROTOCOL_NFS:
|
|
+ case VIR_STORAGE_NET_PROTOCOL_VITASTOR:
|
|
case VIR_STORAGE_NET_PROTOCOL_LAST:
|
|
case VIR_STORAGE_NET_PROTOCOL_NONE:
|
|
virReportError(VIR_ERR_NO_SUPPORT,
|
|
diff --git a/src/qemu/qemu_block.c b/src/qemu/qemu_block.c
|
|
index f9c6da2..d837a05 100644
|
|
--- a/src/qemu/qemu_block.c
|
|
+++ b/src/qemu/qemu_block.c
|
|
@@ -938,6 +938,38 @@ qemuBlockStorageSourceGetRBDProps(virStorageSourcePtr src,
|
|
}
|
|
|
|
|
|
+static virJSONValuePtr
|
|
+qemuBlockStorageSourceGetVitastorProps(virStorageSource *src)
|
|
+{
|
|
+ virJSONValuePtr ret = NULL;
|
|
+ virStorageNetHostDefPtr host;
|
|
+ size_t i;
|
|
+ g_auto(virBuffer) buf = VIR_BUFFER_INITIALIZER;
|
|
+ g_autofree char *etcd = NULL;
|
|
+
|
|
+ for (i = 0; i < src->nhosts; i++) {
|
|
+ host = src->hosts + i;
|
|
+ if ((virStorageNetHostTransport)host->transport != VIR_STORAGE_NET_HOST_TRANS_TCP) {
|
|
+ return NULL;
|
|
+ }
|
|
+ virBufferAsprintf(&buf, i > 0 ? ",%s:%u" : "%s:%u", host->name, host->port);
|
|
+ }
|
|
+ if (src->nhosts > 0) {
|
|
+ etcd = virBufferContentAndReset(&buf);
|
|
+ }
|
|
+
|
|
+ if (virJSONValueObjectCreate(&ret,
|
|
+ "S:etcd-host", etcd,
|
|
+ "S:etcd-prefix", src->query,
|
|
+ "S:config-path", src->configFile,
|
|
+ "s:image", src->path,
|
|
+ NULL) < 0)
|
|
+ return NULL;
|
|
+
|
|
+ return ret;
|
|
+}
|
|
+
|
|
+
|
|
static virJSONValuePtr
|
|
qemuBlockStorageSourceGetSheepdogProps(virStorageSourcePtr src)
|
|
{
|
|
@@ -1224,6 +1256,12 @@ qemuBlockStorageSourceGetBackendProps(virStorageSourcePtr src,
|
|
return NULL;
|
|
break;
|
|
|
|
+ case VIR_STORAGE_NET_PROTOCOL_VITASTOR:
|
|
+ driver = "vitastor";
|
|
+ if (!(fileprops = qemuBlockStorageSourceGetVitastorProps(src)))
|
|
+ return NULL;
|
|
+ break;
|
|
+
|
|
case VIR_STORAGE_NET_PROTOCOL_SHEEPDOG:
|
|
driver = "sheepdog";
|
|
if (!(fileprops = qemuBlockStorageSourceGetSheepdogProps(src)))
|
|
@@ -2183,6 +2221,7 @@ qemuBlockGetBackingStoreString(virStorageSourcePtr src,
|
|
|
|
case VIR_STORAGE_NET_PROTOCOL_SHEEPDOG:
|
|
case VIR_STORAGE_NET_PROTOCOL_RBD:
|
|
+ case VIR_STORAGE_NET_PROTOCOL_VITASTOR:
|
|
case VIR_STORAGE_NET_PROTOCOL_VXHS:
|
|
case VIR_STORAGE_NET_PROTOCOL_NFS:
|
|
case VIR_STORAGE_NET_PROTOCOL_SSH:
|
|
@@ -2560,6 +2599,12 @@ qemuBlockStorageSourceCreateGetStorageProps(virStorageSourcePtr src,
|
|
return -1;
|
|
break;
|
|
|
|
+ case VIR_STORAGE_NET_PROTOCOL_VITASTOR:
|
|
+ driver = "vitastor";
|
|
+ if (!(location = qemuBlockStorageSourceGetVitastorProps(src)))
|
|
+ return -1;
|
|
+ break;
|
|
+
|
|
case VIR_STORAGE_NET_PROTOCOL_SHEEPDOG:
|
|
driver = "sheepdog";
|
|
if (!(location = qemuBlockStorageSourceGetSheepdogProps(src)))
|
|
diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c
|
|
index 6f970a3..4c03fb8 100644
|
|
--- a/src/qemu/qemu_command.c
|
|
+++ b/src/qemu/qemu_command.c
|
|
@@ -1034,6 +1034,43 @@ qemuBuildNetworkDriveStr(virStorageSourcePtr src,
|
|
ret = virBufferContentAndReset(&buf);
|
|
break;
|
|
|
|
+ case VIR_STORAGE_NET_PROTOCOL_VITASTOR:
|
|
+ if (strchr(src->path, ':')) {
|
|
+ virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
|
|
+ _("':' not allowed in Vitastor source volume name '%s'"),
|
|
+ src->path);
|
|
+ return NULL;
|
|
+ }
|
|
+
|
|
+ virBufferStrcat(&buf, "vitastor:image=", src->path, NULL);
|
|
+
|
|
+ if (src->nhosts > 0) {
|
|
+ virBufferAddLit(&buf, ":etcd-host=");
|
|
+ for (i = 0; i < src->nhosts; i++) {
|
|
+ if (i)
|
|
+ virBufferAddLit(&buf, ",");
|
|
+
|
|
+ /* assume host containing : is ipv6 */
|
|
+ if (strchr(src->hosts[i].name, ':'))
|
|
+ virBufferEscape(&buf, '\\', ":", "[%s]",
|
|
+ src->hosts[i].name);
|
|
+ else
|
|
+ virBufferAsprintf(&buf, "%s", src->hosts[i].name);
|
|
+
|
|
+ if (src->hosts[i].port)
|
|
+ virBufferAsprintf(&buf, "\\:%u", src->hosts[i].port);
|
|
+ }
|
|
+ }
|
|
+
|
|
+ if (src->configFile)
|
|
+ virBufferEscape(&buf, '\\', ":", ":config-path=%s", src->configFile);
|
|
+
|
|
+ if (src->query)
|
|
+ virBufferEscape(&buf, '\\', ":", ":etcd-prefix=%s", src->query);
|
|
+
|
|
+ ret = virBufferContentAndReset(&buf);
|
|
+ break;
|
|
+
|
|
case VIR_STORAGE_NET_PROTOCOL_VXHS:
|
|
virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
|
|
_("VxHS protocol does not support URI syntax"));
|
|
diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c
|
|
index 0765dc7..4cff344 100644
|
|
--- a/src/qemu/qemu_domain.c
|
|
+++ b/src/qemu/qemu_domain.c
|
|
@@ -4610,7 +4610,8 @@ qemuDomainValidateStorageSource(virStorageSourcePtr src,
|
|
if (src->query &&
|
|
(actualType != VIR_STORAGE_TYPE_NETWORK ||
|
|
(src->protocol != VIR_STORAGE_NET_PROTOCOL_HTTPS &&
|
|
- src->protocol != VIR_STORAGE_NET_PROTOCOL_HTTP))) {
|
|
+ src->protocol != VIR_STORAGE_NET_PROTOCOL_HTTP &&
|
|
+ src->protocol != VIR_STORAGE_NET_PROTOCOL_VITASTOR))) {
|
|
virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
|
|
_("query is supported only with HTTP(S) protocols"));
|
|
return -1;
|
|
@@ -9704,6 +9705,7 @@ qemuDomainPrepareStorageSourceTLS(virStorageSourcePtr src,
|
|
break;
|
|
|
|
case VIR_STORAGE_NET_PROTOCOL_RBD:
|
|
+ case VIR_STORAGE_NET_PROTOCOL_VITASTOR:
|
|
case VIR_STORAGE_NET_PROTOCOL_SHEEPDOG:
|
|
case VIR_STORAGE_NET_PROTOCOL_GLUSTER:
|
|
case VIR_STORAGE_NET_PROTOCOL_ISCSI:
|
|
diff --git a/src/qemu/qemu_snapshot.c b/src/qemu/qemu_snapshot.c
|
|
index ee333c3..674aa58 100644
|
|
--- a/src/qemu/qemu_snapshot.c
|
|
+++ b/src/qemu/qemu_snapshot.c
|
|
@@ -403,6 +403,7 @@ qemuSnapshotPrepareDiskExternalInactive(virDomainSnapshotDiskDefPtr snapdisk,
|
|
case VIR_STORAGE_NET_PROTOCOL_NONE:
|
|
case VIR_STORAGE_NET_PROTOCOL_NBD:
|
|
case VIR_STORAGE_NET_PROTOCOL_RBD:
|
|
+ case VIR_STORAGE_NET_PROTOCOL_VITASTOR:
|
|
case VIR_STORAGE_NET_PROTOCOL_SHEEPDOG:
|
|
case VIR_STORAGE_NET_PROTOCOL_GLUSTER:
|
|
case VIR_STORAGE_NET_PROTOCOL_ISCSI:
|
|
@@ -493,6 +494,7 @@ qemuSnapshotPrepareDiskExternalActive(virDomainObjPtr vm,
|
|
case VIR_STORAGE_NET_PROTOCOL_NONE:
|
|
case VIR_STORAGE_NET_PROTOCOL_NBD:
|
|
case VIR_STORAGE_NET_PROTOCOL_RBD:
|
|
+ case VIR_STORAGE_NET_PROTOCOL_VITASTOR:
|
|
case VIR_STORAGE_NET_PROTOCOL_SHEEPDOG:
|
|
case VIR_STORAGE_NET_PROTOCOL_ISCSI:
|
|
case VIR_STORAGE_NET_PROTOCOL_HTTP:
|
|
@@ -623,6 +625,7 @@ qemuSnapshotPrepareDiskInternal(virDomainDiskDefPtr disk,
|
|
case VIR_STORAGE_NET_PROTOCOL_NONE:
|
|
case VIR_STORAGE_NET_PROTOCOL_NBD:
|
|
case VIR_STORAGE_NET_PROTOCOL_RBD:
|
|
+ case VIR_STORAGE_NET_PROTOCOL_VITASTOR:
|
|
case VIR_STORAGE_NET_PROTOCOL_SHEEPDOG:
|
|
case VIR_STORAGE_NET_PROTOCOL_GLUSTER:
|
|
case VIR_STORAGE_NET_PROTOCOL_ISCSI:
|
|
diff --git a/src/storage/storage_driver.c b/src/storage/storage_driver.c
|
|
index 16bc53a..1e5d820 100644
|
|
--- a/src/storage/storage_driver.c
|
|
+++ b/src/storage/storage_driver.c
|
|
@@ -1645,6 +1645,7 @@ storageVolLookupByPathCallback(virStoragePoolObjPtr obj,
|
|
|
|
case VIR_STORAGE_POOL_GLUSTER:
|
|
case VIR_STORAGE_POOL_RBD:
|
|
+ case VIR_STORAGE_POOL_VITASTOR:
|
|
case VIR_STORAGE_POOL_SHEEPDOG:
|
|
case VIR_STORAGE_POOL_ZFS:
|
|
case VIR_STORAGE_POOL_LAST:
|
|
diff --git a/src/test/test_driver.c b/src/test/test_driver.c
|
|
index 29c4c86..a27ad94 100644
|
|
--- a/src/test/test_driver.c
|
|
+++ b/src/test/test_driver.c
|
|
@@ -7096,6 +7096,7 @@ testStorageVolumeTypeForPool(int pooltype)
|
|
case VIR_STORAGE_POOL_ISCSI_DIRECT:
|
|
case VIR_STORAGE_POOL_GLUSTER:
|
|
case VIR_STORAGE_POOL_RBD:
|
|
+ case VIR_STORAGE_POOL_VITASTOR:
|
|
return VIR_STORAGE_VOL_NETWORK;
|
|
case VIR_STORAGE_POOL_LOGICAL:
|
|
case VIR_STORAGE_POOL_DISK:
|
|
diff --git a/src/util/virstoragefile.c b/src/util/virstoragefile.c
|
|
index 0d3c2af..edb7f9e 100644
|
|
--- a/src/util/virstoragefile.c
|
|
+++ b/src/util/virstoragefile.c
|
|
@@ -91,6 +91,7 @@ VIR_ENUM_IMPL(virStorageNetProtocol,
|
|
"ssh",
|
|
"vxhs",
|
|
"nfs",
|
|
+ "vitastor",
|
|
);
|
|
|
|
VIR_ENUM_IMPL(virStorageNetHostTransport,
|
|
@@ -2880,6 +2881,75 @@ virStorageSourceParseRBDColonString(const char *rbdstr,
|
|
}
|
|
|
|
|
|
+static int
|
|
+virStorageSourceParseVitastorColonString(const char *colonstr,
|
|
+ virStorageSourcePtr src)
|
|
+{
|
|
+ char *p, *e, *next;
|
|
+ g_autofree char *options = NULL;
|
|
+
|
|
+ /* optionally skip the "vitastor:" prefix if provided */
|
|
+ if (STRPREFIX(colonstr, "vitastor:"))
|
|
+ colonstr += strlen("vitastor:");
|
|
+
|
|
+ options = g_strdup(colonstr);
|
|
+
|
|
+ p = options;
|
|
+ while (*p) {
|
|
+ /* find : delimiter or end of string */
|
|
+ for (e = p; *e && *e != ':'; ++e) {
|
|
+ if (*e == '\\') {
|
|
+ e++;
|
|
+ if (*e == '\0')
|
|
+ break;
|
|
+ }
|
|
+ }
|
|
+ if (*e == '\0') {
|
|
+ next = e; /* last kv pair */
|
|
+ } else {
|
|
+ next = e + 1;
|
|
+ *e = '\0';
|
|
+ }
|
|
+
|
|
+ if (STRPREFIX(p, "image=")) {
|
|
+ src->path = g_strdup(p + strlen("image="));
|
|
+ } else if (STRPREFIX(p, "etcd-prefix=")) {
|
|
+ src->query = g_strdup(p + strlen("etcd-prefix="));
|
|
+ } else if (STRPREFIX(p, "config-path=")) {
|
|
+ src->configFile = g_strdup(p + strlen("config-path="));
|
|
+ } else if (STRPREFIX(p, "etcd-host=")) {
|
|
+ char *h, *sep;
|
|
+
|
|
+ h = p + strlen("etcd-host=");
|
|
+ while (h < e) {
|
|
+ for (sep = h; sep < e; ++sep) {
|
|
+ if (*sep == '\\' && (sep[1] == ',' ||
|
|
+ sep[1] == ';' ||
|
|
+ sep[1] == ' ')) {
|
|
+ *sep = '\0';
|
|
+ sep += 2;
|
|
+ break;
|
|
+ }
|
|
+ }
|
|
+
|
|
+ if (virStorageSourceRBDAddHost(src, h) < 0)
|
|
+ return -1;
|
|
+
|
|
+ h = sep;
|
|
+ }
|
|
+ }
|
|
+
|
|
+ p = next;
|
|
+ }
|
|
+
|
|
+ if (!src->path) {
|
|
+ return -1;
|
|
+ }
|
|
+
|
|
+ return 0;
|
|
+}
|
|
+
|
|
+
|
|
static int
|
|
virStorageSourceParseNBDColonString(const char *nbdstr,
|
|
virStorageSourcePtr src)
|
|
@@ -2992,6 +3062,11 @@ virStorageSourceParseBackingColon(virStorageSourcePtr src,
|
|
return -1;
|
|
break;
|
|
|
|
+ case VIR_STORAGE_NET_PROTOCOL_VITASTOR:
|
|
+ if (virStorageSourceParseVitastorColonString(path, src) < 0)
|
|
+ return -1;
|
|
+ break;
|
|
+
|
|
case VIR_STORAGE_NET_PROTOCOL_SHEEPDOG:
|
|
case VIR_STORAGE_NET_PROTOCOL_LAST:
|
|
case VIR_STORAGE_NET_PROTOCOL_NONE:
|
|
@@ -3581,6 +3656,54 @@ virStorageSourceParseBackingJSONRBD(virStorageSourcePtr src,
|
|
return 0;
|
|
}
|
|
|
|
+static int
|
|
+virStorageSourceParseBackingJSONVitastor(virStorageSourcePtr src,
|
|
+ virJSONValuePtr json,
|
|
+ const char *jsonstr G_GNUC_UNUSED,
|
|
+ int opaque G_GNUC_UNUSED)
|
|
+{
|
|
+ const char *filename;
|
|
+ const char *image = virJSONValueObjectGetString(json, "image");
|
|
+ const char *conf = virJSONValueObjectGetString(json, "config-path");
|
|
+ const char *etcd_prefix = virJSONValueObjectGetString(json, "etcd-prefix");
|
|
+ virJSONValuePtr servers = virJSONValueObjectGetArray(json, "server");
|
|
+ size_t nservers;
|
|
+ size_t i;
|
|
+
|
|
+ src->type = VIR_STORAGE_TYPE_NETWORK;
|
|
+ src->protocol = VIR_STORAGE_NET_PROTOCOL_VITASTOR;
|
|
+
|
|
+ /* legacy syntax passed via 'filename' option */
|
|
+ if ((filename = virJSONValueObjectGetString(json, "filename")))
|
|
+ return virStorageSourceParseVitastorColonString(filename, src);
|
|
+
|
|
+ if (!image) {
|
|
+ virReportError(VIR_ERR_INVALID_ARG, "%s",
|
|
+ _("missing image name in Vitastor backing volume "
|
|
+ "JSON specification"));
|
|
+ return -1;
|
|
+ }
|
|
+
|
|
+ src->path = g_strdup(image);
|
|
+ src->configFile = g_strdup(conf);
|
|
+ src->query = g_strdup(etcd_prefix);
|
|
+
|
|
+ if (servers) {
|
|
+ nservers = virJSONValueArraySize(servers);
|
|
+
|
|
+ src->hosts = g_new0(virStorageNetHostDef, nservers);
|
|
+ src->nhosts = nservers;
|
|
+
|
|
+ for (i = 0; i < nservers; i++) {
|
|
+ if (virStorageSourceParseBackingJSONInetSocketAddress(src->hosts + i,
|
|
+ virJSONValueArrayGet(servers, i)) < 0)
|
|
+ return -1;
|
|
+ }
|
|
+ }
|
|
+
|
|
+ return 0;
|
|
+}
|
|
+
|
|
static int
|
|
virStorageSourceParseBackingJSONRaw(virStorageSourcePtr src,
|
|
virJSONValuePtr json,
|
|
@@ -3759,6 +3882,7 @@ static const struct virStorageSourceJSONDriverParser jsonParsers[] = {
|
|
{"sheepdog", false, virStorageSourceParseBackingJSONSheepdog, 0},
|
|
{"ssh", false, virStorageSourceParseBackingJSONSSH, 0},
|
|
{"rbd", false, virStorageSourceParseBackingJSONRBD, 0},
|
|
+ {"vitastor", false, virStorageSourceParseBackingJSONVitastor, 0},
|
|
{"raw", true, virStorageSourceParseBackingJSONRaw, 0},
|
|
{"nfs", false, virStorageSourceParseBackingJSONNFS, 0},
|
|
{"vxhs", false, virStorageSourceParseBackingJSONVxHS, 0},
|
|
@@ -4503,6 +4627,7 @@ virStorageSourceNetworkDefaultPort(virStorageNetProtocol protocol)
|
|
case VIR_STORAGE_NET_PROTOCOL_GLUSTER:
|
|
return 24007;
|
|
|
|
+ case VIR_STORAGE_NET_PROTOCOL_VITASTOR:
|
|
case VIR_STORAGE_NET_PROTOCOL_RBD:
|
|
/* we don't provide a default for RBD */
|
|
return 0;
|
|
diff --git a/src/util/virstoragefile.h b/src/util/virstoragefile.h
|
|
index 5689c39..3eb4e3c 100644
|
|
--- a/src/util/virstoragefile.h
|
|
+++ b/src/util/virstoragefile.h
|
|
@@ -136,6 +136,7 @@ typedef enum {
|
|
VIR_STORAGE_NET_PROTOCOL_SSH,
|
|
VIR_STORAGE_NET_PROTOCOL_VXHS,
|
|
VIR_STORAGE_NET_PROTOCOL_NFS,
|
|
+ VIR_STORAGE_NET_PROTOCOL_VITASTOR,
|
|
|
|
VIR_STORAGE_NET_PROTOCOL_LAST
|
|
} virStorageNetProtocol;
|
|
diff --git a/tests/storagepoolcapsschemadata/poolcaps-fs.xml b/tests/storagepoolcapsschemadata/poolcaps-fs.xml
|
|
index eee75af..8bd0a57 100644
|
|
--- a/tests/storagepoolcapsschemadata/poolcaps-fs.xml
|
|
+++ b/tests/storagepoolcapsschemadata/poolcaps-fs.xml
|
|
@@ -204,4 +204,11 @@
|
|
</enum>
|
|
</volOptions>
|
|
</pool>
|
|
+ <pool type='vitastor' supported='no'>
|
|
+ <volOptions>
|
|
+ <defaultFormat type='raw'/>
|
|
+ <enum name='targetFormatType'>
|
|
+ </enum>
|
|
+ </volOptions>
|
|
+ </pool>
|
|
</storagepoolCapabilities>
|
|
diff --git a/tests/storagepoolcapsschemadata/poolcaps-full.xml b/tests/storagepoolcapsschemadata/poolcaps-full.xml
|
|
index 805950a..852df0d 100644
|
|
--- a/tests/storagepoolcapsschemadata/poolcaps-full.xml
|
|
+++ b/tests/storagepoolcapsschemadata/poolcaps-full.xml
|
|
@@ -204,4 +204,11 @@
|
|
</enum>
|
|
</volOptions>
|
|
</pool>
|
|
+ <pool type='vitastor' supported='yes'>
|
|
+ <volOptions>
|
|
+ <defaultFormat type='raw'/>
|
|
+ <enum name='targetFormatType'>
|
|
+ </enum>
|
|
+ </volOptions>
|
|
+ </pool>
|
|
</storagepoolCapabilities>
|
|
diff --git a/tests/storagepoolxml2argvtest.c b/tests/storagepoolxml2argvtest.c
|
|
index 967d1f2..1e8ff7a 100644
|
|
--- a/tests/storagepoolxml2argvtest.c
|
|
+++ b/tests/storagepoolxml2argvtest.c
|
|
@@ -68,6 +68,7 @@ testCompareXMLToArgvFiles(bool shouldFail,
|
|
case VIR_STORAGE_POOL_GLUSTER:
|
|
case VIR_STORAGE_POOL_ZFS:
|
|
case VIR_STORAGE_POOL_VSTORAGE:
|
|
+ case VIR_STORAGE_POOL_VITASTOR:
|
|
case VIR_STORAGE_POOL_LAST:
|
|
default:
|
|
VIR_TEST_DEBUG("pool type '%s' has no xml2argv test", defTypeStr);
|
|
diff --git a/tools/virsh-pool.c b/tools/virsh-pool.c
|
|
index 7835fa6..8841fcf 100644
|
|
--- a/tools/virsh-pool.c
|
|
+++ b/tools/virsh-pool.c
|
|
@@ -1237,6 +1237,9 @@ cmdPoolList(vshControl *ctl, const vshCmd *cmd G_GNUC_UNUSED)
|
|
case VIR_STORAGE_POOL_VSTORAGE:
|
|
flags |= VIR_CONNECT_LIST_STORAGE_POOLS_VSTORAGE;
|
|
break;
|
|
+ case VIR_STORAGE_POOL_VITASTOR:
|
|
+ flags |= VIR_CONNECT_LIST_STORAGE_POOLS_VITASTOR;
|
|
+ break;
|
|
case VIR_STORAGE_POOL_LAST:
|
|
break;
|
|
}
|