This takes use of the two utils introduced in previous patches. Node device HAL backend represents PCI device like PCI_8086_2922, (I.E PCI_$vendor_$product), to get the PCI address, we have to traverse /sys/devices/ to find it out. And to get the current scsi host number assigned by the system for the scsi host device. We need to traverse /sys/bus/pci/devices/ with the found PCI address by getScsiHostParentAddress, and the specified unique_id. Later patch will allow to omit the "unique_id", by using the scsi host which has the smallest unique_id. --- src/storage/storage_backend_scsi.c | 81 +++++++++++++++++++++++++++++++++++++- 1 file changed, 79 insertions(+), 2 deletions(-) diff --git a/src/storage/storage_backend_scsi.c b/src/storage/storage_backend_scsi.c index 13c498d..a77b9ae 100644 --- a/src/storage/storage_backend_scsi.c +++ b/src/storage/storage_backend_scsi.c @@ -591,6 +591,66 @@ out: return retval; } +/* + * Node device udev backend and HAL backend represent PCI + * device in different style. Udev backend represents it like + * pci_0000_00_1f_2, and HAL backend represents it like + * pci_8086_2922. + * + * Covert the value of "parent" into PCI device address string + * (e.g. 0000:00:1f:2). Return the PCI address as string on + * success, or -1 on failure. + */ +static char * +getScsiHostParentAddress(const char *parent) +{ + char **tokens = NULL; + char *vendor = NULL; + char *product = NULL; + char *ret = NULL; + int len; + + if (!strchr(parent, '_')) { + virReportError(VIR_ERR_XML_ERROR, "%s", + _("'parent' of scsi_host adapter must " + "be consistent with name of node device")); + return NULL; + } + + if (!(tokens = virStringSplit(parent, "_", 0))) + return NULL; + + len = virStringListLength(tokens); + + switch (len) { + case 4: + if (!(ret = virStringJoin((const char **)(&tokens[1]), ":"))) + goto cleanup; + break; + + case 2: + vendor = tokens[1]; + product = tokens[2]; + if (!(ret = virFindPCIDeviceByVPD(NULL, vendor, product))) { + virReportError(VIR_ERR_INTERNAL_ERROR, + _("Unable to find PCI device with vendor '%s' " + "product '%s'"), vendor, product); + goto cleanup; + } + + break; + default: + virReportError(VIR_ERR_XML_ERROR, "%s", + _("'parent' of scsi_host adapter must " + "be consistent with name of node device")); + goto cleanup; + } + +cleanup: + virStringFreeList(tokens); + return ret; +} + static int getHostNumber(const char *adapter_name, unsigned int *result) @@ -627,10 +687,27 @@ static char * getAdapterName(virStoragePoolSourceAdapter adapter) { char *name = NULL; + char *addr = NULL; if (adapter.type != VIR_STORAGE_POOL_SOURCE_ADAPTER_TYPE_FC_HOST) { - if (VIR_STRDUP(name, adapter.data.scsi_host.name) < 0) - return NULL; + if (adapter.data.scsi_host.parent) { + if (!adapter.data.scsi_host.has_unique_id) { + virReportError(VIR_ERR_INTERNAL_ERROR, "%s", + _("'unique_id' is not specified for " + "scsi_host adapter")); + return NULL; + } else { + if (!(addr = getScsiHostParentAddress(adapter.data.scsi_host.parent))) + return NULL; + + name = virParseStableScsiHostAddress(NULL, addr, + adapter.data.scsi_host.unique_id); + } + } else if (adapter.data.scsi_host.name) { + if (VIR_STRDUP(name, adapter.data.scsi_host.name) < 0) + return NULL; + } + return name; } -- 1.8.1.4 -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list