Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F144712191
D9299.id24342.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
63 KB
Referenced Files
None
Subscribers
None
D9299.id24342.diff
View Options
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
Details
Attached
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)
Attached To
Mode
D9299: Rework CTL frontend & backend options to use nv(3), allow creating multiple ioctl frontend ports
Attached
Detach File
Event Timeline
Log In to Comment