From 590c157c3242d7e199a95eb1e46df1f0b96b7c60 Mon Sep 17 00:00:00 2001 From: huynnp911 Date: Mon, 23 May 2022 16:51:00 +0700 Subject: [PATCH] Add qemu and libvirt patch for ubuntu 20 --- patches/libvirt-6.0.0-vitastor.diff | 659 ++++++++++++++++++++++++++++ patches/qemu-4.2.0-vitastor.patch | 203 +++++++++ 2 files changed, 862 insertions(+) create mode 100644 patches/libvirt-6.0.0-vitastor.diff create mode 100644 patches/qemu-4.2.0-vitastor.patch diff --git a/patches/libvirt-6.0.0-vitastor.diff b/patches/libvirt-6.0.0-vitastor.diff new file mode 100644 index 00000000..2c3d3c15 --- /dev/null +++ b/patches/libvirt-6.0.0-vitastor.diff @@ -0,0 +1,659 @@ +commit 7f01510ef207940b07fac4f5fc8b9f1580b443aa +Author: Vitaliy Filippov +Date: Sun Jun 27 12:52:40 2021 +0300 + + Add Vitastor support + +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 +@@ -1766,6 +1766,35 @@ + + + ++ ++ ++ ++ ++ vitastor ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ + + + +@@ -1891,6 +1920,7 @@ + + + ++ + + + +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 +@@ -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 222bb8c..2c30c55 100644 +--- a/src/conf/domain_conf.c ++++ b/src/conf/domain_conf.c +@@ -5114,8 +5114,7 @@ virDomainDiskDefPostParse(virDomainDiskD + 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) { +@@ -5124,11 +5123,15 @@ virDomainDiskDefPostParse(virDomainDiskD + "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", + _(" element is currently supported " +- "only with 'rbd' disks")); ++ "only with 'rbd' and 'vitastor' disks")); + return -1; + } + } +@@ -9258,6 +9261,10 @@ virDomainDiskSourceNetworkParse(xmlNodeP + return -1; + } + ++ 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, +@@ -9303,6 +9310,10 @@ virDomainDiskSourceNetworkParse(xmlNodeP + /* config file currently only works with remote disks */ + src->configFile = virXPathString("string(./config/@file)", ctxt); + ++ if (src->protocol == VIR_STORAGE_NET_PROTOCOL_HTTP || ++ src->protocol == VIR_STORAGE_NET_PROTOCOL_HTTPS) ++ src->query = virXMLPropString(node, "query"); ++ + if (virDomainStorageNetworkParseHosts(node, &src->hosts, &src->nhosts) < 0) + return -1; + +@@ -24141,6 +24152,10 @@ virDomainDiskSourceFormatNetwork(virBuff + + 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); ++ } ++ + if (src->haveTLS != VIR_TRISTATE_BOOL_ABSENT && + !(flags & VIR_DOMAIN_DEF_FORMAT_MIGRATABLE && + src->tlsFromConfig)) +@@ -31402,6 +31417,7 @@ virDomainDiskTranslateSourcePool(virDomainDiskDefPtr def) + + 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 +@@ -59,7 +59,7 @@ VIR_ENUM_IMPL(virStoragePool, + "logical", "disk", "iscsi", + "iscsi-direct", "scsi", "mpath", + "rbd", "sheepdog", "gluster", +- "zfs", "vstorage", ++ "zfs", "vstorage", "vitastor", + ); + + VIR_ENUM_IMPL(virStoragePoolFormatFileSystem, +@@ -248,6 +248,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 | +@@ -550,6 +562,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); +@@ -1173,6 +1190,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 +@@ -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; +@@ -466,6 +467,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 +@@ -1493,6 +1493,7 @@ virStoragePoolObjSourceFindDuplicateCb(const void *payload, + return 1; + break; + ++ case VIR_STORAGE_POOL_VITASTOR: + case VIR_STORAGE_POOL_RBD: + case VIR_STORAGE_POOL_LAST: + break; +@@ -1994,6 +1995,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 +@@ -888,6 +888,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/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_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 +index cbf0aa4..f0ca9e7 100644 +--- a/src/qemu/qemu_block.c ++++ b/src/qemu/qemu_block.c +@@ -869,6 +869,42 @@ qemuBlockStorageSourceGetRBDProps(virStorageSourcePtr src) + } + + ++static virJSONValuePtr ++qemuBlockStorageSourceGetVitastorProps(virStorageSource *src) ++{ ++ virJSONValuePtr ret = NULL; ++ virStorageNetHostDefPtr host; ++ size_t i; ++ virBuffer buf = VIR_BUFFER_INITIALIZER; ++ char *etcd = NULL; ++ ++ 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); ++ } ++ ++ if (virJSONValueObjectCreate(&ret, ++ "s:driver", "vitastor", ++ "S:etcd-host", etcd, ++ "S:etcd-prefix", src->relPath, ++ "S:config-path", src->configFile, ++ "s:image", src->path, ++ NULL) < 0) ++ goto cleanup; ++ ++cleanup: ++ VIR_FREE(etcd); ++ virBufferFreeAndReset(&buf); ++ return ret; ++} ++ ++ + static virJSONValuePtr + qemuBlockStorageSourceGetSheepdogProps(virStorageSourcePtr src) + { +@@ -1130,6 +1166,11 @@ qemuBlockStorageSourceGetBackendProps(virStorageSourcePtr src, + 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..abec34e 100644 +--- a/src/qemu/qemu_command.c ++++ b/src/qemu/qemu_command.c +@@ -1078,6 +1078,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->relPath) ++ virBufferEscape(&buf, '\\', ":", ":etcd-prefix=%s", src->relPath); ++ ++ 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 +@@ -6862,6 +6862,16 @@ qemuDomainValidateStorageSource(virStora + return -1; + } + ++ 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_VITASTOR))) { ++ virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", ++ _("query is supported only with HTTP(S) protocols")); ++ return -1; ++ } ++ + return 0; + } + +@@ -13836,6 +13846,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 +@@ -14841,6 +14841,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 " +@@ -14925,6 +14926,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 " +@@ -15054,6 +15056,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/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 +@@ -1641,6 +1641,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/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 +@@ -7086,6 +7086,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 +@@ -90,6 +90,7 @@ VIR_ENUM_IMPL(virStorageNetProtocol, + "tftp", + "ssh", + "vxhs", ++ "vitastor", + ); + + VIR_ENUM_IMPL(virStorageNetHostTransport, +@@ -2927,6 +2928,73 @@ virStorageSourceParseRBDColonString(cons + return 0; + } + ++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, +@@ -3022,6 +3090,11 @@ virStorageSourceParseBackingColon(virSto + 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: +@@ -3507,6 +3580,54 @@ virStorageSourceParseBackingJSONRBD(virS + } + + 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, + int opaque G_GNUC_UNUSED) +@@ -3578,6 +3699,7 @@ static const struct virStorageSourceJSON + {"sheepdog", virStorageSourceParseBackingJSONSheepdog, 0}, + {"ssh", virStorageSourceParseBackingJSONSSH, 0}, + {"rbd", virStorageSourceParseBackingJSONRBD, 0}, ++ {"vitastor", virStorageSourceParseBackingJSONVitastor, 0}, + {"raw", virStorageSourceParseBackingJSONRaw, 0}, + {"vxhs", virStorageSourceParseBackingJSONVxHS, 0}, + }; +@@ -4364,6 +4486,7 @@ virStorageSourceNetworkDefaultPort(virSt + 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; +@@ -265,6 +266,7 @@ struct _virStorageSource { + char *snapshot; /* for storage systems supporting internal snapshots */ + char *configFile; /* some storage systems use config file as part of + the source definition */ ++ char *query; /* query string for HTTP based protocols */ + size_t nhosts; + virStorageNetHostDefPtr hosts; + virStorageSourcePoolDefPtr srcpool; +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; + } diff --git a/patches/qemu-4.2.0-vitastor.patch b/patches/qemu-4.2.0-vitastor.patch new file mode 100644 index 00000000..1bf7d44f --- /dev/null +++ b/patches/qemu-4.2.0-vitastor.patch @@ -0,0 +1,203 @@ +diff -NaurpbB qemu-4.2/block/Makefile.objs qemu-4.2/block/Makefile.objs +--- qemu-4.2/block/Makefile.objs 2019-12-13 01:20:47.000000000 +0700 ++++ qemu-4.2/block/Makefile.objs 2022-05-19 09:05:29.047996624 +0700 +@@ -29,6 +29,7 @@ block-obj-$(if $(CONFIG_LIBISCSI),y,n) + + block-obj-$(CONFIG_LIBNFS) += nfs.o + block-obj-$(CONFIG_CURL) += curl.o + block-obj-$(CONFIG_RBD) += rbd.o ++block-obj-$(CONFIG_VITASTOR) += vitastor.o + block-obj-$(CONFIG_GLUSTERFS) += gluster.o + block-obj-$(CONFIG_VXHS) += vxhs.o + block-obj-$(CONFIG_LIBSSH) += ssh.o +@@ -53,6 +54,8 @@ curl.o-cflags := $(CURL_CFLAGS) + curl.o-libs := $(CURL_LIBS) + rbd.o-cflags := $(RBD_CFLAGS) + rbd.o-libs := $(RBD_LIBS) ++vitastor.o-cflags := $(VITASTOR_CFLAGS) ++vitastor.o-libs := $(VITASTOR_LIBS) + gluster.o-cflags := $(GLUSTERFS_CFLAGS) + gluster.o-libs := $(GLUSTERFS_LIBS) + vxhs.o-libs := $(VXHS_LIBS +diff -NaurpbB qemu-4.2/configure qemu-4.2/configure +--- qemu-4.2/configure 2022-05-19 08:32:27.000000000 +0700 ++++ qemu-4.2/configure 2022-05-19 08:52:16.844594720 +0700 +@@ -436,6 +436,7 @@ trace_backends="log" + trace_file="trace" + spice="" + rbd="" ++vitastor="yes" + smartcard="" + libusb="" + usb_redir="" +@@ -1317,6 +1318,10 @@ for opt do + ;; + --enable-rbd) rbd="yes" + ;; ++ --disable-vitastor) vitastor="no" ++ ;; ++ --enable-vitastor) vitastor="yes" ++ ;; + --disable-xfsctl) xfs="no" + ;; + --enable-xfsctl) xfs="yes" +@@ -1813,6 +1818,7 @@ disabled with --disable-FEATURE, default + vhost-user vhost-user backend support + spice spice + rbd rados block device (rbd) ++ vitastor vitastor block device + libiscsi iscsi support + libnfs nfs support + smartcard smartcard support (libcacard) +@@ -4015,6 +4021,27 @@ EOF + fi + fi + ++######################################### ++# vitastor probe ++if test "$vitastor" != "no" ; then ++ cat > $TMPC < ++int main(void) { ++ vitastor_c_create_qemu(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0); ++ return 0; ++} ++EOF ++ vitastor_libs="-lvitastor_client" ++ if compile_prog "" "$vitastor_libs" ; then ++ vitastor=yes ++ else ++ if test "$vitastor" = "yes" ; then ++ feature_not_found "vitastor block device" "Install vitastor-client-dev" ++ fi ++ vitastor=no ++ fi ++fi ++ + ########################################## + # libssh probe + if test "$libssh" != "no" ; then +@@ -6586,6 +6613,7 @@ echo "Trace output file $trace_file-> $config_host_mak + echo "RBD_LIBS=$rbd_libs" >> $config_host_mak + fi ++if test "$vitastor" = "yes" ; then ++ echo "CONFIG_VITASTOR=m" >> $config_host_mak ++ echo "VITASTOR_CFLAGS=$vitastor_cflags" >> $config_host_mak ++ echo "VITASTOR_LIBS=$vitastor_libs" >> $config_host_mak ++fi + + echo "CONFIG_COROUTINE_BACKEND=$coroutine" >> $config_host_mak + if test "$coroutine_pool" = "yes" ; then +diff -NaurpbB qemu-4.2/qapi/block-core.json qemu-4.2/qapi/block-core.json +--- qemu-4.2/qapi/block-core.json 2022-05-19 08:32:27.000000000 +0700 ++++ qemu-4.2/qapi/block-core.json 2022-05-19 09:14:38.869133795 +0700 +@@ -2894,7 +2894,7 @@ + 'nbd', 'nfs', 'null-aio', 'null-co', 'nvme', 'parallels', 'qcow', + 'qcow2', 'qed', 'quorum', 'raw', 'rbd', + { 'name': 'replication', 'if': 'defined(CONFIG_REPLICATION)' }, +- 'sheepdog', ++ 'sheepdog', 'vitastor', + 'ssh', 'throttle', 'vdi', 'vhdx', 'vmdk', 'vpc', 'vvfat', 'vxhs' ] } + + ## +@@ -3728,6 +3728,28 @@ + '*tag': 'str' } } + + ## ++# @BlockdevOptionsVitastor: ++# ++# Driver specific block device options for vitastor ++# ++# @image: Image name ++# @inode: Inode number ++# @pool: Pool ID ++# @size: Desired image size in bytes ++# @config-path: Path to Vitastor configuration ++# @etcd-host: etcd connection address(es) ++# @etcd-prefix: etcd key/value prefix ++## ++{ 'struct': 'BlockdevOptionsVitastor', ++ 'data': { '*inode': 'uint64', ++ '*pool': 'uint64', ++ '*size': 'uint64', ++ '*image': 'str', ++ '*config-path': 'str', ++ '*etcd-host': 'str', ++ '*etcd-prefix': 'str' } } ++ ++## + # @ReplicationMode: + # + # An enumeration of replication modes. +@@ -4087,6 +4109,7 @@ + 'replication': { 'type': 'BlockdevOptionsReplication', + 'if': 'defined(CONFIG_REPLICATION)' }, + 'sheepdog': 'BlockdevOptionsSheepdog', ++ 'vitastor': 'BlockdevOptionsVitastor', + 'ssh': 'BlockdevOptionsSsh', + 'throttle': 'BlockdevOptionsThrottle', + 'vdi': 'BlockdevOptionsGenericFormat', +@@ -4457,6 +4480,17 @@ + '*cluster-size' : 'size' } } + + ## ++# @BlockdevCreateOptionsVitastor: ++# ++# Driver specific image creation options for Vitastor. ++# ++# @size: Size of the virtual disk in bytes ++## ++{ 'struct': 'BlockdevCreateOptionsVitastor', ++ 'data': { 'location': 'BlockdevOptionsVitastor', ++ 'size': 'size' } } ++ ++## + # @BlockdevVmdkSubformat: + # + # Subformat options for VMDK images +@@ -4718,6 +4752,7 @@ + 'qed': 'BlockdevCreateOptionsQed', + 'rbd': 'BlockdevCreateOptionsRbd', + 'sheepdog': 'BlockdevCreateOptionsSheepdog', ++ 'vitastor': 'BlockdevCreateOptionsVitastor', + 'ssh': 'BlockdevCreateOptionsSsh', + 'vdi': 'BlockdevCreateOptionsVdi', + 'vhdx': 'BlockdevCreateOptionsVhdx', +diff -NaurpbB qemu-4.2/debian/rules qemu-4.2/debian/rules +--- qemu-4.2/debian/rules 2022-05-19 15:34:26.354263017 +0700 ++++ qemu-4.2/debian/rules 2022-05-19 15:32:15.720952678 +0700 +@@ -148,7 +148,7 @@ ifneq ($(filter $(DEB_HOST_ARCH),amd64 i + --${enable_system}-system \ + --disable-linux-user \ + --enable-xen \ +- --target-list="aarch64-softmmu arm-softmmu i386-softmmu x86_64-softmmu" ++ --target-list="aarch64-softmmu arm-softmmu i386-softmmu x86_64-softmmu" \ + --enable-modules \ + --enable-module-upgrades \ + $(shell sh debian/extract-config-opts \ +@@ -167,7 +167,7 @@ ifneq ($(filter $(DEB_HOST_ARCH),amd64), + cd b/qemu-microvm && \ + ../../configure ${common_configure_opts} --disable-user \ + --enable-system --enable-kvm \ +- --disable-linux-user --disable-modules --disable-docs \ ++ --disable-linux-user --enable-modules --disable-docs \ + --disable-libssh --disable-tcmalloc --disable-glusterfs \ + --disable-seccomp --disable-bzip2 --disable-slirp --disable-vde \ + --disable-netmap --disable-hax --disable-hvf --disable-whpx \ +@@ -201,7 +201,7 @@ ifeq ($(enable_linux_user),enable) + rm -rf b/user-static; mkdir b/user-static + cd b/user-static && \ + ../../configure ${common_configure_opts} \ +- --static --disable-system --disable-xen \ ++ --enable-modules --enable-module-upgrades --disable-system --disable-xen \ + --target-list="$(addsuffix -linux-user,${user_targets})" + endif + touch $@ \ No newline at end of file -- 2.30.2