Blob Blame History Raw
From 203290639399b4cc3c5039b2f3e653002eb2a9cb Mon Sep 17 00:00:00 2001
From: Ales Kozumplik <akozumpl@redhat.com>
Date: Tue, 14 Dec 2010 10:57:59 +0100
Subject: [PATCH 2/2] Make libiscsi nodes remember the interface they connect through.

Also, make sure we log through that particular interface when more nodes
with the same target exist.

Related: rhbz#529443
---
 libiscsi/libiscsi.c   |   14 +++++++++++---
 libiscsi/libiscsi.h   |    1 +
 libiscsi/pylibiscsi.c |   26 ++++++++++++++++++++------
 3 files changed, 32 insertions(+), 9 deletions(-)

diff --git a/libiscsi/libiscsi.c b/libiscsi/libiscsi.c
index 2ee2017..d4afcf0 100644
--- a/libiscsi/libiscsi.c
+++ b/libiscsi/libiscsi.c
@@ -188,6 +188,8 @@ int libiscsi_discover_sendtargets(struct libiscsi_context *context,
 			strlcpy((*found_nodes)[found].address,
 				 rec->conn[0].address, NI_MAXHOST);
 			(*found_nodes)[found].port = rec->conn[0].port;
+			strlcpy((*found_nodes)[found].iface,
+				 rec->iface.name, LIBISCSI_VALUE_MAXLEN);
 			found++;
 		}
 	}
@@ -207,7 +209,7 @@ int libiscsi_discover_firmware(struct libiscsi_context *context,
 	INIT_LIST_HEAD(&targets);
 	INIT_LIST_HEAD(&ifaces);
 	INIT_LIST_HEAD(&rec_list);
-	
+
 	if (nr_found) {
 		*nr_found = 0;
 	}
@@ -224,7 +226,7 @@ int libiscsi_discover_firmware(struct libiscsi_context *context,
 	}
 
 	CHECK(iface_create_ifaces_from_boot_contexts(&ifaces, &targets));
-	
+
 	memset(&drec, 0, sizeof(drec));
 	drec.type = DISCOVERY_TYPE_FW;
 	rc = idbm_bind_ifaces_to_nodes(discovery_fw, &drec, &ifaces, &rec_list);
@@ -259,6 +261,7 @@ int libiscsi_discover_firmware(struct libiscsi_context *context,
 		new_node->tpgt = rec->tpgt;
 		strlcpy(new_node->address, rec->conn[0].address, NI_MAXHOST);
 		new_node->port = rec->conn[0].port;
+		strlcpy(new_node->iface, rec->iface.name, LIBISCSI_VALUE_MAXLEN);
 
 		++new_node;
 	}
@@ -403,6 +406,11 @@ static void node_to_rec(const struct libiscsi_node *node,
 
 int login_helper(void *data, node_rec_t *rec)
 {
+	char *iface = (char*)data;
+	if (strcmp(iface, rec->iface.name))
+		/* different iface, skip it */
+		return -1;
+
 	int rc = iscsid_req_by_rec(MGMT_IPC_SESSION_LOGIN, rec);
 	if (rc) {
 		iscsi_err_print_msg(rc);
@@ -416,7 +424,7 @@ int libiscsi_node_login(struct libiscsi_context *context,
 {
 	int nr_found = 0, rc;
 
-	CHECK(idbm_for_each_iface(&nr_found, NULL, login_helper,
+	CHECK(idbm_for_each_iface(&nr_found, (void*)node->iface, login_helper,
 		(char *)node->name, node->tpgt,
 		(char *)node->address, node->port))
 	if (nr_found == 0) {
diff --git a/libiscsi/libiscsi.h b/libiscsi/libiscsi.h
index a7d05a5..756590e 100644
--- a/libiscsi/libiscsi.h
+++ b/libiscsi/libiscsi.h
@@ -68,6 +68,7 @@ struct libiscsi_node {
        get used anywhere, so we keep things simple and assume one connection */
     char address[NI_MAXHOST]             /** Portal hostname or IP-address. */;
     int port                             /** Portal port number. */;
+    char iface[LIBISCSI_VALUE_MAXLEN]    /** Interface to connect through. */;
 };
 
 /** \brief libiscsi CHAP authentication information struct
diff --git a/libiscsi/pylibiscsi.c b/libiscsi/pylibiscsi.c
index 69bfaa0..2c1889a 100644
--- a/libiscsi/pylibiscsi.c
+++ b/libiscsi/pylibiscsi.c
@@ -199,25 +199,27 @@ typedef struct {
 static int PyIscsiNode_init(PyObject *self, PyObject *args, PyObject *kwds)
 {
 	PyIscsiNode *node = (PyIscsiNode *)self;
-	char *kwlist[] = {"name", "tpgt", "address", "port", NULL};
-	const char *name = NULL, *address = NULL;
+	char *kwlist[] = {"name", "tpgt", "address", "port", "iface", NULL};
+	const char *name = NULL, *address = NULL, *iface = NULL;
 	int tpgt = -1, port = 3260;
 
-	if (!PyArg_ParseTupleAndKeywords(args, kwds, "s|isi:node.__init__",
-					kwlist, &name, &tpgt, &address, &port))
+	if (!PyArg_ParseTupleAndKeywords(args, kwds, "s|isis:node.__init__",
+					 kwlist, &name, &tpgt, &address,
+					 &port, &iface))
 		return -1;
 	if (address == NULL) {
 		PyErr_SetString(PyExc_ValueError, "address not set");
 		return -1;
 	}
-	if (check_string(name) || check_string(address))
+	if (check_string(name) || check_string(address) || check_string(iface))
 		return -1;
 
 	strcpy(node->node.name, name);
 	node->node.tpgt = tpgt;
 	strcpy(node->node.address, address);
 	node->node.port = port;
-	
+	strcpy(node->node.iface, iface);
+
 	return 0;
 }
 
@@ -234,6 +236,8 @@ static PyObject *PyIscsiNode_get(PyObject *self, void *data)
 		return PyString_FromString(node->node.address);
 	} else if (!strcmp(attr, "port")) {
 		return PyInt_FromLong(node->node.port);
+	} else if (!strcmp(attr, "iface")) {
+		return PyString_FromString(node->node.iface);
 	}
 	return NULL;
 }
@@ -261,6 +265,10 @@ static int PyIscsiNode_set(PyObject *self, PyObject *value, void *data)
 		if (!PyArg_Parse(value, "i", &i))
 			return -1;
 		node->node.port = i;
+	} else if (!strcmp(attr, "iface")) {
+		if (!PyArg_Parse(value, "s", &str) || check_string(str))
+			return -1;
+		strcpy(node->node.iface, str);
 	}
 
 	return 0;
@@ -288,6 +296,10 @@ static int PyIscsiNode_compare(PyIscsiNode *self, PyIscsiNode *other)
 	if (self->node.port > other->node.port)
 		return -1;
 
+	res = strcmp(self->node.iface, other->node.iface);
+	if (res)
+		return res;
+
 	return 0;
 }
 
@@ -441,6 +453,8 @@ static struct PyGetSetDef PyIscsiNode_getseters[] = {
 		"address", "address"},
 	{"port", (getter)PyIscsiNode_get, (setter)PyIscsiNode_set,
 		"port", "port"},
+	{"iface", (getter)PyIscsiNode_get, (setter)PyIscsiNode_set,
+		"iface", "iface"},
 	{NULL}
 };
 
-- 
1.7.3.3