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