Skip site navigation (1)Skip section navigation (2)
Date:      Sun, 6 Sep 2015 11:23:02 +0000 (UTC)
From:      Alexander Motin <mav@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r287500 - in head: sys/cam/ctl usr.sbin/ctladm usr.sbin/ctld
Message-ID:  <201509061123.t86BN2lr006508@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: mav
Date: Sun Sep  6 11:23:01 2015
New Revision: 287500
URL: https://svnweb.freebsd.org/changeset/base/287500

Log:
  Allow LUN options modification via CTL_LUNREQ_MODIFY.
  
  Not all changes take effect, but that is a different question.

Modified:
  head/sys/cam/ctl/ctl.h
  head/sys/cam/ctl/ctl_backend.c
  head/sys/cam/ctl/ctl_backend_block.c
  head/sys/cam/ctl/ctl_backend_ramdisk.c
  head/usr.sbin/ctladm/ctladm.8
  head/usr.sbin/ctladm/ctladm.c
  head/usr.sbin/ctld/ctld.c
  head/usr.sbin/ctld/ctld.h
  head/usr.sbin/ctld/kernel.c

Modified: head/sys/cam/ctl/ctl.h
==============================================================================
--- head/sys/cam/ctl/ctl.h	Sun Sep  6 09:54:56 2015	(r287499)
+++ head/sys/cam/ctl/ctl.h	Sun Sep  6 11:23:01 2015	(r287500)
@@ -208,6 +208,8 @@ typedef STAILQ_HEAD(ctl_options, ctl_opt
 
 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_expand_number(const char *buf, uint64_t *num);

Modified: head/sys/cam/ctl/ctl_backend.c
==============================================================================
--- head/sys/cam/ctl/ctl_backend.c	Sun Sep  6 09:54:56 2015	(r287499)
+++ head/sys/cam/ctl/ctl_backend.c	Sun Sep  6 11:23:01 2015	(r287500)
@@ -185,15 +185,48 @@ ctl_init_opts(ctl_options_t *opts, int n
 		if ((args[i].flags & CTL_BEARG_ASCII) == 0)
 			continue;
 		opt = malloc(sizeof(*opt), M_CTL, M_WAITOK);
-		opt->name = malloc(strlen(args[i].kname) + 1, M_CTL, M_WAITOK);
-		strcpy(opt->name, args[i].kname);
-		opt->value = malloc(strlen(args[i].kvalue) + 1, M_CTL, M_WAITOK);
-		strcpy(opt->value, args[i].kvalue);
+		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;

Modified: head/sys/cam/ctl/ctl_backend_block.c
==============================================================================
--- head/sys/cam/ctl/ctl_backend_block.c	Sun Sep  6 09:54:56 2015	(r287499)
+++ head/sys/cam/ctl/ctl_backend_block.c	Sun Sep  6 11:23:01 2015	(r287500)
@@ -2423,9 +2423,6 @@ ctl_be_block_rm(struct ctl_be_block_soft
 	params = &req->reqdata.rm;
 
 	mtx_lock(&softc->lock);
-
-	be_lun = NULL;
-
 	STAILQ_FOREACH(be_lun, &softc->lun_list, links) {
 		if (be_lun->cbe_lun.lun_id == params->lun_id)
 			break;
@@ -2589,13 +2586,13 @@ ctl_be_block_modify(struct ctl_be_block_
 {
 	struct ctl_lun_modify_params *params;
 	struct ctl_be_block_lun *be_lun;
+	struct ctl_be_lun *cbe_lun;
 	uint64_t oldsize;
 	int error;
 
 	params = &req->reqdata.modify;
 
 	mtx_lock(&softc->lock);
-	be_lun = NULL;
 	STAILQ_FOREACH(be_lun, &softc->lun_list, links) {
 		if (be_lun->cbe_lun.lun_id == params->lun_id)
 			break;
@@ -2608,8 +2605,11 @@ ctl_be_block_modify(struct ctl_be_block_
 			 params->lun_id);
 		goto bailout_error;
 	}
+	cbe_lun = &be_lun->cbe_lun;
 
-	be_lun->params.lun_size_bytes = params->lun_size_bytes;
+	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);
 
 	oldsize = be_lun->size_blocks;
 	if (be_lun->vn == NULL)
@@ -2622,11 +2622,11 @@ ctl_be_block_modify(struct ctl_be_block_
 		error = EINVAL;
 
 	if (be_lun->size_blocks != oldsize)
-		ctl_lun_capacity_changed(&be_lun->cbe_lun);
-	if ((be_lun->cbe_lun.flags & CTL_LUN_FLAG_OFFLINE) &&
+		ctl_lun_capacity_changed(cbe_lun);
+	if ((cbe_lun->flags & CTL_LUN_FLAG_OFFLINE) &&
 	    be_lun->vn != NULL) {
-		be_lun->cbe_lun.flags &= ~CTL_LUN_FLAG_OFFLINE;
-		ctl_lun_online(&be_lun->cbe_lun);
+		cbe_lun->flags &= ~CTL_LUN_FLAG_OFFLINE;
+		ctl_lun_online(cbe_lun);
 	}
 
 	/* Tell the user the exact size we ended up using */

Modified: head/sys/cam/ctl/ctl_backend_ramdisk.c
==============================================================================
--- head/sys/cam/ctl/ctl_backend_ramdisk.c	Sun Sep  6 09:54:56 2015	(r287499)
+++ head/sys/cam/ctl/ctl_backend_ramdisk.c	Sun Sep  6 11:23:01 2015	(r287500)
@@ -73,6 +73,7 @@ typedef enum {
 } ctl_be_ramdisk_lun_flags;
 
 struct ctl_be_ramdisk_lun {
+	struct ctl_lun_create_params params;
 	char lunname[32];
 	uint64_t size_bytes;
 	uint64_t size_blocks;
@@ -535,6 +536,7 @@ ctl_backend_ramdisk_create(struct ctl_be
 	be_lun = malloc(sizeof(*be_lun), M_RAMDISK, M_ZERO | M_WAITOK);
 	cbe_lun = &be_lun->cbe_lun;
 	cbe_lun->be_lun = be_lun;
+	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);
@@ -713,13 +715,12 @@ ctl_backend_ramdisk_modify(struct ctl_be
 		       struct ctl_lun_req *req)
 {
 	struct ctl_be_ramdisk_lun *be_lun;
+	struct ctl_be_lun *cbe_lun;
 	struct ctl_lun_modify_params *params;
 	uint32_t blocksize;
 
 	params = &req->reqdata.modify;
 
-	be_lun = NULL;
-
 	mtx_lock(&softc->lock);
 	STAILQ_FOREACH(be_lun, &softc->lun_list, links) {
 		if (be_lun->cbe_lun.lun_id == params->lun_id)
@@ -733,32 +734,22 @@ ctl_backend_ramdisk_modify(struct ctl_be
 			 __func__, params->lun_id);
 		goto bailout_error;
 	}
+	cbe_lun = &be_lun->cbe_lun;
 
-	if (params->lun_size_bytes == 0) {
-		snprintf(req->error_str, sizeof(req->error_str),
-			"%s: LUN size \"auto\" not supported "
-			"by the ramdisk backend", __func__);
-		goto bailout_error;
-	}
-
+	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);
 	blocksize = be_lun->cbe_lun.blocksize;
 
-	if (params->lun_size_bytes < blocksize) {
+	if (be_lun->params.lun_size_bytes < blocksize) {
 		snprintf(req->error_str, sizeof(req->error_str),
 			"%s: LUN size %ju < blocksize %u", __func__,
-			params->lun_size_bytes, blocksize);
+			be_lun->params.lun_size_bytes, blocksize);
 		goto bailout_error;
 	}
 
-	be_lun->size_blocks = params->lun_size_bytes / blocksize;
+	be_lun->size_blocks = be_lun->params.lun_size_bytes / blocksize;
 	be_lun->size_bytes = be_lun->size_blocks * blocksize;
-
-	/*
-	 * The maximum LBA is the size - 1.
-	 *
-	 * XXX: Note that this field is being updated without locking,
-	 * 	which might cause problems on 32-bit architectures.
-	 */
 	be_lun->cbe_lun.maxlba = be_lun->size_blocks - 1;
 	ctl_lun_capacity_changed(&be_lun->cbe_lun);
 

Modified: head/usr.sbin/ctladm/ctladm.8
==============================================================================
--- head/usr.sbin/ctladm/ctladm.8	Sun Sep  6 09:54:56 2015	(r287499)
+++ head/usr.sbin/ctladm/ctladm.8	Sun Sep  6 11:23:01 2015	(r287500)
@@ -34,7 +34,7 @@
 .\" $Id: //depot/users/kenm/FreeBSD-test2/usr.sbin/ctladm/ctladm.8#3 $
 .\" $FreeBSD$
 .\"
-.Dd June 3, 2015
+.Dd September 6, 2015
 .Dt CTLADM 8
 .Os
 .Sh NAME
@@ -166,6 +166,7 @@
 .Ic modify
 .Aq Fl b Ar backend
 .Aq Fl l Ar lun_id
+.Op Fl o Ar name=value
 .Aq Fl s Ar size_bytes
 .Nm
 .Ic devlist
@@ -859,6 +860,12 @@ and
 .Dq block .
 .It Fl l Ar lun_id
 Specify the LUN number to remove.
+.It Fl o Ar name=value
+Specify a backend-specific name/value pair.
+Multiple
+.Fl o
+arguments may be specified.
+Refer to the backend documentation for arguments that may be used.
 .It Fl s Ar size_bytes
 Specify the size of the LUN in bytes.
 For the

Modified: head/usr.sbin/ctladm/ctladm.c
==============================================================================
--- head/usr.sbin/ctladm/ctladm.c	Sun Sep  6 09:54:56 2015	(r287499)
+++ head/usr.sbin/ctladm/ctladm.c	Sun Sep  6 11:23:01 2015	(r287500)
@@ -183,7 +183,7 @@ static struct ctladm_opts option_table[]
 	{"lunlist", CTLADM_CMD_LUNLIST, CTLADM_ARG_NONE, NULL},
 	{"lunmap", CTLADM_CMD_LUNMAP, CTLADM_ARG_NONE, "p:l:L:"},
 	{"modesense", CTLADM_CMD_MODESENSE, CTLADM_ARG_NEED_TL, "P:S:dlm:c:"},
-	{"modify", CTLADM_CMD_MODIFY, CTLADM_ARG_NONE, "b:l: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"},
 	{"portlist", CTLADM_CMD_PORTLIST, CTLADM_ARG_NONE, "f:ilp:qvx"},
 	{"prin", CTLADM_CMD_PRES_IN, CTLADM_ARG_NEED_TL, "a:"},
@@ -3169,8 +3169,11 @@ cctl_modify_lun(int fd, int argc, char *
 	uint32_t lun_id = 0;
 	int lun_id_set = 0, lun_size_set = 0;
 	char *backend_name = NULL;
+	STAILQ_HEAD(, cctl_req_option) option_list;
+	int num_options = 0;
 	int retval = 0, c;
 
+	STAILQ_INIT(&option_list);
 	while ((c = getopt(argc, argv, combinedopt)) != -1) {
 		switch (c) {
 		case 'b':
@@ -3180,6 +3183,43 @@ cctl_modify_lun(int fd, int argc, char *
 			lun_id = strtoul(optarg, NULL, 0);
 			lun_id_set = 1;
 			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->namelen = strlen(name) + 1;
+			option->value = strdup(value);
+			option->vallen = strlen(value) + 1;
+			free(tmpstr);
+
+			STAILQ_INSERT_TAIL(&option_list, option, links);
+			num_options++;
+			break;
+		}
 		case 's':
 			if (strcasecmp(optarg, "auto") != 0) {
 				retval = expand_number(optarg, &lun_size);
@@ -3203,8 +3243,9 @@ cctl_modify_lun(int fd, int argc, char *
 	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__);
+	if (lun_size_set == 0 && num_options == 0)
+		errx(1, "%s: size (-s) or options (-o) must be specified",
+		    __func__);
 
 	bzero(&req, sizeof(req));
 
@@ -3214,6 +3255,42 @@ cctl_modify_lun(int fd, int argc, char *
 	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) {
+		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));
+			retval = 1;
+			goto bailout;
+		}
+
+		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;
+
+			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__);
 		retval = 1;

Modified: head/usr.sbin/ctld/ctld.c
==============================================================================
--- head/usr.sbin/ctld/ctld.c	Sun Sep  6 09:54:56 2015	(r287499)
+++ head/usr.sbin/ctld/ctld.c	Sun Sep  6 11:23:01 2015	(r287500)
@@ -1961,18 +1961,14 @@ conf_apply(struct conf *oldconf, struct 
 	TAILQ_FOREACH_SAFE(newlun, &newconf->conf_luns, l_next, tmplun) {
 		oldlun = lun_find(oldconf, newlun->l_name);
 		if (oldlun != NULL) {
-			if (newlun->l_size != oldlun->l_size ||
-			    newlun->l_size == 0) {
-				log_debugx("resizing lun \"%s\", CTL lun %d",
+			log_debugx("modifying lun \"%s\", CTL lun %d",
+			    newlun->l_name, newlun->l_ctl_lun);
+			error = kernel_lun_modify(newlun);
+			if (error != 0) {
+				log_warnx("failed to "
+				    "modify lun \"%s\", CTL lun %d",
 				    newlun->l_name, newlun->l_ctl_lun);
-				error = kernel_lun_resize(newlun);
-				if (error != 0) {
-					log_warnx("failed to "
-					    "resize lun \"%s\", CTL lun %d",
-					    newlun->l_name,
-					    newlun->l_ctl_lun);
-					cumulated_error++;
-				}
+				cumulated_error++;
 			}
 			continue;
 		}

Modified: head/usr.sbin/ctld/ctld.h
==============================================================================
--- head/usr.sbin/ctld/ctld.h	Sun Sep  6 09:54:56 2015	(r287499)
+++ head/usr.sbin/ctld/ctld.h	Sun Sep  6 11:23:01 2015	(r287500)
@@ -391,7 +391,7 @@ void			lun_option_set(struct lun_option 
 
 void			kernel_init(void);
 int			kernel_lun_add(struct lun *lun);
-int			kernel_lun_resize(struct lun *lun);
+int			kernel_lun_modify(struct lun *lun);
 int			kernel_lun_remove(struct lun *lun);
 void			kernel_handoff(struct connection *conn);
 void			kernel_limits(const char *offload,

Modified: head/usr.sbin/ctld/kernel.c
==============================================================================
--- head/usr.sbin/ctld/kernel.c	Sun Sep  6 09:54:56 2015	(r287499)
+++ head/usr.sbin/ctld/kernel.c	Sun Sep  6 11:23:01 2015	(r287500)
@@ -743,9 +743,11 @@ kernel_lun_add(struct lun *lun)
 }
 
 int
-kernel_lun_resize(struct lun *lun)
+kernel_lun_modify(struct lun *lun)
 {
+	struct lun_option *lo;
 	struct ctl_lun_req req;
+	int error, i, num_options;
 
 	bzero(&req, sizeof(req));
 
@@ -755,7 +757,30 @@ kernel_lun_resize(struct lun *lun)
 	req.reqdata.modify.lun_id = lun->l_ctl_lun;
 	req.reqdata.modify.lun_size_bytes = lun->l_size;
 
-	if (ioctl(ctl_fd, CTL_LUN_REQ, &req) == -1) {
+	num_options = 0;
+	TAILQ_FOREACH(lo, &lun->l_options, lo_next)
+		num_options++;
+
+	req.num_be_args = num_options;
+	if (num_options > 0) {
+		req.be_args = malloc(num_options * sizeof(*req.be_args));
+		if (req.be_args == NULL) {
+			log_warn("error allocating %zd bytes",
+			    num_options * sizeof(*req.be_args));
+			return (1);
+		}
+
+		i = 0;
+		TAILQ_FOREACH(lo, &lun->l_options, lo_next) {
+			str_arg(&req.be_args[i], lo->lo_name, lo->lo_value);
+			i++;
+		}
+		assert(i == num_options);
+	}
+
+	error = ioctl(ctl_fd, CTL_LUN_REQ, &req);
+	free(req.be_args);
+	if (error != 0) {
 		log_warn("error issuing CTL_LUN_REQ ioctl");
 		return (1);
 	}



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201509061123.t86BN2lr006508>