* src/node_device.c src/node_device_hal.h src/node_device_hal_linux.c:

fix bogus WWN in NPIV support, patch by David Allan
daniel
This commit is contained in:
Daniel Veillard 2009-06-26 14:09:01 +00:00
parent 4c4ea03d7a
commit b052424c0d
4 changed files with 130 additions and 89 deletions

View File

@ -1,3 +1,8 @@
Fri Jun 26 16:07:54 CEST 2009 Daniel Veillard <veillard@redhat.com>
* src/node_device.c src/node_device_hal.h src/node_device_hal_linux.c:
fix bogus WWN in NPIV support, patch by David Allan
Thu Jun 25 17:12:09 CEST 2009 Daniel Veillard <veillard@redhat.com>
* src/storage_conf.c: fix reading of storage pool definitions at startup

View File

@ -33,6 +33,7 @@
#include "memory.h"
#include "logging.h"
#include "node_device_conf.h"
#include "node_device_hal.h"
#include "node_device.h"
#include "storage_backend.h" /* For virWaitForDevices */
@ -49,6 +50,37 @@ static int dev_has_cap(const virNodeDeviceObjPtr dev, const char *cap)
return 0;
}
static int update_caps(virNodeDeviceObjPtr dev)
{
virNodeDevCapsDefPtr cap = dev->def->caps;
while (cap) {
/* The only cap that currently needs updating is the WWN of FC HBAs. */
if (cap->type == VIR_NODE_DEV_CAP_SCSI_HOST) {
if (cap->data.scsi_host.flags & VIR_NODE_DEV_CAP_FLAG_HBA_FC_HOST) {
if (read_wwn(cap->data.scsi_host.host,
"port_name",
&cap->data.scsi_host.wwpn) == -1) {
VIR_ERROR(_("Failed to refresh WWPN for host%d"),
cap->data.scsi_host.host);
}
if (read_wwn(cap->data.scsi_host.host,
"node_name",
&cap->data.scsi_host.wwnn) == -1) {
VIR_ERROR(_("Failed to refresh WWNN for host%d"),
cap->data.scsi_host.host);
}
}
cap = cap->next;
}
}
return 0;
}
#ifdef __linux__
static int update_driver_name(virConnectPtr conn,
virNodeDeviceObjPtr dev)
@ -253,6 +285,8 @@ static char *nodeDeviceDumpXML(virNodeDevicePtr dev,
}
update_driver_name(dev->conn, obj);
update_caps(obj);
ret = virNodeDeviceDefFormat(dev->conn, obj->def);
cleanup:

View File

@ -30,10 +30,14 @@ 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)
#define check_vport_capable(d)
#define read_wwn(host, file, wwn)
#endif /* __linux__ */

View File

@ -34,14 +34,84 @@
#ifdef __linux__
int check_fc_host_linux(union _virNodeDevCapData *d)
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(NULL);
retval = -1;
goto out;
}
/* fd will be closed by caller */
if ((*fd = open(wwn_path, O_RDONLY)) != -1) {
VIR_ERROR(_("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 *sysfs_path = NULL;
char *wwnn_path = NULL;
char *wwpn_path = NULL;
char *p = NULL;
int fd = -1, retval = 0;
char buf[64];
if (open_wwn_file(LINUX_SYSFS_FC_HOST_PREFIX, host, file, &fd) < 0) {
goto out;
}
memset(buf, 0, sizeof(buf));
if (saferead(fd, buf, sizeof(buf)) < 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(NULL);
retval = -1;
goto out;
}
p = strchr(*wwn, '\n');
if (p != NULL) {
*p = '\0';
}
out:
if (fd != -1) {
close(fd);
}
return retval;
}
int check_fc_host_linux(union _virNodeDevCapData *d)
{
char *sysfs_path = NULL;
int retval = 0;
struct stat st;
VIR_DEBUG(_("Checking if host%d is an FC HBA"), d->scsi_host.host);
@ -61,101 +131,29 @@ int check_fc_host_linux(union _virNodeDevCapData *d)
d->scsi_host.flags |= VIR_NODE_DEV_CAP_FLAG_HBA_FC_HOST;
if (virAsprintf(&wwnn_path, "%s/node_name",
sysfs_path) < 0) {
virReportOOMError(NULL);
if (read_wwn(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 ((fd = open(wwnn_path, O_RDONLY)) < 0) {
if (read_wwn(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;
VIR_ERROR(_("Failed to open WWNN path '%s' for reading"),
wwnn_path);
goto out;
}
memset(buf, 0, sizeof(buf));
if (saferead(fd, buf, sizeof(buf)) < 0) {
retval = -1;
VIR_ERROR(_("Failed to read WWNN from '%s'"),
wwnn_path);
goto out;
}
close(fd);
fd = -1;
p = strstr(buf, "0x");
if (p != NULL) {
p += strlen("0x");
} else {
p = buf;
}
d->scsi_host.wwnn = strndup(p, sizeof(buf));
if (d->scsi_host.wwnn == NULL) {
virReportOOMError(NULL);
retval = -1;
goto out;
}
p = strchr(d->scsi_host.wwnn, '\n');
if (p != NULL) {
*p = '\0';
}
if (virAsprintf(&wwpn_path, "%s/port_name",
sysfs_path) < 0) {
virReportOOMError(NULL);
retval = -1;
goto out;
}
if ((fd = open(wwpn_path, O_RDONLY)) < 0) {
retval = -1;
VIR_ERROR(_("Failed to open WWPN path '%s' for reading"),
wwpn_path);
goto out;
}
memset(buf, 0, sizeof(buf));
if (saferead(fd, buf, sizeof(buf)) < 0) {
retval = -1;
VIR_ERROR(_("Failed to read WWPN from '%s'"),
wwpn_path);
goto out;
}
close(fd);
fd = -1;
p = strstr(buf, "0x");
if (p != NULL) {
p += strlen("0x");
} else {
p = buf;
}
d->scsi_host.wwpn = strndup(p, sizeof(buf));
if (d->scsi_host.wwpn == NULL) {
virReportOOMError(NULL);
retval = -1;
goto out;
}
p = strchr(d->scsi_host.wwpn, '\n');
if (p != NULL) {
*p = '\0';
}
out:
if (fd != -1) {
close(fd);
if (retval == -1) {
VIR_FREE(d->scsi_host.wwnn);
VIR_FREE(d->scsi_host.wwpn);
}
VIR_FREE(sysfs_path);
VIR_FREE(wwnn_path);
VIR_FREE(wwpn_path);
return 0;
}