"open_wwn_file" in node_device_linux_sysfs.c is redundant, on one hand it duplicates work of virFileReadAll, on the other hand, it's waste to use a function for it, as there is no other users of it. So I don't see why the file opening work cannot be done in "read_wwn_linux". "read_wwn_linux" can be abstracted as an util function. As what all it does is to read the sysfs entry. So this patch removes "open_wwn_file", and abstract "read_wwn_linux" as an util function "virReadFCHost" (a more general name, because after changes, it can read each of the fc_host entry now). * src/util/virutil.h: (Declare virReadFCHost) * src/util/virutil.c: (Implement virReadFCHost) * src/node_device/node_device_linux_sysfs.c: (Remove open_wwn_file, and read_wwn_linux) src/node_device/node_device_driver.h: (Remove the declaration of read_wwn_linux, and the related macros) src/libvirt_private.syms: (Export virReadFCHost) --- src/libvirt_private.syms | 1 + src/node_device/node_device_driver.h | 4 - src/node_device/node_device_linux_sysfs.c | 92 ++++------------------------- src/util/virutil.c | 67 +++++++++++++++++++++ src/util/virutil.h | 5 ++ 5 files changed, 85 insertions(+), 84 deletions(-) diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms index 7be58ee..9e84b40 100644 --- a/src/libvirt_private.syms +++ b/src/libvirt_private.syms @@ -1299,6 +1299,7 @@ virIsDevMapperDevice; virParseNumber; virParseVersionString; virPipeReadUntilEOF; +virReadFCHost; virScaleInteger; virSetBlocking; virSetCloseExec; diff --git a/src/node_device/node_device_driver.h b/src/node_device/node_device_driver.h index 718e444..a153b18 100644 --- a/src/node_device/node_device_driver.h +++ b/src/node_device/node_device_driver.h @@ -59,14 +59,10 @@ 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 read_wwn(host, file, wwn) read_wwn_linux(host, file, wwn) -int read_wwn_linux(int host, const char *file, char **wwn); - # else /* __linux__ */ # define check_fc_host(d) (-1) # define check_vport_capable(d) (-1) -# define read_wwn(host, file, wwn) # endif /* __linux__ */ diff --git a/src/node_device/node_device_linux_sysfs.c b/src/node_device/node_device_linux_sysfs.c index 9c305d3..742a0bc 100644 --- a/src/node_device/node_device_linux_sysfs.c +++ b/src/node_device/node_device_linux_sysfs.c @@ -37,77 +37,6 @@ #ifdef __linux__ -static int open_wwn_file(const char *prefix, - int host, - const char *file, - int *fd) -{ - int retval = 0; - char *wwn_path = NULL; - - if (virAsprintf(&wwn_path, "%s/host%d/%s", prefix, host, file) < 0) { - virReportOOMError(); - retval = -1; - goto out; - } - - /* fd will be closed by caller */ - if ((*fd = open(wwn_path, O_RDONLY)) != -1) { - VIR_DEBUG("Opened WWN path '%s' for reading", - wwn_path); - } else { - VIR_ERROR(_("Failed to open WWN path '%s' for reading"), - wwn_path); - } - -out: - VIR_FREE(wwn_path); - return retval; -} - - -int read_wwn_linux(int host, const char *file, char **wwn) -{ - char *p = NULL; - int fd = -1, retval = 0; - char buf[65] = ""; - - if (open_wwn_file(LINUX_SYSFS_FC_HOST_PREFIX, host, file, &fd) < 0) { - goto out; - } - - if (saferead(fd, buf, sizeof(buf) - 1) < 0) { - retval = -1; - VIR_DEBUG("Failed to read WWN for host%d '%s'", - host, file); - goto out; - } - - p = strstr(buf, "0x"); - if (p != NULL) { - p += strlen("0x"); - } else { - p = buf; - } - - *wwn = strndup(p, sizeof(buf)); - if (*wwn == NULL) { - virReportOOMError(); - retval = -1; - goto out; - } - - p = strchr(*wwn, '\n'); - if (p != NULL) { - *p = '\0'; - } - -out: - VIR_FORCE_CLOSE(fd); - return retval; -} - - int check_fc_host_linux(union _virNodeDevCapData *d) { char *sysfs_path = NULL; @@ -131,26 +60,29 @@ int check_fc_host_linux(union _virNodeDevCapData *d) d->scsi_host.flags |= VIR_NODE_DEV_CAP_FLAG_HBA_FC_HOST; - if (read_wwn(d->scsi_host.host, - "port_name", - &d->scsi_host.wwpn) == -1) { + 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 (read_wwn(d->scsi_host.host, - "node_name", - &d->scsi_host.wwnn) == -1) { + 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 (read_wwn(d->scsi_host.host, - "fabric_name", - &d->scsi_host.fabric_wwn) == -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; diff --git a/src/util/virutil.c b/src/util/virutil.c index 7c54bea..9442da3 100644 --- a/src/util/virutil.c +++ b/src/util/virutil.c @@ -3260,3 +3260,70 @@ cleanup: VIR_FREE(buf); return ret; } + +#ifdef __linux__ +# define SYSFS_FC_HOST_PATH "/sys/class/fc_host/" + +/* virReadFCHost: + * @sysfs_prefix: "fc_host" sysfs path, defaults to SYSFS_FC_HOST_PATH + * @host: Host number, E.g. 5 of "fc_host/host5" + * @entry: Name of the sysfs entry to read + * @result: Return the entry value as string + * + * Read the value of sysfs "fc_host" entry. + * + * Returns 0 on success, and @result is filled with the entry value. + * as string, Otherwise returns -1. Caller must free @result after + * use. + */ +int +virReadFCHost(const char *sysfs_prefix, + int host, + const char *entry, + char **result) +{ + char *sysfs_path = NULL; + char *p = NULL; + int ret = -1; + char *buf = NULL; + + if (virAsprintf(&sysfs_path, "%s/host%d/%s", + sysfs_prefix ? sysfs_prefix : SYSFS_FC_HOST_PATH, + host, entry) < 0) { + virReportOOMError(); + goto cleanup; + } + + if (virFileReadAll(sysfs_path, 1024, &buf) < 0) + goto cleanup; + + if ((p = strchr(buf, '\n'))) + *p = '\0'; + + if ((p = strstr(buf, "0x"))) + p += strlen("0x"); + else + p = buf; + + if (!(*result = strndup(p, sizeof(buf)))) { + virReportOOMError(); + goto cleanup; + } + + ret = 0; +cleanup: + VIR_FREE(sysfs_path); + VIR_FREE(buf); + return ret; +} +#else +int +virReadFCHost(const char *sysfs_prefix ATTRIBUTE_UNUSED, + int host ATTRIBUTE_UNUSED, + const char *entry ATTRIBUTE_UNUSED, + char **result 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 5a08c81..373c48c 100644 --- a/src/util/virutil.h +++ b/src/util/virutil.h @@ -293,5 +293,10 @@ int virGetDeviceUnprivSGIO(const char *path, int *unpriv_sgio); char * virGetUnprivSGIOSysfsPath(const char *path, const char *sysfs_dir); +int virReadFCHost(const char *sysfs_prefix, + int host, + const char *entry, + char **result) + ATTRIBUTE_NONNULL(3) ATTRIBUTE_NONNULL(4); #endif /* __VIR_UTIL_H__ */ -- 1.7.7.6 -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list