Re: New portal feature breaks systems without IPv6 in kernel

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


Tomo, List

Please find attached a new patch that fixes the breakage for non-ipv6
enabled hosts.



On Sat, May 21, 2011 at 2:47 AM, FUJITA Tomonori
<fujita.tomonori@xxxxxxxxxxxxx> wrote:
> On Fri, 13 May 2011 19:36:04 +1000
> ronnie sahlberg <ronniesahlberg@xxxxxxxxx> wrote:
>
>> On Thu, May 12, 2011 at 8:22 PM, FUJITA Tomonori
>> <fujita.tomonori@xxxxxxxxxxxxx> wrote:
>>> On Wed, 11 May 2011 17:06:35 +1000
>>> ronnie sahlberg <ronniesahlberg@xxxxxxxxx> wrote:
>>>
>>>> By default, if no portal is specified, tgtd will try to bind to both
>>>> IPv6 and IPv4 wildcard.
>>>> This caused the start to fail with an error on systems with no IPv6 available.
>>>
>>> The root problem is that the current code assumes network
>>> configurations in the following way:
>>>
>>> if (list_empty(&iscsi_portals_list)) {
>>>        iscsi_add_portal("0::0", 0, 1, 0);
>>>        iscsi_add_portal("0.0.0.0", 0, 1, 0);
>>> }
>>>
>>> Which is exactly what network programing text books tell us not to do,
>>> I think.
>>>
>>> What we should do here is asking a system about available network
>>> addresses by passing NULL to getaddrinfo() like the old code did.
>>>
>>> I think that we should move the portal allocation code in
>>> iscsi_add_portal() to iscsi_tcp_init_potal(). iscsi_tcp_init_potal()
>>> takes addr and port, then creates iscsi_portal struct.
>>>
>>> Can you fix this in such way?
>>>
>>
>> I can and I will
>> patch eta tomorrow
>
> Ping? Let me know if you are busy about other stuff. I could fix it.
>

Attachment: 0001-Fix-the-brekage-in-the-portal-handling-so-it-is-agai.patch.gz
Description: GNU Zip compressed data

From 73f6b26f019052182c05148e3b0853dd9bae76f6 Mon Sep 17 00:00:00 2001
From: Ronnie Sahlberg <ronniesahlberg@xxxxxxxxx>
Date: Mon, 23 May 2011 18:14:42 +1000
Subject: [PATCH] Fix the brekage in the portal handling so it is again possible to run tgtd on hosts without ipv6 support.


Signed-off-by: Ronnie Sahlberg <ronniesahlberg@xxxxxxxxx>
---
 usr/iscsi/iscsi_tcp.c |   72 ++++++++++++++++++++++--------------------------
 usr/iscsi/iscsid.c    |   17 +++++++-----
 usr/iscsi/iscsid.h    |    5 +++-
 3 files changed, 47 insertions(+), 47 deletions(-)

diff --git a/usr/iscsi/iscsi_tcp.c b/usr/iscsi/iscsi_tcp.c
index e87bbf1..90cdd4a 100644
--- a/usr/iscsi/iscsi_tcp.c
+++ b/usr/iscsi/iscsi_tcp.c
@@ -169,20 +169,25 @@ static void iscsi_tcp_event_handler(int fd, int events, void *data)
 	}
 }
 
-static int iscsi_tcp_init_portal(struct iscsi_portal *portal)
+int iscsi_tcp_init_portal(char *addr, int port, int tpgt)
 {
 	struct addrinfo hints, *res, *res0;
 	char servname[64];
 	int ret, fd, opt, nr_sock = 0;
+	struct iscsi_portal *portal = NULL;
+	char addrstr[64];
+	void *addrptr;
+
+	port = port ? port : ISCSI_LISTEN_PORT;
 
 	memset(servname, 0, sizeof(servname));
-	snprintf(servname, sizeof(servname), "%d", portal->port);
+	snprintf(servname, sizeof(servname), "%d", port);
 
 	memset(&hints, 0, sizeof(hints));
 	hints.ai_socktype = SOCK_STREAM;
 	hints.ai_flags = AI_PASSIVE;
 
-	ret = getaddrinfo(portal->addr, servname, &hints, &res0);
+	ret = getaddrinfo(addr, servname, &hints, &res0);
 	if (ret) {
 		eprintf("unable to get address info, %m\n");
 		return -errno;
@@ -237,8 +242,26 @@ static int iscsi_tcp_init_portal(struct iscsi_portal *portal)
 		else {
 			listen_fds[nr_sock] = fd;
 			nr_sock++;
-			portal->fd = fd;
 		}
+
+		portal = zalloc(sizeof(struct iscsi_portal));
+		switch (res->ai_family) {
+		case AF_INET:
+			addrptr = &((struct sockaddr_in *)
+				    res->ai_addr)->sin_addr;
+			break;
+		case AF_INET6:
+			addrptr = &((struct sockaddr_in6 *)
+				    res->ai_addr)->sin6_addr;
+			break;
+		}
+		portal->addr = strdup(inet_ntop(res->ai_family, addrptr,
+			     addrstr, sizeof(addrstr)));
+		portal->port = port;
+		portal->tpgt = tpgt;
+		portal->fd   = fd;
+
+		list_add(&portal->iscsi_portal_siblings, &iscsi_portals_list);
 	}
 
 	freeaddrinfo(res0);
@@ -246,34 +269,13 @@ static int iscsi_tcp_init_portal(struct iscsi_portal *portal)
 	return !nr_sock;
 }
 
