mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2024-10-29 17:33:09 +00:00
* 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>
|
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
|
* src/storage_conf.c: fix reading of storage pool definitions at startup
|
||||||
|
@ -33,6 +33,7 @@
|
|||||||
#include "memory.h"
|
#include "memory.h"
|
||||||
#include "logging.h"
|
#include "logging.h"
|
||||||
#include "node_device_conf.h"
|
#include "node_device_conf.h"
|
||||||
|
#include "node_device_hal.h"
|
||||||
#include "node_device.h"
|
#include "node_device.h"
|
||||||
#include "storage_backend.h" /* For virWaitForDevices */
|
#include "storage_backend.h" /* For virWaitForDevices */
|
||||||
|
|
||||||
@ -49,6 +50,37 @@ static int dev_has_cap(const virNodeDeviceObjPtr dev, const char *cap)
|
|||||||
return 0;
|
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__
|
#ifdef __linux__
|
||||||
static int update_driver_name(virConnectPtr conn,
|
static int update_driver_name(virConnectPtr conn,
|
||||||
virNodeDeviceObjPtr dev)
|
virNodeDeviceObjPtr dev)
|
||||||
@ -253,6 +285,8 @@ static char *nodeDeviceDumpXML(virNodeDevicePtr dev,
|
|||||||
}
|
}
|
||||||
|
|
||||||
update_driver_name(dev->conn, obj);
|
update_driver_name(dev->conn, obj);
|
||||||
|
update_caps(obj);
|
||||||
|
|
||||||
ret = virNodeDeviceDefFormat(dev->conn, obj->def);
|
ret = virNodeDeviceDefFormat(dev->conn, obj->def);
|
||||||
|
|
||||||
cleanup:
|
cleanup:
|
||||||
|
@ -30,10 +30,14 @@ 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)
|
#define check_fc_host(d)
|
||||||
#define check_vport_capable(d)
|
#define check_vport_capable(d)
|
||||||
|
#define read_wwn(host, file, wwn)
|
||||||
|
|
||||||
#endif /* __linux__ */
|
#endif /* __linux__ */
|
||||||
|
|
||||||
|
@ -34,14 +34,84 @@
|
|||||||
|
|
||||||
#ifdef __linux__
|
#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;
|
char *p = NULL;
|
||||||
int fd = -1, retval = 0;
|
int fd = -1, retval = 0;
|
||||||
char buf[64];
|
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;
|
struct stat st;
|
||||||
|
|
||||||
VIR_DEBUG(_("Checking if host%d is an FC HBA"), d->scsi_host.host);
|
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;
|
d->scsi_host.flags |= VIR_NODE_DEV_CAP_FLAG_HBA_FC_HOST;
|
||||||
|
|
||||||
if (virAsprintf(&wwnn_path, "%s/node_name",
|
if (read_wwn(d->scsi_host.host,
|
||||||
sysfs_path) < 0) {
|
"port_name",
|
||||||
virReportOOMError(NULL);
|
&d->scsi_host.wwpn) == -1) {
|
||||||
|
VIR_ERROR(_("Failed to read WWPN for host%d"),
|
||||||
|
d->scsi_host.host);
|
||||||
retval = -1;
|
retval = -1;
|
||||||
goto out;
|
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;
|
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:
|
out:
|
||||||
if (fd != -1) {
|
if (retval == -1) {
|
||||||
close(fd);
|
VIR_FREE(d->scsi_host.wwnn);
|
||||||
|
VIR_FREE(d->scsi_host.wwpn);
|
||||||
}
|
}
|
||||||
VIR_FREE(sysfs_path);
|
VIR_FREE(sysfs_path);
|
||||||
VIR_FREE(wwnn_path);
|
|
||||||
VIR_FREE(wwpn_path);
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user