提交 244ce462 编写于 作者: O Osier Yang

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)
上级 652a2ec6
......@@ -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__ */
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册