summaryrefslogtreecommitdiffstats
path: root/usr.bin/iscsictl/iscsictl.c
diff options
context:
space:
mode:
Diffstat (limited to 'usr.bin/iscsictl/iscsictl.c')
-rw-r--r--usr.bin/iscsictl/iscsictl.c79
1 files changed, 76 insertions, 3 deletions
diff --git a/usr.bin/iscsictl/iscsictl.c b/usr.bin/iscsictl/iscsictl.c
index a27e32b..8e7faac 100644
--- a/usr.bin/iscsictl/iscsictl.c
+++ b/usr.bin/iscsictl/iscsictl.c
@@ -550,12 +550,70 @@ kernel_list(int iscsi_fd, const struct target *targ __unused,
return (0);
}
+static int
+kernel_wait(int iscsi_fd, int timeout)
+{
+ struct iscsi_session_state *states = NULL;
+ const struct iscsi_session_state *state;
+ const struct iscsi_session_conf *conf;
+ struct iscsi_session_list isl;
+ unsigned int i, nentries = 1;
+ bool all_connected;
+ int error;
+
+ for (;;) {
+ for (;;) {
+ states = realloc(states,
+ nentries * sizeof(struct iscsi_session_state));
+ if (states == NULL)
+ err(1, "realloc");
+
+ memset(&isl, 0, sizeof(isl));
+ isl.isl_nentries = nentries;
+ isl.isl_pstates = states;
+
+ error = ioctl(iscsi_fd, ISCSISLIST, &isl);
+ if (error != 0 && errno == EMSGSIZE) {
+ nentries *= 4;
+ continue;
+ }
+ break;
+ }
+ if (error != 0) {
+ warn("ISCSISLIST");
+ return (error);
+ }
+
+ all_connected = true;
+ for (i = 0; i < isl.isl_nentries; i++) {
+ state = &states[i];
+ conf = &state->iss_conf;
+
+ if (!state->iss_connected) {
+ all_connected = false;
+ break;
+ }
+ }
+
+ if (all_connected)
+ return (0);
+
+ sleep(1);
+
+ if (timeout > 0) {
+ timeout--;
+ if (timeout == 0)
+ return (1);
+ }
+ }
+}
+
static void
usage(void)
{
fprintf(stderr, "usage: iscsictl -A -p portal -t target "
- "[-u user -s secret]\n");
+ "[-u user -s secret] [-w timeout]\n");
fprintf(stderr, " iscsictl -A -d discovery-host "
"[-u user -s secret]\n");
fprintf(stderr, " iscsictl -A -a [-c path]\n");
@@ -567,7 +625,7 @@ usage(void)
fprintf(stderr, " iscsictl -R [-p portal] [-t target]\n");
fprintf(stderr, " iscsictl -R -a\n");
fprintf(stderr, " iscsictl -R -n nickname [-c path]\n");
- fprintf(stderr, " iscsictl -L [-v]\n");
+ fprintf(stderr, " iscsictl -L [-v] [-w timeout]\n");
exit(1);
}
@@ -589,6 +647,7 @@ main(int argc, char **argv)
const char *conf_path = DEFAULT_CONFIG_PATH;
char *nickname = NULL, *discovery_host = NULL, *portal = NULL,
*target = NULL, *user = NULL, *secret = NULL;
+ int timeout = -1;
long long session_id = -1;
char *end;
int ch, error, iscsi_fd, retval, saved_errno;
@@ -596,7 +655,7 @@ main(int argc, char **argv)
struct conf *conf;
struct target *targ;
- while ((ch = getopt(argc, argv, "AMRLac:d:i:n:p:t:u:s:v")) != -1) {
+ while ((ch = getopt(argc, argv, "AMRLac:d:i:n:p:t:u:s:vw:")) != -1) {
switch (ch) {
case 'A':
Aflag = 1;
@@ -647,6 +706,13 @@ main(int argc, char **argv)
case 'v':
vflag = 1;
break;
+ case 'w':
+ timeout = strtol(optarg, &end, 10);
+ if ((size_t)(end - optarg) != strlen(optarg))
+ errx(1, "trailing characters after timeout");
+ if (timeout < 0)
+ errx(1, "timeout cannot be negative");
+ break;
case '?':
default:
usage();
@@ -737,6 +803,8 @@ main(int argc, char **argv)
if (vflag != 0)
errx(1, "-v cannot be used with -M");
+ if (timeout != -1)
+ errx(1, "-w cannot be used with -M");
} else if (Rflag != 0) {
if (user != NULL)
@@ -766,6 +834,8 @@ main(int argc, char **argv)
errx(1, "-i cannot be used with -R");
if (vflag != 0)
errx(1, "-v cannot be used with -R");
+ if (timeout != -1)
+ errx(1, "-w cannot be used with -R");
} else {
assert(Lflag != 0);
@@ -851,6 +921,9 @@ main(int argc, char **argv)
failed += kernel_list(iscsi_fd, targ, vflag);
}
+ if (timeout != -1)
+ failed += kernel_wait(iscsi_fd, timeout);
+
error = close(iscsi_fd);
if (error != 0)
err(1, "close");
OpenPOWER on IntegriCloud