[libvirt PATCH 15/17] util: move virStorageSource code into conf

Pavel Hrdina phrdina at redhat.com
Mon Dec 14 15:55:35 UTC 2020


The code handles XML bits and internal definition and should be
in conf directory.

Signed-off-by: Pavel Hrdina <phrdina at redhat.com>
---
 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.c               | 1316 +++++++++++++++++++++++
 src/conf/storage_source.h               |  518 +++++++++
 src/esx/esx_storage_backend_iscsi.c     |    2 +-
 src/esx/esx_storage_backend_vmfs.c      |    2 +-
 src/libvirt_private.syms                |   97 +-
 src/locking/lock_driver_lockd.c         |    1 +
 src/qemu/qemu_backup.c                  |    2 +-
 src/qemu/qemu_blockjob.c                |    2 +-
 src/qemu/qemu_command.c                 |    2 +-
 src/qemu/qemu_domain.c                  |    2 +-
 src/qemu/qemu_driver.c                  |    2 +-
 src/qemu/qemu_hotplug.c                 |    2 +-
 src/qemu/qemu_migration.c               |    2 +-
 src/qemu/qemu_process.h                 |    2 +-
 src/storage/storage_backend.c           |    2 +-
 src/storage/storage_util.c              |    1 +
 src/storage_file/meson.build            |    3 +
 src/storage_file/storage_file.h         |    2 +-
 src/storage_file/storage_file_backend.h |    2 +-
 src/util/virstoragefile.c               | 1281 ----------------------
 src/util/virstoragefile.h               |  436 +-------
 30 files changed, 1913 insertions(+), 1784 deletions(-)
 create mode 100644 src/conf/storage_source.c
 create mode 100644 src/conf/storage_source.h

diff --git a/po/POTFILES.in b/po/POTFILES.in
index d3a0f85d91..135198820a 100644
--- a/po/POTFILES.in
+++ b/po/POTFILES.in
@@ -43,6 +43,7 @@
 @SRCDIR at src/conf/snapshot_conf.c
 @SRCDIR at src/conf/storage_adapter_conf.c
 @SRCDIR at src/conf/storage_conf.c
+ at SRCDIR@src/conf/storage_source.c
 @SRCDIR at src/conf/virchrdev.c
 @SRCDIR at src/conf/virdomainmomentobjlist.c
 @SRCDIR at src/conf/virdomainobjlist.c
diff --git a/src/conf/backup_conf.c b/src/conf/backup_conf.c
index 90ffcc51d1..7d4c466a9e 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.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..7b8e53ca75 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.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 26c48ef38c..e1fc61073e 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.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 ce8ed48a04..5c95317501 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.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 util/storage_source.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..12efaf56cc 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.c',
   'virstorageobj.c',
 ]
 
diff --git a/src/conf/snapshot_conf.c b/src/conf/snapshot_conf.c
index f896fd1cf2..2abb14b4f6 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.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..fa11d965cd 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.h"
 
 #include "virxml.h"
 #include "viruuid.h"
diff --git a/src/conf/storage_conf.h b/src/conf/storage_conf.h
index ffd406e093..47f2bf602d 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.h"
 #include "virbitmap.h"
 #include "virthread.h"
 #include "device_conf.h"
diff --git a/src/conf/storage_source.c b/src/conf/storage_source.c
new file mode 100644
index 0000000000..271dbc06c0
--- /dev/null
+++ b/src/conf/storage_source.c
@@ -0,0 +1,1316 @@
+/*
+ * storage_source.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.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");
+
+
+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",
+);
+
+
+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(&copy);
+
+    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;
+
+    /* 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);
+
+    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);
+
+    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_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);
+    }
+}
+
+
+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.h b/src/conf/storage_source.h
new file mode 100644
index 0000000000..89bba38599
--- /dev/null
+++ b/src/conf/storage_source.h
@@ -0,0 +1,518 @@
+/*
+ * storage_source.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_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 */
+
+    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;
+};
+
+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);
+
+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..00cc129b1f 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.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..1533cbfe58 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.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 fe6683f728..0b0a57e85d 100644
--- a/src/libvirt_private.syms
+++ b/src/libvirt_private.syms
@@ -1053,6 +1053,56 @@ virStoragePoolEventRefreshNew;
 virStoragePoolEventStateRegisterID;
 
 
