The code handles XML bits and internal definition and should be in conf directory. Signed-off-by: Pavel Hrdina <phrdina@xxxxxxxxxx> --- po/POTFILES.in | 1 + src/conf/backup_conf.c | 2 +- src/conf/checkpoint_conf.c | 2 +- src/conf/domain_conf.c | 2 +- src/conf/domain_conf.h | 4 +- src/conf/meson.build | 1 + src/conf/snapshot_conf.c | 2 +- src/conf/storage_conf.c | 2 +- src/conf/storage_conf.h | 2 +- src/conf/storage_source_conf.c | 1350 +++++++++++++++++++++++ src/conf/storage_source_conf.h | 537 +++++++++ src/esx/esx_storage_backend_iscsi.c | 2 +- src/esx/esx_storage_backend_vmfs.c | 2 +- src/libvirt_private.syms | 101 +- src/qemu/qemu_backup.c | 2 +- src/qemu/qemu_blockjob.c | 2 +- src/qemu/qemu_command.c | 2 +- src/qemu/qemu_driver.c | 1 + src/qemu/qemu_hotplug.c | 2 +- src/qemu/qemu_migration.c | 2 +- src/storage/storage_backend.c | 2 +- src/storage/storage_util.c | 1 + src/storage_file/meson.build | 3 + src/storage_file/storage_file_backend.h | 2 +- src/storage_file/storage_file_probe.c | 2 +- src/storage_file/storage_file_probe.h | 2 +- src/storage_file/storage_source.h | 2 +- src/util/virstoragefile.c | 1308 +--------------------- src/util/virstoragefile.h | 456 +------- 29 files changed, 1968 insertions(+), 1831 deletions(-) create mode 100644 src/conf/storage_source_conf.c create mode 100644 src/conf/storage_source_conf.h diff --git a/po/POTFILES.in b/po/POTFILES.in index eeff3f9f2f..00100d7d73 100644 --- a/po/POTFILES.in +++ b/po/POTFILES.in @@ -43,6 +43,7 @@ @SRCDIR@src/conf/snapshot_conf.c @SRCDIR@src/conf/storage_adapter_conf.c @SRCDIR@src/conf/storage_conf.c +@SRCDIR@src/conf/storage_source_conf.c @SRCDIR@src/conf/virchrdev.c @SRCDIR@src/conf/virdomainmomentobjlist.c @SRCDIR@src/conf/virdomainobjlist.c diff --git a/src/conf/backup_conf.c b/src/conf/backup_conf.c index 90ffcc51d1..ba58b2e322 100644 --- a/src/conf/backup_conf.c +++ b/src/conf/backup_conf.c @@ -26,7 +26,7 @@ #include "virlog.h" #include "viralloc.h" #include "backup_conf.h" -#include "virstoragefile.h" +#include "storage_source_conf.h" #include "virfile.h" #include "virerror.h" #include "virxml.h" diff --git a/src/conf/checkpoint_conf.c b/src/conf/checkpoint_conf.c index 7edc7daa12..16fb138a3e 100644 --- a/src/conf/checkpoint_conf.c +++ b/src/conf/checkpoint_conf.c @@ -30,7 +30,7 @@ #include "virlog.h" #include "viralloc.h" #include "checkpoint_conf.h" -#include "virstoragefile.h" +#include "storage_source_conf.h" #include "viruuid.h" #include "virfile.h" #include "virerror.h" diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c index fcf332fe44..dab4f10326 100644 --- a/src/conf/domain_conf.c +++ b/src/conf/domain_conf.c @@ -43,7 +43,7 @@ #include "nwfilter_conf.h" #include "virnetworkportdef.h" #include "storage_conf.h" -#include "virstoragefile.h" +#include "storage_source_conf.h" #include "virfile.h" #include "virbitmap.h" #include "secret_conf.h" diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h index d514f6360f..f5d346ddf0 100644 --- a/src/conf/domain_conf.h +++ b/src/conf/domain_conf.h @@ -48,7 +48,7 @@ #include "virobject.h" #include "device_conf.h" #include "virbitmap.h" -#include "virstoragefile.h" +#include "storage_source_conf.h" #include "virseclabel.h" #include "virprocess.h" #include "virgic.h" @@ -359,7 +359,7 @@ struct _virDomainHostdevDef { /* Types of disk frontend (guest view). For backends (host view), see - * virStorageType in util/virstoragefile.h */ + * virStorageType in conf/storage_source_conf.h */ typedef enum { VIR_DOMAIN_DISK_DEVICE_DISK, VIR_DOMAIN_DISK_DEVICE_CDROM, diff --git a/src/conf/meson.build b/src/conf/meson.build index 8ddcc9968d..9d4831b815 100644 --- a/src/conf/meson.build +++ b/src/conf/meson.build @@ -54,6 +54,7 @@ storage_conf_sources = [ 'storage_adapter_conf.c', 'storage_capabilities.c', 'storage_conf.c', + 'storage_source_conf.c', 'virstorageobj.c', ] diff --git a/src/conf/snapshot_conf.c b/src/conf/snapshot_conf.c index 673282be7a..0b78699589 100644 --- a/src/conf/snapshot_conf.c +++ b/src/conf/snapshot_conf.c @@ -38,7 +38,7 @@ #include "nwfilter_conf.h" #include "secret_conf.h" #include "snapshot_conf.h" -#include "virstoragefile.h" +#include "storage_source_conf.h" #include "viruuid.h" #include "virfile.h" #include "virerror.h" diff --git a/src/conf/storage_conf.c b/src/conf/storage_conf.c index 0c50529ace..9aed602fd6 100644 --- a/src/conf/storage_conf.c +++ b/src/conf/storage_conf.c @@ -31,7 +31,7 @@ #include "node_device_conf.h" #include "storage_adapter_conf.h" #include "storage_conf.h" -#include "virstoragefile.h" +#include "storage_source_conf.h" #include "virxml.h" #include "viruuid.h" diff --git a/src/conf/storage_conf.h b/src/conf/storage_conf.h index ffd406e093..aeda2891d4 100644 --- a/src/conf/storage_conf.h +++ b/src/conf/storage_conf.h @@ -23,7 +23,7 @@ #include "internal.h" #include "virstorageencryption.h" -#include "virstoragefile.h" +#include "storage_source_conf.h" #include "virbitmap.h" #include "virthread.h" #include "device_conf.h" diff --git a/src/conf/storage_source_conf.c b/src/conf/storage_source_conf.c new file mode 100644 index 0000000000..dab5e855f5 --- /dev/null +++ b/src/conf/storage_source_conf.c @@ -0,0 +1,1350 @@ +/* + * storage_source_conf.c: file utility functions for FS storage backend + * + * Copyright (C) 2007-2017 Red Hat, Inc. + * Copyright (C) 2007-2008 Daniel P. Berrange + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. If not, see + * <http://www.gnu.org/licenses/>. + */ + +#include <config.h> + +#include "storage_source_conf.h" + +#include "viralloc.h" +#include "virbuffer.h" +#include "virerror.h" +#include "virlog.h" +#include "virstring.h" + +#define VIR_FROM_THIS VIR_FROM_STORAGE + +VIR_LOG_INIT("conf.storage_source_conf"); + + +static virClassPtr virStorageSourceClass; + + +VIR_ENUM_IMPL(virStorage, + VIR_STORAGE_TYPE_LAST, + "none", + "file", + "block", + "dir", + "network", + "volume", + "nvme", +); + + +VIR_ENUM_IMPL(virStorageFileFormat, + VIR_STORAGE_FILE_LAST, + "none", + "raw", "dir", "bochs", + "cloop", "dmg", "iso", + "vpc", "vdi", + /* Not direct file formats, but used for various drivers */ + "fat", "vhd", "ploop", + /* Formats with backing file below here */ + "cow", "qcow", "qcow2", "qed", "vmdk", +); + + +VIR_ENUM_IMPL(virStorageFileFeature, + VIR_STORAGE_FILE_FEATURE_LAST, + "lazy_refcounts", +); + + +VIR_ENUM_IMPL(virStorageNetProtocol, + VIR_STORAGE_NET_PROTOCOL_LAST, + "none", + "nbd", + "rbd", + "sheepdog", + "gluster", + "iscsi", + "http", + "https", + "ftp", + "ftps", + "tftp", + "ssh", + "vxhs", + "nfs", +); + + +VIR_ENUM_IMPL(virStorageNetHostTransport, + VIR_STORAGE_NET_HOST_TRANS_LAST, + "tcp", + "unix", + "rdma", +); + + +VIR_ENUM_IMPL(virStorageSourcePoolMode, + VIR_STORAGE_SOURCE_POOL_MODE_LAST, + "default", + "host", + "direct", +); + + +VIR_ENUM_IMPL(virStorageAuth, + VIR_STORAGE_AUTH_TYPE_LAST, + "none", "chap", "ceph", +); + + +/** + * virStorageSourceIsBacking: + * @src: storage source + * + * Returns true if @src is a eligible backing store structure. Useful + * for iterators. + */ +bool +virStorageSourceIsBacking(const virStorageSource *src) +{ + return src && src->type != VIR_STORAGE_TYPE_NONE; +} + +/** + * virStorageSourceHasBacking: + * @src: storage source + * + * Returns true if @src has backing store/chain. + */ +bool +virStorageSourceHasBacking(const virStorageSource *src) +{ + return virStorageSourceIsBacking(src) && src->backingStore && + src->backingStore->type != VIR_STORAGE_TYPE_NONE; +} + + +void +virStorageNetHostDefClear(virStorageNetHostDefPtr def) +{ + if (!def) + return; + + VIR_FREE(def->name); + VIR_FREE(def->socket); +} + + +void +virStorageNetHostDefFree(size_t nhosts, + virStorageNetHostDefPtr hosts) +{ + size_t i; + + if (!hosts) + return; + + for (i = 0; i < nhosts; i++) + virStorageNetHostDefClear(&hosts[i]); + + VIR_FREE(hosts); +} + + +static void +virStoragePermsFree(virStoragePermsPtr def) +{ + if (!def) + return; + + VIR_FREE(def->label); + VIR_FREE(def); +} + + +virStorageNetHostDefPtr +virStorageNetHostDefCopy(size_t nhosts, + virStorageNetHostDefPtr hosts) +{ + virStorageNetHostDefPtr ret = NULL; + size_t i; + + ret = g_new0(virStorageNetHostDef, nhosts); + + for (i = 0; i < nhosts; i++) { + virStorageNetHostDefPtr src = &hosts[i]; + virStorageNetHostDefPtr dst = &ret[i]; + + dst->transport = src->transport; + dst->port = src->port; + + dst->name = g_strdup(src->name); + dst->socket = g_strdup(src->socket); + } + + return ret; +} + + +void +virStorageAuthDefFree(virStorageAuthDefPtr authdef) +{ + if (!authdef) + return; + + VIR_FREE(authdef->username); + VIR_FREE(authdef->secrettype); + virSecretLookupDefClear(&authdef->seclookupdef); + VIR_FREE(authdef); +} + + +virStorageAuthDefPtr +virStorageAuthDefCopy(const virStorageAuthDef *src) +{ + g_autoptr(virStorageAuthDef) authdef = NULL; + + authdef = g_new0(virStorageAuthDef, 1); + + authdef->username = g_strdup(src->username); + /* Not present for storage pool, but used for disk source */ + authdef->secrettype = g_strdup(src->secrettype); + authdef->authType = src->authType; + + virSecretLookupDefCopy(&authdef->seclookupdef, &src->seclookupdef); + + return g_steal_pointer(&authdef); +} + + +virStorageAuthDefPtr +virStorageAuthDefParse(xmlNodePtr node, + xmlXPathContextPtr ctxt) +{ + VIR_XPATH_NODE_AUTORESTORE(ctxt) + virStorageAuthDefPtr ret = NULL; + xmlNodePtr secretnode = NULL; + g_autoptr(virStorageAuthDef) authdef = NULL; + g_autofree char *authtype = NULL; + + ctxt->node = node; + + authdef = g_new0(virStorageAuthDef, 1); + + if (!(authdef->username = virXPathString("string(./@username)", ctxt))) { + virReportError(VIR_ERR_XML_ERROR, "%s", + _("missing username for auth")); + goto cleanup; + } + + authdef->authType = VIR_STORAGE_AUTH_TYPE_NONE; + authtype = virXPathString("string(./@type)", ctxt); + if (authtype) { + /* Used by the storage pool instead of the secret type field + * to define whether chap or ceph being used + */ + if ((authdef->authType = virStorageAuthTypeFromString(authtype)) < 0) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, + _("unknown auth type '%s'"), authtype); + goto cleanup; + } + } + + if (!(secretnode = virXPathNode("./secret ", ctxt))) { + virReportError(VIR_ERR_XML_ERROR, "%s", + _("Missing <secret> element in auth")); + goto cleanup; + } + + /* Used by the domain disk xml parsing in order to ensure the + * <secret type='%s' value matches the expected secret type for + * the style of disk (iscsi is chap, nbd is ceph). For some reason + * the virSecretUsageType{From|To}String() cannot be linked here + * and because only the domain parsing code cares - just keep + * it as a string. + */ + authdef->secrettype = virXMLPropString(secretnode, "type"); + + if (virSecretLookupParseSecret(secretnode, &authdef->seclookupdef) < 0) + goto cleanup; + + ret = g_steal_pointer(&authdef); + + cleanup: + + return ret; +} + + +void +virStorageAuthDefFormat(virBufferPtr buf, + virStorageAuthDefPtr authdef) +{ + if (authdef->authType == VIR_STORAGE_AUTH_TYPE_NONE) { + virBufferEscapeString(buf, "<auth username='%s'>\n", authdef->username); + } else { + virBufferAsprintf(buf, "<auth type='%s' ", + virStorageAuthTypeToString(authdef->authType)); + virBufferEscapeString(buf, "username='%s'>\n", authdef->username); + } + + virBufferAdjustIndent(buf, 2); + virSecretLookupFormatSecret(buf, authdef->secrettype, + &authdef->seclookupdef); + virBufferAdjustIndent(buf, -2); + virBufferAddLit(buf, "</auth>\n"); +} + + +void +virStoragePRDefFree(virStoragePRDefPtr prd) +{ + if (!prd) + return; + + VIR_FREE(prd->path); + VIR_FREE(prd->mgralias); + VIR_FREE(prd); +} + + +virStoragePRDefPtr +virStoragePRDefParseXML(xmlXPathContextPtr ctxt) +{ + virStoragePRDefPtr prd; + virStoragePRDefPtr ret = NULL; + g_autofree char *managed = NULL; + g_autofree char *type = NULL; + g_autofree char *path = NULL; + g_autofree char *mode = NULL; + + prd = g_new0(virStoragePRDef, 1); + + if (!(managed = virXPathString("string(./@managed)", ctxt))) { + virReportError(VIR_ERR_XML_ERROR, "%s", + _("missing @managed attribute for <reservations/>")); + goto cleanup; + } + + if ((prd->managed = virTristateBoolTypeFromString(managed)) <= 0) { + virReportError(VIR_ERR_XML_ERROR, + _("invalid value for 'managed': %s"), managed); + goto cleanup; + } + + type = virXPathString("string(./source[1]/@type)", ctxt); + path = virXPathString("string(./source[1]/@path)", ctxt); + mode = virXPathString("string(./source[1]/@mode)", ctxt); + + if (prd->managed == VIR_TRISTATE_BOOL_NO || type || path || mode) { + if (!type) { + virReportError(VIR_ERR_XML_ERROR, "%s", + _("missing connection type for <reservations/>")); + goto cleanup; + } + + if (!path) { + virReportError(VIR_ERR_XML_ERROR, "%s", + _("missing path for <reservations/>")); + goto cleanup; + } + + if (!mode) { + virReportError(VIR_ERR_XML_ERROR, "%s", + _("missing connection mode for <reservations/>")); + goto cleanup; + } + } + + if (type && STRNEQ(type, "unix")) { + virReportError(VIR_ERR_XML_ERROR, + _("unsupported connection type for <reservations/>: %s"), + type); + goto cleanup; + } + + if (mode && STRNEQ(mode, "client")) { + virReportError(VIR_ERR_XML_ERROR, + _("unsupported connection mode for <reservations/>: %s"), + mode); + goto cleanup; + } + + prd->path = g_steal_pointer(&path); + ret = g_steal_pointer(&prd); + + cleanup: + virStoragePRDefFree(prd); + return ret; +} + + +void +virStoragePRDefFormat(virBufferPtr buf, + virStoragePRDefPtr prd, + bool migratable) +{ + virBufferAsprintf(buf, "<reservations managed='%s'", + virTristateBoolTypeToString(prd->managed)); + if (prd->path && + (prd->managed == VIR_TRISTATE_BOOL_NO || !migratable)) { + virBufferAddLit(buf, ">\n"); + virBufferAdjustIndent(buf, 2); + virBufferAddLit(buf, "<source type='unix'"); + virBufferEscapeString(buf, " path='%s'", prd->path); + virBufferAddLit(buf, " mode='client'/>\n"); + virBufferAdjustIndent(buf, -2); + virBufferAddLit(buf, "</reservations>\n"); + } else { + virBufferAddLit(buf, "/>\n"); + } +} + + +bool +virStoragePRDefIsEqual(virStoragePRDefPtr a, + virStoragePRDefPtr b) +{ + if (!a && !b) + return true; + + if (!a || !b) + return false; + + if (a->managed != b->managed || + STRNEQ_NULLABLE(a->path, b->path)) + return false; + + return true; +} + + +bool +virStoragePRDefIsManaged(virStoragePRDefPtr prd) +{ + return prd && prd->managed == VIR_TRISTATE_BOOL_YES; +} + + +bool +virStorageSourceChainHasManagedPR(virStorageSourcePtr src) +{ + virStorageSourcePtr n; + + for (n = src; virStorageSourceIsBacking(n); n = n->backingStore) { + if (virStoragePRDefIsManaged(n->pr)) + return true; + } + + return false; +} + + +static virStoragePRDefPtr +virStoragePRDefCopy(virStoragePRDefPtr src) +{ + virStoragePRDefPtr copy = NULL; + virStoragePRDefPtr ret = NULL; + + copy = g_new0(virStoragePRDef, 1); + + copy->managed = src->managed; + + copy->path = g_strdup(src->path); + copy->mgralias = g_strdup(src->mgralias); + + ret = g_steal_pointer(©); + + virStoragePRDefFree(copy); + return ret; +} + + +static virStorageSourceNVMeDefPtr +virStorageSourceNVMeDefCopy(const virStorageSourceNVMeDef *src) +{ + virStorageSourceNVMeDefPtr ret = NULL; + + ret = g_new0(virStorageSourceNVMeDef, 1); + + ret->namespc = src->namespc; + ret->managed = src->managed; + virPCIDeviceAddressCopy(&ret->pciAddr, &src->pciAddr); + return ret; +} + + +static bool +virStorageSourceNVMeDefIsEqual(const virStorageSourceNVMeDef *a, + const virStorageSourceNVMeDef *b) +{ + if (!a && !b) + return true; + + if (!a || !b) + return false; + + if (a->namespc != b->namespc || + a->managed != b->managed || + !virPCIDeviceAddressEqual(&a->pciAddr, &b->pciAddr)) + return false; + + return true; +} + + +void +virStorageSourceNVMeDefFree(virStorageSourceNVMeDefPtr def) +{ + if (!def) + return; + + VIR_FREE(def); +} + + +bool +virStorageSourceChainHasNVMe(const virStorageSource *src) +{ + const virStorageSource *n; + + for (n = src; virStorageSourceIsBacking(n); n = n->backingStore) { + if (n->type == VIR_STORAGE_TYPE_NVME) + return true; + } + + return false; +} + + +virSecurityDeviceLabelDefPtr +virStorageSourceGetSecurityLabelDef(virStorageSourcePtr src, + const char *model) +{ + size_t i; + + for (i = 0; i < src->nseclabels; i++) { + if (STREQ_NULLABLE(src->seclabels[i]->model, model)) + return src->seclabels[i]; + } + + return NULL; +} + + +static void +virStorageSourceSeclabelsClear(virStorageSourcePtr def) +{ + size_t i; + + if (def->seclabels) { + for (i = 0; i < def->nseclabels; i++) + virSecurityDeviceLabelDefFree(def->seclabels[i]); + VIR_FREE(def->seclabels); + } +} + + +static int +virStorageSourceSeclabelsCopy(virStorageSourcePtr to, + const virStorageSource *from) +{ + size_t i; + + if (from->nseclabels == 0) + return 0; + + to->seclabels = g_new0(virSecurityDeviceLabelDefPtr, from->nseclabels); + to->nseclabels = from->nseclabels; + + for (i = 0; i < to->nseclabels; i++) { + if (!(to->seclabels[i] = virSecurityDeviceLabelDefCopy(from->seclabels[i]))) + goto error; + } + + return 0; + + error: + virStorageSourceSeclabelsClear(to); + return -1; +} + + +void +virStorageNetCookieDefFree(virStorageNetCookieDefPtr def) +{ + if (!def) + return; + + g_free(def->name); + g_free(def->value); + + g_free(def); +} + + +static void +virStorageSourceNetCookiesClear(virStorageSourcePtr src) +{ + size_t i; + + if (!src || !src->cookies) + return; + + for (i = 0; i < src->ncookies; i++) + virStorageNetCookieDefFree(src->cookies[i]); + + g_clear_pointer(&src->cookies, g_free); + src->ncookies = 0; +} + + +static void +virStorageSourceNetCookiesCopy(virStorageSourcePtr to, + const virStorageSource *from) +{ + size_t i; + + if (from->ncookies == 0) + return; + + to->cookies = g_new0(virStorageNetCookieDefPtr, from->ncookies); + to->ncookies = from->ncookies; + + for (i = 0; i < from->ncookies; i++) { + to->cookies[i]->name = g_strdup(from->cookies[i]->name); + to->cookies[i]->value = g_strdup(from->cookies[i]->value); + } +} + + +/* see https://tools.ietf.org/html/rfc6265#section-4.1.1 */ +static const char virStorageSourceCookieValueInvalidChars[] = + "\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F" + "\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1A\x1B\x1C\x1D\x1E\x1F" + " \",;\\"; + +/* in addition cookie name can't contain these */ +static const char virStorageSourceCookieNameInvalidChars[] = + "()<>@:/[]?={}"; + +static int +virStorageSourceNetCookieValidate(virStorageNetCookieDefPtr def) +{ + g_autofree char *val = g_strdup(def->value); + const char *checkval = val; + size_t len = strlen(val); + + /* name must have at least 1 character */ + if (*(def->name) == '\0') { + virReportError(VIR_ERR_XML_ERROR, "%s", + _("cookie name must not be empty")); + return -1; + } + + /* check invalid characters in name */ + if (virStringHasChars(def->name, virStorageSourceCookieValueInvalidChars) || + virStringHasChars(def->name, virStorageSourceCookieNameInvalidChars)) { + virReportError(VIR_ERR_XML_ERROR, + _("cookie name '%s' contains invalid characters"), + def->name); + return -1; + } + + /* check for optional quotes around the cookie value string */ + if (val[0] == '"') { + if (val[len - 1] != '"') { + virReportError(VIR_ERR_XML_ERROR, + _("value of cookie '%s' contains invalid characters"), + def->name); + return -1; + } + + val[len - 1] = '\0'; + checkval++; + } + + /* check invalid characters in value */ + if (virStringHasChars(checkval, virStorageSourceCookieValueInvalidChars)) { + virReportError(VIR_ERR_XML_ERROR, + _("value of cookie '%s' contains invalid characters"), + def->name); + return -1; + } + + return 0; +} + + +int +virStorageSourceNetCookiesValidate(virStorageSourcePtr src) +{ + size_t i; + size_t j; + + for (i = 0; i < src->ncookies; i++) { + if (virStorageSourceNetCookieValidate(src->cookies[i]) < 0) + return -1; + + for (j = i + 1; j < src->ncookies; j++) { + if (STREQ(src->cookies[i]->name, src->cookies[j]->name)) { + virReportError(VIR_ERR_XML_ERROR, _("duplicate cookie '%s'"), + src->cookies[i]->name); + return -1; + } + } + } + + return 0; +} + + +static virStorageTimestampsPtr +virStorageTimestampsCopy(const virStorageTimestamps *src) +{ + virStorageTimestampsPtr ret; + + ret = g_new0(virStorageTimestamps, 1); + + memcpy(ret, src, sizeof(*src)); + + return ret; +} + + +static virStoragePermsPtr +virStoragePermsCopy(const virStoragePerms *src) +{ + virStoragePermsPtr ret; + + ret = g_new0(virStoragePerms, 1); + + ret->mode = src->mode; + ret->uid = src->uid; + ret->gid = src->gid; + + ret->label = g_strdup(src->label); + + return ret; +} + + +static virStorageSourcePoolDefPtr +virStorageSourcePoolDefCopy(const virStorageSourcePoolDef *src) +{ + virStorageSourcePoolDefPtr ret; + + ret = g_new0(virStorageSourcePoolDef, 1); + + ret->voltype = src->voltype; + ret->pooltype = src->pooltype; + ret->actualtype = src->actualtype; + ret->mode = src->mode; + + ret->pool = g_strdup(src->pool); + ret->volume = g_strdup(src->volume); + + return ret; +} + + +static virStorageSourceSlicePtr +virStorageSourceSliceCopy(const virStorageSourceSlice *src) +{ + virStorageSourceSlicePtr ret = g_new0(virStorageSourceSlice, 1); + + ret->offset = src->offset; + ret->size = src->size; + ret->nodename = g_strdup(src->nodename); + + return ret; +} + + +static void +virStorageSourceSliceFree(virStorageSourceSlicePtr slice) +{ + if (!slice) + return; + + g_free(slice->nodename); + g_free(slice); +} + + +/** + * virStorageSourcePtr: + * + * Deep-copies a virStorageSource structure. If @backing chain is true + * then also copies the backing chain recursively, otherwise just + * the top element is copied. This function doesn't copy the + * storage driver access structure and thus the struct needs to be initialized + * separately. + */ +virStorageSourcePtr +virStorageSourceCopy(const virStorageSource *src, + bool backingChain) +{ + g_autoptr(virStorageSource) def = virStorageSourceNew(); + + def->id = src->id; + def->type = src->type; + def->protocol = src->protocol; + def->format = src->format; + def->capacity = src->capacity; + def->allocation = src->allocation; + def->has_allocation = src->has_allocation; + def->physical = src->physical; + def->readonly = src->readonly; + def->shared = src->shared; + def->haveTLS = src->haveTLS; + def->tlsFromConfig = src->tlsFromConfig; + def->detected = src->detected; + def->debugLevel = src->debugLevel; + def->debug = src->debug; + def->iomode = src->iomode; + def->cachemode = src->cachemode; + def->discard = src->discard; + def->detect_zeroes = src->detect_zeroes; + def->sslverify = src->sslverify; + def->readahead = src->readahead; + def->timeout = src->timeout; + def->metadataCacheMaxSize = src->metadataCacheMaxSize; + + /* storage driver metadata are not copied */ + def->drv = NULL; + + def->path = g_strdup(src->path); + def->volume = g_strdup(src->volume); + def->relPath = g_strdup(src->relPath); + def->backingStoreRaw = g_strdup(src->backingStoreRaw); + def->backingStoreRawFormat = src->backingStoreRawFormat; + def->snapshot = g_strdup(src->snapshot); + def->configFile = g_strdup(src->configFile); + def->nodeformat = g_strdup(src->nodeformat); + def->nodestorage = g_strdup(src->nodestorage); + def->compat = g_strdup(src->compat); + def->tlsAlias = g_strdup(src->tlsAlias); + def->tlsCertdir = g_strdup(src->tlsCertdir); + def->query = g_strdup(src->query); + + if (src->sliceStorage) + def->sliceStorage = virStorageSourceSliceCopy(src->sliceStorage); + + if (src->nhosts) { + if (!(def->hosts = virStorageNetHostDefCopy(src->nhosts, src->hosts))) + return NULL; + + def->nhosts = src->nhosts; + } + + virStorageSourceNetCookiesCopy(def, src); + + if (src->srcpool && + !(def->srcpool = virStorageSourcePoolDefCopy(src->srcpool))) + return NULL; + + if (src->features) + def->features = virBitmapNewCopy(src->features); + + if (src->encryption && + !(def->encryption = virStorageEncryptionCopy(src->encryption))) + return NULL; + + if (src->perms && + !(def->perms = virStoragePermsCopy(src->perms))) + return NULL; + + if (src->timestamps && + !(def->timestamps = virStorageTimestampsCopy(src->timestamps))) + return NULL; + + if (virStorageSourceSeclabelsCopy(def, src) < 0) + return NULL; + + if (src->auth && + !(def->auth = virStorageAuthDefCopy(src->auth))) + return NULL; + + if (src->pr && + !(def->pr = virStoragePRDefCopy(src->pr))) + return NULL; + + if (src->nvme) + def->nvme = virStorageSourceNVMeDefCopy(src->nvme); + + if (virStorageSourceInitiatorCopy(&def->initiator, &src->initiator) < 0) + return NULL; + + if (backingChain && src->backingStore) { + if (!(def->backingStore = virStorageSourceCopy(src->backingStore, + true))) + return NULL; + } + + /* ssh config passthrough for libguestfs */ + def->ssh_host_key_check_disabled = src->ssh_host_key_check_disabled; + def->ssh_user = g_strdup(src->ssh_user); + + def->nfs_user = g_strdup(src->nfs_user); + def->nfs_group = g_strdup(src->nfs_group); + def->nfs_uid = src->nfs_uid; + def->nfs_gid = src->nfs_gid; + + return g_steal_pointer(&def); +} + + +/** + * virStorageSourceIsSameLocation: + * + * Returns true if the sources @a and @b point to the same storage location. + * This does not compare any other configuration option + */ +bool +virStorageSourceIsSameLocation(virStorageSourcePtr a, + virStorageSourcePtr b) +{ + size_t i; + + /* there are multiple possibilities to define an empty source */ + if (virStorageSourceIsEmpty(a) && + virStorageSourceIsEmpty(b)) + return true; + + if (virStorageSourceGetActualType(a) != virStorageSourceGetActualType(b)) + return false; + + if (STRNEQ_NULLABLE(a->path, b->path) || + STRNEQ_NULLABLE(a->volume, b->volume) || + STRNEQ_NULLABLE(a->snapshot, b->snapshot)) + return false; + + if (a->type == VIR_STORAGE_TYPE_NETWORK) { + if (a->protocol != b->protocol || + a->nhosts != b->nhosts) + return false; + + for (i = 0; i < a->nhosts; i++) { + if (a->hosts[i].transport != b->hosts[i].transport || + a->hosts[i].port != b->hosts[i].port || + STRNEQ_NULLABLE(a->hosts[i].name, b->hosts[i].name) || + STRNEQ_NULLABLE(a->hosts[i].socket, b->hosts[i].socket)) + return false; + } + } + + if (a->type == VIR_STORAGE_TYPE_NVME && + !virStorageSourceNVMeDefIsEqual(a->nvme, b->nvme)) + return false; + + return true; +} + + +/** + * virStorageSourceInitChainElement: + * @newelem: New backing chain element disk source + * @old: Existing top level disk source + * @transferLabels: Transfer security labels. + * + * Transfers relevant information from the existing disk source to the new + * backing chain element if they weren't supplied so that labelling info + * and possibly other stuff is correct. + * + * If @transferLabels is true, security labels from the existing disk are copied + * to the new disk. Otherwise the default domain imagelabel label will be used. + * + * Returns 0 on success, -1 on error. + */ +int +virStorageSourceInitChainElement(virStorageSourcePtr newelem, + virStorageSourcePtr old, + bool transferLabels) +{ + if (transferLabels && + !newelem->seclabels && + virStorageSourceSeclabelsCopy(newelem, old) < 0) + return -1; + + newelem->shared = old->shared; + newelem->readonly = old->readonly; + + return 0; +} + + +void +virStorageSourcePoolDefFree(virStorageSourcePoolDefPtr def) +{ + if (!def) + return; + + VIR_FREE(def->pool); + VIR_FREE(def->volume); + + VIR_FREE(def); +} + + +/** + * virStorageSourceGetActualType: + * @def: storage source definition + * + * Returns type of @def. In case when the type is VIR_STORAGE_TYPE_VOLUME + * and virDomainDiskTranslateSourcePool was called on @def the actual type + * of the storage volume is returned rather than VIR_STORAGE_TYPE_VOLUME. + */ +int +virStorageSourceGetActualType(const virStorageSource *def) +{ + if (def->type == VIR_STORAGE_TYPE_VOLUME && + def->srcpool && + def->srcpool->actualtype != VIR_STORAGE_TYPE_NONE) + return def->srcpool->actualtype; + + return def->type; +} + + +bool +virStorageSourceIsLocalStorage(const virStorageSource *src) +{ + virStorageType type = virStorageSourceGetActualType(src); + + switch (type) { + case VIR_STORAGE_TYPE_FILE: + case VIR_STORAGE_TYPE_BLOCK: + case VIR_STORAGE_TYPE_DIR: + return true; + + case VIR_STORAGE_TYPE_NETWORK: + case VIR_STORAGE_TYPE_VOLUME: + /* While NVMe disks are local, they are not accessible via src->path. + * Therefore, we have to return false here. */ + case VIR_STORAGE_TYPE_NVME: + case VIR_STORAGE_TYPE_LAST: + case VIR_STORAGE_TYPE_NONE: + return false; + } + + return false; +} + + +/** + * virStorageSourceIsEmpty: + * + * @src: disk source to check + * + * Returns true if the guest disk has no associated host storage source + * (such as an empty cdrom drive). + */ +bool +virStorageSourceIsEmpty(virStorageSourcePtr src) +{ + if (virStorageSourceIsLocalStorage(src) && !src->path) + return true; + + if (src->type == VIR_STORAGE_TYPE_NONE) + return true; + + if (src->type == VIR_STORAGE_TYPE_NETWORK && + src->protocol == VIR_STORAGE_NET_PROTOCOL_NONE) + return true; + + return false; +} + + +/** + * virStorageSourceIsBlockLocal: + * @src: disk source definition + * + * Returns true if @src describes a locally accessible block storage source. + * This includes block devices and host-mapped iSCSI volumes. + */ +bool +virStorageSourceIsBlockLocal(const virStorageSource *src) +{ + return virStorageSourceGetActualType(src) == VIR_STORAGE_TYPE_BLOCK; +} + + +/** + * virStorageSourceBackingStoreClear: + * + * @src: disk source to clear + * + * Clears information about backing store of the current storage file. + */ +void +virStorageSourceBackingStoreClear(virStorageSourcePtr def) +{ + if (!def) + return; + + VIR_FREE(def->relPath); + VIR_FREE(def->backingStoreRaw); + + /* recursively free backing chain */ + virObjectUnref(def->backingStore); + def->backingStore = NULL; +} + + +void +virStorageSourceClear(virStorageSourcePtr def) +{ + if (!def) + return; + + VIR_FREE(def->path); + VIR_FREE(def->volume); + VIR_FREE(def->snapshot); + VIR_FREE(def->configFile); + VIR_FREE(def->query); + virStorageSourceNetCookiesClear(def); + virStorageSourcePoolDefFree(def->srcpool); + virBitmapFree(def->features); + VIR_FREE(def->compat); + virStorageEncryptionFree(def->encryption); + virStoragePRDefFree(def->pr); + virStorageSourceNVMeDefFree(def->nvme); + virStorageSourceSeclabelsClear(def); + virStoragePermsFree(def->perms); + VIR_FREE(def->timestamps); + + virStorageSourceSliceFree(def->sliceStorage); + + virStorageNetHostDefFree(def->nhosts, def->hosts); + virStorageAuthDefFree(def->auth); + virObjectUnref(def->privateData); + + VIR_FREE(def->nodestorage); + VIR_FREE(def->nodeformat); + + virStorageSourceBackingStoreClear(def); + + VIR_FREE(def->tlsAlias); + VIR_FREE(def->tlsCertdir); + + VIR_FREE(def->ssh_user); + + VIR_FREE(def->nfs_user); + VIR_FREE(def->nfs_group); + + virStorageSourceInitiatorClear(&def->initiator); + + /* clear everything except the class header as the object APIs + * will break otherwise */ + memset((char *) def + sizeof(def->parent), 0, + sizeof(*def) - sizeof(def->parent)); +} + + +static void +virStorageSourceDispose(void *obj) +{ + virStorageSourcePtr src = obj; + + virStorageSourceClear(src); +} + + +static int +virStorageSourceOnceInit(void) +{ + if (!VIR_CLASS_NEW(virStorageSource, virClassForObject())) + return -1; + + return 0; +} + + +VIR_ONCE_GLOBAL_INIT(virStorageSource); + + +virStorageSourcePtr +virStorageSourceNew(void) +{ + virStorageSourcePtr ret; + + if (virStorageSourceInitialize() < 0) + abort(); + + if (!(ret = virObjectNew(virStorageSourceClass))) + abort(); + + return ret; +} + + +/** + * virStorageSourceIsRelative: + * @src: storage source to check + * + * Returns true if given storage source definition is a relative path. + */ +bool +virStorageSourceIsRelative(virStorageSourcePtr src) +{ + virStorageType actual_type = virStorageSourceGetActualType(src); + + if (!src->path) + return false; + + switch (actual_type) { + case VIR_STORAGE_TYPE_FILE: + case VIR_STORAGE_TYPE_BLOCK: + case VIR_STORAGE_TYPE_DIR: + return src->path[0] != '/'; + + case VIR_STORAGE_TYPE_NETWORK: + case VIR_STORAGE_TYPE_VOLUME: + case VIR_STORAGE_TYPE_NVME: + case VIR_STORAGE_TYPE_NONE: + case VIR_STORAGE_TYPE_LAST: + return false; + } + + return false; +} + + +static unsigned int +virStorageSourceNetworkDefaultPort(virStorageNetProtocol protocol) +{ + switch (protocol) { + case VIR_STORAGE_NET_PROTOCOL_HTTP: + return 80; + + case VIR_STORAGE_NET_PROTOCOL_HTTPS: + return 443; + + case VIR_STORAGE_NET_PROTOCOL_FTP: + return 21; + + case VIR_STORAGE_NET_PROTOCOL_FTPS: + return 990; + + case VIR_STORAGE_NET_PROTOCOL_TFTP: + return 69; + + case VIR_STORAGE_NET_PROTOCOL_SHEEPDOG: + return 7000; + + case VIR_STORAGE_NET_PROTOCOL_NBD: + return 10809; + + case VIR_STORAGE_NET_PROTOCOL_SSH: + return 22; + + case VIR_STORAGE_NET_PROTOCOL_ISCSI: + return 3260; + + case VIR_STORAGE_NET_PROTOCOL_GLUSTER: + return 24007; + + case VIR_STORAGE_NET_PROTOCOL_RBD: + /* we don't provide a default for RBD */ + return 0; + + case VIR_STORAGE_NET_PROTOCOL_VXHS: + return 9999; + + case VIR_STORAGE_NET_PROTOCOL_NFS: + /* Port is not supported by NFS, so no default is provided */ + return 0; + + case VIR_STORAGE_NET_PROTOCOL_LAST: + case VIR_STORAGE_NET_PROTOCOL_NONE: + return 0; + } + + return 0; +} + + +void +virStorageSourceNetworkAssignDefaultPorts(virStorageSourcePtr src) +{ + size_t i; + + for (i = 0; i < src->nhosts; i++) { + if (src->hosts[i].transport == VIR_STORAGE_NET_HOST_TRANS_TCP && + src->hosts[i].port == 0) + src->hosts[i].port = virStorageSourceNetworkDefaultPort(src->protocol); + } +} + + +int +virStorageSourcePrivateDataParseRelPath(xmlXPathContextPtr ctxt, + virStorageSourcePtr src) +{ + src->relPath = virXPathString("string(./relPath)", ctxt); + return 0; +} + + +int +virStorageSourcePrivateDataFormatRelPath(virStorageSourcePtr src, + virBufferPtr buf) +{ + if (src->relPath) + virBufferEscapeString(buf, "<relPath>%s</relPath>\n", src->relPath); + + return 0; +} + + +void +virStorageSourceInitiatorParseXML(xmlXPathContextPtr ctxt, + virStorageSourceInitiatorDefPtr initiator) +{ + initiator->iqn = virXPathString("string(./initiator/iqn/@name)", ctxt); +} + + +void +virStorageSourceInitiatorFormatXML(virStorageSourceInitiatorDefPtr initiator, + virBufferPtr buf) +{ + if (!initiator->iqn) + return; + + virBufferAddLit(buf, "<initiator>\n"); + virBufferAdjustIndent(buf, 2); + virBufferEscapeString(buf, "<iqn name='%s'/>\n", initiator->iqn); + virBufferAdjustIndent(buf, -2); + virBufferAddLit(buf, "</initiator>\n"); +} + + +int +virStorageSourceInitiatorCopy(virStorageSourceInitiatorDefPtr dest, + const virStorageSourceInitiatorDef *src) +{ + dest->iqn = g_strdup(src->iqn); + return 0; +} + + +void +virStorageSourceInitiatorClear(virStorageSourceInitiatorDefPtr initiator) +{ + VIR_FREE(initiator->iqn); +} diff --git a/src/conf/storage_source_conf.h b/src/conf/storage_source_conf.h new file mode 100644 index 0000000000..6f39ab4bd0 --- /dev/null +++ b/src/conf/storage_source_conf.h @@ -0,0 +1,537 @@ +/* + * storage_source_conf.h: file utility functions for FS storage backend + * + * Copyright (C) 2007-2009, 2012-2016 Red Hat, Inc. + * Copyright (C) 2007-2008 Daniel P. Berrange + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. If not, see + * <http://www.gnu.org/licenses/>. + */ + +#pragma once + +#include "virbitmap.h" +#include "virenum.h" +#include "virobject.h" +#include "virpci.h" +#include "virseclabel.h" +#include "virsecret.h" +#include "virstorageencryption.h" + +/* Types of disk backends (host resource). Comparable to the public + * virStorageVolType, except we have an undetermined state, don't have + * a netdir type, and add a volume type for reference through a + * storage pool. */ +typedef enum { + VIR_STORAGE_TYPE_NONE, + VIR_STORAGE_TYPE_FILE, + VIR_STORAGE_TYPE_BLOCK, + VIR_STORAGE_TYPE_DIR, + VIR_STORAGE_TYPE_NETWORK, + VIR_STORAGE_TYPE_VOLUME, + VIR_STORAGE_TYPE_NVME, + + VIR_STORAGE_TYPE_LAST +} virStorageType; + +VIR_ENUM_DECL(virStorage); + + +typedef enum { + VIR_STORAGE_FILE_AUTO_SAFE = -2, + VIR_STORAGE_FILE_AUTO = -1, + VIR_STORAGE_FILE_NONE = 0, + VIR_STORAGE_FILE_RAW, + VIR_STORAGE_FILE_DIR, + VIR_STORAGE_FILE_BOCHS, + VIR_STORAGE_FILE_CLOOP, + VIR_STORAGE_FILE_DMG, + VIR_STORAGE_FILE_ISO, + VIR_STORAGE_FILE_VPC, + VIR_STORAGE_FILE_VDI, + + /* Not direct file formats, but used for various drivers */ + VIR_STORAGE_FILE_FAT, + VIR_STORAGE_FILE_VHD, + VIR_STORAGE_FILE_PLOOP, + + /* Not a format, but a marker: all formats below this point have + * libvirt support for following a backing chain */ + VIR_STORAGE_FILE_BACKING, + + VIR_STORAGE_FILE_COW = VIR_STORAGE_FILE_BACKING, + VIR_STORAGE_FILE_QCOW, + VIR_STORAGE_FILE_QCOW2, + VIR_STORAGE_FILE_QED, + VIR_STORAGE_FILE_VMDK, + + VIR_STORAGE_FILE_LAST, +} virStorageFileFormat; + +VIR_ENUM_DECL(virStorageFileFormat); + + +typedef enum { + VIR_STORAGE_FILE_FEATURE_LAZY_REFCOUNTS = 0, + + VIR_STORAGE_FILE_FEATURE_LAST +} virStorageFileFeature; + +VIR_ENUM_DECL(virStorageFileFeature); + + +typedef struct _virStoragePerms virStoragePerms; +typedef virStoragePerms *virStoragePermsPtr; +struct _virStoragePerms { + mode_t mode; + uid_t uid; + gid_t gid; + char *label; +}; + + +typedef struct _virStorageTimestamps virStorageTimestamps; +typedef virStorageTimestamps *virStorageTimestampsPtr; +struct _virStorageTimestamps { + struct timespec atime; + struct timespec btime; /* birth time unknown if btime.tv_nsec == -1 */ + struct timespec ctime; + struct timespec mtime; +}; + + +/* Information related to network storage */ +typedef enum { + VIR_STORAGE_NET_PROTOCOL_NONE, + VIR_STORAGE_NET_PROTOCOL_NBD, + VIR_STORAGE_NET_PROTOCOL_RBD, + VIR_STORAGE_NET_PROTOCOL_SHEEPDOG, + VIR_STORAGE_NET_PROTOCOL_GLUSTER, + VIR_STORAGE_NET_PROTOCOL_ISCSI, + VIR_STORAGE_NET_PROTOCOL_HTTP, + VIR_STORAGE_NET_PROTOCOL_HTTPS, + VIR_STORAGE_NET_PROTOCOL_FTP, + VIR_STORAGE_NET_PROTOCOL_FTPS, + VIR_STORAGE_NET_PROTOCOL_TFTP, + VIR_STORAGE_NET_PROTOCOL_SSH, + VIR_STORAGE_NET_PROTOCOL_VXHS, + VIR_STORAGE_NET_PROTOCOL_NFS, + + VIR_STORAGE_NET_PROTOCOL_LAST +} virStorageNetProtocol; + +VIR_ENUM_DECL(virStorageNetProtocol); + + +typedef enum { + VIR_STORAGE_NET_HOST_TRANS_TCP, + VIR_STORAGE_NET_HOST_TRANS_UNIX, + VIR_STORAGE_NET_HOST_TRANS_RDMA, + + VIR_STORAGE_NET_HOST_TRANS_LAST +} virStorageNetHostTransport; + +VIR_ENUM_DECL(virStorageNetHostTransport); + + +typedef struct _virStorageNetHostDef virStorageNetHostDef; +typedef virStorageNetHostDef *virStorageNetHostDefPtr; +struct _virStorageNetHostDef { + char *name; + unsigned int port; + int transport; /* virStorageNetHostTransport */ + char *socket; /* path to unix socket */ +}; + + +typedef struct _virStorageNetCookieDef virStorageNetCookieDef; +typedef virStorageNetCookieDef *virStorageNetCookieDefPtr; +struct _virStorageNetCookieDef { + char *name; + char *value; +}; + + +void +virStorageNetCookieDefFree(virStorageNetCookieDefPtr def); + +G_DEFINE_AUTOPTR_CLEANUP_FUNC(virStorageNetCookieDef, virStorageNetCookieDefFree); + + +/* Information for a storage volume from a virStoragePool */ + +/* + * Used for volume "type" disk to indicate how to represent + * the disk source if the specified "pool" is of iscsi type. + */ +typedef enum { + VIR_STORAGE_SOURCE_POOL_MODE_DEFAULT = 0, + + /* Use the path as it shows up on host, e.g. + * /dev/disk/by-path/ip-$ip-iscsi-$iqn:iscsi.iscsi-pool0-lun-1 + */ + VIR_STORAGE_SOURCE_POOL_MODE_HOST, + + /* Use the URI from the storage pool source element host attribute. E.g. + * file=iscsi://demo.org:6000/iqn.1992-01.com.example/1. + */ + VIR_STORAGE_SOURCE_POOL_MODE_DIRECT, + + VIR_STORAGE_SOURCE_POOL_MODE_LAST +} virStorageSourcePoolMode; + +VIR_ENUM_DECL(virStorageSourcePoolMode); + + +typedef struct _virStorageSourcePoolDef virStorageSourcePoolDef; +typedef virStorageSourcePoolDef *virStorageSourcePoolDefPtr; +struct _virStorageSourcePoolDef { + char *pool; /* pool name */ + char *volume; /* volume name */ + int voltype; /* virStorageVolType, internal only */ + int pooltype; /* virStoragePoolType from storage_conf.h, internal only */ + int actualtype; /* virStorageType, internal only */ + int mode; /* virStorageSourcePoolMode, currently makes sense only for iscsi pool */ +}; + + +typedef enum { + VIR_STORAGE_AUTH_TYPE_NONE, + VIR_STORAGE_AUTH_TYPE_CHAP, + VIR_STORAGE_AUTH_TYPE_CEPHX, + + VIR_STORAGE_AUTH_TYPE_LAST, +} virStorageAuthType; + +VIR_ENUM_DECL(virStorageAuth); + + +typedef struct _virStorageAuthDef virStorageAuthDef; +typedef virStorageAuthDef *virStorageAuthDefPtr; +struct _virStorageAuthDef { + char *username; + char *secrettype; /* <secret type='%s' for disk source */ + int authType; /* virStorageAuthType */ + virSecretLookupTypeDef seclookupdef; +}; + + +typedef struct _virStoragePRDef virStoragePRDef; +typedef virStoragePRDef *virStoragePRDefPtr; +struct _virStoragePRDef { + int managed; /* enum virTristateBool */ + char *path; + + /* manager object alias */ + char *mgralias; +}; + + +typedef struct _virStorageSourceInitiatorDef virStorageSourceInitiatorDef; +typedef virStorageSourceInitiatorDef *virStorageSourceInitiatorDefPtr; +struct _virStorageSourceInitiatorDef { + char *iqn; /* Initiator IQN */ +}; + + +typedef struct _virStorageSourceNVMeDef virStorageSourceNVMeDef; +typedef virStorageSourceNVMeDef *virStorageSourceNVMeDefPtr; +struct _virStorageSourceNVMeDef { + unsigned long long namespc; + int managed; /* enum virTristateBool */ + virPCIDeviceAddress pciAddr; + + /* Don't forget to update virStorageSourceNVMeDefCopy */ +}; + + +typedef struct _virStorageSourceSlice virStorageSourceSlice; +typedef virStorageSourceSlice *virStorageSourceSlicePtr; +struct _virStorageSourceSlice { + unsigned long long offset; + unsigned long long size; + char *nodename; +}; + + +typedef struct _virStorageSource virStorageSource; +typedef virStorageSource *virStorageSourcePtr; + +/* Stores information related to a host resource. In the case of backing + * chains, multiple source disks join to form a single guest view. + * + * IMPORTANT: When adding fields to this struct it's also necessary to add + * appropriate code to the virStorageSourceCopy deep copy function */ +struct _virStorageSource { + virObject parent; + + unsigned int id; /* backing chain identifier, 0 is unset */ + int type; /* virStorageType */ + char *path; + int protocol; /* virStorageNetProtocol */ + char *volume; /* volume name for remote storage */ + 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; + size_t ncookies; + virStorageNetCookieDefPtr *cookies; + virStorageSourcePoolDefPtr srcpool; + virStorageAuthDefPtr auth; + virStorageEncryptionPtr encryption; + virStoragePRDefPtr pr; + virTristateBool sslverify; + /* both values below have 0 as default value */ + unsigned long long readahead; /* size of the readahead buffer in bytes */ + unsigned long long timeout; /* connection timeout in seconds */ + + virStorageSourceNVMeDefPtr nvme; /* type == VIR_STORAGE_TYPE_NVME */ + + virStorageSourceInitiatorDef initiator; + + virObjectPtr privateData; + + int format; /* virStorageFileFormat in domain backing chains, but + * pool-specific enum for storage volumes */ + virBitmapPtr features; + char *compat; + bool nocow; + bool sparse; + + virStorageSourceSlicePtr sliceStorage; + + virStoragePermsPtr perms; + virStorageTimestampsPtr timestamps; + unsigned long long capacity; /* in bytes, 0 if unknown */ + unsigned long long allocation; /* in bytes, 0 if unknown */ + unsigned long long physical; /* in bytes, 0 if unknown */ + unsigned long long clusterSize; /* in bytes, 0 if unknown */ + bool has_allocation; /* Set to true when provided in XML */ + + unsigned long long metadataCacheMaxSize; /* size of the metadata cache in bytes */ + + size_t nseclabels; + virSecurityDeviceLabelDefPtr *seclabels; + + /* Don't ever write to the image */ + bool readonly; + + /* image is shared across hosts */ + bool shared; + + /* backing chain of the storage source */ + virStorageSourcePtr backingStore; + + /* metadata for storage driver access to remote and local volumes */ + void *drv; + + /* metadata about storage image which need separate fields */ + /* Relative name by which this image was opened from its parent, or NULL + * if this image was opened by absolute name */ + char *relPath; + /* Name of the child backing store recorded in metadata of the + * current file. */ + char *backingStoreRaw; + virStorageFileFormat backingStoreRawFormat; + + /* metadata that allows identifying given storage source */ + char *nodeformat; /* name of the format handler object */ + char *nodestorage; /* name of the storage object */ + + /* An optional setting to enable usage of TLS for the storage source */ + int haveTLS; /* enum virTristateBool */ + + /* Indication whether the haveTLS value was altered due to qemu.conf + * setting when haveTLS is missing from the domain config file */ + bool tlsFromConfig; + + /* If TLS is used, then mgmt of the TLS credentials occurs via an + * object that is generated using a specific alias for a specific + * certificate directory with listen and verify bools. */ + char *tlsAlias; + char *tlsCertdir; + + bool detected; /* true if this entry was not provided by the user */ + + unsigned int debugLevel; + bool debug; + + /* Libvirt currently stores the following properties in virDomainDiskDef. + * These instances are currently just copies from the parent definition and + * are not mapped back to the XML */ + int iomode; /* enum virDomainDiskIo */ + int cachemode; /* enum virDomainDiskCache */ + int discard; /* enum virDomainDiskDiscard */ + int detect_zeroes; /* enum virDomainDiskDetectZeroes */ + + bool floppyimg; /* set to true if the storage source is going to be used + as a source for floppy drive */ + + bool hostcdrom; /* backing device is a cdrom */ + + /* passthrough variables for the ssh driver which we don't handle properly */ + /* these must not be used apart from formatting the output JSON in the qemu driver */ + char *ssh_user; + bool ssh_host_key_check_disabled; + + /* nfs_user and nfs_group store the strings passed in by the user for NFS params. + * nfs_uid and nfs_gid represent the converted/looked up ID numbers which are used + * during run time, and are not based on the configuration */ + char *nfs_user; + char *nfs_group; + uid_t nfs_uid; + gid_t nfs_gid; +}; + +G_DEFINE_AUTOPTR_CLEANUP_FUNC(virStorageSource, virObjectUnref); + +void +virStorageAuthDefFree(virStorageAuthDefPtr def); + +virStorageAuthDefPtr +virStorageAuthDefCopy(const virStorageAuthDef *src); + +virStorageAuthDefPtr +virStorageAuthDefParse(xmlNodePtr node, + xmlXPathContextPtr ctxt); + +void +virStorageAuthDefFormat(virBufferPtr buf, + virStorageAuthDefPtr authdef); + +void +virStoragePRDefFree(virStoragePRDefPtr prd); + +virStoragePRDefPtr +virStoragePRDefParseXML(xmlXPathContextPtr ctxt); + +void +virStoragePRDefFormat(virBufferPtr buf, + virStoragePRDefPtr prd, + bool migratable); + +bool +virStoragePRDefIsEqual(virStoragePRDefPtr a, + virStoragePRDefPtr b); + +bool +virStoragePRDefIsManaged(virStoragePRDefPtr prd); + +bool +virStorageSourceChainHasManagedPR(virStorageSourcePtr src); + +void +virStorageSourceNVMeDefFree(virStorageSourceNVMeDefPtr def); + +G_DEFINE_AUTOPTR_CLEANUP_FUNC(virStorageSourceNVMeDef, virStorageSourceNVMeDefFree); + +bool +virStorageSourceChainHasNVMe(const virStorageSource *src); + +virSecurityDeviceLabelDefPtr +virStorageSourceGetSecurityLabelDef(virStorageSourcePtr src, + const char *model); + +void +virStorageNetHostDefClear(virStorageNetHostDefPtr def); + +void +virStorageNetHostDefFree(size_t nhosts, + virStorageNetHostDefPtr hosts); + +virStorageNetHostDefPtr +virStorageNetHostDefCopy(size_t nhosts, + virStorageNetHostDefPtr hosts); + +int +virStorageSourceInitChainElement(virStorageSourcePtr newelem, + virStorageSourcePtr old, + bool force); + +void +virStorageSourcePoolDefFree(virStorageSourcePoolDefPtr def); + +void +virStorageSourceClear(virStorageSourcePtr def); + +int +virStorageSourceGetActualType(const virStorageSource *def); + +bool +virStorageSourceIsLocalStorage(const virStorageSource *src); + +bool +virStorageSourceIsEmpty(virStorageSourcePtr src); + +bool +virStorageSourceIsBlockLocal(const virStorageSource *src); + +virStorageSourcePtr +virStorageSourceNew(void); + +void +virStorageSourceBackingStoreClear(virStorageSourcePtr def); + +int +virStorageSourceNetCookiesValidate(virStorageSourcePtr src); + +virStorageSourcePtr +virStorageSourceCopy(const virStorageSource *src, + bool backingChain) + ATTRIBUTE_NONNULL(1); + +bool +virStorageSourceIsSameLocation(virStorageSourcePtr a, + virStorageSourcePtr b) + ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2); + +bool +virStorageSourceIsRelative(virStorageSourcePtr src); + +void +virStorageSourceNetworkAssignDefaultPorts(virStorageSourcePtr src) + ATTRIBUTE_NONNULL(1); + +bool +virStorageSourceIsBacking(const virStorageSource *src); + +bool +virStorageSourceHasBacking(const virStorageSource *src); + +int +virStorageSourcePrivateDataParseRelPath(xmlXPathContextPtr ctxt, + virStorageSourcePtr src); + +int +virStorageSourcePrivateDataFormatRelPath(virStorageSourcePtr src, + virBufferPtr buf); + +void +virStorageSourceInitiatorParseXML(xmlXPathContextPtr ctxt, + virStorageSourceInitiatorDefPtr initiator); + +void +virStorageSourceInitiatorFormatXML(virStorageSourceInitiatorDefPtr initiator, + virBufferPtr buf); + +int +virStorageSourceInitiatorCopy(virStorageSourceInitiatorDefPtr dest, + const virStorageSourceInitiatorDef *src); + +void +virStorageSourceInitiatorClear(virStorageSourceInitiatorDefPtr initiator); + +G_DEFINE_AUTOPTR_CLEANUP_FUNC(virStorageAuthDef, virStorageAuthDefFree); diff --git a/src/esx/esx_storage_backend_iscsi.c b/src/esx/esx_storage_backend_iscsi.c index edbc65f5c0..4d16ba2520 100644 --- a/src/esx/esx_storage_backend_iscsi.c +++ b/src/esx/esx_storage_backend_iscsi.c @@ -28,7 +28,7 @@ #include "viralloc.h" #include "viruuid.h" #include "storage_conf.h" -#include "virstoragefile.h" +#include "storage_source_conf.h" #include "esx_storage_backend_iscsi.h" #include "esx_private.h" #include "esx_vi.h" diff --git a/src/esx/esx_storage_backend_vmfs.c b/src/esx/esx_storage_backend_vmfs.c index c7a7863a61..27d8016194 100644 --- a/src/esx/esx_storage_backend_vmfs.c +++ b/src/esx/esx_storage_backend_vmfs.c @@ -32,7 +32,7 @@ #include "virlog.h" #include "viruuid.h" #include "storage_conf.h" -#include "virstoragefile.h" +#include "storage_source_conf.h" #include "esx_storage_backend_vmfs.h" #include "esx_private.h" #include "esx_vi.h" diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms index b49eee3750..b13d0db209 100644 --- a/src/libvirt_private.syms +++ b/src/libvirt_private.syms @@ -1053,6 +1053,58 @@ virStoragePoolEventRefreshNew; virStoragePoolEventStateRegisterID; +# conf/storage_source_conf.h +virStorageAuthDefCopy; +virStorageAuthDefFormat; +virStorageAuthDefFree; +virStorageAuthDefParse; +virStorageFileFeatureTypeFromString; +virStorageFileFeatureTypeToString; +virStorageFileFormatTypeFromString; +virStorageFileFormatTypeToString; +virStorageNetHostDefClear; +virStorageNetHostDefCopy; +virStorageNetHostDefFree; +virStorageNetHostTransportTypeFromString; +virStorageNetHostTransportTypeToString; +virStorageNetProtocolTypeToString; +virStoragePRDefFormat; +virStoragePRDefFree; +virStoragePRDefIsEqual; +virStoragePRDefIsManaged; +virStoragePRDefParseXML; +virStorageSourceBackingStoreClear; +virStorageSourceChainHasManagedPR; +virStorageSourceChainHasNVMe; +virStorageSourceClear; +virStorageSourceCopy; +virStorageSourceGetActualType; +virStorageSourceGetSecurityLabelDef; +virStorageSourceHasBacking; +virStorageSourceInitChainElement; +virStorageSourceInitiatorClear; +virStorageSourceInitiatorCopy; +virStorageSourceInitiatorFormatXML; +virStorageSourceInitiatorParseXML; +virStorageSourceIsBacking; +virStorageSourceIsBlockLocal; +virStorageSourceIsEmpty; +virStorageSourceIsLocalStorage; +virStorageSourceIsRelative; +virStorageSourceIsSameLocation; +virStorageSourceNetCookiesValidate; +virStorageSourceNetworkAssignDefaultPorts; +virStorageSourceNew; +virStorageSourceNVMeDefFree; +virStorageSourcePoolDefFree; +virStorageSourcePoolModeTypeFromString; +virStorageSourcePoolModeTypeToString; +virStorageSourcePrivateDataFormatRelPath; +virStorageSourcePrivateDataParseRelPath; +virStorageTypeFromString; +virStorageTypeToString; + + # conf/virchrdev.h virChrdevAlloc; virChrdevFree; @@ -3161,62 +3213,13 @@ virStorageEncryptionParseNode; # util/virstoragefile.h -virStorageAuthDefCopy; -virStorageAuthDefFormat; -virStorageAuthDefFree; -virStorageAuthDefParse; virStorageFileCanonicalizePath; -virStorageFileFeatureTypeFromString; -virStorageFileFeatureTypeToString; -virStorageFileFormatTypeFromString; -virStorageFileFormatTypeToString; virStorageFileGetNPIVKey; virStorageFileGetSCSIKey; virStorageFileParseBackingStoreStr; virStorageFileParseChainIndex; virStorageIsFile; virStorageIsRelative; -virStorageNetHostDefClear; -virStorageNetHostDefCopy; -virStorageNetHostDefFree; -virStorageNetHostTransportTypeFromString; -virStorageNetHostTransportTypeToString; -virStorageNetProtocolTypeToString; -virStoragePRDefFormat; -virStoragePRDefFree; -virStoragePRDefIsEqual; -virStoragePRDefIsManaged; -virStoragePRDefParseXML; -virStorageSourceBackingStoreClear; -virStorageSourceChainHasManagedPR; -virStorageSourceChainHasNVMe; -virStorageSourceClear; -virStorageSourceCopy; -virStorageSourceGetActualType; -virStorageSourceGetSecurityLabelDef; -virStorageSourceHasBacking; -virStorageSourceInitChainElement; -virStorageSourceInitiatorClear; -virStorageSourceInitiatorCopy; -virStorageSourceInitiatorFormatXML; -virStorageSourceInitiatorParseXML; -virStorageSourceIsBacking; -virStorageSourceIsBlockLocal; -virStorageSourceIsEmpty; -virStorageSourceIsLocalStorage; -virStorageSourceIsRelative; -virStorageSourceIsSameLocation; -virStorageSourceNetCookiesValidate; -virStorageSourceNetworkAssignDefaultPorts; -virStorageSourceNew; -virStorageSourceNVMeDefFree; -virStorageSourcePoolDefFree; -virStorageSourcePoolModeTypeFromString; -virStorageSourcePoolModeTypeToString; -virStorageSourcePrivateDataFormatRelPath; -virStorageSourcePrivateDataParseRelPath; -virStorageTypeFromString; -virStorageTypeToString; # util/virstring.h diff --git a/src/qemu/qemu_backup.c b/src/qemu/qemu_backup.c index 72ca781d8b..4a07f6a5f4 100644 --- a/src/qemu/qemu_backup.c +++ b/src/qemu/qemu_backup.c @@ -30,12 +30,12 @@ #include "qemu_command.h" #include "storage_source.h" +#include "storage_source_conf.h" #include "virerror.h" #include "virlog.h" #include "virbuffer.h" #include "viralloc.h" #include "virxml.h" -#include "virstoragefile.h" #include "virstring.h" #include "backup_conf.h" #include "virdomaincheckpointobjlist.h" diff --git a/src/qemu/qemu_blockjob.c b/src/qemu/qemu_blockjob.c index 0d00dbc947..582fe45c66 100644 --- a/src/qemu/qemu_blockjob.c +++ b/src/qemu/qemu_blockjob.c @@ -32,8 +32,8 @@ #include "conf/domain_conf.h" #include "conf/domain_event.h" +#include "storage_source_conf.h" #include "virlog.h" -#include "virstoragefile.h" #include "virthread.h" #include "virtime.h" #include "locking/domain_lock.h" diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c index 2506248866..1ec302d4ac 100644 --- a/src/qemu/qemu_command.c +++ b/src/qemu/qemu_command.c @@ -53,7 +53,7 @@ #include "virnetdevtap.h" #include "virnetdevopenvswitch.h" #include "device_conf.h" -#include "virstoragefile.h" +#include "storage_source_conf.h" #include "virtpm.h" #include "virscsi.h" #include "virnuma.h" diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c index 5363af3f56..8048c86632 100644 --- a/src/qemu/qemu_driver.c +++ b/src/qemu/qemu_driver.c @@ -83,6 +83,7 @@ #include "domain_nwfilter.h" #include "virhook.h" #include "virstoragefile.h" +#include "storage_source_conf.h" #include "storage_file_probe.h" #include "storage_source.h" #include "virfile.h" diff --git a/src/qemu/qemu_hotplug.c b/src/qemu/qemu_hotplug.c index f1fa5986e1..99950a1360 100644 --- a/src/qemu/qemu_hotplug.c +++ b/src/qemu/qemu_hotplug.c @@ -52,8 +52,8 @@ #include "virnetdevopenvswitch.h" #include "virnetdevmidonet.h" #include "device_conf.h" -#include "virstoragefile.h" #include "storage_source.h" +#include "storage_source_conf.h" #include "virstring.h" #include "virtime.h" #include "virqemu.h" diff --git a/src/qemu/qemu_migration.c b/src/qemu/qemu_migration.c index 5353c7ee01..0adfdb9351 100644 --- a/src/qemu/qemu_migration.c +++ b/src/qemu/qemu_migration.c @@ -52,7 +52,7 @@ #include "virtime.h" #include "locking/domain_lock.h" #include "rpc/virnetsocket.h" -#include "virstoragefile.h" +#include "storage_source_conf.h" #include "viruri.h" #include "virhook.h" #include "virstring.h" diff --git a/src/storage/storage_backend.c b/src/storage/storage_backend.c index 2bce445575..83a4b8602a 100644 --- a/src/storage/storage_backend.c +++ b/src/storage/storage_backend.c @@ -27,8 +27,8 @@ #include "virerror.h" #include "viralloc.h" #include "internal.h" -#include "virstoragefile.h" #include "storage_backend.h" +#include "storage_source_conf.h" #include "virlog.h" #include "virmodule.h" #include "virfile.h" diff --git a/src/storage/storage_util.c b/src/storage/storage_util.c index 04f9a442f2..10c04e1257 100644 --- a/src/storage/storage_util.c +++ b/src/storage/storage_util.c @@ -65,6 +65,7 @@ #include "storage_file_probe.h" #include "storage_util.h" #include "storage_source.h" +#include "storage_source_conf.h" #include "virlog.h" #include "virfile.h" #include "virjson.h" diff --git a/src/storage_file/meson.build b/src/storage_file/meson.build index eb9453e7b0..c97c7f8009 100644 --- a/src/storage_file/meson.build +++ b/src/storage_file/meson.build @@ -22,6 +22,9 @@ virt_storage_file_lib = static_library( dependencies: [ src_dep, ], + include_directories: [ + conf_inc_dir, + ], ) libvirt_libs += virt_storage_file_lib diff --git a/src/storage_file/storage_file_backend.h b/src/storage_file/storage_file_backend.h index ad0f66212c..ecf5883a55 100644 --- a/src/storage_file/storage_file_backend.h +++ b/src/storage_file/storage_file_backend.h @@ -22,7 +22,7 @@ #include <sys/stat.h> -#include "virstoragefile.h" +#include "storage_source_conf.h" /* ------- virStorageFile backends ------------ */ typedef struct _virStorageFileBackend virStorageFileBackend; diff --git a/src/storage_file/storage_file_probe.c b/src/storage_file/storage_file_probe.c index e5e1b272ac..29baa0596f 100644 --- a/src/storage_file/storage_file_probe.c +++ b/src/storage_file/storage_file_probe.c @@ -27,12 +27,12 @@ #include "internal.h" #include "storage_file_probe.h" +#include "storage_source_conf.h" #include "viralloc.h" #include "virbitmap.h" #include "virendian.h" #include "virfile.h" #include "virlog.h" -#include "virstoragefile.h" #define VIR_FROM_THIS VIR_FROM_STORAGE diff --git a/src/storage_file/storage_file_probe.h b/src/storage_file/storage_file_probe.h index c443c11606..0d0ac38185 100644 --- a/src/storage_file/storage_file_probe.h +++ b/src/storage_file/storage_file_probe.h @@ -23,7 +23,7 @@ #include <sys/stat.h> -#include "virstoragefile.h" +#include "storage_source_conf.h" /* Minimum header size required to probe all known formats with * virStorageFileProbeFormat, or obtain metadata from a known format. diff --git a/src/storage_file/storage_source.h b/src/storage_file/storage_source.h index 23f56417a8..5d6ad4606d 100644 --- a/src/storage_file/storage_source.h +++ b/src/storage_file/storage_source.h @@ -21,7 +21,7 @@ #pragma once -#include "virstoragefile.h" +#include "storage_source_conf.h" #ifndef DEV_BSIZE # define DEV_BSIZE 512 diff --git a/src/util/virstoragefile.c b/src/util/virstoragefile.c index c70d5713de..85ccd9f52c 100644 --- a/src/util/virstoragefile.c +++ b/src/util/virstoragefile.c @@ -23,89 +23,19 @@ #include "virstoragefile.h" #include "viralloc.h" -#include "virxml.h" #include "viruuid.h" #include "virerror.h" #include "virlog.h" -#include "virfile.h" #include "vircommand.h" #include "virhash.h" #include "virstring.h" #include "virbuffer.h" -#include "virstorageencryption.h" #include "virsecret.h" #define VIR_FROM_THIS VIR_FROM_STORAGE VIR_LOG_INIT("util.storagefile"); -static virClassPtr virStorageSourceClass; - -VIR_ENUM_IMPL(virStorage, - VIR_STORAGE_TYPE_LAST, - "none", - "file", - "block", - "dir", - "network", - "volume", - "nvme", -); - -VIR_ENUM_IMPL(virStorageFileFormat, - VIR_STORAGE_FILE_LAST, - "none", - "raw", "dir", "bochs", - "cloop", "dmg", "iso", - "vpc", "vdi", - /* Not direct file formats, but used for various drivers */ - "fat", "vhd", "ploop", - /* Formats with backing file below here */ - "cow", "qcow", "qcow2", "qed", "vmdk", -); - -VIR_ENUM_IMPL(virStorageFileFeature, - VIR_STORAGE_FILE_FEATURE_LAST, - "lazy_refcounts", -); - -VIR_ENUM_IMPL(virStorageNetProtocol, - VIR_STORAGE_NET_PROTOCOL_LAST, - "none", - "nbd", - "rbd", - "sheepdog", - "gluster", - "iscsi", - "http", - "https", - "ftp", - "ftps", - "tftp", - "ssh", - "vxhs", - "nfs", -); - -VIR_ENUM_IMPL(virStorageNetHostTransport, - VIR_STORAGE_NET_HOST_TRANS_LAST, - "tcp", - "unix", - "rdma", -); - -VIR_ENUM_IMPL(virStorageSourcePoolMode, - VIR_STORAGE_SOURCE_POOL_MODE_LAST, - "default", - "host", - "direct", -); - -VIR_ENUM_IMPL(virStorageAuth, - VIR_STORAGE_AUTH_TYPE_LAST, - "none", "chap", "ceph", -); - bool virStorageIsFile(const char *backing) @@ -278,6 +208,7 @@ int virStorageFileGetNPIVKey(const char *path G_GNUC_UNUSED, } #endif + /** * virStorageFileParseBackingStoreStr: * @str: backing store specifier string to parse @@ -351,1089 +282,6 @@ virStorageFileParseChainIndex(const char *diskTarget, } -/** - * virStorageSourceIsBacking: - * @src: storage source - * - * Returns true if @src is a eligible backing store structure. Useful - * for iterators. - */ -bool -virStorageSourceIsBacking(const virStorageSource *src) -{ - return src && src->type != VIR_STORAGE_TYPE_NONE; -} - -/** - * virStorageSourceHasBacking: - * @src: storage source - * - * Returns true if @src has backing store/chain. - */ -bool -virStorageSourceHasBacking(const virStorageSource *src) -{ - return virStorageSourceIsBacking(src) && src->backingStore && - src->backingStore->type != VIR_STORAGE_TYPE_NONE; -} - - -void -virStorageNetHostDefClear(virStorageNetHostDefPtr def) -{ - if (!def) - return; - - VIR_FREE(def->name); - VIR_FREE(def->socket); -} - - -void -virStorageNetHostDefFree(size_t nhosts, - virStorageNetHostDefPtr hosts) -{ - size_t i; - - if (!hosts) - return; - - for (i = 0; i < nhosts; i++) - virStorageNetHostDefClear(&hosts[i]); - - VIR_FREE(hosts); -} - - -static void -virStoragePermsFree(virStoragePermsPtr def) -{ - if (!def) - return; - - VIR_FREE(def->label); - VIR_FREE(def); -} - - -virStorageNetHostDefPtr -virStorageNetHostDefCopy(size_t nhosts, - virStorageNetHostDefPtr hosts) -{ - virStorageNetHostDefPtr ret = NULL; - size_t i; - - ret = g_new0(virStorageNetHostDef, nhosts); - - for (i = 0; i < nhosts; i++) { - virStorageNetHostDefPtr src = &hosts[i]; - virStorageNetHostDefPtr dst = &ret[i]; - - dst->transport = src->transport; - dst->port = src->port; - - dst->name = g_strdup(src->name); - dst->socket = g_strdup(src->socket); - } - - return ret; -} - - -void -virStorageAuthDefFree(virStorageAuthDefPtr authdef) -{ - if (!authdef) - return; - - VIR_FREE(authdef->username); - VIR_FREE(authdef->secrettype); - virSecretLookupDefClear(&authdef->seclookupdef); - VIR_FREE(authdef); -} - - -virStorageAuthDefPtr -virStorageAuthDefCopy(const virStorageAuthDef *src) -{ - g_autoptr(virStorageAuthDef) authdef = NULL; - - authdef = g_new0(virStorageAuthDef, 1); - - authdef->username = g_strdup(src->username); - /* Not present for storage pool, but used for disk source */ - authdef->secrettype = g_strdup(src->secrettype); - authdef->authType = src->authType; - - virSecretLookupDefCopy(&authdef->seclookupdef, &src->seclookupdef); - - return g_steal_pointer(&authdef); -} - - -virStorageAuthDefPtr -virStorageAuthDefParse(xmlNodePtr node, - xmlXPathContextPtr ctxt) -{ - VIR_XPATH_NODE_AUTORESTORE(ctxt) - virStorageAuthDefPtr ret = NULL; - xmlNodePtr secretnode = NULL; - g_autoptr(virStorageAuthDef) authdef = NULL; - g_autofree char *authtype = NULL; - - ctxt->node = node; - - authdef = g_new0(virStorageAuthDef, 1); - - if (!(authdef->username = virXPathString("string(./@username)", ctxt))) { - virReportError(VIR_ERR_XML_ERROR, "%s", - _("missing username for auth")); - goto cleanup; - } - - authdef->authType = VIR_STORAGE_AUTH_TYPE_NONE; - authtype = virXPathString("string(./@type)", ctxt); - if (authtype) { - /* Used by the storage pool instead of the secret type field - * to define whether chap or ceph being used - */ - if ((authdef->authType = virStorageAuthTypeFromString(authtype)) < 0) { - virReportError(VIR_ERR_CONFIG_UNSUPPORTED, - _("unknown auth type '%s'"), authtype); - goto cleanup; - } - } - - if (!(secretnode = virXPathNode("./secret ", ctxt))) { - virReportError(VIR_ERR_XML_ERROR, "%s", - _("Missing <secret> element in auth")); - goto cleanup; - } - - /* Used by the domain disk xml parsing in order to ensure the - * <secret type='%s' value matches the expected secret type for - * the style of disk (iscsi is chap, nbd is ceph). For some reason - * the virSecretUsageType{From|To}String() cannot be linked here - * and because only the domain parsing code cares - just keep - * it as a string. - */ - authdef->secrettype = virXMLPropString(secretnode, "type"); - - if (virSecretLookupParseSecret(secretnode, &authdef->seclookupdef) < 0) - goto cleanup; - - ret = g_steal_pointer(&authdef); - - cleanup: - - return ret; -} - - -void -virStorageAuthDefFormat(virBufferPtr buf, - virStorageAuthDefPtr authdef) -{ - if (authdef->authType == VIR_STORAGE_AUTH_TYPE_NONE) { - virBufferEscapeString(buf, "<auth username='%s'>\n", authdef->username); - } else { - virBufferAsprintf(buf, "<auth type='%s' ", - virStorageAuthTypeToString(authdef->authType)); - virBufferEscapeString(buf, "username='%s'>\n", authdef->username); - } - - virBufferAdjustIndent(buf, 2); - virSecretLookupFormatSecret(buf, authdef->secrettype, - &authdef->seclookupdef); - virBufferAdjustIndent(buf, -2); - virBufferAddLit(buf, "</auth>\n"); -} - - -void -virStoragePRDefFree(virStoragePRDefPtr prd) -{ - if (!prd) - return; - - VIR_FREE(prd->path); - VIR_FREE(prd->mgralias); - VIR_FREE(prd); -} - - -virStoragePRDefPtr -virStoragePRDefParseXML(xmlXPathContextPtr ctxt) -{ - virStoragePRDefPtr prd; - virStoragePRDefPtr ret = NULL; - g_autofree char *managed = NULL; - g_autofree char *type = NULL; - g_autofree char *path = NULL; - g_autofree char *mode = NULL; - - prd = g_new0(virStoragePRDef, 1); - - if (!(managed = virXPathString("string(./@managed)", ctxt))) { - virReportError(VIR_ERR_XML_ERROR, "%s", - _("missing @managed attribute for <reservations/>")); - goto cleanup; - } - - if ((prd->managed = virTristateBoolTypeFromString(managed)) <= 0) { - virReportError(VIR_ERR_XML_ERROR, - _("invalid value for 'managed': %s"), managed); - goto cleanup; - } - - type = virXPathString("string(./source[1]/@type)", ctxt); - path = virXPathString("string(./source[1]/@path)", ctxt); - mode = virXPathString("string(./source[1]/@mode)", ctxt); - - if (prd->managed == VIR_TRISTATE_BOOL_NO || type || path || mode) { - if (!type) { - virReportError(VIR_ERR_XML_ERROR, "%s", - _("missing connection type for <reservations/>")); - goto cleanup; - } - - if (!path) { - virReportError(VIR_ERR_XML_ERROR, "%s", - _("missing path for <reservations/>")); - goto cleanup; - } - - if (!mode) { - virReportError(VIR_ERR_XML_ERROR, "%s", - _("missing connection mode for <reservations/>")); - goto cleanup; - } - } - - if (type && STRNEQ(type, "unix")) { - virReportError(VIR_ERR_XML_ERROR, - _("unsupported connection type for <reservations/>: %s"), - type); - goto cleanup; - } - - if (mode && STRNEQ(mode, "client")) { - virReportError(VIR_ERR_XML_ERROR, - _("unsupported connection mode for <reservations/>: %s"), - mode); - goto cleanup; - } - - prd->path = g_steal_pointer(&path); - ret = g_steal_pointer(&prd); - - cleanup: - virStoragePRDefFree(prd); - return ret; -} - - -void -virStoragePRDefFormat(virBufferPtr buf, - virStoragePRDefPtr prd, - bool migratable) -{ - virBufferAsprintf(buf, "<reservations managed='%s'", - virTristateBoolTypeToString(prd->managed)); - if (prd->path && - (prd->managed == VIR_TRISTATE_BOOL_NO || !migratable)) { - virBufferAddLit(buf, ">\n"); - virBufferAdjustIndent(buf, 2); - virBufferAddLit(buf, "<source type='unix'"); - virBufferEscapeString(buf, " path='%s'", prd->path); - virBufferAddLit(buf, " mode='client'/>\n"); - virBufferAdjustIndent(buf, -2); - virBufferAddLit(buf, "</reservations>\n"); - } else { - virBufferAddLit(buf, "/>\n"); - } -} - - -bool -virStoragePRDefIsEqual(virStoragePRDefPtr a, - virStoragePRDefPtr b) -{ - if (!a && !b) - return true; - - if (!a || !b) - return false; - - if (a->managed != b->managed || - STRNEQ_NULLABLE(a->path, b->path)) - return false; - - return true; -} - - -bool -virStoragePRDefIsManaged(virStoragePRDefPtr prd) -{ - return prd && prd->managed == VIR_TRISTATE_BOOL_YES; -} - - -bool -virStorageSourceChainHasManagedPR(virStorageSourcePtr src) -{ - virStorageSourcePtr n; - - for (n = src; virStorageSourceIsBacking(n); n = n->backingStore) { - if (virStoragePRDefIsManaged(n->pr)) - return true; - } - - return false; -} - - -static virStoragePRDefPtr -virStoragePRDefCopy(virStoragePRDefPtr src) -{ - virStoragePRDefPtr copy = NULL; - virStoragePRDefPtr ret = NULL; - - copy = g_new0(virStoragePRDef, 1); - - copy->managed = src->managed; - - copy->path = g_strdup(src->path); - copy->mgralias = g_strdup(src->mgralias); - - ret = g_steal_pointer(©); - - virStoragePRDefFree(copy); - return ret; -} - - -static virStorageSourceNVMeDefPtr -virStorageSourceNVMeDefCopy(const virStorageSourceNVMeDef *src) -{ - virStorageSourceNVMeDefPtr ret = NULL; - - ret = g_new0(virStorageSourceNVMeDef, 1); - - ret->namespc = src->namespc; - ret->managed = src->managed; - virPCIDeviceAddressCopy(&ret->pciAddr, &src->pciAddr); - return ret; -} - - -static bool -virStorageSourceNVMeDefIsEqual(const virStorageSourceNVMeDef *a, - const virStorageSourceNVMeDef *b) -{ - if (!a && !b) - return true; - - if (!a || !b) - return false; - - if (a->namespc != b->namespc || - a->managed != b->managed || - !virPCIDeviceAddressEqual(&a->pciAddr, &b->pciAddr)) - return false; - - return true; -} - - -void -virStorageSourceNVMeDefFree(virStorageSourceNVMeDefPtr def) -{ - if (!def) - return; - - VIR_FREE(def); -} - - -bool -virStorageSourceChainHasNVMe(const virStorageSource *src) -{ - const virStorageSource *n; - - for (n = src; virStorageSourceIsBacking(n); n = n->backingStore) { - if (n->type == VIR_STORAGE_TYPE_NVME) - return true; - } - - return false; -} - - -virSecurityDeviceLabelDefPtr -virStorageSourceGetSecurityLabelDef(virStorageSourcePtr src, - const char *model) -{ - size_t i; - - for (i = 0; i < src->nseclabels; i++) { - if (STREQ_NULLABLE(src->seclabels[i]->model, model)) - return src->seclabels[i]; - } - - return NULL; -} - - -static void -virStorageSourceSeclabelsClear(virStorageSourcePtr def) -{ - size_t i; - - if (def->seclabels) { - for (i = 0; i < def->nseclabels; i++) - virSecurityDeviceLabelDefFree(def->seclabels[i]); - VIR_FREE(def->seclabels); - } -} - - -static int -virStorageSourceSeclabelsCopy(virStorageSourcePtr to, - const virStorageSource *from) -{ - size_t i; - - if (from->nseclabels == 0) - return 0; - - to->seclabels = g_new0(virSecurityDeviceLabelDefPtr, from->nseclabels); - to->nseclabels = from->nseclabels; - - for (i = 0; i < to->nseclabels; i++) { - if (!(to->seclabels[i] = virSecurityDeviceLabelDefCopy(from->seclabels[i]))) - goto error; - } - - return 0; - - error: - virStorageSourceSeclabelsClear(to); - return -1; -} - - -void -virStorageNetCookieDefFree(virStorageNetCookieDefPtr def) -{ - if (!def) - return; - - g_free(def->name); - g_free(def->value); - - g_free(def); -} - - -static void -virStorageSourceNetCookiesClear(virStorageSourcePtr src) -{ - size_t i; - - if (!src || !src->cookies) - return; - - for (i = 0; i < src->ncookies; i++) - virStorageNetCookieDefFree(src->cookies[i]); - - g_clear_pointer(&src->cookies, g_free); - src->ncookies = 0; -} - - -static void -virStorageSourceNetCookiesCopy(virStorageSourcePtr to, - const virStorageSource *from) -{ - size_t i; - - if (from->ncookies == 0) - return; - - to->cookies = g_new0(virStorageNetCookieDefPtr, from->ncookies); - to->ncookies = from->ncookies; - - for (i = 0; i < from->ncookies; i++) { - to->cookies[i]->name = g_strdup(from->cookies[i]->name); - to->cookies[i]->value = g_strdup(from->cookies[i]->value); - } -} - - -/* see https://tools.ietf.org/html/rfc6265#section-4.1.1 */ -static const char virStorageSourceCookieValueInvalidChars[] = - "\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F" - "\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1A\x1B\x1C\x1D\x1E\x1F" - " \",;\\"; - -/* in addition cookie name can't contain these */ -static const char virStorageSourceCookieNameInvalidChars[] = - "()<>@:/[]?={}"; - -static int -virStorageSourceNetCookieValidate(virStorageNetCookieDefPtr def) -{ - g_autofree char *val = g_strdup(def->value); - const char *checkval = val; - size_t len = strlen(val); - - /* name must have at least 1 character */ - if (*(def->name) == '\0') { - virReportError(VIR_ERR_XML_ERROR, "%s", - _("cookie name must not be empty")); - return -1; - } - - /* check invalid characters in name */ - if (virStringHasChars(def->name, virStorageSourceCookieValueInvalidChars) || - virStringHasChars(def->name, virStorageSourceCookieNameInvalidChars)) { - virReportError(VIR_ERR_XML_ERROR, - _("cookie name '%s' contains invalid characters"), - def->name); - return -1; - } - - /* check for optional quotes around the cookie value string */ - if (val[0] == '"') { - if (val[len - 1] != '"') { - virReportError(VIR_ERR_XML_ERROR, - _("value of cookie '%s' contains invalid characters"), - def->name); - return -1; - } - - val[len - 1] = '\0'; - checkval++; - } - - /* check invalid characters in value */ - if (virStringHasChars(checkval, virStorageSourceCookieValueInvalidChars)) { - virReportError(VIR_ERR_XML_ERROR, - _("value of cookie '%s' contains invalid characters"), - def->name); - return -1; - } - - return 0; -} - - -int -virStorageSourceNetCookiesValidate(virStorageSourcePtr src) -{ - size_t i; - size_t j; - - for (i = 0; i < src->ncookies; i++) { - if (virStorageSourceNetCookieValidate(src->cookies[i]) < 0) - return -1; - - for (j = i + 1; j < src->ncookies; j++) { - if (STREQ(src->cookies[i]->name, src->cookies[j]->name)) { - virReportError(VIR_ERR_XML_ERROR, _("duplicate cookie '%s'"), - src->cookies[i]->name); - return -1; - } - } - } - - return 0; -} - - -static virStorageTimestampsPtr -virStorageTimestampsCopy(const virStorageTimestamps *src) -{ - virStorageTimestampsPtr ret; - - ret = g_new0(virStorageTimestamps, 1); - - memcpy(ret, src, sizeof(*src)); - - return ret; -} - - -static virStoragePermsPtr -virStoragePermsCopy(const virStoragePerms *src) -{ - virStoragePermsPtr ret; - - ret = g_new0(virStoragePerms, 1); - - ret->mode = src->mode; - ret->uid = src->uid; - ret->gid = src->gid; - - ret->label = g_strdup(src->label); - - return ret; -} - - -static virStorageSourcePoolDefPtr -virStorageSourcePoolDefCopy(const virStorageSourcePoolDef *src) -{ - virStorageSourcePoolDefPtr ret; - - ret = g_new0(virStorageSourcePoolDef, 1); - - ret->voltype = src->voltype; - ret->pooltype = src->pooltype; - ret->actualtype = src->actualtype; - ret->mode = src->mode; - - ret->pool = g_strdup(src->pool); - ret->volume = g_strdup(src->volume); - - return ret; -} - - -static virStorageSourceSlicePtr -virStorageSourceSliceCopy(const virStorageSourceSlice *src) -{ - virStorageSourceSlicePtr ret = g_new0(virStorageSourceSlice, 1); - - ret->offset = src->offset; - ret->size = src->size; - ret->nodename = g_strdup(src->nodename); - - return ret; -} - - -static void -virStorageSourceSliceFree(virStorageSourceSlicePtr slice) -{ - if (!slice) - return; - - g_free(slice->nodename); - g_free(slice); -} - - -/** - * virStorageSourcePtr: - * - * Deep-copies a virStorageSource structure. If @backing chain is true - * then also copies the backing chain recursively, otherwise just - * the top element is copied. This function doesn't copy the - * storage driver access structure and thus the struct needs to be initialized - * separately. - */ -virStorageSourcePtr -virStorageSourceCopy(const virStorageSource *src, - bool backingChain) -{ - g_autoptr(virStorageSource) def = virStorageSourceNew(); - - def->id = src->id; - def->type = src->type; - def->protocol = src->protocol; - def->format = src->format; - def->capacity = src->capacity; - def->allocation = src->allocation; - def->has_allocation = src->has_allocation; - def->physical = src->physical; - def->readonly = src->readonly; - def->shared = src->shared; - def->haveTLS = src->haveTLS; - def->tlsFromConfig = src->tlsFromConfig; - def->detected = src->detected; - def->debugLevel = src->debugLevel; - def->debug = src->debug; - def->iomode = src->iomode; - def->cachemode = src->cachemode; - def->discard = src->discard; - def->detect_zeroes = src->detect_zeroes; - def->sslverify = src->sslverify; - def->readahead = src->readahead; - def->timeout = src->timeout; - def->metadataCacheMaxSize = src->metadataCacheMaxSize; - - /* storage driver metadata are not copied */ - def->drv = NULL; - - def->path = g_strdup(src->path); - def->volume = g_strdup(src->volume); - def->relPath = g_strdup(src->relPath); - def->backingStoreRaw = g_strdup(src->backingStoreRaw); - def->backingStoreRawFormat = src->backingStoreRawFormat; - def->snapshot = g_strdup(src->snapshot); - def->configFile = g_strdup(src->configFile); - def->nodeformat = g_strdup(src->nodeformat); - def->nodestorage = g_strdup(src->nodestorage); - def->compat = g_strdup(src->compat); - def->tlsAlias = g_strdup(src->tlsAlias); - def->tlsCertdir = g_strdup(src->tlsCertdir); - def->query = g_strdup(src->query); - - if (src->sliceStorage) - def->sliceStorage = virStorageSourceSliceCopy(src->sliceStorage); - - if (src->nhosts) { - if (!(def->hosts = virStorageNetHostDefCopy(src->nhosts, src->hosts))) - return NULL; - - def->nhosts = src->nhosts; - } - - virStorageSourceNetCookiesCopy(def, src); - - if (src->srcpool && - !(def->srcpool = virStorageSourcePoolDefCopy(src->srcpool))) - return NULL; - - if (src->features) - def->features = virBitmapNewCopy(src->features); - - if (src->encryption && - !(def->encryption = virStorageEncryptionCopy(src->encryption))) - return NULL; - - if (src->perms && - !(def->perms = virStoragePermsCopy(src->perms))) - return NULL; - - if (src->timestamps && - !(def->timestamps = virStorageTimestampsCopy(src->timestamps))) - return NULL; - - if (virStorageSourceSeclabelsCopy(def, src) < 0) - return NULL; - - if (src->auth && - !(def->auth = virStorageAuthDefCopy(src->auth))) - return NULL; - - if (src->pr && - !(def->pr = virStoragePRDefCopy(src->pr))) - return NULL; - - if (src->nvme) - def->nvme = virStorageSourceNVMeDefCopy(src->nvme); - - if (virStorageSourceInitiatorCopy(&def->initiator, &src->initiator) < 0) - return NULL; - - if (backingChain && src->backingStore) { - if (!(def->backingStore = virStorageSourceCopy(src->backingStore, - true))) - return NULL; - } - - /* ssh config passthrough for libguestfs */ - def->ssh_host_key_check_disabled = src->ssh_host_key_check_disabled; - def->ssh_user = g_strdup(src->ssh_user); - - def->nfs_user = g_strdup(src->nfs_user); - def->nfs_group = g_strdup(src->nfs_group); - def->nfs_uid = src->nfs_uid; - def->nfs_gid = src->nfs_gid; - - return g_steal_pointer(&def); -} - - -/** - * virStorageSourceIsSameLocation: - * - * Returns true if the sources @a and @b point to the same storage location. - * This does not compare any other configuration option - */ -bool -virStorageSourceIsSameLocation(virStorageSourcePtr a, - virStorageSourcePtr b) -{ - size_t i; - - /* there are multiple possibilities to define an empty source */ - if (virStorageSourceIsEmpty(a) && - virStorageSourceIsEmpty(b)) - return true; - - if (virStorageSourceGetActualType(a) != virStorageSourceGetActualType(b)) - return false; - - if (STRNEQ_NULLABLE(a->path, b->path) || - STRNEQ_NULLABLE(a->volume, b->volume) || - STRNEQ_NULLABLE(a->snapshot, b->snapshot)) - return false; - - if (a->type == VIR_STORAGE_TYPE_NETWORK) { - if (a->protocol != b->protocol || - a->nhosts != b->nhosts) - return false; - - for (i = 0; i < a->nhosts; i++) { - if (a->hosts[i].transport != b->hosts[i].transport || - a->hosts[i].port != b->hosts[i].port || - STRNEQ_NULLABLE(a->hosts[i].name, b->hosts[i].name) || - STRNEQ_NULLABLE(a->hosts[i].socket, b->hosts[i].socket)) - return false; - } - } - - if (a->type == VIR_STORAGE_TYPE_NVME && - !virStorageSourceNVMeDefIsEqual(a->nvme, b->nvme)) - return false; - - return true; -} - - -/** - * virStorageSourceInitChainElement: - * @newelem: New backing chain element disk source - * @old: Existing top level disk source - * @transferLabels: Transfer security labels. - * - * Transfers relevant information from the existing disk source to the new - * backing chain element if they weren't supplied so that labelling info - * and possibly other stuff is correct. - * - * If @transferLabels is true, security labels from the existing disk are copied - * to the new disk. Otherwise the default domain imagelabel label will be used. - * - * Returns 0 on success, -1 on error. - */ -int -virStorageSourceInitChainElement(virStorageSourcePtr newelem, - virStorageSourcePtr old, - bool transferLabels) -{ - if (transferLabels && - !newelem->seclabels && - virStorageSourceSeclabelsCopy(newelem, old) < 0) - return -1; - - newelem->shared = old->shared; - newelem->readonly = old->readonly; - - return 0; -} - - -void -virStorageSourcePoolDefFree(virStorageSourcePoolDefPtr def) -{ - if (!def) - return; - - VIR_FREE(def->pool); - VIR_FREE(def->volume); - - VIR_FREE(def); -} - - -/** - * virStorageSourceGetActualType: - * @def: storage source definition - * - * Returns type of @def. In case when the type is VIR_STORAGE_TYPE_VOLUME - * and virDomainDiskTranslateSourcePool was called on @def the actual type - * of the storage volume is returned rather than VIR_STORAGE_TYPE_VOLUME. - */ -int -virStorageSourceGetActualType(const virStorageSource *def) -{ - if (def->type == VIR_STORAGE_TYPE_VOLUME && - def->srcpool && - def->srcpool->actualtype != VIR_STORAGE_TYPE_NONE) - return def->srcpool->actualtype; - - return def->type; -} - - -bool -virStorageSourceIsLocalStorage(const virStorageSource *src) -{ - virStorageType type = virStorageSourceGetActualType(src); - - switch (type) { - case VIR_STORAGE_TYPE_FILE: - case VIR_STORAGE_TYPE_BLOCK: - case VIR_STORAGE_TYPE_DIR: - return true; - - case VIR_STORAGE_TYPE_NETWORK: - case VIR_STORAGE_TYPE_VOLUME: - /* While NVMe disks are local, they are not accessible via src->path. - * Therefore, we have to return false here. */ - case VIR_STORAGE_TYPE_NVME: - case VIR_STORAGE_TYPE_LAST: - case VIR_STORAGE_TYPE_NONE: - return false; - } - - return false; -} - - -/** - * virStorageSourceIsEmpty: - * - * @src: disk source to check - * - * Returns true if the guest disk has no associated host storage source - * (such as an empty cdrom drive). - */ -bool -virStorageSourceIsEmpty(virStorageSourcePtr src) -{ - if (virStorageSourceIsLocalStorage(src) && !src->path) - return true; - - if (src->type == VIR_STORAGE_TYPE_NONE) - return true; - - if (src->type == VIR_STORAGE_TYPE_NETWORK && - src->protocol == VIR_STORAGE_NET_PROTOCOL_NONE) - return true; - - return false; -} - - -/** - * virStorageSourceIsBlockLocal: - * @src: disk source definition - * - * Returns true if @src describes a locally accessible block storage source. - * This includes block devices and host-mapped iSCSI volumes. - */ -bool -virStorageSourceIsBlockLocal(const virStorageSource *src) -{ - return virStorageSourceGetActualType(src) == VIR_STORAGE_TYPE_BLOCK; -} - - -/** - * virStorageSourceBackingStoreClear: - * - * @src: disk source to clear - * - * Clears information about backing store of the current storage file. - */ -void -virStorageSourceBackingStoreClear(virStorageSourcePtr def) -{ - if (!def) - return; - - VIR_FREE(def->relPath); - VIR_FREE(def->backingStoreRaw); - - /* recursively free backing chain */ - virObjectUnref(def->backingStore); - def->backingStore = NULL; -} - - -void -virStorageSourceClear(virStorageSourcePtr def) -{ - if (!def) - return; - - VIR_FREE(def->path); - VIR_FREE(def->volume); - VIR_FREE(def->snapshot); - VIR_FREE(def->configFile); - VIR_FREE(def->query); - virStorageSourceNetCookiesClear(def); - virStorageSourcePoolDefFree(def->srcpool); - virBitmapFree(def->features); - VIR_FREE(def->compat); - virStorageEncryptionFree(def->encryption); - virStoragePRDefFree(def->pr); - virStorageSourceNVMeDefFree(def->nvme); - virStorageSourceSeclabelsClear(def); - virStoragePermsFree(def->perms); - VIR_FREE(def->timestamps); - - virStorageSourceSliceFree(def->sliceStorage); - - virStorageNetHostDefFree(def->nhosts, def->hosts); - virStorageAuthDefFree(def->auth); - virObjectUnref(def->privateData); - - VIR_FREE(def->nodestorage); - VIR_FREE(def->nodeformat); - - virStorageSourceBackingStoreClear(def); - - VIR_FREE(def->tlsAlias); - VIR_FREE(def->tlsCertdir); - - VIR_FREE(def->ssh_user); - - VIR_FREE(def->nfs_user); - VIR_FREE(def->nfs_group); - - virStorageSourceInitiatorClear(&def->initiator); - - /* clear everything except the class header as the object APIs - * will break otherwise */ - memset((char *) def + sizeof(def->parent), 0, - sizeof(*def) - sizeof(def->parent)); -} - - -static void -virStorageSourceDispose(void *obj) -{ - virStorageSourcePtr src = obj; - - virStorageSourceClear(src); -} - - -static int -virStorageSourceOnceInit(void) -{ - if (!VIR_CLASS_NEW(virStorageSource, virClassForObject())) - return -1; - - return 0; -} - - -VIR_ONCE_GLOBAL_INIT(virStorageSource); - - -virStorageSourcePtr -virStorageSourceNew(void) -{ - virStorageSourcePtr ret; - - if (virStorageSourceInitialize() < 0) - abort(); - - if (!(ret = virObjectNew(virStorageSourceClass))) - abort(); - - return ret; -} - - static char * virStorageFileCanonicalizeFormatPath(char **components, size_t ncomponents, @@ -1642,157 +490,3 @@ virStorageFileCanonicalizePath(const char *path, return ret; } - - -/** - * virStorageSourceIsRelative: - * @src: storage source to check - * - * Returns true if given storage source definition is a relative path. - */ -bool -virStorageSourceIsRelative(virStorageSourcePtr src) -{ - virStorageType actual_type = virStorageSourceGetActualType(src); - - if (!src->path) - return false; - - switch (actual_type) { - case VIR_STORAGE_TYPE_FILE: - case VIR_STORAGE_TYPE_BLOCK: - case VIR_STORAGE_TYPE_DIR: - return src->path[0] != '/'; - - case VIR_STORAGE_TYPE_NETWORK: - case VIR_STORAGE_TYPE_VOLUME: - case VIR_STORAGE_TYPE_NVME: - case VIR_STORAGE_TYPE_NONE: - case VIR_STORAGE_TYPE_LAST: - return false; - } - - return false; -} - - -static unsigned int -virStorageSourceNetworkDefaultPort(virStorageNetProtocol protocol) -{ - switch (protocol) { - case VIR_STORAGE_NET_PROTOCOL_HTTP: - return 80; - - case VIR_STORAGE_NET_PROTOCOL_HTTPS: - return 443; - - case VIR_STORAGE_NET_PROTOCOL_FTP: - return 21; - - case VIR_STORAGE_NET_PROTOCOL_FTPS: - return 990; - - case VIR_STORAGE_NET_PROTOCOL_TFTP: - return 69; - - case VIR_STORAGE_NET_PROTOCOL_SHEEPDOG: - return 7000; - - case VIR_STORAGE_NET_PROTOCOL_NBD: - return 10809; - - case VIR_STORAGE_NET_PROTOCOL_SSH: - return 22; - - case VIR_STORAGE_NET_PROTOCOL_ISCSI: - return 3260; - - case VIR_STORAGE_NET_PROTOCOL_GLUSTER: - return 24007; - - case VIR_STORAGE_NET_PROTOCOL_RBD: - /* we don't provide a default for RBD */ - return 0; - - case VIR_STORAGE_NET_PROTOCOL_VXHS: - return 9999; - - case VIR_STORAGE_NET_PROTOCOL_NFS: - /* Port is not supported by NFS, so no default is provided */ - return 0; - - case VIR_STORAGE_NET_PROTOCOL_LAST: - case VIR_STORAGE_NET_PROTOCOL_NONE: - return 0; - } - - return 0; -} - - -void -virStorageSourceNetworkAssignDefaultPorts(virStorageSourcePtr src) -{ - size_t i; - - for (i = 0; i < src->nhosts; i++) { - if (src->hosts[i].transport == VIR_STORAGE_NET_HOST_TRANS_TCP && - src->hosts[i].port == 0) - src->hosts[i].port = virStorageSourceNetworkDefaultPort(src->protocol); - } -} - - -int -virStorageSourcePrivateDataParseRelPath(xmlXPathContextPtr ctxt, - virStorageSourcePtr src) -{ - src->relPath = virXPathString("string(./relPath)", ctxt); - return 0; -} - - -int -virStorageSourcePrivateDataFormatRelPath(virStorageSourcePtr src, - virBufferPtr buf) -{ - if (src->relPath) - virBufferEscapeString(buf, "<relPath>%s</relPath>\n", src->relPath); - - return 0; -} - -void -virStorageSourceInitiatorParseXML(xmlXPathContextPtr ctxt, - virStorageSourceInitiatorDefPtr initiator) -{ - initiator->iqn = virXPathString("string(./initiator/iqn/@name)", ctxt); -} - -void -virStorageSourceInitiatorFormatXML(virStorageSourceInitiatorDefPtr initiator, - virBufferPtr buf) -{ - if (!initiator->iqn) - return; - - virBufferAddLit(buf, "<initiator>\n"); - virBufferAdjustIndent(buf, 2); - virBufferEscapeString(buf, "<iqn name='%s'/>\n", initiator->iqn); - virBufferAdjustIndent(buf, -2); - virBufferAddLit(buf, "</initiator>\n"); -} - -int -virStorageSourceInitiatorCopy(virStorageSourceInitiatorDefPtr dest, - const virStorageSourceInitiatorDef *src) -{ - dest->iqn = g_strdup(src->iqn); - return 0; -} - -void -virStorageSourceInitiatorClear(virStorageSourceInitiatorDefPtr initiator) -{ - VIR_FREE(initiator->iqn); -} diff --git a/src/util/virstoragefile.h b/src/util/virstoragefile.h index d6f194a7dd..2c1a250f20 100644 --- a/src/util/virstoragefile.h +++ b/src/util/virstoragefile.h @@ -21,372 +21,7 @@ #pragma once -#include <sys/stat.h> - -#include "virbitmap.h" -#include "virobject.h" -#include "virseclabel.h" -#include "virstorageencryption.h" -#include "virsecret.h" -#include "virenum.h" -#include "virpci.h" - -/* Types of disk backends (host resource). Comparable to the public - * virStorageVolType, except we have an undetermined state, don't have - * a netdir type, and add a volume type for reference through a - * storage pool. */ -typedef enum { - VIR_STORAGE_TYPE_NONE, - VIR_STORAGE_TYPE_FILE, - VIR_STORAGE_TYPE_BLOCK, - VIR_STORAGE_TYPE_DIR, - VIR_STORAGE_TYPE_NETWORK, - VIR_STORAGE_TYPE_VOLUME, - VIR_STORAGE_TYPE_NVME, - - VIR_STORAGE_TYPE_LAST -} virStorageType; - -VIR_ENUM_DECL(virStorage); - - -typedef enum { - VIR_STORAGE_FILE_AUTO_SAFE = -2, - VIR_STORAGE_FILE_AUTO = -1, - VIR_STORAGE_FILE_NONE = 0, - VIR_STORAGE_FILE_RAW, - VIR_STORAGE_FILE_DIR, - VIR_STORAGE_FILE_BOCHS, - VIR_STORAGE_FILE_CLOOP, - VIR_STORAGE_FILE_DMG, - VIR_STORAGE_FILE_ISO, - VIR_STORAGE_FILE_VPC, - VIR_STORAGE_FILE_VDI, - - /* Not direct file formats, but used for various drivers */ - VIR_STORAGE_FILE_FAT, - VIR_STORAGE_FILE_VHD, - VIR_STORAGE_FILE_PLOOP, - - /* Not a format, but a marker: all formats below this point have - * libvirt support for following a backing chain */ - VIR_STORAGE_FILE_BACKING, - - VIR_STORAGE_FILE_COW = VIR_STORAGE_FILE_BACKING, - VIR_STORAGE_FILE_QCOW, - VIR_STORAGE_FILE_QCOW2, - VIR_STORAGE_FILE_QED, - VIR_STORAGE_FILE_VMDK, - - VIR_STORAGE_FILE_LAST, -} virStorageFileFormat; - -VIR_ENUM_DECL(virStorageFileFormat); - -typedef enum { - VIR_STORAGE_FILE_FEATURE_LAZY_REFCOUNTS = 0, - - VIR_STORAGE_FILE_FEATURE_LAST -} virStorageFileFeature; - -VIR_ENUM_DECL(virStorageFileFeature); - -typedef struct _virStoragePerms virStoragePerms; -typedef virStoragePerms *virStoragePermsPtr; -struct _virStoragePerms { - mode_t mode; - uid_t uid; - gid_t gid; - char *label; -}; - - -typedef struct _virStorageTimestamps virStorageTimestamps; -typedef virStorageTimestamps *virStorageTimestampsPtr; -struct _virStorageTimestamps { - struct timespec atime; - struct timespec btime; /* birth time unknown if btime.tv_nsec == -1 */ - struct timespec ctime; - struct timespec mtime; -}; - - -/* Information related to network storage */ -typedef enum { - VIR_STORAGE_NET_PROTOCOL_NONE, - VIR_STORAGE_NET_PROTOCOL_NBD, - VIR_STORAGE_NET_PROTOCOL_RBD, - VIR_STORAGE_NET_PROTOCOL_SHEEPDOG, - VIR_STORAGE_NET_PROTOCOL_GLUSTER, - VIR_STORAGE_NET_PROTOCOL_ISCSI, - VIR_STORAGE_NET_PROTOCOL_HTTP, - VIR_STORAGE_NET_PROTOCOL_HTTPS, - VIR_STORAGE_NET_PROTOCOL_FTP, - VIR_STORAGE_NET_PROTOCOL_FTPS, - VIR_STORAGE_NET_PROTOCOL_TFTP, - VIR_STORAGE_NET_PROTOCOL_SSH, - VIR_STORAGE_NET_PROTOCOL_VXHS, - VIR_STORAGE_NET_PROTOCOL_NFS, - - VIR_STORAGE_NET_PROTOCOL_LAST -} virStorageNetProtocol; - -VIR_ENUM_DECL(virStorageNetProtocol); - - -typedef enum { - VIR_STORAGE_NET_HOST_TRANS_TCP, - VIR_STORAGE_NET_HOST_TRANS_UNIX, - VIR_STORAGE_NET_HOST_TRANS_RDMA, - - VIR_STORAGE_NET_HOST_TRANS_LAST -} virStorageNetHostTransport; - -VIR_ENUM_DECL(virStorageNetHostTransport); - -typedef struct _virStorageNetHostDef virStorageNetHostDef; -typedef virStorageNetHostDef *virStorageNetHostDefPtr; -struct _virStorageNetHostDef { - char *name; - unsigned int port; - int transport; /* virStorageNetHostTransport */ - char *socket; /* path to unix socket */ -}; - -typedef struct _virStorageNetCookieDef virStorageNetCookieDef; -typedef virStorageNetCookieDef *virStorageNetCookieDefPtr; -struct _virStorageNetCookieDef { - char *name; - char *value; -}; - -void virStorageNetCookieDefFree(virStorageNetCookieDefPtr def); - -G_DEFINE_AUTOPTR_CLEANUP_FUNC(virStorageNetCookieDef, virStorageNetCookieDefFree); - -/* Information for a storage volume from a virStoragePool */ - -/* - * Used for volume "type" disk to indicate how to represent - * the disk source if the specified "pool" is of iscsi type. - */ -typedef enum { - VIR_STORAGE_SOURCE_POOL_MODE_DEFAULT = 0, - - /* Use the path as it shows up on host, e.g. - * /dev/disk/by-path/ip-$ip-iscsi-$iqn:iscsi.iscsi-pool0-lun-1 - */ - VIR_STORAGE_SOURCE_POOL_MODE_HOST, - - /* Use the URI from the storage pool source element host attribute. E.g. - * file=iscsi://demo.org:6000/iqn.1992-01.com.example/1. - */ - VIR_STORAGE_SOURCE_POOL_MODE_DIRECT, - - VIR_STORAGE_SOURCE_POOL_MODE_LAST -} virStorageSourcePoolMode; - -VIR_ENUM_DECL(virStorageSourcePoolMode); - -typedef struct _virStorageSourcePoolDef virStorageSourcePoolDef; -struct _virStorageSourcePoolDef { - char *pool; /* pool name */ - char *volume; /* volume name */ - int voltype; /* virStorageVolType, internal only */ - int pooltype; /* virStoragePoolType from storage_conf.h, internal only */ - int actualtype; /* virStorageType, internal only */ - int mode; /* virStorageSourcePoolMode, currently makes sense only for iscsi pool */ -}; -typedef virStorageSourcePoolDef *virStorageSourcePoolDefPtr; - - -typedef enum { - VIR_STORAGE_AUTH_TYPE_NONE, - VIR_STORAGE_AUTH_TYPE_CHAP, - VIR_STORAGE_AUTH_TYPE_CEPHX, - - VIR_STORAGE_AUTH_TYPE_LAST, -} virStorageAuthType; -VIR_ENUM_DECL(virStorageAuth); - -typedef struct _virStorageAuthDef virStorageAuthDef; -typedef virStorageAuthDef *virStorageAuthDefPtr; -struct _virStorageAuthDef { - char *username; - char *secrettype; /* <secret type='%s' for disk source */ - int authType; /* virStorageAuthType */ - virSecretLookupTypeDef seclookupdef; -}; - -typedef struct _virStoragePRDef virStoragePRDef; -typedef virStoragePRDef *virStoragePRDefPtr; -struct _virStoragePRDef { - int managed; /* enum virTristateBool */ - char *path; - - /* manager object alias */ - char *mgralias; -}; - -typedef struct _virStorageSourceInitiatorDef virStorageSourceInitiatorDef; -typedef virStorageSourceInitiatorDef *virStorageSourceInitiatorDefPtr; -struct _virStorageSourceInitiatorDef { - char *iqn; /* Initiator IQN */ -}; - -typedef struct _virStorageSourceNVMeDef virStorageSourceNVMeDef; -typedef virStorageSourceNVMeDef *virStorageSourceNVMeDefPtr; -struct _virStorageSourceNVMeDef { - unsigned long long namespc; - int managed; /* enum virTristateBool */ - virPCIDeviceAddress pciAddr; - - /* Don't forget to update virStorageSourceNVMeDefCopy */ -}; - - -typedef struct _virStorageSourceSlice virStorageSourceSlice; -typedef virStorageSourceSlice *virStorageSourceSlicePtr; -struct _virStorageSourceSlice { - unsigned long long offset; - unsigned long long size; - char *nodename; -}; - - -typedef struct _virStorageSource virStorageSource; -typedef virStorageSource *virStorageSourcePtr; - -/* Stores information related to a host resource. In the case of backing - * chains, multiple source disks join to form a single guest view. - * - * IMPORTANT: When adding fields to this struct it's also necessary to add - * appropriate code to the virStorageSourceCopy deep copy function */ -struct _virStorageSource { - virObject parent; - - unsigned int id; /* backing chain identifier, 0 is unset */ - int type; /* virStorageType */ - char *path; - int protocol; /* virStorageNetProtocol */ - char *volume; /* volume name for remote storage */ - 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; - size_t ncookies; - virStorageNetCookieDefPtr *cookies; - virStorageSourcePoolDefPtr srcpool; - virStorageAuthDefPtr auth; - virStorageEncryptionPtr encryption; - virStoragePRDefPtr pr; - virTristateBool sslverify; - /* both values below have 0 as default value */ - unsigned long long readahead; /* size of the readahead buffer in bytes */ - unsigned long long timeout; /* connection timeout in seconds */ - - virStorageSourceNVMeDefPtr nvme; /* type == VIR_STORAGE_TYPE_NVME */ - - virStorageSourceInitiatorDef initiator; - - virObjectPtr privateData; - - int format; /* virStorageFileFormat in domain backing chains, but - * pool-specific enum for storage volumes */ - virBitmapPtr features; - char *compat; - bool nocow; - bool sparse; - - virStorageSourceSlicePtr sliceStorage; - - virStoragePermsPtr perms; - virStorageTimestampsPtr timestamps; - unsigned long long capacity; /* in bytes, 0 if unknown */ - unsigned long long allocation; /* in bytes, 0 if unknown */ - unsigned long long physical; /* in bytes, 0 if unknown */ - unsigned long long clusterSize; /* in bytes, 0 if unknown */ - bool has_allocation; /* Set to true when provided in XML */ - - unsigned long long metadataCacheMaxSize; /* size of the metadata cache in bytes */ - - size_t nseclabels; - virSecurityDeviceLabelDefPtr *seclabels; - - /* Don't ever write to the image */ - bool readonly; - - /* image is shared across hosts */ - bool shared; - - /* backing chain of the storage source */ - virStorageSourcePtr backingStore; - - /* metadata for storage driver access to remote and local volumes */ - void *drv; - - /* metadata about storage image which need separate fields */ - /* Relative name by which this image was opened from its parent, or NULL - * if this image was opened by absolute name */ - char *relPath; - /* Name of the child backing store recorded in metadata of the - * current file. */ - char *backingStoreRaw; - virStorageFileFormat backingStoreRawFormat; - - /* metadata that allows identifying given storage source */ - char *nodeformat; /* name of the format handler object */ - char *nodestorage; /* name of the storage object */ - - /* An optional setting to enable usage of TLS for the storage source */ - int haveTLS; /* enum virTristateBool */ - - /* Indication whether the haveTLS value was altered due to qemu.conf - * setting when haveTLS is missing from the domain config file */ - bool tlsFromConfig; - - /* If TLS is used, then mgmt of the TLS credentials occurs via an - * object that is generated using a specific alias for a specific - * certificate directory with listen and verify bools. */ - char *tlsAlias; - char *tlsCertdir; - - bool detected; /* true if this entry was not provided by the user */ - - unsigned int debugLevel; - bool debug; - - /* Libvirt currently stores the following properties in virDomainDiskDef. - * These instances are currently just copies from the parent definition and - * are not mapped back to the XML */ - int iomode; /* enum virDomainDiskIo */ - int cachemode; /* enum virDomainDiskCache */ - int discard; /* enum virDomainDiskDiscard */ - int detect_zeroes; /* enum virDomainDiskDetectZeroes */ - - bool floppyimg; /* set to true if the storage source is going to be used - as a source for floppy drive */ - - bool hostcdrom; /* backing device is a cdrom */ - - /* passthrough variables for the ssh driver which we don't handle properly */ - /* these must not be used apart from formatting the output JSON in the qemu driver */ - char *ssh_user; - bool ssh_host_key_check_disabled; - - /* nfs_user and nfs_group store the strings passed in by the user for NFS params. - * nfs_uid and nfs_gid represent the converted/looked up ID numbers which are used - * during run time, and are not based on the configuration */ - char *nfs_user; - char *nfs_group; - uid_t nfs_uid; - gid_t nfs_gid; -}; - -G_DEFINE_AUTOPTR_CLEANUP_FUNC(virStorageSource, virObjectUnref); - +#include "internal.h" int virStorageFileParseChainIndex(const char *diskTarget, const char *name, @@ -407,59 +42,6 @@ int virStorageFileGetSCSIKey(const char *path, int virStorageFileGetNPIVKey(const char *path, char **key); -void virStorageAuthDefFree(virStorageAuthDefPtr def); -virStorageAuthDefPtr virStorageAuthDefCopy(const virStorageAuthDef *src); -virStorageAuthDefPtr virStorageAuthDefParse(xmlNodePtr node, - xmlXPathContextPtr ctxt); -void virStorageAuthDefFormat(virBufferPtr buf, virStorageAuthDefPtr authdef); - -void virStoragePRDefFree(virStoragePRDefPtr prd); -virStoragePRDefPtr virStoragePRDefParseXML(xmlXPathContextPtr ctxt); -void virStoragePRDefFormat(virBufferPtr buf, - virStoragePRDefPtr prd, - bool migratable); -bool virStoragePRDefIsEqual(virStoragePRDefPtr a, - virStoragePRDefPtr b); -bool virStoragePRDefIsManaged(virStoragePRDefPtr prd); - -bool -virStorageSourceChainHasManagedPR(virStorageSourcePtr src); - -void virStorageSourceNVMeDefFree(virStorageSourceNVMeDefPtr def); -G_DEFINE_AUTOPTR_CLEANUP_FUNC(virStorageSourceNVMeDef, virStorageSourceNVMeDefFree); - -bool virStorageSourceChainHasNVMe(const virStorageSource *src); - -virSecurityDeviceLabelDefPtr -virStorageSourceGetSecurityLabelDef(virStorageSourcePtr src, - const char *model); - -void virStorageNetHostDefClear(virStorageNetHostDefPtr def); -void virStorageNetHostDefFree(size_t nhosts, virStorageNetHostDefPtr hosts); -virStorageNetHostDefPtr virStorageNetHostDefCopy(size_t nhosts, - virStorageNetHostDefPtr hosts); - -int virStorageSourceInitChainElement(virStorageSourcePtr newelem, - virStorageSourcePtr old, - bool force); -void virStorageSourcePoolDefFree(virStorageSourcePoolDefPtr def); -void virStorageSourceClear(virStorageSourcePtr def); -int virStorageSourceGetActualType(const virStorageSource *def); -bool virStorageSourceIsLocalStorage(const virStorageSource *src); -bool virStorageSourceIsEmpty(virStorageSourcePtr src); -bool virStorageSourceIsBlockLocal(const virStorageSource *src); -virStorageSourcePtr virStorageSourceNew(void); -void virStorageSourceBackingStoreClear(virStorageSourcePtr def); - -int virStorageSourceNetCookiesValidate(virStorageSourcePtr src); - -virStorageSourcePtr virStorageSourceCopy(const virStorageSource *src, - bool backingChain) - ATTRIBUTE_NONNULL(1); -bool virStorageSourceIsSameLocation(virStorageSourcePtr a, - virStorageSourcePtr b) - ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2); - typedef int (*virStorageFileSimplifyPathReadlinkCallback)(const char *path, char **link, @@ -467,39 +49,3 @@ typedef int char *virStorageFileCanonicalizePath(const char *path, virStorageFileSimplifyPathReadlinkCallback cb, void *cbdata); - -bool virStorageSourceIsRelative(virStorageSourcePtr src); - -void -virStorageSourceNetworkAssignDefaultPorts(virStorageSourcePtr src) - ATTRIBUTE_NONNULL(1); - -bool -virStorageSourceIsBacking(const virStorageSource *src); -bool -virStorageSourceHasBacking(const virStorageSource *src); - - -int -virStorageSourcePrivateDataParseRelPath(xmlXPathContextPtr ctxt, - virStorageSourcePtr src); -int -virStorageSourcePrivateDataFormatRelPath(virStorageSourcePtr src, - virBufferPtr buf); - -void -virStorageSourceInitiatorParseXML(xmlXPathContextPtr ctxt, - virStorageSourceInitiatorDefPtr initiator); - -void -virStorageSourceInitiatorFormatXML(virStorageSourceInitiatorDefPtr initiator, - virBufferPtr buf); - -int -virStorageSourceInitiatorCopy(virStorageSourceInitiatorDefPtr dest, - const virStorageSourceInitiatorDef *src); - -void -virStorageSourceInitiatorClear(virStorageSourceInitiatorDefPtr initiator); - -G_DEFINE_AUTOPTR_CLEANUP_FUNC(virStorageAuthDef, virStorageAuthDefFree); -- 2.29.2