6ae9ed
From 8a7b904aff7216941b5f804d4d84d7163b3b6908 Mon Sep 17 00:00:00 2001
6ae9ed
Message-Id: <8a7b904aff7216941b5f804d4d84d7163b3b6908@dist-git>
6ae9ed
From: John Ferlan <jferlan@redhat.com>
6ae9ed
Date: Mon, 1 Aug 2016 13:31:52 -0400
6ae9ed
Subject: [PATCH] util: Introduce virISCSINodeNew
6ae9ed
6ae9ed
https://bugzilla.redhat.com/show_bug.cgi?id=1356436
6ae9ed
6ae9ed
According to RFC 3721 (https://www.ietf.org/rfc/rfc3721.txt), there are
6ae9ed
two ways to "discover" targets in/for the iSCSI environment. Discovery
6ae9ed
is the process which allows the initiator to find the targets to which
6ae9ed
it has access and at least one address at which each target may be
6ae9ed
accessed.
6ae9ed
6ae9ed
The method currently implemented in libvirt using the virISCSIScanTargets
6ae9ed
API is known as "SendTargets" discovery. This method is more useful when
6ae9ed
the target IP Address and TCP port information are available, e.g. in
6ae9ed
libvirt terms the "portal". It returns a list of targets for the portal.
6ae9ed
>From that list, the target can be found. This operation can also fill an
6ae9ed
iSCSI node table into which iSCSI logins may occur. Commit id '56057900'
6ae9ed
altered that filling by adding the "--op nonpersistent" since it was
6ae9ed
not necessarily desired to perform that for non libvirt related targets.
6ae9ed
6ae9ed
The second method is "Static Configuration". This method not only needs
6ae9ed
the IP Address and TCP port (e.g. portal), but also the iSCSI target name.
6ae9ed
In libvirt terms this would be the device path field from the iSCSI pool
6ae9ed
<source> XML. This patch implements the second methodology using that
6ae9ed
required device path as the targetname.
6ae9ed
6ae9ed
(cherry picked from commit ae65c908b7a8a951e0049ff7cd57f03644e1d5b8)
6ae9ed
Signed-off-by: John Ferlan <jferlan@redhat.com>
6ae9ed
---
6ae9ed
 src/libvirt_private.syms |  1 +
6ae9ed
 src/util/viriscsi.c      | 51 ++++++++++++++++++++++++++++++++++++++++++++++++
6ae9ed
 src/util/viriscsi.h      |  6 ++++++
6ae9ed
 3 files changed, 58 insertions(+)
6ae9ed
6ae9ed
diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
6ae9ed
index 4dd93d7..62c9dc5 100644
6ae9ed
--- a/src/libvirt_private.syms
6ae9ed
+++ b/src/libvirt_private.syms
6ae9ed
@@ -1714,6 +1714,7 @@ iptablesRemoveUdpOutput;
6ae9ed
 virISCSIConnectionLogin;
6ae9ed
 virISCSIConnectionLogout;
6ae9ed
 virISCSIGetSession;
6ae9ed
+virISCSINodeNew;
6ae9ed
 virISCSINodeUpdate;
6ae9ed
 virISCSIRescanLUNs;
6ae9ed
 virISCSIScanTargets;
6ae9ed
diff --git a/src/util/viriscsi.c b/src/util/viriscsi.c
6ae9ed
index e705517..504ffbd 100644
6ae9ed
--- a/src/util/viriscsi.c
6ae9ed
+++ b/src/util/viriscsi.c
6ae9ed
@@ -444,6 +444,57 @@ virISCSIScanTargets(const char *portal,
6ae9ed
     return ret;
6ae9ed
 }
6ae9ed
 
6ae9ed
+/*
6ae9ed
+ * virISCSINodeNew:
6ae9ed
+ * @portal: address for iSCSI target
6ae9ed
+ * @target: IQN and specific LUN target
6ae9ed
+ *
6ae9ed
+ * Usage of nonpersistent discovery in virISCSIScanTargets is useful primarily
6ae9ed
+ * only when the target IQN is not known; however, since we have the target IQN
6ae9ed
+ * usage of the "--op new" can be done. This avoids problems if "--op delete"
6ae9ed
+ * had been used wiping out the static nodes determined by the scanning of
6ae9ed
+ * all targets.
6ae9ed
+ *
6ae9ed
+ * NB: If an iSCSI node record is already created for this portal and
6ae9ed
+ * target, subsequent "--op new" commands do not return an error.
6ae9ed
+ *
6ae9ed
+ * Returns 0 on success, -1 w/ error message on error
6ae9ed
+ */
6ae9ed
+int
6ae9ed
+virISCSINodeNew(const char *portal,
6ae9ed
+                const char *target)
6ae9ed
+{
6ae9ed
+    virCommandPtr cmd = NULL;
6ae9ed
+    int status;
6ae9ed
+    int ret = -1;
6ae9ed
+
6ae9ed
+    cmd = virCommandNewArgList(ISCSIADM,
6ae9ed
+                               "--mode", "node",
6ae9ed
+                               "--portal", portal,
6ae9ed
+                               "--targetname", target,
6ae9ed
+                               "--op", "new",
6ae9ed
+                               NULL);
6ae9ed
+
6ae9ed
+    if (virCommandRun(cmd, &status) < 0) {
6ae9ed
+        virReportError(VIR_ERR_INTERNAL_ERROR,
6ae9ed
+                       _("Failed new node mode for target '%s'"),
6ae9ed
+                       target);
6ae9ed
+        goto cleanup;
6ae9ed
+    }
6ae9ed
+
6ae9ed
+    if (status != 0) {
6ae9ed
+        virReportError(VIR_ERR_INTERNAL_ERROR,
6ae9ed
+                       _("%s failed new mode for target '%s' with status '%d'"),
6ae9ed
+                       ISCSIADM, target, status);
6ae9ed
+        goto cleanup;
6ae9ed
+    }
6ae9ed
+
6ae9ed
+    ret = 0;
6ae9ed
+ cleanup:
6ae9ed
+    virCommandFree(cmd);
6ae9ed
+    return ret;
6ae9ed
+}
6ae9ed
+
6ae9ed
 
6ae9ed
 int
6ae9ed
 virISCSINodeUpdate(const char *portal,
6ae9ed
diff --git a/src/util/viriscsi.h b/src/util/viriscsi.h
6ae9ed
index 459249e..a44beea 100644
6ae9ed
--- a/src/util/viriscsi.h
6ae9ed
+++ b/src/util/viriscsi.h
6ae9ed
@@ -54,6 +54,12 @@ virISCSIScanTargets(const char *portal,
6ae9ed
     ATTRIBUTE_NONNULL(1) ATTRIBUTE_RETURN_CHECK;
6ae9ed
 
6ae9ed
 int
6ae9ed
+virISCSINodeNew(const char *portal,
6ae9ed
+                const char *target)
6ae9ed
+    ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2)
6ae9ed
+    ATTRIBUTE_RETURN_CHECK;
6ae9ed
+
6ae9ed
+int
6ae9ed
 virISCSINodeUpdate(const char *portal,
6ae9ed
                    const char *target,
6ae9ed
                    const char *name,
6ae9ed
-- 
6ae9ed
2.9.2
6ae9ed