Ashton Fagg <[email protected]> writes:

> Attached is my first attempt at a "proper" solution. I haven't tested it
> beyond building as I can't take my machine down for testing right now...
>
> But, I'd appreciate a sanity check that I'm on the right track.

Sorry for the noise. I think my mail client mangled the attachment, so
trying again.

diff --git a/usr.sbin/iscsictl/iscsictl.c b/usr.sbin/iscsictl/iscsictl.c
index 77f9c74abde..5fc326acca6 100644
--- a/usr.sbin/iscsictl/iscsictl.c
+++ b/usr.sbin/iscsictl/iscsictl.c
@@ -40,6 +40,8 @@ struct pdu	*ctl_getpdu(char *, size_t);
 int		 ctl_sendpdu(int, struct pdu *);
 void		 show_config(struct ctrlmsghdr *, struct pdu *);
 void		 show_vscsi_stats(struct ctrlmsghdr *, struct pdu *);
+void             poll_and_wait(void);
+void             register_poll(struct ctrlmsghdr *, struct pdu *);
 
 char		cbuf[CONTROL_READ_SIZE];
 
@@ -48,6 +50,14 @@ struct control {
 	int		fd;
 } control;
 
+struct poll_result {
+	u_int8_t   result;
+	int        attempts;
+} pr;
+
+#define POLL_DELAY     1
+#define POLL_ATTEMPTS  10
+
 __dead void
 usage(void)
 {
@@ -68,7 +78,7 @@ main (int argc, char* argv[])
 	char *sockname = ISCSID_CONTROL;
 	struct session_ctlcfg *s;
 	struct iscsi_config *cf;
-	int ch, val = 0;
+	int ch, poll = 0, val = 0;
 
 	/* check flags */
 	while ((ch = getopt(argc, argv, "f:s:")) != -1) {
@@ -135,6 +145,9 @@ main (int argc, char* argv[])
 			    &cf->initiator, sizeof(cf->initiator)) == -1)
 				err(1, "control_compose");
 		}
+
+		/* Reloading, so poll afterwards. */
+		poll = 1;
 		SIMPLEQ_FOREACH(s, &cf->sessions, entry) {
 			struct ctrldata cdv[3];
 			bzero(cdv, sizeof(cdv));
@@ -174,6 +187,12 @@ main (int argc, char* argv[])
 
 	run();
 
+	/* If we've reloaded, we probably should wait in case any new connections
+	   need to come up (or fail). */
+	if (poll) {
+		poll_and_wait();
+	}
+
 	close(control.fd);
 
 	return (0);
@@ -229,6 +248,10 @@ run_command(struct pdu *pdu)
 		case CTRL_INPROGRESS:
 			printf("command in progress...\n");
 			break;
+		case CTRL_SESS_POLL:
+			done = 1;
+			register_poll(cmh, pdu);
+			break;
 		case CTRL_INITIATOR_CONFIG:
 		case CTRL_SESSION_CONFIG:
 			show_config(cmh, pdu);
@@ -383,3 +406,43 @@ show_vscsi_stats(struct ctrlmsghdr *cmh, struct pdu *pdu)
 	    vs->cnt_t2i_status[1], 
 	    vs->cnt_t2i_status[2]);
 }
+
+void
+poll_and_wait(void)
+{
+	pr.result = (u_int8_t) 0;
+	printf("polling...");
+
+	for (pr.attempts = 1; pr.attempts <= POLL_ATTEMPTS; ++pr.attempts) {
+		if (control_compose(NULL, CTRL_SESS_POLL, NULL, 0) == -1)
+			err(1, "control_compose");
+
+		struct pdu *pdu;
+		while ((pdu = TAILQ_FIRST(&control.channel)) != NULL) {
+			run_command(pdu);
+		}
+
+		/* Poll says we are good to go. */
+		if (pr.result != 0) {
+			printf("ok!\n");
+			return;
+		}
+
+		/* Poll says we should wait... */
+		printf("%d, ", pr.attempts);
+		sleep(POLL_DELAY);
+	}
+
+	printf("..,timer exceeded.\n");
+}
+
+void
+register_poll(struct ctrlmsghdr *cmh, struct pdu *pdu)
+{
+	u_int8_t *r = &pr.result;
+
+	if (cmh->len[0] != sizeof(u_int8_t))
+		errx(1, "poll: bad size of response");
+
+	r = pdu_getbuf(pdu, NULL, 1);
+}
diff --git a/usr.sbin/iscsid/Makefile b/usr.sbin/iscsid/Makefile
index 7a62024e68b..bac59d934f8 100644
--- a/usr.sbin/iscsid/Makefile
+++ b/usr.sbin/iscsid/Makefile
@@ -2,7 +2,7 @@
 
 PROG=	iscsid
 SRCS=	connection.c control.c initiator.c iscsid.c log.c logmsg.c pdu.c \
-	session.c task.c util.c vscsi.c
+	poll.c session.c task.c util.c vscsi.c
 
 MAN=	iscsid.8
 
