mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2024-10-20 04:59:49 +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;
|
virParseNumber;
|
||||||
virParseVersionString;
|
virParseVersionString;
|
||||||
virPipeReadUntilEOF;
|
virPipeReadUntilEOF;
|
||||||
|
virReadFCHost;
|
||||||
virScaleInteger;
|
virScaleInteger;
|
||||||
virSetBlocking;
|
virSetBlocking;
|
||||||
virSetCloseExec;
|
virSetCloseExec;
|
||||||
|
@ -59,14 +59,10 @@ int check_fc_host_linux(union _virNodeDevCapData *d);
|
|||||||
# define check_vport_capable(d) check_vport_capable_linux(d)
|
# define check_vport_capable(d) check_vport_capable_linux(d)
|
||||||
int check_vport_capable_linux(union _virNodeDevCapData *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__ */
|
# else /* __linux__ */
|
||||||
|
|
||||||
# define check_fc_host(d) (-1)
|
# define check_fc_host(d) (-1)
|
||||||
# define check_vport_capable(d) (-1)
|
# define check_vport_capable(d) (-1)
|
||||||
# define read_wwn(host, file, wwn)
|
|
||||||
|
|
||||||
# endif /* __linux__ */
|
# endif /* __linux__ */
|
||||||
|
|
||||||
|
@ -37,77 +37,6 @@
|
|||||||
|
|
||||||
#ifdef __linux__
|
#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)
|
int check_fc_host_linux(union _virNodeDevCapData *d)
|
||||||
{
|
{
|
||||||
char *sysfs_path = NULL;
|
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;
|
d->scsi_host.flags |= VIR_NODE_DEV_CAP_FLAG_HBA_FC_HOST;
|
||||||
|
|
||||||
if (read_wwn(d->scsi_host.host,
|
if (virReadFCHost(NULL,
|
||||||
"port_name",
|
d->scsi_host.host,
|
||||||
&d->scsi_host.wwpn) == -1) {
|
"port_name",
|
||||||
|
&d->scsi_host.wwpn) == -1) {
|
||||||
VIR_ERROR(_("Failed to read WWPN for host%d"),
|
VIR_ERROR(_("Failed to read WWPN for host%d"),
|
||||||
d->scsi_host.host);
|
d->scsi_host.host);
|
||||||
retval = -1;
|
retval = -1;
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (read_wwn(d->scsi_host.host,
|
if (virReadFCHost(NULL,
|
||||||
"node_name",
|
d->scsi_host.host,
|
||||||
&d->scsi_host.wwnn) == -1) {
|
"node_name",
|
||||||
|
&d->scsi_host.wwnn) == -1) {
|
||||||
VIR_ERROR(_("Failed to read WWNN for host%d"),
|
VIR_ERROR(_("Failed to read WWNN for host%d"),
|
||||||
d->scsi_host.host);
|
d->scsi_host.host);
|
||||||
retval = -1;
|
retval = -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (read_wwn(d->scsi_host.host,
|
if (virReadFCHost(NULL,
|
||||||
"fabric_name",
|
d->scsi_host.host,
|
||||||
&d->scsi_host.fabric_wwn) == -1) {
|
"fabric_name",
|
||||||
|
&d->scsi_host.fabric_wwn) == -1) {
|
||||||
VIR_ERROR(_("Failed to read fabric WWN for host%d"),
|
VIR_ERROR(_("Failed to read fabric WWN for host%d"),
|
||||||
d->scsi_host.host);
|
d->scsi_host.host);
|
||||||
retval = -1;
|
retval = -1;
|
||||||
|
@ -3383,3 +3383,70 @@ cleanup:
|
|||||||
VIR_FREE(buf);
|
VIR_FREE(buf);
|
||||||
return ret;
|
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);
|
int *unpriv_sgio);
|
||||||
char * virGetUnprivSGIOSysfsPath(const char *path,
|
char * virGetUnprivSGIOSysfsPath(const char *path,
|
||||||
const char *sysfs_dir);
|
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__ */
|
#endif /* __VIR_UTIL_H__ */
|
||||||
|
Loading…
Reference in New Issue
Block a user