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