Changeset View
Standalone View
usr.sbin/ctladm/ctladm.c
Show First 20 Lines • Show All 44 Lines • ▼ Show 20 Lines | |||||
#include <sys/param.h> | #include <sys/param.h> | ||||
#include <sys/callout.h> | #include <sys/callout.h> | ||||
#include <sys/ioctl.h> | #include <sys/ioctl.h> | ||||
#include <sys/linker.h> | #include <sys/linker.h> | ||||
#include <sys/module.h> | #include <sys/module.h> | ||||
#include <sys/queue.h> | #include <sys/queue.h> | ||||
#include <sys/sbuf.h> | #include <sys/sbuf.h> | ||||
#include <sys/nv.h> | |||||
#include <sys/stat.h> | #include <sys/stat.h> | ||||
#include <bsdxml.h> | #include <bsdxml.h> | ||||
#include <ctype.h> | #include <ctype.h> | ||||
#include <err.h> | #include <err.h> | ||||
#include <errno.h> | #include <errno.h> | ||||
#include <fcntl.h> | #include <fcntl.h> | ||||
#include <getopt.h> | #include <getopt.h> | ||||
#include <stdlib.h> | #include <stdlib.h> | ||||
▲ Show 20 Lines • Show All 112 Lines • ▼ Show 20 Lines | static struct ctladm_opts option_table[] = { | ||||
{"inquiry", CTLADM_CMD_INQUIRY, CTLADM_ARG_NEED_TL, NULL}, | {"inquiry", CTLADM_CMD_INQUIRY, CTLADM_ARG_NEED_TL, NULL}, | ||||
{"islist", CTLADM_CMD_ISLIST, CTLADM_ARG_NONE, "vx"}, | {"islist", CTLADM_CMD_ISLIST, CTLADM_ARG_NONE, "vx"}, | ||||
{"islogout", CTLADM_CMD_ISLOGOUT, CTLADM_ARG_NONE, "ac:i:p:"}, | {"islogout", CTLADM_CMD_ISLOGOUT, CTLADM_ARG_NONE, "ac:i:p:"}, | ||||
{"isterminate", CTLADM_CMD_ISTERMINATE, CTLADM_ARG_NONE, "ac:i:p:"}, | {"isterminate", CTLADM_CMD_ISTERMINATE, CTLADM_ARG_NONE, "ac:i:p:"}, | ||||
{"lunlist", CTLADM_CMD_LUNLIST, CTLADM_ARG_NONE, NULL}, | {"lunlist", CTLADM_CMD_LUNLIST, CTLADM_ARG_NONE, NULL}, | ||||
{"lunmap", CTLADM_CMD_LUNMAP, CTLADM_ARG_NONE, "p:l:L:"}, | {"lunmap", CTLADM_CMD_LUNMAP, CTLADM_ARG_NONE, "p:l:L:"}, | ||||
{"modesense", CTLADM_CMD_MODESENSE, CTLADM_ARG_NEED_TL, "P:S:dlm:c:"}, | {"modesense", CTLADM_CMD_MODESENSE, CTLADM_ARG_NEED_TL, "P:S:dlm:c:"}, | ||||
{"modify", CTLADM_CMD_MODIFY, CTLADM_ARG_NONE, "b:l:o:s:"}, | {"modify", CTLADM_CMD_MODIFY, CTLADM_ARG_NONE, "b:l:o:s:"}, | ||||
{"port", CTLADM_CMD_PORT, CTLADM_ARG_NONE, "lo:p:qt:w:W:x"}, | {"port", CTLADM_CMD_PORT, CTLADM_ARG_NONE, "lo:O:d:crp:qt:w:W:x"}, | ||||
{"portlist", CTLADM_CMD_PORTLIST, CTLADM_ARG_NONE, "f:ilp:qvx"}, | {"portlist", CTLADM_CMD_PORTLIST, CTLADM_ARG_NONE, "f:ilp:qvx"}, | ||||
{"prin", CTLADM_CMD_PRES_IN, CTLADM_ARG_NEED_TL, "a:"}, | {"prin", CTLADM_CMD_PRES_IN, CTLADM_ARG_NEED_TL, "a:"}, | ||||
{"prout", CTLADM_CMD_PRES_OUT, CTLADM_ARG_NEED_TL, "a:k:r:s:"}, | {"prout", CTLADM_CMD_PRES_OUT, CTLADM_ARG_NEED_TL, "a:k:r:s:"}, | ||||
{"read", CTLADM_CMD_READ, CTLADM_ARG_NEED_TL, rw_opts}, | {"read", CTLADM_CMD_READ, CTLADM_ARG_NEED_TL, rw_opts}, | ||||
{"readcapacity", CTLADM_CMD_READCAPACITY, CTLADM_ARG_NEED_TL, "c:"}, | {"readcapacity", CTLADM_CMD_READCAPACITY, CTLADM_ARG_NEED_TL, "c:"}, | ||||
{"remove", CTLADM_CMD_RM, CTLADM_ARG_NONE, "b:l:o:"}, | {"remove", CTLADM_CMD_RM, CTLADM_ARG_NONE, "b:l:o:"}, | ||||
{"reportluns", CTLADM_CMD_REPORT_LUNS, CTLADM_ARG_NEED_TL, NULL}, | {"reportluns", CTLADM_CMD_REPORT_LUNS, CTLADM_ARG_NEED_TL, NULL}, | ||||
{"reqsense", CTLADM_CMD_REQ_SENSE, CTLADM_ARG_NEED_TL, NULL}, | {"reqsense", CTLADM_CMD_REQ_SENSE, CTLADM_ARG_NEED_TL, NULL}, | ||||
▲ Show 20 Lines • Show All 174 Lines • ▼ Show 20 Lines | cctl_dump_structs(int fd, ctladm_cmdargs cmdargs __unused) | ||||
return (0); | return (0); | ||||
} | } | ||||
typedef enum { | typedef enum { | ||||
CCTL_PORT_MODE_NONE, | CCTL_PORT_MODE_NONE, | ||||
CCTL_PORT_MODE_LIST, | CCTL_PORT_MODE_LIST, | ||||
CCTL_PORT_MODE_SET, | CCTL_PORT_MODE_SET, | ||||
CCTL_PORT_MODE_ON, | CCTL_PORT_MODE_ON, | ||||
CCTL_PORT_MODE_OFF | CCTL_PORT_MODE_OFF, | ||||
CCTL_PORT_MODE_CREATE, | |||||
CCTL_PORT_MODE_REMOVE | |||||
} cctl_port_mode; | } cctl_port_mode; | ||||
static struct ctladm_opts cctl_fe_table[] = { | static struct ctladm_opts cctl_fe_table[] = { | ||||
{"fc", CTL_PORT_FC, CTLADM_ARG_NONE, NULL}, | {"fc", CTL_PORT_FC, CTLADM_ARG_NONE, NULL}, | ||||
{"scsi", CTL_PORT_SCSI, CTLADM_ARG_NONE, NULL}, | {"scsi", CTL_PORT_SCSI, CTLADM_ARG_NONE, NULL}, | ||||
{"internal", CTL_PORT_INTERNAL, CTLADM_ARG_NONE, NULL}, | {"internal", CTL_PORT_INTERNAL, CTLADM_ARG_NONE, NULL}, | ||||
{"iscsi", CTL_PORT_ISCSI, CTLADM_ARG_NONE, NULL}, | {"iscsi", CTL_PORT_ISCSI, CTLADM_ARG_NONE, NULL}, | ||||
{"sas", CTL_PORT_SAS, CTLADM_ARG_NONE, NULL}, | {"sas", CTL_PORT_SAS, CTLADM_ARG_NONE, NULL}, | ||||
{"all", CTL_PORT_ALL, CTLADM_ARG_NONE, NULL}, | {"all", CTL_PORT_ALL, CTLADM_ARG_NONE, NULL}, | ||||
{NULL, 0, 0, NULL} | {NULL, 0, 0, NULL} | ||||
}; | }; | ||||
static int | static int | ||||
cctl_port(int fd, int argc, char **argv, char *combinedopt) | cctl_port(int fd, int argc, char **argv, char *combinedopt) | ||||
{ | { | ||||
int c; | int c; | ||||
int32_t targ_port = -1; | int32_t targ_port = -1; | ||||
int retval = 0; | int retval = 0; | ||||
int wwnn_set = 0, wwpn_set = 0; | int wwnn_set = 0, wwpn_set = 0; | ||||
uint64_t wwnn = 0, wwpn = 0; | uint64_t wwnn = 0, wwpn = 0; | ||||
cctl_port_mode port_mode = CCTL_PORT_MODE_NONE; | cctl_port_mode port_mode = CCTL_PORT_MODE_NONE; | ||||
struct ctl_port_entry entry; | struct ctl_port_entry entry; | ||||
struct ctl_req req; | |||||
char *driver = NULL; | |||||
nvlist_t *option_list; | |||||
ctl_port_type port_type = CTL_PORT_NONE; | ctl_port_type port_type = CTL_PORT_NONE; | ||||
int quiet = 0, xml = 0; | int quiet = 0, xml = 0; | ||||
option_list = nvlist_create(0); | |||||
if (option_list == NULL) | |||||
err(1, "%s: unable to allocate nvlist", __func__); | |||||
while ((c = getopt(argc, argv, combinedopt)) != -1) { | while ((c = getopt(argc, argv, combinedopt)) != -1) { | ||||
switch (c) { | switch (c) { | ||||
case 'l': | case 'l': | ||||
if (port_mode != CCTL_PORT_MODE_NONE) | if (port_mode != CCTL_PORT_MODE_NONE) | ||||
goto bailout_badarg; | goto bailout_badarg; | ||||
port_mode = CCTL_PORT_MODE_LIST; | port_mode = CCTL_PORT_MODE_LIST; | ||||
break; | break; | ||||
case 'c': | |||||
port_mode = CCTL_PORT_MODE_CREATE; | |||||
break; | |||||
case 'r': | |||||
port_mode = CCTL_PORT_MODE_REMOVE; | |||||
break; | |||||
case 'o': | case 'o': | ||||
if (port_mode != CCTL_PORT_MODE_NONE) | if (port_mode != CCTL_PORT_MODE_NONE) | ||||
goto bailout_badarg; | goto bailout_badarg; | ||||
if (strcasecmp(optarg, "on") == 0) | if (strcasecmp(optarg, "on") == 0) | ||||
port_mode = CCTL_PORT_MODE_ON; | port_mode = CCTL_PORT_MODE_ON; | ||||
mav: I am not sure what to do, but I am not exactly happy about changing option name here. Why -i… | |||||
else if (strcasecmp(optarg, "off") == 0) | else if (strcasecmp(optarg, "off") == 0) | ||||
port_mode = CCTL_PORT_MODE_OFF; | port_mode = CCTL_PORT_MODE_OFF; | ||||
else { | else { | ||||
warnx("Invalid -o argument %s, \"on\" or " | warnx("Invalid -o argument %s, \"on\" or " | ||||
"\"off\" are the only valid args", | "\"off\" are the only valid args", | ||||
optarg); | optarg); | ||||
retval = 1; | retval = 1; | ||||
goto bailout; | goto bailout; | ||||
} | } | ||||
break; | break; | ||||
case 'O': { | |||||
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, "="); | |||||
Not Done Inline ActionsWhy do you need second strsep() here? tmpstr should already be the value. mav: Why do you need second strsep() here? tmpstr should already be the value. | |||||
if (value == NULL) { | |||||
warnx("%s: option -O takes \"name=value\"" | |||||
"argument", __func__); | |||||
retval = 1; | |||||
goto bailout; | |||||
} | |||||
free(tmpstr); | |||||
nvlist_add_string(option_list, name, value); | |||||
break; | |||||
} | |||||
case 'd': | |||||
if (driver != NULL) { | |||||
Done Inline ActionsHere should be free(driver) before new assignment in case -d specified twice. mav: Here should be free(driver) before new assignment in case -d specified twice. | |||||
warnx("%s: option -d cannot be specified twice", | |||||
__func__); | |||||
retval = 1; | |||||
goto bailout; | |||||
} | |||||
driver = strdup(optarg); | |||||
break; | |||||
case 'p': | case 'p': | ||||
targ_port = strtol(optarg, NULL, 0); | targ_port = strtol(optarg, NULL, 0); | ||||
break; | break; | ||||
Not Done Inline ActionsI've already told that double conversion looks unneeded to me. Why not write directly into the nvlist? mav: I've already told that double conversion looks unneeded to me. Why not write directly into the… | |||||
case 'q': | case 'q': | ||||
quiet = 1; | quiet = 1; | ||||
break; | break; | ||||
case 't': { | case 't': { | ||||
ctladm_optret optret; | ctladm_optret optret; | ||||
ctladm_cmdargs argnum; | ctladm_cmdargs argnum; | ||||
const char *subopt; | const char *subopt; | ||||
ctl_port_type tmp_port_type; | ctl_port_type tmp_port_type; | ||||
Show All 36 Lines | case 'W': | ||||
wwpn_set = 1; | wwpn_set = 1; | ||||
break; | break; | ||||
case 'x': | case 'x': | ||||
xml = 1; | xml = 1; | ||||
break; | break; | ||||
} | } | ||||
} | } | ||||
if (driver == NULL) | |||||
driver = strdup("ioctl"); | |||||
/* | /* | ||||
* The user can specify either one or more frontend types (-t), or | * The user can specify either one or more frontend types (-t), or | ||||
* a specific frontend, but not both. | * a specific frontend, but not both. | ||||
* | * | ||||
* If the user didn't specify a frontend type or number, set it to | * If the user didn't specify a frontend type or number, set it to | ||||
* all. This is primarily needed for the enable/disable ioctls. | * all. This is primarily needed for the enable/disable ioctls. | ||||
* This will be a no-op for the listing code. For the set ioctl, | * This will be a no-op for the listing code. For the set ioctl, | ||||
* we'll throw an error, since that only works on one port at a time. | * we'll throw an error, since that only works on one port at a time. | ||||
Show All 19 Lines | case CCTL_PORT_MODE_LIST: { | ||||
char argx[] = "-x"; | char argx[] = "-x"; | ||||
char argq[] = "-q"; | char argq[] = "-q"; | ||||
char *argvx[2]; | char *argvx[2]; | ||||
int argcx = 0; | int argcx = 0; | ||||
optind = 0; | optind = 0; | ||||
optreset = 1; | optreset = 1; | ||||
if (xml) | if (xml) | ||||
argvx[argcx++] = argx; | argvx[argcx++] = argx; | ||||
Done Inline ActionsYou've probably missed my previous comment about this. There should be command line option to specify the driver. mav: You've probably missed my previous comment about this. There should be command line option to… | |||||
if (quiet) | if (quiet) | ||||
argvx[argcx++] = argq; | argvx[argcx++] = argq; | ||||
cctl_portlist(fd, argcx, argvx, opts); | cctl_portlist(fd, argcx, argvx, opts); | ||||
break; | break; | ||||
} | } | ||||
case CCTL_PORT_MODE_REMOVE: | |||||
if (targ_port == -1) { | |||||
warnx("%s: -r require -p", __func__); | |||||
retval = 1; | |||||
goto bailout; | |||||
} | |||||
case CCTL_PORT_MODE_CREATE: { | |||||
bzero(&req, sizeof(req)); | |||||
strlcpy(req.driver, driver, sizeof(req.driver)); | |||||
if (port_mode == CCTL_PORT_MODE_REMOVE) { | |||||
req.reqtype = CTL_REQ_REMOVE; | |||||
nvlist_add_stringf(option_list, "port_id", "%d", | |||||
targ_port); | |||||
Not Done Inline ActionsI don't think this is a good assumption. There should be an option, alike to -b for backends, to specify what port to create. While there is only ioctl ports are supported now, that may be not for long. mav: I don't think this is a good assumption. There should be an option, alike to -b for backends… | |||||
} else | |||||
req.reqtype = CTL_REQ_CREATE; | |||||
req.args = nvlist_pack(option_list, &req.args_len); | |||||
if (req.args == NULL) { | |||||
warn("%s: error packing nvlist", __func__); | |||||
retval = 1; | |||||
goto bailout; | |||||
} | |||||
Not Done Inline ActionsThis type hard coding does not look good to me. I'd just pass everything as strings and let kernel decide. mav: This type hard coding does not look good to me. I'd just pass everything as strings and let… | |||||
retval = ioctl(fd, CTL_PORT_REQ, &req); | |||||
if (retval == -1) { | |||||
Done Inline ActionsWhy? mav: Why? | |||||
warn("%s: CTL_PORT_REQ ioctl failed", __func__); | |||||
retval = 1; | |||||
goto bailout; | |||||
} | |||||
switch (req.status) { | |||||
case CTL_LUN_ERROR: | |||||
warnx("error: %s", req.error_str); | |||||
retval = 1; | |||||
goto bailout; | |||||
case CTL_LUN_WARNING: | |||||
warnx("warning: %s", req.error_str); | |||||
break; | |||||
case CTL_LUN_OK: | |||||
break; | |||||
default: | |||||
warnx("unknown status: %d", req.status); | |||||
retval = 1; | |||||
goto bailout; | |||||
} | |||||
break; | |||||
} | |||||
case CCTL_PORT_MODE_SET: | case CCTL_PORT_MODE_SET: | ||||
if (targ_port == -1) { | if (targ_port == -1) { | ||||
warnx("%s: -w and -W require -n", __func__); | warnx("%s: -w and -W require -n", __func__); | ||||
retval = 1; | retval = 1; | ||||
goto bailout; | goto bailout; | ||||
} | } | ||||
if (wwnn_set) { | if (wwnn_set) { | ||||
Show All 30 Lines | cctl_port(int fd, int argc, char **argv, char *combinedopt) | ||||
default: | default: | ||||
warnx("%s: one of -l, -o or -w/-W must be specified", __func__); | warnx("%s: one of -l, -o or -w/-W must be specified", __func__); | ||||
retval = 1; | retval = 1; | ||||
goto bailout; | goto bailout; | ||||
break; | break; | ||||
} | } | ||||
bailout: | bailout: | ||||
nvlist_destroy(req.args_nvl); | |||||
free(driver); | |||||
return (retval); | return (retval); | ||||
bailout_badarg: | bailout_badarg: | ||||
warnx("%s: only one of -l, -o or -w/-W may be specified", __func__); | warnx("%s: only one of -l, -o or -w/-W may be specified", __func__); | ||||
return (1); | return (1); | ||||
} | } | ||||
static int | static int | ||||
▲ Show 20 Lines • Show All 1,693 Lines • ▼ Show 20 Lines | bailout: | ||||
ctl_scsi_free_io(io); | ctl_scsi_free_io(io); | ||||
if (dataptr != NULL) | if (dataptr != NULL) | ||||
free(dataptr); | free(dataptr); | ||||
return (retval); | return (retval); | ||||
} | } | ||||
struct cctl_req_option { | |||||
char *name; | |||||
int namelen; | |||||
char *value; | |||||
int vallen; | |||||
STAILQ_ENTRY(cctl_req_option) links; | |||||
}; | |||||
static int | static int | ||||
cctl_create_lun(int fd, int argc, char **argv, char *combinedopt) | cctl_create_lun(int fd, int argc, char **argv, char *combinedopt) | ||||
{ | { | ||||
struct ctl_lun_req req; | struct ctl_lun_req req; | ||||
int device_type = -1; | int device_type = -1; | ||||
uint64_t lun_size = 0; | uint64_t lun_size = 0; | ||||
uint32_t blocksize = 0, req_lun_id = 0; | uint32_t blocksize = 0, req_lun_id = 0; | ||||
char *serial_num = NULL; | char *serial_num = NULL; | ||||
char *device_id = NULL; | char *device_id = NULL; | ||||
int lun_size_set = 0, blocksize_set = 0, lun_id_set = 0; | int lun_size_set = 0, blocksize_set = 0, lun_id_set = 0; | ||||
char *backend_name = NULL; | char *backend_name = NULL; | ||||
STAILQ_HEAD(, cctl_req_option) option_list; | nvlist_t *option_list; | ||||
int num_options = 0; | |||||
int retval = 0, c; | int retval = 0, c; | ||||
STAILQ_INIT(&option_list); | option_list = nvlist_create(0); | ||||
if (option_list == NULL) | |||||
err(1, "%s: unable to allocate nvlist", __func__); | |||||
while ((c = getopt(argc, argv, combinedopt)) != -1) { | while ((c = getopt(argc, argv, combinedopt)) != -1) { | ||||
switch (c) { | switch (c) { | ||||
case 'b': | case 'b': | ||||
backend_name = strdup(optarg); | backend_name = strdup(optarg); | ||||
break; | break; | ||||
case 'B': | case 'B': | ||||
blocksize = strtoul(optarg, NULL, 0); | blocksize = strtoul(optarg, NULL, 0); | ||||
blocksize_set = 1; | blocksize_set = 1; | ||||
break; | break; | ||||
case 'd': | case 'd': | ||||
device_id = strdup(optarg); | device_id = strdup(optarg); | ||||
break; | break; | ||||
case 'l': | case 'l': | ||||
req_lun_id = strtoul(optarg, NULL, 0); | req_lun_id = strtoul(optarg, NULL, 0); | ||||
lun_id_set = 1; | lun_id_set = 1; | ||||
break; | break; | ||||
case 'o': { | case 'o': { | ||||
struct cctl_req_option *option; | |||||
char *tmpstr; | char *tmpstr; | ||||
char *name, *value; | char *name, *value; | ||||
tmpstr = strdup(optarg); | tmpstr = strdup(optarg); | ||||
name = strsep(&tmpstr, "="); | name = strsep(&tmpstr, "="); | ||||
if (name == NULL) { | if (name == NULL) { | ||||
warnx("%s: option -o takes \"name=value\"" | warnx("%s: option -o takes \"name=value\"" | ||||
"argument", __func__); | "argument", __func__); | ||||
retval = 1; | retval = 1; | ||||
goto bailout; | goto bailout; | ||||
} | } | ||||
value = strsep(&tmpstr, "="); | value = strsep(&tmpstr, "="); | ||||
if (value == NULL) { | if (value == NULL) { | ||||
warnx("%s: option -o takes \"name=value\"" | warnx("%s: option -o takes \"name=value\"" | ||||
"argument", __func__); | "argument", __func__); | ||||
retval = 1; | retval = 1; | ||||
goto bailout; | 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->namelen = strlen(name) + 1; | |||||
option->value = strdup(value); | |||||
option->vallen = strlen(value) + 1; | |||||
free(tmpstr); | |||||
STAILQ_INSERT_TAIL(&option_list, option, links); | free(tmpstr); | ||||
num_options++; | nvlist_add_string(option_list, name, value); | ||||
break; | break; | ||||
} | } | ||||
case 's': | case 's': | ||||
if (strcasecmp(optarg, "auto") != 0) { | if (strcasecmp(optarg, "auto") != 0) { | ||||
retval = expand_number(optarg, &lun_size); | retval = expand_number(optarg, &lun_size); | ||||
if (retval != 0) { | if (retval != 0) { | ||||
warn("%s: invalid -s argument", | warn("%s: invalid -s argument", | ||||
__func__); | __func__); | ||||
▲ Show 20 Lines • Show All 50 Lines • ▼ Show 20 Lines | cctl_create_lun(int fd, int argc, char **argv, char *combinedopt) | ||||
} | } | ||||
if (device_id != NULL) { | if (device_id != NULL) { | ||||
strlcpy(req.reqdata.create.device_id, device_id, | strlcpy(req.reqdata.create.device_id, device_id, | ||||
sizeof(req.reqdata.create.device_id)); | sizeof(req.reqdata.create.device_id)); | ||||
req.reqdata.create.flags |= CTL_LUN_FLAG_DEVID; | req.reqdata.create.flags |= CTL_LUN_FLAG_DEVID; | ||||
} | } | ||||
req.num_be_args = num_options; | req.args = nvlist_pack(option_list, &req.args_len); | ||||
if (num_options > 0) { | if (req.args == NULL) { | ||||
struct cctl_req_option *option, *next_option; | warn("%s: error packing nvlist", __func__); | ||||
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)); | |||||
retval = 1; | retval = 1; | ||||
goto bailout; | goto bailout; | ||||
} | } | ||||
for (i = 0, option = STAILQ_FIRST(&option_list); | retval = ioctl(fd, CTL_LUN_REQ, &req); | ||||
i < num_options; i++, option = next_option) { | free(req.args); | ||||
next_option = STAILQ_NEXT(option, links); | if (retval == -1) { | ||||
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; | |||||
STAILQ_REMOVE(&option_list, option, cctl_req_option, | |||||
links); | |||||
free(option->name); | |||||
free(option->value); | |||||
free(option); | |||||
} | |||||
} | |||||
if (ioctl(fd, CTL_LUN_REQ, &req) == -1) { | |||||
warn("%s: error issuing CTL_LUN_REQ ioctl", __func__); | warn("%s: error issuing CTL_LUN_REQ ioctl", __func__); | ||||
retval = 1; | retval = 1; | ||||
goto bailout; | goto bailout; | ||||
} | } | ||||
switch (req.status) { | switch (req.status) { | ||||
case CTL_LUN_ERROR: | case CTL_LUN_ERROR: | ||||
warnx("LUN creation error: %s", req.error_str); | warnx("LUN creation error: %s", req.error_str); | ||||
Show All 14 Lines | cctl_create_lun(int fd, int argc, char **argv, char *combinedopt) | ||||
fprintf(stdout, "backend: %s\n", req.backend); | fprintf(stdout, "backend: %s\n", req.backend); | ||||
fprintf(stdout, "device type: %d\n",req.reqdata.create.device_type); | fprintf(stdout, "device type: %d\n",req.reqdata.create.device_type); | ||||
fprintf(stdout, "LUN size: %ju bytes\n", | fprintf(stdout, "LUN size: %ju bytes\n", | ||||
(uintmax_t)req.reqdata.create.lun_size_bytes); | (uintmax_t)req.reqdata.create.lun_size_bytes); | ||||
fprintf(stdout, "blocksize %u bytes\n", | fprintf(stdout, "blocksize %u bytes\n", | ||||
req.reqdata.create.blocksize_bytes); | req.reqdata.create.blocksize_bytes); | ||||
fprintf(stdout, "LUN ID: %d\n", req.reqdata.create.req_lun_id); | 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, "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: | bailout: | ||||
nvlist_destroy(req.args_nvl); | |||||
return (retval); | return (retval); | ||||
} | } | ||||
static int | static int | ||||
cctl_rm_lun(int fd, int argc, char **argv, char *combinedopt) | cctl_rm_lun(int fd, int argc, char **argv, char *combinedopt) | ||||
{ | { | ||||
struct ctl_lun_req req; | struct ctl_lun_req req; | ||||
uint32_t lun_id = 0; | uint32_t lun_id = 0; | ||||
int lun_id_set = 0; | int lun_id_set = 0; | ||||
char *backend_name = NULL; | char *backend_name = NULL; | ||||
STAILQ_HEAD(, cctl_req_option) option_list; | nvlist_t *option_list; | ||||
int num_options = 0; | |||||
int retval = 0, c; | int retval = 0, c; | ||||
STAILQ_INIT(&option_list); | option_list = nvlist_create(0); | ||||
if (option_list == NULL) | |||||
err(1, "%s: unable to allocate nvlist", __func__); | |||||
while ((c = getopt(argc, argv, combinedopt)) != -1) { | while ((c = getopt(argc, argv, combinedopt)) != -1) { | ||||
switch (c) { | switch (c) { | ||||
case 'b': | case 'b': | ||||
backend_name = strdup(optarg); | backend_name = strdup(optarg); | ||||
break; | break; | ||||
case 'l': | case 'l': | ||||
lun_id = strtoul(optarg, NULL, 0); | lun_id = strtoul(optarg, NULL, 0); | ||||
lun_id_set = 1; | lun_id_set = 1; | ||||
break; | break; | ||||
case 'o': { | case 'o': { | ||||
struct cctl_req_option *option; | |||||
char *tmpstr; | char *tmpstr; | ||||
char *name, *value; | char *name, *value; | ||||
tmpstr = strdup(optarg); | tmpstr = strdup(optarg); | ||||
name = strsep(&tmpstr, "="); | name = strsep(&tmpstr, "="); | ||||
if (name == NULL) { | if (name == NULL) { | ||||
warnx("%s: option -o takes \"name=value\"" | warnx("%s: option -o takes \"name=value\"" | ||||
"argument", __func__); | "argument", __func__); | ||||
retval = 1; | retval = 1; | ||||
goto bailout; | goto bailout; | ||||
} | } | ||||
value = strsep(&tmpstr, "="); | value = strsep(&tmpstr, "="); | ||||
if (value == NULL) { | if (value == NULL) { | ||||
warnx("%s: option -o takes \"name=value\"" | warnx("%s: option -o takes \"name=value\"" | ||||
"argument", __func__); | "argument", __func__); | ||||
retval = 1; | retval = 1; | ||||
goto bailout; | 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->namelen = strlen(name) + 1; | |||||
option->value = strdup(value); | |||||
option->vallen = strlen(value) + 1; | |||||
free(tmpstr); | |||||
STAILQ_INSERT_TAIL(&option_list, option, links); | free(tmpstr); | ||||
num_options++; | nvlist_add_string(option_list, name, value); | ||||
break; | break; | ||||
} | } | ||||
default: | default: | ||||
break; | break; | ||||
} | } | ||||
} | } | ||||
if (backend_name == NULL) | if (backend_name == NULL) | ||||
errx(1, "%s: backend name (-b) must be specified", __func__); | errx(1, "%s: backend name (-b) must be specified", __func__); | ||||
if (lun_id_set == 0) | if (lun_id_set == 0) | ||||
errx(1, "%s: LUN id (-l) must be specified", __func__); | errx(1, "%s: LUN id (-l) must be specified", __func__); | ||||
bzero(&req, sizeof(req)); | bzero(&req, sizeof(req)); | ||||
strlcpy(req.backend, backend_name, sizeof(req.backend)); | strlcpy(req.backend, backend_name, sizeof(req.backend)); | ||||
req.reqtype = CTL_LUNREQ_RM; | req.reqtype = CTL_LUNREQ_RM; | ||||
req.reqdata.rm.lun_id = lun_id; | req.reqdata.rm.lun_id = lun_id; | ||||
req.num_be_args = num_options; | req.args = nvlist_pack(option_list, &req.args_len); | ||||
if (num_options > 0) { | if (req.args == NULL) { | ||||
Done Inline ActionsI suppose nvlist_destroy() should be moved up just after nvlist_pack() to not leak memory if one fail. Same time here should probably be freed req.args. mav: I suppose nvlist_destroy() should be moved up just after nvlist_pack() to not leak memory if… | |||||
struct cctl_req_option *option, *next_option; | warn("%s: error packing nvlist", __func__); | ||||
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)); | |||||
retval = 1; | retval = 1; | ||||
goto bailout; | goto bailout; | ||||
} | } | ||||
for (i = 0, option = STAILQ_FIRST(&option_list); | retval = ioctl(fd, CTL_LUN_REQ, &req); | ||||
i < num_options; i++, option = next_option) { | free(req.args); | ||||
next_option = STAILQ_NEXT(option, links); | if (retval == -1) { | ||||
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; | |||||
STAILQ_REMOVE(&option_list, option, cctl_req_option, | |||||
links); | |||||
free(option->name); | |||||
free(option->value); | |||||
free(option); | |||||
} | |||||
} | |||||
if (ioctl(fd, CTL_LUN_REQ, &req) == -1) { | |||||
warn("%s: error issuing CTL_LUN_REQ ioctl", __func__); | warn("%s: error issuing CTL_LUN_REQ ioctl", __func__); | ||||
retval = 1; | retval = 1; | ||||
goto bailout; | goto bailout; | ||||
} | } | ||||
switch (req.status) { | switch (req.status) { | ||||
case CTL_LUN_ERROR: | case CTL_LUN_ERROR: | ||||
warnx("LUN removal error: %s", req.error_str); | warnx("LUN removal error: %s", req.error_str); | ||||
retval = 1; | retval = 1; | ||||
goto bailout; | goto bailout; | ||||
case CTL_LUN_WARNING: | case CTL_LUN_WARNING: | ||||
warnx("LUN removal warning: %s", req.error_str); | warnx("LUN removal warning: %s", req.error_str); | ||||
break; | break; | ||||
case CTL_LUN_OK: | case CTL_LUN_OK: | ||||
break; | break; | ||||
default: | default: | ||||
warnx("unknown LUN removal status: %d", req.status); | warnx("unknown LUN removal status: %d", req.status); | ||||
retval = 1; | retval = 1; | ||||
goto bailout; | goto bailout; | ||||
} | } | ||||
printf("LUN %d removed successfully\n", lun_id); | printf("LUN %d removed successfully\n", lun_id); | ||||
bailout: | bailout: | ||||
nvlist_destroy(req.args_nvl); | |||||
return (retval); | return (retval); | ||||
} | } | ||||
static int | static int | ||||
cctl_modify_lun(int fd, int argc, char **argv, char *combinedopt) | cctl_modify_lun(int fd, int argc, char **argv, char *combinedopt) | ||||
{ | { | ||||
struct ctl_lun_req req; | struct ctl_lun_req req; | ||||
uint64_t lun_size = 0; | uint64_t lun_size = 0; | ||||
uint32_t lun_id = 0; | uint32_t lun_id = 0; | ||||
int lun_id_set = 0, lun_size_set = 0; | int lun_id_set = 0, lun_size_set = 0; | ||||
char *backend_name = NULL; | char *backend_name = NULL; | ||||
STAILQ_HEAD(, cctl_req_option) option_list; | nvlist_t *option_list; | ||||
int num_options = 0; | |||||
int retval = 0, c; | int retval = 0, c; | ||||
STAILQ_INIT(&option_list); | option_list = nvlist_create(0); | ||||
if (option_list == NULL) | |||||
err(1, "%s: unable to allocate nvlist", __func__); | |||||
while ((c = getopt(argc, argv, combinedopt)) != -1) { | while ((c = getopt(argc, argv, combinedopt)) != -1) { | ||||
switch (c) { | switch (c) { | ||||
case 'b': | case 'b': | ||||
backend_name = strdup(optarg); | backend_name = strdup(optarg); | ||||
break; | break; | ||||
case 'l': | case 'l': | ||||
lun_id = strtoul(optarg, NULL, 0); | lun_id = strtoul(optarg, NULL, 0); | ||||
lun_id_set = 1; | lun_id_set = 1; | ||||
break; | break; | ||||
case 'o': { | case 'o': { | ||||
struct cctl_req_option *option; | |||||
char *tmpstr; | char *tmpstr; | ||||
char *name, *value; | char *name, *value; | ||||
tmpstr = strdup(optarg); | tmpstr = strdup(optarg); | ||||
name = strsep(&tmpstr, "="); | name = strsep(&tmpstr, "="); | ||||
if (name == NULL) { | if (name == NULL) { | ||||
warnx("%s: option -o takes \"name=value\"" | warnx("%s: option -o takes \"name=value\"" | ||||
"argument", __func__); | "argument", __func__); | ||||
retval = 1; | retval = 1; | ||||
goto bailout; | goto bailout; | ||||
} | } | ||||
value = strsep(&tmpstr, "="); | value = strsep(&tmpstr, "="); | ||||
if (value == NULL) { | if (value == NULL) { | ||||
warnx("%s: option -o takes \"name=value\"" | warnx("%s: option -o takes \"name=value\"" | ||||
"argument", __func__); | "argument", __func__); | ||||
retval = 1; | retval = 1; | ||||
goto bailout; | 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->namelen = strlen(name) + 1; | |||||
option->value = strdup(value); | |||||
option->vallen = strlen(value) + 1; | |||||
free(tmpstr); | |||||
STAILQ_INSERT_TAIL(&option_list, option, links); | free(tmpstr); | ||||
num_options++; | nvlist_add_string(option_list, name, value); | ||||
break; | break; | ||||
} | } | ||||
case 's': | case 's': | ||||
if (strcasecmp(optarg, "auto") != 0) { | if (strcasecmp(optarg, "auto") != 0) { | ||||
retval = expand_number(optarg, &lun_size); | retval = expand_number(optarg, &lun_size); | ||||
if (retval != 0) { | if (retval != 0) { | ||||
warn("%s: invalid -s argument", | warn("%s: invalid -s argument", | ||||
__func__); | __func__); | ||||
Show All 9 Lines | cctl_modify_lun(int fd, int argc, char **argv, char *combinedopt) | ||||
} | } | ||||
if (backend_name == NULL) | if (backend_name == NULL) | ||||
errx(1, "%s: backend name (-b) must be specified", __func__); | errx(1, "%s: backend name (-b) must be specified", __func__); | ||||
if (lun_id_set == 0) | if (lun_id_set == 0) | ||||
errx(1, "%s: LUN id (-l) must be specified", __func__); | errx(1, "%s: LUN id (-l) must be specified", __func__); | ||||
if (lun_size_set == 0 && num_options == 0) | if (lun_size_set == 0 && nvlist_empty(option_list)) | ||||
errx(1, "%s: size (-s) or options (-o) must be specified", | errx(1, "%s: size (-s) or options (-o) must be specified", | ||||
__func__); | __func__); | ||||
bzero(&req, sizeof(req)); | bzero(&req, sizeof(req)); | ||||
strlcpy(req.backend, backend_name, sizeof(req.backend)); | strlcpy(req.backend, backend_name, sizeof(req.backend)); | ||||
req.reqtype = CTL_LUNREQ_MODIFY; | req.reqtype = CTL_LUNREQ_MODIFY; | ||||
req.reqdata.modify.lun_id = lun_id; | req.reqdata.modify.lun_id = lun_id; | ||||
req.reqdata.modify.lun_size_bytes = lun_size; | req.reqdata.modify.lun_size_bytes = lun_size; | ||||
req.num_be_args = num_options; | req.args = nvlist_pack(option_list, &req.args_len); | ||||
Done Inline ActionsSame as above. mav: Same as above. | |||||
if (num_options > 0) { | if (req.args == NULL) { | ||||
struct cctl_req_option *option, *next_option; | warn("%s: error packing nvlist", __func__); | ||||
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)); | |||||
retval = 1; | retval = 1; | ||||
goto bailout; | goto bailout; | ||||
} | } | ||||
for (i = 0, option = STAILQ_FIRST(&option_list); | retval = ioctl(fd, CTL_LUN_REQ, &req); | ||||
i < num_options; i++, option = next_option) { | free(req.args); | ||||
next_option = STAILQ_NEXT(option, links); | if (retval == -1) { | ||||
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; | |||||
STAILQ_REMOVE(&option_list, option, cctl_req_option, | |||||
links); | |||||
free(option->name); | |||||
free(option->value); | |||||
free(option); | |||||
} | |||||
} | |||||
if (ioctl(fd, CTL_LUN_REQ, &req) == -1) { | |||||
warn("%s: error issuing CTL_LUN_REQ ioctl", __func__); | warn("%s: error issuing CTL_LUN_REQ ioctl", __func__); | ||||
retval = 1; | retval = 1; | ||||
goto bailout; | goto bailout; | ||||
} | } | ||||
switch (req.status) { | switch (req.status) { | ||||
case CTL_LUN_ERROR: | case CTL_LUN_ERROR: | ||||
warnx("LUN modification error: %s", req.error_str); | warnx("LUN modification error: %s", req.error_str); | ||||
retval = 1; | retval = 1; | ||||
goto bailout; | goto bailout; | ||||
case CTL_LUN_WARNING: | case CTL_LUN_WARNING: | ||||
warnx("LUN modification warning: %s", req.error_str); | warnx("LUN modification warning: %s", req.error_str); | ||||
break; | break; | ||||
case CTL_LUN_OK: | case CTL_LUN_OK: | ||||
break; | break; | ||||
default: | default: | ||||
warnx("unknown LUN modification status: %d", req.status); | warnx("unknown LUN modification status: %d", req.status); | ||||
retval = 1; | retval = 1; | ||||
goto bailout; | goto bailout; | ||||
} | } | ||||
printf("LUN %d modified successfully\n", lun_id); | printf("LUN %d modified successfully\n", lun_id); | ||||
bailout: | bailout: | ||||
nvlist_destroy(req.args_nvl); | |||||
return (retval); | return (retval); | ||||
} | } | ||||
struct cctl_islist_conn { | struct cctl_islist_conn { | ||||
int connection_id; | int connection_id; | ||||
char *initiator; | char *initiator; | ||||
char *initiator_addr; | char *initiator_addr; | ||||
char *initiator_alias; | char *initiator_alias; | ||||
▲ Show 20 Lines • Show All 906 Lines • ▼ Show 20 Lines | case 'x': | ||||
dump_xml = 1; | dump_xml = 1; | ||||
break; | break; | ||||
default: | default: | ||||
break; | break; | ||||
} | } | ||||
} | } | ||||
retry: | retry: | ||||
port_str = malloc(port_len); | port_str = malloc(port_len); | ||||
Done Inline ActionsWhy not port_str? mav: Why not port_str? | |||||
bzero(&list, sizeof(list)); | bzero(&list, sizeof(list)); | ||||
list.alloc_len = port_len; | list.alloc_len = port_len; | ||||
list.status = CTL_LUN_LIST_NONE; | list.status = CTL_LUN_LIST_NONE; | ||||
list.lun_xml = port_str; | list.lun_xml = port_str; | ||||
if (ioctl(fd, CTL_PORT_LIST, &list) == -1) { | if (ioctl(fd, CTL_PORT_LIST, &list) == -1) { | ||||
warn("%s: error issuing CTL_PORT_LIST ioctl", __func__); | warn("%s: error issuing CTL_PORT_LIST ioctl", __func__); | ||||
▲ Show 20 Lines • Show All 155 Lines • ▼ Show 20 Lines | |||||
" ctladm lunlist\n" | " ctladm lunlist\n" | ||||
" ctladm lunmap -p targ_port [-l pLUN] [-L cLUN]\n" | " ctladm lunmap -p targ_port [-l pLUN] [-L cLUN]\n" | ||||
" ctladm delay [dev_id] <-l datamove|done> [-T oneshot|cont]\n" | " ctladm delay [dev_id] <-l datamove|done> [-T oneshot|cont]\n" | ||||
" [-t secs]\n" | " [-t secs]\n" | ||||
" ctladm inject [dev_id] <-i action> <-p pattern> [-r lba,len]\n" | " ctladm inject [dev_id] <-i action> <-p pattern> [-r lba,len]\n" | ||||
" [-s len fmt [args]] [-c] [-d delete_id]\n" | " [-s len fmt [args]] [-c] [-d delete_id]\n" | ||||
" ctladm port <-o <on|off> | [-w wwnn][-W wwpn]>\n" | " ctladm port <-o <on|off> | [-w wwnn][-W wwpn]>\n" | ||||
" [-p targ_port] [-t port_type]\n" | " [-p targ_port] [-t port_type]\n" | ||||
" <-c> [-d driver] [-O name=value]\n" | |||||
" <-d> <-p targ_port>\n" | |||||
Not Done Inline ActionsWhy -d is twice here, while -r is missing? mav: Why -d is twice here, while -r is missing? | |||||
" ctladm portlist [-f frontend] [-i] [-p targ_port] [-q] [-v] [-x]\n" | " ctladm portlist [-f frontend] [-i] [-p targ_port] [-q] [-v] [-x]\n" | ||||
" ctladm islist [-v | -x]\n" | " ctladm islist [-v | -x]\n" | ||||
" ctladm islogout <-a | -c connection-id | -i name | -p portal>\n" | " ctladm islogout <-a | -c connection-id | -i name | -p portal>\n" | ||||
" ctladm isterminate <-a | -c connection-id | -i name | -p portal>\n" | " ctladm isterminate <-a | -c connection-id | -i name | -p portal>\n" | ||||
" ctladm dumpooa\n" | " ctladm dumpooa\n" | ||||
" ctladm dumpstructs\n" | " ctladm dumpstructs\n" | ||||
" ctladm help\n" | " ctladm help\n" | ||||
"General Options:\n" | "General Options:\n" | ||||
▲ Show 20 Lines • Show All 64 Lines • ▼ Show 20 Lines | |||||
"-p pattern : command pattern to look for\n" | "-p pattern : command pattern to look for\n" | ||||
"-r lba,len : LBA range for pattern\n" | "-r lba,len : LBA range for pattern\n" | ||||
"-s len fmt [args] : sense data for custom sense action\n" | "-s len fmt [args] : sense data for custom sense action\n" | ||||
"-c : continuous operation\n" | "-c : continuous operation\n" | ||||
"-d delete_id : error id to delete\n" | "-d delete_id : error id to delete\n" | ||||
"port options:\n" | "port options:\n" | ||||
"-l : list frontend ports\n" | "-l : list frontend ports\n" | ||||
"-o on|off : turn frontend ports on or off\n" | "-o on|off : turn frontend ports on or off\n" | ||||
"-O pp|vp : creates new ioctl frontend port using pp and/or vp\n" | |||||
"-w wwnn : set WWNN for one frontend\n" | "-w wwnn : set WWNN for one frontend\n" | ||||
"-W wwpn : set WWPN for one frontend\n" | "-W wwpn : set WWPN for one frontend\n" | ||||
"-t port_type : specify fc, scsi, ioctl, internal frontend type\n" | "-t port_type : specify fc, scsi, ioctl, internal frontend type\n" | ||||
"-p targ_port : specify target port number\n" | "-p targ_port : specify target port number\n" | ||||
"-q : omit header in list output\n" | "-q : omit header in list output\n" | ||||
"-x : output port list in XML format\n" | "-x : output port list in XML format\n" | ||||
Not Done Inline ActionsHere missing -c -d and -r options. mav: Here missing -c -d and -r options. | |||||
"portlist options:\n" | "portlist options:\n" | ||||
"-f frontend : specify frontend type\n" | "-f frontend : specify frontend type\n" | ||||
"-i : report target and initiators addresses\n" | "-i : report target and initiators addresses\n" | ||||
"-l : report LUN mapping\n" | "-l : report LUN mapping\n" | ||||
"-p targ_port : specify target port number\n" | "-p targ_port : specify target port number\n" | ||||
"-q : omit header in list output\n" | "-q : omit header in list output\n" | ||||
"-v : verbose output (report all port options)\n" | "-v : verbose output (report all port options)\n" | ||||
"-x : output port list in XML format\n" | "-x : output port list in XML format\n" | ||||
Show All 30 Lines | main(int argc, char **argv) | ||||
retries = 0; | retries = 0; | ||||
lun = 0; | lun = 0; | ||||
initid = 7; | initid = 7; | ||||
if (argc < 2) { | if (argc < 2) { | ||||
usage(1); | usage(1); | ||||
retval = 1; | retval = 1; | ||||
goto bailout; | goto bailout; | ||||
} | } | ||||
Done Inline ActionsWhy was that new-line removed? mav: Why was that new-line removed? | |||||
Not Done Inline ActionsBetter, but still seems like a pointless whitespace change. mav: Better, but still seems like a pointless whitespace change. | |||||
/* | /* | ||||
* Get the base option. | * Get the base option. | ||||
*/ | */ | ||||
optreturn = getoption(option_table,argv[1], &command, &cmdargs,&subopt); | optreturn = getoption(option_table,argv[1], &command, &cmdargs,&subopt); | ||||
if (optreturn == CC_OR_AMBIGUOUS) { | if (optreturn == CC_OR_AMBIGUOUS) { | ||||
warnx("ambiguous option %s", argv[1]); | warnx("ambiguous option %s", argv[1]); | ||||
usage(0); | usage(0); | ||||
▲ Show 20 Lines • Show All 264 Lines • Show Last 20 Lines |
I am not sure what to do, but I am not exactly happy about changing option name here. Why -i actually?