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
Signed-off-by: John Ferlan <jferlan(a)redhat.com>
---
po/POTFILES.in | 1 +
src/Makefile.am | 1 +
src/conf/storage_conf.c | 34 ++--
src/libvirt_private.syms | 10 +-
src/node_device/node_device_linux_sysfs.c | 5 +-
src/storage/storage_backend_scsi.c | 15 +-
src/util/virscsihost.c | 297 ++++++++++++++++++++++++++++++
src/util/virscsihost.h | 40 ++++
src/util/virutil.c | 269 ---------------------------
src/util/virutil.h | 20 --
tests/scsihosttest.c | 16 +-
11 files changed, 386 insertions(+), 322 deletions(-)
create mode 100644 src/util/virscsihost.c
create mode 100644 src/util/virscsihost.h
diff --git a/po/POTFILES.in b/po/POTFILES.in
index 1331093..e9a3569 100644
--- a/po/POTFILES.in
+++ b/po/POTFILES.in
@@ -240,6 +240,7 @@ src/util/virqemu.c
src/util/virrandom.c
src/util/virrotatingfile.c
src/util/virscsi.c
+src/util/virscsihost.c
src/util/virscsivhost.c
src/util/virsecret.c
src/util/virsexpr.c
diff --git a/src/Makefile.am b/src/Makefile.am
index 0fec45b..5db0ea9 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -164,6 +164,7 @@ UTIL_SOURCES = \
util/virrandom.h util/virrandom.c \
util/virrotatingfile.h util/virrotatingfile.c \
util/virscsi.c util/virscsi.h \
+ util/virscsihost.c util/virscsihost.h \
util/virscsivhost.c util/virscsivhost.h \
util/virseclabel.c util/virseclabel.h \
util/virsecret.c util/virsecret.h \
diff --git a/src/conf/storage_conf.c b/src/conf/storage_conf.c
index 5e13bbf..8289ccc 100644
--- a/src/conf/storage_conf.c
+++ b/src/conf/storage_conf.c
@@ -43,6 +43,7 @@
#include "virbuffer.h"
#include "viralloc.h"
#include "virfile.h"
+#include "virscsihost.h"
#include "virstring.h"
#include "virlog.h"
#include "virvhba.h"
@@ -2277,16 +2278,16 @@ getSCSIHostNumber(virStoragePoolSourceAdapter adapter,
virPCIDeviceAddress addr = adapter.data.scsi_host.parentaddr;
unsigned int unique_id = adapter.data.scsi_host.unique_id;
- if (!(name = virGetSCSIHostNameByParentaddr(addr.domain,
+ if (!(name = virSCSIHostGetNameByParentaddr(addr.domain,
addr.bus,
addr.slot,
addr.function,
unique_id)))
goto cleanup;
- if (virGetSCSIHostNumber(name, &num) < 0)
+ if (virSCSIHostGetNumber(name, &num) < 0)
goto cleanup;
} else {
- if (virGetSCSIHostNumber(adapter.data.scsi_host.name, &num) < 0)
+ if (virSCSIHostGetNumber(adapter.data.scsi_host.name, &num) < 0)
goto cleanup;
}
@@ -2298,6 +2299,20 @@ getSCSIHostNumber(virStoragePoolSourceAdapter adapter,
return ret;
}
+
+static bool
+isSameHostnum(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:
*
@@ -2315,14 +2330,12 @@ matchFCHostToSCSIHost(virConnectPtr conn,
{
char *name = NULL;
char *parent_name = NULL;
- unsigned int fc_hostnum;
/* 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
*/
if (fc_adapter.data.fchost.parent &&
- virGetSCSIHostNumber(fc_adapter.data.fchost.parent, &fc_hostnum) == 0
&&
- scsi_hostnum == fc_hostnum)
+ isSameHostnum(fc_adapter.data.fchost.parent, scsi_hostnum))
return true;
/* If we find an fc_adapter name, then either libvirt created a vHBA
@@ -2334,11 +2347,11 @@ matchFCHostToSCSIHost(virConnectPtr conn,
/* Get the scsi_hostN for the vHBA in order to see if it
* matches our scsi_hostnum
*/
- if (virGetSCSIHostNumber(name, &fc_hostnum) == 0 &&
- scsi_hostnum == fc_hostnum) {
+ if (isSameHostnum(name, scsi_hostnum)) {
VIR_FREE(name);
return true;
}
+ VIR_FREE(name);
/* We weren't provided a parent, so we have to query the node
* device driver in order to ascertain the parent of the vHBA.
@@ -2347,10 +2360,8 @@ matchFCHostToSCSIHost(virConnectPtr conn,
*/
if (conn && !fc_adapter.data.fchost.parent) {
if ((parent_name = virVHBAGetParent(conn, name))) {
- if (virGetSCSIHostNumber(parent_name, &fc_hostnum) == 0 &&
- scsi_hostnum == fc_hostnum) {
+ if (isSameHostnum(parent_name, scsi_hostnum)) {
VIR_FREE(parent_name);
- VIR_FREE(name);
return true;
}
VIR_FREE(parent_name);
@@ -2360,7 +2371,6 @@ matchFCHostToSCSIHost(virConnectPtr conn,
VIR_DEBUG("Could not determine parent vHBA");
}
}
- VIR_FREE(name);
}
/* NB: Lack of a name means that this vHBA hasn't yet been created,
diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
index b58742d..ec3cab7 100644
--- a/src/libvirt_private.syms
+++ b/src/libvirt_private.syms
@@ -2349,6 +2349,12 @@ virSCSIDeviceNew;
virSCSIDeviceSetUsedBy;
+# util/virscsihost.h
+virSCSIHostFindByPCI;
+virSCSIHostGetNameByParentaddr;
+virSCSIHostGetNumber;
+virSCSIHostGetUniqueId;
+
# util/virscsivhost.h
virSCSIVHostDeviceFileIterate;
virSCSIVHostDeviceFree;
@@ -2674,7 +2680,6 @@ virUSBDeviceSetUsedBy;
virDoubleToStr;
virEnumFromString;
virEnumToString;
-virFindSCSIHostByPCI;
virFormatIntDecimal;
virGetDeviceID;
virGetDeviceUnprivSGIO;
@@ -2686,8 +2691,6 @@ virGetGroupName;
virGetHostname;
virGetHostnameQuiet;
virGetListenFDs;
-virGetSCSIHostNameByParentaddr;
-virGetSCSIHostNumber;
virGetSelfLastChanged;
virGetSystemPageSize;
virGetSystemPageSizeKB;
@@ -2711,7 +2714,6 @@ virParseNumber;
virParseOwnershipIds;
virParseVersionString;
virPipeReadUntilEOF;
-virReadSCSIUniqueId;
virScaleInteger;
virSetBlocking;
virSetCloseExec;
diff --git a/src/node_device/node_device_linux_sysfs.c
b/src/node_device/node_device_linux_sysfs.c
index 1c72b07..8ac8bf6 100644
--- a/src/node_device/node_device_linux_sysfs.c
+++ b/src/node_device/node_device_linux_sysfs.c
@@ -33,6 +33,7 @@
#include "viralloc.h"
#include "virlog.h"
#include "virfile.h"
+#include "virscsihost.h"
#include "virstring.h"
#include "virvhba.h"
@@ -48,8 +49,8 @@ nodeDeviceSysfsGetSCSIHostCaps(virNodeDevCapDataPtr d)
char *tmp = NULL;
int ret = -1;
- if (virReadSCSIUniqueId(NULL, d->scsi_host.host,
- &d->scsi_host.unique_id) < 0) {
+ if ((d->scsi_host.unique_id =
+ virSCSIHostGetUniqueId(NULL, d->scsi_host.host)) < 0) {
VIR_DEBUG("Failed to read unique_id for host%d",
d->scsi_host.host);
d->scsi_host.unique_id = -1;
}
diff --git a/src/storage/storage_backend_scsi.c b/src/storage/storage_backend_scsi.c
index 2da15dd..da3b847 100644
--- a/src/storage/storage_backend_scsi.c
+++ b/src/storage/storage_backend_scsi.c
@@ -33,6 +33,7 @@
#include "virlog.h"
#include "virfile.h"
#include "vircommand.h"
+#include "virscsihost.h"
#include "virstring.h"
#include "virvhba.h"
#include "storage_util.h"
@@ -159,7 +160,7 @@ virStoragePoolFCRefreshThread(void *opaque)
pool->def->allocation = pool->def->capacity =
pool->def->available = 0;
if (virStoragePoolObjIsActive(pool) &&
- virGetSCSIHostNumber(fchost_name, &host) == 0 &&
+ virSCSIHostGetNumber(fchost_name, &host) == 0 &&
virStorageBackendSCSITriggerRescan(host) == 0) {
virStoragePoolObjClearVols(pool);
found = virStorageBackendSCSIFindLUs(pool, host);
@@ -184,7 +185,7 @@ getAdapterName(virStoragePoolSourceAdapter adapter)
virPCIDeviceAddress addr = adapter.data.scsi_host.parentaddr;
unsigned int unique_id = adapter.data.scsi_host.unique_id;
- if (!(name = virGetSCSIHostNameByParentaddr(addr.domain,
+ if (!(name = virSCSIHostGetNameByParentaddr(addr.domain,
addr.bus,
addr.slot,
addr.function,
@@ -312,7 +313,7 @@ createVport(virConnectPtr conn,
skip_capable_check = true;
}
- if (virGetSCSIHostNumber(parent_hoststr, &parent_host) < 0)
+ if (virSCSIHostGetNumber(parent_hoststr, &parent_host) < 0)
goto cleanup;
/* NOTE:
@@ -413,13 +414,13 @@ deleteVport(virConnectPtr conn,
* the parent scsi_host which we did not save at startup time
*/
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;
} else {
if (!(vhba_parent = virVHBAGetParent(conn, name)))
goto cleanup;
- if (virGetSCSIHostNumber(vhba_parent, &parent_host) < 0)
+ if (virSCSIHostGetNumber(vhba_parent, &parent_host) < 0)
goto cleanup;
}
@@ -460,7 +461,7 @@ virStorageBackendSCSICheckPool(virStoragePoolObjPtr pool,
}
}
- if (virGetSCSIHostNumber(name, &host) < 0)
+ if (virSCSIHostGetNumber(name, &host) < 0)
goto cleanup;
if (virAsprintf(&path, "%s/host%d",
@@ -489,7 +490,7 @@ virStorageBackendSCSIRefreshPool(virConnectPtr conn ATTRIBUTE_UNUSED,
if (!(name = getAdapterName(pool->def->source.adapter)))
return -1;
- if (virGetSCSIHostNumber(name, &host) < 0)
+ if (virSCSIHostGetNumber(name, &host) < 0)
goto out;
VIR_DEBUG("Scanning host%u", host);
diff --git a/src/util/virscsihost.c b/src/util/virscsihost.c
new file mode 100644
index 0000000..eea0474
--- /dev/null
+++ b/src/util/virscsihost.c
@@ -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__ */
diff --git a/src/util/virscsihost.h b/src/util/virscsihost.h
new file mode 100644
index 0000000..c35ccb9
--- /dev/null
+++ b/src/util/virscsihost.h
@@ -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__ */
diff --git a/src/util/virutil.c b/src/util/virutil.c
index 51a1394..6fb70db 100644
--- a/src/util/virutil.c
+++ b/src/util/virutil.c
@@ -27,7 +27,6 @@
#include <config.h>
#include <stdlib.h>
-#include <dirent.h>
#include <stdio.h>
#include <stdarg.h>
#include <unistd.h>
@@ -1776,274 +1775,6 @@ virGetDeviceUnprivSGIO(const char *path,
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:
diff --git a/src/util/virutil.h b/src/util/virutil.h
index b320c06..877207c 100644
--- a/src/util/virutil.h
+++ b/src/util/virutil.h
@@ -164,26 +164,6 @@ int virGetDeviceUnprivSGIO(const char *path,
int *unpriv_sgio);
char *virGetUnprivSGIOSysfsPath(const char *path,
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);
diff --git a/tests/scsihosttest.c b/tests/scsihosttest.c
index 7f16e04..9efc2d2 100644
--- a/tests/scsihosttest.c
+++ b/tests/scsihosttest.c
@@ -26,9 +26,9 @@
# include <fcntl.h>
# include <sys/stat.h>
# include "virstring.h"
-# include "virutil.h"
# include "virerror.h"
# include "virlog.h"
+# include "virscsihost.h"
# define VIR_FROM_THIS VIR_FROM_NONE
@@ -173,8 +173,8 @@ testVirReadSCSIUniqueId(const void *data ATTRIBUTE_UNUSED)
int hostnum, unique_id;
for (hostnum = 0; hostnum < 4; hostnum++) {
- if (virReadSCSIUniqueId(TEST_SCSIHOST_CLASS_PATH,
- hostnum, &unique_id) < 0) {
+ if ((unique_id = virSCSIHostGetUniqueId(TEST_SCSIHOST_CLASS_PATH,
+ hostnum)) < 0) {
fprintf(stderr, "Failed to read hostnum=%d unique_id\n", hostnum);
return -1;
}
@@ -196,7 +196,7 @@ testVirReadSCSIUniqueId(const void *data ATTRIBUTE_UNUSED)
return 0;
}
-/* Test virFindSCSIHostByPCI */
+/* Test virSCSIHostFindByPCI */
static int
testVirFindSCSIHostByPCI(const void *data ATTRIBUTE_UNUSED)
{
@@ -212,25 +212,25 @@ testVirFindSCSIHostByPCI(const void *data ATTRIBUTE_UNUSED)
"sysfs/class/scsi_host") < 0)
goto cleanup;
- if (!(ret_host = virFindSCSIHostByPCI(TEST_SCSIHOST_CLASS_PATH,
+ if (!(ret_host = virSCSIHostFindByPCI(TEST_SCSIHOST_CLASS_PATH,
pci_addr1, unique_id1)) ||
STRNEQ(ret_host, "host0"))
goto cleanup;
VIR_FREE(ret_host);
- if (!(ret_host = virFindSCSIHostByPCI(TEST_SCSIHOST_CLASS_PATH,
+ if (!(ret_host = virSCSIHostFindByPCI(TEST_SCSIHOST_CLASS_PATH,
pci_addr1, unique_id2)) ||
STRNEQ(ret_host, "host1"))
goto cleanup;
VIR_FREE(ret_host);
- if (!(ret_host = virFindSCSIHostByPCI(TEST_SCSIHOST_CLASS_PATH,
+ if (!(ret_host = virSCSIHostFindByPCI(TEST_SCSIHOST_CLASS_PATH,
pci_addr2, unique_id1)) ||
STRNEQ(ret_host, "host2"))
goto cleanup;
VIR_FREE(ret_host);
- if (!(ret_host = virFindSCSIHostByPCI(TEST_SCSIHOST_CLASS_PATH,
+ if (!(ret_host = virSCSIHostFindByPCI(TEST_SCSIHOST_CLASS_PATH,
pci_addr2, unique_id2)) ||
STRNEQ(ret_host, "host3"))
goto cleanup;
--
2.7.4