}
+/*
+ * 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
virStorageBackendLogicalCheckPool(virStoragePoolObjPtr pool,
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;
}
virStorageBackendLogicalStartPool(virConnectPtr conn ATTRIBUTE_UNUSED,
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 0;