+# conf/storage_source.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;
+virStorageTypeFromString;
+virStorageTypeToString;
+
+
 # conf/virchrdev.h
 virChrdevAlloc;
 virChrdevFree;
@@ -3164,55 +3214,8 @@ virStorageEncryptionParseNode;
 
 
 # util/virstoragefile.h
-virStorageAuthDefCopy;
-virStorageAuthDefFormat;
-virStorageAuthDefFree;
-virStorageAuthDefParse;
-virStorageFileFeatureTypeFromString;
-virStorageFileFeatureTypeToString;
-virStorageFileFormatTypeFromString;
-virStorageFileFormatTypeToString;
 virStorageFileGetNPIVKey;
 virStorageFileGetSCSIKey;
-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;
-virStorageTypeFromString;
-virStorageTypeToString;
 
 
 # util/virstring.h
diff --git a/src/locking/lock_driver_lockd.c b/src/locking/lock_driver_lockd.c
index b8c2121e78..5523f8cbb8 100644
--- a/src/locking/lock_driver_lockd.c
+++ b/src/locking/lock_driver_lockd.c
@@ -35,6 +35,7 @@
 #include "configmake.h"
 #include "virstring.h"
 #include "virutil.h"
+#include "virstoragefile.h"
 
 #include "lock_driver_lockd.h"
 
diff --git a/src/qemu/qemu_backup.c b/src/qemu/qemu_backup.c
index bd699ad29f..997214a840 100644
--- a/src/qemu/qemu_backup.c
+++ b/src/qemu/qemu_backup.c
@@ -35,7 +35,7 @@
 #include "virbuffer.h"
 #include "viralloc.h"
 #include "virxml.h"
-#include "virstoragefile.h"
+#include "storage_source.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 2a5a5e66f4..85abbed21a 100644
--- a/src/qemu/qemu_blockjob.c
+++ b/src/qemu/qemu_blockjob.c
@@ -33,7 +33,7 @@
 #include "conf/domain_event.h"
 
 #include "virlog.h"
-#include "virstoragefile.h"
+#include "storage_source.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 b06a086e18..a2537a1583 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.h"
 #include "virtpm.h"
 #include "virscsi.h"
 #include "virnuma.h"
diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c
index ef073e5395..8ddb7b70d2 100644
--- a/src/qemu/qemu_domain.c
+++ b/src/qemu/qemu_domain.c
@@ -51,7 +51,7 @@
 #include "domain_validate.h"
 #include "virtime.h"
 #include "virnetdevopenvswitch.h"
-#include "virstoragefile.h"
+#include "storage_source.h"
 #include "storage_file.h"
 #include "virstring.h"
 #include "virthreadjob.h"
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index 00ce56c6b9..f6554e1506 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -82,7 +82,7 @@
 #include "virsysinfo.h"
 #include "domain_nwfilter.h"
 #include "virhook.h"
-#include "virstoragefile.h"
+#include "storage_source.h"
 #include "storage_file.h"
 #include "virfile.h"
 #include "virfdstream.h"
diff --git a/src/qemu/qemu_hotplug.c b/src/qemu/qemu_hotplug.c
index a0727b8b90..d32f97ef5c 100644
--- a/src/qemu/qemu_hotplug.c
+++ b/src/qemu/qemu_hotplug.c
@@ -52,7 +52,7 @@
 #include "virnetdevopenvswitch.h"
 #include "virnetdevmidonet.h"
 #include "device_conf.h"
-#include "virstoragefile.h"
+#include "storage_source.h"
 #include "storage_file.h"
 #include "virstring.h"
 #include "virtime.h"
diff --git a/src/qemu/qemu_migration.c b/src/qemu/qemu_migration.c
index 16c9f18e0a..50c5de68b8 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.h"
 #include "viruri.h"
 #include "virhook.h"
 #include "virstring.h"
diff --git a/src/qemu/qemu_process.h b/src/qemu/qemu_process.h
index f4feeaa68f..1ced774fec 100644
--- a/src/qemu/qemu_process.h
+++ b/src/qemu/qemu_process.h
@@ -23,7 +23,7 @@
 
 #include "qemu_conf.h"
 #include "qemu_domain.h"
