Re: [PATCH 1/1] iscsi: add support to use multiple portals for iscsi

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Tomo,

Please find attached an updated patch with your suggestions.


regards
ronnie sahlberg


On Thu, Apr 14, 2011 at 7:08 PM, FUJITA Tomonori
<fujita.tomonori@xxxxxxxxxxxxx> wrote:

> I always like to use list_head (and with its accessors) for the
> simplicity and readability.

Attachment: 0001-Add-support-for-multiple-portals.patch.gz
Description: GNU Zip compressed data

From 6b5596380bd740604eb72dd94d5a9ca541e1e6eb Mon Sep 17 00:00:00 2001
From: Ronnie Sahlberg <ronniesahlberg@xxxxxxxxx>
Date: Sat, 16 Apr 2011 07:27:32 +1000
Subject: [PATCH] Add support for multiple portals.

This patch makes it possible to bind tgtd to multiple portals like

tgtd --iscsi portal=10.1.1.1:3260,portal=10.1.1.2:3261,portal=10.1.1.3:3262

Signed-off-by: Ronnie Sahlberg <ronniesahlberg@xxxxxxxxx>
---
 usr/iscsi/iscsi_tcp.c |   31 ++++++++++++++++++++++++++++---
 usr/iscsi/iscsid.c    |   41 +++++++++++++++++++++++++++++------------
 usr/iscsi/iscsid.h    |   11 +++++++++--
 usr/iscsi/isns.c      |   15 ++++++++++-----
 4 files changed, 76 insertions(+), 22 deletions(-)

diff --git a/usr/iscsi/iscsi_tcp.c b/usr/iscsi/iscsi_tcp.c
index 0fbb671..14c55bb 100644
--- a/usr/iscsi/iscsi_tcp.c
+++ b/usr/iscsi/iscsi_tcp.c
@@ -169,20 +169,20 @@ static void iscsi_tcp_event_handler(int fd, int events, void *data)
 	}
 }
 
-static int iscsi_tcp_init(void)
+static int iscsi_tcp_init_portal(struct iscsi_portal *portal)
 {
 	struct addrinfo hints, *res, *res0;
 	char servname[64];
 	int ret, fd, opt, nr_sock = 0;
 
 	memset(servname, 0, sizeof(servname));
-	snprintf(servname, sizeof(servname), "%d", iscsi_listen_port);
+	snprintf(servname, sizeof(servname), "%d", portal->port);
 
 	memset(&hints, 0, sizeof(hints));
 	hints.ai_socktype = SOCK_STREAM;
 	hints.ai_flags = AI_PASSIVE;
 
-	ret = getaddrinfo(iscsi_portal_addr, servname, &hints, &res0);
+	ret = getaddrinfo(portal->addr, servname, &hints, &res0);
 	if (ret) {
 		eprintf("unable to get address info, %m\n");
 		return -errno;
@@ -237,6 +237,7 @@ static int iscsi_tcp_init(void)
 		else {
 			listen_fds[nr_sock] = fd;
 			nr_sock++;
+			portal->fd = fd;
 		}
 	}
 
@@ -245,6 +246,30 @@ static int iscsi_tcp_init(void)
 	return !nr_sock;
 }
 
