ctl: Make max_luns and max_ports tunable variables instead of hardcoded

defines.

Reviewed by:	trasz (earlier version), bapt (earlier version), bcr (manpages)
MFC after:	2 Weeks
Sponsored by:	Gandi.net
Differential Revision:	https://reviews.freebsd.org/D12836
This commit is contained in:
Emmanuel Vadot 2017-11-07 16:59:52 +00:00
parent cee09850f7
commit 530fdf6771
4 changed files with 113 additions and 60 deletions

View File

@ -191,6 +191,15 @@ If there is no primary node (both nodes are secondary, or secondary node has
no connection to primary one), secondary node(s) report Transitioning state.
State with two primary nodes is illegal (split brain condition).
.El
.Sh TUNABLE VARIABLES
The following variables are available as
.Xr loader 8
tunables:
.Bl -tag -width indent
.It Va kern.cam.ctl.max_luns
Specifies the maximum number of LUNs we support, must be a power of 2. (Default 1024)
.It Va kern.cam.ctl.max_ports
Specifies the maximum number of ports we support, must be a power of 2. (Default 256)
.Sh SEE ALSO
.Xr cfiscsi 4 ,
.Xr cfumass 4 ,

View File

@ -414,6 +414,29 @@ SYSCTL_INT(_kern_cam_ctl, OID_AUTO, time_io_secs, CTLFLAG_RWTUN,
&ctl_time_io_secs, 0, "Log requests taking more seconds");
#endif
/*
* Maximum number of LUNs we support. MUST be a power of 2.
*/
#define CTL_DEFAULT_MAX_LUNS 1024
static int ctl_max_luns = CTL_DEFAULT_MAX_LUNS;
TUNABLE_INT("kern.cam.ctl.max_luns", &ctl_max_luns);
SYSCTL_INT(_kern_cam_ctl, OID_AUTO, max_luns, CTLFLAG_RDTUN,
&ctl_max_luns, CTL_DEFAULT_MAX_LUNS, "Maximum number of LUNs");
/*
* Maximum number of ports registered at one time.
*/
#define CTL_DEFAULT_MAX_PORTS 256
static int ctl_max_ports = CTL_DEFAULT_MAX_PORTS;
TUNABLE_INT("kern.cam.ctl.max_ports", &ctl_max_ports);
SYSCTL_INT(_kern_cam_ctl, OID_AUTO, max_ports, CTLFLAG_RDTUN,
&ctl_max_ports, CTL_DEFAULT_MAX_LUNS, "Maximum number of ports");
/*
* Maximum number of initiators we support.
*/
#define CTL_MAX_INITIATORS (CTL_MAX_INIT_PER_PORT * ctl_max_ports)
/*
* Supported pages (0x00), Serial number (0x80), Device ID (0x83),
* Extended INQUIRY Data (0x86), Mode Page Policy (0x87),
@ -1005,8 +1028,8 @@ ctl_isc_ha_link_up(struct ctl_softc *softc)
msg.login.version = CTL_HA_VERSION;
msg.login.ha_mode = softc->ha_mode;
msg.login.ha_id = softc->ha_id;
msg.login.max_luns = CTL_MAX_LUNS;
msg.login.max_ports = CTL_MAX_PORTS;
msg.login.max_luns = ctl_max_luns;
msg.login.max_ports = ctl_max_ports;
msg.login.max_init_per_port = CTL_MAX_INIT_PER_PORT;
ctl_ha_msg_send(CTL_HA_CHAN_CTL, &msg.login, sizeof(msg.login),
M_WAITOK);
@ -1069,7 +1092,7 @@ ctl_isc_ua(struct ctl_softc *softc, union ctl_ha_msg *msg, int len)
uint32_t iid = ctl_get_initindex(&msg->hdr.nexus);
mtx_lock(&softc->ctl_lock);
if (msg->hdr.nexus.targ_mapped_lun >= CTL_MAX_LUNS ||
if (msg->hdr.nexus.targ_mapped_lun >= ctl_max_luns ||
(lun = softc->ctl_luns[msg->hdr.nexus.targ_mapped_lun]) == NULL) {
mtx_unlock(&softc->ctl_lock);
return;
@ -1103,7 +1126,7 @@ ctl_isc_lun_sync(struct ctl_softc *softc, union ctl_ha_msg *msg, int len)
targ_lun = msg->hdr.nexus.targ_mapped_lun;
mtx_lock(&softc->ctl_lock);
if (targ_lun >= CTL_MAX_LUNS ||
if (targ_lun >= ctl_max_luns ||
(lun = softc->ctl_luns[targ_lun]) == NULL) {
mtx_unlock(&softc->ctl_lock);
return;
@ -1325,8 +1348,8 @@ ctl_isc_login(struct ctl_softc *softc, union ctl_ha_msg *msg, int len)
ctl_ha_msg_abort(CTL_HA_CHAN_CTL);
return;
}
if (msg->login.max_luns != CTL_MAX_LUNS ||
msg->login.max_ports != CTL_MAX_PORTS ||
if (msg->login.max_luns != ctl_max_luns ||
msg->login.max_ports != ctl_max_ports ||
msg->login.max_init_per_port != CTL_MAX_INIT_PER_PORT) {
printf("CTL HA peers have different limits\n");
ctl_ha_msg_abort(CTL_HA_CHAN_CTL);
@ -1343,7 +1366,7 @@ ctl_isc_mode_sync(struct ctl_softc *softc, union ctl_ha_msg *msg, int len)
targ_lun = msg->hdr.nexus.targ_mapped_lun;
mtx_lock(&softc->ctl_lock);
if (targ_lun >= CTL_MAX_LUNS ||
if (targ_lun >= ctl_max_luns ||
(lun = softc->ctl_luns[targ_lun]) == NULL) {
mtx_unlock(&softc->ctl_lock);
return;
@ -1873,6 +1896,26 @@ ctl_init(void)
OID_AUTO, "ha_mode", CTLFLAG_RDTUN, (int *)&softc->ha_mode, 0,
"HA mode (0 - act/stby, 1 - serialize only, 2 - xfer)");
if (ctl_max_luns <= 0 || powerof2(ctl_max_luns) == 0) {
printf("Bad value %d for kern.cam.ctl.max_luns, must be a power of two, using %d\n",
ctl_max_luns, CTL_DEFAULT_MAX_LUNS);
ctl_max_luns = CTL_DEFAULT_MAX_LUNS;
}
softc->ctl_luns = malloc(sizeof(struct ctl_lun *) * ctl_max_luns,
M_DEVBUF, M_WAITOK | M_ZERO);
softc->ctl_lun_mask = malloc(sizeof(uint32_t) *
((ctl_max_luns + 31) / 32), M_DEVBUF, M_WAITOK | M_ZERO);
if (ctl_max_ports <= 0 || powerof2(ctl_max_ports) == 0) {
printf("Bad value %d for kern.cam.ctl.max_ports, must be a power of two, using %d\n",
ctl_max_ports, CTL_DEFAULT_MAX_PORTS);
ctl_max_ports = CTL_DEFAULT_MAX_PORTS;
}
softc->ctl_port_mask = malloc(sizeof(uint32_t) *
((ctl_max_ports + 31) / 32), M_DEVBUF, M_WAITOK | M_ZERO);
softc->ctl_ports = malloc(sizeof(struct ctl_port *) * ctl_max_ports,
M_DEVBUF, M_WAITOK | M_ZERO);
/*
* In Copan's HA scheme, the "master" and "slave" roles are
* figured out through the slot the controller is in. Although it
@ -1884,10 +1927,10 @@ ctl_init(void)
if (softc->ha_id == 0 || softc->ha_id > NUM_HA_SHELVES) {
softc->flags |= CTL_FLAG_ACTIVE_SHELF;
softc->is_single = 1;
softc->port_cnt = CTL_MAX_PORTS;
softc->port_cnt = ctl_max_ports;
softc->port_min = 0;
} else {
softc->port_cnt = CTL_MAX_PORTS / NUM_HA_SHELVES;
softc->port_cnt = ctl_max_ports / NUM_HA_SHELVES;
softc->port_min = (softc->ha_id - 1) * softc->port_cnt;
}
softc->port_max = softc->port_min + softc->port_cnt;
@ -1988,6 +2031,11 @@ ctl_shutdown(void)
uma_zdestroy(softc->io_zone);
mtx_destroy(&softc->ctl_lock);
free(softc->ctl_luns, M_DEVBUF);
free(softc->ctl_lun_mask, M_DEVBUF);
free(softc->ctl_port_mask, M_DEVBUF);
free(softc->ctl_ports, M_DEVBUF);
sysctl_ctx_free(&softc->sysctl_ctx);
free(softc, M_DEVBUF);
@ -2249,7 +2297,7 @@ ctl_serialize_other_sc_cmd(struct ctl_scsiio *ctsio)
/* Make sure that we know about this LUN. */
mtx_lock(&softc->ctl_lock);
if (targ_lun >= CTL_MAX_LUNS ||
if (targ_lun >= ctl_max_luns ||
(lun = softc->ctl_luns[targ_lun]) == NULL) {
mtx_unlock(&softc->ctl_lock);
@ -2717,7 +2765,7 @@ ctl_ioctl(struct cdev *dev, u_long cmd, caddr_t addr, int flag,
mtx_lock(&softc->ctl_lock);
if ((ooa_hdr->flags & CTL_OOA_FLAG_ALL_LUNS) == 0 &&
(ooa_hdr->lun_num >= CTL_MAX_LUNS ||
(ooa_hdr->lun_num >= ctl_max_luns ||
softc->ctl_luns[ooa_hdr->lun_num] == NULL)) {
mtx_unlock(&softc->ctl_lock);
free(entries, M_CTL);
@ -2770,7 +2818,7 @@ ctl_ioctl(struct cdev *dev, u_long cmd, caddr_t addr, int flag,
#ifdef CTL_IO_DELAY
mtx_lock(&softc->ctl_lock);
if (delay_info->lun_id >= CTL_MAX_LUNS ||
if (delay_info->lun_id >= ctl_max_luns ||
(lun = softc->ctl_luns[delay_info->lun_id]) == NULL) {
mtx_unlock(&softc->ctl_lock);
delay_info->status = CTL_DELAY_STATUS_INVALID_LUN;
@ -2849,7 +2897,7 @@ ctl_ioctl(struct cdev *dev, u_long cmd, caddr_t addr, int flag,
bcopy(err_desc, new_err_desc, sizeof(*new_err_desc));
mtx_lock(&softc->ctl_lock);
if (err_desc->lun_id >= CTL_MAX_LUNS ||
if (err_desc->lun_id >= ctl_max_luns ||
(lun = softc->ctl_luns[err_desc->lun_id]) == NULL) {
mtx_unlock(&softc->ctl_lock);
free(new_err_desc, M_CTL);
@ -2893,7 +2941,7 @@ ctl_ioctl(struct cdev *dev, u_long cmd, caddr_t addr, int flag,
delete_done = 0;
mtx_lock(&softc->ctl_lock);
if (delete_desc->lun_id >= CTL_MAX_LUNS ||
if (delete_desc->lun_id >= ctl_max_luns ||
(lun = softc->ctl_luns[delete_desc->lun_id]) == NULL) {
mtx_unlock(&softc->ctl_lock);
printf("%s: CTL_ERROR_INJECT_DELETE: invalid LUN %ju\n",
@ -2936,7 +2984,7 @@ ctl_ioctl(struct cdev *dev, u_long cmd, caddr_t addr, int flag,
continue;
}
for (j = 0; j < CTL_MAX_PORTS; j++) {
for (j = 0; j < ctl_max_ports; j++) {
if (lun->pr_keys[j] == NULL)
continue;
for (k = 0; k < CTL_MAX_INIT_PER_PORT; k++){
@ -3411,7 +3459,7 @@ ctl_ioctl(struct cdev *dev, u_long cmd, caddr_t addr, int flag,
if (lm->plun != UINT32_MAX) {
if (lm->lun == UINT32_MAX)
retval = ctl_lun_map_unset(port, lm->plun);
else if (lm->lun < CTL_MAX_LUNS &&
else if (lm->lun < ctl_max_luns &&
softc->ctl_luns[lm->lun] != NULL)
retval = ctl_lun_map_set(port, lm->plun, lm->lun);
else
@ -4519,6 +4567,13 @@ ctl_alloc_lun(struct ctl_softc *ctl_softc, struct ctl_lun *ctl_lun,
if (lun_malloced)
lun->flags = CTL_LUN_MALLOCED;
lun->pending_sense = malloc(sizeof(struct scsi_sense_data *) *
ctl_max_ports, M_DEVBUF, M_WAITOK | M_ZERO);
lun->pending_ua = malloc(sizeof(ctl_ua_type *) * ctl_max_ports,
M_DEVBUF, M_WAITOK | M_ZERO);
lun->pr_keys = malloc(sizeof(uint64_t *) * ctl_max_ports,
M_DEVBUF, M_WAITOK | M_ZERO);
/* Generate LUN ID. */
devidlen = max(CTL_DEVID_MIN_LEN,
strnlen(be_lun->device_id, CTL_DEVID_LEN));
@ -4605,13 +4660,13 @@ ctl_alloc_lun(struct ctl_softc *ctl_softc, struct ctl_lun *ctl_lun,
* if it is available. Otherwise, allocate the first available LUN.
*/
if (be_lun->flags & CTL_LUN_FLAG_ID_REQ) {
if ((be_lun->req_lun_id > (CTL_MAX_LUNS - 1))
if ((be_lun->req_lun_id > (ctl_max_luns - 1))
|| (ctl_is_set(ctl_softc->ctl_lun_mask, be_lun->req_lun_id))) {
mtx_unlock(&ctl_softc->ctl_lock);
if (be_lun->req_lun_id > (CTL_MAX_LUNS - 1)) {
if (be_lun->req_lun_id > (ctl_max_luns - 1)) {
printf("ctl: requested LUN ID %d is higher "
"than CTL_MAX_LUNS - 1 (%d)\n",
be_lun->req_lun_id, CTL_MAX_LUNS - 1);
"than ctl_max_luns - 1 (%d)\n",
be_lun->req_lun_id, ctl_max_luns - 1);
} else {
/*
* XXX KDM return an error, or just assign
@ -4630,7 +4685,7 @@ fail:
}
lun_number = be_lun->req_lun_id;
} else {
lun_number = ctl_ffz(ctl_softc->ctl_lun_mask, 0, CTL_MAX_LUNS);
lun_number = ctl_ffz(ctl_softc->ctl_lun_mask, 0, ctl_max_luns);
if (lun_number == -1) {
mtx_unlock(&ctl_softc->ctl_lock);
printf("ctl: can't allocate LUN, out of LUNs\n");
@ -4697,7 +4752,9 @@ fail:
lun->legacy_stats.blocksize = be_lun->blocksize;
if (be_lun->blocksize == 0)
lun->legacy_stats.flags = CTL_LUN_STATS_NO_BLOCKSIZE;
for (len = 0; len < CTL_MAX_PORTS; len++)
lun->legacy_stats.ports = malloc(sizeof(struct ctl_lun_io_port_stats) *
ctl_max_ports, M_DEVBUF, M_WAITOK | M_ZERO);
for (len = 0; len < ctl_max_ports; len++)
lun->legacy_stats.ports[len].targ_port = len;
#endif /* CTL_LEGACY_STATS */
lun->stats.item = lun_number;
@ -4760,10 +4817,12 @@ ctl_free_lun(struct ctl_lun *lun)
ctl_tpc_lun_shutdown(lun);
mtx_destroy(&lun->lun_lock);
free(lun->lun_devid, M_CTL);
for (i = 0; i < CTL_MAX_PORTS; i++)
for (i = 0; i < ctl_max_ports; i++)
free(lun->pending_ua[i], M_CTL);
for (i = 0; i < CTL_MAX_PORTS; i++)
free(lun->pending_ua, M_DEVBUF);
for (i = 0; i < ctl_max_ports; i++)
free(lun->pr_keys[i], M_CTL);
free(lun->pr_keys, M_DEVBUF);
free(lun->write_buffer, M_CTL);
free(lun->prevent, M_CTL);
if (lun->flags & CTL_LUN_MALLOCED)
@ -8483,7 +8542,7 @@ ctl_hndl_per_res_out_on_other_sc(union ctl_io *io)
targ_lun = msg->hdr.nexus.targ_mapped_lun;
mtx_lock(&softc->ctl_lock);
if (targ_lun >= CTL_MAX_LUNS ||
if (targ_lun >= ctl_max_luns ||
(lun = softc->ctl_luns[targ_lun]) == NULL) {
mtx_unlock(&softc->ctl_lock);
return;
@ -9010,7 +9069,7 @@ ctl_report_luns(struct ctl_scsiio *ctsio)
CTL_DEBUG_PRINT(("ctl_report_luns\n"));
num_luns = 0;
num_port_luns = port->lun_map ? port->lun_map_size : CTL_MAX_LUNS;
num_port_luns = port->lun_map ? port->lun_map_size : ctl_max_luns;
mtx_lock(&softc->ctl_lock);
for (targ_lun_id = 0; targ_lun_id < num_port_luns; targ_lun_id++) {
if (ctl_lun_map_from_port(port, targ_lun_id) != UINT32_MAX)
@ -11200,7 +11259,7 @@ ctl_failover_lun(union ctl_io *rio)
/* Find and lock the LUN. */
mtx_lock(&softc->ctl_lock);
if (targ_lun > CTL_MAX_LUNS ||
if (targ_lun > ctl_max_luns ||
(lun = softc->ctl_luns[targ_lun]) == NULL) {
mtx_unlock(&softc->ctl_lock);
return;
@ -11282,7 +11341,7 @@ ctl_scsiio_precheck(struct ctl_softc *softc, struct ctl_scsiio *ctsio)
lun = NULL;
targ_lun = ctsio->io_hdr.nexus.targ_mapped_lun;
if (targ_lun < CTL_MAX_LUNS)
if (targ_lun < ctl_max_luns)
lun = softc->ctl_luns[targ_lun];
if (lun) {
/*
@ -11672,7 +11731,7 @@ ctl_do_lun_reset(struct ctl_lun *lun, uint32_t initidx, ctl_ua_type ua_type)
xio->io_hdr.flags |= CTL_FLAG_ABORT | CTL_FLAG_ABORT_STATUS;
}
/* Clear CA. */
for (i = 0; i < CTL_MAX_PORTS; i++) {
for (i = 0; i < ctl_max_ports; i++) {
free(lun->pending_sense[i], M_CTL);
lun->pending_sense[i] = NULL;
}
@ -11705,7 +11764,7 @@ ctl_lun_reset(union ctl_io *io)
targ_lun = io->io_hdr.nexus.targ_mapped_lun;
initidx = ctl_get_initindex(&io->io_hdr.nexus);
mtx_lock(&softc->ctl_lock);
if (targ_lun >= CTL_MAX_LUNS ||
if (targ_lun >= ctl_max_luns ||
(lun = softc->ctl_luns[targ_lun]) == NULL) {
mtx_unlock(&softc->ctl_lock);
io->taskio.task_status = CTL_TASK_LUN_DOES_NOT_EXIST;
@ -11784,7 +11843,7 @@ ctl_abort_task_set(union ctl_io *io)
*/
targ_lun = io->io_hdr.nexus.targ_mapped_lun;
mtx_lock(&softc->ctl_lock);
if (targ_lun >= CTL_MAX_LUNS ||
if (targ_lun >= ctl_max_luns ||
(lun = softc->ctl_luns[targ_lun]) == NULL) {
mtx_unlock(&softc->ctl_lock);
io->taskio.task_status = CTL_TASK_LUN_DOES_NOT_EXIST;
@ -11886,7 +11945,7 @@ ctl_abort_task(union ctl_io *io)
*/
targ_lun = io->io_hdr.nexus.targ_mapped_lun;
mtx_lock(&softc->ctl_lock);
if (targ_lun >= CTL_MAX_LUNS ||
if (targ_lun >= ctl_max_luns ||
(lun = softc->ctl_luns[targ_lun]) == NULL) {
mtx_unlock(&softc->ctl_lock);
io->taskio.task_status = CTL_TASK_LUN_DOES_NOT_EXIST;
@ -12010,7 +12069,7 @@ ctl_query_task(union ctl_io *io, int task_set)
targ_lun = io->io_hdr.nexus.targ_mapped_lun;
mtx_lock(&softc->ctl_lock);
if (targ_lun >= CTL_MAX_LUNS ||
if (targ_lun >= ctl_max_luns ||
(lun = softc->ctl_luns[targ_lun]) == NULL) {
mtx_unlock(&softc->ctl_lock);
io->taskio.task_status = CTL_TASK_LUN_DOES_NOT_EXIST;
@ -12049,7 +12108,7 @@ ctl_query_async_event(union ctl_io *io)
targ_lun = io->io_hdr.nexus.targ_mapped_lun;
mtx_lock(&softc->ctl_lock);
if (targ_lun >= CTL_MAX_LUNS ||
if (targ_lun >= ctl_max_luns ||
(lun = softc->ctl_luns[targ_lun]) == NULL) {
mtx_unlock(&softc->ctl_lock);
io->taskio.task_status = CTL_TASK_LUN_DOES_NOT_EXIST;
@ -12141,7 +12200,7 @@ ctl_handle_isc(union ctl_io *io)
break;
case CTL_MSG_R2R: /* Only used in SER_ONLY mode. */
entry = ctl_get_cmd_entry(&io->scsiio, NULL);
if (targ_lun >= CTL_MAX_LUNS ||
if (targ_lun >= ctl_max_luns ||
(lun = softc->ctl_luns[targ_lun]) == NULL) {
ctl_done(io);
break;
@ -12161,7 +12220,7 @@ ctl_handle_isc(union ctl_io *io)
ctl_done(io);
break;
}
if (targ_lun >= CTL_MAX_LUNS ||
if (targ_lun >= ctl_max_luns ||
(lun = softc->ctl_luns[targ_lun]) == NULL) {
ctl_free_io(io);
break;
@ -13130,7 +13189,7 @@ ctl_queue_sense(union ctl_io *io)
* If we don't have a LUN for this, just toss the sense information.
*/
mtx_lock(&softc->ctl_lock);
if (targ_lun >= CTL_MAX_LUNS ||
if (targ_lun >= ctl_max_luns ||
(lun = softc->ctl_luns[targ_lun]) == NULL) {
mtx_unlock(&softc->ctl_lock);
goto bailout;

View File

@ -58,26 +58,11 @@
*/
#define CTL_MAX_TARGID 15
/*
* Maximum number of LUNs we support at the moment. MUST be a power of 2.
*/
#define CTL_MAX_LUNS 1024
/*
* Maximum number of initiators per port.
*/
#define CTL_MAX_INIT_PER_PORT 2048
/*
* Maximum number of ports registered at one time.
*/
#define CTL_MAX_PORTS 256
/*
* Maximum number of initiators we support.
*/
#define CTL_MAX_INITIATORS (CTL_MAX_INIT_PER_PORT * CTL_MAX_PORTS)
/* Hopefully this won't conflict with new misc devices that pop up */
#define CTL_MINOR 225
@ -150,7 +135,7 @@ struct ctl_lun_io_stats {
uint64_t lun_number;
uint32_t blocksize;
ctl_lun_stats_flags flags;
struct ctl_lun_io_port_stats ports[CTL_MAX_PORTS];
struct ctl_lun_io_port_stats *ports;
};
struct ctl_stats {

View File

@ -390,8 +390,8 @@ struct ctl_lun {
TAILQ_HEAD(ctl_ooaq, ctl_io_hdr) ooa_queue;
TAILQ_HEAD(ctl_blockq,ctl_io_hdr) blocked_queue;
STAILQ_ENTRY(ctl_lun) links;
struct scsi_sense_data *pending_sense[CTL_MAX_PORTS];
ctl_ua_type *pending_ua[CTL_MAX_PORTS];
struct scsi_sense_data **pending_sense;
ctl_ua_type **pending_ua;
uint8_t ua_tpt_info[8];
time_t lasttpt;
uint8_t ie_asc; /* Informational exceptions */
@ -407,7 +407,7 @@ struct ctl_lun {
struct ctl_io_stats stats;
uint32_t res_idx;
uint32_t pr_generation;
uint64_t *pr_keys[CTL_MAX_PORTS];
uint64_t **pr_keys;
int pr_key_count;
uint32_t pr_res_idx;
uint8_t pr_res_type;
@ -453,16 +453,16 @@ struct ctl_softc {
struct sysctl_oid *sysctl_tree;
void *othersc_pool;
struct proc *ctl_proc;
uint32_t ctl_lun_mask[(CTL_MAX_LUNS + 31) / 32];
struct ctl_lun *ctl_luns[CTL_MAX_LUNS];
uint32_t ctl_port_mask[(CTL_MAX_PORTS + 31) / 32];
uint32_t *ctl_lun_mask;
struct ctl_lun **ctl_luns;
uint32_t *ctl_port_mask;
STAILQ_HEAD(, ctl_lun) lun_list;
STAILQ_HEAD(, ctl_be_lun) pending_lun_queue;
uint32_t num_frontends;
STAILQ_HEAD(, ctl_frontend) fe_list;
uint32_t num_ports;
STAILQ_HEAD(, ctl_port) port_list;
struct ctl_port *ctl_ports[CTL_MAX_PORTS];
struct ctl_port **ctl_ports;
uint32_t num_backends;
STAILQ_HEAD(, ctl_backend_driver) be_list;
struct uma_zone *io_zone;