[libvirt] [PATCH 5/9] nodedev: Refactor the helpers

Osier Yang jyang at redhat.com
Mon Jan 14 14:34:55 UTC 2013


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 9e84b40..2945917 100644
--- a/src/libvirt_private.syms
+++ b/src/libvirt_private.syms
@@ -1295,6 +1295,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 51e8115..050ea62 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 @@ nodeDeviceLookupSCSIHostByWWN(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 a153b18..7775a59 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 20714d3..1afa21c 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 1be8526..87f1000 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 9442da3..8b74afb 100644
--- a/src/util/virutil.c
+++ b/src/util/virutil.c
@@ -3263,6 +3263,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
@@ -3316,6 +3317,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,
@@ -3326,4 +3384,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




More information about the libvir-list mailing list