+static int iscsi_tcp_init(void)
+{
+	struct iscsi_portal *portal;
+
+	/* if the user did not set a portal we default to wildcard
+	   for ipv4 and ipv6
+	*/
+	if (list_empty(&iscsi_portals_list)) {
+		iscsi_add_portal("0::0", 0);
+		iscsi_add_portal("0.0.0.0", 0);
+	}
+
+	list_for_each_entry(portal, &iscsi_portals_list,
+			    iscsi_portal_siblings) {
+		int ret;
+
+		ret = iscsi_tcp_init_portal(portal);
+		if (ret)
+			return ret;
+	}
+
+	return 0;
+}
+
 static void iscsi_tcp_exit(void)
 {
 	int i;
diff --git a/usr/iscsi/iscsid.c b/usr/iscsi/iscsid.c
index e8140e0..b61bb28 100644
--- a/usr/iscsi/iscsid.c
+++ b/usr/iscsi/iscsid.c
@@ -43,8 +43,7 @@
 
 #define MAX_QUEUE_CMD	128
 
-int iscsi_listen_port = ISCSI_LISTEN_PORT;
-char *iscsi_portal_addr;
+LIST_HEAD(iscsi_portals_list);
 
 enum {
 	IOSTATE_FREE,
@@ -74,6 +73,18 @@ enum {
 	IOSTATE_TX_END,
 };
 
+void iscsi_add_portal(char *addr, int port)
+{
+	struct iscsi_portal *new_portal;
+
+	new_portal = zalloc(sizeof(struct iscsi_portal));
+	new_portal->addr = strdup(addr);
+	new_portal->port = port ? port : ISCSI_LISTEN_PORT;
+	new_portal->fd   = -1;
+
+	list_add(&new_portal->iscsi_portal_siblings, &iscsi_portals_list);
+};
+
 void conn_read_pdu(struct iscsi_connection *conn)
 {
 	conn->rx_iostate = IOSTATE_RX_BHS;
@@ -827,7 +838,7 @@ static void text_scan_text(struct iscsi_connection *conn)
 			struct sockaddr_storage ss;
 			socklen_t slen, blen;
 			char *p, buf[NI_MAXHOST + 128];
-			int ret;
+			int ret, port;
 
 			if (value[0] == 0)
 				continue;
@@ -861,7 +872,14 @@ static void text_scan_text(struct iscsi_connection *conn)
 			if (ss.ss_family == AF_INET6)
 				 *p++ = ']';
 
-			sprintf(p, ":%d,1", iscsi_listen_port);
+			if (ss.ss_family == AF_INET6)
+				port = ntohs(((struct sockaddr_in6 *)
+						&ss)->sin6_port);
+			else
+				port = ntohs(((struct sockaddr_in *)
+						&ss)->sin_port);
+
+			sprintf(p, ":%d,1", port);
 			target_list_build(conn, buf,
 					  strcmp(value, "All") ? value : NULL);
 		} else
@@ -2374,13 +2392,13 @@ static int iscsi_param_parser(char *p)
 	while (*p) {
 		if (!strncmp(p, "portal", 6)) {
 			char *addr, *q;
-			int len;
+			int len, port = 0;
 
 			addr = p + 7;
 
 			q = strchr(addr, ':');
 			if (q)
-				iscsi_listen_port = atoi(q + 1);
+				port = atoi(q + 1);
 			else
 				q = strchr(addr, ',');
 
@@ -2389,13 +2407,12 @@ static int iscsi_param_parser(char *p)
 			else
 				len = strlen(addr);
 
-			if (iscsi_portal_addr) {
-				free(iscsi_portal_addr);
-				iscsi_portal_addr = NULL;
-			}
 			if (len) {
-				iscsi_portal_addr = zalloc(len + 1);
-				memcpy(iscsi_portal_addr, addr, len);
+				char *tmp;
+				tmp = zalloc(len + 1);
+				memcpy(tmp, addr, len);
+				iscsi_add_portal(tmp, port);
+				free(tmp);
 			}
 		}
 
diff --git a/usr/iscsi/iscsid.h b/usr/iscsi/iscsid.h
index e496712..76f6496 100644
--- a/usr/iscsi/iscsid.h
+++ b/usr/iscsi/iscsid.h
@@ -266,8 +266,14 @@ enum task_flags {
 	TASK_in_scsi,
 };
 
-extern int iscsi_listen_port;
-extern char *iscsi_portal_addr;
+struct iscsi_portal {
+	struct list_head iscsi_portal_siblings;
+	char *addr;
+	int port;
+	int fd;
+};
+
+extern struct list_head iscsi_portals_list;
 
 #define set_task_pending(t)	((t)->flags |= (1 << TASK_pending))
 #define clear_task_pending(t)	((t)->flags &= ~(1 << TASK_pending))
@@ -302,6 +308,7 @@ extern int iscsi_tx_handler(struct iscsi_connection *conn);
 extern void iscsi_rx_handler(struct iscsi_connection *conn);
 extern int iscsi_scsi_cmd_execute(struct iscsi_task *task);
 extern int iscsi_transportid(int tid, uint64_t itn_id, char *buf, int size);
+extern void iscsi_add_portal(char *addr, int port);
 
 /* iscsid.c iscsi_task */
 extern void iscsi_free_task(struct iscsi_task *task);
diff --git a/usr/iscsi/isns.c b/usr/iscsi/isns.c
index 19531de..0afd251 100644
--- a/usr/iscsi/isns.c
+++ b/usr/iscsi/isns.c
@@ -71,6 +71,7 @@ static char *rxbuf;
 static uint16_t transaction;
 static char eid[ISCSI_NAME_LEN];
 static uint8_t ip[16]; /* IET supoprts only one portal */
+static uint16_t port;
 static struct sockaddr_storage ss;
 
 /*
@@ -147,10 +148,14 @@ static int isns_get_ip(int fd)
 		ip[14] = 0xff & (addr >> 16);
 		ip[13] = 0xff & (addr >> 8);
 		ip[12] = 0xff & addr;
+
+		port = (((struct sockaddr_in *) &lss)->sin_port);
 		break;
 	case AF_INET6:
 		for (i = 0; i < ARRAY_SIZE(ip); i++)
 			ip[i] = ((struct sockaddr_in6 *) &lss)->sin6_addr.s6_addr[i];
+
+		port = (((struct sockaddr_in6 *) &lss)->sin6_port);
 		break;
 	}
 
@@ -417,7 +422,7 @@ int isns_target_register(char *name)
 	struct isns_hdr *hdr = (struct isns_hdr *) buf;
 	struct isns_tlv *tlv;
 	struct iscsi_target *target;
-	uint32_t port = htonl(iscsi_listen_port);
+	uint32_t p    = htonl(port);
 	uint32_t node = htonl(ISNS_NODE_TARGET);
 	uint32_t type = htonl(2);
 	int err;
@@ -447,7 +452,7 @@ int isns_target_register(char *name)
 		length += isns_tlv_set(&tlv, ISNS_ATTR_PORTAL_IP_ADDRESS,
 				       sizeof(ip), &ip);
 		length += isns_tlv_set(&tlv, ISNS_ATTR_PORTAL_PORT,
-				       sizeof(port), &port);
+				       sizeof(p), &p);
 		flags = ISNS_FLAG_REPLACE;
 
 		if (scn_listen_port) {
@@ -958,14 +963,14 @@ static void isns_timeout_fn(void *data)
 int isns_init(void)
 {
 	int err;
-	char port[8];
+	char p[8];
 	struct addrinfo hints, *res;
 	struct iscsi_target *target;
 
-	snprintf(port, sizeof(port), "%d", isns_port);
+	snprintf(p, sizeof(p), "%d", isns_port);
 	memset(&hints, 0, sizeof(hints));
 	hints.ai_socktype = SOCK_STREAM;
-	err = getaddrinfo(isns_addr, (char *) &port, &hints, &res);
+	err = getaddrinfo(isns_addr, (char *) &p, &hints, &res);
 	if (err) {
 		eprintf("getaddrinfo error %s\n", isns_addr);
 		return -1;
-- 
1.7.3.1


[Index of Archives]     [Linux SCSI]     [Linux RAID]     [Linux Clusters]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]

  Powered by Linux