diff --git a/usr.sbin/iscsid/iscsid.c b/usr.sbin/iscsid/iscsid.c
index d3526e96363..61f831c3b24 100644
--- a/usr.sbin/iscsid/iscsid.c
+++ b/usr.sbin/iscsid/iscsid.c
@@ -211,6 +211,7 @@ iscsid_ctrl_dispatch(void *ch, struct pdu *pdu)
 	struct initiator_config *ic;
 	struct session_config *sc;
 	struct session *s;
+	struct session_poll *p;
 	int *valp;
 
 	cmh = pdu_getbuf(pdu, NULL, 0);
@@ -304,6 +305,20 @@ iscsid_ctrl_dispatch(void *ch, struct pdu *pdu)
 
 		control_compose(ch, CTRL_SUCCESS, NULL, 0);
 		break;
+	case CTRL_SESS_POLL:
+		p = poll_alloc();
+
+		TAILQ_FOREACH(s, &initiator->sessions, entry) {
+			poll_session(p, s);
+		}
+
+		poll_finalize(p);
+
+		control_compose(ch, CTRL_SESS_POLL,
+		    (void *) &(p->status), sizeof(u_int8_t));
+
+		poll_dealloc(p);
+		break;
 	default:
 		log_warnx("unknown control message type %d", cmh->type);
 		control_compose(ch, CTRL_FAILURE, NULL, 0);
diff --git a/usr.sbin/iscsid/iscsid.h b/usr.sbin/iscsid/iscsid.h
index b43fb5dcd99..08d5f251a39 100644
--- a/usr.sbin/iscsid/iscsid.h
+++ b/usr.sbin/iscsid/iscsid.h
@@ -67,7 +67,7 @@ struct ctrldata {
 #define CTRL_LOG_VERBOSE	6
 #define CTRL_VSCSI_STATS	7
 #define CTRL_SHOW_SUM		8
-
+#define CTRL_SESS_POLL          9
 
 TAILQ_HEAD(session_head, session);
 TAILQ_HEAD(connection_head, connection);
@@ -251,6 +251,13 @@ struct session {
 	int			 action;
 };
 
+struct session_poll {
+	u_int16_t session_count; /* Total number of configured sessions*/
+	u_int16_t init_count;    /* Number of sessions in init state */
+	u_int16_t running_count; /* Number of sessions in running state */
+	u_int8_t  status;        /* Status flag */
+};
+
 struct connection {
 	struct event		 ev;
 	struct event		 wev;
@@ -391,6 +398,12 @@ void	vscsi_status(int, int, void *, size_t);
 void	vscsi_event(unsigned long, u_int, u_int);
 struct vscsi_stats *vscsi_stats(void);
 
+/* Session polling */
+struct session_poll *poll_alloc(void);
+void    poll_dealloc(struct session_poll *);
+void    poll_session(struct session_poll *, struct session *);
+void    poll_finalize(struct session_poll *);
+
 /* logmsg.c */
 void	log_hexdump(void *, size_t);
 void	log_pdu(struct pdu *, int);
diff --git a/usr.sbin/iscsid/poll.c b/usr.sbin/iscsid/poll.c
new file mode 100644
index 00000000000..d3c79985d71
--- /dev/null
+++ b/usr.sbin/iscsid/poll.c
@@ -0,0 +1,80 @@
+/*
+ * Copyright (c) 2021 Dr Ashton Fagg <[email protected]>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include <sys/types.h>
+#include <sys/socket.h>
+
+#include <event.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#include "iscsid.h"
+#include "log.h"
+
+struct session_poll
+*poll_alloc(void)
+{
+	struct session_poll *p;
+
+	if (!(p = calloc(1, sizeof(*p))))
+		fatal("poll_alloc failed.");
+
+	p->session_count = (u_int16_t) 0;
+	p->init_count    = (u_int16_t) 0;
+	p->running_count = (u_int16_t) 0;
+
+	return p;
+}
+
+
+void
+poll_dealloc(struct session_poll *p)
+{
+	free(p);
+}
+
+void
+poll_session(struct session_poll *p, struct session *s)
+{
+	if (!s)
+		fatal("poll_session failed: invalid session");
+
+	++(p->session_count);
+
+	/* If SESS_RUNNING, this determines the session has either
+           been brought up successfully, or has failed. Either way,
+	   we aren't waiting on it. */
+	if (s->state & SESS_RUNNING)
+		++(p->running_count);
+	/* Otherwise, it is in SESS_INIT. These need to be waited on. */
+	else if (s->state & SESS_RUNNING)
+		++(p->init_count);
+	else
+		fatal("poll_session: unknown state.");
+}
+
+void
+poll_finalize(struct session_poll *p)
+{
+	/* Perform final book keeping to determine status.
+         *
+	 * status will be non-zero if the number of sessions that are
+         * in states other than SESS_INIT is equal to the total number
+	 * of configured sessions. This indicates to the poller that
+	 * we are not waiting for something to complete. */
+	p->status = (u_int8_t) (p->session_count == p->running_count);
+}

Reply via email to