Add support for multiple portal groups per target.

This change allows multiple "portal-group" options to be specified per
target.  Each of them may include new optional auth-group name parameter
to override per-target auth parameters for specific portal group.

Kernel side support was added earlier at r278161.

MFC after:	2 weeks
Sponsored by:	iXsystems, Inc.
This commit is contained in:
Alexander Motin 2015-02-06 17:43:13 +00:00
parent c869aa71f0
commit 92847ee1f3
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=278322
7 changed files with 278 additions and 110 deletions

View File

@ -27,7 +27,7 @@
.\"
.\" $FreeBSD$
.\"
.Dd February 1, 2015
.Dd February 6, 2015
.Dt CTL.CONF 5
.Os
.Sh NAME
@ -66,7 +66,7 @@ file is:
.No target Ar name {
.Dl auth-group Ar name
.Dl portal-group Ar name
.Dl portal-group Ar name Op Ar agname
.Dl lun Ar number Ar name
.Dl lun Ar number No {
.Dl path Ar path
@ -310,12 +310,15 @@ This clause is mutually exclusive with
.Sy auth-group ;
one cannot use
both in a single target.
.It Ic portal-group Ar name
.It Ic portal-group Ar name Op Ar agname
Assign a previously defined portal group to the target.
The default portal group is
.Qq Ar default ,
which makes the target available
on TCP port 3260 on all configured IPv4 and IPv6 addresses.
Optional second argument specifies auth group name for connections
to this specific portal group.
If second argument is not specified, target auth group is used.
.It Ic redirect Aq Ar address
IPv4 or IPv6 address to redirect initiators to.
When configured, all initiators attempting to connect to this target

View File

@ -91,6 +91,7 @@ conf_new(void)
TAILQ_INIT(&conf->conf_luns);
TAILQ_INIT(&conf->conf_targets);
TAILQ_INIT(&conf->conf_auth_groups);
TAILQ_INIT(&conf->conf_ports);
TAILQ_INIT(&conf->conf_portal_groups);
TAILQ_INIT(&conf->conf_isns);
@ -124,6 +125,7 @@ conf_delete(struct conf *conf)
portal_group_delete(pg);
TAILQ_FOREACH_SAFE(is, &conf->conf_isns, i_next, istmp)
isns_delete(is);
assert(TAILQ_EMPTY(&conf->conf_ports));
free(conf->conf_pidfile_path);
free(conf);
}
@ -609,6 +611,7 @@ portal_group_new(struct conf *conf, const char *name)
log_err(1, "calloc");
pg->pg_name = checked_strdup(name);
TAILQ_INIT(&pg->pg_portals);
TAILQ_INIT(&pg->pg_ports);
pg->pg_conf = conf;
pg->pg_tag = 0; /* Assigned later in conf_apply(). */
TAILQ_INSERT_TAIL(&conf->conf_portal_groups, pg, pg_next);
@ -620,7 +623,10 @@ void
portal_group_delete(struct portal_group *pg)
{
struct portal *portal, *tmp;
struct port *port, *tport;
TAILQ_FOREACH_SAFE(port, &pg->pg_ports, p_pgs, tport)
port_delete(port);
TAILQ_REMOVE(&pg->pg_conf->conf_portal_groups, pg, pg_next);
TAILQ_FOREACH_SAFE(portal, &pg->pg_portals, p_next, tmp)
@ -784,6 +790,7 @@ isns_do_register(struct isns *isns, int s, const char *hostname)
struct target *target;
struct portal *portal;
struct portal_group *pg;
struct port *port;
struct isns_req *req;
int res = 0;
uint32_t error;
@ -807,11 +814,14 @@ isns_do_register(struct isns *isns, int s, const char *hostname)
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);
TAILQ_FOREACH(port, &target->t_ports, p_ts) {
if ((pg = port->p_portal_group) == NULL)
continue;
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);
@ -1123,6 +1133,68 @@ valid_iscsi_name(const char *name)
return (true);
}
struct port *
port_new(struct conf *conf, struct target *target, struct portal_group *pg)
{
struct port *port;
port = calloc(1, sizeof(*port));
if (port == NULL)
log_err(1, "calloc");
asprintf(&port->p_name, "%s-%s", pg->pg_name, target->t_name);
if (port_find(conf, port->p_name) != NULL) {
log_warnx("duplicate port \"%s\"", port->p_name);
free(port);
return (NULL);
}
port->p_conf = conf;
TAILQ_INSERT_TAIL(&conf->conf_ports, port, p_next);
TAILQ_INSERT_TAIL(&target->t_ports, port, p_ts);
port->p_target = target;
TAILQ_INSERT_TAIL(&pg->pg_ports, port, p_pgs);
port->p_portal_group = pg;
return (port);
}
struct port *
port_find(const struct conf *conf, const char *name)
{
struct port *port;
TAILQ_FOREACH(port, &conf->conf_ports, p_next) {
if (strcasecmp(port->p_name, name) == 0)
return (port);
}
return (NULL);
}
struct port *
port_find_in_pg(const struct portal_group *pg, const char *target)
{
struct port *port;
TAILQ_FOREACH(port, &pg->pg_ports, p_pgs) {
if (strcasecmp(port->p_target->t_name, target) == 0)
return (port);
}
return (NULL);
}
void
port_delete(struct port *port)
{
if (port->p_portal_group)
TAILQ_REMOVE(&port->p_portal_group->pg_ports, port, p_pgs);
if (port->p_target)
TAILQ_REMOVE(&port->p_target->t_ports, port, p_ts);
TAILQ_REMOVE(&port->p_conf->conf_ports, port, p_next);
free(port->p_name);
free(port);
}
struct target *
target_new(struct conf *conf, const char *name)
{
@ -1151,6 +1223,7 @@ target_new(struct conf *conf, const char *name)
targ->t_name[i] = tolower(targ->t_name[i]);
targ->t_conf = conf;
TAILQ_INIT(&targ->t_ports);
TAILQ_INSERT_TAIL(&conf->conf_targets, targ, t_next);
return (targ);
@ -1159,7 +1232,10 @@ target_new(struct conf *conf, const char *name)
void
target_delete(struct target *targ)
{
struct port *port, *tport;
TAILQ_FOREACH_SAFE(port, &targ->t_ports, p_ts, tport)
port_delete(port);
TAILQ_REMOVE(&targ->t_conf->conf_targets, targ, t_next);
free(targ->t_name);
@ -1196,13 +1272,6 @@ target_set_redirection(struct target *target, const char *addr)
return (0);
}
void
target_set_ctl_port(struct target *target, uint32_t value)
{
target->t_ctl_port = value;
}
struct lun *
lun_new(struct conf *conf, const char *name)
{
@ -1508,6 +1577,7 @@ conf_verify(struct conf *conf)
{
struct auth_group *ag;
struct portal_group *pg;
struct port *port;
struct target *targ;
struct lun *lun;
bool found;
@ -1527,10 +1597,10 @@ conf_verify(struct conf *conf)
"default");
assert(targ->t_auth_group != NULL);
}
if (targ->t_portal_group == NULL) {
targ->t_portal_group = portal_group_find(conf,
"default");
assert(targ->t_portal_group != NULL);
if (TAILQ_EMPTY(&targ->t_ports)) {
pg = portal_group_find(conf, "default");
assert(pg != NULL);
port_new(conf, targ, pg);
}
found = false;
for (i = 0; i < MAX_LUNS; i++) {
@ -1558,20 +1628,14 @@ conf_verify(struct conf *conf)
if (pg->pg_discovery_filter == PG_FILTER_UNKNOWN)
pg->pg_discovery_filter = PG_FILTER_NONE;
TAILQ_FOREACH(targ, &conf->conf_targets, t_next) {
if (targ->t_portal_group == pg)
break;
}
if (pg->pg_redirection != NULL) {
if (targ != NULL) {
if (!TAILQ_EMPTY(&pg->pg_ports)) {
if (pg->pg_redirection != NULL) {
log_debugx("portal-group \"%s\" assigned "
"to target \"%s\", but configured "
"to target, but configured "
"for redirection",
pg->pg_name, targ->t_name);
pg->pg_name);
}
pg->pg_unassigned = false;
} else if (targ != NULL) {
pg->pg_unassigned = false;
} else {
if (strcmp(pg->pg_name, "default") != 0)
log_warnx("portal-group \"%s\" not assigned "
@ -1592,6 +1656,12 @@ conf_verify(struct conf *conf)
break;
}
}
TAILQ_FOREACH(port, &conf->conf_ports, p_next) {
if (port->p_auth_group == ag) {
found = true;
break;
}
}
TAILQ_FOREACH(pg, &conf->conf_portal_groups, pg_next) {
if (pg->pg_discovery_auth_group == ag) {
found = true;
@ -1613,10 +1683,10 @@ conf_verify(struct conf *conf)
static int
conf_apply(struct conf *oldconf, struct conf *newconf)
{
struct target *oldtarg, *newtarg, *tmptarg;
struct lun *oldlun, *newlun, *tmplun;
struct portal_group *oldpg, *newpg;
struct portal *oldp, *newp;
struct port *oldport, *newport, *tmpport;
struct isns *oldns, *newns;
pid_t otherpid;
int changed, cumulated_error = 0, error, sockbuf;
@ -1684,17 +1754,17 @@ conf_apply(struct conf *oldconf, struct conf *newconf)
* really happen, so leave it as it is for now.
*/
/*
* First, remove any targets present in the old configuration
* First, remove any ports present in the old configuration
* and missing in the new one.
*/
TAILQ_FOREACH_SAFE(oldtarg, &oldconf->conf_targets, t_next, tmptarg) {
newtarg = target_find(newconf, oldtarg->t_name);
if (newtarg != NULL)
TAILQ_FOREACH_SAFE(oldport, &oldconf->conf_ports, p_next, tmpport) {
newport = port_find(newconf, oldport->p_name);
if (newport != NULL)
continue;
error = kernel_port_remove(oldtarg);
error = kernel_port_remove(oldport);
if (error != 0) {
log_warnx("failed to remove target %s",
oldtarg->t_name);
log_warnx("failed to remove port %s",
oldport->p_name);
/*
* XXX: Uncomment after fixing the root cause.
*
@ -1809,21 +1879,21 @@ conf_apply(struct conf *oldconf, struct conf *newconf)
}
/*
* Now add new targets or modify existing ones.
* Now add new ports or modify existing ones.
*/
TAILQ_FOREACH(newtarg, &newconf->conf_targets, t_next) {
oldtarg = target_find(oldconf, newtarg->t_name);
TAILQ_FOREACH(newport, &newconf->conf_ports, p_next) {
oldport = port_find(oldconf, newport->p_name);
if (oldtarg == NULL)
error = kernel_port_add(newtarg);
else {
target_set_ctl_port(newtarg, oldtarg->t_ctl_port);
error = kernel_port_update(newtarg);
if (oldport == NULL) {
error = kernel_port_add(newport);
} else {
newport->p_ctl_port = oldport->p_ctl_port;
error = kernel_port_update(newport);
}
if (error != 0) {
log_warnx("failed to %s target %s",
(oldtarg == NULL) ? "add" : "update",
newtarg->t_name);
log_warnx("failed to %s port %s",
(oldport == NULL) ? "add" : "update",
newport->p_name);
/*
* XXX: Uncomment after fixing the root cause.
*

View File

@ -119,11 +119,25 @@ struct portal_group {
int pg_discovery_filter;
bool pg_unassigned;
TAILQ_HEAD(, portal) pg_portals;
TAILQ_HEAD(, port) pg_ports;
char *pg_redirection;
uint16_t pg_tag;
};
struct port {
TAILQ_ENTRY(port) p_next;
TAILQ_ENTRY(port) p_pgs;
TAILQ_ENTRY(port) p_ts;
struct conf *p_conf;
char *p_name;
struct auth_group *p_auth_group;
struct portal_group *p_portal_group;
struct target *p_target;
uint32_t p_ctl_port;
};
struct lun_option {
TAILQ_ENTRY(lun_option) lo_next;
struct lun *lo_lun;
@ -152,12 +166,10 @@ struct target {
struct conf *t_conf;
struct lun *t_luns[MAX_LUNS];
struct auth_group *t_auth_group;
struct portal_group *t_portal_group;
TAILQ_HEAD(, port) t_ports;
char *t_name;
char *t_alias;
char *t_redirection;
uint32_t t_ctl_port;
};
struct isns {
@ -172,6 +184,7 @@ struct conf {
TAILQ_HEAD(, lun) conf_luns;
TAILQ_HEAD(, target) conf_targets;
TAILQ_HEAD(, auth_group) conf_auth_groups;
TAILQ_HEAD(, port) conf_ports;
TAILQ_HEAD(, portal_group) conf_portal_groups;
TAILQ_HEAD(, isns) conf_isns;
int conf_isns_period;
@ -199,6 +212,7 @@ struct conf {
struct connection {
struct portal *conn_portal;
struct port *conn_port;
struct target *conn_target;
int conn_socket;
int conn_session_type;
@ -317,14 +331,19 @@ void isns_register(struct isns *isns, struct isns *oldisns);
void isns_check(struct isns *isns);
void isns_deregister(struct isns *isns);
struct port *port_new(struct conf *conf, struct target *target,
struct portal_group *pg);
struct port *port_find(const struct conf *conf, const char *name);
struct port *port_find_in_pg(const struct portal_group *pg,
const char *target);
void port_delete(struct port *port);
struct target *target_new(struct conf *conf, const char *name);
void target_delete(struct target *target);
struct target *target_find(struct conf *conf,
const char *name);
int target_set_redirection(struct target *target,
const char *addr);
void target_set_ctl_port(struct target *target,
uint32_t value);
struct lun *lun_new(struct conf *conf, const char *name);
void lun_delete(struct lun *lun);
@ -351,9 +370,9 @@ int kernel_lun_add(struct lun *lun);
int kernel_lun_resize(struct lun *lun);
int kernel_lun_remove(struct lun *lun);
void kernel_handoff(struct connection *conn);
int kernel_port_add(struct target *targ);
int kernel_port_update(struct target *targ);
int kernel_port_remove(struct target *targ);
int kernel_port_add(struct port *port);
int kernel_port_update(struct port *port);
int kernel_port_remove(struct port *port);
void kernel_capsicate(void);
#ifdef ICL_KERNEL_PROXY

View File

@ -162,6 +162,7 @@ logout_new_response(struct pdu *request)
static void
discovery_add_target(struct keys *response_keys, const struct target *targ)
{
struct port *port;
struct portal *portal;
char *buf;
char hbuf[NI_MAXHOST], sbuf[NI_MAXSERV];
@ -169,7 +170,10 @@ discovery_add_target(struct keys *response_keys, const struct target *targ)
int ret;
keys_add(response_keys, "TargetName", targ->t_name);
TAILQ_FOREACH(portal, &targ->t_portal_group->pg_portals, p_next) {
TAILQ_FOREACH(port, &targ->t_ports, p_ts) {
if (port->p_portal_group == NULL)
continue;
TAILQ_FOREACH(portal, &port->p_portal_group->pg_portals, p_next) {
ai = portal->p_ai;
ret = getnameinfo(ai->ai_addr, ai->ai_addrlen,
hbuf, sizeof(hbuf), sbuf, sizeof(sbuf),
@ -183,13 +187,13 @@ discovery_add_target(struct keys *response_keys, const struct target *targ)
if (strcmp(hbuf, "0.0.0.0") == 0)
continue;
ret = asprintf(&buf, "%s:%s,%d", hbuf, sbuf,
targ->t_portal_group->pg_tag);
port->p_portal_group->pg_tag);
break;
case AF_INET6:
if (strcmp(hbuf, "::") == 0)
continue;
ret = asprintf(&buf, "[%s]:%s,%d", hbuf, sbuf,
targ->t_portal_group->pg_tag);
port->p_portal_group->pg_tag);
break;
default:
continue;
@ -198,19 +202,24 @@ discovery_add_target(struct keys *response_keys, const struct target *targ)
log_err(1, "asprintf");
keys_add(response_keys, "TargetAddress", buf);
free(buf);
}
}
}
static bool
discovery_target_filtered_out(const struct connection *conn,
const struct target *targ)
const struct port *port)
{
const struct auth_group *ag;
const struct portal_group *pg;
const struct target *targ;
const struct auth *auth;
int error;
ag = targ->t_auth_group;
targ = port->p_target;
ag = port->p_auth_group;
if (ag == NULL)
ag = targ->t_auth_group;
pg = conn->conn_portal->p_portal_group;
assert(pg->pg_discovery_auth_group != PG_FILTER_UNKNOWN);
@ -265,8 +274,8 @@ discovery(struct connection *conn)
{
struct pdu *request, *response;
struct keys *request_keys, *response_keys;
const struct port *port;
const struct portal_group *pg;
const struct target *targ;
const char *send_targets;
pg = conn->conn_portal->p_portal_group;
@ -284,29 +293,23 @@ discovery(struct connection *conn)
response_keys = keys_new();
if (strcmp(send_targets, "All") == 0) {
TAILQ_FOREACH(targ, &pg->pg_conf->conf_targets, t_next) {
if (targ->t_portal_group != pg) {
log_debugx("not returning target \"%s\"; "
"belongs to a different portal group",
targ->t_name);
continue;
}
if (discovery_target_filtered_out(conn, targ)) {
TAILQ_FOREACH(port, &pg->pg_ports, p_pgs) {
if (discovery_target_filtered_out(conn, port)) {
/* Ignore this target. */
continue;
}
discovery_add_target(response_keys, targ);
discovery_add_target(response_keys, port->p_target);
}
} else {
targ = target_find(pg->pg_conf, send_targets);
if (targ == NULL) {
port = port_find_in_pg(pg, send_targets);
if (port == NULL) {
log_debugx("initiator requested information on unknown "
"target \"%s\"; returning nothing", send_targets);
} else {
if (discovery_target_filtered_out(conn, targ)) {
if (discovery_target_filtered_out(conn, port)) {
/* Ignore this target. */
} else {
discovery_add_target(response_keys, targ);
discovery_add_target(response_keys, port->p_target);
}
}
}

View File

@ -121,9 +121,10 @@ struct cctl_lun {
struct cctl_port {
uint32_t port_id;
int cfiscsi_status;
int cfiscsi_state;
char *cfiscsi_target;
uint16_t cfiscsi_portal_group_tag;
char *ctld_portal_group_name;
STAILQ_HEAD(,cctl_lun_nv) attr_list;
STAILQ_ENTRY(cctl_port) links;
};
@ -332,10 +333,13 @@ cctl_end_pelement(void *user_data, const char *name)
if (strcmp(name, "cfiscsi_target") == 0) {
cur_port->cfiscsi_target = str;
str = NULL;
} else if (strcmp(name, "cfiscsi_status") == 0) {
cur_port->cfiscsi_status = strtoul(str, NULL, 0);
} else if (strcmp(name, "cfiscsi_state") == 0) {
cur_port->cfiscsi_state = strtoul(str, NULL, 0);
} else if (strcmp(name, "cfiscsi_portal_group_tag") == 0) {
cur_port->cfiscsi_portal_group_tag = strtoul(str, NULL, 0);
} else if (strcmp(name, "ctld_portal_group_name") == 0) {
cur_port->ctld_portal_group_name = str;
str = NULL;
} else if (strcmp(name, "targ_port") == 0) {
devlist->cur_port = NULL;
} else if (strcmp(name, "ctlportlist") == 0) {
@ -373,6 +377,8 @@ conf_new_from_kernel(void)
{
struct conf *conf = NULL;
struct target *targ;
struct portal_group *pg;
struct port *cp;
struct lun *cl;
struct lun_option *lo;
struct ctl_lun_list list;
@ -496,9 +502,9 @@ conf_new_from_kernel(void)
"ignoring", (uintmax_t)port->port_id);
continue;
}
if (port->cfiscsi_status != 1) {
if (port->cfiscsi_state != 1) {
log_debugx("CTL port %ju is not active (%d); ignoring",
(uintmax_t)port->port_id, port->cfiscsi_status);
(uintmax_t)port->port_id, port->cfiscsi_state);
continue;
}
@ -514,6 +520,28 @@ conf_new_from_kernel(void)
continue;
}
}
if (port->ctld_portal_group_name == NULL)
continue;
pg = portal_group_find(conf, port->ctld_portal_group_name);
if (pg == NULL) {
#if 0
log_debugx("found new kernel portal group %s for CTL port %ld",
port->ctld_portal_group_name, port->port_id);
#endif
pg = portal_group_new(conf, port->ctld_portal_group_name);
if (pg == NULL) {
log_warnx("portal_group_new failed");
continue;
}
}
pg->pg_tag = port->cfiscsi_portal_group_tag;
cp = port_new(conf, targ, pg);
if (cp == NULL) {
log_warnx("port_new failed");
continue;
}
cp->p_ctl_port = port->port_id;
}
STAILQ_FOREACH(lun, &devlist.lun_list, links) {
@ -804,32 +832,34 @@ kernel_handoff(struct connection *conn)
}
int
kernel_port_add(struct target *targ)
kernel_port_add(struct port *port)
{
struct ctl_port_entry entry;
struct ctl_req req;
struct ctl_lun_map lm;
struct target *targ = port->p_target;
struct portal_group *pg = port->p_portal_group;
char tagstr[16];
int error, i;
int error, i, n;
/* Create iSCSI port. */
bzero(&req, sizeof(req));
strlcpy(req.driver, "iscsi", sizeof(req.driver));
req.reqtype = CTL_REQ_CREATE;
req.num_args = 4;
req.args = malloc(req.num_args * sizeof(*req.args));
req.args[0].namelen = sizeof("port_id");
req.args[0].name = __DECONST(char *, "port_id");
req.args[0].vallen = sizeof(targ->t_ctl_port);
req.args[0].value = &targ->t_ctl_port;
req.args[0].flags = CTL_BEARG_WR;
str_arg(&req.args[1], "cfiscsi_target", targ->t_name);
snprintf(tagstr, sizeof(tagstr), "%d", targ->t_portal_group->pg_tag);
str_arg(&req.args[2], "cfiscsi_portal_group_tag", tagstr);
n = 0;
req.args[n].namelen = sizeof("port_id");
req.args[n].name = __DECONST(char *, "port_id");
req.args[n].vallen = sizeof(port->p_ctl_port);
req.args[n].value = &port->p_ctl_port;
req.args[n++].flags = CTL_BEARG_WR;
str_arg(&req.args[n++], "cfiscsi_target", targ->t_name);
snprintf(tagstr, sizeof(tagstr), "%d", pg->pg_tag);
str_arg(&req.args[n++], "cfiscsi_portal_group_tag", tagstr);
if (targ->t_alias)
str_arg(&req.args[3], "cfiscsi_target_alias", targ->t_alias);
else
req.num_args--;
str_arg(&req.args[n++], "cfiscsi_target_alias", targ->t_alias);
str_arg(&req.args[n++], "ctld_portal_group_name", pg->pg_name);
req.num_args = n;
error = ioctl(ctl_fd, CTL_PORT_REQ, &req);
free(req.args);
if (error != 0) {
@ -848,7 +878,7 @@ kernel_port_add(struct target *targ)
}
/* Explicitly enable mapping to block any access except allowed. */
lm.port = targ->t_ctl_port;
lm.port = port->p_ctl_port;
lm.plun = UINT32_MAX;
lm.lun = 0;
error = ioctl(ctl_fd, CTL_LUN_MAP, &lm);
@ -859,7 +889,7 @@ kernel_port_add(struct target *targ)
for (i = 0; i < MAX_LUNS; i++) {
if (targ->t_luns[i] == NULL)
continue;
lm.port = targ->t_ctl_port;
lm.port = port->p_ctl_port;
lm.plun = i;
lm.lun = targ->t_luns[i]->l_ctl_lun;
error = ioctl(ctl_fd, CTL_LUN_MAP, &lm);
@ -869,7 +899,7 @@ kernel_port_add(struct target *targ)
/* Enable port */
bzero(&entry, sizeof(entry));
entry.targ_port = targ->t_ctl_port;
entry.targ_port = port->p_ctl_port;
error = ioctl(ctl_fd, CTL_ENABLE_PORT, &entry);
if (error != 0) {
log_warn("CTL_ENABLE_PORT ioctl failed");
@ -880,14 +910,15 @@ kernel_port_add(struct target *targ)
}
int
kernel_port_update(struct target *targ)
kernel_port_update(struct port *port)
{
struct ctl_lun_map lm;
struct target *targ = port->p_target;
int error, i;
/* Map configured LUNs and unmap others */
for (i = 0; i < MAX_LUNS; i++) {
lm.port = targ->t_ctl_port;
lm.port = port->p_ctl_port;
lm.plun = i;
if (targ->t_luns[i] == NULL)
lm.lun = UINT32_MAX;
@ -901,10 +932,12 @@ kernel_port_update(struct target *targ)
}
int
kernel_port_remove(struct target *targ)
kernel_port_remove(struct port *port)
{
struct ctl_req req;
char tagstr[16];
struct target *targ = port->p_target;
struct portal_group *pg = port->p_portal_group;
int error;
bzero(&req, sizeof(req));
@ -913,7 +946,7 @@ kernel_port_remove(struct target *targ)
req.num_args = 2;
req.args = malloc(req.num_args * sizeof(*req.args));
str_arg(&req.args[0], "cfiscsi_target", targ->t_name);
snprintf(tagstr, sizeof(tagstr), "%d", targ->t_portal_group->pg_tag);
snprintf(tagstr, sizeof(tagstr), "%d", pg->pg_tag);
str_arg(&req.args[1], "cfiscsi_portal_group_tag", tagstr);
error = ioctl(ctl_fd, CTL_PORT_REQ, &req);

View File

@ -827,19 +827,22 @@ login(struct connection *conn)
log_errx(1, "received Login PDU without TargetName");
}
conn->conn_target = target_find(pg->pg_conf, target_name);
if (conn->conn_target == NULL) {
conn->conn_port = port_find_in_pg(pg, target_name);
if (conn->conn_port == NULL) {
login_send_error(request, 0x02, 0x03);
log_errx(1, "requested target \"%s\" not found",
target_name);
}
conn->conn_target = conn->conn_port->p_target;
}
/*
* At this point we know what kind of authentication we need.
*/
if (conn->conn_session_type == CONN_SESSION_TYPE_NORMAL) {
ag = conn->conn_target->t_auth_group;
ag = conn->conn_port->p_auth_group;
if (ag == NULL)
ag = conn->conn_target->t_auth_group;
if (ag->ag_name != NULL) {
log_debugx("initiator requests to connect "
"to target \"%s\"; auth-group \"%s\"",

View File

@ -652,21 +652,58 @@ target_initiator_portal: INITIATOR_PORTAL STR
}
;
target_portal_group: PORTAL_GROUP STR
target_portal_group: PORTAL_GROUP STR STR
{
if (target->t_portal_group != NULL) {
log_warnx("portal-group for target \"%s\" "
"specified more than once", target->t_name);
struct portal_group *tpg;
struct auth_group *tag;
struct port *tp;
tpg = portal_group_find(conf, $2);
if (tpg == NULL) {
log_warnx("unknown portal-group \"%s\" for target "
"\"%s\"", $2, target->t_name);
free($2);
free($3);
return (1);
}
tag = auth_group_find(conf, $3);
if (tag == NULL) {
log_warnx("unknown auth-group \"%s\" for target "
"\"%s\"", $3, target->t_name);
free($2);
free($3);
return (1);
}
tp = port_new(conf, target, tpg);
if (tp == NULL) {
log_warnx("can't link portal-group \"%s\" to target "
"\"%s\"", $2, target->t_name);
free($2);
return (1);
}
target->t_portal_group = portal_group_find(conf, $2);
if (target->t_portal_group == NULL) {
tp->p_auth_group = tag;
free($2);
free($3);
}
| PORTAL_GROUP STR
{
struct portal_group *tpg;
struct port *tp;
tpg = portal_group_find(conf, $2);
if (tpg == NULL) {
log_warnx("unknown portal-group \"%s\" for target "
"\"%s\"", $2, target->t_name);
free($2);
return (1);
}
tp = port_new(conf, target, tpg);
if (tp == NULL) {
log_warnx("can't link portal-group \"%s\" to target "
"\"%s\"", $2, target->t_name);
free($2);
return (1);
}
free($2);
}
;