When scanning for targets, iSCSI might give different results
depending on the interface used. This is basically just name of
config file under /etc/iscsi/ifaces to use. The file contains
initiator IQN thus different results claim.
Signed-off-by: Michal Privoznik <mprivozn(a)redhat.com>
Reviewed-by: John Ferlan <jferlan(a)redhat.com>
---
src/storage/storage_backend_iscsi.c | 4 +-
src/util/viriscsi.c | 79 ++++++++++++++++++++++++++++++++++---
src/util/viriscsi.h | 1 +
tests/viriscsitest.c | 2 +-
4 files changed, 78 insertions(+), 8 deletions(-)
diff --git a/src/storage/storage_backend_iscsi.c b/src/storage/storage_backend_iscsi.c
index 7871d1915b..3b9dddb4fd 100644
--- a/src/storage/storage_backend_iscsi.c
+++ b/src/storage/storage_backend_iscsi.c
@@ -194,7 +194,9 @@ virStorageBackendISCSIFindPoolSources(const char *srcSpec,
if (!(portal = virStorageBackendISCSIPortal(source)))
goto cleanup;
- if (virISCSIScanTargets(portal, &ntargets, &targets) < 0)
+ if (virISCSIScanTargets(portal,
+ source->initiator.iqn,
+ &ntargets, &targets) < 0)
goto cleanup;
if (VIR_ALLOC_N(list.sources, ntargets) < 0)
diff --git a/src/util/viriscsi.c b/src/util/viriscsi.c
index 1ddf00aa4c..549f75b434 100644
--- a/src/util/viriscsi.c
+++ b/src/util/viriscsi.c
@@ -40,6 +40,13 @@
VIR_LOG_INIT("util.iscsi");
+static int
+virISCSIScanTargetsInternal(const char *portal,
+ const char *ifacename,
+ size_t *ntargetsret,
+ char ***targetsret);
+
+
struct virISCSISessionData {
char *session;
const char *devpath;
@@ -286,9 +293,10 @@ virISCSIConnection(const char *portal,
* iscsiadm doesn't let you send commands to the Interface IQN,
* unless you've first issued a 'sendtargets' command to the
* portal. Without the sendtargets all that is received is a
- * "iscsiadm: No records found"
+ * "iscsiadm: No records found". However, we must ensure that
+ * the command is issued over interface name we invented above.
*/
- if (virISCSIScanTargets(portal, NULL, NULL) < 0)
+ if (virISCSIScanTargetsInternal(portal, ifacename, NULL, NULL) < 0)
goto cleanup;
break;
@@ -371,10 +379,11 @@ virISCSIGetTargets(char **const groups,
}
-int
-virISCSIScanTargets(const char *portal,
- size_t *ntargetsret,
- char ***targetsret)
+static int
+virISCSIScanTargetsInternal(const char *portal,
+ const char *ifacename,
+ size_t *ntargetsret,
+ char ***targetsret)
{
/**
*
@@ -400,6 +409,12 @@ virISCSIScanTargets(const char *portal,
"--op",
"nonpersistent",
NULL);
+ if (ifacename) {
+ virCommandAddArgList(cmd,
+ "--interface", ifacename,
+ NULL);
+ }
+
memset(&list, 0, sizeof(list));
if (virCommandRunRegex(cmd,
@@ -425,6 +440,58 @@ virISCSIScanTargets(const char *portal,
return ret;
}
+
+/**
+ * virISCSIScanTargets:
+ * @portal: iSCSI portal
+ * @initiatoriqn: Initiator IQN
+ * @ntargets: number of items in @targetsret array
+ * @targets: array of targets
+ *
+ * For given @portal issue sendtargets command. Optionally,
+ * @initiatoriqn can be set to override default configuration.
+ * The targets are stored into @targets array and the size of
+ * the array is stored into @ntargets.
+ *
+ * Returns: 0 on success,
+ * -1 otherwise (with error reported)
+ */
+int
+virISCSIScanTargets(const char *portal,
+ const char *initiatoriqn,
+ size_t *ntargets,
+ char ***targets)
+{
+ char *ifacename = NULL;
+ int ret = -1;
+
+ if (ntargets)
+ *ntargets = 0;
+ if (targets)
+ *targets = NULL;
+
+ if (initiatoriqn) {
+ switch ((virStorageBackendIQNFound(initiatoriqn, &ifacename))) {
+ case IQN_FOUND:
+ break;
+
+ case IQN_MISSING:
+ virReportError(VIR_ERR_OPERATION_FAILED,
+ _("no iSCSI interface defined for IQN %s"),
+ initiatoriqn);
+ ATTRIBUTE_FALLTHROUGH;
+ case IQN_ERROR:
+ default:
+ return -1;
+ }
+ }
+
+ ret = virISCSIScanTargetsInternal(portal, ifacename, ntargets, targets);
+ VIR_FREE(ifacename);
+ return ret;
+}
+
+
/*
* virISCSINodeNew:
* @portal: address for iSCSI target
diff --git a/src/util/viriscsi.h b/src/util/viriscsi.h
index a44beeaf67..31b589dbf9 100644
--- a/src/util/viriscsi.h
+++ b/src/util/viriscsi.h
@@ -49,6 +49,7 @@ virISCSIRescanLUNs(const char *session)
int
virISCSIScanTargets(const char *portal,
+ const char *initiatoriqn,
size_t *ntargetsret,
char ***targetsret)
ATTRIBUTE_NONNULL(1) ATTRIBUTE_RETURN_CHECK;
diff --git a/tests/viriscsitest.c b/tests/viriscsitest.c
index aa4ba57707..4bdb782e36 100644
--- a/tests/viriscsitest.c
+++ b/tests/viriscsitest.c
@@ -145,7 +145,7 @@ testISCSIScanTargets(const void *data)
virCommandSetDryRun(NULL, testIscsiadmCb, NULL);
- if (virISCSIScanTargets(info->portal, &ntargets, &targets) < 0)
+ if (virISCSIScanTargets(info->portal, NULL, &ntargets, &targets) < 0)
goto cleanup;
if (info->nexpected != ntargets) {
--
2.16.4