summaryrefslogtreecommitdiff
path: root/utils
diff options
context:
space:
mode:
authorMike Christie <michaelc@cs.wisc.edu>2010-03-22 17:42:50 -0500
committerMike Christie <michaelc@cs.wisc.edu>2010-03-22 17:42:50 -0500
commitc94bb3206d8816f9d13c8d971513202d94cbb9ea (patch)
treec9983e982f849150741fbb8d2ed1b61816cbc2da /utils
parentdbc5d37682103a8e3b578fdea743eb41ff46ff3c (diff)
downloadopen-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.c5
-rw-r--r--utils/open-isns/isns-proto.h1
-rw-r--r--utils/open-isns/isns.h5
-rw-r--r--utils/open-isns/scn.c2
-rw-r--r--utils/open-isns/simple.c16
-rw-r--r--utils/open-isns/socket.c35
-rw-r--r--utils/open-isns/sysdep-unix.c54
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)
{