Add "iscsictl -M", which allows one to change session parameters

without removing it and adding back.

Sponsored by:	The FreeBSD Foundation
This commit is contained in:
trasz 2014-06-18 17:46:34 +00:00
parent 49d8d5028f
commit d7c1812c7a
2 changed files with 155 additions and 9 deletions

View File

@ -27,7 +27,7 @@
.\" .\"
.\" $FreeBSD$ .\" $FreeBSD$
.\" .\"
.Dd April 24, 2014 .Dd June 18, 2014
.Dt ISCSICTL 8 .Dt ISCSICTL 8
.Os .Os
.Sh NAME .Sh NAME
@ -47,6 +47,17 @@
.Fl A .Fl A
.Fl n Ar nickname Op Fl c Ar path .Fl n Ar nickname Op Fl c Ar path
.Nm .Nm
.Fl M
.Fl i Ar session-id
.Op Fl p Ar portal
.Op Fl t Ar target
.Op Fl u Ar user
.Op Fl s Ar secret
.Nm
.Fl M
.Fl i Ar session-id
.Op Fl n Ar nickname Op Fl c Ar path
.Nm
.Fl R .Fl R
.Op Fl p Ar portal .Op Fl p Ar portal
.Op Fl t Ar target .Op Fl t Ar target
@ -68,6 +79,8 @@ The following options are available:
.Bl -tag -width ".Fl A" .Bl -tag -width ".Fl A"
.It Fl A .It Fl A
Add session. Add session.
.It Fl M
Modify session.
.It Fl R .It Fl R
Remove session. Remove session.
.It Fl L .It Fl L
@ -84,6 +97,10 @@ Target host name or address used for SendTargets discovery.
When used, it will add a temporary discovery session. When used, it will add a temporary discovery session.
After discovery is done, sessions will be added for each discovered target, After discovery is done, sessions will be added for each discovered target,
and the temporary discovery sesion will be removed. and the temporary discovery sesion will be removed.
.It Fl i
Session ID, as displayed by
.Nm
.Fl v .
.It Fl n .It Fl n
The "nickname" of session defined in the configuration file. The "nickname" of session defined in the configuration file.
.It Fl p .It Fl p

View File

