提交 4360a098 编写于 作者: O Osier Yang

nodedev: Refactor the helpers

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)
上级 d91f7dec
......@@ -1864,6 +1864,8 @@ virGetUserName;
virGetUserRuntimeDirectory;
virHexToBin;
virIndexToDiskName;
virIsCapableFCHost;
virIsCapableVport;
virIsDevMapperDevice;
virParseNumber;
virParseVersionString;
......
......@@ -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);
......
......@@ -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__ */
......
......@@ -236,14 +236,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;
}
......
/*
* 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 < 0) {
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__ */
......@@ -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;
......
......@@ -3386,6 +3386,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
......@@ -3439,6 +3440,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,
......@@ -3449,4 +3507,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__ */
......@@ -303,4 +303,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__ */
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册