Page MenuHomeFreeBSD

D12181.id32545.diff
No OneTemporary

D12181.id32545.diff

Index: sys/cam/ctl/ctl_frontend_iscsi.h
===================================================================
--- sys/cam/ctl/ctl_frontend_iscsi.h
+++ sys/cam/ctl/ctl_frontend_iscsi.h
@@ -47,6 +47,8 @@
int ct_online;
int ct_target_id;
struct ctl_port ct_port;
+ int ct_nb_conn;
+ int ct_max_conn;
};
struct cfiscsi_data_wait {
Index: sys/cam/ctl/ctl_frontend_iscsi.c
===================================================================
--- sys/cam/ctl/ctl_frontend_iscsi.c
+++ sys/cam/ctl/ctl_frontend_iscsi.c
@@ -98,6 +98,9 @@
static int maxtags = 256;
SYSCTL_INT(_kern_cam_ctl_iscsi, OID_AUTO, maxtags, CTLFLAG_RWTUN,
&maxtags, 0, "Max number of requests queued by initiator");
+static int maxconn = 512;
+SYSCTL_INT(_kern_cam_ctl_iscsi, OID_AUTO, maxconn, CTLFLAG_RWTUN,
+ &maxconn, 0, "Default max number of connections to a target");
#define CFISCSI_DEBUG(X, ...) \
do { \
@@ -1309,8 +1312,10 @@
("destroying session with non-empty queue"));
cfiscsi_session_unregister_initiator(cs);
- if (cs->cs_target != NULL)
+ if (cs->cs_target != NULL) {
+ cs->cs_target->ct_nb_conn--;
cfiscsi_target_release(cs->cs_target);
+ }
icl_conn_close(cs->cs_conn);
icl_conn_free(cs->cs_conn);
@@ -1565,6 +1570,7 @@
return;
}
cs->cs_target = ct;
+ ct->ct_nb_conn++;
mtx_unlock(&softc->lock);
refcount_acquire(&cs->cs_outstanding_ctl_pdus);
@@ -1816,6 +1822,32 @@
ci->status = CTL_ISCSI_OK;
}
+static void
+cfiscsi_ioctl_maxconn(struct ctl_iscsi *ci)
+{
+ struct cfiscsi_softc *softc;
+ struct ctl_iscsi_maxconn_params *cihp;
+ struct cfiscsi_target *ct;
+
+ cihp = (struct ctl_iscsi_maxconn_params *)&(ci->data);
+ softc = &cfiscsi_softc;
+
+ ct = cfiscsi_target_find(softc, cihp->target_name,
+ cihp->portal_group_tag);
+
+ if (ct == NULL) {
+ ci->status = CTL_ISCSI_ERROR;
+ snprintf(ci->error_str, sizeof(ci->error_str),
+ "%s: target not found", __func__);
+ return;
+ }
+
+ cihp->max_conn = ct->ct_max_conn;
+ cihp->nb_conn = ct->ct_nb_conn;
+
+ ci->status = CTL_ISCSI_OK;
+}
+
static void
cfiscsi_ioctl_limits(struct ctl_iscsi *ci)
{
@@ -2074,6 +2106,7 @@
struct scsi_vpd_id_descriptor *desc;
ctl_options_t opts;
int retval, len, idlen;
+ uint64_t max_conn;
uint16_t tag;
ctl_init_opts(&opts, req->num_args, req->kern_args);
@@ -2105,6 +2138,10 @@
ctl_free_opts(&opts);
return;
}
+ retval = ctl_get_opt_number(&opts, "cfiscsi_max_conn", &max_conn);
+ if (!retval) {
+ ct->ct_max_conn = max_conn;
+ }
port = &ct->ct_port;
// WAT
if (ct->ct_state == CFISCSI_TARGET_STATE_DYING)
@@ -2266,6 +2303,9 @@
case CTL_ISCSI_LIMITS:
cfiscsi_ioctl_limits(ci);
break;
+ case CTL_ISCSI_MAXCONN:
+ cfiscsi_ioctl_maxconn(ci);
+ break;
#ifdef ICL_KERNEL_PROXY
case CTL_ISCSI_LISTEN:
cfiscsi_ioctl_listen(ci);
@@ -2373,6 +2413,9 @@
return (ct);
}
+ newct->ct_nb_conn = 0;
+ newct->ct_max_conn = maxconn;
+
strlcpy(newct->ct_name, name, sizeof(newct->ct_name));
if (alias != NULL)
strlcpy(newct->ct_alias, alias, sizeof(newct->ct_alias));
Index: sys/cam/ctl/ctl_ioctl.h
===================================================================
--- sys/cam/ctl/ctl_ioctl.h
+++ sys/cam/ctl/ctl_ioctl.h
@@ -671,6 +671,7 @@
CTL_ISCSI_SEND,
CTL_ISCSI_RECEIVE,
#endif
+ CTL_ISCSI_MAXCONN,
} ctl_iscsi_type;
typedef enum {
@@ -747,6 +748,14 @@
int spare[4];
};
+struct ctl_iscsi_maxconn_params {
+ char target_name[CTL_ISCSI_NAME_LEN];
+ int portal_group_tag; /* passed to kernel */
+ int nb_conn; /* filled in kernel */
+ int max_conn; /* filled in kernel */
+ int spare[4];
+};
+
#ifdef ICL_KERNEL_PROXY
struct ctl_iscsi_listen_params {
int iser;
@@ -795,6 +804,7 @@
struct ctl_iscsi_logout_params logout;
struct ctl_iscsi_terminate_params terminate;
struct ctl_iscsi_limits_params limits;
+ struct ctl_iscsi_maxconn_params maxconn;
#ifdef ICL_KERNEL_PROXY
struct ctl_iscsi_listen_params listen;
struct ctl_iscsi_accept_params accept;
Index: usr.sbin/ctld/ctld.h
===================================================================
--- usr.sbin/ctld/ctld.h
+++ usr.sbin/ctld/ctld.h
@@ -187,6 +187,7 @@
char *t_name;
char *t_alias;
char *t_redirection;
+ char *t_max_conn;
};
struct isns {
@@ -403,6 +404,7 @@
int kernel_lun_modify(struct lun *lun);
int kernel_lun_remove(struct lun *lun);
void kernel_handoff(struct connection *conn);
+int kernel_maxconn(struct connection *conn);
void kernel_limits(const char *offload,
size_t *max_data_segment_length);
int kernel_port_add(struct port *port);
Index: usr.sbin/ctld/kernel.c
===================================================================
--- usr.sbin/ctld/kernel.c
+++ usr.sbin/ctld/kernel.c
@@ -922,6 +922,33 @@
}
}
+int
+kernel_maxconn(struct connection *conn)
+{
+ struct ctl_iscsi req;
+
+ bzero(&req, sizeof(req));
+
+ req.type = CTL_ISCSI_MAXCONN;
+ strlcpy(req.data.maxconn.target_name,
+ conn->conn_target->t_name, sizeof(req.data.maxconn.target_name));
+ req.data.maxconn.portal_group_tag =
+ conn->conn_portal->p_portal_group->pg_tag;
+
+ if (ioctl(ctl_fd, CTL_ISCSI, &req) == -1) {
+ log_err(1, "error issuing CTL_ISCSI ioctl; "
+ "dropping connection");
+ return (1);
+ }
+
+ if (req.status != CTL_ISCSI_OK) {
+ log_errx(1, "error returned from CTL iSCSI maxconn request: "
+ "%s; dropping connection", req.error_str);
+ return (1);
+ }
+ return !(req.data.maxconn.nb_conn < req.data.maxconn.max_conn);
+}
+
void
kernel_limits(const char *offload, size_t *max_data_segment_length)
{
@@ -972,7 +999,7 @@
bzero(&req, sizeof(req));
strlcpy(req.driver, "iscsi", sizeof(req.driver));
req.reqtype = CTL_REQ_CREATE;
- req.num_args = 5;
+ req.num_args = 6;
TAILQ_FOREACH(o, &pg->pg_options, o_next)
req.num_args++;
req.args = malloc(req.num_args * sizeof(*req.args));
@@ -989,6 +1016,8 @@
str_arg(&req.args[n++], "cfiscsi_portal_group_tag", tagstr);
if (targ->t_alias)
str_arg(&req.args[n++], "cfiscsi_target_alias", targ->t_alias);
+ if (targ->t_max_conn)
+ str_arg(&req.args[n++], "cfiscsi_max_conn", targ->t_max_conn);
str_arg(&req.args[n++], "ctld_portal_group_name", pg->pg_name);
TAILQ_FOREACH(o, &pg->pg_options, o_next)
str_arg(&req.args[n++], o->o_name, o->o_value);
Index: usr.sbin/ctld/login.c
===================================================================
--- usr.sbin/ctld/login.c
+++ usr.sbin/ctld/login.c
@@ -687,6 +687,11 @@
assert(conn->conn_target != NULL);
kernel_limits(conn->conn_portal->p_portal_group->pg_offload,
&conn->conn_data_segment_limit);
+ if (kernel_maxconn(conn) == true) {
+ login_send_error(request, 0x02, 0x00);
+ log_errx(1, "Max number of connections to target reached");
+ }
+
} else {
conn->conn_data_segment_limit = MAX_DATA_SEGMENT_LENGTH;
}
Index: usr.sbin/ctld/parse.y
===================================================================
--- usr.sbin/ctld/parse.y
+++ usr.sbin/ctld/parse.y
@@ -60,7 +60,7 @@
%token CLOSING_BRACKET CTL_LUN DEBUG DEVICE_ID DEVICE_TYPE
%token DISCOVERY_AUTH_GROUP DISCOVERY_FILTER FOREIGN
%token INITIATOR_NAME INITIATOR_PORTAL ISNS_SERVER ISNS_PERIOD ISNS_TIMEOUT
-%token LISTEN LISTEN_ISER LUN MAXPROC OFFLOAD OPENING_BRACKET OPTION
+%token LISTEN LISTEN_ISER LUN MAXCONN MAXPROC OFFLOAD OPENING_BRACKET OPTION
%token PATH PIDFILE PORT PORTAL_GROUP REDIRECT SEMICOLON SERIAL SIZE STR
%token TAG TARGET TIMEOUT
@@ -524,6 +524,8 @@
target_lun
|
target_lun_ref
+ |
+ target_max_conn
;
target_alias: ALIAS STR
@@ -803,6 +805,17 @@
}
;
+target_max_conn: MAXCONN STR
+ {
+ if (target->t_max_conn != NULL) {
+ log_warnx("max_conn for target \"%s\" "
+ "specified more than once", target->t_name);
+ return (1);
+ }
+ target->t_max_conn = $2;
+ }
+ ;
+
target_lun: LUN lun_number
OPENING_BRACKET lun_entries CLOSING_BRACKET
{
Index: usr.sbin/ctld/token.l
===================================================================
--- usr.sbin/ctld/token.l
+++ usr.sbin/ctld/token.l
@@ -67,6 +67,7 @@
listen-iser { return LISTEN_ISER; }
lun { return LUN; }
maxproc { return MAXPROC; }
+max_conn { return MAXCONN; }
offload { return OFFLOAD; }
option { return OPTION; }
path { return PATH; }
Index: usr.sbin/ctld/uclparse.c
===================================================================
--- usr.sbin/ctld/uclparse.c
+++ usr.sbin/ctld/uclparse.c
@@ -775,6 +775,16 @@
}
}
+ if (!strcmp(key, "max_conn")) {
+ if (obj->type != UCL_STRING) {
+ log_warnx("\"max_conn\" property of target "
+ "\"%s\" is not a string", target->t_name);
+ return (1);
+ }
+
+ target->t_max_conn = strdup(ucl_object_tostring(obj));
+ }
+
if (!strcmp(key, "redirect")) {
if (obj->type != UCL_STRING) {
log_warnx("\"redirect\" property of target "

File Metadata

Mime Type
text/plain
Expires
Tue, Mar 10, 5:57 PM (9 h, 41 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
29504248
Default Alt Text
D12181.id32545.diff (8 KB)

Event Timeline