@ -349,6 +349,82 @@ kernel_add(int iscsi_fd, const struct target *targ)
return (error); return (error);
} }
static int
kernel_modify(int iscsi_fd, unsigned int session_id, const struct target *targ)
{
struct iscsi_session_modify ism;
int error;
memset(&ism, 0, sizeof(ism));
ism.ism_session_id = session_id;
conf_from_target(&ism.ism_conf, targ);
error = ioctl(iscsi_fd, ISCSISMODIFY, &ism);
if (error != 0)
warn("ISCSISMODIFY");
return (error);
}
static void
kernel_modify_some(int iscsi_fd, unsigned int session_id, const char *target,
const char *target_addr, const char *user, const char *secret)
{
struct iscsi_session_state *states = NULL;
struct iscsi_session_state *state;
struct iscsi_session_conf *conf;
struct iscsi_session_list isl;
struct iscsi_session_modify ism;
unsigned int i, nentries = 1;
int error;
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)
errx(1, "ISCSISLIST");
for (i = 0; i < isl.isl_nentries; i++) {
state = &states[i];
if (state->iss_id == session_id)
break;
}
if (i == isl.isl_nentries)
errx(1, "session-id %u not found", session_id);
conf = &state->iss_conf;
if (target != NULL)
strlcpy(conf->isc_target, target, sizeof(conf->isc_target));
if (target_addr != NULL)
strlcpy(conf->isc_target_addr, target_addr,
sizeof(conf->isc_target_addr));
if (user != NULL)
strlcpy(conf->isc_user, user, sizeof(conf->isc_user));
if (secret != NULL)
strlcpy(conf->isc_secret, secret, sizeof(conf->isc_secret));
memset(&ism, 0, sizeof(ism));
ism.ism_session_id = session_id;
memcpy(&ism.ism_conf, conf, sizeof(ism.ism_conf));
error = ioctl(iscsi_fd, ISCSISMODIFY, &ism);
if (error != 0)
warn("ISCSISMODIFY");
}
static int static int
kernel_remove(int iscsi_fd, const struct target *targ) kernel_remove(int iscsi_fd, const struct target *targ)
{ {
@ -404,7 +480,7 @@ kernel_list(int iscsi_fd, const struct target *targ __unused,
state = &states[i]; state = &states[i];
conf = &state->iss_conf; conf = &state->iss_conf;
printf("Session ID: %d\n", state->iss_id); printf("Session ID: %u\n", state->iss_id);
printf("Initiator name: %s\n", conf->isc_initiator); printf("Initiator name: %s\n", conf->isc_initiator);
printf("Initiator portal: %s\n", printf("Initiator portal: %s\n",
conf->isc_initiator_addr); conf->isc_initiator_addr);
@ -482,6 +558,10 @@ usage(void)
"[-u user -s secret]\n"); "[-u user -s secret]\n");
fprintf(stderr, " iscsictl -A -a [-c path]\n"); fprintf(stderr, " iscsictl -A -a [-c path]\n");
fprintf(stderr, " iscsictl -A -n nickname [-c path]\n"); fprintf(stderr, " iscsictl -A -n nickname [-c path]\n");
fprintf(stderr, " iscsictl -M -i session-id [-p portal] "
"[-t target] [-u user] [-s secret]\n");
fprintf(stderr, " iscsictl -M -i session-id -n nickname "
"[-c path]\n");
fprintf(stderr, " iscsictl -R [-p portal] [-t target]\n"); fprintf(stderr, " iscsictl -R [-p portal] [-t target]\n");
fprintf(stderr, " iscsictl -R -a\n"); fprintf(stderr, " iscsictl -R -a\n");
fprintf(stderr, " iscsictl -R -n nickname [-c path]\n"); fprintf(stderr, " iscsictl -R -n nickname [-c path]\n");
@ -503,20 +583,25 @@ checked_strdup(const char *s)
int int
main(int argc, char **argv) main(int argc, char **argv)
{ {
int Aflag = 0, Rflag = 0, Lflag = 0, aflag = 0, vflag = 0; int Aflag = 0, Mflag = 0, Rflag = 0, Lflag = 0, aflag = 0, vflag = 0;
const char *conf_path = DEFAULT_CONFIG_PATH; const char *conf_path = DEFAULT_CONFIG_PATH;
char *nickname = NULL, *discovery_host = NULL, *host = NULL, char *nickname = NULL, *discovery_host = NULL, *host = NULL,
*target = NULL, *user = NULL, *secret = NULL; *target = NULL, *user = NULL, *secret = NULL;
long long session_id = -1;
char *end;
int ch, error, iscsi_fd, retval, saved_errno; int ch, error, iscsi_fd, retval, saved_errno;
int failed = 0; int failed = 0;
struct conf *conf; struct conf *conf;
struct target *targ; struct target *targ;
while ((ch = getopt(argc, argv, "ARLac:d:n:p:t:u:s:v")) != -1) { while ((ch = getopt(argc, argv, "AMRLac:d:i:n:p:t:u:s:v")) != -1) {
switch (ch) { switch (ch) {
case 'A': case 'A':
Aflag = 1; Aflag = 1;
break; break;
case 'M':
Mflag = 1;
break;
case 'R': case 'R':
Rflag = 1; Rflag = 1;
break; break;
@ -532,6 +617,16 @@ main(int argc, char **argv)
case 'd': case 'd':
discovery_host = optarg; discovery_host = optarg;
break; break;
case 'i':
session_id = strtol(optarg, &end, 10);
if ((size_t)(end - optarg) != strlen(optarg))
errx(1, "trailing characters after session-id");
if (session_id < 0)
errx(1, "session-id cannot be negative");
if (session_id > UINT_MAX)
errx(1, "session-id cannot be greater than %u",
UINT_MAX);
break;
case 'n': case 'n':
nickname = optarg; nickname = optarg;
break; break;
@ -559,10 +654,10 @@ main(int argc, char **argv)
if (argc != 0) if (argc != 0)
usage(); usage();
if (Aflag + Rflag + Lflag == 0) if (Aflag + Mflag + Rflag + Lflag == 0)
Lflag = 1; Lflag = 1;
if (Aflag + Rflag + Lflag > 1) if (Aflag + Mflag + Rflag + Lflag > 1)
errx(1, "at most one of -A, -R, or -L may be specified"); errx(1, "at most one of -A, -M, -R, or -L may be specified");
/* /*
* Note that we ignore unneccessary/inapplicable "-c" flag; so that * Note that we ignore unneccessary/inapplicable "-c" flag; so that
@ -614,9 +709,33 @@ main(int argc, char **argv)
if (secret != NULL && user == NULL) if (secret != NULL && user == NULL)
errx(1, "-s must always be used with -u"); errx(1, "-s must always be used with -u");
if (session_id != -1)
errx(1, "-i cannot be used with -A");
if (vflag != 0) if (vflag != 0)
errx(1, "-v cannot be used with -A"); errx(1, "-v cannot be used with -A");
} else if (Mflag != 0) {
if (session_id == -1)
errx(1, "-M requires -i");
if (discovery_host != NULL)
errx(1, "-M and -d are mutually exclusive");
if (aflag != 0)
errx(1, "-M and -a are mutually exclusive");
if (nickname != NULL) {
if (host != NULL)
errx(1, "-n and -p and mutually exclusive");
if (target != NULL)
errx(1, "-n and -t and mutually exclusive");
if (user != NULL)
errx(1, "-n and -u and mutually exclusive");
if (secret != NULL)
errx(1, "-n and -s and mutually exclusive");
}
if (vflag != 0)
errx(1, "-v cannot be used with -M");
} else if (Rflag != 0) { } else if (Rflag != 0) {
if (user != NULL) if (user != NULL)
errx(1, "-R and -u are mutually exclusive"); errx(1, "-R and -u are mutually exclusive");
@ -646,6 +765,8 @@ main(int argc, char **argv)
} else } else
errx(1, "must specify either -a, -n, -t, or -p"); errx(1, "must specify either -a, -n, -t, or -p");
if (session_id != -1)
errx(1, "-i cannot be used with -R");
if (vflag != 0) if (vflag != 0)
errx(1, "-v cannot be used with -R"); errx(1, "-v cannot be used with -R");
@ -664,6 +785,9 @@ main(int argc, char **argv)
errx(1, "-L and -n and mutually exclusive"); errx(1, "-L and -n and mutually exclusive");
if (discovery_host != NULL) if (discovery_host != NULL)
errx(1, "-L and -d and mutually exclusive"); errx(1, "-L and -d and mutually exclusive");
if (session_id != -1)
errx(1, "-i cannot be used with -L");
} }
iscsi_fd = open(ISCSI_PATH, O_RDWR); iscsi_fd = open(ISCSI_PATH, O_RDWR);
@ -687,15 +811,20 @@ main(int argc, char **argv)
conf = conf_new_from_file(conf_path); conf = conf_new_from_file(conf_path);
targ = target_find(conf, nickname); targ = target_find(conf, nickname);
if (targ == NULL) if (targ == NULL)
errx(1, "target %s not found in the configuration file", errx(1, "target %s not found in %s",
nickname); nickname, conf_path);
if (Aflag != 0) if (Aflag != 0)
failed += kernel_add(iscsi_fd, targ); failed += kernel_add(iscsi_fd, targ);
else if (Mflag != 0)
failed += kernel_modify(iscsi_fd, session_id, targ);
else if (Rflag != 0) else if (Rflag != 0)
failed += kernel_remove(iscsi_fd, targ); failed += kernel_remove(iscsi_fd, targ);
else else
failed += kernel_list(iscsi_fd, targ, vflag); failed += kernel_list(iscsi_fd, targ, vflag);
} else if (Mflag != 0) {
kernel_modify_some(iscsi_fd, session_id, target, host,
user, secret);
} else { } else {
if (Aflag != 0 && target != NULL) { if (Aflag != 0 && target != NULL) {
if (valid_iscsi_name(target) == false) if (valid_iscsi_name(target) == false)