On 06/07/2013 01:03 PM, Osier Yang wrote:
> 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;

Given the following code, the call to Split could use 4 (or 5) for the
max...  Not that it matters.

> +
> +    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"));

so the optional unique_id isn't so optional after all for a couple of
code paths.  Issuing a message here could be confusing.  Has this been
tested within an environment where unique_id isn't specified?


> +                return NULL;
> +            } else {
> +                if (!(addr = 
> getScsiHostParentAddress(adapter.data.scsi_host.parent)))
> +                    return NULL;
> +
> +                name = virParseStableScsiHostAddress(NULL, addr,
> +                                                     
> adapter.data.scsi_host.unique_id);

You need a VIR_FREE(addr); here

John
> +            }
> +        } else if (adapter.data.scsi_host.name) {
> +            if (VIR_STRDUP(name, adapter.data.scsi_host.name) < 0)
> +                return NULL;
> +        }
> +
>          return name;
>      }
>  
> 

--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list

Reply via email to