From 203290639399b4cc3c5039b2f3e653002eb2a9cb Mon Sep 17 00:00:00 2001 From: Ales Kozumplik 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