This adds two util functions (virIsCapableFCHost and virIsCapableVport), and rename helper check_fc_host_linux as detect_scsi_host_caps, check_capable_vport_linux is removed, as it's abstracted to the util function virIsCapableVport. detect_scsi_host_caps nows detect both the fc_host and vport_ops capabilities. "stat(2)" is replaced with "access(2)" for saving. * src/util/virutil.h: - Declare virIsCapableFCHost and virIsCapableVport * src/util/virutil.c: - Implement virIsCapableFCHost and virIsCapableVport * src/node_device/node_device_linux_sysfs.c: - Remove check_capable_vport_linux - Rename check_fc_host_linux as detect_scsi_host_caps, and refactor it a bit to detect both fc_host and vport_os capabilities * src/node_device/node_device_driver.h: - Change/remove the related declarations * src/node_device/node_device_udev.c: (Use detect_scsi_host_caps) * src/node_device/node_device_hal.c: (Likewise) * src/node_device/node_device_driver.c (Likewise) --- src/libvirt_private.syms | 2 + src/node_device/node_device_driver.c | 7 +- src/node_device/node_device_driver.h | 10 +-- src/node_device/node_device_hal.c | 4 +- src/node_device/node_device_linux_sysfs.c | 135 ++++++++--------------------- src/node_device/node_device_udev.c | 3 +- src/util/virutil.c | 73 ++++++++++++++++ src/util/virutil.h | 3 + 8 files changed, 123 insertions(+), 114 deletions(-) diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms index 2e83747..41c0d84 100644 --- a/src/libvirt_private.syms +++ b/src/libvirt_private.syms @@ -1293,6 +1293,8 @@ virGetUserName; virGetUserRuntimeDirectory; virHexToBin; virIndexToDiskName; +virIsCapableFCHost; +virIsCapableVport; virIsDevMapperDevice; virParseNumber; virParseVersionString; diff --git a/src/node_device/node_device_driver.c b/src/node_device/node_device_driver.c index ef85af5..db2f922 100644 --- a/src/node_device/node_device_driver.c +++ b/src/node_device/node_device_driver.c @@ -48,7 +48,7 @@ static int update_caps(virNodeDeviceObjPtr dev) while (cap) { /* The only caps that currently need updating are FC related. */ if (cap->type == VIR_NODE_DEV_CAP_SCSI_HOST) { - check_fc_host(&dev->def->caps->data); + detect_scsi_host_caps(&dev->def->caps->data); } cap = cap->next; } @@ -241,18 +241,15 @@ nodeDeviceLookupByWWN(virConnectPtr conn, nodeDeviceLock(driver); for (i = 0; i < devs->count; i++) { - obj = devs->objs[i]; virNodeDeviceObjLock(obj); cap = obj->def->caps; while (cap) { - if (cap->type == VIR_NODE_DEV_CAP_SCSI_HOST) { - check_fc_host(&cap->data); + detect_scsi_host_caps(&cap->data); if (cap->data.scsi_host.flags & VIR_NODE_DEV_CAP_FLAG_HBA_FC_HOST) { - if (STREQ(cap->data.scsi_host.wwnn, wwnn) && STREQ(cap->data.scsi_host.wwpn, wwpn)) { dev = virGetNodeDevice(conn, obj->def->name); diff --git a/src/node_device/node_device_driver.h b/src/node_device/node_device_driver.h index edd2915..17bd020 100644 --- a/src/node_device/node_device_driver.h +++ b/src/node_device/node_device_driver.h @@ -53,16 +53,12 @@ int nodedevRegister(void); # ifdef __linux__ -# define check_fc_host(d) check_fc_host_linux(d) -int check_fc_host_linux(union _virNodeDevCapData *d); - -# define check_vport_capable(d) check_vport_capable_linux(d) -int check_vport_capable_linux(union _virNodeDevCapData *d); +# define detect_scsi_host_caps(d) detect_scsi_host_caps_linux(d) +int detect_scsi_host_caps_linux(union _virNodeDevCapData *d); # else /* __linux__ */ -# define check_fc_host(d) (-1) -# define check_vport_capable(d) (-1) +# define detect_scsi_host_caps(d) (-1) # endif /* __linux__ */ diff --git a/src/node_device/node_device_hal.c b/src/node_device/node_device_hal.c index 33e0170..18cdab8 100644 --- a/src/node_device/node_device_hal.c +++ b/src/node_device/node_device_hal.c @@ -234,14 +234,12 @@ static int gather_scsi_host_cap(LibHalContext *ctx, const char *udi, (void)get_int_prop(ctx, udi, "scsi_host.host", (int *)&d->scsi_host.host); - retval = check_fc_host(d); + retval = detect_scsi_host_caps(d); if (retval == -1) { goto out; } - retval = check_vport_capable(d); - out: return retval; } diff --git a/src/node_device/node_device_linux_sysfs.c b/src/node_device/node_device_linux_sysfs.c index 742a0bc..054afea 100644 --- a/src/node_device/node_device_linux_sysfs.c +++ b/src/node_device/node_device_linux_sysfs.c @@ -1,8 +1,8 @@ /* - * node_device_hal_linuc.c: Linux specific code to gather device data + * node_device_linux_sysfs.c: Linux specific code to gather device data * not available through HAL. * - * Copyright (C) 2009-2011 Red Hat, Inc. + * Copyright (C) 2009-2013 Red Hat, Inc. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -37,112 +37,53 @@ #ifdef __linux__ -int check_fc_host_linux(union _virNodeDevCapData *d) +int +detect_scsi_host_caps_linux(union _virNodeDevCapData *d) { - char *sysfs_path = NULL; - int retval = 0; - struct stat st; + int ret = -1; VIR_DEBUG("Checking if host%d is an FC HBA", d->scsi_host.host); - if (virAsprintf(&sysfs_path, "%shost%d", - LINUX_SYSFS_FC_HOST_PREFIX, - d->scsi_host.host) < 0) { - virReportOOMError(); - retval = -1; - goto out; + if (virIsCapableFCHost(NULL, d->scsi_host.host)) { + d->scsi_host.flags |= VIR_NODE_DEV_CAP_FLAG_HBA_FC_HOST; + + if (virReadFCHost(NULL, + d->scsi_host.host, + "port_name", + &d->scsi_host.wwpn) == -1) { + VIR_ERROR(_("Failed to read WWPN for host%d"), d->scsi_host.host); + goto cleanup; + } + + if (virReadFCHost(NULL, + d->scsi_host.host, + "node_name", + &d->scsi_host.wwnn) == -1) { + VIR_ERROR(_("Failed to read WWNN for host%d"), d->scsi_host.host); + goto cleanup; + } + + if (virReadFCHost(NULL, + d->scsi_host.host, + "fabric_name", + &d->scsi_host.fabric_wwn) == -1) { + VIR_ERROR(_("Failed to read fabric WWN for host%d"), + d->scsi_host.host); + goto cleanup; + } } - if (stat(sysfs_path, &st) != 0) { - /* Not an FC HBA; not an error, either. */ - goto out; - } - - d->scsi_host.flags |= VIR_NODE_DEV_CAP_FLAG_HBA_FC_HOST; - - if (virReadFCHost(NULL, - d->scsi_host.host, - "port_name", - &d->scsi_host.wwpn) == -1) { - VIR_ERROR(_("Failed to read WWPN for host%d"), - d->scsi_host.host); - retval = -1; - goto out; - } - - if (virReadFCHost(NULL, - d->scsi_host.host, - "node_name", - &d->scsi_host.wwnn) == -1) { - VIR_ERROR(_("Failed to read WWNN for host%d"), - d->scsi_host.host); - retval = -1; - } - - if (virReadFCHost(NULL, - d->scsi_host.host, - "fabric_name", - &d->scsi_host.fabric_wwn) == -1) { - VIR_ERROR(_("Failed to read fabric WWN for host%d"), - d->scsi_host.host); - retval = -1; - goto out; - } + if (virIsCapableVport(NULL, d->scsi_host.host) == 0) + d->scsi_host.flags |= VIR_NODE_DEV_CAP_FLAG_HBA_VPORT_OPS; -out: - if (retval == -1) { + ret = 0; +cleanup: + if (ret == -1) { VIR_FREE(d->scsi_host.wwnn); VIR_FREE(d->scsi_host.wwpn); VIR_FREE(d->scsi_host.fabric_wwn); } - VIR_FREE(sysfs_path); - return retval; -} - - -int check_vport_capable_linux(union _virNodeDevCapData *d) -{ - char *sysfs_path = NULL; - struct stat st; - int retval = 0; - - if (virAsprintf(&sysfs_path, - "%shost%d%s", - LINUX_SYSFS_FC_HOST_PREFIX, - d->scsi_host.host, - LINUX_SYSFS_VPORT_CREATE_POSTFIX) < 0) { - virReportOOMError(); - retval = -1; - goto out; - } - - if (stat(sysfs_path, &st) == 0) { - d->scsi_host.flags |= VIR_NODE_DEV_CAP_FLAG_HBA_VPORT_OPS; - goto out; - } - - VIR_FREE(sysfs_path); - if (virAsprintf(&sysfs_path, - "%shost%d%s", - LINUX_SYSFS_SCSI_HOST_PREFIX, - d->scsi_host.host, - LINUX_SYSFS_VPORT_CREATE_POSTFIX) < 0) { - virReportOOMError(); - retval = -1; - goto out; - } - - if (stat(sysfs_path, &st) == 0) { - d->scsi_host.flags |= VIR_NODE_DEV_CAP_FLAG_HBA_VPORT_OPS; - } else { - /* Not a vport capable HBA; not an error, either. */ - VIR_DEBUG("No vport operation path found for host%d", - d->scsi_host.host); - } - -out: - VIR_FREE(sysfs_path); - return retval; + return ret; } #endif /* __linux__ */ diff --git a/src/node_device/node_device_udev.c b/src/node_device/node_device_udev.c index 4137488..87a2f61 100644 --- a/src/node_device/node_device_udev.c +++ b/src/node_device/node_device_udev.c @@ -663,8 +663,7 @@ static int udevProcessSCSIHost(struct udev_device *device ATTRIBUTE_UNUSED, goto out; } - check_fc_host(&def->caps->data); - check_vport_capable(&def->caps->data); + detect_scsi_host_caps(&def->caps->data); if (udevGenerateDeviceName(device, def, NULL) != 0) { goto out; diff --git a/src/util/virutil.c b/src/util/virutil.c index 0f2cb4f..95c5b81 100644 --- a/src/util/virutil.c +++ b/src/util/virutil.c @@ -3272,6 +3272,7 @@ cleanup: #ifdef __linux__ # define SYSFS_FC_HOST_PATH "/sys/class/fc_host/" +# define SYSFS_SCSI_HOST_PATH "/sys/class/scsi_host/" /* virReadFCHost: * @sysfs_prefix: "fc_host" sysfs path, defaults to SYSFS_FC_HOST_PATH @@ -3325,6 +3326,63 @@ cleanup: VIR_FREE(buf); return ret; } + +int +virIsCapableFCHost(const char *sysfs_prefix, + int host) +{ + char *sysfs_path = NULL; + int ret = -1; + + if (virAsprintf(&sysfs_path, "%shost%d", + sysfs_prefix ? sysfs_prefix : SYSFS_FC_HOST_PATH, + host) < 0) { + virReportOOMError(); + return -1; + } + + if (access(sysfs_path, F_OK) == 0) + ret = 0; + + VIR_FREE(sysfs_path); + return ret; +} + +int +virIsCapableVport(const char *sysfs_prefix, + int host) +{ + char *scsi_host_path = NULL; + char *fc_host_path = NULL; + int ret = -1; + + if (virAsprintf(&fc_host_path, + "%shost%d%s", + sysfs_prefix ? sysfs_prefix : SYSFS_FC_HOST_PATH, + host, + "vport_create") < 0) { + virReportOOMError(); + return -1; + } + + if (virAsprintf(&scsi_host_path, + "%shost%d%s", + sysfs_prefix ? sysfs_prefix : SYSFS_SCSI_HOST_PATH, + host, + "vport_create") < 0) { + virReportOOMError(); + goto cleanup; + } + + if ((access(fc_host_path, F_OK) == 0) || + (access(scsi_host_path, F_OK) == 0)) + ret = 0; + +cleanup: + VIR_FREE(fc_host_path); + VIR_FREE(scsi_host_path); + return ret; +} #else int virReadFCHost(const char *sysfs_prefix ATTRIBUTE_UNUSED, @@ -3335,4 +3393,19 @@ virReadFCHost(const char *sysfs_prefix ATTRIBUTE_UNUSED, virReportSystemError(ENOSYS, "%s", _("Not supported on this platform")); return -1; } + +int +virIsCapableFCHost(int host ATTRIBUTE_UNUSED) +{ + virReportSystemError(ENOSYS, "%s", _("Not supported on this platform")); + return -1; +} + +int +virIsCapbleVport(const char *sysfs_prefix ATTRIBUTE_UNUSED, + int host ATTRIBUTE_UNUSED) +{ + virReportSystemError(ENOSYS, "%s", _("Not supported on this platform")); + return -1; +} #endif /* __linux__ */ diff --git a/src/util/virutil.h b/src/util/virutil.h index 373c48c..d87aa92 100644 --- a/src/util/virutil.h +++ b/src/util/virutil.h @@ -299,4 +299,7 @@ int virReadFCHost(const char *sysfs_prefix, char **result) ATTRIBUTE_NONNULL(3) ATTRIBUTE_NONNULL(4); +int virIsCapableFCHost(const char *sysfs_prefix, int host); +int virIsCapableVport(const char *sysfs_prefix, int host); + #endif /* __VIR_UTIL_H__ */ -- 1.7.7.6 -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list