1 /*
2  * storage_backend.c: internal storage driver backend contract
3  *
4  * Copyright (C) 2007-2016 Red Hat, Inc.
5  * Copyright (C) 2007-2008 Daniel P. Berrange
6  *
7  * This library is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU Lesser General Public
9  * License as published by the Free Software Foundation; either
10  * version 2.1 of the License, or (at your option) any later version.
11  *
12  * This library is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15  * Lesser General Public License for more details.
16  *
17  * You should have received a copy of the GNU Lesser General Public
18  * License along with this library.  If not, see
19  * <http://www.gnu.org/licenses/>.
20  */
21 
22 #include <config.h>
23 
24 #include <sys/stat.h>
25 
26 #include "datatypes.h"
27 #include "virerror.h"
28 #include "viralloc.h"
29 #include "internal.h"
30 #include "storage_backend.h"
31 #include "storage_source_conf.h"
32 #include "virlog.h"
33 #include "virmodule.h"
34 #include "virfile.h"
35 #include "configmake.h"
36 
37 #if WITH_STORAGE_LVM
38 # include "storage_backend_logical.h"
39 #endif
40 #if WITH_STORAGE_ISCSI
41 # include "storage_backend_iscsi.h"
42 #endif
43 #if WITH_STORAGE_ISCSI_DIRECT
44 # include "storage_backend_iscsi_direct.h"
45 #endif
46 #if WITH_STORAGE_SCSI
47 # include "storage_backend_scsi.h"
48 #endif
49 #if WITH_STORAGE_MPATH
50 # include "storage_backend_mpath.h"
51 #endif
52 #if WITH_STORAGE_DISK
53 # include "storage_backend_disk.h"
54 #endif
55 #if WITH_STORAGE_DIR
56 # include "storage_backend_fs.h"
57 #endif
58 #if WITH_STORAGE_RBD
59 # include "storage_backend_rbd.h"
60 #endif
61 #if WITH_STORAGE_SHEEPDOG
62 # include "storage_backend_sheepdog.h"
63 #endif
64 #if WITH_STORAGE_GLUSTER
65 # include "storage_backend_gluster.h"
66 #endif
67 #if WITH_STORAGE_ZFS
68 # include "storage_backend_zfs.h"
69 #endif
70 #if WITH_STORAGE_VSTORAGE
71 # include "storage_backend_vstorage.h"
72 #endif
73 
74 #define VIR_FROM_THIS VIR_FROM_STORAGE
75 
76 VIR_LOG_INIT("storage.storage_backend");
77 
78 #define VIR_STORAGE_BACKENDS_MAX 20
79 
80 static virStorageBackend *virStorageBackends[VIR_STORAGE_BACKENDS_MAX];
81 static size_t virStorageBackendsCount;
82 
83 #define STORAGE_BACKEND_MODULE_DIR LIBDIR "/libvirt/storage-backend"
84 
85 static int
virStorageDriverLoadBackendModule(const char * name,const char * regfunc,bool forceload)86 virStorageDriverLoadBackendModule(const char *name,
87                                   const char *regfunc,
88                                   bool forceload)
89 {
90     g_autofree char *modfile = NULL;
91 
92     if (!(modfile = virFileFindResourceFull(name,
93                                             "libvirt_storage_backend_",
94                                             VIR_FILE_MODULE_EXT,
95                                             abs_top_builddir "/src",
96                                             STORAGE_BACKEND_MODULE_DIR,
97                                             "LIBVIRT_STORAGE_BACKEND_DIR")))
98         return -1;
99 
100     return virModuleLoad(modfile, regfunc, forceload);
101 }
102 
103 
104 #define VIR_STORAGE_BACKEND_REGISTER(func, module) \
105     if (virStorageDriverLoadBackendModule(module, #func, allbackends) < 0) \
106         return -1
107 
108 int
virStorageBackendDriversRegister(bool allbackends G_GNUC_UNUSED)109 virStorageBackendDriversRegister(bool allbackends G_GNUC_UNUSED)
110 {
111 #if WITH_STORAGE_DIR || WITH_STORAGE_FS
112     VIR_STORAGE_BACKEND_REGISTER(virStorageBackendFsRegister, "fs");
113 #endif
114 #if WITH_STORAGE_LVM
115     VIR_STORAGE_BACKEND_REGISTER(virStorageBackendLogicalRegister, "logical");
116 #endif
117 #if WITH_STORAGE_ISCSI
118     VIR_STORAGE_BACKEND_REGISTER(virStorageBackendISCSIRegister, "iscsi");
119 #endif
120 #if WITH_STORAGE_ISCSI_DIRECT
121     VIR_STORAGE_BACKEND_REGISTER(virStorageBackendISCSIDirectRegister, "iscsi-direct");
122 #endif
123 #if WITH_STORAGE_SCSI
124     VIR_STORAGE_BACKEND_REGISTER(virStorageBackendSCSIRegister, "scsi");
125 #endif
126 #if WITH_STORAGE_MPATH
127     VIR_STORAGE_BACKEND_REGISTER(virStorageBackendMpathRegister, "mpath");
128 #endif
129 #if WITH_STORAGE_DISK
130     VIR_STORAGE_BACKEND_REGISTER(virStorageBackendDiskRegister, "disk");
131 #endif
132 #if WITH_STORAGE_RBD
133     VIR_STORAGE_BACKEND_REGISTER(virStorageBackendRBDRegister, "rbd");
134 #endif
135 #if WITH_STORAGE_SHEEPDOG
136     VIR_STORAGE_BACKEND_REGISTER(virStorageBackendSheepdogRegister, "sheepdog");
137 #endif
138 #if WITH_STORAGE_GLUSTER
139     VIR_STORAGE_BACKEND_REGISTER(virStorageBackendGlusterRegister, "gluster");
140 #endif
141 #if WITH_STORAGE_ZFS
142     VIR_STORAGE_BACKEND_REGISTER(virStorageBackendZFSRegister, "zfs");
143 #endif
144 #if WITH_STORAGE_VSTORAGE
145     VIR_STORAGE_BACKEND_REGISTER(virStorageBackendVstorageRegister, "vstorage");
146 #endif
147 
148     return 0;
149 }
150 #undef VIR_STORAGE_BACKEND_REGISTER
151 
152 
153 int
virStorageBackendRegister(virStorageBackend * backend)154 virStorageBackendRegister(virStorageBackend *backend)
155 {
156     VIR_DEBUG("Registering storage backend '%s'",
157               virStoragePoolTypeToString(backend->type));
158 
159     if (virStorageBackendsCount >= VIR_STORAGE_BACKENDS_MAX) {
160         virReportError(VIR_ERR_INTERNAL_ERROR,
161                        _("Too many drivers, cannot register storage backend '%s'"),
162                        virStoragePoolTypeToString(backend->type));
163         return -1;
164     }
165 
166     virStorageBackends[virStorageBackendsCount] = backend;
167     virStorageBackendsCount++;
168     return 0;
169 }
170 
171 
172 virStorageBackend *
virStorageBackendForType(int type)173 virStorageBackendForType(int type)
174 {
175     size_t i;
176     for (i = 0; i < virStorageBackendsCount; i++)
177         if (virStorageBackends[i]->type == type)
178             return virStorageBackends[i];
179 
180     virReportError(VIR_ERR_INTERNAL_ERROR,
181                    _("missing backend for pool type %d (%s)"),
182                    type, NULLSTR(virStoragePoolTypeToString(type)));
183     return NULL;
184 }
185 
186 
187 virCaps *
virStorageBackendGetCapabilities(void)188 virStorageBackendGetCapabilities(void)
189 {
190     virCaps *caps;
191     size_t i;
192 
193     if (!(caps = virCapabilitiesNew(VIR_ARCH_NONE, false, false)))
194         return NULL;
195 
196     for (i = 0; i < virStorageBackendsCount; i++)
197         virCapabilitiesAddStoragePool(caps, virStorageBackends[i]->type);
198 
199     return caps;
200 }
201