提交 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 @@
# 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);
......@@ -65,6 +67,7 @@ struct _virStorageBackend {
int type;
virStorageBackendFindPoolSources findPoolSources;
virStorageBackendCheckPool checkPool;
virStorageBackendStartPool startPool;
virStorageBackendBuildPool buildPool;
virStorageBackendRefreshPool refreshPool;
......
......@@ -479,6 +479,30 @@ virStorageBackendFileSystemUnmount(virStoragePoolObjPtr pool) {
#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
......@@ -489,7 +513,6 @@ virStorageBackendFileSystemUnmount(virStoragePoolObjPtr pool) {
*
* Returns 0 on success, -1 on error
*/
#if WITH_STORAGE_FS
static int
virStorageBackendFileSystemStart(virConnectPtr conn ATTRIBUTE_UNUSED,
virStoragePoolObjPtr pool)
......@@ -937,6 +960,7 @@ virStorageBackend virStorageBackendDirectory = {
.type = VIR_STORAGE_POOL_DIR,
.buildPool = virStorageBackendFileSystemBuild,
.checkPool = virStorageBackendFileSystemCheck,
.refreshPool = virStorageBackendFileSystemRefresh,
.deletePool = virStorageBackendFileSystemDelete,
.buildVol = virStorageBackendFileSystemVolBuild,
......@@ -951,6 +975,7 @@ virStorageBackend virStorageBackendFileSystem = {
.type = VIR_STORAGE_POOL_FS,
.buildPool = virStorageBackendFileSystemBuild,
.checkPool = virStorageBackendFileSystemCheck,
.startPool = virStorageBackendFileSystemStart,
.refreshPool = virStorageBackendFileSystemRefresh,
.stopPool = virStorageBackendFileSystemStop,
......@@ -965,6 +990,7 @@ virStorageBackend virStorageBackendNetFileSystem = {
.type = VIR_STORAGE_POOL_NETFS,
.buildPool = virStorageBackendFileSystemBuild,
.checkPool = virStorageBackendFileSystemCheck,
.startPool = virStorageBackendFileSystemStart,
.findPoolSources = virStorageBackendFileSystemNetFindPoolSources,
.refreshPool = virStorageBackendFileSystemRefresh,
......
......@@ -633,6 +633,39 @@ cleanup:
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)
......@@ -730,6 +763,7 @@ cleanup:
virStorageBackend virStorageBackendISCSI = {
.type = VIR_STORAGE_POOL_ISCSI,
.checkPool = virStorageBackendISCSICheckPool,
.startPool = virStorageBackendISCSIStartPool,
.refreshPool = virStorageBackendISCSIRefreshPool,
.stopPool = virStorageBackendISCSIStopPool,
......
......@@ -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
virStorageBackendLogicalStartPool(virConnectPtr conn ATTRIBUTE_UNUSED,
virStoragePoolObjPtr pool)
......@@ -684,6 +705,7 @@ virStorageBackend virStorageBackendLogical = {
.type = VIR_STORAGE_POOL_LOGICAL,
.findPoolSources = virStorageBackendLogicalFindPoolSources,
.checkPool = virStorageBackendLogicalCheckPool,
.startPool = virStorageBackendLogicalStartPool,
.buildPool = virStorageBackendLogicalBuildPool,
.refreshPool = virStorageBackendLogicalRefreshPool,
......
......@@ -291,6 +291,22 @@ out:
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,
......@@ -313,5 +329,6 @@ virStorageBackendMpathRefreshPool(virConnectPtr conn ATTRIBUTE_UNUSED,
virStorageBackend virStorageBackendMpath = {
.type = VIR_STORAGE_POOL_MPATH,
.checkPool = virStorageBackendMpathCheckPool,
.refreshPool = virStorageBackendMpathRefreshPool,
};
......@@ -587,6 +587,26 @@ out:
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,
......@@ -621,5 +641,6 @@ out:
virStorageBackend virStorageBackendSCSI = {
.type = VIR_STORAGE_POOL_SCSI,
.checkPool = virStorageBackendSCSICheckPool,
.refreshPool = virStorageBackendSCSIRefreshPool,
};
......@@ -69,34 +69,49 @@ storageDriverAutostart(virStorageDriverStatePtr driver) {
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;
}
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册