"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