virGetUserRuntimeDirectory;
virHexToBin;
virIndexToDiskName;
+virIsCapableFCHost;
+virIsCapableVport;
virIsDevMapperDevice;
virParseNumber;
virParseVersionString;
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;
}
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);
# 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__ */
(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
#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__ */
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;
#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
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,
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__ */
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__ */