diff options
author | Alexander Eremin <a.eremin@nexenta.com> | 2013-09-23 10:41:22 +0400 |
---|---|---|
committer | Robert Mustacchi <rm@joyent.com> | 2013-09-25 13:46:00 -0700 |
commit | cd69fabe0332d2cf0e51b2cb6597286e0abcf6be (patch) | |
tree | 844c239a3590c5e0c7ba416186098ecc70054987 /usr/src | |
parent | c2589d1319a6171334739fb4b10ddc8317ec486b (diff) | |
download | illumos-joyent-cd69fabe0332d2cf0e51b2cb6597286e0abcf6be.tar.gz |
4086 readonly option for lofiadm(1m)
Reviewed by: Garrett D'Amore <garrett@damore.org>
Reviewed by: Yuri Pankov <yuri.pankov@nexenta.com>
Approved by: Robert Mustacchi <rm@joyent.com>
Diffstat (limited to 'usr/src')
-rw-r--r-- | usr/src/cmd/lofiadm/main.c | 35 | ||||
-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, 98 insertions, 25 deletions
diff --git a/usr/src/cmd/lofiadm/main.c b/usr/src/cmd/lofiadm/main.c index 23c127da4e..3777646d58 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" @@ -364,10 +366,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) + mech_alias_t *cipher, const char *rkey, size_t rksz, boolean_t rdonly) { struct lofi_ioctl li; + li.li_readonly = rdonly; + li.li_crypto_enabled = B_FALSE; if (cipher != NULL) { /* set up encryption for mapped file */ @@ -497,7 +501,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) { @@ -517,6 +521,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. */ @@ -526,7 +533,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); @@ -1789,6 +1806,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; @@ -1808,7 +1826,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:U")) != EOF) { + while ((c = getopt(argc, argv, "a:c:Cd:efk:o:rs:T:U")) != EOF) { switch (c) { case 'a': addflag = B_TRUE; @@ -1863,6 +1881,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)) @@ -1893,6 +1914,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); @@ -2009,7 +2031,8 @@ main(int argc, char *argv[]) * Now to the real work. */ if (addflag) - add_mapping(lfd, devicename, filename, cipher, rkey, rksz); + add_mapping(lfd, devicename, filename, cipher, rkey, rksz, + rdflag); 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 493223c3b2..eb7a2c0616 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 @@ -135,6 +136,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; |