# define __VIR_STORAGE_BACKEND_H__
# include <stdint.h>
+# include <stdbool.h>
# include "internal.h"
# include "storage_conf.h"
typedef char * (*virStorageBackendFindPoolSources)(virConnectPtr conn, const char *srcSpec, unsigned int flags);
+typedef int (*virStorageBackendCheckPool)(virConnectPtr conn, virStoragePoolObjPtr pool, bool *active);
typedef int (*virStorageBackendStartPool)(virConnectPtr conn, virStoragePoolObjPtr pool);
typedef int (*virStorageBackendBuildPool)(virConnectPtr conn, virStoragePoolObjPtr pool, unsigned int flags);
typedef int (*virStorageBackendRefreshPool)(virConnectPtr conn, virStoragePoolObjPtr pool);
int type;
virStorageBackendFindPoolSources findPoolSources;
+ virStorageBackendCheckPool checkPool;
virStorageBackendStartPool startPool;
virStorageBackendBuildPool buildPool;
virStorageBackendRefreshPool refreshPool;
#endif /* WITH_STORAGE_FS */
+static int
+virStorageBackendFileSystemCheck(virConnectPtr conn ATTRIBUTE_UNUSED,
+ virStoragePoolObjPtr pool,
+ bool *isActive)
+{
+ *isActive = false;
+ if (pool->def->type == VIR_STORAGE_POOL_DIR) {
+ if (access(pool->def->target.path, F_OK) == 0)
+ *isActive = true;
+#if WITH_STORAGE_FS
+ } else {
+ int ret;
+ if ((ret = virStorageBackendFileSystemIsMounted(pool)) != 0) {
+ if (ret < 0)
+ return -1;
+ *isActive = true;
+ }
+#endif /* WITH_STORAGE_FS */
+ }
+
+ return 0;
+}
+
+#if WITH_STORAGE_FS
/**
* @conn connection to report errors against
* @pool storage pool to start
*
* Returns 0 on success, -1 on error
*/
-#if WITH_STORAGE_FS
static int
virStorageBackendFileSystemStart(virConnectPtr conn ATTRIBUTE_UNUSED,
virStoragePoolObjPtr pool)
.type = VIR_STORAGE_POOL_DIR,
.buildPool = virStorageBackendFileSystemBuild,
+ .checkPool = virStorageBackendFileSystemCheck,
.refreshPool = virStorageBackendFileSystemRefresh,
.deletePool = virStorageBackendFileSystemDelete,
.buildVol = virStorageBackendFileSystemVolBuild,
.type = VIR_STORAGE_POOL_FS,
.buildPool = virStorageBackendFileSystemBuild,
+ .checkPool = virStorageBackendFileSystemCheck,
.startPool = virStorageBackendFileSystemStart,
.refreshPool = virStorageBackendFileSystemRefresh,
.stopPool = virStorageBackendFileSystemStop,
.type = VIR_STORAGE_POOL_NETFS,
.buildPool = virStorageBackendFileSystemBuild,
+ .checkPool = virStorageBackendFileSystemCheck,
.startPool = virStorageBackendFileSystemStart,
.findPoolSources = virStorageBackendFileSystemNetFindPoolSources,
.refreshPool = virStorageBackendFileSystemRefresh,
return ret;
}
+static int
+virStorageBackendISCSICheckPool(virConnectPtr conn ATTRIBUTE_UNUSED,
+ virStoragePoolObjPtr pool,
+ bool *isActive)
+{
+ char *session = NULL;
+ int ret = -1;
+
+ *isActive = false;
+
+ if (pool->def->source.host.name == NULL) {
+ virStorageReportError(VIR_ERR_INTERNAL_ERROR,
+ "%s", _("missing source host"));
+ return -1;
+ }
+
+ if (pool->def->source.ndevice != 1 ||
+ pool->def->source.devices[0].path == NULL) {
+ virStorageReportError(VIR_ERR_INTERNAL_ERROR,
+ "%s", _("missing source device"));
+ return -1;
+ }
+
+ if ((session = virStorageBackendISCSISession(pool, 1)) != NULL) {
+ *isActive = true;
+ VIR_FREE(session);
+ }
+ ret = 0;
+
+ return ret;
+}
+
+
static int
virStorageBackendISCSIStartPool(virConnectPtr conn ATTRIBUTE_UNUSED,
virStoragePoolObjPtr pool)
virStorageBackend virStorageBackendISCSI = {
.type = VIR_STORAGE_POOL_ISCSI,
+ .checkPool = virStorageBackendISCSICheckPool,
.startPool = virStorageBackendISCSIStartPool,
.refreshPool = virStorageBackendISCSIRefreshPool,
.stopPool = virStorageBackendISCSIStopPool,
}
+static int
+virStorageBackendLogicalCheckPool(virConnectPtr conn ATTRIBUTE_UNUSED,
+ virStoragePoolObjPtr pool,
+ bool *isActive)
+{
+ char *path;
+
+ *isActive = false;
+ if (virAsprintf(&path, "/dev/%s", pool->def->source.name) < 0) {
+ virReportOOMError();
+ return -1;
+ }
+
+ if (access(path, F_OK) == 0)
+ *isActive = true;
+
+ VIR_FREE(path);
+
+ return 0;
+}
+
static int
virStorageBackendLogicalStartPool(virConnectPtr conn ATTRIBUTE_UNUSED,
virStoragePoolObjPtr pool)
.type = VIR_STORAGE_POOL_LOGICAL,
.findPoolSources = virStorageBackendLogicalFindPoolSources,
+ .checkPool = virStorageBackendLogicalCheckPool,
.startPool = virStorageBackendLogicalStartPool,
.buildPool = virStorageBackendLogicalBuildPool,
.refreshPool = virStorageBackendLogicalRefreshPool,
return retval;
}
+static int
+virStorageBackendMpathCheckPool(virConnectPtr conn ATTRIBUTE_UNUSED,
+ virStoragePoolObjPtr pool ATTRIBUTE_UNUSED,
+ bool *isActive)
+{
+ const char *path = "/dev/mpath";
+
+ *isActive = false;
+
+ if (access(path, F_OK) == 0)
+ *isActive = true;
+
+ return 0;
+}
+
+
static int
virStorageBackendMpathRefreshPool(virConnectPtr conn ATTRIBUTE_UNUSED,
virStorageBackend virStorageBackendMpath = {
.type = VIR_STORAGE_POOL_MPATH,
+ .checkPool = virStorageBackendMpathCheckPool,
.refreshPool = virStorageBackendMpathRefreshPool,
};
return retval;
}
+static int
+virStorageBackendSCSICheckPool(virConnectPtr conn ATTRIBUTE_UNUSED,
+ virStoragePoolObjPtr pool,
+ bool *isActive)
+{
+ char *path;
+
+ *isActive = false;
+ if (virAsprintf(&path, "/sys/class/scsi_host/%s", pool->def->source.adapter) < 0) {
+ virReportOOMError();
+ return -1;
+ }
+
+ if (access(path, F_OK) == 0)
+ *isActive = true;
+
+ VIR_FREE(path);
+
+ return 0;
+}
static int
virStorageBackendSCSIRefreshPool(virConnectPtr conn ATTRIBUTE_UNUSED,
virStorageBackend virStorageBackendSCSI = {
.type = VIR_STORAGE_POOL_SCSI,
+ .checkPool = virStorageBackendSCSICheckPool,
.refreshPool = virStorageBackendSCSIRefreshPool,
};
for (i = 0 ; i < driver->pools.count ; i++) {
virStoragePoolObjPtr pool = driver->pools.objs[i];
+ virStorageBackendPtr backend;
+ bool started = false;
virStoragePoolObjLock(pool);
- if (pool->autostart &&
- !virStoragePoolObjIsActive(pool)) {
- virStorageBackendPtr backend;
- if ((backend = virStorageBackendForType(pool->def->type)) == NULL) {
- VIR_ERROR(_("Missing backend %d"), pool->def->type);
- virStoragePoolObjUnlock(pool);
- continue;
- }
+ if ((backend = virStorageBackendForType(pool->def->type)) == NULL) {
+ VIR_ERROR(_("Missing backend %d"), pool->def->type);
+ virStoragePoolObjUnlock(pool);
+ continue;
+ }
+ if (backend->checkPool &&
+ backend->checkPool(NULL, pool, &started) < 0) {
+ virErrorPtr err = virGetLastError();
+ VIR_ERROR(_("Failed to initialize storage pool '%s': %s"),
+ pool->def->name, err ? err->message :
+ _("no error message found"));
+ virStoragePoolObjUnlock(pool);
+ continue;
+ }
+
+ if (!started &&
+ pool->autostart &&
+ !virStoragePoolObjIsActive(pool)) {
if (backend->startPool &&
backend->startPool(NULL, pool) < 0) {
virErrorPtr err = virGetLastError();
VIR_ERROR(_("Failed to autostart storage pool '%s': %s"),
pool->def->name, err ? err->message :
- "no error message found");
+ _("no error message found"));
virStoragePoolObjUnlock(pool);
continue;
}
+ started = true;
+ }
+ if (started) {
if (backend->refreshPool(NULL, pool) < 0) {
virErrorPtr err = virGetLastError();
if (backend->stopPool)
backend->stopPool(NULL, pool);
VIR_ERROR(_("Failed to autostart storage pool '%s': %s"),
pool->def->name, err ? err->message :
- "no error message found");
+ _("no error message found"));
virStoragePoolObjUnlock(pool);
continue;
}