提交 1b7e0b1a 编写于 作者: D Daniel P. Berrange

Check whether pools are already active upon libvirtd startup

When libvirt starts up all storage pools default to the inactive
state, even if the underlying storage is already active on the
host. This introduces a new API into the internal storage backend
drivers that checks whether a storage pool is already active. If
the pool is active at libvirtd startup, the volume list will be
immediately populated.

* src/storage/storage_backend.h: New internal API for checking
  storage pool state
* src/storage/storage_driver.c: Check whether a pool is active
  upon driver startup
* src/storage/storage_backend_fs.c, src/storage/storage_backend_iscsi.c,
  src/storage/storage_backend_logical.c, src/storage/storage_backend_mpath.c,
  src/storage/storage_backend_scsi.c: Add checks for pool state
上级 4d0350fc
...@@ -25,10 +25,12 @@ ...@@ -25,10 +25,12 @@
# define __VIR_STORAGE_BACKEND_H__ # define __VIR_STORAGE_BACKEND_H__
# include <stdint.h> # include <stdint.h>
# include <stdbool.h>
# include "internal.h" # include "internal.h"
# include "storage_conf.h" # include "storage_conf.h"
typedef char * (*virStorageBackendFindPoolSources)(virConnectPtr conn, const char *srcSpec, unsigned int flags); 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 (*virStorageBackendStartPool)(virConnectPtr conn, virStoragePoolObjPtr pool);
typedef int (*virStorageBackendBuildPool)(virConnectPtr conn, virStoragePoolObjPtr pool, unsigned int flags); typedef int (*virStorageBackendBuildPool)(virConnectPtr conn, virStoragePoolObjPtr pool, unsigned int flags);
typedef int (*virStorageBackendRefreshPool)(virConnectPtr conn, virStoragePoolObjPtr pool); typedef int (*virStorageBackendRefreshPool)(virConnectPtr conn, virStoragePoolObjPtr pool);
...@@ -65,6 +67,7 @@ struct _virStorageBackend { ...@@ -65,6 +67,7 @@ struct _virStorageBackend {
int type; int type;
virStorageBackendFindPoolSources findPoolSources; virStorageBackendFindPoolSources findPoolSources;
virStorageBackendCheckPool checkPool;
virStorageBackendStartPool startPool; virStorageBackendStartPool startPool;
virStorageBackendBuildPool buildPool; virStorageBackendBuildPool buildPool;
virStorageBackendRefreshPool refreshPool; virStorageBackendRefreshPool refreshPool;
......
...@@ -479,6 +479,30 @@ virStorageBackendFileSystemUnmount(virStoragePoolObjPtr pool) { ...@@ -479,6 +479,30 @@ virStorageBackendFileSystemUnmount(virStoragePoolObjPtr pool) {
#endif /* WITH_STORAGE_FS */ #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 * @conn connection to report errors against
* @pool storage pool to start * @pool storage pool to start
...@@ -489,7 +513,6 @@ virStorageBackendFileSystemUnmount(virStoragePoolObjPtr pool) { ...@@ -489,7 +513,6 @@ virStorageBackendFileSystemUnmount(virStoragePoolObjPtr pool) {
* *
* Returns 0 on success, -1 on error * Returns 0 on success, -1 on error
*/ */
#if WITH_STORAGE_FS
static int static int
virStorageBackendFileSystemStart(virConnectPtr conn ATTRIBUTE_UNUSED, virStorageBackendFileSystemStart(virConnectPtr conn ATTRIBUTE_UNUSED,
virStoragePoolObjPtr pool) virStoragePoolObjPtr pool)
...@@ -937,6 +960,7 @@ virStorageBackend virStorageBackendDirectory = { ...@@ -937,6 +960,7 @@ virStorageBackend virStorageBackendDirectory = {
.type = VIR_STORAGE_POOL_DIR, .type = VIR_STORAGE_POOL_DIR,
.buildPool = virStorageBackendFileSystemBuild, .buildPool = virStorageBackendFileSystemBuild,
.checkPool = virStorageBackendFileSystemCheck,
.refreshPool = virStorageBackendFileSystemRefresh, .refreshPool = virStorageBackendFileSystemRefresh,
.deletePool = virStorageBackendFileSystemDelete, .deletePool = virStorageBackendFileSystemDelete,
.buildVol = virStorageBackendFileSystemVolBuild, .buildVol = virStorageBackendFileSystemVolBuild,
...@@ -951,6 +975,7 @@ virStorageBackend virStorageBackendFileSystem = { ...@@ -951,6 +975,7 @@ virStorageBackend virStorageBackendFileSystem = {
.type = VIR_STORAGE_POOL_FS, .type = VIR_STORAGE_POOL_FS,
.buildPool = virStorageBackendFileSystemBuild, .buildPool = virStorageBackendFileSystemBuild,
.checkPool = virStorageBackendFileSystemCheck,
.startPool = virStorageBackendFileSystemStart, .startPool = virStorageBackendFileSystemStart,
.refreshPool = virStorageBackendFileSystemRefresh, .refreshPool = virStorageBackendFileSystemRefresh,
.stopPool = virStorageBackendFileSystemStop, .stopPool = virStorageBackendFileSystemStop,
...@@ -965,6 +990,7 @@ virStorageBackend virStorageBackendNetFileSystem = { ...@@ -965,6 +990,7 @@ virStorageBackend virStorageBackendNetFileSystem = {
.type = VIR_STORAGE_POOL_NETFS, .type = VIR_STORAGE_POOL_NETFS,
.buildPool = virStorageBackendFileSystemBuild, .buildPool = virStorageBackendFileSystemBuild,
.checkPool = virStorageBackendFileSystemCheck,
.startPool = virStorageBackendFileSystemStart, .startPool = virStorageBackendFileSystemStart,
.findPoolSources = virStorageBackendFileSystemNetFindPoolSources, .findPoolSources = virStorageBackendFileSystemNetFindPoolSources,
.refreshPool = virStorageBackendFileSystemRefresh, .refreshPool = virStorageBackendFileSystemRefresh,
......
...@@ -633,6 +633,39 @@ cleanup: ...@@ -633,6 +633,39 @@ cleanup:
return ret; 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 static int
virStorageBackendISCSIStartPool(virConnectPtr conn ATTRIBUTE_UNUSED, virStorageBackendISCSIStartPool(virConnectPtr conn ATTRIBUTE_UNUSED,
virStoragePoolObjPtr pool) virStoragePoolObjPtr pool)
...@@ -730,6 +763,7 @@ cleanup: ...@@ -730,6 +763,7 @@ cleanup:
virStorageBackend virStorageBackendISCSI = { virStorageBackend virStorageBackendISCSI = {
.type = VIR_STORAGE_POOL_ISCSI, .type = VIR_STORAGE_POOL_ISCSI,
.checkPool = virStorageBackendISCSICheckPool,
.startPool = virStorageBackendISCSIStartPool, .startPool = virStorageBackendISCSIStartPool,
.refreshPool = virStorageBackendISCSIRefreshPool, .refreshPool = virStorageBackendISCSIRefreshPool,
.stopPool = virStorageBackendISCSIStopPool, .stopPool = virStorageBackendISCSIStopPool,
......
...@@ -360,6 +360,27 @@ virStorageBackendLogicalFindPoolSources(virConnectPtr conn ATTRIBUTE_UNUSED, ...@@ -360,6 +360,27 @@ virStorageBackendLogicalFindPoolSources(virConnectPtr conn ATTRIBUTE_UNUSED,
} }
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 static int
virStorageBackendLogicalStartPool(virConnectPtr conn ATTRIBUTE_UNUSED, virStorageBackendLogicalStartPool(virConnectPtr conn ATTRIBUTE_UNUSED,
virStoragePoolObjPtr pool) virStoragePoolObjPtr pool)
...@@ -684,6 +705,7 @@ virStorageBackend virStorageBackendLogical = { ...@@ -684,6 +705,7 @@ virStorageBackend virStorageBackendLogical = {
.type = VIR_STORAGE_POOL_LOGICAL, .type = VIR_STORAGE_POOL_LOGICAL,
.findPoolSources = virStorageBackendLogicalFindPoolSources, .findPoolSources = virStorageBackendLogicalFindPoolSources,
.checkPool = virStorageBackendLogicalCheckPool,
.startPool = virStorageBackendLogicalStartPool, .startPool = virStorageBackendLogicalStartPool,
.buildPool = virStorageBackendLogicalBuildPool, .buildPool = virStorageBackendLogicalBuildPool,
.refreshPool = virStorageBackendLogicalRefreshPool, .refreshPool = virStorageBackendLogicalRefreshPool,
......
...@@ -291,6 +291,22 @@ out: ...@@ -291,6 +291,22 @@ out:
return retval; 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 static int
virStorageBackendMpathRefreshPool(virConnectPtr conn ATTRIBUTE_UNUSED, virStorageBackendMpathRefreshPool(virConnectPtr conn ATTRIBUTE_UNUSED,
...@@ -313,5 +329,6 @@ virStorageBackendMpathRefreshPool(virConnectPtr conn ATTRIBUTE_UNUSED, ...@@ -313,5 +329,6 @@ virStorageBackendMpathRefreshPool(virConnectPtr conn ATTRIBUTE_UNUSED,
virStorageBackend virStorageBackendMpath = { virStorageBackend virStorageBackendMpath = {
.type = VIR_STORAGE_POOL_MPATH, .type = VIR_STORAGE_POOL_MPATH,
.checkPool = virStorageBackendMpathCheckPool,
.refreshPool = virStorageBackendMpathRefreshPool, .refreshPool = virStorageBackendMpathRefreshPool,
}; };
...@@ -587,6 +587,26 @@ out: ...@@ -587,6 +587,26 @@ out:
return retval; 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 static int
virStorageBackendSCSIRefreshPool(virConnectPtr conn ATTRIBUTE_UNUSED, virStorageBackendSCSIRefreshPool(virConnectPtr conn ATTRIBUTE_UNUSED,
...@@ -621,5 +641,6 @@ out: ...@@ -621,5 +641,6 @@ out:
virStorageBackend virStorageBackendSCSI = { virStorageBackend virStorageBackendSCSI = {
.type = VIR_STORAGE_POOL_SCSI, .type = VIR_STORAGE_POOL_SCSI,
.checkPool = virStorageBackendSCSICheckPool,
.refreshPool = virStorageBackendSCSIRefreshPool, .refreshPool = virStorageBackendSCSIRefreshPool,
}; };
...@@ -69,34 +69,49 @@ storageDriverAutostart(virStorageDriverStatePtr driver) { ...@@ -69,34 +69,49 @@ storageDriverAutostart(virStorageDriverStatePtr driver) {
for (i = 0 ; i < driver->pools.count ; i++) { for (i = 0 ; i < driver->pools.count ; i++) {
virStoragePoolObjPtr pool = driver->pools.objs[i]; virStoragePoolObjPtr pool = driver->pools.objs[i];
virStorageBackendPtr backend;
bool started = false;
virStoragePoolObjLock(pool); virStoragePoolObjLock(pool);
if (pool->autostart && if ((backend = virStorageBackendForType(pool->def->type)) == NULL) {
!virStoragePoolObjIsActive(pool)) { VIR_ERROR(_("Missing backend %d"), pool->def->type);
virStorageBackendPtr backend; virStoragePoolObjUnlock(pool);
if ((backend = virStorageBackendForType(pool->def->type)) == NULL) { continue;
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 && if (backend->startPool &&
backend->startPool(NULL, pool) < 0) { backend->startPool(NULL, pool) < 0) {
virErrorPtr err = virGetLastError(); virErrorPtr err = virGetLastError();
VIR_ERROR(_("Failed to autostart storage pool '%s': %s"), VIR_ERROR(_("Failed to autostart storage pool '%s': %s"),
pool->def->name, err ? err->message : pool->def->name, err ? err->message :
"no error message found"); _("no error message found"));
virStoragePoolObjUnlock(pool); virStoragePoolObjUnlock(pool);
continue; continue;
} }
started = true;
}
if (started) {
if (backend->refreshPool(NULL, pool) < 0) { if (backend->refreshPool(NULL, pool) < 0) {
virErrorPtr err = virGetLastError(); virErrorPtr err = virGetLastError();
if (backend->stopPool) if (backend->stopPool)
backend->stopPool(NULL, pool); backend->stopPool(NULL, pool);
VIR_ERROR(_("Failed to autostart storage pool '%s': %s"), VIR_ERROR(_("Failed to autostart storage pool '%s': %s"),
pool->def->name, err ? err->message : pool->def->name, err ? err->message :
"no error message found"); _("no error message found"));
virStoragePoolObjUnlock(pool); virStoragePoolObjUnlock(pool);
continue; continue;
} }
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册