1*ea99aae6Sclaudio /*
2*ea99aae6Sclaudio * Copyright (c) 2021 Dr Ashton Fagg <ashton@fagg.id.au>
3*ea99aae6Sclaudio *
4*ea99aae6Sclaudio * Permission to use, copy, modify, and distribute this software for any
5*ea99aae6Sclaudio * purpose with or without fee is hereby granted, provided that the above
6*ea99aae6Sclaudio * copyright notice and this permission notice appear in all copies.
7*ea99aae6Sclaudio *
8*ea99aae6Sclaudio * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9*ea99aae6Sclaudio * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10*ea99aae6Sclaudio * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11*ea99aae6Sclaudio * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12*ea99aae6Sclaudio * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13*ea99aae6Sclaudio * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14*ea99aae6Sclaudio * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15*ea99aae6Sclaudio */
16*ea99aae6Sclaudio
17*ea99aae6Sclaudio #include <sys/types.h>
18*ea99aae6Sclaudio #include <sys/queue.h>
19*ea99aae6Sclaudio #include <sys/socket.h>
20*ea99aae6Sclaudio #include <sys/uio.h>
21*ea99aae6Sclaudio
22*ea99aae6Sclaudio #include <event.h>
23*ea99aae6Sclaudio #include <stdio.h>
24*ea99aae6Sclaudio #include <stdlib.h>
25*ea99aae6Sclaudio #include <string.h>
26*ea99aae6Sclaudio #include <unistd.h>
27*ea99aae6Sclaudio
28*ea99aae6Sclaudio #include "iscsid.h"
29*ea99aae6Sclaudio #include "log.h"
30*ea99aae6Sclaudio
31*ea99aae6Sclaudio void
poll_session(struct session_poll * p,struct session * s)32*ea99aae6Sclaudio poll_session(struct session_poll *p, struct session *s)
33*ea99aae6Sclaudio {
34*ea99aae6Sclaudio if (!s)
35*ea99aae6Sclaudio fatal("poll_session failed: invalid session");
36*ea99aae6Sclaudio
37*ea99aae6Sclaudio ++p->session_count;
38*ea99aae6Sclaudio
39*ea99aae6Sclaudio /*
40*ea99aae6Sclaudio * If SESS_RUNNING, the session has either been brought up
41*ea99aae6Sclaudio * successfully, or has failed.
42*ea99aae6Sclaudio */
43*ea99aae6Sclaudio if (s->state & SESS_RUNNING) {
44*ea99aae6Sclaudio struct connection *c;
45*ea99aae6Sclaudio int is_logged_in = 0;
46*ea99aae6Sclaudio int is_failed = 0;
47*ea99aae6Sclaudio int is_waiting = 0;
48*ea99aae6Sclaudio
49*ea99aae6Sclaudio ++p->session_running_count;
50*ea99aae6Sclaudio
51*ea99aae6Sclaudio /* Next, check what state the connections are in. */
52*ea99aae6Sclaudio TAILQ_FOREACH(c, &s->connections, entry) {
53*ea99aae6Sclaudio if (c->state & CONN_LOGGED_IN)
54*ea99aae6Sclaudio ++is_logged_in;
55*ea99aae6Sclaudio else if (c->state & CONN_FAILED)
56*ea99aae6Sclaudio ++is_failed;
57*ea99aae6Sclaudio else if (c->state & CONN_NEVER_LOGGED_IN)
58*ea99aae6Sclaudio ++is_waiting;
59*ea99aae6Sclaudio
60*ea99aae6Sclaudio }
61*ea99aae6Sclaudio
62*ea99aae6Sclaudio /*
63*ea99aae6Sclaudio * Potentially, we have multiple connections for each session.
64*ea99aae6Sclaudio * Handle this by saying that a single connection logging
65*ea99aae6Sclaudio * in takes precedent over a failed connection. Only say
66*ea99aae6Sclaudio * the session login has failed if none of the connections
67*ea99aae6Sclaudio * have logged in and nothing is in flight.
68*ea99aae6Sclaudio */
69*ea99aae6Sclaudio
70*ea99aae6Sclaudio if (is_logged_in)
71*ea99aae6Sclaudio ++p->conn_logged_in_count;
72*ea99aae6Sclaudio if (is_failed)
73*ea99aae6Sclaudio ++p->conn_failed_count;
74*ea99aae6Sclaudio if (is_waiting)
75*ea99aae6Sclaudio ++p->conn_waiting_count;
76*ea99aae6Sclaudio
77*ea99aae6Sclaudio /* Sessions in SESS_INIT need to be waited on. */
78*ea99aae6Sclaudio } else if (s->state & SESS_INIT)
79*ea99aae6Sclaudio ++p->session_init_count;
80*ea99aae6Sclaudio else
81*ea99aae6Sclaudio fatal("poll_session: unknown state.");
82*ea99aae6Sclaudio }
83*ea99aae6Sclaudio
84*ea99aae6Sclaudio /*
85*ea99aae6Sclaudio * Set session_poll sess_conn_status based on the number of sessions
86*ea99aae6Sclaudio * versus number of logged in or failed sessions. If the numbers are
87*ea99aae6Sclaudio * equal iscsictl can stop polling since all sessions reached a stable state.
88*ea99aae6Sclaudio */
89*ea99aae6Sclaudio void
poll_finalize(struct session_poll * p)90*ea99aae6Sclaudio poll_finalize(struct session_poll *p)
91*ea99aae6Sclaudio {
92*ea99aae6Sclaudio p->sess_conn_status = (p->session_count == p->conn_logged_in_count +
93*ea99aae6Sclaudio p->conn_failed_count);
94*ea99aae6Sclaudio }
95