[libvirt] [PATCH 1/1] Merge DanPB's SCSI HBA pool code

Jim Meyering jim at meyering.net
Mon Feb 23 17:14:15 UTC 2009


David Allan wrote:
> Last March, DanPB posted code to create pools from SCSI HBAs.  This patch is simply bringing that code into the current tree.
>
> * src/storage_backend_scsi.[ch] contain the pool implementataion
> * There are small changes to several other source files to integrate the new pool type.

[hmm... I wrote this a couple days ago and nearly forgot to send it. ]

This looks fine, overall.
a few suggestions below.

...
> diff --git a/src/storage_backend_scsi.c b/src/storage_backend_scsi.c
...
> +    /*
> +     * First get the class based path eg
> +     *
> +     *   /sys/class/scsi_host/host1/device
> +     */
> +    if ((dev = malloc(sizeof(LINUX_SYSFS_SCSI_HOST_PREFIX) +
> +                      strlen(pool->def->source.adapter) +
> +                      sizeof(LINUX_SYSFS_SCSI_HOST_POSTFIX) +
> +                      1)) == NULL) {
> +        virReportOOMError(conn);
> +        return -1;
> +    }
> +
> +    strcpy(dev, LINUX_SYSFS_SCSI_HOST_PREFIX);
> +    strcat(dev, pool->def->source.adapter);
> +    strcat(dev, LINUX_SYSFS_SCSI_HOST_POSTFIX);

use virAsprintf in place of the above malloc/strcpy/strcat calls

> +    /*
> +     * Now resolve the class based path symlink to the real
> +     * device path, which is likely under PCI bus hierarchy
> +     * and is the path tracked by HAL
> +     */
> +    /* Readlink does not null terminate, so we reserve one byte */
> +    if ((len = readlink(dev, relLink, sizeof(relLink)-1)) < 0) {
> +        virStorageReportError(conn, VIR_ERR_INTERNAL_ERROR,
> +                              _("cannot find SCSI host adapter '%s' at '%s'"),
> +                              pool->def->source.adapter, dev);
> +        free(dev);
> +        return -1;
> +    }
> +    relLink[len] = '\0';
> +
> +
> +    /*
> +     * The symlink is relative, so now we have to turn it
> +     * into a absolute path
> +     */
> +    if ((tmp = realloc(dev,
> +                       sizeof(LINUX_SYSFS_SCSI_HOST_PREFIX) +
> +                       strlen(pool->def->source.adapter) +
> +                       1 +
> +                       strlen(relLink) +
> +                       1)) == NULL) {
> +        virReportOOMError(conn);
> +        free(dev);
> +        return -1;
> +    }
> +    dev = tmp;
> +
> +    strcpy(dev, LINUX_SYSFS_SCSI_HOST_PREFIX);
> +    strcat(dev, pool->def->source.adapter);
> +    strcat(dev, "/");
> +    strcat(dev, relLink);

use virAsprintf here, too.

> +    /*
> +     * And finally canonicalize the absolute path to remove the
> +     * copious  ..  components
> +     */
> +    if (!realpath(dev, absLink)) {

Don't use realpath.  e.g. mingw lacks it.
Instead, use canonicalize_file_name, which should be
portable thanks to gnulib's canonicalize-lgpl module --
which you can include by adding that to the list of module
names in bootstrap.

> +        char ebuf[1024];
> +        virStorageReportError(conn, VIR_ERR_INTERNAL_ERROR,
> +                              _("cannot canonicalize link: %s"),
> +                              virStrerror(errno, ebuf, sizeof ebuf));
> +        free(dev);
> +        return -1;
> +    }
> +    free(dev);
> +
> +    if (strlen(absLink) >= buflen) {
> +        virStorageReportError(conn, VIR_ERR_INTERNAL_ERROR,
> +                              _("link too long for buffer"));
> +        return -1;
> +    }
> +    strcpy(buf, absLink);
> +
> +    return 0;
> +}
...
> +/**
> + * virStorageBackendSCSIAddLUN:
> + *
> + * @conn: connection to report errors against
> + * @pool: pool to register volume with
> + * @ctx: HAL context
> + * @devname: HAL device name for LUN
> + *
> + * Given a HAL device supported 'block' and 'storage' capabilities
> + * register it as a volume in the pool
> + *
> + * Returns 0 on success, -1 on error
> + */
> +static int
> +virStorageBackendSCSIAddLUN(virConnectPtr conn,
> +                            virStoragePoolObjPtr pool,
> +                            LibHalContext *ctx,
> +                            const char *devname)
> +{
> +    char **strdevs = NULL;
> +    int numstrdevs = 0;
> +    char *dev = NULL, *key = NULL;
> +    unsigned long long size;

How about uint64_t instead, since it's the value
returned by libhal_device_get_property_uint64?

> +    int host, bus, target, lun;
> +    int n = -1, i;
> +    int ret = -1;
> +    char name[100];
...
> +    HAL_GET_PROPERTY(strdevs[0], "storage.serial", &derr, string, key);
> +    HAL_GET_PROPERTY(strdevs[0], "storage.size", &derr, uint64, size);
...




More information about the libvir-list mailing list