mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2025-02-22 11:22:23 +00:00
util: Add one helper virReadFCHost to read the value of fc_host entry
"open_wwn_file" in node_device_linux_sysfs.c is redundant, on one hand it duplicates work of virFileReadAll, on the other hand, it's waste to use a function for it, as there is no other users of it. So I don't see why the file opening work cannot be done in "read_wwn_linux". "read_wwn_linux" can be abstracted as an util function. As what all it does is to read the sysfs entry. So this patch removes "open_wwn_file", and abstract "read_wwn_linux" as an util function "virReadFCHost" (a more general name, because after changes, it can read each of the fc_host entry now). * src/util/virutil.h: (Declare virReadFCHost) * src/util/virutil.c: (Implement virReadFCHost) * src/node_device/node_device_linux_sysfs.c: (Remove open_wwn_file, and read_wwn_linux) src/node_device/node_device_driver.h: (Remove the declaration of read_wwn_linux, and the related macros) src/libvirt_private.syms: (Export virReadFCHost)
This commit is contained in:
parent
652a2ec630
commit
244ce462e2
@ -1868,6 +1868,7 @@ virIsDevMapperDevice;
|
||||
virParseNumber;
|
||||
virParseVersionString;
|
||||
virPipeReadUntilEOF;
|
||||
virReadFCHost;
|
||||
virScaleInteger;
|
||||
virSetBlocking;
|
||||
virSetCloseExec;
|
||||
|
@ -59,14 +59,10 @@ 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 read_wwn(host, file, wwn) read_wwn_linux(host, file, wwn)
|
||||
int read_wwn_linux(int host, const char *file, char **wwn);
|
||||
|
||||
# else /* __linux__ */
|
||||
|
||||
# define check_fc_host(d) (-1)
|
||||
# define check_vport_capable(d) (-1)
|
||||
# define read_wwn(host, file, wwn)
|
||||
|
||||
# endif /* __linux__ */
|
||||
|
||||
|
@ -37,77 +37,6 @@
|
||||
|
||||
#ifdef __linux__
|
||||
|
||||
static int open_wwn_file(const char *prefix,
|
||||
int host,
|
||||
const char *file,
|
||||
int *fd)
|
||||
{
|
||||
int retval = 0;
|
||||
char *wwn_path = NULL;
|
||||
|
||||
if (virAsprintf(&wwn_path, "%s/host%d/%s", prefix, host, file) < 0) {
|
||||
virReportOOMError();
|
||||
retval = -1;
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* fd will be closed by caller */
|
||||
if ((*fd = open(wwn_path, O_RDONLY)) != -1) {
|
||||
VIR_DEBUG("Opened WWN path '%s' for reading",
|
||||
wwn_path);
|
||||
} else {
|
||||
VIR_ERROR(_("Failed to open WWN path '%s' for reading"),
|
||||
wwn_path);
|
||||
}
|
||||
|
||||
out:
|
||||
VIR_FREE(wwn_path);
|
||||
return retval;
|
||||
}
|
||||
|
||||
|
||||
int read_wwn_linux(int host, const char *file, char **wwn)
|
||||
{
|
||||
char *p = NULL;
|
||||
int fd = -1, retval = 0;
|
||||
char buf[65] = "";
|
||||
|
||||
if (open_wwn_file(LINUX_SYSFS_FC_HOST_PREFIX, host, file, &fd) < 0) {
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (saferead(fd, buf, sizeof(buf) - 1) < 0) {
|
||||
retval = -1;
|
||||
VIR_DEBUG("Failed to read WWN for host%d '%s'",
|
||||
host, file);
|
||||
goto out;
|
||||
}
|
||||
|
||||
p = strstr(buf, "0x");
|
||||
if (p != NULL) {
|
||||
p += strlen("0x");
|
||||
} else {
|
||||
p = buf;
|
||||
}
|
||||
|
||||
*wwn = strndup(p, sizeof(buf));
|
||||
if (*wwn == NULL) {
|
||||
virReportOOMError();
|
||||
retval = -1;
|
||||
goto out;
|
||||
}
|
||||
|
||||
p = strchr(*wwn, '\n');
|
||||
if (p != NULL) {
|
||||
*p = '\0';
|
||||
}
|
||||
|
||||
out:
|
||||
VIR_FORCE_CLOSE(fd);
|
||||
return retval;
|
||||
}
|
||||
|
||||
|
||||
int check_fc_host_linux(union _virNodeDevCapData *d)
|
||||
{
|
||||
char *sysfs_path = NULL;
|
||||
@ -131,26 +60,29 @@ int check_fc_host_linux(union _virNodeDevCapData *d)
|
||||
|
||||
d->scsi_host.flags |= VIR_NODE_DEV_CAP_FLAG_HBA_FC_HOST;
|
||||
|
||||
if (read_wwn(d->scsi_host.host,
|
||||
"port_name",
|
||||
&d->scsi_host.wwpn) == -1) {
|
||||
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 (read_wwn(d->scsi_host.host,
|
||||
"node_name",
|
||||
&d->scsi_host.wwnn) == -1) {
|
||||
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 (read_wwn(d->scsi_host.host,
|
||||
"fabric_name",
|
||||
&d->scsi_host.fabric_wwn) == -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;
|
||||
|
@ -3383,3 +3383,70 @@ cleanup:
|
||||
VIR_FREE(buf);
|
||||
return ret;
|
||||
}
|
||||
|
||||
#ifdef __linux__
|
||||
# define SYSFS_FC_HOST_PATH "/sys/class/fc_host/"
|
||||
|
||||
/* virReadFCHost:
|
||||
* @sysfs_prefix: "fc_host" sysfs path, defaults to SYSFS_FC_HOST_PATH
|
||||
* @host: Host number, E.g. 5 of "fc_host/host5"
|
||||
* @entry: Name of the sysfs entry to read
|
||||
* @result: Return the entry value as string
|
||||
*
|
||||
* Read the value of sysfs "fc_host" entry.
|
||||
*
|
||||
* Returns 0 on success, and @result is filled with the entry value.
|
||||
* as string, Otherwise returns -1. Caller must free @result after
|
||||
* use.
|
||||
*/
|
||||
int
|
||||
virReadFCHost(const char *sysfs_prefix,
|
||||
int host,
|
||||
const char *entry,
|
||||
char **result)
|
||||
{
|
||||
char *sysfs_path = NULL;
|
||||
char *p = NULL;
|
||||
int ret = -1;
|
||||
char *buf = NULL;
|
||||
|
||||
if (virAsprintf(&sysfs_path, "%s/host%d/%s",
|
||||
sysfs_prefix ? sysfs_prefix : SYSFS_FC_HOST_PATH,
|
||||
host, entry) < 0) {
|
||||
virReportOOMError();
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
if (virFileReadAll(sysfs_path, 1024, &buf) < 0)
|
||||
goto cleanup;
|
||||
|
||||
if ((p = strchr(buf, '\n')))
|
||||
*p = '\0';
|
||||
|
||||
if ((p = strstr(buf, "0x")))
|
||||
p += strlen("0x");
|
||||
else
|
||||
p = buf;
|
||||
|
||||
if (!(*result = strndup(p, sizeof(buf)))) {
|
||||
virReportOOMError();
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
ret = 0;
|
||||
cleanup:
|
||||
VIR_FREE(sysfs_path);
|
||||
VIR_FREE(buf);
|
||||
return ret;
|
||||
}
|
||||
#else
|
||||
int
|
||||
virReadFCHost(const char *sysfs_prefix ATTRIBUTE_UNUSED,
|
||||
int host ATTRIBUTE_UNUSED,
|
||||
const char *entry ATTRIBUTE_UNUSED,
|
||||
char **result ATTRIBUTE_UNUSED)
|
||||
{
|
||||
virReportSystemError(ENOSYS, "%s", _("Not supported on this platform"));
|
||||
return -1;
|
||||
}
|
||||
#endif /* __linux__ */
|
||||
|
@ -297,5 +297,10 @@ int virGetDeviceUnprivSGIO(const char *path,
|
||||
int *unpriv_sgio);
|
||||
char * virGetUnprivSGIOSysfsPath(const char *path,
|
||||
const char *sysfs_dir);
|
||||
int virReadFCHost(const char *sysfs_prefix,
|
||||
int host,
|
||||
const char *entry,
|
||||
char **result)
|
||||
ATTRIBUTE_NONNULL(3) ATTRIBUTE_NONNULL(4);
|
||||
|
||||
#endif /* __VIR_UTIL_H__ */
|
||||
|
Loading…
x
Reference in New Issue
Block a user