diff options
Diffstat (limited to 'usr/src')
| -rw-r--r-- | usr/src/cmd/lofiadm/main.c | 34 | ||||
| -rw-r--r-- | usr/src/man/man1m/lofiadm.1m | 34 | ||||
| -rw-r--r-- | usr/src/uts/common/io/lofi.c | 49 | ||||
| -rw-r--r-- | usr/src/uts/common/sys/lofi.h | 5 | 
4 files changed, 97 insertions, 25 deletions
| diff --git a/usr/src/cmd/lofiadm/main.c b/usr/src/cmd/lofiadm/main.c index 0d310c2579..96d6764817 100644 --- a/usr/src/cmd/lofiadm/main.c +++ b/usr/src/cmd/lofiadm/main.c @@ -22,6 +22,8 @@   * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.   * Use is subject to license terms.   * Copyright 2012 Joyent, Inc.  All rights reserved. + * + * Copyright 2013 Nexenta Systems, Inc. All rights reserved.   */  /* @@ -64,7 +66,7 @@  #include <blowfish/blowfish_impl.h>  static const char USAGE[] = -	"Usage: %s -a file [ device ] " +	"Usage: %s [-r] -a file [ device ] "  	" [-c aes-128-cbc|aes-192-cbc|aes-256-cbc|des3-cbc|blowfish-cbc]"  	" [-e] [-k keyfile] [-T [token]:[manuf]:[serial]:key]\n"  	"       %s -d file | device\n" @@ -367,10 +369,12 @@ lofi_map_file(int lfd, struct lofi_ioctl li, const char *filename,  static void  add_mapping(int lfd, const char *devicename, const char *filename,      mech_alias_t *cipher, const char *rkey, size_t rksz, -    boolean_t no_devlink_flag) +    boolean_t rdonly, boolean_t no_devlink_flag)  {  	struct lofi_ioctl li; +	li.li_readonly = rdonly; +  	li.li_crypto_enabled = B_FALSE;  	if (cipher != NULL) {  		/* set up encryption for mapped file */ @@ -501,7 +505,7 @@ print_mappings(int fd)  	int	minor;  	int	maxminor;  	char	path[MAXPATHLEN]; -	char	options[MAXPATHLEN]; +	char	options[MAXPATHLEN] = { 0 };  	li.li_minor = 0;  	if (ioctl(fd, LOFI_GET_MAXMINOR, &li) == -1) { @@ -521,6 +525,9 @@ print_mappings(int fd)  		}  		(void) snprintf(path, sizeof (path), "/dev/%s/%d",  		    LOFI_BLOCK_NAME, minor); + +		options[0] = '\0'; +  		/*  		 * Encrypted lofi and compressed lofi are mutually exclusive.  		 */ @@ -530,7 +537,17 @@ print_mappings(int fd)  		else if (li.li_algorithm[0] != '\0')  			(void) snprintf(options, sizeof (options),  			    gettext("Compressed(%s)"), li.li_algorithm); -		else +		if (li.li_readonly) { +			if (strlen(options) != 0) { +				(void) strlcat(options, ",", sizeof (options)); +				(void) strlcat(options, "Readonly", +				    sizeof (options)); +			} else { +				(void) snprintf(options, sizeof (options), +				    gettext("Readonly")); +			} +		} +		if (strlen(options) == 0)  			(void) snprintf(options, sizeof (options), "-");  		(void) printf(FORMAT, path, li.li_filename, options); @@ -1793,6 +1810,7 @@ main(int argc, char *argv[])  	const char *pname;  	boolean_t errflag = B_FALSE;  	boolean_t addflag = B_FALSE; +	boolean_t rdflag = B_FALSE;  	boolean_t deleteflag = B_FALSE;  	boolean_t ephflag = B_FALSE;  	boolean_t compressflag = B_FALSE; @@ -1813,7 +1831,7 @@ main(int argc, char *argv[])  	(void) setlocale(LC_ALL, "");  	(void) textdomain(TEXT_DOMAIN); -	while ((c = getopt(argc, argv, "a:c:Cd:efk:o:s:T:UX")) != EOF) { +	while ((c = getopt(argc, argv, "a:c:Cd:efk:o:rs:T:UX")) != EOF) {  		switch (c) {  		case 'a':  			addflag = B_TRUE; @@ -1868,6 +1886,9 @@ main(int argc, char *argv[])  			need_crypto = B_TRUE;  			cipher_only = B_FALSE;	/* need to unset cipher_only */  			break; +		case 'r': +			rdflag = B_TRUE; +			break;  		case 's':  			segsize = convert_to_num(optarg);  			if (segsize < DEV_BSIZE || !ISP2(segsize)) @@ -1905,6 +1926,7 @@ main(int argc, char *argv[])  	/* Check for mutually exclusive combinations of options */  	if (errflag ||  	    (addflag && deleteflag) || +	    (rdflag && !addflag) ||  	    (!addflag && need_crypto) ||  	    ((compressflag || uncompressflag) && (addflag || deleteflag)))  		usage(pname); @@ -2022,7 +2044,7 @@ main(int argc, char *argv[])  	 */  	if (addflag)  		add_mapping(lfd, devicename, filename, cipher, rkey, rksz, -		    no_devlink_flag); +		    rdflag, no_devlink_flag);  	else if (compressflag)  		lofi_compress(&lfd, filename, compress_index, segsize);  	else if (uncompressflag) diff --git a/usr/src/man/man1m/lofiadm.1m b/usr/src/man/man1m/lofiadm.1m index 71c74a2658..e1ea5d0055 100644 --- a/usr/src/man/man1m/lofiadm.1m +++ b/usr/src/man/man1m/lofiadm.1m @@ -1,61 +1,62 @@  '\" te +.\" Copyright 2013 Nexenta Systems, Inc. All rights reserved.  .\" Copyright (c) 2008, Sun Microsystems, Inc. All Rights Reserved  .\" The contents of this file are subject to the terms of the Common Development and Distribution License (the "License").  You may not use this file except in compliance with the License. You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE or http://www.opensolaris.org/os/licensing.  .\"  See the License for the specific language governing permissions and limitations under the License. When distributing Covered Code, include this CDDL HEADER in each file and include the License file at usr/src/OPENSOLARIS.LICENSE.  If applicable, add the following below this CDDL HEADER, with  .\" the fields enclosed by brackets "[]" replaced with your own identifying information: Portions Copyright [yyyy] [name of copyright owner] -.TH LOFIADM 1M "Aug 31, 2009" +.TH LOFIADM 1M "Aug 28, 2013"  .SH NAME  lofiadm \- administer files available as block devices through lofi  .SH SYNOPSIS  .LP  .nf -\fB/usr/sbin/lofiadm\fR \fB-a\fR \fIfile\fR [\fIdevice\fR] +\fBlofiadm\fR [\fB-r\fR] \fB-a\fR \fIfile\fR [\fIdevice\fR]  .fi  .LP  .nf -\fB/usr/sbin/lofiadm\fR \fB-c\fR \fIcrypto_algorithm\fR \fB-a\fR \fIfile\fR [\fIdevice\fR] +\fBlofiadm\fR [\fB-r\fR] \fB-c\fR \fIcrypto_algorithm\fR \fB-a\fR \fIfile\fR [\fIdevice\fR]  .fi  .LP  .nf -\fB/usr/sbin/lofiadm\fR \fB-c\fR \fIcrypto_algorithm\fR \fB-k\fR \fIraw_key_file\fR \fB-a\fR \fIfile\fR [\fIdevice\fR] +\fBlofiadm\fR [\fB-r\fR] \fB-c\fR \fIcrypto_algorithm\fR \fB-k\fR \fIraw_key_file\fR \fB-a\fR \fIfile\fR [\fIdevice\fR]  .fi  .LP  .nf -\fB/usr/sbin/lofiadm\fR \fB-c\fR \fIcrypto_algorithm\fR \fB-T\fR \fItoken_key\fR \fB-a\fR \fIfile\fR [\fIdevice\fR] +\fBlofiadm\fR [\fB-r\fR] \fB-c\fR \fIcrypto_algorithm\fR \fB-T\fR \fItoken_key\fR \fB-a\fR \fIfile\fR [\fIdevice\fR]  .fi  .LP  .nf -\fB/usr/sbin/lofiadm\fR \fB-c\fR \fIcrypto_algorithm\fR \fB-T\fR \fItoken_key\fR +\fBlofiadm\fR [\fB-r\fR] \fB-c\fR \fIcrypto_algorithm\fR \fB-T\fR \fItoken_key\fR       \fB-k\fR \fIwrapped_key_file\fR \fB-a\fR \fIfile\fR [\fIdevice\fR]  .fi  .LP  .nf -\fB/usr/sbin/lofiadm\fR \fB-c\fR \fIcrypto_algorithm\fR \fB-e\fR \fB-a\fR \fIfile\fR [\fIdevice\fR] +\fBlofiadm\fR [\fB-r\fR] \fB-c\fR \fIcrypto_algorithm\fR \fB-e\fR \fB-a\fR \fIfile\fR [\fIdevice\fR]  .fi  .LP  .nf -\fB/usr/sbin/lofiadm\fR \fB-C\fR \fIalgorithm\fR [\fB-s\fR \fIsegment_size\fR] \fIfile\fR +\fBlofiadm\fR \fB-C\fR \fIalgorithm\fR [\fB-s\fR \fIsegment_size\fR] \fIfile\fR  .fi  .LP  .nf -\fB/usr/sbin/lofiadm\fR \fB-d\fR \fIfile\fR | \fIdevice\fR +\fBlofiadm\fR \fB-d\fR \fIfile\fR | \fIdevice\fR  .fi  .LP  .nf -\fB/usr/sbin/lofiadm\fR \fB-U\fR \fIfile\fR +\fBlofiadm\fR \fB-U\fR \fIfile\fR  .fi  .LP  .nf -\fB/usr/sbin/lofiadm\fR [ \fIfile\fR | \fIdevice\fR] +\fBlofiadm\fR [ \fIfile\fR | \fIdevice\fR]  .fi  .SH DESCRIPTION @@ -137,6 +138,17 @@ block device is not busy, and deallocates the block device.  .sp  .ne 2  .na +\fB\fB-r\fR +.ad +.sp .6 +.RS 4n +If the \fB-r\fR option is specified before the \fB-a\fR option, the +\fIdevice\fR will be opened read-only. +.RE + +.sp +.ne 2 +.na  \fB\fB-s\fR \fIsegment_size\fR\fR  .ad  .sp .6 diff --git a/usr/src/uts/common/io/lofi.c b/usr/src/uts/common/io/lofi.c index 049a0235fd..5229e680ff 100644 --- a/usr/src/uts/common/io/lofi.c +++ b/usr/src/uts/common/io/lofi.c @@ -20,6 +20,8 @@   */  /*   * Copyright (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved. + * + * Copyright 2013 Nexenta Systems, Inc. All rights reserved.   */  /* @@ -478,6 +480,11 @@ lofi_open(dev_t *devp, int flag, int otyp, struct cred *credp)  		return (EINVAL);  	} +	if (lsp->ls_readonly && (flag & FWRITE)) { +		mutex_exit(&lofi_lock); +		return (EROFS); +	} +  	mutex_exit(&lofi_lock);  	return (0);  } @@ -1620,11 +1627,13 @@ lofi_access(struct lofi_state *lsp)   * allow the global zone visibility into NGZ lofi nodes.   */  static int -file_to_lofi_nocheck(char *filename, struct lofi_state **lspp) +file_to_lofi_nocheck(char *filename, boolean_t readonly, +    struct lofi_state **lspp)  {  	struct lofi_state *lsp;  	vnode_t *vp = NULL;  	int err = 0; +	int rdfiles = 0;  	ASSERT(MUTEX_HELD(&lofi_lock)); @@ -1646,12 +1655,30 @@ file_to_lofi_nocheck(char *filename, struct lofi_state **lspp)  		if (lsp->ls_vp == vp) {  			if (lspp != NULL)  				*lspp = lsp; +			if (lsp->ls_readonly) { +				rdfiles++; +				/* Skip if '-r' is specified */ +				if (readonly) +					continue; +			}  			goto out;  		}  	}  	err = ENOENT; +	/* +	 * If a filename is given as an argument for lofi_unmap, we shouldn't +	 * allow unmap if there are multiple read-only lofi devices associated +	 * with this file. +	 */ +	if (lspp != NULL) { +		if (rdfiles == 1) +			err = 0; +		else if (rdfiles > 1) +			err = EBUSY; +	} +  out:  	if (vp != NULL)  		VN_RELE(vp); @@ -1663,13 +1690,13 @@ out:   * it.   */  static int -file_to_lofi(char *filename, struct lofi_state **lspp) +file_to_lofi(char *filename, boolean_t readonly, struct lofi_state **lspp)  {  	int err = 0;  	ASSERT(MUTEX_HELD(&lofi_lock)); -	if ((err = file_to_lofi_nocheck(filename, lspp)) != 0) +	if ((err = file_to_lofi_nocheck(filename, readonly, lspp)) != 0)  		return (err);  	if ((err = lofi_access(*lspp)) != 0) @@ -2122,7 +2149,8 @@ lofi_map_file(dev_t dev, struct lofi_ioctl *ulip, int pickminor,  	}  	mutex_exit(&curproc->p_lock); -	if (file_to_lofi_nocheck(klip->li_filename, NULL) == 0) { +	if (file_to_lofi_nocheck(klip->li_filename, klip->li_readonly, +	    NULL) == 0) {  		error = EBUSY;  		goto err;  	} @@ -2243,6 +2271,8 @@ lofi_map_file(dev_t dev, struct lofi_ioctl *ulip, int pickminor,  	lsp->ls_kstat->ks_lock = &lsp->ls_kstat_lock;  	kstat_zone_add(lsp->ls_kstat, GLOBAL_ZONEID); +	lsp->ls_readonly = klip->li_readonly; +  	if ((error = lofi_init_crypto(lsp, klip)) != 0)  		goto err; @@ -2343,7 +2373,8 @@ lofi_unmap_file(struct lofi_ioctl *ulip, int byfilename,  	mutex_enter(&lofi_lock);  	if (byfilename) { -		if ((err = file_to_lofi(klip->li_filename, &lsp)) != 0) { +		if ((err = file_to_lofi(klip->li_filename, klip->li_readonly, +		    &lsp)) != 0) {  			mutex_exit(&lofi_lock);  			return (err);  		} @@ -2460,6 +2491,8 @@ lofi_get_info(dev_t dev, struct lofi_ioctl *ulip, int which,  			    sizeof (klip->li_filename));  		} +		klip->li_readonly = lsp->ls_readonly; +  		(void) strlcpy(klip->li_algorithm, lsp->ls_comp_algorithm,  		    sizeof (klip->li_algorithm));  		klip->li_crypto_enabled = lsp->ls_crypto_enabled; @@ -2469,7 +2502,8 @@ lofi_get_info(dev_t dev, struct lofi_ioctl *ulip, int which,  		return (error);  	case LOFI_GET_MINOR:  		mutex_enter(&lofi_lock); -		error = file_to_lofi(klip->li_filename, &lsp); +		error = file_to_lofi(klip->li_filename, +		    klip->li_readonly, &lsp);  		if (error == 0)  			klip->li_minor = getminor(lsp->ls_dev);  		mutex_exit(&lofi_lock); @@ -2481,7 +2515,8 @@ lofi_get_info(dev_t dev, struct lofi_ioctl *ulip, int which,  		return (error);  	case LOFI_CHECK_COMPRESSED:  		mutex_enter(&lofi_lock); -		error = file_to_lofi(klip->li_filename, &lsp); +		error = file_to_lofi(klip->li_filename, +		    klip->li_readonly, &lsp);  		if (error != 0) {  			mutex_exit(&lofi_lock);  			free_lofi_ioctl(klip); diff --git a/usr/src/uts/common/sys/lofi.h b/usr/src/uts/common/sys/lofi.h index d82cc0341e..957c4b4feb 100644 --- a/usr/src/uts/common/sys/lofi.h +++ b/usr/src/uts/common/sys/lofi.h @@ -20,9 +20,10 @@   */  /*   * Copyright (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved. + * + * Copyright 2013 Nexenta Systems, Inc. All rights reserved.   */ -  #ifndef	_SYS_LOFI_H  #define	_SYS_LOFI_H @@ -128,6 +129,7 @@ struct lofi_ioctl {  	uint32_t 	li_minor;  	boolean_t	li_force;  	boolean_t	li_cleanup; +	boolean_t	li_readonly;  	char	li_filename[MAXPATHLEN];  	/* the following fields are required for compression support */ @@ -223,6 +225,7 @@ struct lofi_state {  	uint32_t	ls_lyr_open_count;  	int		ls_openflag;  	boolean_t	ls_cleanup;	/* cleanup on close */ +	boolean_t	ls_readonly;  	taskq_t		*ls_taskq;  	kstat_t		*ls_kstat;  	kmutex_t	ls_kstat_lock; | 
