From d9ff5473111291de687681e6cb34fcfe94a01f40 Mon Sep 17 00:00:00 2001 From: claudio Date: Mon, 21 Apr 2014 17:44:47 +0000 Subject: [PATCH] Cope with the iscsid changes. Makes the msg handling a lot easier. This also introduces some stuff that is work in progress. --- usr.sbin/iscsictl/iscsictl.c | 224 +++++++++++++++++++---------------- usr.sbin/iscsictl/iscsictl.h | 5 +- usr.sbin/iscsictl/parser.c | 24 +++- 3 files changed, 148 insertions(+), 105 deletions(-) diff --git a/usr.sbin/iscsictl/iscsictl.c b/usr.sbin/iscsictl/iscsictl.c index a46461aef90..07adcb262a4 100644 --- a/usr.sbin/iscsictl/iscsictl.c +++ b/usr.sbin/iscsictl/iscsictl.c @@ -1,4 +1,4 @@ -/* $OpenBSD: iscsictl.c,v 1.5 2014/04/20 22:22:18 claudio Exp $ */ +/* $OpenBSD: iscsictl.c,v 1.6 2014/04/21 17:44:47 claudio Exp $ */ /* * Copyright (c) 2010 Claudio Jeker @@ -17,6 +17,7 @@ */ #include +#include #include #include #include @@ -34,13 +35,20 @@ #include "iscsictl.h" __dead void usage(void); -void run_command(int, struct pdu *); +void run(void); +void run_command(struct pdu *); 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 *); char cbuf[CONTROL_READ_SIZE]; +struct control { + struct pduq channel; + int fd; +} control; + __dead void usage(void) { @@ -55,18 +63,13 @@ int main (int argc, char* argv[]) { struct sockaddr_un sun; + struct session_config sc; struct parse_result *res; char *confname = ISCSID_CONFIG; char *sockname = ISCSID_CONTROL; - struct pdu *pdu; - struct ctrlmsghdr *cmh; - struct session_config *sc; - struct initiator_config *ic; struct session_ctlcfg *s; struct iscsi_config *cf; - char *tname, *iname; - int ch, csock; - int *vp, val = 0; + int ch, val = 0; /* check flags */ while ((ch = getopt(argc, argv, "f:s:")) != -1) { @@ -90,14 +93,15 @@ main (int argc, char* argv[]) exit(1); /* connect to iscsid control socket */ - if ((csock = socket(AF_UNIX, SOCK_STREAM, 0)) == -1) + TAILQ_INIT(&control.channel); + if ((control.fd = socket(AF_UNIX, SOCK_SEQPACKET, 0)) == -1) err(1, "socket"); bzero(&sun, sizeof(sun)); sun.sun_family = AF_UNIX; strlcpy(sun.sun_path, sockname, sizeof(sun.sun_path)); - if (connect(csock, (struct sockaddr *)&sun, sizeof(sun)) == -1) + if (connect(control.fd, (struct sockaddr *)&sun, sizeof(sun)) == -1) err(1, "connect: %s", sockname); switch (res->action) { @@ -106,127 +110,102 @@ main (int argc, char* argv[]) val = 1; /* FALLTHROUGH */ case LOG_BRIEF: - if ((pdu = pdu_new()) == NULL) - err(1, "pdu_new"); - if ((cmh = pdu_alloc(sizeof(*cmh))) == NULL) - err(1, "pdu_alloc"); - bzero(cmh, sizeof(*cmh)); - cmh->type = CTRL_LOG_VERBOSE; - cmh->len[0] = sizeof(int); - if ((vp = pdu_dup(&val, sizeof(int))) == NULL) - err(1, "pdu_dup"); - pdu_addbuf(pdu, cmh, sizeof(*cmh), 0); - pdu_addbuf(pdu, vp, sizeof(int), 1); - run_command(csock, pdu); + if (control_compose(NULL, CTRL_LOG_VERBOSE, + &val, sizeof(int)) == -1) + err(1, "control_compose"); break; - case SHOW: case SHOW_SUM: + if (control_compose(NULL, CTRL_SHOW_SUM, NULL, 0) == -1) + err(1, "control_compose"); + break; + case SHOW_SESS: usage(); /* NOTREACHED */ case SHOW_VSCSI_STATS: - if ((pdu = pdu_new()) == NULL) - err(1, "pdu_new"); - if ((cmh = pdu_alloc(sizeof(*cmh))) == NULL) - err(1, "pdu_alloc"); - bzero(cmh, sizeof(*cmh)); - cmh->type = CTRL_VSCSI_STATS; - pdu_addbuf(pdu, cmh, sizeof(*cmh), 0); - run_command(csock, pdu); + if (control_compose(NULL, CTRL_VSCSI_STATS, NULL, 0) == -1) + err(1, "control_compose"); break; case RELOAD: if ((cf = parse_config(confname)) == NULL) errx(1, "errors while loading configuration file."); if (cf->initiator.isid_base != 0) { - if ((pdu = pdu_new()) == NULL) - err(1, "pdu_new"); - if ((cmh = pdu_alloc(sizeof(*cmh))) == NULL) - err(1, "pdu_alloc"); - bzero(cmh, sizeof(*cmh)); - cmh->type = CTRL_INITIATOR_CONFIG; - cmh->len[0] = sizeof(*ic); - if ((ic = pdu_dup(&cf->initiator, - sizeof(cf->initiator))) == NULL) - err(1, "pdu_dup"); - pdu_addbuf(pdu, cmh, sizeof(*cmh), 0); - pdu_addbuf(pdu, ic, sizeof(*ic), 1); - run_command(csock, pdu); + if (control_compose(NULL, CTRL_INITIATOR_CONFIG, + &cf->initiator, sizeof(cf->initiator)) == -1) + err(1, "control_compose"); } SIMPLEQ_FOREACH(s, &cf->sessions, entry) { - if ((pdu = pdu_new()) == NULL) - err(1, "pdu_new"); - if ((cmh = pdu_alloc(sizeof(*cmh))) == NULL) - err(1, "pdu_alloc"); - bzero(cmh, sizeof(*cmh)); - cmh->type = CTRL_SESSION_CONFIG; - cmh->len[0] = sizeof(*sc); - if ((sc = pdu_dup(&s->session, sizeof(s->session))) == - NULL) - err(1, "pdu_dup"); + struct ctrldata cdv[3]; + + bzero(cdv, sizeof(cdv)); + + cdv[0].buf = &s->session; + cdv[0].len = sizeof(s->session); + if (s->session.TargetName) { - if ((tname = pdu_dup(s->session.TargetName, - strlen(s->session.TargetName) + 1)) == - NULL) - err(1, "pdu_dup"); - cmh->len[1] = strlen(s->session.TargetName) + 1; - } else - tname = NULL; + cdv[1].buf = s->session.TargetName; + cdv[1].len = + strlen(s->session.TargetName) + 1; + } if (s->session.InitiatorName) { - if ((iname = pdu_dup(s->session.InitiatorName, - strlen(s->session.InitiatorName) + 1)) == - NULL) - err(1, "pdu_dup"); - cmh->len[2] = strlen(s->session.InitiatorName) - + 1; - } else - iname = NULL; - pdu_addbuf(pdu, cmh, sizeof(*cmh), 0); - pdu_addbuf(pdu, sc, sizeof(*sc), 1); - if (tname) - pdu_addbuf(pdu, tname, strlen(tname) + 1, 2); - if (iname) - pdu_addbuf(pdu, iname, strlen(iname) + 1, 3); - - run_command(csock, pdu); + cdv[2].buf = s->session.InitiatorName; + cdv[2].len = + strlen(s->session.InitiatorName) + 1; + } + + if (control_build(NULL, CTRL_SESSION_CONFIG, + nitems(cdv), cdv) == -1) + err(1, "control_build"); } break; case DISCOVERY: printf("discover %s\n", log_sockaddr(&res->addr)); - if ((pdu = pdu_new()) == NULL) - err(1, "pdu_new"); - if ((cmh = pdu_alloc(sizeof(*cmh))) == NULL) - err(1, "pdu_alloc"); - if ((sc = pdu_alloc(sizeof(*sc))) == NULL) - err(1, "pdu_alloc"); - bzero(cmh, sizeof(*cmh)); - bzero(sc, sizeof(*sc)); - snprintf(sc->SessionName, sizeof(sc->SessionName), + + bzero(&sc, sizeof(sc)); + snprintf(sc.SessionName, sizeof(sc.SessionName), "discovery.%d", (int)getpid()); - bcopy(&res->addr, &sc->connection.TargetAddr, res->addr.ss_len); - sc->SessionType = SESSION_TYPE_DISCOVERY; - cmh->type = CTRL_SESSION_CONFIG; - cmh->len[0] = sizeof(*sc); - pdu_addbuf(pdu, cmh, sizeof(*cmh), 0); - pdu_addbuf(pdu, sc, sizeof(*sc), 1); - - run_command(csock, pdu); + bcopy(&res->addr, &sc.connection.TargetAddr, res->addr.ss_len); + sc.SessionType = SESSION_TYPE_DISCOVERY; + + if (control_compose(NULL, CTRL_SESSION_CONFIG, + &sc, sizeof(sc)) == -1) + err(1, "control_compose"); } - close(csock); + run(); + + close(control.fd); return (0); } void -run_command(int csock, struct pdu *pdu) +control_queue(void *ch, struct pdu *pdu) +{ + TAILQ_INSERT_TAIL(&control.channel, pdu, entry); +} + +void +run(void) +{ + struct pdu *pdu; + + while ((pdu = TAILQ_FIRST(&control.channel)) != NULL) { + TAILQ_REMOVE(&control.channel, pdu, entry); + run_command(pdu); + } +} + +void +run_command(struct pdu *pdu) { struct ctrlmsghdr *cmh; int done = 0; ssize_t n; - if (ctl_sendpdu(csock, pdu) == -1) + if (ctl_sendpdu(control.fd, pdu) == -1) err(1, "send"); while (!done) { - if ((n = recv(csock, cbuf, sizeof(cbuf), 0)) == -1 && + if ((n = recv(control.fd, cbuf, sizeof(cbuf), 0)) == -1 && !(errno == EAGAIN || errno == EINTR)) err(1, "recv"); @@ -249,6 +228,10 @@ run_command(int csock, struct pdu *pdu) case CTRL_INPROGRESS: printf("command in progress...\n"); break; + case CTRL_INITIATOR_CONFIG: + case CTRL_SESSION_CONFIG: + show_config(cmh, pdu); + break; case CTRL_VSCSI_STATS: show_vscsi_stats(cmh, pdu); done = 1; @@ -324,6 +307,45 @@ ctl_sendpdu(int fd, struct pdu *pdu) return 0; } +void +show_config(struct ctrlmsghdr *cmh, struct pdu *pdu) +{ + struct initiator_config *ic; + struct session_config *sc; + + switch (cmh->type) { + case CTRL_INITIATOR_CONFIG: + if (cmh->len[0] != sizeof(*ic)) + errx(1, "bad size of response"); + ic = pdu_getbuf(pdu, NULL, 1); + if (ic == NULL) + return; + + printf("Initiator: ISID base %x qalifier %hx\n", + ic->isid_base, ic->isid_qual); + break; + case CTRL_SESSION_CONFIG: + if (cmh->len[0] != sizeof(*sc)) + errx(1, "bad size of response"); + sc = pdu_getbuf(pdu, NULL, 1); + if (sc == NULL) + return; + + printf("\nSession '%s':%s\n", sc->SessionName, + sc->disabled ? " disabled" : ""); + printf(" SessionType: %s\tMaxConnections: %hd\n", + sc->SessionType == SESSION_TYPE_DISCOVERY ? "discovery" : + "normal", sc->MaxConnections); +// printf(" InitiatorName: %s\n", sc->InitiatorName); + printf(" InitiatorAddr: %s\n", + log_sockaddr(&sc->connection.LocalAddr)); +// printf(" TargetName: %s\n", sc->TargetName); + printf(" TargetAddr: %s\n", + log_sockaddr(&sc->connection.TargetAddr)); + break; + } +} + void show_vscsi_stats(struct ctrlmsghdr *cmh, struct pdu *pdu) { @@ -332,8 +354,8 @@ show_vscsi_stats(struct ctrlmsghdr *cmh, struct pdu *pdu) if (cmh->len[0] != sizeof(struct vscsi_stats)) errx(1, "bad size of response"); vs = pdu_getbuf(pdu, NULL, 1); - if (vs == NULL) - return; + if (vs == NULL) + return; printf("VSCSI ioctl statistics:\n"); printf("%u probe calls and %u detach calls\n", diff --git a/usr.sbin/iscsictl/iscsictl.h b/usr.sbin/iscsictl/iscsictl.h index 7daeb653237..a289d83f040 100644 --- a/usr.sbin/iscsictl/iscsictl.h +++ b/usr.sbin/iscsictl/iscsictl.h @@ -1,4 +1,4 @@ -/* $OpenBSD: iscsictl.h,v 1.3 2014/04/20 22:22:18 claudio Exp $ */ +/* $OpenBSD: iscsictl.h,v 1.4 2014/04/21 17:44:47 claudio Exp $ */ /* * Copyright (c) 2009 David Gwynne @@ -32,8 +32,8 @@ enum actions { NONE, LOG_VERBOSE, LOG_BRIEF, - SHOW, SHOW_SUM, + SHOW_SESS, SHOW_VSCSI_STATS, RELOAD, DISCOVERY @@ -41,6 +41,7 @@ enum actions { struct parse_result { struct sockaddr_storage addr; + char name[32]; int flags; enum actions action; u_int8_t prefixlen; diff --git a/usr.sbin/iscsictl/parser.c b/usr.sbin/iscsictl/parser.c index b7c30c900ef..2dbde985456 100644 --- a/usr.sbin/iscsictl/parser.c +++ b/usr.sbin/iscsictl/parser.c @@ -1,4 +1,4 @@ -/* $OpenBSD: parser.c,v 1.2 2014/04/20 22:22:18 claudio Exp $ */ +/* $OpenBSD: parser.c,v 1.3 2014/04/21 17:44:47 claudio Exp $ */ /* * Copyright (c) 2004 Esben Norby @@ -40,6 +40,7 @@ enum token_type { ENDTOKEN, KEYWORD, ADDRESS, + NAME, FLAG }; @@ -54,12 +55,13 @@ static const struct token t_main[]; static const struct token t_show[]; static const struct token t_log[]; static const struct token t_discovery[]; +static const struct token t_session[]; static const struct token t_vscsi[]; static const struct token t_main[] = { {KEYWORD, "reload", RELOAD, NULL}, {KEYWORD, "discover", DISCOVERY, t_discovery}, - {KEYWORD, "show", SHOW, t_show}, + {KEYWORD, "show", SHOW_SUM, t_show}, {KEYWORD, "log", NONE, t_log}, {ENDTOKEN, "", NONE, NULL} }; @@ -67,6 +69,7 @@ static const struct token t_main[] = { static const struct token t_show[] = { {NOTOKEN, "", NONE, NULL}, {KEYWORD, "summary", SHOW_SUM, NULL}, + {KEYWORD, "session", SHOW_SESS, t_session}, {KEYWORD, "vscsi", NONE, t_vscsi}, {ENDTOKEN, "", NONE, NULL} }; @@ -82,6 +85,11 @@ static const struct token t_discovery[] = { {ENDTOKEN, "", NONE, NULL} }; +static const struct token t_session[] = { + {NAME, "", NONE, NULL}, + {ENDTOKEN, "", NONE, NULL} +}; + static const struct token t_vscsi[] = { {KEYWORD, "stats", SHOW_VSCSI_STATS, NULL}, {ENDTOKEN, "", NONE, NULL} @@ -162,6 +170,15 @@ match_token(const char *word, const struct token *table) res.action = t->value; } break; + case NAME: + if (word != NULL && strlen(word) > 0) { + if (strlcpy(res.name, word, sizeof(res.name)) >= + sizeof(res.name)) + errx(1, "name too long"); + match++; + t = &table[i]; + } + break; case ENDTOKEN: break; } @@ -197,6 +214,9 @@ show_valid_args(const struct token *table) case ADDRESS: fprintf(stderr, "
\n"); break; + case NAME: + fprintf(stderr, " \n"); + break; case ENDTOKEN: break; } -- 2.20.1