mirror of https://gitee.com/openkylin/libvirt.git
* 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:
parent
4c4ea03d7a
commit
b052424c0d
|
@ -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
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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__ */
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue