mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2024-12-22 13:45:38 +00:00
util: Move scsi_host specific functions from virutil
Create a virscsihost.c and place the functions there. That removes the last #ifdef __linux__ from virutil.c. Take the opporunity to also change the function names and in one case the parameters slightly
This commit is contained in:
parent
d2d74a986d
commit
03346def06
@ -242,6 +242,7 @@ src/util/virqemu.c
|
|||||||
src/util/virrandom.c
|
src/util/virrandom.c
|
||||||
src/util/virrotatingfile.c
|
src/util/virrotatingfile.c
|
||||||
src/util/virscsi.c
|
src/util/virscsi.c
|
||||||
|
src/util/virscsihost.c
|
||||||
src/util/virscsivhost.c
|
src/util/virscsivhost.c
|
||||||
src/util/virsecret.c
|
src/util/virsecret.c
|
||||||
src/util/virsexpr.c
|
src/util/virsexpr.c
|
||||||
|
@ -164,6 +164,7 @@ UTIL_SOURCES = \
|
|||||||
util/virrandom.h util/virrandom.c \
|
util/virrandom.h util/virrandom.c \
|
||||||
util/virrotatingfile.h util/virrotatingfile.c \
|
util/virrotatingfile.h util/virrotatingfile.c \
|
||||||
util/virscsi.c util/virscsi.h \
|
util/virscsi.c util/virscsi.h \
|
||||||
|
util/virscsihost.c util/virscsihost.h \
|
||||||
util/virscsivhost.c util/virscsivhost.h \
|
util/virscsivhost.c util/virscsivhost.h \
|
||||||
util/virseclabel.c util/virseclabel.h \
|
util/virseclabel.c util/virseclabel.h \
|
||||||
util/virsecret.c util/virsecret.h \
|
util/virsecret.c util/virsecret.h \
|
||||||
|
@ -44,6 +44,7 @@
|
|||||||
#include "virbuffer.h"
|
#include "virbuffer.h"
|
||||||
#include "viralloc.h"
|
#include "viralloc.h"
|
||||||
#include "virfile.h"
|
#include "virfile.h"
|
||||||
|
#include "virscsihost.h"
|
||||||
#include "virstring.h"
|
#include "virstring.h"
|
||||||
#include "virlog.h"
|
#include "virlog.h"
|
||||||
#include "virvhba.h"
|
#include "virvhba.h"
|
||||||
@ -2289,16 +2290,16 @@ getSCSIHostNumber(virStoragePoolSourceAdapter adapter,
|
|||||||
virPCIDeviceAddress addr = adapter.data.scsi_host.parentaddr;
|
virPCIDeviceAddress addr = adapter.data.scsi_host.parentaddr;
|
||||||
unsigned int unique_id = adapter.data.scsi_host.unique_id;
|
unsigned int unique_id = adapter.data.scsi_host.unique_id;
|
||||||
|
|
||||||
if (!(name = virGetSCSIHostNameByParentaddr(addr.domain,
|
if (!(name = virSCSIHostGetNameByParentaddr(addr.domain,
|
||||||
addr.bus,
|
addr.bus,
|
||||||
addr.slot,
|
addr.slot,
|
||||||
addr.function,
|
addr.function,
|
||||||
unique_id)))
|
unique_id)))
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
if (virGetSCSIHostNumber(name, &num) < 0)
|
if (virSCSIHostGetNumber(name, &num) < 0)
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
} else {
|
} else {
|
||||||
if (virGetSCSIHostNumber(adapter.data.scsi_host.name, &num) < 0)
|
if (virSCSIHostGetNumber(adapter.data.scsi_host.name, &num) < 0)
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2310,6 +2311,21 @@ getSCSIHostNumber(virStoragePoolSourceAdapter adapter,
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static bool
|
||||||
|
virStorageIsSameHostnum(const char *name,
|
||||||
|
unsigned int scsi_hostnum)
|
||||||
|
{
|
||||||
|
unsigned int fc_hostnum;
|
||||||
|
|
||||||
|
if (virSCSIHostGetNumber(name, &fc_hostnum) == 0 &&
|
||||||
|
scsi_hostnum == fc_hostnum)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* matchFCHostToSCSIHost:
|
* matchFCHostToSCSIHost:
|
||||||
*
|
*
|
||||||
@ -2328,14 +2344,12 @@ matchFCHostToSCSIHost(virConnectPtr conn,
|
|||||||
char *name = NULL;
|
char *name = NULL;
|
||||||
char *scsi_host_name = NULL;
|
char *scsi_host_name = NULL;
|
||||||
char *parent_name = NULL;
|
char *parent_name = NULL;
|
||||||
unsigned int fc_hostnum;
|
|
||||||
|
|
||||||
/* If we have a parent defined, get its hostnum, and compare to the
|
/* If we have a parent defined, get its hostnum, and compare to the
|
||||||
* scsi_hostnum. If they are the same, then we have a match
|
* scsi_hostnum. If they are the same, then we have a match
|
||||||
*/
|
*/
|
||||||
if (fc_adapter.data.fchost.parent &&
|
if (fc_adapter.data.fchost.parent &&
|
||||||
virGetSCSIHostNumber(fc_adapter.data.fchost.parent, &fc_hostnum) == 0 &&
|
virStorageIsSameHostnum(fc_adapter.data.fchost.parent, scsi_hostnum))
|
||||||
scsi_hostnum == fc_hostnum)
|
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
/* If we find an fc_adapter name, then either libvirt created a vHBA
|
/* If we find an fc_adapter name, then either libvirt created a vHBA
|
||||||
@ -2347,11 +2361,11 @@ matchFCHostToSCSIHost(virConnectPtr conn,
|
|||||||
/* Get the scsi_hostN for the vHBA in order to see if it
|
/* Get the scsi_hostN for the vHBA in order to see if it
|
||||||
* matches our scsi_hostnum
|
* matches our scsi_hostnum
|
||||||
*/
|
*/
|
||||||
if (virGetSCSIHostNumber(name, &fc_hostnum) == 0 &&
|
if (virStorageIsSameHostnum(name, scsi_hostnum)) {
|
||||||
scsi_hostnum == fc_hostnum) {
|
|
||||||
VIR_FREE(name);
|
VIR_FREE(name);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
VIR_FREE(name);
|
||||||
|
|
||||||
/* We weren't provided a parent, so we have to query the node
|
/* We weren't provided a parent, so we have to query the node
|
||||||
* device driver in order to ascertain the parent of the vHBA.
|
* device driver in order to ascertain the parent of the vHBA.
|
||||||
@ -2366,10 +2380,8 @@ matchFCHostToSCSIHost(virConnectPtr conn,
|
|||||||
if ((parent_name = virNodeDeviceGetParentName(conn,
|
if ((parent_name = virNodeDeviceGetParentName(conn,
|
||||||
scsi_host_name))) {
|
scsi_host_name))) {
|
||||||
VIR_FREE(scsi_host_name);
|
VIR_FREE(scsi_host_name);
|
||||||
if (virGetSCSIHostNumber(parent_name, &fc_hostnum) == 0 &&
|
if (virStorageIsSameHostnum(parent_name, scsi_hostnum)) {
|
||||||
scsi_hostnum == fc_hostnum) {
|
|
||||||
VIR_FREE(parent_name);
|
VIR_FREE(parent_name);
|
||||||
VIR_FREE(name);
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
VIR_FREE(parent_name);
|
VIR_FREE(parent_name);
|
||||||
@ -2380,7 +2392,6 @@ matchFCHostToSCSIHost(virConnectPtr conn,
|
|||||||
VIR_FREE(scsi_host_name);
|
VIR_FREE(scsi_host_name);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
VIR_FREE(name);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* NB: Lack of a name means that this vHBA hasn't yet been created,
|
/* NB: Lack of a name means that this vHBA hasn't yet been created,
|
||||||
|
@ -2354,6 +2354,12 @@ virSCSIDeviceNew;
|
|||||||
virSCSIDeviceSetUsedBy;
|
virSCSIDeviceSetUsedBy;
|
||||||
|
|
||||||
|
|
||||||
|
# util/virscsihost.h
|
||||||
|
virSCSIHostFindByPCI;
|
||||||
|
virSCSIHostGetNameByParentaddr;
|
||||||
|
virSCSIHostGetNumber;
|
||||||
|
virSCSIHostGetUniqueId;
|
||||||
|
|
||||||
# util/virscsivhost.h
|
# util/virscsivhost.h
|
||||||
virSCSIVHostDeviceFileIterate;
|
virSCSIVHostDeviceFileIterate;
|
||||||
virSCSIVHostDeviceFree;
|
virSCSIVHostDeviceFree;
|
||||||
@ -2679,7 +2685,6 @@ virUSBDeviceSetUsedBy;
|
|||||||
virDoubleToStr;
|
virDoubleToStr;
|
||||||
virEnumFromString;
|
virEnumFromString;
|
||||||
virEnumToString;
|
virEnumToString;
|
||||||
virFindSCSIHostByPCI;
|
|
||||||
virFormatIntDecimal;
|
virFormatIntDecimal;
|
||||||
virGetDeviceID;
|
virGetDeviceID;
|
||||||
virGetDeviceUnprivSGIO;
|
virGetDeviceUnprivSGIO;
|
||||||
@ -2691,8 +2696,6 @@ virGetGroupName;
|
|||||||
virGetHostname;
|
virGetHostname;
|
||||||
virGetHostnameQuiet;
|
virGetHostnameQuiet;
|
||||||
virGetListenFDs;
|
virGetListenFDs;
|
||||||
virGetSCSIHostNameByParentaddr;
|
|
||||||
virGetSCSIHostNumber;
|
|
||||||
virGetSelfLastChanged;
|
virGetSelfLastChanged;
|
||||||
virGetSystemPageSize;
|
virGetSystemPageSize;
|
||||||
virGetSystemPageSizeKB;
|
virGetSystemPageSizeKB;
|
||||||
@ -2716,7 +2719,6 @@ virParseNumber;
|
|||||||
virParseOwnershipIds;
|
virParseOwnershipIds;
|
||||||
virParseVersionString;
|
virParseVersionString;
|
||||||
virPipeReadUntilEOF;
|
virPipeReadUntilEOF;
|
||||||
virReadSCSIUniqueId;
|
|
||||||
virScaleInteger;
|
virScaleInteger;
|
||||||
virSetBlocking;
|
virSetBlocking;
|
||||||
virSetCloseExec;
|
virSetCloseExec;
|
||||||
|
@ -33,6 +33,7 @@
|
|||||||
#include "viralloc.h"
|
#include "viralloc.h"
|
||||||
#include "virlog.h"
|
#include "virlog.h"
|
||||||
#include "virfile.h"
|
#include "virfile.h"
|
||||||
|
#include "virscsihost.h"
|
||||||
#include "virstring.h"
|
#include "virstring.h"
|
||||||
#include "virvhba.h"
|
#include "virvhba.h"
|
||||||
|
|
||||||
@ -48,8 +49,8 @@ nodeDeviceSysfsGetSCSIHostCaps(virNodeDevCapDataPtr d)
|
|||||||
char *tmp = NULL;
|
char *tmp = NULL;
|
||||||
int ret = -1;
|
int ret = -1;
|
||||||
|
|
||||||
if (virReadSCSIUniqueId(NULL, d->scsi_host.host,
|
if ((d->scsi_host.unique_id =
|
||||||
&d->scsi_host.unique_id) < 0) {
|
virSCSIHostGetUniqueId(NULL, d->scsi_host.host)) < 0) {
|
||||||
VIR_DEBUG("Failed to read unique_id for host%d", d->scsi_host.host);
|
VIR_DEBUG("Failed to read unique_id for host%d", d->scsi_host.host);
|
||||||
d->scsi_host.unique_id = -1;
|
d->scsi_host.unique_id = -1;
|
||||||
}
|
}
|
||||||
|
@ -33,6 +33,7 @@
|
|||||||
#include "virlog.h"
|
#include "virlog.h"
|
||||||
#include "virfile.h"
|
#include "virfile.h"
|
||||||
#include "vircommand.h"
|
#include "vircommand.h"
|
||||||
|
#include "virscsihost.h"
|
||||||
#include "virstring.h"
|
#include "virstring.h"
|
||||||
#include "virvhba.h"
|
#include "virvhba.h"
|
||||||
#include "storage_util.h"
|
#include "storage_util.h"
|
||||||
@ -160,7 +161,7 @@ virStoragePoolFCRefreshThread(void *opaque)
|
|||||||
pool->def->allocation = pool->def->capacity = pool->def->available = 0;
|
pool->def->allocation = pool->def->capacity = pool->def->available = 0;
|
||||||
|
|
||||||
if (virStoragePoolObjIsActive(pool) &&
|
if (virStoragePoolObjIsActive(pool) &&
|
||||||
virGetSCSIHostNumber(fchost_name, &host) == 0 &&
|
virSCSIHostGetNumber(fchost_name, &host) == 0 &&
|
||||||
virStorageBackendSCSITriggerRescan(host) == 0) {
|
virStorageBackendSCSITriggerRescan(host) == 0) {
|
||||||
virStoragePoolObjClearVols(pool);
|
virStoragePoolObjClearVols(pool);
|
||||||
found = virStorageBackendSCSIFindLUs(pool, host);
|
found = virStorageBackendSCSIFindLUs(pool, host);
|
||||||
@ -185,7 +186,7 @@ getAdapterName(virStoragePoolSourceAdapter adapter)
|
|||||||
virPCIDeviceAddress addr = adapter.data.scsi_host.parentaddr;
|
virPCIDeviceAddress addr = adapter.data.scsi_host.parentaddr;
|
||||||
unsigned int unique_id = adapter.data.scsi_host.unique_id;
|
unsigned int unique_id = adapter.data.scsi_host.unique_id;
|
||||||
|
|
||||||
if (!(name = virGetSCSIHostNameByParentaddr(addr.domain,
|
if (!(name = virSCSIHostGetNameByParentaddr(addr.domain,
|
||||||
addr.bus,
|
addr.bus,
|
||||||
addr.slot,
|
addr.slot,
|
||||||
addr.function,
|
addr.function,
|
||||||
@ -318,7 +319,7 @@ createVport(virConnectPtr conn,
|
|||||||
skip_capable_check = true;
|
skip_capable_check = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (virGetSCSIHostNumber(parent_hoststr, &parent_host) < 0)
|
if (virSCSIHostGetNumber(parent_hoststr, &parent_host) < 0)
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
|
|
||||||
/* NOTE:
|
/* NOTE:
|
||||||
@ -420,7 +421,7 @@ deleteVport(virConnectPtr conn,
|
|||||||
* the parent scsi_host which we did not save at startup time
|
* the parent scsi_host which we did not save at startup time
|
||||||
*/
|
*/
|
||||||
if (adapter.data.fchost.parent) {
|
if (adapter.data.fchost.parent) {
|
||||||
if (virGetSCSIHostNumber(adapter.data.fchost.parent, &parent_host) < 0)
|
if (virSCSIHostGetNumber(adapter.data.fchost.parent, &parent_host) < 0)
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
} else {
|
} else {
|
||||||
if (virAsprintf(&scsi_host_name, "scsi_%s", name) < 0)
|
if (virAsprintf(&scsi_host_name, "scsi_%s", name) < 0)
|
||||||
@ -429,7 +430,7 @@ deleteVport(virConnectPtr conn,
|
|||||||
if (!(vhba_parent = virNodeDeviceGetParentName(conn, scsi_host_name)))
|
if (!(vhba_parent = virNodeDeviceGetParentName(conn, scsi_host_name)))
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
|
|
||||||
if (virGetSCSIHostNumber(vhba_parent, &parent_host) < 0)
|
if (virSCSIHostGetNumber(vhba_parent, &parent_host) < 0)
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -471,7 +472,7 @@ virStorageBackendSCSICheckPool(virStoragePoolObjPtr pool,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (virGetSCSIHostNumber(name, &host) < 0)
|
if (virSCSIHostGetNumber(name, &host) < 0)
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
|
|
||||||
if (virAsprintf(&path, "%s/host%d",
|
if (virAsprintf(&path, "%s/host%d",
|
||||||
@ -500,7 +501,7 @@ virStorageBackendSCSIRefreshPool(virConnectPtr conn ATTRIBUTE_UNUSED,
|
|||||||
if (!(name = getAdapterName(pool->def->source.adapter)))
|
if (!(name = getAdapterName(pool->def->source.adapter)))
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
if (virGetSCSIHostNumber(name, &host) < 0)
|
if (virSCSIHostGetNumber(name, &host) < 0)
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
VIR_DEBUG("Scanning host%u", host);
|
VIR_DEBUG("Scanning host%u", host);
|
||||||
|
297
src/util/virscsihost.c
Normal file
297
src/util/virscsihost.c
Normal file
@ -0,0 +1,297 @@
|
|||||||
|
/*
|
||||||
|
* virscsihost.c: Generic scsi_host management utility functions
|
||||||
|
*
|
||||||
|
* This library is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU Lesser General Public
|
||||||
|
* License as published by the Free Software Foundation; either
|
||||||
|
* version 2.1 of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This library is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
* Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public
|
||||||
|
* License along with this library. If not, see
|
||||||
|
* <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <config.h>
|
||||||
|
#include <dirent.h>
|
||||||
|
|
||||||
|
#include "viralloc.h"
|
||||||
|
#include "virerror.h"
|
||||||
|
#include "virfile.h"
|
||||||
|
#include "virlog.h"
|
||||||
|
#include "virscsihost.h"
|
||||||
|
#include "virstring.h"
|
||||||
|
|
||||||
|
#define VIR_FROM_THIS VIR_FROM_NONE
|
||||||
|
|
||||||
|
VIR_LOG_INIT("util.scsi_host");
|
||||||
|
|
||||||
|
#ifdef __linux__
|
||||||
|
|
||||||
|
# define SYSFS_SCSI_HOST_PATH "/sys/class/scsi_host"
|
||||||
|
|
||||||
|
/* virSCSIHostGetUniqueId:
|
||||||
|
* @sysfs_prefix: "scsi_host" sysfs path, defaults to SYSFS_SCSI_HOST_PATH
|
||||||
|
* @host: Host number, E.g. 5 of "scsi_host/host5"
|
||||||
|
*
|
||||||
|
* Read the value of the "scsi_host" unique_id file.
|
||||||
|
*
|
||||||
|
* Returns the value on success or -1 on failure.
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
virSCSIHostGetUniqueId(const char *sysfs_prefix,
|
||||||
|
int host)
|
||||||
|
{
|
||||||
|
char *sysfs_path = NULL;
|
||||||
|
char *p = NULL;
|
||||||
|
int ret = -1;
|
||||||
|
char *buf = NULL;
|
||||||
|
int unique_id;
|
||||||
|
|
||||||
|
if (virAsprintf(&sysfs_path, "%s/host%d/unique_id",
|
||||||
|
sysfs_prefix ? sysfs_prefix : SYSFS_SCSI_HOST_PATH,
|
||||||
|
host) < 0)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
if (virFileReadAll(sysfs_path, 1024, &buf) < 0)
|
||||||
|
goto cleanup;
|
||||||
|
|
||||||
|
if ((p = strchr(buf, '\n')))
|
||||||
|
*p = '\0';
|
||||||
|
|
||||||
|
if (virStrToLong_i(buf, NULL, 10, &unique_id) < 0) {
|
||||||
|
virReportError(VIR_ERR_INTERNAL_ERROR,
|
||||||
|
_("unable to parse unique_id: %s"), buf);
|
||||||
|
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = unique_id;
|
||||||
|
|
||||||
|
cleanup:
|
||||||
|
VIR_FREE(sysfs_path);
|
||||||
|
VIR_FREE(buf);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* virSCSIHostFindByPCI:
|
||||||
|
* @sysfs_prefix: "scsi_host" sysfs path, defaults to SYSFS_SCSI_HOST_PATH
|
||||||
|
* @parentaddr: string of the PCI address "scsi_host" device to be found
|
||||||
|
* @unique_id: unique_id value of the to be found "scsi_host" device
|
||||||
|
* @result: Return the host# of the matching "scsi_host" device
|
||||||
|
*
|
||||||
|
* Iterate over the SYSFS_SCSI_HOST_PATH entries looking for a matching
|
||||||
|
* PCI Address in the expected format (dddd:bb:ss.f, where 'dddd' is the
|
||||||
|
* 'domain' value, 'bb' is the 'bus' value, 'ss' is the 'slot' value, and
|
||||||
|
* 'f' is the 'function' value from the PCI address) with a unique_id file
|
||||||
|
* entry having the value expected. Unlike virReadSCSIUniqueId() we don't
|
||||||
|
* have a host number yet and that's what we're looking for.
|
||||||
|
*
|
||||||
|
* Returns the host name of the "scsi_host" which must be freed by the caller,
|
||||||
|
* or NULL on failure
|
||||||
|
*/
|
||||||
|
char *
|
||||||
|
virSCSIHostFindByPCI(const char *sysfs_prefix,
|
||||||
|
const char *parentaddr,
|
||||||
|
unsigned int unique_id)
|
||||||
|
{
|
||||||
|
const char *prefix = sysfs_prefix ? sysfs_prefix : SYSFS_SCSI_HOST_PATH;
|
||||||
|
struct dirent *entry = NULL;
|
||||||
|
DIR *dir = NULL;
|
||||||
|
char *host_link = NULL;
|
||||||
|
char *host_path = NULL;
|
||||||
|
char *p = NULL;
|
||||||
|
char *ret = NULL;
|
||||||
|
char *buf = NULL;
|
||||||
|
char *unique_path = NULL;
|
||||||
|
unsigned int read_unique_id;
|
||||||
|
|
||||||
|
if (virDirOpen(&dir, prefix) < 0)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
while (virDirRead(dir, &entry, prefix) > 0) {
|
||||||
|
if (!virFileIsLink(entry->d_name))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (virAsprintf(&host_link, "%s/%s", prefix, entry->d_name) < 0)
|
||||||
|
goto cleanup;
|
||||||
|
|
||||||
|
if (virFileResolveLink(host_link, &host_path) < 0)
|
||||||
|
goto cleanup;
|
||||||
|
|
||||||
|
if (!strstr(host_path, parentaddr)) {
|
||||||
|
VIR_FREE(host_link);
|
||||||
|
VIR_FREE(host_path);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
VIR_FREE(host_link);
|
||||||
|
VIR_FREE(host_path);
|
||||||
|
|
||||||
|
if (virAsprintf(&unique_path, "%s/%s/unique_id", prefix,
|
||||||
|
entry->d_name) < 0)
|
||||||
|
goto cleanup;
|
||||||
|
|
||||||
|
if (!virFileExists(unique_path)) {
|
||||||
|
VIR_FREE(unique_path);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (virFileReadAll(unique_path, 1024, &buf) < 0)
|
||||||
|
goto cleanup;
|
||||||
|
|
||||||
|
if ((p = strchr(buf, '\n')))
|
||||||
|
*p = '\0';
|
||||||
|
|
||||||
|
if (virStrToLong_ui(buf, NULL, 10, &read_unique_id) < 0)
|
||||||
|
goto cleanup;
|
||||||
|
|
||||||
|
VIR_FREE(buf);
|
||||||
|
|
||||||
|
if (read_unique_id != unique_id) {
|
||||||
|
VIR_FREE(unique_path);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
ignore_value(VIR_STRDUP(ret, entry->d_name));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
cleanup:
|
||||||
|
VIR_DIR_CLOSE(dir);
|
||||||
|
VIR_FREE(unique_path);
|
||||||
|
VIR_FREE(host_link);
|
||||||
|
VIR_FREE(host_path);
|
||||||
|
VIR_FREE(buf);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* virSCSIHostGetNumber:
|
||||||
|
* @adapter_name: Name of the host adapter
|
||||||
|
* @result: Return the entry value as unsigned int
|
||||||
|
*
|
||||||
|
* Convert the various forms of scsi_host names into the numeric
|
||||||
|
* host# value that can be used in order to scan sysfs looking for
|
||||||
|
* the specific host.
|
||||||
|
*
|
||||||
|
* Names can be either "scsi_host#" or just "host#", where
|
||||||
|
* "host#" is the back-compat format, but both equate to
|
||||||
|
* the same source adapter. First check if both pool and def
|
||||||
|
* are using same format (easier) - if so, then compare
|
||||||
|
*
|
||||||
|
* Returns 0 on success, and @result has the host number.
|
||||||
|
* Otherwise returns -1.
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
virSCSIHostGetNumber(const char *adapter_name,
|
||||||
|
unsigned int *result)
|
||||||
|
{
|
||||||
|
/* Specifying adapter like 'host5' is still supported for
|
||||||
|
* back-compat reason.
|
||||||
|
*/
|
||||||
|
if (STRPREFIX(adapter_name, "scsi_host")) {
|
||||||
|
adapter_name += strlen("scsi_host");
|
||||||
|
} else if (STRPREFIX(adapter_name, "fc_host")) {
|
||||||
|
adapter_name += strlen("fc_host");
|
||||||
|
} else if (STRPREFIX(adapter_name, "host")) {
|
||||||
|
adapter_name += strlen("host");
|
||||||
|
} else {
|
||||||
|
virReportError(VIR_ERR_INTERNAL_ERROR,
|
||||||
|
_("Invalid adapter name '%s' for SCSI pool"),
|
||||||
|
adapter_name);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (virStrToLong_ui(adapter_name, NULL, 10, result) == -1) {
|
||||||
|
virReportError(VIR_ERR_INTERNAL_ERROR,
|
||||||
|
_("Invalid adapter name '%s' for SCSI pool"),
|
||||||
|
adapter_name);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* virSCSIHostGetNameByParentaddr:
|
||||||
|
* @domain: The domain from the scsi_host parentaddr
|
||||||
|
* @bus: The bus from the scsi_host parentaddr
|
||||||
|
* @slot: The slot from the scsi_host parentaddr
|
||||||
|
* @function: The function from the scsi_host parentaddr
|
||||||
|
* @unique_id: The unique id value for parentaddr
|
||||||
|
*
|
||||||
|
* Generate a parentaddr and find the scsi_host host# for
|
||||||
|
* the provided parentaddr PCI address fields.
|
||||||
|
*
|
||||||
|
* Returns the "host#" string which must be free'd by
|
||||||
|
* the caller or NULL on error
|
||||||
|
*/
|
||||||
|
char *
|
||||||
|
virSCSIHostGetNameByParentaddr(unsigned int domain,
|
||||||
|
unsigned int bus,
|
||||||
|
unsigned int slot,
|
||||||
|
unsigned int function,
|
||||||
|
unsigned int unique_id)
|
||||||
|
{
|
||||||
|
char *name = NULL;
|
||||||
|
char *parentaddr = NULL;
|
||||||
|
|
||||||
|
if (virAsprintf(&parentaddr, "%04x:%02x:%02x.%01x",
|
||||||
|
domain, bus, slot, function) < 0)
|
||||||
|
goto cleanup;
|
||||||
|
if (!(name = virSCSIHostFindByPCI(NULL, parentaddr, unique_id))) {
|
||||||
|
virReportError(VIR_ERR_XML_ERROR,
|
||||||
|
_("Failed to find scsi_host using PCI '%s' "
|
||||||
|
"and unique_id='%u'"),
|
||||||
|
parentaddr, unique_id);
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
|
cleanup:
|
||||||
|
VIR_FREE(parentaddr);
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
int
|
||||||
|
virSCSIHostGetUniqueId(const char *sysfs_prefix ATTRIBUTE_UNUSED,
|
||||||
|
int host ATTRIBUTE_UNUSED)
|
||||||
|
{
|
||||||
|
virReportSystemError(ENOSYS, "%s", _("Not supported on this platform"));
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
char *
|
||||||
|
virSCSIHostFindByPCI(const char *sysfs_prefix ATTRIBUTE_UNUSED,
|
||||||
|
const char *parentaddr ATTRIBUTE_UNUSED,
|
||||||
|
unsigned int unique_id ATTRIBUTE_UNUSED)
|
||||||
|
{
|
||||||
|
virReportSystemError(ENOSYS, "%s", _("Not supported on this platform"));
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
virSCSIHostGetNumber(const char *adapter_name ATTRIBUTE_UNUSED,
|
||||||
|
unsigned int *result ATTRIBUTE_UNUSED)
|
||||||
|
{
|
||||||
|
virReportSystemError(ENOSYS, "%s", _("Not supported on this platform"));
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
char *
|
||||||
|
virSCSIHostGetNameByParentaddr(unsigned int domain ATTRIBUTE_UNUSED,
|
||||||
|
unsigned int bus ATTRIBUTE_UNUSED,
|
||||||
|
unsigned int slot ATTRIBUTE_UNUSED,
|
||||||
|
unsigned int function ATTRIBUTE_UNUSED,
|
||||||
|
unsigned int unique_id ATTRIBUTE_UNUSED)
|
||||||
|
{
|
||||||
|
virReportSystemError(ENOSYS, "%s", _("Not supported on this platform"));
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* __linux__ */
|
40
src/util/virscsihost.h
Normal file
40
src/util/virscsihost.h
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
/*
|
||||||
|
* virscsihost.h: Generic scsi_host management utility functions
|
||||||
|
*
|
||||||
|
* This library is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU Lesser General Public
|
||||||
|
* License as published by the Free Software Foundation; either
|
||||||
|
* version 2.1 of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This library is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
* Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public
|
||||||
|
* License along with this library. If not, see
|
||||||
|
* <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __VIR_SCSI_HOST_H__
|
||||||
|
# define __VIR_SCSI_HOST_H__
|
||||||
|
|
||||||
|
# include "internal.h"
|
||||||
|
|
||||||
|
int virSCSIHostGetUniqueId(const char *sysfs_prefix, int host);
|
||||||
|
|
||||||
|
char *virSCSIHostFindByPCI(const char *sysfs_prefix,
|
||||||
|
const char *parentaddr,
|
||||||
|
unsigned int unique_id);
|
||||||
|
|
||||||
|
int virSCSIHostGetNumber(const char *adapter_name,
|
||||||
|
unsigned int *result)
|
||||||
|
ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2);
|
||||||
|
|
||||||
|
char *virSCSIHostGetNameByParentaddr(unsigned int domain,
|
||||||
|
unsigned int bus,
|
||||||
|
unsigned int slot,
|
||||||
|
unsigned int function,
|
||||||
|
unsigned int unique_id);
|
||||||
|
|
||||||
|
#endif /* __VIR_SCSI_HOST_H__ */
|
@ -27,7 +27,6 @@
|
|||||||
#include <config.h>
|
#include <config.h>
|
||||||
|
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <dirent.h>
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
@ -1776,274 +1775,6 @@ virGetDeviceUnprivSGIO(const char *path,
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef __linux__
|
|
||||||
|
|
||||||
# define SYSFS_SCSI_HOST_PATH "/sys/class/scsi_host"
|
|
||||||
|
|
||||||
/* virReadSCSIUniqueId:
|
|
||||||
* @sysfs_prefix: "scsi_host" sysfs path, defaults to SYSFS_SCSI_HOST_PATH
|
|
||||||
* @host: Host number, E.g. 5 of "scsi_host/host5"
|
|
||||||
* @result: Return the entry value as an unsigned int
|
|
||||||
*
|
|
||||||
* Read the value of the "scsi_host" unique_id file.
|
|
||||||
*
|
|
||||||
* Returns 0 on success, and @result is filled with the unique_id value
|
|
||||||
* Otherwise returns -1
|
|
||||||
*/
|
|
||||||
int
|
|
||||||
virReadSCSIUniqueId(const char *sysfs_prefix,
|
|
||||||
int host,
|
|
||||||
int *result)
|
|
||||||
{
|
|
||||||
char *sysfs_path = NULL;
|
|
||||||
char *p = NULL;
|
|
||||||
int ret = -1;
|
|
||||||
char *buf = NULL;
|
|
||||||
int unique_id;
|
|
||||||
|
|
||||||
if (virAsprintf(&sysfs_path, "%s/host%d/unique_id",
|
|
||||||
sysfs_prefix ? sysfs_prefix : SYSFS_SCSI_HOST_PATH,
|
|
||||||
host) < 0)
|
|
||||||
goto cleanup;
|
|
||||||
|
|
||||||
if (virFileReadAll(sysfs_path, 1024, &buf) < 0)
|
|
||||||
goto cleanup;
|
|
||||||
|
|
||||||
if ((p = strchr(buf, '\n')))
|
|
||||||
*p = '\0';
|
|
||||||
|
|
||||||
if (virStrToLong_i(buf, NULL, 10, &unique_id) < 0) {
|
|
||||||
virReportError(VIR_ERR_INTERNAL_ERROR,
|
|
||||||
_("unable to parse unique_id: %s"), buf);
|
|
||||||
|
|
||||||
goto cleanup;
|
|
||||||
}
|
|
||||||
|
|
||||||
*result = unique_id;
|
|
||||||
ret = 0;
|
|
||||||
|
|
||||||
cleanup:
|
|
||||||
VIR_FREE(sysfs_path);
|
|
||||||
VIR_FREE(buf);
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* virFindSCSIHostByPCI:
|
|
||||||
* @sysfs_prefix: "scsi_host" sysfs path, defaults to SYSFS_SCSI_HOST_PATH
|
|
||||||
* @parentaddr: string of the PCI address "scsi_host" device to be found
|
|
||||||
* @unique_id: unique_id value of the to be found "scsi_host" device
|
|
||||||
* @result: Return the host# of the matching "scsi_host" device
|
|
||||||
*
|
|
||||||
* Iterate over the SYSFS_SCSI_HOST_PATH entries looking for a matching
|
|
||||||
* PCI Address in the expected format (dddd:bb:ss.f, where 'dddd' is the
|
|
||||||
* 'domain' value, 'bb' is the 'bus' value, 'ss' is the 'slot' value, and
|
|
||||||
* 'f' is the 'function' value from the PCI address) with a unique_id file
|
|
||||||
* entry having the value expected. Unlike virReadSCSIUniqueId() we don't
|
|
||||||
* have a host number yet and that's what we're looking for.
|
|
||||||
*
|
|
||||||
* Returns the host name of the "scsi_host" which must be freed by the caller,
|
|
||||||
* or NULL on failure
|
|
||||||
*/
|
|
||||||
char *
|
|
||||||
virFindSCSIHostByPCI(const char *sysfs_prefix,
|
|
||||||
const char *parentaddr,
|
|
||||||
unsigned int unique_id)
|
|
||||||
{
|
|
||||||
const char *prefix = sysfs_prefix ? sysfs_prefix : SYSFS_SCSI_HOST_PATH;
|
|
||||||
struct dirent *entry = NULL;
|
|
||||||
DIR *dir = NULL;
|
|
||||||
char *host_link = NULL;
|
|
||||||
char *host_path = NULL;
|
|
||||||
char *p = NULL;
|
|
||||||
char *ret = NULL;
|
|
||||||
char *buf = NULL;
|
|
||||||
char *unique_path = NULL;
|
|
||||||
unsigned int read_unique_id;
|
|
||||||
|
|
||||||
if (virDirOpen(&dir, prefix) < 0)
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
while (virDirRead(dir, &entry, prefix) > 0) {
|
|
||||||
if (!virFileIsLink(entry->d_name))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
if (virAsprintf(&host_link, "%s/%s", prefix, entry->d_name) < 0)
|
|
||||||
goto cleanup;
|
|
||||||
|
|
||||||
if (virFileResolveLink(host_link, &host_path) < 0)
|
|
||||||
goto cleanup;
|
|
||||||
|
|
||||||
if (!strstr(host_path, parentaddr)) {
|
|
||||||
VIR_FREE(host_link);
|
|
||||||
VIR_FREE(host_path);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
VIR_FREE(host_link);
|
|
||||||
VIR_FREE(host_path);
|
|
||||||
|
|
||||||
if (virAsprintf(&unique_path, "%s/%s/unique_id", prefix,
|
|
||||||
entry->d_name) < 0)
|
|
||||||
goto cleanup;
|
|
||||||
|
|
||||||
if (!virFileExists(unique_path)) {
|
|
||||||
VIR_FREE(unique_path);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (virFileReadAll(unique_path, 1024, &buf) < 0)
|
|
||||||
goto cleanup;
|
|
||||||
|
|
||||||
if ((p = strchr(buf, '\n')))
|
|
||||||
*p = '\0';
|
|
||||||
|
|
||||||
if (virStrToLong_ui(buf, NULL, 10, &read_unique_id) < 0)
|
|
||||||
goto cleanup;
|
|
||||||
|
|
||||||
VIR_FREE(buf);
|
|
||||||
|
|
||||||
if (read_unique_id != unique_id) {
|
|
||||||
VIR_FREE(unique_path);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
ignore_value(VIR_STRDUP(ret, entry->d_name));
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
cleanup:
|
|
||||||
VIR_DIR_CLOSE(dir);
|
|
||||||
VIR_FREE(unique_path);
|
|
||||||
VIR_FREE(host_link);
|
|
||||||
VIR_FREE(host_path);
|
|
||||||
VIR_FREE(buf);
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* virGetSCSIHostNumber:
|
|
||||||
* @adapter_name: Name of the host adapter
|
|
||||||
* @result: Return the entry value as unsigned int
|
|
||||||
*
|
|
||||||
* Convert the various forms of scsi_host names into the numeric
|
|
||||||
* host# value that can be used in order to scan sysfs looking for
|
|
||||||
* the specific host.
|
|
||||||
*
|
|
||||||
* Names can be either "scsi_host#" or just "host#", where
|
|
||||||
* "host#" is the back-compat format, but both equate to
|
|
||||||
* the same source adapter. First check if both pool and def
|
|
||||||
* are using same format (easier) - if so, then compare
|
|
||||||
*
|
|
||||||
* Returns 0 on success, and @result has the host number.
|
|
||||||
* Otherwise returns -1.
|
|
||||||
*/
|
|
||||||
int
|
|
||||||
virGetSCSIHostNumber(const char *adapter_name,
|
|
||||||
unsigned int *result)
|
|
||||||
{
|
|
||||||
/* Specifying adapter like 'host5' is still supported for
|
|
||||||
* back-compat reason.
|
|
||||||
*/
|
|
||||||
if (STRPREFIX(adapter_name, "scsi_host")) {
|
|
||||||
adapter_name += strlen("scsi_host");
|
|
||||||
} else if (STRPREFIX(adapter_name, "fc_host")) {
|
|
||||||
adapter_name += strlen("fc_host");
|
|
||||||
} else if (STRPREFIX(adapter_name, "host")) {
|
|
||||||
adapter_name += strlen("host");
|
|
||||||
} else {
|
|
||||||
virReportError(VIR_ERR_INTERNAL_ERROR,
|
|
||||||
_("Invalid adapter name '%s' for SCSI pool"),
|
|
||||||
adapter_name);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (virStrToLong_ui(adapter_name, NULL, 10, result) == -1) {
|
|
||||||
virReportError(VIR_ERR_INTERNAL_ERROR,
|
|
||||||
_("Invalid adapter name '%s' for SCSI pool"),
|
|
||||||
adapter_name);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* virGetSCSIHostNameByParentaddr:
|
|
||||||
* @domain: The domain from the scsi_host parentaddr
|
|
||||||
* @bus: The bus from the scsi_host parentaddr
|
|
||||||
* @slot: The slot from the scsi_host parentaddr
|
|
||||||
* @function: The function from the scsi_host parentaddr
|
|
||||||
* @unique_id: The unique id value for parentaddr
|
|
||||||
*
|
|
||||||
* Generate a parentaddr and find the scsi_host host# for
|
|
||||||
* the provided parentaddr PCI address fields.
|
|
||||||
*
|
|
||||||
* Returns the "host#" string which must be free'd by
|
|
||||||
* the caller or NULL on error
|
|
||||||
*/
|
|
||||||
char *
|
|
||||||
virGetSCSIHostNameByParentaddr(unsigned int domain,
|
|
||||||
unsigned int bus,
|
|
||||||
unsigned int slot,
|
|
||||||
unsigned int function,
|
|
||||||
unsigned int unique_id)
|
|
||||||
{
|
|
||||||
char *name = NULL;
|
|
||||||
char *parentaddr = NULL;
|
|
||||||
|
|
||||||
if (virAsprintf(&parentaddr, "%04x:%02x:%02x.%01x",
|
|
||||||
domain, bus, slot, function) < 0)
|
|
||||||
goto cleanup;
|
|
||||||
if (!(name = virFindSCSIHostByPCI(NULL, parentaddr, unique_id))) {
|
|
||||||
virReportError(VIR_ERR_XML_ERROR,
|
|
||||||
_("Failed to find scsi_host using PCI '%s' "
|
|
||||||
"and unique_id='%u'"),
|
|
||||||
parentaddr, unique_id);
|
|
||||||
goto cleanup;
|
|
||||||
}
|
|
||||||
|
|
||||||
cleanup:
|
|
||||||
VIR_FREE(parentaddr);
|
|
||||||
return name;
|
|
||||||
}
|
|
||||||
|
|
||||||
#else
|
|
||||||
|
|
||||||
int
|
|
||||||
virReadSCSIUniqueId(const char *sysfs_prefix ATTRIBUTE_UNUSED,
|
|
||||||
int host ATTRIBUTE_UNUSED,
|
|
||||||
int *result ATTRIBUTE_UNUSED)
|
|
||||||
{
|
|
||||||
virReportSystemError(ENOSYS, "%s", _("Not supported on this platform"));
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
char *
|
|
||||||
virFindSCSIHostByPCI(const char *sysfs_prefix ATTRIBUTE_UNUSED,
|
|
||||||
const char *parentaddr ATTRIBUTE_UNUSED,
|
|
||||||
unsigned int unique_id ATTRIBUTE_UNUSED)
|
|
||||||
{
|
|
||||||
virReportSystemError(ENOSYS, "%s", _("Not supported on this platform"));
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
int
|
|
||||||
virGetSCSIHostNumber(const char *adapter_name ATTRIBUTE_UNUSED,
|
|
||||||
unsigned int *result ATTRIBUTE_UNUSED)
|
|
||||||
{
|
|
||||||
virReportSystemError(ENOSYS, "%s", _("Not supported on this platform"));
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
char *
|
|
||||||
virGetSCSIHostNameByParentaddr(unsigned int domain ATTRIBUTE_UNUSED,
|
|
||||||
unsigned int bus ATTRIBUTE_UNUSED,
|
|
||||||
unsigned int slot ATTRIBUTE_UNUSED,
|
|
||||||
unsigned int function ATTRIBUTE_UNUSED,
|
|
||||||
unsigned int unique_id ATTRIBUTE_UNUSED)
|
|
||||||
{
|
|
||||||
virReportSystemError(ENOSYS, "%s", _("Not supported on this platform"));
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif /* __linux__ */
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* virParseOwnershipIds:
|
* virParseOwnershipIds:
|
||||||
|
@ -164,26 +164,6 @@ 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 virReadSCSIUniqueId(const char *sysfs_prefix,
|
|
||||||
int host,
|
|
||||||
int *result)
|
|
||||||
ATTRIBUTE_NONNULL(3);
|
|
||||||
char *
|
|
||||||
virFindSCSIHostByPCI(const char *sysfs_prefix,
|
|
||||||
const char *parentaddr,
|
|
||||||
unsigned int unique_id);
|
|
||||||
int
|
|
||||||
virGetSCSIHostNumber(const char *adapter_name,
|
|
||||||
unsigned int *result)
|
|
||||||
ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2);
|
|
||||||
char *
|
|
||||||
virGetSCSIHostNameByParentaddr(unsigned int domain,
|
|
||||||
unsigned int bus,
|
|
||||||
unsigned int slot,
|
|
||||||
unsigned int function,
|
|
||||||
unsigned int unique_id);
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
int virParseOwnershipIds(const char *label, uid_t *uidPtr, gid_t *gidPtr);
|
int virParseOwnershipIds(const char *label, uid_t *uidPtr, gid_t *gidPtr);
|
||||||
|
|
||||||
|
@ -26,9 +26,9 @@
|
|||||||
# include <fcntl.h>
|
# include <fcntl.h>
|
||||||
# include <sys/stat.h>
|
# include <sys/stat.h>
|
||||||
# include "virstring.h"
|
# include "virstring.h"
|
||||||
# include "virutil.h"
|
|
||||||
# include "virerror.h"
|
# include "virerror.h"
|
||||||
# include "virlog.h"
|
# include "virlog.h"
|
||||||
|
# include "virscsihost.h"
|
||||||
|
|
||||||
# define VIR_FROM_THIS VIR_FROM_NONE
|
# define VIR_FROM_THIS VIR_FROM_NONE
|
||||||
|
|
||||||
@ -173,8 +173,8 @@ testVirReadSCSIUniqueId(const void *data ATTRIBUTE_UNUSED)
|
|||||||
int hostnum, unique_id;
|
int hostnum, unique_id;
|
||||||
|
|
||||||
for (hostnum = 0; hostnum < 4; hostnum++) {
|
for (hostnum = 0; hostnum < 4; hostnum++) {
|
||||||
if (virReadSCSIUniqueId(TEST_SCSIHOST_CLASS_PATH,
|
if ((unique_id = virSCSIHostGetUniqueId(TEST_SCSIHOST_CLASS_PATH,
|
||||||
hostnum, &unique_id) < 0) {
|
hostnum)) < 0) {
|
||||||
fprintf(stderr, "Failed to read hostnum=%d unique_id\n", hostnum);
|
fprintf(stderr, "Failed to read hostnum=%d unique_id\n", hostnum);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
@ -196,7 +196,7 @@ testVirReadSCSIUniqueId(const void *data ATTRIBUTE_UNUSED)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Test virFindSCSIHostByPCI */
|
/* Test virSCSIHostFindByPCI */
|
||||||
static int
|
static int
|
||||||
testVirFindSCSIHostByPCI(const void *data ATTRIBUTE_UNUSED)
|
testVirFindSCSIHostByPCI(const void *data ATTRIBUTE_UNUSED)
|
||||||
{
|
{
|
||||||
@ -212,25 +212,25 @@ testVirFindSCSIHostByPCI(const void *data ATTRIBUTE_UNUSED)
|
|||||||
"sysfs/class/scsi_host") < 0)
|
"sysfs/class/scsi_host") < 0)
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
|
|
||||||
if (!(ret_host = virFindSCSIHostByPCI(TEST_SCSIHOST_CLASS_PATH,
|
if (!(ret_host = virSCSIHostFindByPCI(TEST_SCSIHOST_CLASS_PATH,
|
||||||
pci_addr1, unique_id1)) ||
|
pci_addr1, unique_id1)) ||
|
||||||
STRNEQ(ret_host, "host0"))
|
STRNEQ(ret_host, "host0"))
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
VIR_FREE(ret_host);
|
VIR_FREE(ret_host);
|
||||||
|
|
||||||
if (!(ret_host = virFindSCSIHostByPCI(TEST_SCSIHOST_CLASS_PATH,
|
if (!(ret_host = virSCSIHostFindByPCI(TEST_SCSIHOST_CLASS_PATH,
|
||||||
pci_addr1, unique_id2)) ||
|
pci_addr1, unique_id2)) ||
|
||||||
STRNEQ(ret_host, "host1"))
|
STRNEQ(ret_host, "host1"))
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
VIR_FREE(ret_host);
|
VIR_FREE(ret_host);
|
||||||
|
|
||||||
if (!(ret_host = virFindSCSIHostByPCI(TEST_SCSIHOST_CLASS_PATH,
|
if (!(ret_host = virSCSIHostFindByPCI(TEST_SCSIHOST_CLASS_PATH,
|
||||||
pci_addr2, unique_id1)) ||
|
pci_addr2, unique_id1)) ||
|
||||||
STRNEQ(ret_host, "host2"))
|
STRNEQ(ret_host, "host2"))
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
VIR_FREE(ret_host);
|
VIR_FREE(ret_host);
|
||||||
|
|
||||||
if (!(ret_host = virFindSCSIHostByPCI(TEST_SCSIHOST_CLASS_PATH,
|
if (!(ret_host = virSCSIHostFindByPCI(TEST_SCSIHOST_CLASS_PATH,
|
||||||
pci_addr2, unique_id2)) ||
|
pci_addr2, unique_id2)) ||
|
||||||
STRNEQ(ret_host, "host3"))
|
STRNEQ(ret_host, "host3"))
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
|
Loading…
Reference in New Issue
Block a user