This function is going to be made static in used in virStoragePoolObjAssignDef(). Therefore move it and all the static functions it calls a few lines up. Signed-off-by: Michal Privoznik <mprivozn@xxxxxxxxxx> --- src/conf/virstorageobj.c | 788 +++++++++++++++++++++++------------------------ 1 file changed, 394 insertions(+), 394 deletions(-) diff --git a/src/conf/virstorageobj.c b/src/conf/virstorageobj.c index ea0ae6fd86..b710ec652d 100644 --- a/src/conf/virstorageobj.c +++ b/src/conf/virstorageobj.c @@ -1118,6 +1118,400 @@ virStoragePoolObjIsDuplicate(virStoragePoolObjListPtr pools, } +static int +getSCSIHostNumber(virStorageAdapterSCSIHostPtr scsi_host, + unsigned int *hostnum) +{ + int ret = -1; + unsigned int num; + char *name = NULL; + + if (scsi_host->has_parent) { + virPCIDeviceAddressPtr addr = &scsi_host->parentaddr; + unsigned int unique_id = scsi_host->unique_id; + + if (!(name = virSCSIHostGetNameByParentaddr(addr->domain, + addr->bus, + addr->slot, + addr->function, + unique_id))) + goto cleanup; + if (virSCSIHostGetNumber(name, &num) < 0) + goto cleanup; + } else { + if (virSCSIHostGetNumber(scsi_host->name, &num) < 0) + goto cleanup; + } + + *hostnum = num; + ret = 0; + + cleanup: + VIR_FREE(name); + return ret; +} + + +static bool +virStorageIsSameHostnum(const char *name, + unsigned int scsi_hostnum) +{ + unsigned int fc_hostnum; + + if (virSCSIHostGetNumber(name, &fc_hostnum) == 0 && + scsi_hostnum == fc_hostnum) + return true; + + return false; +} + + +/* + * matchFCHostToSCSIHost: + * + * @conn: Connection pointer + * @fchost: fc_host adapter ptr (either def or pool->def) + * @scsi_hostnum: Already determined "scsi_pool" hostnum + * + * Returns true/false whether there is a match between the incoming + * fc_adapter host# and the scsi_host host# + */ +static bool +matchFCHostToSCSIHost(virConnectPtr conn, + virStorageAdapterFCHostPtr fchost, + unsigned int scsi_hostnum) +{ + bool ret = false; + char *name = NULL; + char *scsi_host_name = NULL; + char *parent_name = NULL; + + /* If we have a parent defined, get its hostnum, and compare to the + * scsi_hostnum. If they are the same, then we have a match + */ + if (fchost->parent && + virStorageIsSameHostnum(fchost->parent, scsi_hostnum)) + return true; + + /* If we find an fc adapter name, then either libvirt created a vHBA + * for this fc_host or a 'virsh nodedev-create' generated a vHBA. + */ + if ((name = virVHBAGetHostByWWN(NULL, fchost->wwnn, fchost->wwpn))) { + + /* Get the scsi_hostN for the vHBA in order to see if it + * matches our scsi_hostnum + */ + if (virStorageIsSameHostnum(name, scsi_hostnum)) { + ret = true; + goto cleanup; + } + + /* We weren't provided a parent, so we have to query the node + * device driver in order to ascertain the parent of the vHBA. + * If the parent fc_hostnum is the same as the scsi_hostnum, we + * have a match. + */ + if (conn && !fchost->parent) { + if (virAsprintf(&scsi_host_name, "scsi_%s", name) < 0) + goto cleanup; + if ((parent_name = virNodeDeviceGetParentName(conn, + scsi_host_name))) { + if (virStorageIsSameHostnum(parent_name, scsi_hostnum)) { + ret = true; + goto cleanup; + } + } else { + /* Throw away the error and fall through */ + virResetLastError(); + VIR_DEBUG("Could not determine parent vHBA"); + } + } + } + + /* NB: Lack of a name means that this vHBA hasn't yet been created, + * which means our scsi_host cannot be using the vHBA. Furthermore, + * lack of a provided parent means libvirt is going to choose the + * "best" fc_host capable adapter based on availabilty. That could + * conflict with an existing scsi_host definition, but there's no + * way to know that now. + */ + + cleanup: + VIR_FREE(name); + VIR_FREE(parent_name); + VIR_FREE(scsi_host_name); + return ret; +} + + +static bool +matchSCSIAdapterParent(virStorageAdapterSCSIHostPtr pool_scsi_host, + virStorageAdapterSCSIHostPtr def_scsi_host) +{ + virPCIDeviceAddressPtr pooladdr = &pool_scsi_host->parentaddr; + virPCIDeviceAddressPtr defaddr = &def_scsi_host->parentaddr; + + if (pooladdr->domain == defaddr->domain && + pooladdr->bus == defaddr->bus && + pooladdr->slot == defaddr->slot && + pooladdr->function == defaddr->function && + pool_scsi_host->unique_id == def_scsi_host->unique_id) + return true; + + return false; +} + + +static bool +virStoragePoolSourceMatchSingleHost(virStoragePoolSourcePtr poolsrc, + virStoragePoolSourcePtr defsrc) +{ + if (poolsrc->nhost != 1 && defsrc->nhost != 1) + return false; + + if (defsrc->hosts[0].port && + poolsrc->hosts[0].port != defsrc->hosts[0].port) + return false; + + return STREQ(poolsrc->hosts[0].name, defsrc->hosts[0].name); +} + + +static bool +virStoragePoolSourceISCSIMatch(virStoragePoolObjPtr obj, + virStoragePoolDefPtr def) +{ + virStoragePoolSourcePtr poolsrc = &obj->def->source; + virStoragePoolSourcePtr defsrc = &def->source; + + /* NB: Do not check the source host name */ + if (STRNEQ_NULLABLE(poolsrc->initiator.iqn, defsrc->initiator.iqn)) + return false; + + return true; +} + + +static virStoragePoolObjPtr +virStoragePoolObjSourceMatchTypeDIR(virStoragePoolObjPtr obj, + virStoragePoolDefPtr def) +{ + if (obj->def->type == VIR_STORAGE_POOL_DIR) { + if (STREQ(obj->def->target.path, def->target.path)) + return obj; + } else if (obj->def->type == VIR_STORAGE_POOL_GLUSTER) { + if (STREQ(obj->def->source.name, def->source.name) && + STREQ_NULLABLE(obj->def->source.dir, def->source.dir) && + virStoragePoolSourceMatchSingleHost(&obj->def->source, + &def->source)) + return obj; + } else if (obj->def->type == VIR_STORAGE_POOL_NETFS) { + if (STREQ(obj->def->source.dir, def->source.dir) && + virStoragePoolSourceMatchSingleHost(&obj->def->source, + &def->source)) + return obj; + } + + return NULL; +} + + +static virStoragePoolObjPtr +virStoragePoolObjSourceMatchTypeISCSI(virStoragePoolObjPtr obj, + virStoragePoolDefPtr def, + virConnectPtr conn) +{ + virStorageAdapterPtr pool_adapter = &obj->def->source.adapter; + virStorageAdapterPtr def_adapter = &def->source.adapter; + virStorageAdapterSCSIHostPtr pool_scsi_host; + virStorageAdapterSCSIHostPtr def_scsi_host; + virStorageAdapterFCHostPtr pool_fchost; + virStorageAdapterFCHostPtr def_fchost; + unsigned int pool_hostnum; + unsigned int def_hostnum; + unsigned int scsi_hostnum; + + if (pool_adapter->type == VIR_STORAGE_ADAPTER_TYPE_FC_HOST && + def_adapter->type == VIR_STORAGE_ADAPTER_TYPE_FC_HOST) { + pool_fchost = &pool_adapter->data.fchost; + def_fchost = &def_adapter->data.fchost; + + if (STREQ(pool_fchost->wwnn, def_fchost->wwnn) && + STREQ(pool_fchost->wwpn, def_fchost->wwpn)) + return obj; + } else if (pool_adapter->type == VIR_STORAGE_ADAPTER_TYPE_SCSI_HOST && + def_adapter->type == VIR_STORAGE_ADAPTER_TYPE_SCSI_HOST) { + pool_scsi_host = &pool_adapter->data.scsi_host; + def_scsi_host = &def_adapter->data.scsi_host; + + if (pool_scsi_host->has_parent && + def_scsi_host->has_parent && + matchSCSIAdapterParent(pool_scsi_host, def_scsi_host)) + return obj; + + if (getSCSIHostNumber(pool_scsi_host, &pool_hostnum) < 0 || + getSCSIHostNumber(def_scsi_host, &def_hostnum) < 0) + return NULL; + if (pool_hostnum == def_hostnum) + return obj; + } else if (pool_adapter->type == VIR_STORAGE_ADAPTER_TYPE_FC_HOST && + def_adapter->type == VIR_STORAGE_ADAPTER_TYPE_SCSI_HOST) { + pool_fchost = &pool_adapter->data.fchost; + def_scsi_host = &def_adapter->data.scsi_host; + + /* Get the scsi_hostN for the scsi_host source adapter def */ + if (getSCSIHostNumber(def_scsi_host, &scsi_hostnum) < 0) + return NULL; + + if (matchFCHostToSCSIHost(conn, pool_fchost, scsi_hostnum)) + return obj; + + } else if (pool_adapter->type == VIR_STORAGE_ADAPTER_TYPE_SCSI_HOST && + def_adapter->type == VIR_STORAGE_ADAPTER_TYPE_FC_HOST) { + pool_scsi_host = &pool_adapter->data.scsi_host; + def_fchost = &def_adapter->data.fchost; + + if (getSCSIHostNumber(pool_scsi_host, &scsi_hostnum) < 0) + return NULL; + + if (matchFCHostToSCSIHost(conn, def_fchost, scsi_hostnum)) + return obj; + } + + return NULL; +} + + +static virStoragePoolObjPtr +virStoragePoolObjSourceMatchTypeDEVICE(virStoragePoolObjPtr obj, + virStoragePoolDefPtr def) +{ + virStoragePoolObjPtr matchobj = NULL; + + if (obj->def->type == VIR_STORAGE_POOL_ISCSI) { + if (def->type != VIR_STORAGE_POOL_ISCSI) + return NULL; + + if ((matchobj = virStoragePoolSourceFindDuplicateDevices(obj, def))) { + if (!virStoragePoolSourceISCSIMatch(matchobj, def)) + return NULL; + } + return matchobj; + } + + if (def->type == VIR_STORAGE_POOL_ISCSI) + return NULL; + + /* VIR_STORAGE_POOL_FS + * VIR_STORAGE_POOL_LOGICAL + * VIR_STORAGE_POOL_DISK + * VIR_STORAGE_POOL_ZFS */ + return virStoragePoolSourceFindDuplicateDevices(obj, def); +} + + +struct _virStoragePoolObjFindDuplicateData { + virConnectPtr conn; + virStoragePoolDefPtr def; +}; + +static int +virStoragePoolObjSourceFindDuplicateCb(const void *payload, + const void *name ATTRIBUTE_UNUSED, + const void *opaque) +{ + virStoragePoolObjPtr obj = (virStoragePoolObjPtr) payload; + struct _virStoragePoolObjFindDuplicateData *data = + (struct _virStoragePoolObjFindDuplicateData *) opaque; + + /* Don't match against ourself if re-defining existing pool ! */ + if (STREQ(obj->def->name, data->def->name)) + return 0; + + switch ((virStoragePoolType)obj->def->type) { + case VIR_STORAGE_POOL_DIR: + case VIR_STORAGE_POOL_GLUSTER: + case VIR_STORAGE_POOL_NETFS: + if (data->def->type == obj->def->type && + virStoragePoolObjSourceMatchTypeDIR(obj, data->def)) + return 1; + break; + + case VIR_STORAGE_POOL_SCSI: + if (data->def->type == obj->def->type && + virStoragePoolObjSourceMatchTypeISCSI(obj, data->def, data->conn)) + return 1; + break; + + case VIR_STORAGE_POOL_ISCSI: + case VIR_STORAGE_POOL_ISCSI_DIRECT: + case VIR_STORAGE_POOL_FS: + case VIR_STORAGE_POOL_LOGICAL: + case VIR_STORAGE_POOL_DISK: + case VIR_STORAGE_POOL_ZFS: + if ((data->def->type == VIR_STORAGE_POOL_ISCSI || + data->def->type == VIR_STORAGE_POOL_ISCSI_DIRECT || + data->def->type == VIR_STORAGE_POOL_FS || + data->def->type == VIR_STORAGE_POOL_LOGICAL || + data->def->type == VIR_STORAGE_POOL_DISK || + data->def->type == VIR_STORAGE_POOL_ZFS) && + virStoragePoolObjSourceMatchTypeDEVICE(obj, data->def)) + return 1; + break; + + case VIR_STORAGE_POOL_SHEEPDOG: + if (data->def->type == obj->def->type && + virStoragePoolSourceMatchSingleHost(&obj->def->source, + &data->def->source)) + return 1; + break; + + case VIR_STORAGE_POOL_MPATH: + /* Only one mpath pool is valid per host */ + if (data->def->type == obj->def->type) + return 1; + break; + + case VIR_STORAGE_POOL_VSTORAGE: + if (data->def->type == obj->def->type && + STREQ(obj->def->source.name, data->def->source.name)) + return 1; + break; + + case VIR_STORAGE_POOL_RBD: + case VIR_STORAGE_POOL_LAST: + break; + } + + return 0; +} + + +int +virStoragePoolObjSourceFindDuplicate(virConnectPtr conn, + virStoragePoolObjListPtr pools, + virStoragePoolDefPtr def) +{ + struct _virStoragePoolObjFindDuplicateData data = { .conn = conn, + .def = def }; + virStoragePoolObjPtr obj = NULL; + + virObjectRWLockRead(pools); + obj = virHashSearch(pools->objs, virStoragePoolObjSourceFindDuplicateCb, + &data, NULL); + virObjectRWUnlock(pools); + + if (obj) { + virReportError(VIR_ERR_OPERATION_FAILED, + _("Storage source conflict with pool: '%s'"), + obj->def->name); + return -1; + } + + return 0; +} + + /** * virStoragePoolObjAssignDef: * @pools: Storage Pool object list pointer @@ -1529,400 +1923,6 @@ virStoragePoolObjGetNames(virStoragePoolObjListPtr pools, } -static int -getSCSIHostNumber(virStorageAdapterSCSIHostPtr scsi_host, - unsigned int *hostnum) -{ - int ret = -1; - unsigned int num; - char *name = NULL; - - if (scsi_host->has_parent) { - virPCIDeviceAddressPtr addr = &scsi_host->parentaddr; - unsigned int unique_id = scsi_host->unique_id; - - if (!(name = virSCSIHostGetNameByParentaddr(addr->domain, - addr->bus, - addr->slot, - addr->function, - unique_id))) - goto cleanup; - if (virSCSIHostGetNumber(name, &num) < 0) - goto cleanup; - } else { - if (virSCSIHostGetNumber(scsi_host->name, &num) < 0) - goto cleanup; - } - - *hostnum = num; - ret = 0; - - cleanup: - VIR_FREE(name); - return ret; -} - - -static bool -virStorageIsSameHostnum(const char *name, - unsigned int scsi_hostnum) -{ - unsigned int fc_hostnum; - - if (virSCSIHostGetNumber(name, &fc_hostnum) == 0 && - scsi_hostnum == fc_hostnum) - return true; - - return false; -} - - -/* - * matchFCHostToSCSIHost: - * - * @conn: Connection pointer - * @fchost: fc_host adapter ptr (either def or pool->def) - * @scsi_hostnum: Already determined "scsi_pool" hostnum - * - * Returns true/false whether there is a match between the incoming - * fc_adapter host# and the scsi_host host# - */ -static bool -matchFCHostToSCSIHost(virConnectPtr conn, - virStorageAdapterFCHostPtr fchost, - unsigned int scsi_hostnum) -{ - bool ret = false; - char *name = NULL; - char *scsi_host_name = NULL; - char *parent_name = NULL; - - /* If we have a parent defined, get its hostnum, and compare to the - * scsi_hostnum. If they are the same, then we have a match - */ - if (fchost->parent && - virStorageIsSameHostnum(fchost->parent, scsi_hostnum)) - return true; - - /* If we find an fc adapter name, then either libvirt created a vHBA - * for this fc_host or a 'virsh nodedev-create' generated a vHBA. - */ - if ((name = virVHBAGetHostByWWN(NULL, fchost->wwnn, fchost->wwpn))) { - - /* Get the scsi_hostN for the vHBA in order to see if it - * matches our scsi_hostnum - */ - if (virStorageIsSameHostnum(name, scsi_hostnum)) { - ret = true; - goto cleanup; - } - - /* We weren't provided a parent, so we have to query the node - * device driver in order to ascertain the parent of the vHBA. - * If the parent fc_hostnum is the same as the scsi_hostnum, we - * have a match. - */ - if (conn && !fchost->parent) { - if (virAsprintf(&scsi_host_name, "scsi_%s", name) < 0) - goto cleanup; - if ((parent_name = virNodeDeviceGetParentName(conn, - scsi_host_name))) { - if (virStorageIsSameHostnum(parent_name, scsi_hostnum)) { - ret = true; - goto cleanup; - } - } else { - /* Throw away the error and fall through */ - virResetLastError(); - VIR_DEBUG("Could not determine parent vHBA"); - } - } - } - - /* NB: Lack of a name means that this vHBA hasn't yet been created, - * which means our scsi_host cannot be using the vHBA. Furthermore, - * lack of a provided parent means libvirt is going to choose the - * "best" fc_host capable adapter based on availabilty. That could - * conflict with an existing scsi_host definition, but there's no - * way to know that now. - */ - - cleanup: - VIR_FREE(name); - VIR_FREE(parent_name); - VIR_FREE(scsi_host_name); - return ret; -} - - -static bool -matchSCSIAdapterParent(virStorageAdapterSCSIHostPtr pool_scsi_host, - virStorageAdapterSCSIHostPtr def_scsi_host) -{ - virPCIDeviceAddressPtr pooladdr = &pool_scsi_host->parentaddr; - virPCIDeviceAddressPtr defaddr = &def_scsi_host->parentaddr; - - if (pooladdr->domain == defaddr->domain && - pooladdr->bus == defaddr->bus && - pooladdr->slot == defaddr->slot && - pooladdr->function == defaddr->function && - pool_scsi_host->unique_id == def_scsi_host->unique_id) - return true; - - return false; -} - - -static bool -virStoragePoolSourceMatchSingleHost(virStoragePoolSourcePtr poolsrc, - virStoragePoolSourcePtr defsrc) -{ - if (poolsrc->nhost != 1 && defsrc->nhost != 1) - return false; - - if (defsrc->hosts[0].port && - poolsrc->hosts[0].port != defsrc->hosts[0].port) - return false; - - return STREQ(poolsrc->hosts[0].name, defsrc->hosts[0].name); -} - - -static bool -virStoragePoolSourceISCSIMatch(virStoragePoolObjPtr obj, - virStoragePoolDefPtr def) -{ - virStoragePoolSourcePtr poolsrc = &obj->def->source; - virStoragePoolSourcePtr defsrc = &def->source; - - /* NB: Do not check the source host name */ - if (STRNEQ_NULLABLE(poolsrc->initiator.iqn, defsrc->initiator.iqn)) - return false; - - return true; -} - - -static virStoragePoolObjPtr -virStoragePoolObjSourceMatchTypeDIR(virStoragePoolObjPtr obj, - virStoragePoolDefPtr def) -{ - if (obj->def->type == VIR_STORAGE_POOL_DIR) { - if (STREQ(obj->def->target.path, def->target.path)) - return obj; - } else if (obj->def->type == VIR_STORAGE_POOL_GLUSTER) { - if (STREQ(obj->def->source.name, def->source.name) && - STREQ_NULLABLE(obj->def->source.dir, def->source.dir) && - virStoragePoolSourceMatchSingleHost(&obj->def->source, - &def->source)) - return obj; - } else if (obj->def->type == VIR_STORAGE_POOL_NETFS) { - if (STREQ(obj->def->source.dir, def->source.dir) && - virStoragePoolSourceMatchSingleHost(&obj->def->source, - &def->source)) - return obj; - } - - return NULL; -} - - -static virStoragePoolObjPtr -virStoragePoolObjSourceMatchTypeISCSI(virStoragePoolObjPtr obj, - virStoragePoolDefPtr def, - virConnectPtr conn) -{ - virStorageAdapterPtr pool_adapter = &obj->def->source.adapter; - virStorageAdapterPtr def_adapter = &def->source.adapter; - virStorageAdapterSCSIHostPtr pool_scsi_host; - virStorageAdapterSCSIHostPtr def_scsi_host; - virStorageAdapterFCHostPtr pool_fchost; - virStorageAdapterFCHostPtr def_fchost; - unsigned int pool_hostnum; - unsigned int def_hostnum; - unsigned int scsi_hostnum; - - if (pool_adapter->type == VIR_STORAGE_ADAPTER_TYPE_FC_HOST && - def_adapter->type == VIR_STORAGE_ADAPTER_TYPE_FC_HOST) { - pool_fchost = &pool_adapter->data.fchost; - def_fchost = &def_adapter->data.fchost; - - if (STREQ(pool_fchost->wwnn, def_fchost->wwnn) && - STREQ(pool_fchost->wwpn, def_fchost->wwpn)) - return obj; - } else if (pool_adapter->type == VIR_STORAGE_ADAPTER_TYPE_SCSI_HOST && - def_adapter->type == VIR_STORAGE_ADAPTER_TYPE_SCSI_HOST) { - pool_scsi_host = &pool_adapter->data.scsi_host; - def_scsi_host = &def_adapter->data.scsi_host; - - if (pool_scsi_host->has_parent && - def_scsi_host->has_parent && - matchSCSIAdapterParent(pool_scsi_host, def_scsi_host)) - return obj; - - if (getSCSIHostNumber(pool_scsi_host, &pool_hostnum) < 0 || - getSCSIHostNumber(def_scsi_host, &def_hostnum) < 0) - return NULL; - if (pool_hostnum == def_hostnum) - return obj; - } else if (pool_adapter->type == VIR_STORAGE_ADAPTER_TYPE_FC_HOST && - def_adapter->type == VIR_STORAGE_ADAPTER_TYPE_SCSI_HOST) { - pool_fchost = &pool_adapter->data.fchost; - def_scsi_host = &def_adapter->data.scsi_host; - - /* Get the scsi_hostN for the scsi_host source adapter def */ - if (getSCSIHostNumber(def_scsi_host, &scsi_hostnum) < 0) - return NULL; - - if (matchFCHostToSCSIHost(conn, pool_fchost, scsi_hostnum)) - return obj; - - } else if (pool_adapter->type == VIR_STORAGE_ADAPTER_TYPE_SCSI_HOST && - def_adapter->type == VIR_STORAGE_ADAPTER_TYPE_FC_HOST) { - pool_scsi_host = &pool_adapter->data.scsi_host; - def_fchost = &def_adapter->data.fchost; - - if (getSCSIHostNumber(pool_scsi_host, &scsi_hostnum) < 0) - return NULL; - - if (matchFCHostToSCSIHost(conn, def_fchost, scsi_hostnum)) - return obj; - } - - return NULL; -} - - -static virStoragePoolObjPtr -virStoragePoolObjSourceMatchTypeDEVICE(virStoragePoolObjPtr obj, - virStoragePoolDefPtr def) -{ - virStoragePoolObjPtr matchobj = NULL; - - if (obj->def->type == VIR_STORAGE_POOL_ISCSI) { - if (def->type != VIR_STORAGE_POOL_ISCSI) - return NULL; - - if ((matchobj = virStoragePoolSourceFindDuplicateDevices(obj, def))) { - if (!virStoragePoolSourceISCSIMatch(matchobj, def)) - return NULL; - } - return matchobj; - } - - if (def->type == VIR_STORAGE_POOL_ISCSI) - return NULL; - - /* VIR_STORAGE_POOL_FS - * VIR_STORAGE_POOL_LOGICAL - * VIR_STORAGE_POOL_DISK - * VIR_STORAGE_POOL_ZFS */ - return virStoragePoolSourceFindDuplicateDevices(obj, def); -} - - -struct _virStoragePoolObjFindDuplicateData { - virConnectPtr conn; - virStoragePoolDefPtr def; -}; - -static int -virStoragePoolObjSourceFindDuplicateCb(const void *payload, - const void *name ATTRIBUTE_UNUSED, - const void *opaque) -{ - virStoragePoolObjPtr obj = (virStoragePoolObjPtr) payload; - struct _virStoragePoolObjFindDuplicateData *data = - (struct _virStoragePoolObjFindDuplicateData *) opaque; - - /* Don't match against ourself if re-defining existing pool ! */ - if (STREQ(obj->def->name, data->def->name)) - return 0; - - switch ((virStoragePoolType)obj->def->type) { - case VIR_STORAGE_POOL_DIR: - case VIR_STORAGE_POOL_GLUSTER: - case VIR_STORAGE_POOL_NETFS: - if (data->def->type == obj->def->type && - virStoragePoolObjSourceMatchTypeDIR(obj, data->def)) - return 1; - break; - - case VIR_STORAGE_POOL_SCSI: - if (data->def->type == obj->def->type && - virStoragePoolObjSourceMatchTypeISCSI(obj, data->def, data->conn)) - return 1; - break; - - case VIR_STORAGE_POOL_ISCSI: - case VIR_STORAGE_POOL_ISCSI_DIRECT: - case VIR_STORAGE_POOL_FS: - case VIR_STORAGE_POOL_LOGICAL: - case VIR_STORAGE_POOL_DISK: - case VIR_STORAGE_POOL_ZFS: - if ((data->def->type == VIR_STORAGE_POOL_ISCSI || - data->def->type == VIR_STORAGE_POOL_ISCSI_DIRECT || - data->def->type == VIR_STORAGE_POOL_FS || - data->def->type == VIR_STORAGE_POOL_LOGICAL || - data->def->type == VIR_STORAGE_POOL_DISK || - data->def->type == VIR_STORAGE_POOL_ZFS) && - virStoragePoolObjSourceMatchTypeDEVICE(obj, data->def)) - return 1; - break; - - case VIR_STORAGE_POOL_SHEEPDOG: - if (data->def->type == obj->def->type && - virStoragePoolSourceMatchSingleHost(&obj->def->source, - &data->def->source)) - return 1; - break; - - case VIR_STORAGE_POOL_MPATH: - /* Only one mpath pool is valid per host */ - if (data->def->type == obj->def->type) - return 1; - break; - - case VIR_STORAGE_POOL_VSTORAGE: - if (data->def->type == obj->def->type && - STREQ(obj->def->source.name, data->def->source.name)) - return 1; - break; - - case VIR_STORAGE_POOL_RBD: - case VIR_STORAGE_POOL_LAST: - break; - } - - return 0; -} - - -int -virStoragePoolObjSourceFindDuplicate(virConnectPtr conn, - virStoragePoolObjListPtr pools, - virStoragePoolDefPtr def) -{ - struct _virStoragePoolObjFindDuplicateData data = { .conn = conn, - .def = def }; - virStoragePoolObjPtr obj = NULL; - - virObjectRWLockRead(pools); - obj = virHashSearch(pools->objs, virStoragePoolObjSourceFindDuplicateCb, - &data, NULL); - virObjectRWUnlock(pools); - - if (obj) { - virReportError(VIR_ERR_OPERATION_FAILED, - _("Storage source conflict with pool: '%s'"), - obj->def->name); - return -1; - } - - return 0; -} - - #define MATCH(FLAG) (flags & (FLAG)) static bool virStoragePoolObjMatch(virStoragePoolObjPtr obj, -- 2.16.4 -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list