diff options
Diffstat (limited to 'usr.sbin/ctld/kernel.c')
-rw-r--r-- | usr.sbin/ctld/kernel.c | 62 |
1 files changed, 54 insertions, 8 deletions
diff --git a/usr.sbin/ctld/kernel.c b/usr.sbin/ctld/kernel.c index cde4486..dea1917 100644 --- a/usr.sbin/ctld/kernel.c +++ b/usr.sbin/ctld/kernel.c @@ -60,10 +60,8 @@ __FBSDID("$FreeBSD$"); #include <cam/scsi/scsi_message.h> #include <cam/ctl/ctl.h> #include <cam/ctl/ctl_io.h> -#include <cam/ctl/ctl_frontend_internal.h> #include <cam/ctl/ctl_backend.h> #include <cam/ctl/ctl_ioctl.h> -#include <cam/ctl/ctl_backend_block.h> #include <cam/ctl/ctl_util.h> #include <cam/ctl/ctl_scsi_all.h> @@ -110,6 +108,7 @@ struct cctl_lun_nv { struct cctl_lun { uint64_t lun_id; char *backend_type; + uint8_t device_type; uint64_t size_blocks; uint32_t blocksize; char *serial_number; @@ -121,6 +120,7 @@ struct cctl_lun { struct cctl_port { uint32_t port_id; + char *port_frontend; char *port_name; int pp; int vp; @@ -222,6 +222,8 @@ cctl_end_element(void *user_data, const char *name) if (strcmp(name, "backend_type") == 0) { cur_lun->backend_type = str; str = NULL; + } else if (strcmp(name, "lun_type") == 0) { + cur_lun->device_type = strtoull(str, NULL, 0); } else if (strcmp(name, "size") == 0) { cur_lun->size_blocks = strtoull(str, NULL, 0); } else if (strcmp(name, "blocksize") == 0) { @@ -333,7 +335,10 @@ cctl_end_pelement(void *user_data, const char *name) devlist->cur_sb[devlist->level] = NULL; devlist->level--; - if (strcmp(name, "port_name") == 0) { + if (strcmp(name, "frontend_type") == 0) { + cur_port->port_frontend = str; + str = NULL; + } else if (strcmp(name, "port_name") == 0) { cur_port->port_name = str; str = NULL; } else if (strcmp(name, "physical_port") == 0) { @@ -473,7 +478,7 @@ retry_port: return (NULL); } - if (list.status == CTL_PORT_LIST_ERROR) { + if (list.status == CTL_LUN_LIST_ERROR) { log_warnx("error returned from CTL_PORT_LIST ioctl: %s", list.error_str); free(str); @@ -508,6 +513,8 @@ retry_port: name = NULL; STAILQ_FOREACH(port, &devlist.port_list, links) { + if (strcmp(port->port_frontend, "ha") == 0) + continue; if (name) free(name); if (port->pp == 0 && port->vp == 0) @@ -606,6 +613,7 @@ retry_port: continue; } lun_set_backend(cl, lun->backend_type); + lun_set_device_type(cl, lun->device_type); lun_set_blocksize(cl, lun->blocksize); lun_set_device_id(cl, lun->device_id); lun_set_serial(cl, lun->serial_number); @@ -658,8 +666,13 @@ kernel_lun_add(struct lun *lun) if (lun->l_size != 0) req.reqdata.create.lun_size_bytes = lun->l_size; + if (lun->l_ctl_lun >= 0) { + req.reqdata.create.req_lun_id = lun->l_ctl_lun; + req.reqdata.create.flags |= CTL_LUN_FLAG_ID_REQ; + } + req.reqdata.create.flags |= CTL_LUN_FLAG_DEV_TYPE; - req.reqdata.create.device_type = T_DIRECT; + req.reqdata.create.device_type = lun->l_device_type; if (lun->l_serial != NULL) { strncpy(req.reqdata.create.serial_num, lun->l_serial, @@ -745,9 +758,11 @@ kernel_lun_add(struct lun *lun) } int -kernel_lun_resize(struct lun *lun) +kernel_lun_modify(struct lun *lun) { + struct lun_option *lo; struct ctl_lun_req req; + int error, i, num_options; bzero(&req, sizeof(req)); @@ -757,7 +772,30 @@ kernel_lun_resize(struct lun *lun) req.reqdata.modify.lun_id = lun->l_ctl_lun; req.reqdata.modify.lun_size_bytes = lun->l_size; - if (ioctl(ctl_fd, CTL_LUN_REQ, &req) == -1) { + num_options = 0; + TAILQ_FOREACH(lo, &lun->l_options, lo_next) + num_options++; + + req.num_be_args = num_options; + if (num_options > 0) { + req.be_args = malloc(num_options * sizeof(*req.be_args)); + if (req.be_args == NULL) { + log_warn("error allocating %zd bytes", + num_options * sizeof(*req.be_args)); + return (1); + } + + i = 0; + TAILQ_FOREACH(lo, &lun->l_options, lo_next) { + str_arg(&req.be_args[i], lo->lo_name, lo->lo_value); + i++; + } + assert(i == num_options); + } + + error = ioctl(ctl_fd, CTL_LUN_REQ, &req); + free(req.be_args); + if (error != 0) { log_warn("error issuing CTL_LUN_REQ ioctl"); return (1); } @@ -963,11 +1001,13 @@ kernel_port_add(struct port *port) } int -kernel_port_update(struct port *port) +kernel_port_update(struct port *port, struct port *oport) { struct ctl_lun_map lm; struct target *targ = port->p_target; + struct target *otarg = oport->p_target; int error, i; + uint32_t olun; /* Map configured LUNs and unmap others */ for (i = 0; i < MAX_LUNS; i++) { @@ -977,6 +1017,12 @@ kernel_port_update(struct port *port) lm.lun = UINT32_MAX; else lm.lun = targ->t_luns[i]->l_ctl_lun; + if (otarg->t_luns[i] == NULL) + olun = UINT32_MAX; + else + olun = otarg->t_luns[i]->l_ctl_lun; + if (lm.lun == olun) + continue; error = ioctl(ctl_fd, CTL_LUN_MAP, &lm); if (error != 0) log_warn("CTL_LUN_MAP ioctl failed"); |