diff options
author | Mike Christie <michaelc@cs.wisc.edu> | 2010-03-22 17:42:50 -0500 |
---|---|---|
committer | Mike Christie <michaelc@cs.wisc.edu> | 2010-03-22 17:42:50 -0500 |
commit | c94bb3206d8816f9d13c8d971513202d94cbb9ea (patch) | |
tree | c9983e982f849150741fbb8d2ed1b61816cbc2da /utils | |
parent | dbc5d37682103a8e3b578fdea743eb41ff46ff3c (diff) | |
download | open-iscsi-c94bb3206d8816f9d13c8d971513202d94cbb9ea.tar.gz |
iscsid: add isns discovery daemon and SCN support
This adds the following params to iscsid.conf
discovery.daemon.isns.addresses
discovery.daemon.isns.poll_interval
These work like SendTargets where if you the param iscsid will do
discovery and log into the portals found.
This also adds iSNS SCN support. Like the other code it only supports
login of new targets.
Some notes:
- It does not appear to work with the Microsoft iSNS server
shipping with Windows 2008 rc. I have not tested 2003.
The server does not seem to be sending any SCNs and at the
same time when we register for SCNs it tells us the operation
was successful. From the Microsoft docs it appears that
the server does not support SCN events.
- Linux-isns is not working with our code. The Linux-isns
code appears to be sending iSNS SCN pdus with an incorrect
format.
- It is working with open-isns.git.
Diffstat (limited to 'utils')
-rw-r--r-- | utils/open-isns/esi.c | 5 | ||||
-rw-r--r-- | utils/open-isns/isns-proto.h | 1 | ||||
-rw-r--r-- | utils/open-isns/isns.h | 5 | ||||
-rw-r--r-- | utils/open-isns/scn.c | 2 | ||||
-rw-r--r-- | utils/open-isns/simple.c | 16 | ||||
-rw-r--r-- | utils/open-isns/socket.c | 35 | ||||
-rw-r--r-- | utils/open-isns/sysdep-unix.c | 54 |
7 files changed, 97 insertions, 21 deletions
diff --git a/utils/open-isns/esi.c b/utils/open-isns/esi.c index 3fe62ac..47d52c6 100644 --- a/utils/open-isns/esi.c +++ b/utils/open-isns/esi.c @@ -49,7 +49,8 @@ static ISNS_LIST_DECLARE(isns_esi_list); static void isns_esi_transmit(void *); static void isns_esi_sendto(isns_esi_t *, isns_esi_portal_t *); -static void isns_process_esi_response(uint32_t, isns_simple_t *); +static void isns_process_esi_response(uint32_t, int, + isns_simple_t *); static void isns_esi_disconnect(isns_esi_portal_t *); static void isns_esi_restart(isns_esi_portal_t *); static void isns_esi_drop_portal(isns_esi_portal_t *, isns_db_t *, int); @@ -465,7 +466,7 @@ isns_process_esi(isns_server_t *srv, isns_simple_t *call, isns_simple_t **reply) } void -isns_process_esi_response(uint32_t xid, isns_simple_t *msg) +isns_process_esi_response(uint32_t xid, int status, isns_simple_t *msg) { isns_portal_info_t portal_info; isns_esi_portal_t *esp; diff --git a/utils/open-isns/isns-proto.h b/utils/open-isns/isns-proto.h index 1e2f682..fbc3376 100644 --- a/utils/open-isns/isns-proto.h +++ b/utils/open-isns/isns-proto.h @@ -20,6 +20,7 @@ struct isns_hdr { #define ISNS_VERSION 0x0001 #define ISNS_MAX_PDU_SIZE 65535 +#define ISNS_DEFAULT_PORT 3205 /* * Values for the i_flags field: diff --git a/utils/open-isns/isns.h b/utils/open-isns/isns.h index 73d4a45..53c22d5 100644 --- a/utils/open-isns/isns.h +++ b/utils/open-isns/isns.h @@ -125,7 +125,8 @@ extern int isns_simple_transmit(isns_socket_t *, isns_simple_t *, const isns_portal_info_t *, unsigned int, - void (*callback)(uint32_t, isns_simple_t *)); + void (*callback)(uint32_t, int, + isns_simple_t *)); extern void isns_simple_free(isns_simple_t *); extern const isns_attr_list_t *isns_simple_get_attrs(isns_simple_t *); @@ -488,6 +489,7 @@ extern isns_socket_t * isns_create_bound_client_socket(const char *myaddr, const char *hostname, const char *portname, int af_hint, int sock_type); extern isns_socket_t * isns_connect_to_portal(const isns_portal_info_t *); +extern void isns_socket_set_report_failure(isns_socket_t *); extern void isns_socket_set_disconnect_fatal(isns_socket_t *); extern int isns_socket_get_local_addr(const isns_socket_t *, struct sockaddr_storage *); @@ -652,6 +654,7 @@ extern int isns_portal_equal(const isns_portal_info_t *, const isns_portal_info_t *); extern int isns_enumerate_portals(isns_portal_info_t *, unsigned int); +extern int isns_get_nr_portals(void); /* Local registry stuff */ extern int isns_local_registry_load(const char *, pid_t, isns_object_list_t *); diff --git a/utils/open-isns/scn.c b/utils/open-isns/scn.c index d8fda1d..51fcba3 100644 --- a/utils/open-isns/scn.c +++ b/utils/open-isns/scn.c @@ -738,7 +738,7 @@ again: * comes in, or when the message timed out. */ static void -isns_process_scn_response(uint32_t xid, isns_simple_t *msg) +isns_process_scn_response(uint32_t xid, int status, isns_simple_t *msg) { isns_scn_t *scn; diff --git a/utils/open-isns/simple.c b/utils/open-isns/simple.c index 97e181f..1af89fd 100644 --- a/utils/open-isns/simple.c +++ b/utils/open-isns/simple.c @@ -15,7 +15,7 @@ #include "socket.h" #include "util.h" -typedef void isns_simple_callback_fn_t(uint32_t, isns_simple_t *); +typedef void isns_simple_callback_fn_t(uint32_t, int status, isns_simple_t *); static int isns_attr_list_scanner_get_pg(struct isns_attr_list_scanner *st); @@ -124,7 +124,7 @@ isns_simple_recv_response(isns_message_t *cmsg, isns_message_t *rmsg) { isns_simple_callback_fn_t *user_callback; isns_simple_t *resp = NULL; - int status; + int status = ISNS_INTERNAL_ERROR; /* rmsg being NULL means the call timed out. */ if (rmsg == NULL) @@ -133,15 +133,16 @@ isns_simple_recv_response(isns_message_t *cmsg, isns_message_t *rmsg) status = isns_message_status(rmsg); if (status != ISNS_SUCCESS) { isns_error("Server flags error: %s (status 0x%04x)\n", - isns_strerror(status), status); - return; + isns_strerror(status), status); + goto callback; } status = isns_simple_decode(rmsg, &resp); if (status) { isns_error("Unable to decode server response: %s (status 0x%04x)\n", isns_strerror(status), status); - return; + resp = NULL; + goto callback; } isns_simple_print(resp, isns_debug_message); @@ -149,8 +150,9 @@ isns_simple_recv_response(isns_message_t *cmsg, isns_message_t *rmsg) callback: user_callback = cmsg->im_calldata; if (user_callback) - user_callback(cmsg->im_xid, resp); - isns_simple_free(resp); + user_callback(cmsg->im_xid, status, resp); + if (resp) + isns_simple_free(resp); } /* diff --git a/utils/open-isns/socket.c b/utils/open-isns/socket.c index f0a758b..baed13c 100644 --- a/utils/open-isns/socket.c +++ b/utils/open-isns/socket.c @@ -1320,6 +1320,12 @@ isns_socket_set_disconnect_fatal(isns_socket_t *sock) sock->is_disconnect_fatal = 1; } +void +isns_socket_set_report_failure(isns_socket_t *sock) +{ + sock->is_report_failure = 1; +} + /* * Set the socket's security context */ @@ -1688,17 +1694,13 @@ again: isns_assert(!sock->is_destroy); isns_socket_release(sock); return msg; - default: isns_message_release(msg); + isns_socket_release(sock); + return NULL; } } - /* This will return 0 if the socket was marked for - * destruction. */ - if (!isns_socket_release(sock)) - continue; - isns_print_socket(sock); /* This handles reconnect, idle disconnect etc. */ @@ -1721,16 +1723,18 @@ again: } /* Check whether pending messages have timed out. */ - while (sock->is_state == ISNS_SOCK_IDLE - && (msg = isns_message_queue_head(&sock->is_pending)) != NULL) { + while ((msg = isns_message_queue_head(&sock->is_pending)) != + NULL) { if (__timeout_expired(&now, &msg->im_timeout)) { isns_debug_socket("sock %p message %04x timed out\n", sock, msg->im_xid); isns_message_unlink(msg); if (msg == watch_msg) { isns_message_release(msg); + isns_socket_release(sock); return NULL; } + isns_net_timeout(sock, msg); continue; } @@ -1774,22 +1778,33 @@ again: if (sock->is_state == ISNS_SOCK_FAILED) { if (sock->is_disconnect_fatal) goto kill_socket; - if (sock->is_report_failure) + if (sock->is_report_failure) { + isns_socket_release(sock); return NULL; + } sock->is_state = ISNS_SOCK_DISCONNECTED; + isns_socket_release(sock); continue; } if (sock->is_state == ISNS_SOCK_DEAD) { kill_socket: isns_list_del(&sock->is_list); - if (sock->is_report_failure) + if (sock->is_report_failure) { + isns_socket_release(sock); return NULL; + } if (!sock->is_client) isns_socket_free(sock); + isns_socket_release(sock); continue; } + /* This will return 0 if the socket was marked for + * destruction. */ + if (!isns_socket_release(sock)) + continue; + /* should not happen */ if (i >= max_sockets) break; diff --git a/utils/open-isns/sysdep-unix.c b/utils/open-isns/sysdep-unix.c index 8c601a7..d2a9532 100644 --- a/utils/open-isns/sysdep-unix.c +++ b/utils/open-isns/sysdep-unix.c @@ -11,6 +11,60 @@ #include "isns.h" #include "util.h" +int isns_get_nr_portals(void) +{ + char buffer[8192], *end, *ptr; + struct ifconf ifc; + unsigned int nportals = 0; + int fd = -1; + + if ((fd = socket(PF_INET, SOCK_DGRAM, 0)) < 0) { + isns_error("%s: no socket - %m\n", __FUNCTION__); + return 0; + } + + ifc.ifc_buf = buffer; + ifc.ifc_len = sizeof(buffer); + if (ioctl(fd, SIOCGIFCONF, &ifc) < 0) { + isns_error("ioctl(SIOCGIFCONF): %m\n"); + goto out; + } + + ptr = buffer; + end = buffer + ifc.ifc_len; + while (ptr < end) { + struct ifreq ifr; + struct sockaddr_storage ifaddr; + int ifflags; + + memcpy(&ifr, ptr, sizeof(ifr)); + ptr += sizeof(ifr); + + /* Get the interface addr */ + memcpy(&ifaddr, &ifr.ifr_addr, sizeof(ifr.ifr_addr)); + + if (ioctl(fd, SIOCGIFFLAGS, &ifr) < 0) { + isns_error("ioctl(%s, SIOCGIFFLAGS): %m\n", + ifr.ifr_name); + continue; + } + ifflags = ifr.ifr_flags; + + if ((ifflags & IFF_UP) == 0) + continue; + if ((ifflags & IFF_LOOPBACK) != 0) + continue; + + if (ifaddr.ss_family == AF_INET6 || ifaddr.ss_family == AF_INET) + nportals++; + } + +out: + if (fd >= 0) + close(fd); + return nportals; +} + int isns_enumerate_portals(isns_portal_info_t *result, unsigned int max) { |