-#include "virstoragefile.h"
+#include "storage_source.h"
 #include "vireventthread.h"
 
 int qemuProcessPrepareMonitorChr(virDomainChrSourceDefPtr monConfig,
diff --git a/src/storage/storage_backend.c b/src/storage/storage_backend.c
index 2bce445575..87c8bc525d 100644
--- a/src/storage/storage_backend.c
+++ b/src/storage/storage_backend.c
@@ -27,7 +27,7 @@
 #include "virerror.h"
 #include "viralloc.h"
 #include "internal.h"
-#include "virstoragefile.h"
+#include "storage_source.h"
 #include "storage_backend.h"
 #include "virlog.h"
 #include "virmodule.h"
diff --git a/src/storage/storage_util.c b/src/storage/storage_util.c
index a1949a5a24..7616ec63a0 100644
--- a/src/storage/storage_util.c
+++ b/src/storage/storage_util.c
@@ -63,6 +63,7 @@
 #include "viruuid.h"
 #include "virstoragefile.h"
 #include "storage_file.h"
+#include "storage_source.h"
 #include "storage_util.h"
 #include "virlog.h"
 #include "virfile.h"
diff --git a/src/storage_file/meson.build b/src/storage_file/meson.build
index 4d85d16929..ef1345c866 100644
--- a/src/storage_file/meson.build
+++ b/src/storage_file/meson.build
@@ -18,6 +18,9 @@ virt_storage_file_lib = static_library(
   [
     storage_file_sources,
   ],
+  include_directories: [
+    conf_inc_dir,
+  ],
   dependencies: [
     src_dep,
   ],
diff --git a/src/storage_file/storage_file.h b/src/storage_file/storage_file.h
index 8afedc35b3..181efded87 100644
--- a/src/storage_file/storage_file.h
+++ b/src/storage_file/storage_file.h
@@ -21,7 +21,7 @@
 
 #pragma once
 
-#include "virstoragefile.h"
+#include "storage_source.h"
 
 
 /* Minimum header size required to probe all known formats with
diff --git a/src/storage_file/storage_file_backend.h b/src/storage_file/storage_file_backend.h
index ad0f66212c..3d6b2b7fc0 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.h"
 
 /* ------- virStorageFile backends ------------ */
 typedef struct _virStorageFileBackend virStorageFileBackend;
diff --git a/src/util/virstoragefile.c b/src/util/virstoragefile.c
index 3489934546..1c61f3c143 100644
--- a/src/util/virstoragefile.c
+++ b/src/util/virstoragefile.c
@@ -23,84 +23,8 @@
 #include "virstoragefile.h"
 
 #include "viralloc.h"
-#include "virxml.h"
 #include "virerror.h"
-#include "virlog.h"
 #include "vircommand.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",
-);
-
-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",
-);
 
 
 #ifdef WITH_UDEV
@@ -239,1208 +163,3 @@ int virStorageFileGetNPIVKey(const char *path G_GNUC_UNUSED,
     return -1;
 }
 #endif
-
-
-/**
- * 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(&copy);
-
-    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;
-
-    /* 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);
-
-    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);
-
-    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_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);
-    }
-}
-
-
-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 557e7da81e..d8a8f36831 100644
--- a/src/util/virstoragefile.h
+++ b/src/util/virstoragefile.h
@@ -21,444 +21,10 @@
 
 #pragma once
 
-#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_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 */
-
-    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;
-};
-
-G_DEFINE_AUTOPTR_CLEANUP_FUNC(virStorageSource, virObjectUnref);
-
+#include "internal.h"
 
 int virStorageFileGetSCSIKey(const char *path,
                              char **key,
                              bool ignoreError);
 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);
-
-bool virStorageSourceIsRelative(virStorageSourcePtr src);
-
-void
-virStorageSourceNetworkAssignDefaultPorts(virStorageSourcePtr src)
-    ATTRIBUTE_NONNULL(1);
-
-bool
-virStorageSourceIsBacking(const virStorageSource *src);
-bool
-virStorageSourceHasBacking(const virStorageSource *src);
-
-
-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.28.0




More information about the libvir-list mailing list