Date: Mon, 24 Nov 2014 00:47:04 +0000 (UTC) From: Alexander Motin <mav@FreeBSD.org> To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-10@freebsd.org Subject: svn commit: r274939 - stable/10/usr.sbin/ctld Message-ID: <201411240047.sAO0l4rG089198@svn.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: mav Date: Mon Nov 24 00:47:04 2014 New Revision: 274939 URL: https://svnweb.freebsd.org/changeset/base/274939 Log: MFC r273635, r273793, r274797: Add basic iSNS client to the iSCSI target. This makes ctld(8) register its iSCSI targets and portals on configured iSNS servers to allow initiators find them without active discovery. Fetching of allowed initiators from iSNS is not implemented now, so target ACLs still should be configured manually. Relnotes: Yes Sponsored by: iXsystems, Inc. Added: stable/10/usr.sbin/ctld/isns.c - copied, changed from r273635, head/usr.sbin/ctld/isns.c stable/10/usr.sbin/ctld/isns.h - copied unchanged from r273635, head/usr.sbin/ctld/isns.h Modified: stable/10/usr.sbin/ctld/Makefile stable/10/usr.sbin/ctld/ctl.conf.5 stable/10/usr.sbin/ctld/ctld.c stable/10/usr.sbin/ctld/ctld.h stable/10/usr.sbin/ctld/parse.y stable/10/usr.sbin/ctld/token.l Directory Properties: stable/10/ (props changed) Modified: stable/10/usr.sbin/ctld/Makefile ============================================================================== --- stable/10/usr.sbin/ctld/Makefile Mon Nov 24 00:34:49 2014 (r274938) +++ stable/10/usr.sbin/ctld/Makefile Mon Nov 24 00:47:04 2014 (r274939) @@ -1,7 +1,8 @@ # $FreeBSD$ PROG= ctld -SRCS= chap.c ctld.c discovery.c kernel.c keys.c log.c login.c parse.y pdu.c token.l y.tab.h +SRCS= chap.c ctld.c discovery.c isns.c kernel.c keys.c log.c +SRCS+= login.c parse.y pdu.c token.l y.tab.h CFLAGS+= -I${.CURDIR} CFLAGS+= -I${.CURDIR}/../../sys CFLAGS+= -I${.CURDIR}/../../sys/cam/ctl Modified: stable/10/usr.sbin/ctld/ctl.conf.5 ============================================================================== --- stable/10/usr.sbin/ctld/ctl.conf.5 Mon Nov 24 00:34:49 2014 (r274938) +++ stable/10/usr.sbin/ctld/ctl.conf.5 Mon Nov 24 00:47:04 2014 (r274939) @@ -27,7 +27,7 @@ .\" .\" $FreeBSD$ .\" -.Dd October 22, 2014 +.Dd October 28, 2014 .Dt CTL.CONF 5 .Os .Sh NAME @@ -106,6 +106,15 @@ The timeout for login sessions, after wh will be forcibly terminated. The default is 60. A setting of 0 disables the timeout. +.It Ic isns-server Ar address +An IPv4 or IPv6 address and optionally port of iSNS server to register on. +.It Ic isns-period Ar seconds +iSNS registration period. +Registered Network Entity not updated during this period will be unregistered. +The default is 900. +.It Ic isns-timeout Ar seconds +Timeout for iSNS requests. +The default is 5. .El .Ss auth-group Context .Bl -tag -width indent Modified: stable/10/usr.sbin/ctld/ctld.c ============================================================================== --- stable/10/usr.sbin/ctld/ctld.c Mon Nov 24 00:34:49 2014 (r274938) +++ stable/10/usr.sbin/ctld/ctld.c Mon Nov 24 00:47:04 2014 (r274939) @@ -50,6 +50,7 @@ __FBSDID("$FreeBSD$"); #include <unistd.h> #include "ctld.h" +#include "isns.h" bool proxy_mode = false; @@ -89,7 +90,10 @@ conf_new(void) TAILQ_INIT(&conf->conf_targets); TAILQ_INIT(&conf->conf_auth_groups); TAILQ_INIT(&conf->conf_portal_groups); + TAILQ_INIT(&conf->conf_isns); + conf->conf_isns_period = 900; + conf->conf_isns_timeout = 5; conf->conf_debug = 0; conf->conf_timeout = 60; conf->conf_maxproc = 30; @@ -103,6 +107,7 @@ conf_delete(struct conf *conf) struct target *targ, *tmp; struct auth_group *ag, *cagtmp; struct portal_group *pg, *cpgtmp; + struct isns *is, *istmp; assert(conf->conf_pidfh == NULL); @@ -112,6 +117,8 @@ conf_delete(struct conf *conf) auth_group_delete(ag); TAILQ_FOREACH_SAFE(pg, &conf->conf_portal_groups, pg_next, cpgtmp) portal_group_delete(pg); + TAILQ_FOREACH_SAFE(is, &conf->conf_isns, i_next, istmp) + isns_delete(is); free(conf->conf_pidfile_path); free(conf); } @@ -619,47 +626,28 @@ portal_group_find(const struct conf *con return (NULL); } -int -portal_group_add_listen(struct portal_group *pg, const char *value, bool iser) +static int +parse_addr_port(char *arg, const char *def_port, struct addrinfo **ai) { struct addrinfo hints; - struct portal *portal; - char *addr, *ch, *arg; + char *addr, *ch; const char *port; int error, colons = 0; - portal = portal_new(pg); - portal->p_listen = checked_strdup(value); - portal->p_iser = iser; - - arg = portal->p_listen; - if (arg[0] == '\0') { - log_warnx("empty listen address"); - portal_delete(portal); - return (1); - } if (arg[0] == '[') { /* * IPv6 address in square brackets, perhaps with port. */ arg++; addr = strsep(&arg, "]"); - if (arg == NULL) { - log_warnx("invalid listen address %s", - portal->p_listen); - portal_delete(portal); + if (arg == NULL) return (1); - } if (arg[0] == '\0') { - port = "3260"; + port = def_port; } else if (arg[0] == ':') { port = arg + 1; - } else { - log_warnx("invalid listen address %s", - portal->p_listen); - portal_delete(portal); + } else return (1); - } } else { /* * Either IPv6 address without brackets - and without @@ -671,11 +659,11 @@ portal_group_add_listen(struct portal_gr } if (colons > 1) { addr = arg; - port = "3260"; + port = def_port; } else { addr = strsep(&arg, ":"); if (arg == NULL) - port = "3260"; + port = def_port; else port = arg; } @@ -685,11 +673,23 @@ portal_group_add_listen(struct portal_gr hints.ai_family = PF_UNSPEC; hints.ai_socktype = SOCK_STREAM; hints.ai_flags = AI_PASSIVE; + error = getaddrinfo(addr, port, &hints, ai); + if (error != 0) + return (1); + return (0); +} - error = getaddrinfo(addr, port, &hints, &portal->p_ai); - if (error != 0) { - log_warnx("getaddrinfo for %s failed: %s", - portal->p_listen, gai_strerror(error)); +int +portal_group_add_listen(struct portal_group *pg, const char *value, bool iser) +{ + struct portal *portal; + + portal = portal_new(pg); + portal->p_listen = checked_strdup(value); + portal->p_iser = iser; + + if (parse_addr_port(portal->p_listen, "3260", &portal->p_ai)) { + log_warnx("invalid listen address %s", portal->p_listen); portal_delete(portal); return (1); } @@ -702,6 +702,258 @@ portal_group_add_listen(struct portal_gr return (0); } +int +isns_new(struct conf *conf, const char *addr) +{ + struct isns *isns; + + isns = calloc(1, sizeof(*isns)); + if (isns == NULL) + log_err(1, "calloc"); + isns->i_conf = conf; + TAILQ_INSERT_TAIL(&conf->conf_isns, isns, i_next); + isns->i_addr = checked_strdup(addr); + + if (parse_addr_port(isns->i_addr, "3205", &isns->i_ai)) { + log_warnx("invalid iSNS address %s", isns->i_addr); + isns_delete(isns); + return (1); + } + + /* + * XXX: getaddrinfo(3) may return multiple addresses; we should turn + * those into multiple servers. + */ + + return (0); +} + +void +isns_delete(struct isns *isns) +{ + + TAILQ_REMOVE(&isns->i_conf->conf_isns, isns, i_next); + free(isns->i_addr); + if (isns->i_ai != NULL) + freeaddrinfo(isns->i_ai); + free(isns); +} + +static int +isns_do_connect(struct isns *isns) +{ + int s; + + s = socket(isns->i_ai->ai_family, isns->i_ai->ai_socktype, + isns->i_ai->ai_protocol); + if (s < 0) { + log_warn("socket(2) failed for %s", isns->i_addr); + return (-1); + } + if (connect(s, isns->i_ai->ai_addr, isns->i_ai->ai_addrlen)) { + log_warn("connect(2) failed for %s", isns->i_addr); + close(s); + return (-1); + } + return(s); +} + +static int +isns_do_register(struct isns *isns, int s, const char *hostname) +{ + struct conf *conf = isns->i_conf; + struct target *target; + struct portal *portal; + struct portal_group *pg; + struct isns_req *req; + int res = 0; + uint32_t error; + + req = isns_req_create(ISNS_FUNC_DEVATTRREG, ISNS_FLAG_CLIENT); + isns_req_add_str(req, 32, TAILQ_FIRST(&conf->conf_targets)->t_name); + isns_req_add_delim(req); + isns_req_add_str(req, 1, hostname); + isns_req_add_32(req, 2, 2); /* 2 -- iSCSI */ + isns_req_add_32(req, 6, conf->conf_isns_period); + TAILQ_FOREACH(pg, &conf->conf_portal_groups, pg_next) { + if (pg->pg_unassigned) + continue; + TAILQ_FOREACH(portal, &pg->pg_portals, p_next) { + isns_req_add_addr(req, 16, portal->p_ai); + isns_req_add_port(req, 17, portal->p_ai); + } + } + TAILQ_FOREACH(target, &conf->conf_targets, t_next) { + isns_req_add_str(req, 32, target->t_name); + isns_req_add_32(req, 33, 1); /* 1 -- Target*/ + if (target->t_alias != NULL) + isns_req_add_str(req, 34, target->t_alias); + pg = target->t_portal_group; + isns_req_add_32(req, 51, pg->pg_tag); + TAILQ_FOREACH(portal, &pg->pg_portals, p_next) { + isns_req_add_addr(req, 49, portal->p_ai); + isns_req_add_port(req, 50, portal->p_ai); + } + } + res = isns_req_send(s, req); + if (res < 0) { + log_warn("send(2) failed for %s", isns->i_addr); + goto quit; + } + res = isns_req_receive(s, req); + if (res < 0) { + log_warn("receive(2) failed for %s", isns->i_addr); + goto quit; + } + error = isns_req_get_status(req); + if (error != 0) { + log_warnx("iSNS register error %d for %s", error, isns->i_addr); + res = -1; + } +quit: + isns_req_free(req); + return (res); +} + +static int +isns_do_check(struct isns *isns, int s, const char *hostname) +{ + struct conf *conf = isns->i_conf; + struct isns_req *req; + int res = 0; + uint32_t error; + + req = isns_req_create(ISNS_FUNC_DEVATTRQRY, ISNS_FLAG_CLIENT); + isns_req_add_str(req, 32, TAILQ_FIRST(&conf->conf_targets)->t_name); + isns_req_add_str(req, 1, hostname); + isns_req_add_delim(req); + isns_req_add(req, 2, 0, NULL); + res = isns_req_send(s, req); + if (res < 0) { + log_warn("send(2) failed for %s", isns->i_addr); + goto quit; + } + res = isns_req_receive(s, req); + if (res < 0) { + log_warn("receive(2) failed for %s", isns->i_addr); + goto quit; + } + error = isns_req_get_status(req); + if (error != 0) { + log_warnx("iSNS check error %d for %s", error, isns->i_addr); + res = -1; + } +quit: + isns_req_free(req); + return (res); +} + +static int +isns_do_deregister(struct isns *isns, int s, const char *hostname) +{ + struct conf *conf = isns->i_conf; + struct isns_req *req; + int res = 0; + uint32_t error; + + req = isns_req_create(ISNS_FUNC_DEVDEREG, ISNS_FLAG_CLIENT); + isns_req_add_str(req, 32, TAILQ_FIRST(&conf->conf_targets)->t_name); + isns_req_add_delim(req); + isns_req_add_str(req, 1, hostname); + res = isns_req_send(s, req); + if (res < 0) { + log_warn("send(2) failed for %s", isns->i_addr); + goto quit; + } + res = isns_req_receive(s, req); + if (res < 0) { + log_warn("receive(2) failed for %s", isns->i_addr); + goto quit; + } + error = isns_req_get_status(req); + if (error != 0) { + log_warnx("iSNS deregister error %d for %s", error, isns->i_addr); + res = -1; + } +quit: + isns_req_free(req); + return (res); +} + +void +isns_register(struct isns *isns, struct isns *oldisns) +{ + struct conf *conf = isns->i_conf; + int s, res; + char hostname[256]; + + if (TAILQ_EMPTY(&conf->conf_targets) || + TAILQ_EMPTY(&conf->conf_portal_groups)) + return; + set_timeout(conf->conf_isns_timeout, false); + s = isns_do_connect(isns); + if (s < 0) { + set_timeout(0, false); + return; + } + gethostname(hostname, sizeof(hostname)); + + if (oldisns == NULL || TAILQ_EMPTY(&oldisns->i_conf->conf_targets)) + oldisns = isns; + res = isns_do_deregister(oldisns, s, hostname); + res = isns_do_register(isns, s, hostname); + close(s); + set_timeout(0, false); +} + +void +isns_check(struct isns *isns) +{ + struct conf *conf = isns->i_conf; + int s, res; + char hostname[256]; + + if (TAILQ_EMPTY(&conf->conf_targets) || + TAILQ_EMPTY(&conf->conf_portal_groups)) + return; + set_timeout(conf->conf_isns_timeout, false); + s = isns_do_connect(isns); + if (s < 0) { + set_timeout(0, false); + return; + } + gethostname(hostname, sizeof(hostname)); + + res = isns_do_check(isns, s, hostname); + if (res < 0) { + res = isns_do_deregister(isns, s, hostname); + res = isns_do_register(isns, s, hostname); + } + close(s); + set_timeout(0, false); +} + +void +isns_deregister(struct isns *isns) +{ + struct conf *conf = isns->i_conf; + int s, res; + char hostname[256]; + + if (TAILQ_EMPTY(&conf->conf_targets) || + TAILQ_EMPTY(&conf->conf_portal_groups)) + return; + set_timeout(conf->conf_isns_timeout, false); + s = isns_do_connect(isns); + if (s < 0) + return; + gethostname(hostname, sizeof(hostname)); + + res = isns_do_deregister(isns, s, hostname); + close(s); + set_timeout(0, false); +} + static bool valid_hex(const char ch) { @@ -1251,6 +1503,7 @@ conf_apply(struct conf *oldconf, struct struct lun *oldlun, *newlun, *tmplun; struct portal_group *oldpg, *newpg; struct portal *oldp, *newp; + struct isns *oldns, *newns; pid_t otherpid; int changed, cumulated_error = 0, error; int one = 1; @@ -1288,6 +1541,16 @@ conf_apply(struct conf *oldconf, struct } } + /* Deregister on removed iSNS servers. */ + TAILQ_FOREACH(oldns, &oldconf->conf_isns, i_next) { + TAILQ_FOREACH(newns, &newconf->conf_isns, i_next) { + if (strcmp(oldns->i_addr, newns->i_addr) == 0) + break; + } + if (newns == NULL) + isns_deregister(oldns); + } + /* * XXX: If target or lun removal fails, we should somehow "move" * the old lun or target into newconf, so that subsequent @@ -1317,10 +1580,8 @@ conf_apply(struct conf *oldconf, struct oldlun->l_ctl_lun); cumulated_error++; } - lun_delete(oldlun); } kernel_port_remove(oldtarg); - target_delete(oldtarg); continue; } @@ -1343,7 +1604,6 @@ conf_apply(struct conf *oldconf, struct oldlun->l_ctl_lun); cumulated_error++; } - lun_delete(oldlun); continue; } @@ -1569,6 +1829,19 @@ conf_apply(struct conf *oldconf, struct } } + /* (Re-)Register on remaining/new iSNS servers. */ + TAILQ_FOREACH(newns, &newconf->conf_isns, i_next) { + TAILQ_FOREACH(oldns, &oldconf->conf_isns, i_next) { + if (strcmp(oldns->i_addr, newns->i_addr) == 0) + break; + } + isns_register(newns, oldns); + } + + /* Schedule iSNS update */ + if (!TAILQ_EMPTY(&newconf->conf_isns)) + set_timeout((newconf->conf_isns_period + 2) / 3, false); + return (cumulated_error); } @@ -1580,7 +1853,7 @@ timed_out(void) } static void -sigalrm_handler(int dummy __unused) +sigalrm_handler_fatal(int dummy __unused) { /* * It would be easiest to just log an error and exit. We can't @@ -1600,19 +1873,35 @@ sigalrm_handler(int dummy __unused) } static void -set_timeout(const struct conf *conf) +sigalrm_handler(int dummy __unused) +{ + + sigalrm_received = true; +} + +void +set_timeout(int timeout, int fatal) { struct sigaction sa; struct itimerval itv; int error; - if (conf->conf_timeout <= 0) { + if (timeout <= 0) { log_debugx("session timeout disabled"); + bzero(&itv, sizeof(itv)); + error = setitimer(ITIMER_REAL, &itv, NULL); + if (error != 0) + log_err(1, "setitimer"); + sigalrm_received = false; return; } + sigalrm_received = false; bzero(&sa, sizeof(sa)); - sa.sa_handler = sigalrm_handler; + if (fatal) + sa.sa_handler = sigalrm_handler_fatal; + else + sa.sa_handler = sigalrm_handler; sigfillset(&sa.sa_mask); error = sigaction(SIGALRM, &sa, NULL); if (error != 0) @@ -1622,12 +1911,10 @@ set_timeout(const struct conf *conf) * First SIGALRM will arive after conf_timeout seconds. * If we do nothing, another one will arrive a second later. */ + log_debugx("setting session timeout to %d seconds", timeout); bzero(&itv, sizeof(itv)); itv.it_interval.tv_sec = 1; - itv.it_value.tv_sec = conf->conf_timeout; - - log_debugx("setting session timeout to %d seconds", - conf->conf_timeout); + itv.it_value.tv_sec = timeout; error = setitimer(ITIMER_REAL, &itv, NULL); if (error != 0) log_err(1, "setitimer"); @@ -1713,7 +2000,7 @@ handle_connection(struct portal *portal, setproctitle("%s", host); conn = connection_new(portal, fd, host, client_sa); - set_timeout(conf); + set_timeout(conf->conf_timeout, true); kernel_capsicate(); login(conn); if (conn->conn_session_type == CONN_SESSION_TYPE_NORMAL) { @@ -1760,7 +2047,7 @@ main_loop(struct conf *conf, bool dont_f pidfile_write(conf->conf_pidfh); for (;;) { - if (sighup_received || sigterm_received) + if (sighup_received || sigterm_received || timed_out()) return; #ifdef ICL_KERNEL_PROXY @@ -1884,6 +2171,7 @@ int main(int argc, char **argv) { struct conf *oldconf, *newconf, *tmpconf; + struct isns *newns; const char *config_path = DEFAULT_CONFIG_PATH; int debug = 0, ch, error; bool dont_daemonize = false; @@ -1943,6 +2231,10 @@ main(int argc, char **argv) } } + /* Schedule iSNS update */ + if (!TAILQ_EMPTY(&newconf->conf_isns)) + set_timeout((newconf->conf_isns_period + 2) / 3, false); + for (;;) { main_loop(newconf, dont_daemonize); if (sighup_received) { @@ -1978,12 +2270,25 @@ main(int argc, char **argv) error = conf_apply(oldconf, newconf); if (error != 0) log_warnx("failed to apply configuration"); + conf_delete(oldconf); + oldconf = NULL; log_warnx("exiting on signal"); exit(0); } else { nchildren -= wait_for_children(false); assert(nchildren >= 0); + if (timed_out()) { + set_timeout(0, false); + TAILQ_FOREACH(newns, &newconf->conf_isns, i_next) + isns_check(newns); + /* Schedule iSNS update */ + if (!TAILQ_EMPTY(&newconf->conf_isns)) { + set_timeout((newconf->conf_isns_period + + 2) / 3, + false); + } + } } } /* NOTREACHED */ Modified: stable/10/usr.sbin/ctld/ctld.h ============================================================================== --- stable/10/usr.sbin/ctld/ctld.h Mon Nov 24 00:34:49 2014 (r274938) +++ stable/10/usr.sbin/ctld/ctld.h Mon Nov 24 00:47:04 2014 (r274939) @@ -146,11 +146,21 @@ struct target { char *t_alias; }; +struct isns { + TAILQ_ENTRY(isns) i_next; + struct conf *i_conf; + char *i_addr; + struct addrinfo *i_ai; +}; + struct conf { char *conf_pidfile_path; TAILQ_HEAD(, target) conf_targets; TAILQ_HEAD(, auth_group) conf_auth_groups; TAILQ_HEAD(, portal_group) conf_portal_groups; + TAILQ_HEAD(, isns) conf_isns; + int conf_isns_period; + int conf_isns_timeout; int conf_debug; int conf_timeout; int conf_maxproc; @@ -277,6 +287,12 @@ struct portal_group *portal_group_find(c int portal_group_add_listen(struct portal_group *pg, const char *listen, bool iser); +int isns_new(struct conf *conf, const char *addr); +void isns_delete(struct isns *is); +void isns_register(struct isns *isns, struct isns *oldisns); +void isns_check(struct isns *isns); +void isns_deregister(struct isns *isns); + struct target *target_new(struct conf *conf, const char *name); void target_delete(struct target *target); struct target *target_find(struct conf *conf, @@ -354,6 +370,7 @@ void log_debugx(const char *, ...) __p char *checked_strdup(const char *); bool valid_iscsi_name(const char *name); +void set_timeout(int timeout, int fatal); bool timed_out(void); #endif /* !CTLD_H */ Copied and modified: stable/10/usr.sbin/ctld/isns.c (from r273635, head/usr.sbin/ctld/isns.c) ============================================================================== --- head/usr.sbin/ctld/isns.c Sat Oct 25 12:50:26 2014 (r273635, copy source) +++ stable/10/usr.sbin/ctld/isns.c Mon Nov 24 00:47:04 2014 (r274939) @@ -63,7 +63,7 @@ isns_req_alloc(void) req->ir_buflen = sizeof(struct isns_hdr); req->ir_usedlen = 0; req->ir_buf = calloc(req->ir_buflen, 1); - if (req == NULL) { + if (req->ir_buf == NULL) { free(req); log_err(1, "calloc"); return (NULL); Copied: stable/10/usr.sbin/ctld/isns.h (from r273635, head/usr.sbin/ctld/isns.h) ============================================================================== --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ stable/10/usr.sbin/ctld/isns.h Mon Nov 24 00:47:04 2014 (r274939, copy of r273635, head/usr.sbin/ctld/isns.h) @@ -0,0 +1,92 @@ +/*- + * Copyright (c) 2014 Alexander Motin <mav@FreeBSD.org> + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $FreeBSD$ + */ + +#ifndef _ISNS_H +#define _ISNS_H + +#define ISNS_VERSION 0x0001 + +#define ISNS_FUNC_DEVATTRREG 0x0001 +#define ISNS_FUNC_DEVATTRQRY 0x0002 +#define ISNS_FUNC_DEVGETNEXT 0x0003 +#define ISNS_FUNC_DEVDEREG 0x0004 +#define ISNS_FUNC_SCNREG 0x0005 +#define ISNS_FUNC_SCNDEREG 0x0006 +#define ISNS_FUNC_SCNEVENT 0x0007 +#define ISNS_FUNC_SCN 0x0008 +#define ISNS_FUNC_DDREG 0x0009 +#define ISNS_FUNC_DDDEREG 0x000a +#define ISNS_FUNC_DDSREG 0x000b +#define ISNS_FUNC_DDSDEREG 0x000c +#define ISNS_FUNC_ESI 0x000d +#define ISNS_FUNC_HEARTBEAT 0x000e +#define ISNS_FUNC_RESPONSE 0x8000 + +#define ISNS_FLAG_CLIENT 0x8000 +#define ISNS_FLAG_SERVER 0x4000 +#define ISNS_FLAG_AUTH 0x2000 +#define ISNS_FLAG_REPLACE 0x1000 +#define ISNS_FLAG_LAST 0x0800 +#define ISNS_FLAG_FIRST 0x0400 + +struct isns_hdr { + uint8_t ih_version[2]; + uint8_t ih_function[2]; + uint8_t ih_length[2]; + uint8_t ih_flags[2]; + uint8_t ih_transaction[2]; + uint8_t ih_sequence[2]; +}; + +struct isns_tlv { + uint8_t it_tag[4]; + uint8_t it_length[4]; + uint8_t it_value[]; +}; + +struct isns_req { + u_int ir_buflen; + u_int ir_usedlen; + uint8_t *ir_buf; +}; + +struct isns_req * isns_req_alloc(void); +struct isns_req * isns_req_create(uint16_t func, uint16_t flags); +void isns_req_free(struct isns_req *req); +void isns_req_add(struct isns_req *req, uint32_t tag, uint32_t len, + const void *value); +void isns_req_add_delim(struct isns_req *req); +void isns_req_add_str(struct isns_req *req, uint32_t tag, const char *value); +void isns_req_add_32(struct isns_req *req, uint32_t tag, uint32_t value); +void isns_req_add_addr(struct isns_req *req, uint32_t tag, struct addrinfo *ai); +void isns_req_add_port(struct isns_req *req, uint32_t tag, struct addrinfo *ai); +int isns_req_send(int s, struct isns_req *req); +int isns_req_receive(int s, struct isns_req *req); +uint32_t isns_req_get_status(struct isns_req *req); + +#endif /* _ISNS_H */ Modified: stable/10/usr.sbin/ctld/parse.y ============================================================================== --- stable/10/usr.sbin/ctld/parse.y Mon Nov 24 00:34:49 2014 (r274938) +++ stable/10/usr.sbin/ctld/parse.y Mon Nov 24 00:47:04 2014 (r274939) @@ -61,6 +61,7 @@ extern void yyrestart(FILE *); %token CLOSING_BRACKET DEBUG DEVICE_ID DISCOVERY_AUTH_GROUP INITIATOR_NAME %token INITIATOR_PORTAL LISTEN LISTEN_ISER LUN MAXPROC NUM OPENING_BRACKET %token OPTION PATH PIDFILE PORTAL_GROUP SERIAL SIZE STR TARGET TIMEOUT +%token ISNS_SERVER ISNS_PERIOD ISNS_TIMEOUT %union { @@ -87,6 +88,12 @@ statement: | pidfile | + isns_server + | + isns_period + | + isns_timeout + | auth_group | portal_group @@ -123,6 +130,29 @@ pidfile: PIDFILE STR } ; +isns_server: ISNS_SERVER STR + { + int error; + + error = isns_new(conf, $2); + free($2); + if (error != 0) + return (1); + } + ; + +isns_period: ISNS_PERIOD NUM + { + conf->conf_isns_period = $2; + } + ; + +isns_timeout: ISNS_TIMEOUT NUM + { + conf->conf_isns_timeout = $2; + } + ; + auth_group: AUTH_GROUP auth_group_name OPENING_BRACKET auth_group_entries CLOSING_BRACKET { Modified: stable/10/usr.sbin/ctld/token.l ============================================================================== --- stable/10/usr.sbin/ctld/token.l Mon Nov 24 00:34:49 2014 (r274938) +++ stable/10/usr.sbin/ctld/token.l Mon Nov 24 00:47:04 2014 (r274939) @@ -67,6 +67,9 @@ maxproc { return MAXPROC; } option { return OPTION; } path { return PATH; } pidfile { return PIDFILE; } +isns-server { return ISNS_SERVER; } +isns-period { return ISNS_PERIOD; } +isns-timeout { return ISNS_TIMEOUT; } portal-group { return PORTAL_GROUP; } serial { return SERIAL; } size { return SIZE; }
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201411240047.sAO0l4rG089198>