Page MenuHomeFreeBSD

D9299.id24342.diff
No OneTemporary

D9299.id24342.diff

Index: sys/cam/ctl/ctl.h
===================================================================
--- sys/cam/ctl/ctl.h
+++ sys/cam/ctl/ctl.h
@@ -194,24 +194,6 @@
void ctl_isc_announce_mode(struct ctl_lun *lun, uint32_t initidx,
uint8_t page, uint8_t subpage);
-/*
- * KPI to manipulate LUN/port options
- */
-
-struct ctl_option {
- STAILQ_ENTRY(ctl_option) links;
- char *name;
- char *value;
-};
-typedef STAILQ_HEAD(ctl_options, ctl_option) ctl_options_t;
-
-struct ctl_be_arg;
-void ctl_init_opts(ctl_options_t *opts, int num_args, struct ctl_be_arg *args);
-void ctl_update_opts(ctl_options_t *opts, int num_args,
- struct ctl_be_arg *args);
-void ctl_free_opts(ctl_options_t *opts);
-char * ctl_get_opt(ctl_options_t *opts, const char *name);
-int ctl_get_opt_number(ctl_options_t *opts, const char *name, uint64_t *num);
int ctl_expand_number(const char *buf, uint64_t *num);
#endif /* _KERNEL */
Index: sys/cam/ctl/ctl.c
===================================================================
--- sys/cam/ctl/ctl.c
+++ sys/cam/ctl/ctl.c
@@ -65,6 +65,8 @@
#include <sys/smp.h>
#include <sys/endian.h>
#include <sys/sysctl.h>
+#include <sys/nv.h>
+#include <sys/dnv.h>
#include <vm/uma.h>
#include <cam/cam.h>
@@ -2414,105 +2416,6 @@
return (kptr);
}
-static void
-ctl_free_args(int num_args, struct ctl_be_arg *args)
-{
- int i;
-
- if (args == NULL)
- return;
-
- for (i = 0; i < num_args; i++) {
- free(args[i].kname, M_CTL);
- free(args[i].kvalue, M_CTL);
- }
-
- free(args, M_CTL);
-}
-
-static struct ctl_be_arg *
-ctl_copyin_args(int num_args, struct ctl_be_arg *uargs,
- char *error_str, size_t error_str_len)
-{
- struct ctl_be_arg *args;
- int i;
-
- args = ctl_copyin_alloc(uargs, num_args * sizeof(*args),
- error_str, error_str_len);
-
- if (args == NULL)
- goto bailout;
-
- for (i = 0; i < num_args; i++) {
- args[i].kname = NULL;
- args[i].kvalue = NULL;
- }
-
- for (i = 0; i < num_args; i++) {
- uint8_t *tmpptr;
-
- if (args[i].namelen == 0) {
- snprintf(error_str, error_str_len, "Argument %d "
- "name length is zero", i);
- goto bailout;
- }
-
- args[i].kname = ctl_copyin_alloc(args[i].name,
- args[i].namelen, error_str, error_str_len);
- if (args[i].kname == NULL)
- goto bailout;
-
- if (args[i].kname[args[i].namelen - 1] != '\0') {
- snprintf(error_str, error_str_len, "Argument %d "
- "name is not NUL-terminated", i);
- goto bailout;
- }
-
- if (args[i].flags & CTL_BEARG_RD) {
- if (args[i].vallen == 0) {
- snprintf(error_str, error_str_len, "Argument %d "
- "value length is zero", i);
- goto bailout;
- }
-
- tmpptr = ctl_copyin_alloc(args[i].value,
- args[i].vallen, error_str, error_str_len);
- if (tmpptr == NULL)
- goto bailout;
-
- if ((args[i].flags & CTL_BEARG_ASCII)
- && (tmpptr[args[i].vallen - 1] != '\0')) {
- snprintf(error_str, error_str_len, "Argument "
- "%d value is not NUL-terminated", i);
- free(tmpptr, M_CTL);
- goto bailout;
- }
- args[i].kvalue = tmpptr;
- } else {
- args[i].kvalue = malloc(args[i].vallen,
- M_CTL, M_WAITOK | M_ZERO);
- }
- }
-
- return (args);
-bailout:
-
- ctl_free_args(num_args, args);
-
- return (NULL);
-}
-
-static void
-ctl_copyout_args(int num_args, struct ctl_be_arg *args)
-{
- int i;
-
- for (i = 0; i < num_args; i++) {
- if (args[i].flags & CTL_BEARG_WR)
- copyout(args[i].kvalue, args[i].value, args[i].vallen);
- }
-}
-
/*
* Escape characters that are illegal or not recommended in XML.
*/
@@ -2984,8 +2887,12 @@
case CTL_LUN_REQ: {
struct ctl_lun_req *lun_req;
struct ctl_backend_driver *backend;
+ void *packed;
+ nvlist_t *tmp_args_nvl;
+ size_t packed_len;
lun_req = (struct ctl_lun_req *)addr;
+ tmp_args_nvl = lun_req->args_nvl;
backend = ctl_backend_find(lun_req->backend);
if (backend == NULL) {
@@ -2996,25 +2903,44 @@
lun_req->backend);
break;
}
- if (lun_req->num_be_args > 0) {
- lun_req->kern_be_args = ctl_copyin_args(
- lun_req->num_be_args,
- lun_req->be_args,
- lun_req->error_str,
- sizeof(lun_req->error_str));
- if (lun_req->kern_be_args == NULL) {
+
+ if (lun_req->args != NULL) {
+ lun_req->args = ctl_copyin_alloc(lun_req->args,
+ lun_req->args_len, lun_req->error_str,
+ sizeof(lun_req->error_str));
+
+ if (lun_req->args == NULL) {
lun_req->status = CTL_LUN_ERROR;
break;
}
- }
+ lun_req->args_nvl = nvlist_unpack(lun_req->args,
+ lun_req->args_len, 0);
+
+ if (lun_req->args_nvl == NULL) {
+ lun_req->status = CTL_LUN_ERROR;
+ break;
+ }
+ } else
+ lun_req->args_nvl = nvlist_create(0);
+
retval = backend->ioctl(dev, cmd, addr, flag, td);
+ nvlist_destroy(lun_req->args_nvl);
+ lun_req->args_nvl = tmp_args_nvl;
- if (lun_req->num_be_args > 0) {
- ctl_copyout_args(lun_req->num_be_args,
- lun_req->kern_be_args);
- ctl_free_args(lun_req->num_be_args,
- lun_req->kern_be_args);
+ if (lun_req->result_nvl != NULL) {
+ packed = nvlist_pack(lun_req->result_nvl, &packed_len);
+ if (packed == NULL) {
+ lun_req->status = CTL_LUN_ERROR;
+ break;
+ }
+
+ if (packed_len <= lun_req->result_len)
+ copyout(packed, lun_req->result, packed_len);
+
+ lun_req->result_len = packed_len;
+ free(packed, M_NVLIST);
+ nvlist_destroy(lun_req->result_nvl);
}
break;
}
@@ -3021,7 +2947,10 @@
case CTL_LUN_LIST: {
struct sbuf *sb;
struct ctl_lun_list *list;
- struct ctl_option *opt;
+ const char *name, *value;
+ void *cookie = NULL;
+ int type;
+ uint64_t valuei;
list = (struct ctl_lun_list *)addr;
@@ -3147,11 +3076,24 @@
if (retval != 0)
break;
}
- STAILQ_FOREACH(opt, &lun->be_lun->options, links) {
- retval = sbuf_printf(sb, "\t<%s>%s</%s>\n",
- opt->name, opt->value, opt->name);
- if (retval != 0)
- break;
+
+ while ((name = nvlist_next(lun->be_lun->options, &type,
+ &cookie)) != NULL) {
+ sbuf_printf(sb, "\t<%s>", name);
+
+ if (type == NV_TYPE_STRING) {
+ value = nvlist_get_string(
+ lun->be_lun->options, name);
+ sbuf_printf(sb, "%s", value);
+ }
+
+ if (type == NV_TYPE_NUMBER) {
+ valuei = nvlist_get_number(
+ lun->be_lun->options, name);
+ sbuf_printf(sb, "%lu", valuei);
+ }
+
+ sbuf_printf(sb, "</%s>\n", name);
}
retval = sbuf_printf(sb, "</lun>\n");
@@ -3205,8 +3147,12 @@
case CTL_PORT_REQ: {
struct ctl_req *req;
struct ctl_frontend *fe;
+ void *packed;
+ nvlist_t *tmp_args_nvl;
+ size_t packed_len;
req = (struct ctl_req *)addr;
+ tmp_args_nvl = req->args_nvl;
fe = ctl_frontend_find(req->driver);
if (fe == NULL) {
@@ -3215,23 +3161,54 @@
"Frontend \"%s\" not found.", req->driver);
break;
}
- if (req->num_args > 0) {
- req->kern_args = ctl_copyin_args(req->num_args,
- req->args, req->error_str, sizeof(req->error_str));
- if (req->kern_args == NULL) {
+
+ if (req->args != NULL) {
+ req->args = ctl_copyin_alloc(req->args,
+ req->args_len, req->error_str,
+ sizeof(req->error_str));
+
+ if (req->args == NULL) {
req->status = CTL_LUN_ERROR;
+ snprintf(req->error_str, sizeof(req->error_str),
+ "Cannot copyin args.");
break;
}
- }
+ req->args_nvl = nvlist_unpack(req->args,
+ req->args_len, 0);
+
+ if (req->args_nvl == NULL) {
+ req->status = CTL_LUN_ERROR;
+ snprintf(req->error_str, sizeof(req->error_str),
+ "Cannot unpack args nvlist.");
+ break;
+ }
+ } else
+ req->args_nvl = nvlist_create(0);
+
if (fe->ioctl)
retval = fe->ioctl(dev, cmd, addr, flag, td);
else
retval = ENODEV;
- if (req->num_args > 0) {
- ctl_copyout_args(req->num_args, req->kern_args);
- ctl_free_args(req->num_args, req->kern_args);
+ nvlist_destroy(req->args_nvl);
+ req->args_nvl = tmp_args_nvl;
+
+ if (req->result_nvl != NULL) {
+ packed = nvlist_pack(req->result_nvl, &packed_len);
+ if (packed == NULL) {
+ req->status = CTL_LUN_ERROR;
+ snprintf(req->error_str, sizeof(req->error_str),
+ "Cannot pack result nvlist.");
+ break;
+ }
+
+ if (packed_len <= req->result_len)
+ copyout(packed, req->result, packed_len);
+
+ req->result_len = packed_len;
+ free(packed, M_NVLIST);
+ nvlist_destroy(req->result_nvl);
}
break;
}
@@ -3239,8 +3216,10 @@
struct sbuf *sb;
struct ctl_port *port;
struct ctl_lun_list *list;
- struct ctl_option *opt;
- int j;
+ const char *name, *value;
+ void *cookie = NULL;
+ int j, type;
+ uint64_t valuei;
uint32_t plun;
list = (struct ctl_lun_list *)addr;
@@ -3315,11 +3294,25 @@
if (retval != 0)
break;
}
- STAILQ_FOREACH(opt, &port->options, links) {
- retval = sbuf_printf(sb, "\t<%s>%s</%s>\n",
- opt->name, opt->value, opt->name);
- if (retval != 0)
- break;
+
+ printf("port_name = %s, port_options = %p\n", port->port_name, port->options);
+ while ((name = nvlist_next(port->options, &type,
+ &cookie)) != NULL) {
+ sbuf_printf(sb, "\t<%s>", name);
+
+ if (type == NV_TYPE_STRING) {
+ value = nvlist_get_string(port->options,
+ name);
+ sbuf_printf(sb, "%s", value);
+ }
+
+ if (type == NV_TYPE_NUMBER) {
+ valuei = nvlist_get_number(port->options,
+ name);
+ sbuf_printf(sb, "%lu", valuei);
+ }
+
+ sbuf_printf(sb, "</%s>\n", name);
}
if (port->lun_map != NULL) {
@@ -4126,8 +4119,8 @@
CTL_PAGE_DEFAULT];
scsi_ulto3b(cylinders, rigid_disk_page->cylinders);
- if ((value = ctl_get_opt(&lun->be_lun->options,
- "rpm")) != NULL) {
+ if ((value = dnvlist_get_string(lun->be_lun->options,
+ "rpm", NULL)) != NULL) {
scsi_ulto2b(strtol(value, NULL, 0),
rigid_disk_page->rotation_rate);
}
@@ -4180,10 +4173,12 @@
sizeof(caching_page_default));
caching_page = &lun->mode_pages.caching_page[
CTL_PAGE_SAVED];
- value = ctl_get_opt(&lun->be_lun->options, "writecache");
+ value = dnvlist_get_string(lun->be_lun->options,
+ "writecache", NULL);
if (value != NULL && strcmp(value, "off") == 0)
caching_page->flags1 &= ~SCP_WCE;
- value = ctl_get_opt(&lun->be_lun->options, "readcache");
+ value = dnvlist_get_string(lun->be_lun->options,
+ "readcache", NULL);
if (value != NULL && strcmp(value, "off") == 0)
caching_page->flags1 |= SCP_RCD;
memcpy(&lun->mode_pages.caching_page[CTL_PAGE_CURRENT],
@@ -4212,8 +4207,8 @@
sizeof(control_page_default));
control_page = &lun->mode_pages.control_page[
CTL_PAGE_SAVED];
- value = ctl_get_opt(&lun->be_lun->options,
- "reordering");
+ value = dnvlist_get_string(lun->be_lun->options,
+ "reordering", NULL);
if (value != NULL &&
strcmp(value, "unrestricted") == 0) {
control_page->queue_flags &=
@@ -4288,8 +4283,8 @@
&lbp_page_default,
sizeof(lbp_page_default));
page = &lun->mode_pages.lbp_page[CTL_PAGE_SAVED];
- value = ctl_get_opt(&lun->be_lun->options,
- "avail-threshold");
+ value = dnvlist_get_string(lun->be_lun->options,
+ "avail-threshold", NULL);
if (value != NULL &&
ctl_expand_number(value, &ival) == 0) {
page->descr[0].flags |= SLBPPD_ENABLED |
@@ -4301,8 +4296,8 @@
scsi_ulto4b(ival >> CTL_LBP_EXPONENT,
page->descr[0].count);
}
- value = ctl_get_opt(&lun->be_lun->options,
- "used-threshold");
+ value = dnvlist_get_string(lun->be_lun->options,
+ "used-threshold", NULL);
if (value != NULL &&
ctl_expand_number(value, &ival) == 0) {
page->descr[1].flags |= SLBPPD_ENABLED |
@@ -4314,8 +4309,8 @@
scsi_ulto4b(ival >> CTL_LBP_EXPONENT,
page->descr[1].count);
}
- value = ctl_get_opt(&lun->be_lun->options,
- "pool-avail-threshold");
+ value = dnvlist_get_string(lun->be_lun->options,
+ "pool-avail-threshold", NULL);
if (value != NULL &&
ctl_expand_number(value, &ival) == 0) {
page->descr[2].flags |= SLBPPD_ENABLED |
@@ -4327,8 +4322,8 @@
scsi_ulto4b(ival >> CTL_LBP_EXPONENT,
page->descr[2].count);
}
- value = ctl_get_opt(&lun->be_lun->options,
- "pool-used-threshold");
+ value = dnvlist_get_string(lun->be_lun->options,
+ "pool-used-threshold", NULL);
if (value != NULL &&
ctl_expand_number(value, &ival) == 0) {
page->descr[3].flags |= SLBPPD_ENABLED |
@@ -4520,20 +4515,20 @@
strnlen(be_lun->device_id, CTL_DEVID_LEN));
idlen1 = sizeof(*t10id) + devidlen;
len = sizeof(struct scsi_vpd_id_descriptor) + idlen1;
- scsiname = ctl_get_opt(&be_lun->options, "scsiname");
+ scsiname = dnvlist_get_string(be_lun->options, "scsiname", NULL);
if (scsiname != NULL) {
idlen2 = roundup2(strlen(scsiname) + 1, 4);
len += sizeof(struct scsi_vpd_id_descriptor) + idlen2;
}
- eui = ctl_get_opt(&be_lun->options, "eui");
+ eui = dnvlist_get_string(be_lun->options, "eui", NULL);
if (eui != NULL) {
len += sizeof(struct scsi_vpd_id_descriptor) + 16;
}
- naa = ctl_get_opt(&be_lun->options, "naa");
+ naa = dnvlist_get_string(be_lun->options, "naa", NULL);
if (naa != NULL) {
len += sizeof(struct scsi_vpd_id_descriptor) + 16;
}
- uuid = ctl_get_opt(&be_lun->options, "uuid");
+ uuid = dnvlist_get_string(be_lun->options, "uuid", NULL);
if (uuid != NULL) {
len += sizeof(struct scsi_vpd_id_descriptor) + 18;
}
@@ -4545,7 +4540,7 @@
desc->length = idlen1;
t10id = (struct scsi_vpd_id_t10 *)&desc->identifier[0];
memset(t10id->vendor, ' ', sizeof(t10id->vendor));
- if ((vendor = ctl_get_opt(&be_lun->options, "vendor")) == NULL) {
+ if ((vendor = dnvlist_get_string(be_lun->options, "vendor", NULL)) == NULL) {
strncpy((char *)t10id->vendor, CTL_VENDOR, sizeof(t10id->vendor));
} else {
strncpy(t10id->vendor, vendor,
@@ -4658,7 +4653,7 @@
if (be_lun->flags & CTL_LUN_FLAG_PRIMARY)
lun->flags |= CTL_LUN_PRIMARY_SC;
- value = ctl_get_opt(&be_lun->options, "removable");
+ value = dnvlist_get_string(be_lun->options, "removable", NULL);
if (value != NULL) {
if (strcmp(value, "on") == 0)
lun->flags |= CTL_LUN_REMOVABLE;
@@ -9716,6 +9711,7 @@
{
struct ctl_lun *lun = CTL_LUN(ctsio);
struct scsi_vpd_block_limits *bl_ptr;
+ const char *val;
uint64_t ival;
ctsio->kern_data_ptr = malloc(sizeof(*bl_ptr), M_CTL, M_WAITOK | M_ZERO);
@@ -9745,12 +9741,16 @@
scsi_ulto4b(lun->be_lun->opttxferlen, bl_ptr->opt_txfer_len);
if (lun->be_lun->flags & CTL_LUN_FLAG_UNMAP) {
ival = 0xffffffff;
- ctl_get_opt_number(&lun->be_lun->options,
- "unmap_max_lba", &ival);
+ val = dnvlist_get_string(lun->be_lun->options,
+ "unmap_max_lba", NULL);
+ if (val != NULL)
+ ctl_expand_number(val, &ival);
scsi_ulto4b(ival, bl_ptr->max_unmap_lba_cnt);
ival = 0xffffffff;
- ctl_get_opt_number(&lun->be_lun->options,
- "unmap_max_descr", &ival);
+ val = dnvlist_get_string(lun->be_lun->options,
+ "unmap_max_descr", NULL);
+ if (val != NULL)
+ ctl_expand_number(val, &ival);
scsi_ulto4b(ival, bl_ptr->max_unmap_blk_cnt);
if (lun->be_lun->ublockexp != 0) {
scsi_ulto4b((1 << lun->be_lun->ublockexp),
@@ -9766,7 +9766,10 @@
scsi_ulto4b(0, bl_ptr->max_atomic_transfer_length_with_atomic_boundary);
scsi_ulto4b(0, bl_ptr->max_atomic_boundary_size);
ival = UINT64_MAX;
- ctl_get_opt_number(&lun->be_lun->options, "write_same_max_lba", &ival);
+ val = dnvlist_get_string(lun->be_lun->options,
+ "write_same_max_lba", NULL);
+ if (val != NULL)
+ ctl_expand_number(val, &ival);
scsi_u64to8b(ival, bl_ptr->max_write_same_length);
}
@@ -9805,13 +9808,13 @@
bdc_ptr->page_code = SVPD_BDC;
scsi_ulto2b(sizeof(*bdc_ptr) - 4, bdc_ptr->page_length);
if (lun != NULL &&
- (value = ctl_get_opt(&lun->be_lun->options, "rpm")) != NULL)
+ (value = dnvlist_get_string(lun->be_lun->options, "rpm", NULL)) != NULL)
i = strtol(value, NULL, 0);
else
i = CTL_DEFAULT_ROTATION_RATE;
scsi_ulto2b(i, bdc_ptr->medium_rotation_rate);
if (lun != NULL &&
- (value = ctl_get_opt(&lun->be_lun->options, "formfactor")) != NULL)
+ (value = dnvlist_get_string(lun->be_lun->options, "formfactor", NULL)) != NULL)
i = strtol(value, NULL, 0);
else
i = 0;
@@ -9856,7 +9859,8 @@
if (lun != NULL && lun->be_lun->flags & CTL_LUN_FLAG_UNMAP) {
lbp_ptr->flags = SVPD_LBP_UNMAP | SVPD_LBP_WS16 |
SVPD_LBP_WS10 | SVPD_LBP_RZ | SVPD_LBP_ANC_SUP;
- value = ctl_get_opt(&lun->be_lun->options, "provisioning_type");
+ value = dnvlist_get_string(lun->be_lun->options,
+ "provisioning_type", NULL);
if (value != NULL) {
if (strcmp(value, "resource") == 0)
lbp_ptr->prov_type = SVPD_LBP_RESOURCE;
@@ -9950,7 +9954,7 @@
struct ctl_lun *lun = CTL_LUN(ctsio);
struct scsi_inquiry_data *inq_ptr;
struct scsi_inquiry *cdb;
- char *val;
+ const char *val;
uint32_t alloc_len, data_len;
ctl_port_type port_type;
@@ -10028,8 +10032,8 @@
* We have 8 bytes for the vendor name, and 16 bytes for the device
* name and 4 bytes for the revision.
*/
- if (lun == NULL || (val = ctl_get_opt(&lun->be_lun->options,
- "vendor")) == NULL) {
+ if (lun == NULL || (val = dnvlist_get_string(lun->be_lun->options,
+ "vendor", NULL)) == NULL) {
strncpy(inq_ptr->vendor, CTL_VENDOR, sizeof(inq_ptr->vendor));
} else {
memset(inq_ptr->vendor, ' ', sizeof(inq_ptr->vendor));
@@ -10039,7 +10043,8 @@
if (lun == NULL) {
strncpy(inq_ptr->product, CTL_DIRECT_PRODUCT,
sizeof(inq_ptr->product));
- } else if ((val = ctl_get_opt(&lun->be_lun->options, "product")) == NULL) {
+ } else if ((val = dnvlist_get_string(lun->be_lun->options, "product",
+ NULL)) == NULL) {
switch (lun->be_lun->lun_type) {
case T_DIRECT:
strncpy(inq_ptr->product, CTL_DIRECT_PRODUCT,
@@ -10068,8 +10073,8 @@
* XXX make this a macro somewhere so it automatically gets
* incremented when we make changes.
*/
- if (lun == NULL || (val = ctl_get_opt(&lun->be_lun->options,
- "revision")) == NULL) {
+ if (lun == NULL || (val = dnvlist_get_string(lun->be_lun->options,
+ "revision", NULL)) == NULL) {
strncpy(inq_ptr->revision, "0001", sizeof(inq_ptr->revision));
} else {
memset(inq_ptr->revision, ' ', sizeof(inq_ptr->revision));
Index: sys/cam/ctl/ctl_backend.h
===================================================================
--- sys/cam/ctl/ctl_backend.h
+++ sys/cam/ctl/ctl_backend.h
@@ -86,6 +86,8 @@
typedef void (*be_lun_config_t)(void *be_lun,
ctl_lun_config_status status);
+#include <sys/nv.h>
+
/*
* The lun_type field is the SCSI device type of this particular LUN. In
* general, this should be T_DIRECT, although backends will want to create
@@ -173,7 +175,7 @@
be_lun_config_t lun_config_status; /* passed to CTL */
struct ctl_backend_driver *be; /* passed to CTL */
void *ctl_lun; /* used by CTL */
- ctl_options_t options; /* passed to CTL */
+ nvlist_t *options; /* passed to CTL */
STAILQ_ENTRY(ctl_be_lun) links; /* used by CTL */
};
Index: sys/cam/ctl/ctl_backend.c
===================================================================
--- sys/cam/ctl/ctl_backend.c
+++ sys/cam/ctl/ctl_backend.c
@@ -139,93 +139,3 @@
return (NULL);
}
-void
-ctl_init_opts(ctl_options_t *opts, int num_args, struct ctl_be_arg *args)
-{
- struct ctl_option *opt;
- int i;
-
- STAILQ_INIT(opts);
- for (i = 0; i < num_args; i++) {
- if ((args[i].flags & CTL_BEARG_RD) == 0)
- continue;
- if ((args[i].flags & CTL_BEARG_ASCII) == 0)
- continue;
- opt = malloc(sizeof(*opt), M_CTL, M_WAITOK);
- opt->name = strdup(args[i].kname, M_CTL);
- opt->value = strdup(args[i].kvalue, M_CTL);
- STAILQ_INSERT_TAIL(opts, opt, links);
- }
-}
-
-void
-ctl_update_opts(ctl_options_t *opts, int num_args, struct ctl_be_arg *args)
-{
- struct ctl_option *opt;
- int i;
-
- for (i = 0; i < num_args; i++) {
- if ((args[i].flags & CTL_BEARG_RD) == 0)
- continue;
- if ((args[i].flags & CTL_BEARG_ASCII) == 0)
- continue;
- STAILQ_FOREACH(opt, opts, links) {
- if (strcmp(opt->name, args[i].kname) == 0)
- break;
- }
- if (args[i].kvalue != NULL &&
- ((char *)args[i].kvalue)[0] != 0) {
- if (opt) {
- free(opt->value, M_CTL);
- opt->value = strdup(args[i].kvalue, M_CTL);
- } else {
- opt = malloc(sizeof(*opt), M_CTL, M_WAITOK);
- opt->name = strdup(args[i].kname, M_CTL);
- opt->value = strdup(args[i].kvalue, M_CTL);
- STAILQ_INSERT_TAIL(opts, opt, links);
- }
- } else if (opt) {
- STAILQ_REMOVE(opts, opt, ctl_option, links);
- free(opt->name, M_CTL);
- free(opt->value, M_CTL);
- free(opt, M_CTL);
- }
- }
-}
-
-void
-ctl_free_opts(ctl_options_t *opts)
-{
- struct ctl_option *opt;
-
- while ((opt = STAILQ_FIRST(opts)) != NULL) {
- STAILQ_REMOVE_HEAD(opts, links);
- free(opt->name, M_CTL);
- free(opt->value, M_CTL);
- free(opt, M_CTL);
- }
-}
-
-char *
-ctl_get_opt(ctl_options_t *opts, const char *name)
-{
- struct ctl_option *opt;
-
- STAILQ_FOREACH(opt, opts, links) {
- if (strcmp(opt->name, name) == 0) {
- return (opt->value);
- }
- }
- return (NULL);
-}
-
-int
-ctl_get_opt_number(ctl_options_t *opts, const char *name, uint64_t *val)
-{
- const char *value;
-
- value = ctl_get_opt(opts, name);
- if (value == NULL)
- return (-2);
- return (ctl_expand_number(value, val));
-}
Index: sys/cam/ctl/ctl_backend_block.c
===================================================================
--- sys/cam/ctl/ctl_backend_block.c
+++ sys/cam/ctl/ctl_backend_block.c
@@ -76,6 +76,8 @@
#include <sys/sdt.h>
#include <sys/devicestat.h>
#include <sys/sysctl.h>
+#include <sys/nv.h>
+#include <sys/dnv.h>
#include <geom/geom.h>
@@ -1815,7 +1817,7 @@
struct ctl_be_lun *cbe_lun;
struct ctl_be_block_filedata *file_data;
struct ctl_lun_create_params *params;
- char *value;
+ const char *value;
struct vattr vattr;
off_t ps, pss, po, pos, us, uss, uo, uos;
int error;
@@ -1865,10 +1867,10 @@
us = ps = vattr.va_blocksize;
uo = po = 0;
- value = ctl_get_opt(&cbe_lun->options, "pblocksize");
+ value = dnvlist_get_string(cbe_lun->options, "pblocksize", NULL);
if (value != NULL)
ctl_expand_number(value, &ps);
- value = ctl_get_opt(&cbe_lun->options, "pblockoffset");
+ value = dnvlist_get_string(cbe_lun->options, "pblockoffset", NULL);
if (value != NULL)
ctl_expand_number(value, &po);
pss = ps / cbe_lun->blocksize;
@@ -1879,10 +1881,10 @@
cbe_lun->pblockoff = (pss - pos) % pss;
}
- value = ctl_get_opt(&cbe_lun->options, "ublocksize");
+ value = dnvlist_get_string(cbe_lun->options, "ublocksize", NULL);
if (value != NULL)
ctl_expand_number(value, &us);
- value = ctl_get_opt(&cbe_lun->options, "ublockoffset");
+ value = dnvlist_get_string(cbe_lun->options, "ublockoffset", NULL);
if (value != NULL)
ctl_expand_number(value, &uo);
uss = us / cbe_lun->blocksize;
@@ -1915,7 +1917,7 @@
struct ctl_lun_create_params *params;
struct cdevsw *csw;
struct cdev *dev;
- char *value;
+ const char *value;
int error, atomic, maxio, ref, unmap, tmp;
off_t ps, pss, po, pos, us, uss, uo, uos, otmp;
@@ -2031,10 +2033,10 @@
us = ps;
uo = po;
- value = ctl_get_opt(&cbe_lun->options, "pblocksize");
+ value = dnvlist_get_string(cbe_lun->options, "pblocksize", NULL);
if (value != NULL)
ctl_expand_number(value, &ps);
- value = ctl_get_opt(&cbe_lun->options, "pblockoffset");
+ value = dnvlist_get_string(cbe_lun->options, "pblockoffset", NULL);
if (value != NULL)
ctl_expand_number(value, &po);
pss = ps / cbe_lun->blocksize;
@@ -2045,10 +2047,10 @@
cbe_lun->pblockoff = (pss - pos) % pss;
}
- value = ctl_get_opt(&cbe_lun->options, "ublocksize");
+ value = dnvlist_get_string(cbe_lun->options, "ublocksize", NULL);
if (value != NULL)
ctl_expand_number(value, &us);
- value = ctl_get_opt(&cbe_lun->options, "ublockoffset");
+ value = dnvlist_get_string(cbe_lun->options, "ublockoffset", NULL);
if (value != NULL)
ctl_expand_number(value, &uo);
uss = us / cbe_lun->blocksize;
@@ -2073,7 +2075,7 @@
curthread);
unmap = (error == 0) ? arg.value.i : 0;
}
- value = ctl_get_opt(&cbe_lun->options, "unmap");
+ value = dnvlist_get_string(cbe_lun->options, "unmap", NULL);
if (value != NULL)
unmap = (strcmp(value, "on") == 0);
if (unmap)
@@ -2123,7 +2125,7 @@
{
struct ctl_be_lun *cbe_lun = &be_lun->cbe_lun;
struct nameidata nd;
- char *value;
+ const char *value;
int error, flags;
error = 0;
@@ -2134,7 +2136,7 @@
}
pwd_ensure_dirs();
- value = ctl_get_opt(&cbe_lun->options, "file");
+ value = dnvlist_get_string(cbe_lun->options, "file", NULL);
if (value == NULL) {
snprintf(req->error_str, sizeof(req->error_str),
"no file argument specified");
@@ -2144,7 +2146,7 @@
be_lun->dev_path = strdup(value, M_CTLBLK);
flags = FREAD;
- value = ctl_get_opt(&cbe_lun->options, "readonly");
+ value = dnvlist_get_string(cbe_lun->options, "readonly", NULL);
if (value != NULL) {
if (strcmp(value, "on") != 0)
flags |= FWRITE;
@@ -2203,7 +2205,7 @@
cbe_lun->serseq = CTL_LUN_SERSEQ_OFF;
if (be_lun->dispatch != ctl_be_block_dispatch_dev)
cbe_lun->serseq = CTL_LUN_SERSEQ_READ;
- value = ctl_get_opt(&cbe_lun->options, "serseq");
+ value = dnvlist_get_string(cbe_lun->options, "serseq", NULL);
if (value != NULL && strcmp(value, "on") == 0)
cbe_lun->serseq = CTL_LUN_SERSEQ_ON;
else if (value != NULL && strcmp(value, "read") == 0)
@@ -2221,7 +2223,7 @@
struct ctl_lun_create_params *params;
char num_thread_str[16];
char tmpstr[32];
- char *value;
+ const char *value;
int retval, num_threads;
int tmp_num_threads;
@@ -2241,8 +2243,7 @@
sprintf(be_lun->lunname, "cblk%d", softc->num_luns);
mtx_init(&be_lun->io_lock, "cblk io lock", NULL, MTX_DEF);
mtx_init(&be_lun->queue_lock, "cblk queue lock", NULL, MTX_DEF);
- ctl_init_opts(&cbe_lun->options,
- req->num_be_args, req->kern_be_args);
+ cbe_lun->options = nvlist_clone(req->args_nvl);
be_lun->lun_zone = uma_zcreate(be_lun->lunname, CTLBLK_MAX_SEG,
NULL, NULL, NULL, NULL, /*align*/ 0, /*flags*/0);
if (be_lun->lun_zone == NULL) {
@@ -2257,7 +2258,7 @@
cbe_lun->lun_type = T_DIRECT;
be_lun->flags = CTL_BE_BLOCK_LUN_UNCONFIGURED;
cbe_lun->flags = 0;
- value = ctl_get_opt(&cbe_lun->options, "ha_role");
+ value = dnvlist_get_string(cbe_lun->options, "ha_role", NULL);
if (value != NULL) {
if (strcmp(value, "primary") == 0)
cbe_lun->flags |= CTL_LUN_FLAG_PRIMARY;
@@ -2290,7 +2291,7 @@
num_threads = 1;
}
- value = ctl_get_opt(&cbe_lun->options, "num_threads");
+ value = dnvlist_get_string(cbe_lun->options, "num_threads", NULL);
if (value != NULL) {
tmp_num_threads = strtol(value, NULL, 0);
@@ -2455,7 +2456,7 @@
free(be_lun->dev_path, M_CTLBLK);
if (be_lun->lun_zone != NULL)
uma_zdestroy(be_lun->lun_zone);
- ctl_free_opts(&cbe_lun->options);
+ nvlist_destroy(cbe_lun->options);
mtx_destroy(&be_lun->queue_lock);
mtx_destroy(&be_lun->io_lock);
free(be_lun, M_CTLBLK);
@@ -2539,7 +2540,7 @@
uma_zdestroy(be_lun->lun_zone);
- ctl_free_opts(&cbe_lun->options);
+ nvlist_destroy(cbe_lun->options);
free(be_lun->dev_path, M_CTLBLK);
mtx_destroy(&be_lun->queue_lock);
mtx_destroy(&be_lun->io_lock);
@@ -2559,7 +2560,7 @@
struct ctl_lun_modify_params *params;
struct ctl_be_block_lun *be_lun;
struct ctl_be_lun *cbe_lun;
- char *value;
+ const char *value;
uint64_t oldsize;
int error, wasprim;
@@ -2581,10 +2582,12 @@
if (params->lun_size_bytes != 0)
be_lun->params.lun_size_bytes = params->lun_size_bytes;
- ctl_update_opts(&cbe_lun->options, req->num_be_args, req->kern_be_args);
+ nvlist_destroy(cbe_lun->options);
+ cbe_lun->options = nvlist_clone(req->args_nvl);
+
wasprim = (cbe_lun->flags & CTL_LUN_FLAG_PRIMARY);
- value = ctl_get_opt(&cbe_lun->options, "ha_role");
+ value = dnvlist_get_string(cbe_lun->options, "ha_role", NULL);
if (value != NULL) {
if (strcmp(value, "primary") == 0)
cbe_lun->flags |= CTL_LUN_FLAG_PRIMARY;
Index: sys/cam/ctl/ctl_backend_ramdisk.c
===================================================================
--- sys/cam/ctl/ctl_backend_ramdisk.c
+++ sys/cam/ctl/ctl_backend_ramdisk.c
@@ -58,6 +58,8 @@
#include <sys/ioccom.h>
#include <sys/module.h>
#include <sys/sysctl.h>
+#include <sys/nv.h>
+#include <sys/dnv.h>
#include <cam/scsi/scsi_all.h>
#include <cam/scsi/scsi_da.h>
@@ -465,7 +467,7 @@
if (retval == 0) {
taskqueue_drain_all(be_lun->io_taskqueue);
taskqueue_free(be_lun->io_taskqueue);
- ctl_free_opts(&be_lun->cbe_lun.options);
+ nvlist_destroy(be_lun->cbe_lun.options);
mtx_destroy(&be_lun->queue_lock);
free(be_lun, M_RAMDISK);
}
@@ -485,7 +487,7 @@
struct ctl_be_ramdisk_lun *be_lun;
struct ctl_be_lun *cbe_lun;
struct ctl_lun_create_params *params;
- char *value;
+ const char *value;
char tmpstr[32];
int retval;
@@ -495,10 +497,10 @@
be_lun = malloc(sizeof(*be_lun), M_RAMDISK, M_ZERO | M_WAITOK);
cbe_lun = &be_lun->cbe_lun;
cbe_lun->be_lun = be_lun;
+ cbe_lun->options = nvlist_clone(req->args_nvl);
be_lun->params = req->reqdata.create;
be_lun->softc = softc;
sprintf(be_lun->lunname, "cram%d", softc->num_luns);
- ctl_init_opts(&cbe_lun->options, req->num_be_args, req->kern_be_args);
if (params->flags & CTL_LUN_FLAG_DEV_TYPE)
cbe_lun->lun_type = params->device_type;
@@ -506,7 +508,7 @@
cbe_lun->lun_type = T_DIRECT;
be_lun->flags = CTL_BE_RAMDISK_LUN_UNCONFIGURED;
cbe_lun->flags = 0;
- value = ctl_get_opt(&cbe_lun->options, "ha_role");
+ value = dnvlist_get_string(cbe_lun->options, "ha_role", NULL);
if (value != NULL) {
if (strcmp(value, "primary") == 0)
cbe_lun->flags |= CTL_LUN_FLAG_PRIMARY;
@@ -538,10 +540,10 @@
params->blocksize_bytes = cbe_lun->blocksize;
params->lun_size_bytes = be_lun->size_bytes;
- value = ctl_get_opt(&cbe_lun->options, "unmap");
+ value = dnvlist_get_string(cbe_lun->options, "unmap", NULL);
if (value != NULL && strcmp(value, "on") == 0)
cbe_lun->flags |= CTL_LUN_FLAG_UNMAP;
- value = ctl_get_opt(&cbe_lun->options, "readonly");
+ value = dnvlist_get_string(cbe_lun->options, "readonly", NULL);
if (value != NULL) {
if (strcmp(value, "on") == 0)
cbe_lun->flags |= CTL_LUN_FLAG_READONLY;
@@ -548,7 +550,7 @@
} else if (cbe_lun->lun_type != T_DIRECT)
cbe_lun->flags |= CTL_LUN_FLAG_READONLY;
cbe_lun->serseq = CTL_LUN_SERSEQ_OFF;
- value = ctl_get_opt(&cbe_lun->options, "serseq");
+ value = dnvlist_get_string(cbe_lun->options, "serseq", NULL);
if (value != NULL && strcmp(value, "on") == 0)
cbe_lun->serseq = CTL_LUN_SERSEQ_ON;
else if (value != NULL && strcmp(value, "read") == 0)
@@ -671,7 +673,7 @@
if (be_lun->io_taskqueue != NULL) {
taskqueue_free(be_lun->io_taskqueue);
}
- ctl_free_opts(&cbe_lun->options);
+ nvlist_destroy(cbe_lun->options);
mtx_destroy(&be_lun->queue_lock);
free(be_lun, M_RAMDISK);
}
@@ -685,7 +687,7 @@
struct ctl_be_ramdisk_lun *be_lun;
struct ctl_be_lun *cbe_lun;
struct ctl_lun_modify_params *params;
- char *value;
+ const char *value;
uint32_t blocksize;
int wasprim;
@@ -707,10 +709,12 @@
if (params->lun_size_bytes != 0)
be_lun->params.lun_size_bytes = params->lun_size_bytes;
- ctl_update_opts(&cbe_lun->options, req->num_be_args, req->kern_be_args);
+ nvlist_destroy(cbe_lun->options);
+ cbe_lun->options = nvlist_clone(req->args_nvl);
+
wasprim = (cbe_lun->flags & CTL_LUN_FLAG_PRIMARY);
- value = ctl_get_opt(&cbe_lun->options, "ha_role");
+ value = dnvlist_get_string(cbe_lun->options, "ha_role", NULL);
if (value != NULL) {
if (strcmp(value, "primary") == 0)
cbe_lun->flags |= CTL_LUN_FLAG_PRIMARY;
Index: sys/cam/ctl/ctl_frontend.h
===================================================================
--- sys/cam/ctl/ctl_frontend.h
+++ sys/cam/ctl/ctl_frontend.h
@@ -42,6 +42,8 @@
#include <cam/ctl/ctl_ioctl.h>
+#include <sys/nv.h>
+
typedef enum {
CTL_PORT_STATUS_NONE = 0x00,
CTL_PORT_STATUS_ONLINE = 0x01,
@@ -235,7 +237,7 @@
uint64_t wwnn; /* set by CTL before online */
uint64_t wwpn; /* set by CTL before online */
ctl_port_status status; /* used by CTL */
- ctl_options_t options; /* passed to CTL */
+ nvlist_t *options; /* passed to CTL */
struct ctl_devid *port_devid; /* passed to CTL */
struct ctl_devid *target_devid; /* passed to CTL */
struct ctl_devid *init_devid; /* passed to CTL */
Index: sys/cam/ctl/ctl_frontend.c
===================================================================
--- sys/cam/ctl/ctl_frontend.c
+++ sys/cam/ctl/ctl_frontend.c
@@ -50,6 +50,8 @@
#include <sys/endian.h>
#include <sys/queue.h>
#include <sys/sysctl.h>
+#include <sys/nv.h>
+#include <sys/dnv.h>
#include <cam/scsi/scsi_all.h>
#include <cam/scsi/scsi_da.h>
@@ -198,8 +200,10 @@
}
port->targ_port = port_num;
port->ctl_pool_ref = pool;
- if (port->options.stqh_first == NULL)
- STAILQ_INIT(&port->options);
+
+ if (port->options == NULL)
+ port->options = nvlist_create(0);
+
port->stats.item = port_num;
mtx_init(&port->port_lock, "CTL port", NULL, MTX_DEF);
@@ -238,7 +242,7 @@
mtx_unlock(&softc->ctl_lock);
ctl_pool_free(pool);
- ctl_free_opts(&port->options);
+ nvlist_destroy(port->options);
ctl_lun_map_deinit(port);
free(port->port_devid, M_CTL);
@@ -329,7 +333,7 @@
port->port_online(port->onoff_arg);
mtx_lock(&softc->ctl_lock);
if (softc->is_single == 0) {
- value = ctl_get_opt(&port->options, "ha_shared");
+ value = dnvlist_get_string(port->options, "ha_shared", NULL);
if (value != NULL && strcmp(value, "on") == 0)
port->status |= CTL_PORT_STATUS_HA_SHARED;
else
Index: sys/cam/ctl/ctl_frontend_ioctl.c
===================================================================
--- sys/cam/ctl/ctl_frontend_ioctl.c
+++ sys/cam/ctl/ctl_frontend_ioctl.c
@@ -41,6 +41,8 @@
#include <sys/conf.h>
#include <sys/queue.h>
#include <sys/sysctl.h>
+#include <sys/nv.h>
+#include <sys/dnv.h>
#include <cam/cam.h>
#include <cam/scsi/scsi_all.h>
Index: sys/cam/ctl/ctl_frontend_iscsi.c
===================================================================
--- sys/cam/ctl/ctl_frontend_iscsi.c
+++ sys/cam/ctl/ctl_frontend_iscsi.c
@@ -54,6 +54,8 @@
#include <sys/systm.h>
#include <sys/uio.h>
#include <sys/unistd.h>
+#include <sys/nv.h>
+#include <sys/dnv.h>
#include <vm/uma.h>
#include <cam/scsi/scsi_all.h>
@@ -2074,39 +2076,37 @@
{
struct cfiscsi_target *ct;
struct ctl_port *port;
- const char *target, *alias, *tags;
+ const char *target, *alias;
struct scsi_vpd_id_descriptor *desc;
- ctl_options_t opts;
int retval, len, idlen;
- uint16_t tag;
+ int64_t tag;
- ctl_init_opts(&opts, req->num_args, req->kern_args);
- target = ctl_get_opt(&opts, "cfiscsi_target");
- alias = ctl_get_opt(&opts, "cfiscsi_target_alias");
- tags = ctl_get_opt(&opts, "cfiscsi_portal_group_tag");
- if (target == NULL || tags == NULL) {
+ target = dnvlist_get_string(req->args_nvl, "cfiscsi_target", NULL);
+ alias = dnvlist_get_string(req->args_nvl, "cfiscsi_target_alias", NULL);
+ tag = (int64_t)dnvlist_get_number(req->args_nvl,
+ "cfiscsi_portal_group_tag", (uint64_t)-1);
+
+ if (target == NULL || tag == -1) {
req->status = CTL_LUN_ERROR;
snprintf(req->error_str, sizeof(req->error_str),
"Missing required argument");
- ctl_free_opts(&opts);
return;
}
- tag = strtol(tags, (char **)NULL, 10);
- ct = cfiscsi_target_find_or_create(&cfiscsi_softc, target, alias, tag);
+
+ ct = cfiscsi_target_find_or_create(&cfiscsi_softc, target, alias,
+ (uint16_t)tag);
if (ct == NULL) {
req->status = CTL_LUN_ERROR;
snprintf(req->error_str, sizeof(req->error_str),
"failed to create target \"%s\"", target);
- ctl_free_opts(&opts);
return;
}
if (ct->ct_state == CFISCSI_TARGET_STATE_ACTIVE) {
req->status = CTL_LUN_ERROR;
snprintf(req->error_str, sizeof(req->error_str),
- "target \"%s\" for portal group tag %u already exists",
+ "target \"%s\" for portal group tag %ld already exists",
target, tag);
cfiscsi_target_release(ct);
- ctl_free_opts(&opts);
return;
}
port = &ct->ct_port;
@@ -2119,7 +2119,7 @@
/* XXX KDM what should the real number be here? */
port->num_requested_ctl_io = 4096;
port->port_name = "iscsi";
- port->physical_port = tag;
+ port->physical_port = (int)tag;
port->virtual_port = ct->ct_target_id;
port->port_online = cfiscsi_online;
port->port_offline = cfiscsi_offline;
@@ -2128,10 +2128,8 @@
port->fe_datamove = cfiscsi_datamove;
port->fe_done = cfiscsi_done;
port->targ_port = -1;
+ port->options = nvlist_clone(req->args_nvl);
- port->options = opts;
- STAILQ_INIT(&opts);
-
/* Generate Port ID. */
idlen = strlen(target) + strlen(",t,0x0001") + 1;
idlen = roundup2(idlen, 4);
@@ -2144,7 +2142,7 @@
desc->id_type = SVPD_ID_PIV | SVPD_ID_ASSOC_PORT |
SVPD_ID_TYPE_SCSI_NAME;
desc->length = idlen;
- snprintf(desc->identifier, idlen, "%s,t,0x%4.4x", target, tag);
+ snprintf(desc->identifier, idlen, "%s,t,0x%4.4lx", target, tag);
/* Generate Target ID. */
idlen = strlen(target) + 1;
@@ -2162,7 +2160,6 @@
retval = ctl_port_register(port);
if (retval != 0) {
- ctl_free_opts(&port->options);
cfiscsi_target_release(ct);
free(port->port_devid, M_CFISCSI);
free(port->target_devid, M_CFISCSI);
@@ -2174,8 +2171,8 @@
done:
ct->ct_state = CFISCSI_TARGET_STATE_ACTIVE;
req->status = CTL_LUN_OK;
- memcpy(req->kern_args[0].kvalue, &port->targ_port,
- sizeof(port->targ_port)); //XXX
+ req->result_nvl = nvlist_create(0);
+ nvlist_add_number(req->result_nvl, "port_id", port->targ_port);
}
static void
@@ -2182,24 +2179,22 @@
cfiscsi_ioctl_port_remove(struct ctl_req *req)
{
struct cfiscsi_target *ct;
- const char *target, *tags;
- ctl_options_t opts;
+ const char *target;
uint16_t tag;
- ctl_init_opts(&opts, req->num_args, req->kern_args);
- target = ctl_get_opt(&opts, "cfiscsi_target");
- tags = ctl_get_opt(&opts, "cfiscsi_portal_group_tag");
- if (target == NULL || tags == NULL) {
- ctl_free_opts(&opts);
+ target = dnvlist_get_string(req->args_nvl, "cfiscsi_target", NULL);
+ tag = (uint16_t)dnvlist_get_number(req->args_nvl,
+ "cfiscsi_portal_group_tag", 0);
+
+ if (target == NULL || tag == 0) {
req->status = CTL_LUN_ERROR;
snprintf(req->error_str, sizeof(req->error_str),
"Missing required argument");
return;
}
- tag = strtol(tags, (char **)NULL, 10);
+
ct = cfiscsi_target_find(&cfiscsi_softc, target, tag);
if (ct == NULL) {
- ctl_free_opts(&opts);
req->status = CTL_LUN_ERROR;
snprintf(req->error_str, sizeof(req->error_str),
"can't find target \"%s\"", target);
@@ -2206,13 +2201,11 @@
return;
}
if (ct->ct_state != CFISCSI_TARGET_STATE_ACTIVE) {
- ctl_free_opts(&opts);
req->status = CTL_LUN_ERROR;
snprintf(req->error_str, sizeof(req->error_str),
"target \"%s\" is already dying", target);
return;
}
- ctl_free_opts(&opts);
ct->ct_state = CFISCSI_TARGET_STATE_DYING;
ctl_port_offline(&ct->ct_port);
Index: sys/cam/ctl/ctl_ioctl.h
===================================================================
--- sys/cam/ctl/ctl_ioctl.h
+++ sys/cam/ctl/ctl_ioctl.h
@@ -46,6 +46,7 @@
#endif
#include <sys/ioccom.h>
+#include <sys/nv.h>
#define CTL_DEFAULT_DEV "/dev/cam/ctl"
/*
@@ -334,34 +335,6 @@
#define CTL_BEARG_RW (CTL_BEARG_RD|CTL_BEARG_WR)
#define CTL_BEARG_ASCII 0x04
-/*
- * Backend Argument:
- *
- * namelen: Length of the name field, including the terminating NUL.
- *
- * name: Name of the parameter. This must be NUL-terminated.
- *
- * flags: Flags for the parameter, see above for values.
- *
- * vallen: Length of the value in bytes, including the terminating NUL.
- *
- * value: Value to be set/fetched. This must be NUL-terminated.
- *
- * kname: For kernel use only.
- *
- * kvalue: For kernel use only.
- */
-struct ctl_be_arg {
- unsigned int namelen;
- char *name;
- int flags;
- unsigned int vallen;
- void *value;
-
- char *kname;
- void *kvalue;
-};
-
typedef enum {
CTL_LUNREQ_CREATE,
CTL_LUNREQ_RM,
@@ -537,11 +510,14 @@
char backend[CTL_BE_NAME_LEN];
ctl_lunreq_type reqtype;
union ctl_lunreq_data reqdata;
- int num_be_args;
- struct ctl_be_arg *be_args;
+ void * args;
+ nvlist_t * args_nvl;
+ size_t args_len;
+ void * result;
+ nvlist_t * result_nvl;
+ size_t result_len;
ctl_lun_status status;
char error_str[CTL_ERROR_STR_LEN];
- struct ctl_be_arg *kern_be_args;
};
/*
@@ -630,11 +606,14 @@
struct ctl_req {
char driver[CTL_DRIVER_NAME_LEN];
ctl_req_type reqtype;
- int num_args;
- struct ctl_be_arg *args;
+ void * args;
+ nvlist_t * args_nvl;
+ size_t args_len;
+ void * result;
+ nvlist_t * result_nvl;
+ size_t result_len;
ctl_lun_status status;
char error_str[CTL_ERROR_STR_LEN];
- struct ctl_be_arg *kern_args;
};
/*
Index: sys/cam/ctl/ctl_tpc.c
===================================================================
--- sys/cam/ctl/ctl_tpc.c
+++ sys/cam/ctl/ctl_tpc.c
@@ -39,6 +39,8 @@
#include <sys/conf.h>
#include <sys/queue.h>
#include <sys/sysctl.h>
+#include <sys/nv.h>
+#include <sys/dnv.h>
#include <machine/atomic.h>
#include <cam/cam.h>
@@ -1652,7 +1654,7 @@
struct scsi_ec_segment *seg;
struct tpc_list *list, *tlist;
uint8_t *ptr;
- char *value;
+ const char *value;
int len, off, lencscd, lenseg, leninl, nseg;
CTL_DEBUG_PRINT(("ctl_extended_copy_lid1\n"));
@@ -1715,7 +1717,7 @@
list = malloc(sizeof(struct tpc_list), M_CTL, M_WAITOK | M_ZERO);
list->service_action = cdb->service_action;
- value = ctl_get_opt(&lun->be_lun->options, "insecure_tpc");
+ value = dnvlist_get_string(lun->be_lun->options, "insecure_tpc", NULL);
if (value != NULL && strcmp(value, "on") == 0)
list->init_port = -1;
else
@@ -1806,7 +1808,7 @@
struct scsi_ec_segment *seg;
struct tpc_list *list, *tlist;
uint8_t *ptr;
- char *value;
+ const char *value;
int len, off, lencscd, lenseg, leninl, nseg;
CTL_DEBUG_PRINT(("ctl_extended_copy_lid4\n"));
@@ -1869,7 +1871,7 @@
list = malloc(sizeof(struct tpc_list), M_CTL, M_WAITOK | M_ZERO);
list->service_action = cdb->service_action;
- value = ctl_get_opt(&lun->be_lun->options, "insecure_tpc");
+ value = dnvlist_get_string(lun->be_lun->options, "insecure_tpc", NULL);
if (value != NULL && strcmp(value, "on") == 0)
list->init_port = -1;
else
Index: usr.sbin/ctladm/Makefile
===================================================================
--- usr.sbin/ctladm/Makefile
+++ usr.sbin/ctladm/Makefile
@@ -14,7 +14,7 @@
WARNS?= 3
.endif
-LIBADD= cam sbuf bsdxml util
+LIBADD= cam sbuf bsdxml util nv
MAN= ctladm.8
.include <bsd.prog.mk>
Index: usr.sbin/ctladm/ctladm.c
===================================================================
--- usr.sbin/ctladm/ctladm.c
+++ usr.sbin/ctladm/ctladm.c
@@ -51,6 +51,7 @@
#include <sys/queue.h>
#include <sys/callout.h>
#include <sys/sbuf.h>
+#include <sys/nv.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
@@ -151,6 +152,14 @@
const char *subopt;
};
+struct cctl_req_option {
+ char *name;
+ int namelen;
+ char *value;
+ int vallen;
+ STAILQ_ENTRY(cctl_req_option) links;
+};
+
typedef enum {
CC_OR_NOT_FOUND,
CC_OR_AMBIGUOUS,
@@ -393,8 +402,11 @@
cctl_port_mode port_mode = CCTL_PORT_MODE_NONE;
struct ctl_port_entry entry;
ctl_port_type port_type = CTL_PORT_NONE;
+ STAILQ_HEAD(, cctl_req_option) option_list;
int quiet = 0, xml = 0;
+ STAILQ_INIT(&option_list);
+
while ((c = getopt(argc, argv, combinedopt)) != -1) {
switch (c) {
case 'l':
@@ -403,7 +415,7 @@
port_mode = CCTL_PORT_MODE_LIST;
break;
- case 'o':
+ case 'i':
if (port_mode != CCTL_PORT_MODE_NONE)
goto bailout_badarg;
@@ -412,7 +424,7 @@
else if (strcasecmp(optarg, "off") == 0)
port_mode = CCTL_PORT_MODE_OFF;
else {
- warnx("Invalid -o argument %s, \"on\" or "
+ warnx("Invalid -i argument %s, \"on\" or "
"\"off\" are the only valid args",
optarg);
retval = 1;
@@ -419,6 +431,40 @@
goto bailout;
}
break;
+ case 'o': {
+ struct cctl_req_option *option;
+ char *tmpstr;
+ char *name, *value;
+
+ tmpstr = strdup(optarg);
+ name = strsep(&tmpstr, "=");
+ if (name == NULL) {
+ warnx("%s: option -o takes \"name=value\""
+ "argument", __func__);
+ retval = 1;
+ goto bailout;
+ }
+ value = strsep(&tmpstr, "=");
+ if (value == NULL) {
+ warnx("%s: option -o takes \"name=value\""
+ "argument", __func__);
+ retval = 1;
+ goto bailout;
+ }
+ option = malloc(sizeof(*option));
+ if (option == NULL) {
+ warn("%s: error allocating %zd bytes",
+ __func__, sizeof(*option));
+ retval = 1;
+ goto bailout;
+ }
+ option->name = strdup(name);
+ option->value = strdup(value);
+ free(tmpstr);
+
+ STAILQ_INSERT_TAIL(&option_list, option, links);
+ break;
+ }
case 'p':
targ_port = strtol(optarg, NULL, 0);
break;
@@ -2271,14 +2317,6 @@
return (retval);
}
-struct cctl_req_option {
- char *name;
- int namelen;
- char *value;
- int vallen;
- STAILQ_ENTRY(cctl_req_option) links;
-};
-
static int
cctl_create_lun(int fd, int argc, char **argv, char *combinedopt)
{
@@ -2413,15 +2451,13 @@
req.reqdata.create.flags |= CTL_LUN_FLAG_DEVID;
}
- req.num_be_args = num_options;
- if (num_options > 0) {
+ if (!STAILQ_EMPTY(&option_list)) {
struct cctl_req_option *option, *next_option;
int i;
- req.be_args = malloc(num_options * sizeof(*req.be_args));
- if (req.be_args == NULL) {
- warn("%s: error allocating %zd bytes", __func__,
- num_options * sizeof(*req.be_args));
+ req.args_nvl = nvlist_create(0);
+ if (req.args_nvl == NULL) {
+ warn("%s: error allocating nvlist", __func__);
retval = 1;
goto bailout;
}
@@ -2429,24 +2465,21 @@
for (i = 0, option = STAILQ_FIRST(&option_list);
i < num_options; i++, option = next_option) {
next_option = STAILQ_NEXT(option, links);
-
- req.be_args[i].namelen = option->namelen;
- req.be_args[i].name = strdup(option->name);
- req.be_args[i].vallen = option->vallen;
- req.be_args[i].value = strdup(option->value);
- /*
- * XXX KDM do we want a way to specify a writeable
- * flag of some sort? Do we want a way to specify
- * binary data?
- */
- req.be_args[i].flags = CTL_BEARG_ASCII | CTL_BEARG_RD;
-
+ nvlist_add_string(req.args_nvl, option->name,
+ option->value);
STAILQ_REMOVE(&option_list, option, cctl_req_option,
- links);
+ links);
free(option->name);
free(option->value);
free(option);
}
+
+ req.args = nvlist_pack(req.args_nvl, &req.args_len);
+ if (req.args == NULL) {
+ warn("%s: error packing nvlist", __func__);
+ retval = 1;
+ goto bailout;
+ }
}
if (ioctl(fd, CTL_LUN_REQ, &req) == -1) {
@@ -2480,7 +2513,7 @@
req.reqdata.create.blocksize_bytes);
fprintf(stdout, "LUN ID: %d\n", req.reqdata.create.req_lun_id);
fprintf(stdout, "Serial Number: %s\n", req.reqdata.create.serial_num);
- fprintf(stdout, "Device ID; %s\n", req.reqdata.create.device_id);
+ fprintf(stdout, "Device ID: %s\n", req.reqdata.create.device_id);
bailout:
return (retval);
@@ -2563,15 +2596,14 @@
req.reqdata.rm.lun_id = lun_id;
- req.num_be_args = num_options;
- if (num_options > 0) {
+ if (!STAILQ_EMPTY(&option_list)) {
struct cctl_req_option *option, *next_option;
int i;
- req.be_args = malloc(num_options * sizeof(*req.be_args));
- if (req.be_args == NULL) {
- warn("%s: error allocating %zd bytes", __func__,
- num_options * sizeof(*req.be_args));
+ req.args_nvl = nvlist_create(0);
+
+ if (req.args_nvl == NULL) {
+ warn("%s: error allocating nvlist", __func__);
retval = 1;
goto bailout;
}
@@ -2579,24 +2611,21 @@
for (i = 0, option = STAILQ_FIRST(&option_list);
i < num_options; i++, option = next_option) {
next_option = STAILQ_NEXT(option, links);
-
- req.be_args[i].namelen = option->namelen;
- req.be_args[i].name = strdup(option->name);
- req.be_args[i].vallen = option->vallen;
- req.be_args[i].value = strdup(option->value);
- /*
- * XXX KDM do we want a way to specify a writeable
- * flag of some sort? Do we want a way to specify
- * binary data?
- */
- req.be_args[i].flags = CTL_BEARG_ASCII | CTL_BEARG_RD;
-
+ nvlist_add_string(req.args_nvl, option->name,
+ option->value);
STAILQ_REMOVE(&option_list, option, cctl_req_option,
- links);
+ links);
free(option->name);
free(option->value);
free(option);
}
+
+ req.args = nvlist_pack(req.args_nvl, &req.args_len);
+ if (req.args == NULL) {
+ warn("%s: error packing nvlist", __func__);
+ retval = 1;
+ goto bailout;
+ }
}
if (ioctl(fd, CTL_LUN_REQ, &req) == -1) {
@@ -2721,15 +2750,14 @@
req.reqdata.modify.lun_id = lun_id;
req.reqdata.modify.lun_size_bytes = lun_size;
- req.num_be_args = num_options;
- if (num_options > 0) {
+ if (!STAILQ_EMPTY(&option_list)) {
struct cctl_req_option *option, *next_option;
int i;
- req.be_args = malloc(num_options * sizeof(*req.be_args));
- if (req.be_args == NULL) {
- warn("%s: error allocating %zd bytes", __func__,
- num_options * sizeof(*req.be_args));
+ req.args_nvl = nvlist_create(0);
+
+ if (req.args_nvl == NULL) {
+ warn("%s: error allocating nvlist", __func__);
retval = 1;
goto bailout;
}
@@ -2737,24 +2765,21 @@
for (i = 0, option = STAILQ_FIRST(&option_list);
i < num_options; i++, option = next_option) {
next_option = STAILQ_NEXT(option, links);
-
- req.be_args[i].namelen = option->namelen;
- req.be_args[i].name = strdup(option->name);
- req.be_args[i].vallen = option->vallen;
- req.be_args[i].value = strdup(option->value);
- /*
- * XXX KDM do we want a way to specify a writeable
- * flag of some sort? Do we want a way to specify
- * binary data?
- */
- req.be_args[i].flags = CTL_BEARG_ASCII | CTL_BEARG_RD;
-
+ nvlist_add_string(req.args_nvl, option->name,
+ option->value);
STAILQ_REMOVE(&option_list, option, cctl_req_option,
- links);
+ links);
free(option->name);
free(option->value);
free(option);
}
+
+ req.args = nvlist_pack(req.args_nvl, &req.args_len);
+ if (req.args == NULL) {
+ warn("%s: error packing nvlist", __func__);
+ retval = 1;
+ goto bailout;
+ }
}
if (ioctl(fd, CTL_LUN_REQ, &req) == -1) {
Index: usr.sbin/ctld/Makefile
===================================================================
--- usr.sbin/ctld/Makefile
+++ usr.sbin/ctld/Makefile
@@ -13,7 +13,7 @@
#CFLAGS+= -DICL_KERNEL_PROXY
MAN= ctld.8 ctl.conf.5
-LIBADD= bsdxml l md sbuf util ucl m
+LIBADD= bsdxml l md sbuf util ucl m nv
YFLAGS+= -v
CLEANFILES= y.tab.c y.tab.h y.output
Index: usr.sbin/ctld/ctld.h
===================================================================
--- usr.sbin/ctld/ctld.h
+++ usr.sbin/ctld/ctld.h
@@ -150,7 +150,9 @@
struct pport *p_pport;
struct target *p_target;
int p_foreign;
-
+ int p_ioctl_port;
+ int p_ioctl_pp;
+ int p_ioctl_vp;
uint32_t p_ctl_port;
};
@@ -367,6 +369,8 @@
struct port *port_new(struct conf *conf, struct target *target,
struct portal_group *pg);
+struct port *port_new_ioctl(struct conf *conf, struct target *target,
+ int pp, int vp);
struct port *port_new_pp(struct conf *conf, struct target *target,
struct pport *pp);
struct port *port_find(const struct conf *conf, const char *name);
Index: usr.sbin/ctld/ctld.c
===================================================================
--- usr.sbin/ctld/ctld.c
+++ usr.sbin/ctld/ctld.c
@@ -1232,6 +1232,7 @@
log_err(1, "calloc");
port->p_conf = conf;
port->p_name = name;
+ port->p_ioctl_port = 0;
TAILQ_INSERT_TAIL(&conf->conf_ports, port, p_next);
TAILQ_INSERT_TAIL(&target->t_ports, port, p_ts);
port->p_target = target;
@@ -1242,6 +1243,51 @@
}
struct port *
+port_new_ioctl(struct conf *conf, struct target *target, int pp, int vp)
+{
+ struct pport *pport;
+ struct port *port;
+ char *pname;
+ char *name;
+ int ret;
+
+ ret = asprintf(&pname, "ioctl/%d/%d", pp, vp);
+ if (ret <= 0) {
+ log_err(1, "asprintf");
+ return (NULL);
+ }
+
+ pport = pport_find(conf, pname);
+ if (pport != NULL) {
+ free(pname);
+ return (port_new_pp(conf, target, pport));
+ }
+
+ ret = asprintf(&name, "%s-%s", pname, target->t_name);
+ free(pname);
+
+ if (ret <= 0)
+ log_err(1, "asprintf");
+ if (port_find(conf, name) != NULL) {
+ log_warnx("duplicate port \"%s\"", name);
+ free(name);
+ return (NULL);
+ }
+ port = calloc(1, sizeof(*port));
+ if (port == NULL)
+ log_err(1, "calloc");
+ port->p_conf = conf;
+ port->p_name = name;
+ port->p_ioctl_port = 1;
+ port->p_ioctl_pp = pp;
+ port->p_ioctl_vp = vp;
+ TAILQ_INSERT_TAIL(&conf->conf_ports, port, p_next);
+ TAILQ_INSERT_TAIL(&target->t_ports, port, p_ts);
+ port->p_target = target;
+ return (port);
+}
+
+struct port *
port_new_pp(struct conf *conf, struct target *target, struct pport *pp)
{
struct port *port;
@@ -1613,9 +1659,9 @@
TAILQ_FOREACH(auth_name, &ag->ag_names, an_next)
fprintf(stderr, "\t initiator-name %s\n",
auth_name->an_initator_name);
- TAILQ_FOREACH(auth_portal, &ag->ag_portals, an_next)
+ TAILQ_FOREACH(auth_portal, &ag->ag_portals, ap_next)
fprintf(stderr, "\t initiator-portal %s\n",
- auth_portal->an_initator_portal);
+ auth_portal->ap_initator_portal);
fprintf(stderr, "}\n");
}
TAILQ_FOREACH(pg, &conf->conf_portal_groups, pg_next) {
@@ -1629,7 +1675,7 @@
fprintf(stderr, "\t\tpath %s\n", lun->l_path);
TAILQ_FOREACH(o, &lun->l_options, o_next)
fprintf(stderr, "\t\toption %s %s\n",
- lo->o_name, lo->o_value);
+ o->o_name, o->o_value);
fprintf(stderr, "\t}\n");
}
TAILQ_FOREACH(targ, &conf->conf_targets, t_next) {
Index: usr.sbin/ctld/kernel.c
===================================================================
--- usr.sbin/ctld/kernel.c
+++ usr.sbin/ctld/kernel.c
@@ -46,6 +46,7 @@
#include <sys/callout.h>
#include <sys/sbuf.h>
#include <sys/capsicum.h>
+#include <sys/nv.h>
#include <assert.h>
#include <bsdxml.h>
#include <ctype.h>
@@ -71,6 +72,8 @@
#include <netdb.h>
#endif
+#define NVLIST_BUFSIZE 1024
+
extern bool proxy_mode;
static int ctl_fd = 0;
@@ -642,23 +645,12 @@
return (conf);
}
-static void
-str_arg(struct ctl_be_arg *arg, const char *name, const char *value)
-{
-
- arg->namelen = strlen(name) + 1;
- arg->name = __DECONST(char *, name);
- arg->vallen = strlen(value) + 1;
- arg->value = __DECONST(char *, value);
- arg->flags = CTL_BEARG_ASCII | CTL_BEARG_RD;
-}
-
int
kernel_lun_add(struct lun *lun)
{
struct option *o;
struct ctl_lun_req req;
- int error, i, num_options;
+ int error;
bzero(&req, sizeof(req));
@@ -714,29 +706,26 @@
assert(o != NULL);
}
- num_options = 0;
- TAILQ_FOREACH(o, &lun->l_options, o_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));
+ if (!TAILQ_EMPTY(&lun->l_options)) {
+ req.args_nvl = nvlist_create(0);
+ if (req.args_nvl == NULL) {
+ log_warn("error allocating nvlist");
return (1);
}
- i = 0;
- TAILQ_FOREACH(o, &lun->l_options, o_next) {
- str_arg(&req.be_args[i], o->o_name, o->o_value);
- i++;
+ TAILQ_FOREACH(o, &lun->l_options, o_next)
+ nvlist_add_string(req.args_nvl, o->o_name, o->o_value);
+
+ req.args = nvlist_pack(req.args_nvl, &req.args_len);
+ if (req.args == NULL) {
+ log_warn("error packing nvlist");
+ return (1);
}
- assert(i == num_options);
}
error = ioctl(ctl_fd, CTL_LUN_REQ, &req);
- free(req.be_args);
+ nvlist_destroy(req.args_nvl);
+
if (error != 0) {
log_warn("error issuing CTL_LUN_REQ ioctl");
return (1);
@@ -766,7 +755,7 @@
{
struct option *o;
struct ctl_lun_req req;
- int error, i, num_options;
+ int error;
bzero(&req, sizeof(req));
@@ -776,29 +765,26 @@
req.reqdata.modify.lun_id = lun->l_ctl_lun;
req.reqdata.modify.lun_size_bytes = lun->l_size;
- num_options = 0;
- TAILQ_FOREACH(o, &lun->l_options, o_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));
+ if (!TAILQ_EMPTY(&lun->l_options)) {
+ req.args_nvl = nvlist_create(0);
+ if (req.args_nvl == NULL) {
+ log_warn("error allocating nvlist");
return (1);
}
- i = 0;
- TAILQ_FOREACH(o, &lun->l_options, o_next) {
- str_arg(&req.be_args[i], o->o_name, o->o_value);
- i++;
+ TAILQ_FOREACH(o, &lun->l_options, o_next)
+ nvlist_add_string(req.args_nvl, o->o_name, o->o_value);
+
+ req.args = nvlist_pack(req.args_nvl, &req.args_len);
+ if (req.args == NULL) {
+ log_warn("error packing nvlist");
+ return (1);
}
- assert(i == num_options);
}
error = ioctl(ctl_fd, CTL_LUN_REQ, &req);
- free(req.be_args);
+ nvlist_destroy(req.args_nvl);
+
if (error != 0) {
log_warn("error issuing CTL_LUN_REQ ioctl");
return (1);
@@ -978,37 +964,54 @@
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, n;
+ char result_buf[NVLIST_BUFSIZE];
+ int error, i;
/* Create iSCSI port. */
- if (port->p_portal_group) {
+ if (port->p_portal_group || port->p_ioctl_port) {
bzero(&req, sizeof(req));
- strlcpy(req.driver, "iscsi", sizeof(req.driver));
req.reqtype = CTL_REQ_CREATE;
- req.num_args = 5;
- TAILQ_FOREACH(o, &pg->pg_options, o_next)
- req.num_args++;
- req.args = malloc(req.num_args * sizeof(*req.args));
- if (req.args == NULL)
- log_err(1, "malloc");
- 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[n++], "cfiscsi_target_alias", targ->t_alias);
- 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);
- req.num_args = n;
+
+ if (port->p_portal_group) {
+ strlcpy(req.driver, "iscsi", sizeof(req.driver));
+ req.args_nvl = nvlist_create(0);
+ nvlist_add_string(req.args_nvl, "cfiscsi_target",
+ targ->t_name);
+ nvlist_add_string(req.args_nvl,
+ "ctld_portal_group_name", pg->pg_name);
+ nvlist_add_number(req.args_nvl,
+ "cfiscsi_portal_group_tag", pg->pg_tag);
+
+ if (targ->t_alias) {
+ nvlist_add_string(req.args_nvl,
+ "cfiscsi_target_alias", targ->t_alias);
+ }
+
+ TAILQ_FOREACH(o, &pg->pg_options, o_next)
+ nvlist_add_string(req.args_nvl, o->o_name,
+ o->o_value);
+ }
+
+ if (port->p_ioctl_port) {
+ strlcpy(req.driver, "ioctl", sizeof(req.driver));
+ req.args_nvl = nvlist_create(0);
+ nvlist_add_number(req.args_nvl, "pp",
+ port->p_ioctl_pp);
+ nvlist_add_number(req.args_nvl, "vp",
+ port->p_ioctl_vp);
+ }
+
+ req.args = nvlist_pack(req.args_nvl, &req.args_len);
+ if (req.args == NULL) {
+ log_warn("error packing nvlist");
+ return (1);
+ }
+
+ req.result = result_buf;
+ req.result_len = sizeof(result_buf);
error = ioctl(ctl_fd, CTL_PORT_REQ, &req);
- free(req.args);
+ nvlist_destroy(req.args_nvl);
+
if (error != 0) {
log_warn("error issuing CTL_PORT_REQ ioctl");
return (1);
@@ -1023,6 +1026,15 @@
req.status);
return (1);
}
+
+ req.result_nvl = nvlist_unpack(result_buf, req.result_len, 0);
+ if (req.result_nvl == NULL) {
+ log_warnx("error unpacking result nvlist");
+ return (1);
+ }
+
+ port->p_ctl_port = nvlist_get_number(req.result_nvl, "port_id");
+ nvlist_destroy(req.result_nvl);
} else if (port->p_pport) {
port->p_ctl_port = port->p_pport->pp_ctl_port;
@@ -1106,7 +1118,6 @@
struct ctl_port_entry entry;
struct ctl_lun_map lm;
struct ctl_req req;
- char tagstr[16];
struct target *targ = port->p_target;
struct portal_group *pg = port->p_portal_group;
int error;
@@ -1120,20 +1131,35 @@
return (-1);
}
- /* Remove iSCSI port. */
- if (port->p_portal_group) {
+ /* Remove iSCSI or ioctl port. */
+ if (port->p_portal_group || port->p_ioctl_port) {
bzero(&req, sizeof(req));
- strlcpy(req.driver, "iscsi", sizeof(req.driver));
+ strlcpy(req.driver, port->p_ioctl_port ? "ioctl" : "iscsi",
+ sizeof(req.driver));
req.reqtype = CTL_REQ_REMOVE;
- req.num_args = 2;
- req.args = malloc(req.num_args * sizeof(*req.args));
- if (req.args == NULL)
- log_err(1, "malloc");
- str_arg(&req.args[0], "cfiscsi_target", targ->t_name);
- snprintf(tagstr, sizeof(tagstr), "%d", pg->pg_tag);
- str_arg(&req.args[1], "cfiscsi_portal_group_tag", tagstr);
+ req.args_nvl = nvlist_create(0);
+ if (req.args_nvl == NULL)
+ log_err(1, "nvlist_create");
+
+ if (port->p_ioctl_port)
+ nvlist_add_number(req.args_nvl, "port_id",
+ port->p_ctl_port);
+ else {
+ nvlist_add_string(req.args_nvl, "cfiscsi_target",
+ targ->t_name);
+ nvlist_add_number(req.args_nvl, "cfiscsi_portal_group_tag",
+ pg->pg_tag);
+ }
+
+ req.args = nvlist_pack(req.args_nvl, &req.args_len);
+ if (req.args == NULL) {
+ log_warn("error packing nvlist");
+ return (1);
+ }
+
error = ioctl(ctl_fd, CTL_PORT_REQ, &req);
- free(req.args);
+ nvlist_destroy(req.args_nvl);
+
if (error != 0) {
log_warn("error issuing CTL_PORT_REQ ioctl");
return (1);
Index: usr.sbin/ctld/parse.y
===================================================================
--- usr.sbin/ctld/parse.y
+++ usr.sbin/ctld/parse.y
@@ -766,28 +766,41 @@
{
struct pport *pp;
struct port *tp;
+ int ret, i_pp, i_vp = 0;
- pp = pport_find(conf, $2);
- if (pp == NULL) {
- log_warnx("unknown port \"%s\" for target \"%s\"",
- $2, target->t_name);
- free($2);
- return (1);
+ ret = sscanf($2, "ioctl/%d/%d", &i_pp, &i_vp);
+ if (ret > 0) {
+ tp = port_new_ioctl(conf, target, i_pp, i_vp);
+ if (tp == NULL) {
+ log_warnx("can't create new ioctl port for "
+ "target \"%s\"", target->t_name);
+ free($2);
+ return (1);
+ }
+ } else {
+ pp = pport_find(conf, $2);
+ if (pp == NULL) {
+ log_warnx("unknown port \"%s\" for target \"%s\"",
+ $2, target->t_name);
+ free($2);
+ return (1);
+ }
+ if (!TAILQ_EMPTY(&pp->pp_ports)) {
+ log_warnx("can't link port \"%s\" to target \"%s\", "
+ "port already linked to some target",
+ $2, target->t_name);
+ free($2);
+ return (1);
+ }
+ tp = port_new_pp(conf, target, pp);
+ if (tp == NULL) {
+ log_warnx("can't link port \"%s\" to target \"%s\"",
+ $2, target->t_name);
+ free($2);
+ return (1);
+ }
}
- if (!TAILQ_EMPTY(&pp->pp_ports)) {
- log_warnx("can't link port \"%s\" to target \"%s\", "
- "port already linked to some target",
- $2, target->t_name);
- free($2);
- return (1);
- }
- tp = port_new_pp(conf, target, pp);
- if (tp == NULL) {
- log_warnx("can't link port \"%s\" to target \"%s\"",
- $2, target->t_name);
- free($2);
- return (1);
- }
+
free($2);
}
;
Index: usr.sbin/ctld/uclparse.c
===================================================================
--- usr.sbin/ctld/uclparse.c
+++ usr.sbin/ctld/uclparse.c
@@ -754,7 +754,20 @@
struct pport *pp;
struct port *tp;
const char *value = ucl_object_tostring(obj);
+ int ret, i_pp, i_vp = 0;
+ ret = sscanf(value, "ioctl/%d/%d", &i_pp, &i_vp);
+ if (ret > 0) {
+ tp = port_new_ioctl(conf, target, i_pp, i_vp);
+ if (tp == NULL) {
+ log_warnx("can't create new ioctl port "
+ "for target \"%s\"", target->t_name);
+ return (1);
+ }
+
+ return (0);
+ }
+
pp = pport_find(conf, value);
if (pp == NULL) {
log_warnx("unknown port \"%s\" for target \"%s\"",

File Metadata

Mime Type
text/plain
Expires
Thu, Feb 12, 1:07 PM (8 h, 28 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
28666899
Default Alt Text
D9299.id24342.diff (63 KB)

Event Timeline