summaryrefslogtreecommitdiffstats
path: root/usr.sbin/ctladm/ctladm.c
diff options
context:
space:
mode:
Diffstat (limited to 'usr.sbin/ctladm/ctladm.c')
-rw-r--r--usr.sbin/ctladm/ctladm.c106
1 files changed, 102 insertions, 4 deletions
diff --git a/usr.sbin/ctladm/ctladm.c b/usr.sbin/ctladm/ctladm.c
index 77e7b02..f53e9f1 100644
--- a/usr.sbin/ctladm/ctladm.c
+++ b/usr.sbin/ctladm/ctladm.c
@@ -1,8 +1,12 @@
/*-
* Copyright (c) 2003, 2004 Silicon Graphics International Corp.
* Copyright (c) 1997-2007 Kenneth D. Merry
+ * Copyright (c) 2012 The FreeBSD Foundation
* All rights reserved.
*
+ * Portions of this software were developed by Edward Tomasz Napierala
+ * under sponsorship from the FreeBSD Foundation.
+ *
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
@@ -68,6 +72,7 @@ __FBSDID("$FreeBSD$");
#include <cam/ctl/ctl_util.h>
#include <cam/ctl/ctl_scsi_all.h>
#include <camlib.h>
+#include <libutil.h>
#include "ctladm.h"
#ifdef min
@@ -110,7 +115,8 @@ typedef enum {
CTLADM_CMD_PRES_IN,
CTLADM_CMD_PRES_OUT,
CTLADM_CMD_INQ_VPD_DEVID,
- CTLADM_CMD_RTPG
+ CTLADM_CMD_RTPG,
+ CTLADM_CMD_MODIFY
} ctladm_cmdfunction;
typedef enum {
@@ -175,6 +181,7 @@ struct ctladm_opts option_table[] = {
{"inquiry", CTLADM_CMD_INQUIRY, CTLADM_ARG_NEED_TL, NULL},
{"lunlist", CTLADM_CMD_LUNLIST, CTLADM_ARG_NONE, NULL},
{"modesense", CTLADM_CMD_MODESENSE, CTLADM_ARG_NEED_TL, "P:S:dlm:c:"},
+ {"modify", CTLADM_CMD_MODIFY, CTLADM_ARG_NONE, "b:l:s:"},
{"port", CTLADM_CMD_PORT, CTLADM_ARG_NONE, "lo:p:qt:w:W:x"},
{"prin", CTLADM_CMD_PRES_IN, CTLADM_ARG_NEED_TL, "a:"},
{"prout", CTLADM_CMD_PRES_OUT, CTLADM_ARG_NEED_TL, "a:k:r:s:"},
@@ -249,6 +256,7 @@ static int cctl_create_lun(int fd, int argc, char **argv, char *combinedopt);
static int cctl_inquiry_vpd_devid(int fd, int target, int lun, int initiator);
static int cctl_report_target_port_group(int fd, int target, int lun,
int initiator);
+static int cctl_modify_lun(int fd, int argc, char **argv, char *combinedopt);
ctladm_optret
getoption(struct ctladm_opts *table, char *arg, uint32_t *cmdnum,
@@ -3045,7 +3053,15 @@ cctl_create_lun(int fd, int argc, char **argv, char *combinedopt)
break;
}
case 's':
- lun_size = strtoull(optarg, NULL, 0);
+ if (strcasecmp(optarg, "auto") != 0) {
+ retval = expand_number(optarg, &lun_size);
+ if (retval != 0) {
+ warn("%s: invalid -s argument",
+ __func__);
+ retval = 1;
+ goto bailout;
+ }
+ }
lun_size_set = 1;
break;
case 'S':
@@ -3289,12 +3305,12 @@ cctl_rm_lun(int fd, int argc, char **argv, char *combinedopt)
}
if (req.status == CTL_LUN_ERROR) {
- warnx("%s: error returned from LUN creation request:\n%s",
+ warnx("%s: error returned from LUN removal request:\n%s",
__func__, req.error_str);
retval = 1;
goto bailout;
} else if (req.status != CTL_LUN_OK) {
- warnx("%s: unknown LUN creation request status %d",
+ warnx("%s: unknown LUN removal request status %d",
__func__, req.status);
retval = 1;
goto bailout;
@@ -3306,6 +3322,84 @@ bailout:
return (retval);
}
+static int
+cctl_modify_lun(int fd, int argc, char **argv, char *combinedopt)
+{
+ struct ctl_lun_req req;
+ uint64_t lun_size = 0;
+ uint32_t lun_id = 0;
+ int lun_id_set = 0, lun_size_set = 0;
+ char *backend_name = NULL;
+ int retval = 0, c;
+
+ while ((c = getopt(argc, argv, combinedopt)) != -1) {
+ switch (c) {
+ case 'b':
+ backend_name = strdup(optarg);
+ break;
+ case 'l':
+ lun_id = strtoul(optarg, NULL, 0);
+ lun_id_set = 1;
+ break;
+ case 's':
+ if (strcasecmp(optarg, "auto") != 0) {
+ retval = expand_number(optarg, &lun_size);
+ if (retval != 0) {
+ warn("%s: invalid -s argument",
+ __func__);
+ retval = 1;
+ goto bailout;
+ }
+ }
+ lun_size_set = 1;
+ break;
+ default:
+ break;
+ }
+ }
+
+ if (backend_name == NULL)
+ errx(1, "%s: backend name (-b) must be specified", __func__);
+
+ if (lun_id_set == 0)
+ errx(1, "%s: LUN id (-l) must be specified", __func__);
+
+ if (lun_size_set == 0)
+ errx(1, "%s: size (-s) must be specified", __func__);
+
+ bzero(&req, sizeof(req));
+
+ strlcpy(req.backend, backend_name, sizeof(req.backend));
+ req.reqtype = CTL_LUNREQ_MODIFY;
+
+ req.reqdata.modify.lun_id = lun_id;
+ req.reqdata.modify.lun_size_bytes = lun_size;
+
+ if (ioctl(fd, CTL_LUN_REQ, &req) == -1) {
+ warn("%s: error issuing CTL_LUN_REQ ioctl", __func__);
+ retval = 1;
+ goto bailout;
+ }
+
+ if (req.status == CTL_LUN_ERROR) {
+ warnx("%s: error returned from LUN modification request:\n%s",
+ __func__, req.error_str);
+ retval = 1;
+ goto bailout;
+ } else if (req.status != CTL_LUN_OK) {
+ warnx("%s: unknown LUN modification request status %d",
+ __func__, req.status);
+ retval = 1;
+ goto bailout;
+ }
+
+ printf("LUN %d modified successfully\n", lun_id);
+
+bailout:
+ return (retval);
+}
+
+
/*
* Name/value pair used for per-LUN attributes.
*/
@@ -3601,6 +3695,7 @@ usage(int error)
" [-l lun_id] [-o name=value] [-s size_bytes]\n"
" [-S serial_num] [-t dev_type]\n"
" ctladm remove <-b backend> <-l lun_id> [-o name=value]\n"
+" ctladm modify <-b backend> <-l lun_id> <-s size_bytes>\n"
" ctladm devlist [-b][-v][-x]\n"
" ctladm shutdown\n"
" ctladm startup\n"
@@ -3987,6 +4082,9 @@ main(int argc, char **argv)
case CTLADM_CMD_RTPG:
retval = cctl_report_target_port_group(fd, target, lun, initid);
break;
+ case CTLADM_CMD_MODIFY:
+ retval = cctl_modify_lun(fd, argc, argv, combinedopt);
+ break;
case CTLADM_CMD_HELP:
default:
usage(retval);
OpenPOWER on IntegriCloud