libvirt/src/storage/storage_backend.c

258 lines
7.4 KiB
C
Raw Normal View History

/*
Mark many more strings for translation. * Makefile.maint (err_func_re): Add to the list and make it readable. * po/POTFILES.in: Add src/util.c and src/xm_internal.c, and sort. * src/storage_backend.c: Fix comment. * src/util.c (virFileLinkPointsTo): Mark a string. * qemud/remote.c (remoteDispatchClientRequest): Mark strings. (remoteDispatchOpen, CHECK_CONN, remoteDispatchGetType): Likewise. (remoteDispatchDomainGetSchedulerType): Likewise. (remoteDispatchDomainGetSchedulerParameters): Likewise. (remoteDispatchDomainSetSchedulerParameters): Likewise. (remoteDispatchDomainBlockStats): Likewise. (remoteDispatchDomainInterfaceStats): Likewise. (remoteDispatchDomainAttachDevice, remoteDispatchDomainCreate): (remoteDispatchDomainDestroy, remoteDispatchDomainDetachDevice): (remoteDispatchDomainDumpXml, remoteDispatchDomainGetAutostart): (remoteDispatchDomainGetInfo, remoteDispatchDomainGetMaxMemory): (remoteDispatchDomainGetMaxVcpus, remoteDispatchDomainGetOsType): (remoteDispatchDomainGetVcpus): Likewise. (remoteDispatchDomainMigratePerform): Likewise. (remoteDispatchListDefinedDomains, remoteDispatchDomainPinVcpu): (remoteDispatchDomainReboot, remoteDispatchDomainResume): (remoteDispatchDomainSave, remoteDispatchDomainCoreDump): (remoteDispatchDomainSetAutostart): Likewise. (remoteDispatchDomainSetMaxMemory, remoteDispatchDomainSetMemory): (remoteDispatchDomainSetVcpus, remoteDispatchDomainShutdown): (remoteDispatchDomainSuspend, remoteDispatchDomainUndefine): (remoteDispatchListDefinedNetworks, remoteDispatchListDomains): (remoteDispatchListNetworks, remoteDispatchNetworkCreate): (remoteDispatchNetworkDestroy, remoteDispatchNetworkDumpXml): (remoteDispatchNetworkGetAutostart, remoteDispatchNetworkGetBridgeName): (remoteDispatchNetworkSetAutostart, remoteDispatchNetworkUndefine): (addrToString, remoteDispatchAuthSaslInit, remoteDispatchAuthSaslStart): (remoteDispatchAuthSaslStep, remoteDispatchListDefinedStoragePools): (remoteDispatchListStoragePools, remoteDispatchStoragePoolCreate): (remoteDispatchStoragePoolBuild, remoteDispatchStoragePoolDestroy): (remoteDispatchStoragePoolDelete, remoteDispatchStoragePoolRefresh): (remoteDispatchStoragePoolGetInfo, remoteDispatchStoragePoolDumpXml): (remoteDispatchStoragePoolGetAutostart): Likewise. (remoteDispatchStoragePoolSetAutostart): (remoteDispatchStoragePoolListVolumes): (remoteDispatchStoragePoolNumOfVolumes): (remoteDispatchStoragePoolUndefine, remoteDispatchStorageVolCreateXml): (remoteDispatchStorageVolDelete, remoteDispatchStorageVolGetInfo): (remoteDispatchStorageVolDumpXml, remoteDispatchStorageVolGetPath): (remoteDispatchStorageVolLookupByName): Likewise. * src/qemu_driver.c (qemudOpenMonitor, qemudStartVMDaemon): (dhcpStartDhcpDaemon, qemudStartNetworkDaemon): (qemudDomainSuspend, qemudDomainResume, qemudDomainShutdown): (qemudDomainGetOSType, qemudDomainSetMaxMemory): (qemudDomainSetMemory, qemudDomainGetInfo, qemudDomainSave): (qemudDomainRestore, qemudDomainDumpXML, qemudDomainStart): (qemudDomainUndefine, qemudDomainChangeCDROM): (qemudDomainAttachDevice, qemudDomainGetAutostart): (qemudDomainSetAutostart, qemudDomainInterfaceStats): (qemudNetworkLookupByUUID, qemudNetworkLookupByName): (qemudNetworkUndefine, qemudNetworkStart, qemudNetworkDestroy): (qemudNetworkDumpXML, qemudNetworkGetAutostart): (qemudNetworkSetAutostart): Likewise. * src/virsh.c (cmdVcpupin, cmdAttachDevice, cmdDetachDevice): Likewise. * src/xm_internal.c (xenXMConfigCacheRefresh, xenXMDomainPinVcpu): Likewise.
2008-03-27 13:43:01 +00:00
* storage_backend.c: internal storage driver backend contract
*
* Copyright (C) 2007-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/>.
*
* Author: Daniel P. Berrange <berrange@redhat.com>
*/
#include <config.h>
#include <string.h>
2008-02-20 15:38:29 +00:00
#include <sys/stat.h>
#include "datatypes.h"
#include "virerror.h"
2012-12-12 18:06:53 +00:00
#include "viralloc.h"
#include "internal.h"
#include "virstoragefile.h"
2008-09-05 12:03:45 +00:00
#include "storage_backend.h"
2012-12-12 17:59:27 +00:00
#include "virlog.h"
#include "virfile.h"
#include "configmake.h"
#if WITH_STORAGE_LVM
# include "storage_backend_logical.h"
#endif
#if WITH_STORAGE_ISCSI
# include "storage_backend_iscsi.h"
#endif
#if WITH_STORAGE_SCSI
# include "storage_backend_scsi.h"
#endif
#if WITH_STORAGE_MPATH
# include "storage_backend_mpath.h"
#endif
#if WITH_STORAGE_DISK
# include "storage_backend_disk.h"
#endif
#if WITH_STORAGE_DIR
# include "storage_backend_fs.h"
#endif
#if WITH_STORAGE_RBD
# include "storage_backend_rbd.h"
#endif
#if WITH_STORAGE_SHEEPDOG
# include "storage_backend_sheepdog.h"
#endif
storage: initial support for linking with libgfapi We support gluster volumes in domain XML, so we also ought to support them as a storage pool. Besides, a future patch will want to take advantage of libgfapi to handle the case of a gluster device holding qcow2 rather than raw storage, and for that to work, we need a storage backend that can read gluster storage volume contents. This sets up the framework. Note that the new pool is named 'gluster' to match a <disk type='network'><source protocol='gluster'> image source already supported in a <domain>; it does NOT match the <pool type='netfs'><source><target type='glusterfs'>, since that uses a FUSE mount to a local file name rather than a network name. This and subsequent patches have been tested against glusterfs 3.4.1 (available on Fedora 19); there are likely bugs in older versions that may prevent decent use of gfapi, so this patch enforces the minimum version tested. A future patch may lower the minimum. On the other hand, I hit at least two bugs in 3.4.1 that will be fixed in 3.5/3.4.2, where it might be worth raising the minimum: glfs_readdir is nicer to use than glfs_readdir_r [1], and glfs_fini should only return failure on an actual failure [2]. [1] http://lists.gnu.org/archive/html/gluster-devel/2013-10/msg00085.html [2] http://lists.gnu.org/archive/html/gluster-devel/2013-10/msg00086.html * configure.ac (WITH_STORAGE_GLUSTER): New conditional. * m4/virt-gluster.m4: new file. * libvirt.spec.in (BuildRequires): Support gluster in spec file. * src/conf/storage_conf.h (VIR_STORAGE_POOL_GLUSTER): New pool type. * src/conf/storage_conf.c (poolTypeInfo): Treat similar to sheepdog and rbd. (virStoragePoolDefFormat): Don't output target for gluster. * src/storage/storage_backend_gluster.h: New file. * src/storage/storage_backend_gluster.c: Likewise. * po/POTFILES.in: Add new file. * src/storage/storage_backend.c (backends): Register new type. * src/Makefile.am (STORAGE_DRIVER_GLUSTER_SOURCES): Build new files. * src/storage/storage_backend.h (_virStorageBackend): Documet assumption. Signed-off-by: Eric Blake <eblake@redhat.com>
2013-11-19 23:26:05 +00:00
#if WITH_STORAGE_GLUSTER
# include "storage_backend_gluster.h"
#endif
#if WITH_STORAGE_ZFS
# include "storage_backend_zfs.h"
#endif
#if WITH_STORAGE_VSTORAGE
# include "storage_backend_vstorage.h"
#endif
#define VIR_FROM_THIS VIR_FROM_STORAGE
VIR_LOG_INIT("storage.storage_backend");
#define VIR_STORAGE_BACKENDS_MAX 20
static virStorageBackendPtr virStorageBackends[VIR_STORAGE_BACKENDS_MAX];
static size_t virStorageBackendsCount;
static virStorageFileBackendPtr virStorageFileBackends[VIR_STORAGE_BACKENDS_MAX];
static size_t virStorageFileBackendsCount;
#if WITH_DRIVER_MODULES
# define STORAGE_BACKEND_MODULE_DIR LIBDIR "/libvirt/storage-backend"
static int
virStorageDriverLoadBackendModule(const char *name,
const char *regfunc)
{
char *modfile = NULL;
int ret;
if (!(modfile = virFileFindResourceFull(name,
"libvirt_storage_backend_",
".so",
abs_topbuilddir "/src/.libs",
STORAGE_BACKEND_MODULE_DIR,
"LIBVIRT_STORAGE_BACKEND_DIR")))
return 1;
ret = virDriverLoadModuleFull(modfile, regfunc, NULL);
VIR_FREE(modfile);
return ret;
}
# define VIR_STORAGE_BACKEND_REGISTER(func, module) \
if (virStorageDriverLoadBackendModule(module, #func) < 0) \
return -1
#else
# define VIR_STORAGE_BACKEND_REGISTER(func, module) \
if (func() < 0) \
return -1
#endif
int
virStorageBackendDriversRegister(void)
{
#if WITH_STORAGE_DIR || WITH_STORAGE_FS
VIR_STORAGE_BACKEND_REGISTER(virStorageBackendFsRegister, "fs");
#endif
#if WITH_STORAGE_LVM
VIR_STORAGE_BACKEND_REGISTER(virStorageBackendLogicalRegister, "logical");
#endif
#if WITH_STORAGE_ISCSI
VIR_STORAGE_BACKEND_REGISTER(virStorageBackendISCSIRegister, "iscsi");
#endif
#if WITH_STORAGE_SCSI
VIR_STORAGE_BACKEND_REGISTER(virStorageBackendSCSIRegister, "scsi");
#endif
#if WITH_STORAGE_MPATH
VIR_STORAGE_BACKEND_REGISTER(virStorageBackendMpathRegister, "mpath");
#endif
#if WITH_STORAGE_DISK
VIR_STORAGE_BACKEND_REGISTER(virStorageBackendDiskRegister, "disk");
#endif
#if WITH_STORAGE_RBD
VIR_STORAGE_BACKEND_REGISTER(virStorageBackendRBDRegister, "rbd");
#endif
#if WITH_STORAGE_SHEEPDOG
VIR_STORAGE_BACKEND_REGISTER(virStorageBackendSheepdogRegister, "sheepdog");
storage: initial support for linking with libgfapi We support gluster volumes in domain XML, so we also ought to support them as a storage pool. Besides, a future patch will want to take advantage of libgfapi to handle the case of a gluster device holding qcow2 rather than raw storage, and for that to work, we need a storage backend that can read gluster storage volume contents. This sets up the framework. Note that the new pool is named 'gluster' to match a <disk type='network'><source protocol='gluster'> image source already supported in a <domain>; it does NOT match the <pool type='netfs'><source><target type='glusterfs'>, since that uses a FUSE mount to a local file name rather than a network name. This and subsequent patches have been tested against glusterfs 3.4.1 (available on Fedora 19); there are likely bugs in older versions that may prevent decent use of gfapi, so this patch enforces the minimum version tested. A future patch may lower the minimum. On the other hand, I hit at least two bugs in 3.4.1 that will be fixed in 3.5/3.4.2, where it might be worth raising the minimum: glfs_readdir is nicer to use than glfs_readdir_r [1], and glfs_fini should only return failure on an actual failure [2]. [1] http://lists.gnu.org/archive/html/gluster-devel/2013-10/msg00085.html [2] http://lists.gnu.org/archive/html/gluster-devel/2013-10/msg00086.html * configure.ac (WITH_STORAGE_GLUSTER): New conditional. * m4/virt-gluster.m4: new file. * libvirt.spec.in (BuildRequires): Support gluster in spec file. * src/conf/storage_conf.h (VIR_STORAGE_POOL_GLUSTER): New pool type. * src/conf/storage_conf.c (poolTypeInfo): Treat similar to sheepdog and rbd. (virStoragePoolDefFormat): Don't output target for gluster. * src/storage/storage_backend_gluster.h: New file. * src/storage/storage_backend_gluster.c: Likewise. * po/POTFILES.in: Add new file. * src/storage/storage_backend.c (backends): Register new type. * src/Makefile.am (STORAGE_DRIVER_GLUSTER_SOURCES): Build new files. * src/storage/storage_backend.h (_virStorageBackend): Documet assumption. Signed-off-by: Eric Blake <eblake@redhat.com>
2013-11-19 23:26:05 +00:00
#endif
#if WITH_STORAGE_GLUSTER
VIR_STORAGE_BACKEND_REGISTER(virStorageBackendGlusterRegister, "gluster");
#endif
#if WITH_STORAGE_ZFS
VIR_STORAGE_BACKEND_REGISTER(virStorageBackendZFSRegister, "zfs");
#endif
#if WITH_STORAGE_VSTORAGE
VIR_STORAGE_BACKEND_REGISTER(virStorageBackendVstorageRegister, "vstorage");
#endif
return 0;
}
#undef VIR_STORAGE_BACKEND_REGISTER
int
virStorageBackendRegister(virStorageBackendPtr backend)
{
VIR_DEBUG("Registering storage backend '%s'",
virStorageTypeToString(backend->type));
if (virStorageBackendsCount >= VIR_STORAGE_BACKENDS_MAX) {
virReportError(VIR_ERR_INTERNAL_ERROR,
_("Too many drivers, cannot register storage backend '%s'"),
virStorageTypeToString(backend->type));
return -1;
}
virStorageBackends[virStorageBackendsCount] = backend;
virStorageBackendsCount++;
return 0;
}
int
virStorageBackendFileRegister(virStorageFileBackendPtr backend)
{
VIR_DEBUG("Registering storage file backend '%s' protocol '%s'",
virStorageTypeToString(backend->type),
virStorageNetProtocolTypeToString(backend->protocol));
if (virStorageFileBackendsCount >= VIR_STORAGE_BACKENDS_MAX) {
virReportError(VIR_ERR_INTERNAL_ERROR,
_("Too many drivers, cannot register storage file "
"backend '%s'"),
virStorageTypeToString(backend->type));
return -1;
}
virStorageFileBackends[virStorageFileBackendsCount] = backend;
virStorageFileBackendsCount++;
return 0;
}
virStorageBackendPtr
virStorageBackendForType(int type)
Fix UUID handling in secrets/storage encryption APIs Convert all the secret/storage encryption APIs / wire format to handle UUIDs in raw format instead of non-canonical printable format. Guarentees data format correctness. * docs/schemas/storageencryption.rng: Make UUID mandatory for a secret and validate fully * docs/schemas/secret.rng: Fully validate UUID * include/libvirt/libvirt.h, include/libvirt/libvirt.h.in, Add virSecretLookupByUUID and virSecretGetUUID. Make virSecretGetUUIDString follow normal API design pattern * python/generator.py: Skip generation of virSecretGetUUID, virSecretGetUUIDString and virSecretLookupByUUID * python/libvir.c, python/libvirt-python-api.xml: Manual impl of virSecretGetUUID,virSecretGetUUIDString and virSecretLookupByUUID * qemud/remote.c: s/virSecretLookupByUUIDString/virSecretLookupByUUID/ Fix get_nonnull_secret/make_nonnull_secret to use unsigned char * qemud/remote_protocol.x: Fix remote_nonnull_secret to use a remote_uuid instead of remote_nonnull_string for UUID field. Rename REMOTE_PROC_SECRET_LOOKUP_BY_UUID_STRING to REMOTE_PROC_SECRET_LOOKUP_BY_UUID_STRING and make it take an remote_uuid value * qemud/remote_dispatch_args.h, qemud/remote_dispatch_prototypes.h, qemud/remote_dispatch_ret.h, qemud/remote_dispatch_table.h, qemud/remote_protocol.c, qemud/remote_protocol.h: Re-generate * src/datatypes.h, src/datatypes.c: Store UUID in raw format instead of printable. Change virGetSecret to use raw format UUID * src/driver.h: Rename virDrvSecretLookupByUUIDString to virDrvSecretLookupByUUID and use raw format UUID * src/libvirt.c: Add virSecretLookupByUUID and virSecretGetUUID and re-implement virSecretLookupByUUIDString and virSecretGetUUIDString in terms of those * src/libvirt_public.syms: Add virSecretLookupByUUID and virSecretGetUUID * src/remote_internal.c: Rename remoteSecretLookupByUUIDString to remoteSecretLookupByUUID. Fix typo in args for remoteSecretDefineXML impl. Use raw UUID format for get_nonnull_secret and make_nonnull_secret * src/storage_encryption_conf.c, src/storage_encryption_conf.h: Storage UUID in raw format, and require it to be present in XML. Use UUID parser to validate. * secret_conf.h, secret_conf.c: Generate a UUID if none is provided. Storage UUID in raw format. * src/secret_driver.c: Adjust to deal with raw UUIDs. Save secrets in a filed with printable UUID, instead of base64 UUID. * src/virsh.c: Adjust for changed public API contract of virSecretGetUUIDString. * src/storage_Backend.c: DOn't undefine secret we just generated upon successful volume creation. Fix to handle raw UUIDs. Generate a non-clashing UUID * src/qemu_driver.c: Change to use lookupByUUID instead of lookupByUUIDString
2009-09-10 16:44:12 +00:00
{
size_t i;
for (i = 0; i < virStorageBackendsCount; i++)
if (virStorageBackends[i]->type == type)
return virStorageBackends[i];
Fix UUID handling in secrets/storage encryption APIs Convert all the secret/storage encryption APIs / wire format to handle UUIDs in raw format instead of non-canonical printable format. Guarentees data format correctness. * docs/schemas/storageencryption.rng: Make UUID mandatory for a secret and validate fully * docs/schemas/secret.rng: Fully validate UUID * include/libvirt/libvirt.h, include/libvirt/libvirt.h.in, Add virSecretLookupByUUID and virSecretGetUUID. Make virSecretGetUUIDString follow normal API design pattern * python/generator.py: Skip generation of virSecretGetUUID, virSecretGetUUIDString and virSecretLookupByUUID * python/libvir.c, python/libvirt-python-api.xml: Manual impl of virSecretGetUUID,virSecretGetUUIDString and virSecretLookupByUUID * qemud/remote.c: s/virSecretLookupByUUIDString/virSecretLookupByUUID/ Fix get_nonnull_secret/make_nonnull_secret to use unsigned char * qemud/remote_protocol.x: Fix remote_nonnull_secret to use a remote_uuid instead of remote_nonnull_string for UUID field. Rename REMOTE_PROC_SECRET_LOOKUP_BY_UUID_STRING to REMOTE_PROC_SECRET_LOOKUP_BY_UUID_STRING and make it take an remote_uuid value * qemud/remote_dispatch_args.h, qemud/remote_dispatch_prototypes.h, qemud/remote_dispatch_ret.h, qemud/remote_dispatch_table.h, qemud/remote_protocol.c, qemud/remote_protocol.h: Re-generate * src/datatypes.h, src/datatypes.c: Store UUID in raw format instead of printable. Change virGetSecret to use raw format UUID * src/driver.h: Rename virDrvSecretLookupByUUIDString to virDrvSecretLookupByUUID and use raw format UUID * src/libvirt.c: Add virSecretLookupByUUID and virSecretGetUUID and re-implement virSecretLookupByUUIDString and virSecretGetUUIDString in terms of those * src/libvirt_public.syms: Add virSecretLookupByUUID and virSecretGetUUID * src/remote_internal.c: Rename remoteSecretLookupByUUIDString to remoteSecretLookupByUUID. Fix typo in args for remoteSecretDefineXML impl. Use raw UUID format for get_nonnull_secret and make_nonnull_secret * src/storage_encryption_conf.c, src/storage_encryption_conf.h: Storage UUID in raw format, and require it to be present in XML. Use UUID parser to validate. * secret_conf.h, secret_conf.c: Generate a UUID if none is provided. Storage UUID in raw format. * src/secret_driver.c: Adjust to deal with raw UUIDs. Save secrets in a filed with printable UUID, instead of base64 UUID. * src/virsh.c: Adjust for changed public API contract of virSecretGetUUIDString. * src/storage_Backend.c: DOn't undefine secret we just generated upon successful volume creation. Fix to handle raw UUIDs. Generate a non-clashing UUID * src/qemu_driver.c: Change to use lookupByUUID instead of lookupByUUIDString
2009-09-10 16:44:12 +00:00
virReportError(VIR_ERR_INTERNAL_ERROR,
_("missing backend for pool type %d (%s)"),
type, NULLSTR(virStoragePoolTypeToString(type)));
return NULL;
Fix UUID handling in secrets/storage encryption APIs Convert all the secret/storage encryption APIs / wire format to handle UUIDs in raw format instead of non-canonical printable format. Guarentees data format correctness. * docs/schemas/storageencryption.rng: Make UUID mandatory for a secret and validate fully * docs/schemas/secret.rng: Fully validate UUID * include/libvirt/libvirt.h, include/libvirt/libvirt.h.in, Add virSecretLookupByUUID and virSecretGetUUID. Make virSecretGetUUIDString follow normal API design pattern * python/generator.py: Skip generation of virSecretGetUUID, virSecretGetUUIDString and virSecretLookupByUUID * python/libvir.c, python/libvirt-python-api.xml: Manual impl of virSecretGetUUID,virSecretGetUUIDString and virSecretLookupByUUID * qemud/remote.c: s/virSecretLookupByUUIDString/virSecretLookupByUUID/ Fix get_nonnull_secret/make_nonnull_secret to use unsigned char * qemud/remote_protocol.x: Fix remote_nonnull_secret to use a remote_uuid instead of remote_nonnull_string for UUID field. Rename REMOTE_PROC_SECRET_LOOKUP_BY_UUID_STRING to REMOTE_PROC_SECRET_LOOKUP_BY_UUID_STRING and make it take an remote_uuid value * qemud/remote_dispatch_args.h, qemud/remote_dispatch_prototypes.h, qemud/remote_dispatch_ret.h, qemud/remote_dispatch_table.h, qemud/remote_protocol.c, qemud/remote_protocol.h: Re-generate * src/datatypes.h, src/datatypes.c: Store UUID in raw format instead of printable. Change virGetSecret to use raw format UUID * src/driver.h: Rename virDrvSecretLookupByUUIDString to virDrvSecretLookupByUUID and use raw format UUID * src/libvirt.c: Add virSecretLookupByUUID and virSecretGetUUID and re-implement virSecretLookupByUUIDString and virSecretGetUUIDString in terms of those * src/libvirt_public.syms: Add virSecretLookupByUUID and virSecretGetUUID * src/remote_internal.c: Rename remoteSecretLookupByUUIDString to remoteSecretLookupByUUID. Fix typo in args for remoteSecretDefineXML impl. Use raw UUID format for get_nonnull_secret and make_nonnull_secret * src/storage_encryption_conf.c, src/storage_encryption_conf.h: Storage UUID in raw format, and require it to be present in XML. Use UUID parser to validate. * secret_conf.h, secret_conf.c: Generate a UUID if none is provided. Storage UUID in raw format. * src/secret_driver.c: Adjust to deal with raw UUIDs. Save secrets in a filed with printable UUID, instead of base64 UUID. * src/virsh.c: Adjust for changed public API contract of virSecretGetUUIDString. * src/storage_Backend.c: DOn't undefine secret we just generated upon successful volume creation. Fix to handle raw UUIDs. Generate a non-clashing UUID * src/qemu_driver.c: Change to use lookupByUUID instead of lookupByUUIDString
2009-09-10 16:44:12 +00:00
}
virStorageFileBackendPtr
virStorageFileBackendForTypeInternal(int type,
int protocol,
bool report)
{
size_t i;
for (i = 0; i < virStorageFileBackendsCount; i++) {
if (virStorageFileBackends[i]->type == type) {
if (type == VIR_STORAGE_TYPE_NETWORK &&
virStorageFileBackends[i]->protocol != protocol)
continue;
return virStorageFileBackends[i];
}
}
if (!report)
return NULL;
if (type == VIR_STORAGE_TYPE_NETWORK) {
virReportError(VIR_ERR_INTERNAL_ERROR,
_("missing storage backend for network files "
"using %s protocol"),
virStorageNetProtocolTypeToString(protocol));
} else {
virReportError(VIR_ERR_INTERNAL_ERROR,
_("missing storage backend for '%s' storage"),
virStorageTypeToString(type));
}
return NULL;
}
virStorageFileBackendPtr
virStorageFileBackendForType(int type,
int protocol)
{
return virStorageFileBackendForTypeInternal(type, protocol, true);
}