mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2025-01-22 04:25:18 +00:00
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)
This commit is contained in:
parent
d91f7dec46
commit
4360a09844
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
if (virIsCapableVport(NULL, d->scsi_host.host) == 0)
|
||||
d->scsi_host.flags |= VIR_NODE_DEV_CAP_FLAG_HBA_VPORT_OPS;
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
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__ */
|
||||
|
Loading…
x
Reference in New Issue
Block a user