[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