-int iscsi_add_portal(char *addr, int port, int tpgt, int do_create)
+int iscsi_add_portal(char *addr, int port, int tpgt)
 {
-	struct iscsi_portal *new_portal;
-
-	list_for_each_entry(new_portal, &iscsi_portals_list,
-			    iscsi_portal_siblings) {
-		if (!strcmp(addr, new_portal->addr)
-			&& port == new_portal->port) {
-			eprintf("add_portal failed. This portal already "
-				"exists %s:%d\n", addr, port);
-			return -1;
-		}
-	}
-
-	new_portal = zalloc(sizeof(struct iscsi_portal));
-	new_portal->addr = strdup(addr);
-	new_portal->port = port ? port : ISCSI_LISTEN_PORT;
-	new_portal->tpgt = tpgt;
-	new_portal->fd   = -1;
-
-	if (do_create && iscsi_tcp_init_portal(new_portal)) {
+	if (iscsi_tcp_init_portal(addr, port, tpgt)) {
 		eprintf("failed to create/bind to portal %s:%d\n", addr, port);
-		free(new_portal->addr);
-		free(new_portal);
 		return -1;
 	}
 
-	list_add(&new_portal->iscsi_portal_siblings, &iscsi_portals_list);
 	return 0;
 };
 
@@ -300,23 +302,15 @@ int iscsi_delete_portal(char *addr, int port)
 
 static int iscsi_tcp_init(void)
 {
-	struct iscsi_portal *portal;
+	/* If we were passed any portals on the command line */
+	if (portal_arguments)
+		iscsi_param_parse_portals(portal_arguments, 1, 0);
 
 	/* 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, 1, 0);
-		iscsi_add_portal("0.0.0.0", 0, 1, 0);
-	}
-
-	list_for_each_entry(portal, &iscsi_portals_list,
-			    iscsi_portal_siblings) {
-		int ret;
-
-		ret = iscsi_tcp_init_portal(portal);
-		if (ret)
-			return ret;
+		iscsi_add_portal(NULL, 3260, 1);
 	}
 
 	return 0;
diff --git a/usr/iscsi/iscsid.c b/usr/iscsi/iscsid.c
index 104bdfa..83ce490 100644
--- a/usr/iscsi/iscsid.c
+++ b/usr/iscsi/iscsid.c
@@ -45,6 +45,8 @@
 
 LIST_HEAD(iscsi_portals_list);
 
+char *portal_arguments;
+
 enum {
 	IOSTATE_FREE,
 
@@ -2359,8 +2361,8 @@ int iscsi_transportid(int tid, uint64_t itn_id, char *buf, int size)
 	return len;
 }
 
-static int iscsi_param_parse_portals(char *p, int do_add,
-			int do_create, int do_delete)
+int iscsi_param_parse_portals(char *p, int do_add,
+			int do_delete)
 {
 	while (*p) {
 		if (!strncmp(p, "portal", 6)) {
@@ -2401,8 +2403,8 @@ static int iscsi_param_parse_portals(char *p, int do_add,
 				char *tmp;
 				tmp = zalloc(len + 1);
 				memcpy(tmp, addr, len);
-				if (do_add && iscsi_add_portal(tmp, port, 1,
-							do_create)) {
+				if (do_add && iscsi_add_portal(tmp,
+							port, 1)) {
 					free(tmp);
 					return -1;
 				}
@@ -2424,17 +2426,18 @@ static int iscsi_param_parse_portals(char *p, int do_add,
 
 static int iscsi_param_parser(char *p)
 {
-	return iscsi_param_parse_portals(p, 1, 0, 0);
+	portal_arguments = p;
+	return 0;
 }
 
 static int iscsi_portal_create(char *p)
 {
-	return iscsi_param_parse_portals(p, 1, 1, 0);
+	return iscsi_param_parse_portals(p, 1, 0);
 }
 
 static int iscsi_portal_destroy(char *p)
 {
-	return iscsi_param_parse_portals(p, 0, 0, 1);
+	return iscsi_param_parse_portals(p, 0, 1);
 }
 
 static struct tgt_driver iscsi = {
diff --git a/usr/iscsi/iscsid.h b/usr/iscsi/iscsid.h
index 0a72261..ce083de 100644
--- a/usr/iscsi/iscsid.h
+++ b/usr/iscsi/iscsid.h
@@ -276,6 +276,8 @@ struct iscsi_portal {
 
 extern struct list_head iscsi_portals_list;
 
+extern char *portal_arguments;
+
 #define set_task_pending(t)	((t)->flags |= (1 << TASK_pending))
 #define clear_task_pending(t)	((t)->flags &= ~(1 << TASK_pending))
 #define task_pending(t)		((t)->flags & (1 << TASK_pending))
@@ -309,8 +311,9 @@ 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 int iscsi_add_portal(char *addr, int port, int tpgt, int do_create);
+extern int iscsi_add_portal(char *addr, int port, int tpgt);
 extern int iscsi_delete_portal(char *addr, int port);
+extern int iscsi_param_parse_portals(char *p, int do_add, int do_delete);
 
 /* iscsid.c iscsi_task */
 extern void iscsi_free_task(struct iscsi_task *task);
-- 
1.7.3.1


[Linux SCSI]     [Linux RAID]     [Linux Clusters]     [Linux USB Devel]     [Video for Linux]     [Linux Audio Users]     [Photo]     [Yosemite News]    [Yosemite Photos]    [Free Online Dating]     [Linux Kernel]     [XFree86]     [Video Devices]

Add to Google Powered by Linux