提交 71b803ac 编写于 作者: J John Ferlan

storage: Add helper to compare logical pool def against pvs output

https://bugzilla.redhat.com/show_bug.cgi?id=1025230

Add a new helper virStorageBackendLogicalMatchPoolSource to compare the
pool's source name against the output from a 'pvs' command to list all
volume group physical volume data on the host.  In addition, compare the
pool's source device list against the particular volume group's device
list to ensure the source device(s) listed for the pool match what the
was listed for the volume group.

Then for pool startup or check API's we need to call this new API in
order to ensure that the pool we're about to start or declare active
during checkPool has a valid definition vs. the running host.
上级 ae5519f7
...@@ -498,11 +498,98 @@ virStorageBackendLogicalFindPoolSources(virConnectPtr conn ATTRIBUTE_UNUSED, ...@@ -498,11 +498,98 @@ virStorageBackendLogicalFindPoolSources(virConnectPtr conn ATTRIBUTE_UNUSED,
} }
/*
* virStorageBackendLogicalMatchPoolSource
* @pool: Pointer to the source pool object
*
* Search the output generated by a 'pvs --noheadings -o pv_name,vg_name'
* to match the 'vg_name' with the pool def->source.name and for the list
* of pool def->source.devices[].
*
* Returns true if the volume group name matches the pool's source.name
* and at least one of the pool's def->source.devices[] matches the
* list of physical device names listed for the pool. Return false if
* we cannot find a matching volume group name and if we cannot match
* the any device list members.
*/
static bool
virStorageBackendLogicalMatchPoolSource(virStoragePoolObjPtr pool)
{
virStoragePoolSourceList sourceList;
virStoragePoolSource *thisSource;
size_t i, j;
int matchcount = 0;
bool ret = false;
memset(&sourceList, 0, sizeof(sourceList));
sourceList.type = VIR_STORAGE_POOL_LOGICAL;
if (virStorageBackendLogicalGetPoolSources(&sourceList) < 0)
goto cleanup;
/* Search the pvs output for this pool's source.name */
for (i = 0; i < sourceList.nsources; i++) {
thisSource = &sourceList.sources[i];
if (STREQ(thisSource->name, pool->def->source.name))
break;
}
if (i == sourceList.nsources) {
virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
_("cannot find logical volume group name '%s'"),
pool->def->source.name);
goto cleanup;
}
/* Let's make sure the pool's device(s) match what the pvs output has
* for volume group devices.
*/
for (i = 0; i < pool->def->source.ndevice; i++) {
for (j = 0; j < thisSource->ndevice; j++) {
if (STREQ(pool->def->source.devices[i].path,
thisSource->devices[j].path))
matchcount++;
}
}
/* If we didn't find any matches, then this pool has listed (a) source
* device path(s) that don't/doesn't match what was created for the pool
*/
if (matchcount == 0) {
virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
_("cannot find any matching source devices for logical "
"volume group '%s'"), pool->def->source.name);
goto cleanup;
}
/* Either there's more devices in the pool source device list or there's
* more devices in the pvs output. Could easily happen if someone decides
* to 'add' to or 'remove' from the volume group outside of libvirt's
* knowledge. Rather than fail on that, provide a warning and move on.
*/
if (matchcount != pool->def->source.ndevice)
VIR_WARN("pool device list count doesn't match pvs device list count");
ret = true;
cleanup:
for (i = 0; i < sourceList.nsources; i++)
virStoragePoolSourceClear(&sourceList.sources[i]);
VIR_FREE(sourceList.sources);
return ret;
}
static int static int
virStorageBackendLogicalCheckPool(virStoragePoolObjPtr pool, virStorageBackendLogicalCheckPool(virStoragePoolObjPtr pool,
bool *isActive) bool *isActive)
{ {
*isActive = virFileExists(pool->def->target.path); /* If we can find the target.path as well as ensure that the
* pool's def source
*/
*isActive = virFileExists(pool->def->target.path) &&
virStorageBackendLogicalMatchPoolSource(pool);
return 0; return 0;
} }
...@@ -510,7 +597,11 @@ static int ...@@ -510,7 +597,11 @@ static int
virStorageBackendLogicalStartPool(virConnectPtr conn ATTRIBUTE_UNUSED, virStorageBackendLogicalStartPool(virConnectPtr conn ATTRIBUTE_UNUSED,
virStoragePoolObjPtr pool) virStoragePoolObjPtr pool)
{ {
if (virStorageBackendLogicalSetActive(pool, 1) < 0) /* Let's make sure that the pool's name matches the pvs output and
* that the pool's source devices match the pvs output.
*/
if (!virStorageBackendLogicalMatchPoolSource(pool) ||
virStorageBackendLogicalSetActive(pool, 1) < 0)
return -1; return -1;
return 0; return 0;
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册