2021-07-09 01:09:21 +03:00
|
|
|
commit bd283191b3e7a4c6d1c100d3d96e348a1ebffe55
|
2021-06-27 18:43:29 +03:00
|
|
|
Author: Vitaliy Filippov <vitalif@yourcmc.ru>
|
|
|
|
Date: Sun Jun 27 12:52:40 2021 +0300
|
|
|
|
|
|
|
|
Add Vitastor support
|
|
|
|
|
2021-06-28 01:20:55 +03:00
|
|
|
diff --git a/docs/schemas/domaincommon.rng b/docs/schemas/domaincommon.rng
|
|
|
|
index aa50eac..082b4f8 100644
|
|
|
|
--- a/docs/schemas/domaincommon.rng
|
|
|
|
+++ b/docs/schemas/domaincommon.rng
|
|
|
|
@@ -1728,6 +1728,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">
|
|
|
|
@@ -1851,6 +1880,7 @@
|
|
|
|
<ref name="diskSourceNetworkProtocolHTTP"/>
|
|
|
|
<ref name="diskSourceNetworkProtocolSimple"/>
|
|
|
|
<ref name="diskSourceNetworkProtocolVxHS"/>
|
|
|
|
+ <ref name="diskSourceNetworkProtocolVitastor"/>
|
|
|
|
</choice>
|
|
|
|
</define>
|
|
|
|
|
2021-06-27 18:43:29 +03:00
|
|
|
diff --git a/include/libvirt/libvirt-storage.h b/include/libvirt/libvirt-storage.h
|
|
|
|
index 4bf2b5f..dbc011b 100644
|
|
|
|
--- a/include/libvirt/libvirt-storage.h
|
|
|
|
+++ b/include/libvirt/libvirt-storage.h
|
|
|
|
@@ -240,6 +240,7 @@ typedef enum {
|
|
|
|
VIR_CONNECT_LIST_STORAGE_POOLS_GLUSTER = 1 << 16,
|
|
|
|
VIR_CONNECT_LIST_STORAGE_POOLS_ZFS = 1 << 17,
|
|
|
|
VIR_CONNECT_LIST_STORAGE_POOLS_VSTORAGE = 1 << 18,
|
|
|
|
+ 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
|
2021-07-09 01:09:21 +03:00
|
|
|
index 222bb8c..685d255 100644
|
2021-06-27 18:43:29 +03:00
|
|
|
--- a/src/conf/domain_conf.c
|
|
|
|
+++ b/src/conf/domain_conf.c
|
2021-07-09 01:09:21 +03:00
|
|
|
@@ -8653,6 +8653,10 @@ virDomainDiskSourceNetworkParse(xmlNodePtr node,
|
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
|
|
|
|
+ if (src->protocol == VIR_STORAGE_NET_PROTOCOL_VITASTOR) {
|
|
|
|
+ src->relPath = virXMLPropString(node, "query");
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
if ((haveTLS = virXMLPropString(node, "tls")) &&
|
|
|
|
(src->haveTLS = virTristateBoolTypeFromString(haveTLS)) <= 0) {
|
|
|
|
virReportError(VIR_ERR_XML_ERROR,
|
|
|
|
@@ -23849,6 +23853,10 @@ virDomainDiskSourceFormatNetwork(virBufferPtr attrBuf,
|
|
|
|
|
|
|
|
virBufferEscapeString(attrBuf, " name='%s'", path ? path : src->path);
|
|
|
|
|
|
|
|
+ if (src->protocol == VIR_STORAGE_NET_PROTOCOL_VITASTOR && src->relPath != NULL) {
|
|
|
|
+ virBufferEscapeString(attrBuf, " query='%s'", src->relPath);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
VIR_FREE(path);
|
|
|
|
|
|
|
|
if (src->haveTLS != VIR_TRISTATE_BOOL_ABSENT &&
|
|
|
|
@@ -30930,6 +30938,7 @@ virDomainDiskTranslateSourcePool(virDomainDiskDefPtr def)
|
2021-06-27 18:43:29 +03:00
|
|
|
|
|
|
|
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 55db7a9..7cbe937 100644
|
|
|
|
--- a/src/conf/storage_conf.c
|
|
|
|
+++ b/src/conf/storage_conf.c
|
|
|
|
@@ -58,7 +58,7 @@ VIR_ENUM_IMPL(virStoragePool,
|
|
|
|
"logical", "disk", "iscsi",
|
|
|
|
"iscsi-direct", "scsi", "mpath",
|
|
|
|
"rbd", "sheepdog", "gluster",
|
|
|
|
- "zfs", "vstorage")
|
|
|
|
+ "zfs", "vstorage", "vitastor")
|
|
|
|
|
|
|
|
VIR_ENUM_IMPL(virStoragePoolFormatFileSystem,
|
|
|
|
VIR_STORAGE_POOL_FS_LAST,
|
|
|
|
@@ -232,6 +232,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 |
|
|
|
|
@@ -434,6 +446,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) {
|
|
|
|
char *format = virXPathString("string(./format/@type)", ctxt);
|
|
|
|
@@ -1009,6 +1026,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 dc0aa2a..ed4983d 100644
|
|
|
|
--- a/src/conf/storage_conf.h
|
|
|
|
+++ b/src/conf/storage_conf.h
|
|
|
|
@@ -91,6 +91,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;
|
|
|
|
@@ -422,6 +423,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 6ea6a97..3ba45b9 100644
|
|
|
|
--- a/src/conf/virstorageobj.c
|
|
|
|
+++ b/src/conf/virstorageobj.c
|
|
|
|
@@ -1478,6 +1478,7 @@ virStoragePoolObjSourceFindDuplicateCb(const void *payload,
|
|
|
|
return 1;
|
|
|
|
break;
|
|
|
|
|
|
|
|
+ case VIR_STORAGE_POOL_VITASTOR:
|
|
|
|
case VIR_STORAGE_POOL_RBD:
|
|
|
|
case VIR_STORAGE_POOL_LAST:
|
|
|
|
break;
|
|
|
|
@@ -1971,6 +1972,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 2ea3e94..d5d2273 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
|
|
|
|
*
|
|
|
|
* Returns the number of storage pools found or -1 and sets @pools to
|
|
|
|
diff --git a/src/libxl/libxl_conf.c b/src/libxl/libxl_conf.c
|
|
|
|
index 73e988a..ab7bb81 100644
|
|
|
|
--- a/src/libxl/libxl_conf.c
|
|
|
|
+++ b/src/libxl/libxl_conf.c
|
|
|
|
@@ -905,6 +905,7 @@ libxlMakeNetworkDiskSrcStr(virStorageSourcePtr src,
|
|
|
|
case VIR_STORAGE_NET_PROTOCOL_SHEEPDOG:
|
|
|
|
case VIR_STORAGE_NET_PROTOCOL_SSH:
|
|
|
|
case VIR_STORAGE_NET_PROTOCOL_VXHS:
|
|
|
|
+ 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
|
2021-07-09 01:09:21 +03:00
|
|
|
index cbf0aa4..096700d 100644
|
2021-06-27 18:43:29 +03:00
|
|
|
--- a/src/qemu/qemu_block.c
|
|
|
|
+++ b/src/qemu/qemu_block.c
|
2021-07-09 01:09:21 +03:00
|
|
|
@@ -959,6 +959,42 @@ qemuBlockStorageSourceGetRBDProps(virStorageSourcePtr src)
|
2021-06-27 18:43:29 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
+static virJSONValuePtr
|
|
|
|
+qemuBlockStorageSourceGetVitastorProps(virStorageSource *src)
|
|
|
|
+{
|
|
|
|
+ virJSONValuePtr ret = NULL;
|
2021-07-09 01:09:21 +03:00
|
|
|
+ virStorageNetHostDefPtr host;
|
|
|
|
+ size_t i;
|
|
|
|
+ virBuffer buf = VIR_BUFFER_INITIALIZER;
|
|
|
|
+ char *etcd = NULL;
|
2021-06-27 18:43:29 +03:00
|
|
|
+
|
2021-07-09 01:09:21 +03:00
|
|
|
+ for (i = 0; i < src->nhosts; i++) {
|
|
|
|
+ host = src->hosts + i;
|
|
|
|
+ if ((virStorageNetHostTransport)host->transport != VIR_STORAGE_NET_HOST_TRANS_TCP) {
|
|
|
|
+ goto cleanup;
|
|
|
|
+ }
|
|
|
|
+ virBufferAsprintf(&buf, i > 0 ? ",%s:%u" : "%s:%u", host->name, host->port);
|
|
|
|
+ }
|
|
|
|
+ if (src->nhosts > 0) {
|
|
|
|
+ etcd = virBufferContentAndReset(&buf);
|
|
|
|
+ }
|
2021-06-27 18:43:29 +03:00
|
|
|
+
|
|
|
|
+ if (virJSONValueObjectCreate(&ret,
|
|
|
|
+ "s:driver", "vitastor",
|
2021-11-21 16:16:46 +03:00
|
|
|
+ "S:etcd-host", etcd,
|
|
|
|
+ "S:etcd-prefix", src->relPath,
|
|
|
|
+ "S:config-path", src->configFile,
|
2021-06-27 18:43:29 +03:00
|
|
|
+ "s:image", src->path,
|
|
|
|
+ NULL) < 0)
|
2021-07-09 01:09:21 +03:00
|
|
|
+ goto cleanup;
|
2021-06-27 18:43:29 +03:00
|
|
|
+
|
2021-07-09 01:09:21 +03:00
|
|
|
+cleanup:
|
|
|
|
+ VIR_FREE(etcd);
|
|
|
|
+ virBufferFreeAndReset(&buf);
|
2021-06-27 18:43:29 +03:00
|
|
|
+ return ret;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+
|
|
|
|
static virJSONValuePtr
|
|
|
|
qemuBlockStorageSourceGetSheepdogProps(virStorageSourcePtr src)
|
|
|
|
{
|
2021-07-09 01:09:21 +03:00
|
|
|
@@ -1174,6 +1210,11 @@ qemuBlockStorageSourceGetBackendProps(virStorageSourcePtr src,
|
2021-06-27 18:43:29 +03:00
|
|
|
return NULL;
|
|
|
|
break;
|
|
|
|
|
|
|
|
+ case VIR_STORAGE_NET_PROTOCOL_VITASTOR:
|
|
|
|
+ if (!(fileprops = qemuBlockStorageSourceGetVitastorProps(src)))
|
|
|
|
+ return NULL;
|
|
|
|
+ break;
|
|
|
|
+
|
|
|
|
case VIR_STORAGE_NET_PROTOCOL_SHEEPDOG:
|
|
|
|
if (!(fileprops = qemuBlockStorageSourceGetSheepdogProps(src)))
|
|
|
|
return NULL;
|
|
|
|
diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c
|
|
|
|
index 822d5f8..e375cef 100644
|
|
|
|
--- a/src/qemu/qemu_command.c
|
|
|
|
+++ b/src/qemu/qemu_command.c
|
|
|
|
@@ -975,6 +975,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) {
|
2021-11-21 16:16:46 +03:00
|
|
|
+ virBufferAddLit(&buf, ":etcd-host=");
|
2021-06-27 18:43:29 +03:00
|
|
|
+ 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)
|
2021-11-21 16:16:46 +03:00
|
|
|
+ virBufferEscape(&buf, '\\', ":", ":config-path=%s", src->configFile);
|
2021-06-27 18:43:29 +03:00
|
|
|
+
|
|
|
|
+ if (src->relPath)
|
2021-11-21 16:16:46 +03:00
|
|
|
+ virBufferEscape(&buf, '\\', ":", ":etcd-prefix=%s", src->relPath);
|
2021-06-27 18:43:29 +03:00
|
|
|
+
|
|
|
|
+ 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 ec6b340..f399efa 100644
|
|
|
|
--- a/src/qemu/qemu_domain.c
|
|
|
|
+++ b/src/qemu/qemu_domain.c
|
|
|
|
@@ -10881,6 +10881,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_driver.c b/src/qemu/qemu_driver.c
|
|
|
|
index 1d96170..2d24396 100644
|
|
|
|
--- a/src/qemu/qemu_driver.c
|
|
|
|
+++ b/src/qemu/qemu_driver.c
|
|
|
|
@@ -14687,6 +14687,7 @@ qemuDomainSnapshotPrepareDiskExternalInactive(virDomainSnapshotDiskDefPtr snapdi
|
|
|
|
case VIR_STORAGE_NET_PROTOCOL_TFTP:
|
|
|
|
case VIR_STORAGE_NET_PROTOCOL_SSH:
|
|
|
|
case VIR_STORAGE_NET_PROTOCOL_VXHS:
|
|
|
|
+ case VIR_STORAGE_NET_PROTOCOL_VITASTOR:
|
|
|
|
case VIR_STORAGE_NET_PROTOCOL_LAST:
|
|
|
|
virReportError(VIR_ERR_INTERNAL_ERROR,
|
|
|
|
_("external inactive snapshots are not supported on "
|
|
|
|
@@ -14764,6 +14765,7 @@ qemuDomainSnapshotPrepareDiskExternalActive(virDomainSnapshotDiskDefPtr snapdisk
|
|
|
|
case VIR_STORAGE_NET_PROTOCOL_TFTP:
|
|
|
|
case VIR_STORAGE_NET_PROTOCOL_SSH:
|
|
|
|
case VIR_STORAGE_NET_PROTOCOL_VXHS:
|
|
|
|
+ case VIR_STORAGE_NET_PROTOCOL_VITASTOR:
|
|
|
|
case VIR_STORAGE_NET_PROTOCOL_LAST:
|
|
|
|
virReportError(VIR_ERR_INTERNAL_ERROR,
|
|
|
|
_("external active snapshots are not supported on "
|
|
|
|
@@ -14887,6 +14889,7 @@ qemuDomainSnapshotPrepareDiskInternal(virDomainDiskDefPtr disk,
|
|
|
|
case VIR_STORAGE_NET_PROTOCOL_TFTP:
|
|
|
|
case VIR_STORAGE_NET_PROTOCOL_SSH:
|
|
|
|
case VIR_STORAGE_NET_PROTOCOL_VXHS:
|
|
|
|
+ case VIR_STORAGE_NET_PROTOCOL_VITASTOR:
|
|
|
|
case VIR_STORAGE_NET_PROTOCOL_LAST:
|
|
|
|
virReportError(VIR_ERR_INTERNAL_ERROR,
|
|
|
|
_("internal inactive snapshots are not supported on "
|
|
|
|
diff --git a/src/qemu/qemu_parse_command.c b/src/qemu/qemu_parse_command.c
|
|
|
|
index c4650f0..551da41 100644
|
|
|
|
--- a/src/qemu/qemu_parse_command.c
|
|
|
|
+++ b/src/qemu/qemu_parse_command.c
|
|
|
|
@@ -2184,6 +2184,7 @@ qemuParseCommandLine(virFileCachePtr capsCache,
|
|
|
|
case VIR_STORAGE_NET_PROTOCOL_TFTP:
|
|
|
|
case VIR_STORAGE_NET_PROTOCOL_SSH:
|
|
|
|
case VIR_STORAGE_NET_PROTOCOL_LAST:
|
|
|
|
+ case VIR_STORAGE_NET_PROTOCOL_VITASTOR:
|
|
|
|
case VIR_STORAGE_NET_PROTOCOL_NONE:
|
|
|
|
/* ignored for now */
|
|
|
|
break;
|
|
|
|
diff --git a/src/storage/storage_driver.c b/src/storage/storage_driver.c
|
|
|
|
index 4a13e90..33301c7 100644
|
|
|
|
--- a/src/storage/storage_driver.c
|
|
|
|
+++ b/src/storage/storage_driver.c
|
|
|
|
@@ -1568,6 +1568,7 @@ storageVolLookupByPathCallback(virStoragePoolObjPtr obj,
|
|
|
|
case VIR_STORAGE_POOL_RBD:
|
|
|
|
case VIR_STORAGE_POOL_SHEEPDOG:
|
|
|
|
case VIR_STORAGE_POOL_ZFS:
|
|
|
|
+ case VIR_STORAGE_POOL_VITASTOR:
|
|
|
|
case VIR_STORAGE_POOL_LAST:
|
|
|
|
ignore_value(VIR_STRDUP(stable_path, data->path));
|
|
|
|
break;
|
|
|
|
diff --git a/src/util/virstoragefile.c b/src/util/virstoragefile.c
|
|
|
|
index bd4b027..b323cd6 100644
|
|
|
|
--- a/src/util/virstoragefile.c
|
|
|
|
+++ b/src/util/virstoragefile.c
|
|
|
|
@@ -84,7 +84,8 @@ VIR_ENUM_IMPL(virStorageNetProtocol, VIR_STORAGE_NET_PROTOCOL_LAST,
|
|
|
|
"ftps",
|
|
|
|
"tftp",
|
|
|
|
"ssh",
|
|
|
|
- "vxhs")
|
|
|
|
+ "vxhs",
|
|
|
|
+ "vitastor")
|
|
|
|
|
|
|
|
VIR_ENUM_IMPL(virStorageNetHostTransport, VIR_STORAGE_NET_HOST_TRANS_LAST,
|
|
|
|
"tcp",
|
|
|
|
@@ -2839,6 +2840,83 @@ virStorageSourceParseRBDColonString(const char *rbdstr,
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
+static int
|
|
|
|
+virStorageSourceParseVitastorColonString(const char *colonstr,
|
|
|
|
+ virStorageSourcePtr src)
|
|
|
|
+{
|
|
|
|
+ char *p, *e, *next;
|
|
|
|
+ char *options = NULL;
|
|
|
|
+
|
|
|
|
+ /* optionally skip the "vitastor:" prefix if provided */
|
|
|
|
+ if (STRPREFIX(colonstr, "vitastor:"))
|
|
|
|
+ colonstr += strlen("vitastor:");
|
|
|
|
+
|
|
|
|
+ if (VIR_STRDUP(options, colonstr) < 0)
|
|
|
|
+ return -1;
|
|
|
|
+
|
|
|
|
+ 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=")) {
|
|
|
|
+ if (VIR_STRDUP(src->path, p + strlen("image=")) < 0)
|
|
|
|
+ return -1;
|
2021-11-21 16:16:46 +03:00
|
|
|
+ } else if (STRPREFIX(p, "etcd-prefix=")) {
|
|
|
|
+ if (VIR_STRDUP(src->relPath, p + strlen("etcd-prefix=")) < 0)
|
2021-06-27 18:43:29 +03:00
|
|
|
+ return -1;
|
2021-11-21 16:16:46 +03:00
|
|
|
+ } else if (STRPREFIX(p, "config-path=")) {
|
|
|
|
+ if (VIR_STRDUP(src->configFile, p + strlen("config-path=")) < 0)
|
2021-06-27 18:43:29 +03:00
|
|
|
+ return -1;
|
2021-11-21 16:16:46 +03:00
|
|
|
+ } else if (STRPREFIX(p, "etcd-host=")) {
|
2021-06-27 18:43:29 +03:00
|
|
|
+ char *h, *sep;
|
|
|
|
+
|
2021-11-21 16:16:46 +03:00
|
|
|
+ h = p + strlen("etcd-host=");
|
2021-06-27 18:43:29 +03:00
|
|
|
+ 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)
|
|
|
|
+ goto error;
|
|
|
|
+
|
|
|
|
+ h = sep;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ p = next;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if (!src->path) {
|
|
|
|
+ goto error;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ return 0;
|
|
|
|
+
|
|
|
|
+error:
|
|
|
|
+ VIR_FREE(options);
|
|
|
|
+ return -1;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+
|
|
|
|
static int
|
|
|
|
virStorageSourceParseNBDColonString(const char *nbdstr,
|
|
|
|
virStorageSourcePtr src)
|
|
|
|
@@ -2942,6 +3020,11 @@ virStorageSourceParseBackingColon(virStorageSourcePtr src,
|
|
|
|
goto cleanup;
|
|
|
|
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:
|
|
|
|
@@ -3441,6 +3524,56 @@ virStorageSourceParseBackingJSONRBD(virStorageSourcePtr src,
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
+static int
|
|
|
|
+virStorageSourceParseBackingJSONVitastor(virStorageSourcePtr src,
|
|
|
|
+ virJSONValuePtr json,
|
|
|
|
+ int opaque ATTRIBUTE_UNUSED)
|
|
|
|
+{
|
|
|
|
+ const char *filename;
|
|
|
|
+ const char *image = virJSONValueObjectGetString(json, "image");
|
2021-11-21 16:16:46 +03:00
|
|
|
+ const char *conf = virJSONValueObjectGetString(json, "config-path");
|
|
|
|
+ const char *etcd_prefix = virJSONValueObjectGetString(json, "etcd-prefix");
|
2021-06-27 18:43:29 +03:00
|
|
|
+ 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;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if (VIR_STRDUP(src->path, image) < 0 ||
|
|
|
|
+ VIR_STRDUP(src->configFile, conf) < 0 ||
|
|
|
|
+ VIR_STRDUP(src->relPath, etcd_prefix) < 0)
|
|
|
|
+ return -1;
|
|
|
|
+
|
|
|
|
+ if (servers) {
|
|
|
|
+ nservers = virJSONValueArraySize(servers);
|
|
|
|
+
|
|
|
|
+ if (VIR_ALLOC_N(src->hosts, nservers) < 0)
|
|
|
|
+ return -1;
|
|
|
|
+
|
|
|
|
+ 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,
|
|
|
|
@@ -3507,6 +3640,7 @@ static const struct virStorageSourceJSONDriverParser jsonParsers[] = {
|
|
|
|
{"sheepdog", virStorageSourceParseBackingJSONSheepdog, 0},
|
|
|
|
{"ssh", virStorageSourceParseBackingJSONSSH, 0},
|
|
|
|
{"rbd", virStorageSourceParseBackingJSONRBD, 0},
|
|
|
|
+ {"vitastor", virStorageSourceParseBackingJSONVitastor, 0},
|
|
|
|
{"raw", virStorageSourceParseBackingJSONRaw, 0},
|
|
|
|
{"vxhs", virStorageSourceParseBackingJSONVxHS, 0},
|
|
|
|
};
|
|
|
|
@@ -4276,6 +4410,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 1d6161a..8d83bf3 100644
|
|
|
|
--- a/src/util/virstoragefile.h
|
|
|
|
+++ b/src/util/virstoragefile.h
|
|
|
|
@@ -134,6 +134,7 @@ typedef enum {
|
|
|
|
VIR_STORAGE_NET_PROTOCOL_TFTP,
|
|
|
|
VIR_STORAGE_NET_PROTOCOL_SSH,
|
|
|
|
VIR_STORAGE_NET_PROTOCOL_VXHS,
|
|
|
|
+ VIR_STORAGE_NET_PROTOCOL_VITASTOR,
|
|
|
|
|
|
|
|
VIR_STORAGE_NET_PROTOCOL_LAST
|
|
|
|
} virStorageNetProtocol;
|
|
|
|
diff --git a/src/xenconfig/xen_xl.c b/src/xenconfig/xen_xl.c
|
|
|
|
index accfc3a..a18f9c3 100644
|
|
|
|
--- a/src/xenconfig/xen_xl.c
|
|
|
|
+++ b/src/xenconfig/xen_xl.c
|
|
|
|
@@ -1535,6 +1535,7 @@ xenFormatXLDiskSrcNet(virStorageSourcePtr src)
|
|
|
|
case VIR_STORAGE_NET_PROTOCOL_SHEEPDOG:
|
|
|
|
case VIR_STORAGE_NET_PROTOCOL_SSH:
|
|
|
|
case VIR_STORAGE_NET_PROTOCOL_VXHS:
|
|
|
|
+ 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/tools/virsh-pool.c b/tools/virsh-pool.c
|
|
|
|
index 70ca39b..9caef51 100644
|
|
|
|
--- a/tools/virsh-pool.c
|
|
|
|
+++ b/tools/virsh-pool.c
|
|
|
|
@@ -1219,6 +1219,9 @@ cmdPoolList(vshControl *ctl, const vshCmd *cmd ATTRIBUTE_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;
|
|
|
|
}
|