File 0003-fabrics-Introduce-connection-connect-error-mapping.patch of Package libnvme.27881

From: Daniel Wagner <dwagner@suse.de>
Date: Thu, 14 Apr 2022 13:38:25 +0200
Subject: fabrics: Introduce connection connect error mapping
Git-commit: 2242d0763e8fb0cc0e0e18191991e36148865d19
References: bsc#1199994

The kernel returns status information via error codes. Currently we
map all error codes to ENVME_CONNECT_WRITE if the operation
fails. Some of those error codes should be treated differently, such
as EALREADY which means the connection attempt failed because the
connection is already established.

Many of the error codes are overloaded so we have to guess if they are
actually from the nvme subsystem and not from the write
command. Though in practice it's almost certainly the nvme
subsystem. Still it's a guessing game due the very limited API
between userland and kernel.

Signed-off-by: Daniel Wagner <dwagner@suse.de>
---
 src/nvme/fabrics.c |   21 ++++++++++++++++++++-
 src/nvme/util.c    |    5 +++++
 src/nvme/util.h    |   10 ++++++++++
 3 files changed, 35 insertions(+), 1 deletion(-)

--- a/src/nvme/fabrics.c
+++ b/src/nvme/fabrics.c
@@ -523,7 +523,26 @@ static int __nvmf_add_ctrl(nvme_root_t r
 	if (ret != len) {
 		nvme_msg(r, LOG_NOTICE, "Failed to write to %s: %s\n",
 			 nvmf_dev, strerror(errno));
-		ret = -ENVME_CONNECT_WRITE;
+		switch (errno) {
+		case EALREADY:
+			ret = -ENVME_CONNECT_ALREADY;
+			break;
+		case EINVAL:
+			ret = -ENVME_CONNECT_INVAL;
+			break;
+		case EADDRINUSE:
+			ret = -ENVME_CONNECT_ADDRINUSE;
+			break;
+		case ENODEV:
+			ret = -ENVME_CONNECT_NODEV;
+			break;
+		case EOPNOTSUPP:
+			ret = -ENVME_CONNECT_OPNOTSUPP;
+			break;
+		default:
+			ret = -ENVME_CONNECT_WRITE;
+			break;
+		}
 		goto out_close;
 	}
 
--- a/src/nvme/util.c
+++ b/src/nvme/util.c
@@ -516,6 +516,11 @@ static const char * const libnvme_status
 	[ENVME_CONNECT_INVAL_TR] = "invalid transport type",
 	[ENVME_CONNECT_LOOKUP_SUBSYS_NAME] = "failed to lookup subsystem name",
 	[ENVME_CONNECT_LOOKUP_SUBSYS] = "failed to lookup subsystem",
+	[ENVME_CONNECT_ALREADY] = "already connnected",
+	[ENVME_CONNECT_INVAL] = "invalid arguments/configuration",
+	[ENVME_CONNECT_ADDRINUSE] = "hostnqn already in use",
+	[ENVME_CONNECT_NODEV] = "invalid interface",
+	[ENVME_CONNECT_OPNOTSUPP] ="not supported",
 };
 
 const char *nvme_errno_to_string(int status)
--- a/src/nvme/util.h
+++ b/src/nvme/util.h
@@ -31,6 +31,11 @@
  * @ENVME_CONNECT_INVAL_TR:	invalid transport type
  * @ENVME_CONNECT_LOOKUP_SUBSYS_NAME:	failed to lookup subsystem name
  * @ENVME_CONNECT_LOOKUP_SUBSYS: failed to lookup subsystem
+ * @ENVME_CONNECT_ALREADY:	the connect attempt failed, already connected
+ * @ENVME_CONNECT_INVAL:	invalid arguments/configuration
+ * @ENVME_CONNECT_ADDRINUSE:	hostnqn already in use
+ * @ENVME_CONNECT_NODEV:	invalid interface
+ * @ENVME_CONNECT_OPNOTSUPP:	not supported
  */
 enum nvme_connect_err {
 	ENVME_CONNECT_RESOLVE	= 1000,
@@ -45,6 +50,11 @@ enum nvme_connect_err {
 	ENVME_CONNECT_INVAL_TR,
 	ENVME_CONNECT_LOOKUP_SUBSYS_NAME,
 	ENVME_CONNECT_LOOKUP_SUBSYS,
+	ENVME_CONNECT_ALREADY,
+	ENVME_CONNECT_INVAL,
+	ENVME_CONNECT_ADDRINUSE,
+	ENVME_CONNECT_NODEV,
+	ENVME_CONNECT_OPNOTSUPP,
 };
 
 /**
openSUSE Build Service is sponsored by