Home | History | Annotate | Download | only in sys
      1 /*
      2  * CDDL HEADER START
      3  *
      4  * The contents of this file are subject to the terms of the
      5  * Common Development and Distribution License (the "License").
      6  * You may not use this file except in compliance with the License.
      7  *
      8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
      9  * or http://www.opensolaris.org/os/licensing.
     10  * See the License for the specific language governing permissions
     11  * and limitations under the License.
     12  *
     13  * When distributing Covered Code, include this CDDL HEADER in each
     14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
     15  * If applicable, add the following below this CDDL HEADER, with the
     16  * fields enclosed by brackets "[]" replaced with your own identifying
     17  * information: Portions Copyright [yyyy] [name of copyright owner]
     18  *
     19  * CDDL HEADER END
     20  */
     21 /*
     22  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
     23  * Use is subject to license terms.
     24  */
     25 
     26 
     27 #ifndef	_SYS_LOFI_H
     28 #define	_SYS_LOFI_H
     29 
     30 #include <sys/types.h>
     31 #include <sys/time.h>
     32 #include <sys/taskq.h>
     33 #include <sys/vtoc.h>
     34 #include <sys/dkio.h>
     35 #include <sys/vnode.h>
     36 #include <sys/list.h>
     37 #include <sys/crypto/api.h>
     38 
     39 #ifdef	__cplusplus
     40 extern "C" {
     41 #endif
     42 
     43 /*
     44  * /dev names:
     45  *	/dev/lofictl	- master control device
     46  *	/dev/lofi	- block devices, named by minor number
     47  *	/dev/rlofi	- character devices, named by minor number
     48  */
     49 #define	LOFI_DRIVER_NAME	"lofi"
     50 #define	LOFI_CTL_NODE		"ctl"
     51 #define	LOFI_CTL_NAME		LOFI_DRIVER_NAME LOFI_CTL_NODE
     52 #define	LOFI_BLOCK_NAME		LOFI_DRIVER_NAME
     53 #define	LOFI_CHAR_NAME		"r" LOFI_DRIVER_NAME
     54 
     55 #define	SEGHDR		1
     56 #define	COMPRESSED	1
     57 #define	UNCOMPRESSED	0
     58 #define	MAXALGLEN	36
     59 
     60 /*
     61  *
     62  * Use is:
     63  *	ld = open("/dev/lofictl", O_RDWR | O_EXCL);
     64  *
     65  * lofi must be opened exclusively. Access is controlled by permissions on
     66  * the device, which is 644 by default. Write-access is required for ioctls
     67  * that change state, but only read-access is required for the ioctls that
     68  * return information. Basically, only root can add and remove files, but
     69  * non-root can look at the current lists.
     70  *
     71  * ioctl usage:
     72  *
     73  * kernel ioctls
     74  *
     75  *	strcpy(li.li_filename, "somefilename");
     76  *	ioctl(ld, LOFI_MAP_FILE, &li);
     77  *	newminor = li.li_minor;
     78  *
     79  *	strcpy(li.li_filename, "somefilename");
     80  *	ioctl(ld, LOFI_UNMAP_FILE, &li);
     81  *
     82  *	strcpy(li.li_filename, "somefilename");
     83  *	li.li_minor = minor_number;
     84  *	ioctl(ld, LOFI_MAP_FILE_MINOR, &li);
     85  *
     86  *	li.li_minor = minor_number;
     87  *	ioctl(ld, LOFI_UNMAP_FILE_MINOR, &li);
     88  *
     89  *	li.li_minor = minor_number;
     90  *	ioctl(ld, LOFI_GET_FILENAME, &li);
     91  *	filename = li.li_filename;
     92  *	encrypted = li.li_crypto_enabled;
     93  *
     94  *	strcpy(li.li_filename, "somefilename");
     95  *	ioctl(ld, LOFI_GET_MINOR, &li);
     96  *	minor = li.li_minor;
     97  *
     98  *	li.li_minor = 0;
     99  *	ioctl(ld, LOFI_GET_MAXMINOR, &li);
    100  *	maxminor = li.li_minor;
    101  *
    102  *	strcpy(li.li_filename, "somefilename");
    103  *	li.li_minor = 0;
    104  *	ioctl(ld, LOFI_CHECK_COMPRESSED, &li);
    105  *
    106  * If the 'li_force' flag is set for any of the LOFI_UNMAP_* commands, then if
    107  * the device is busy, the underlying vnode will be closed, and any subsequent
    108  * operations will fail.  It will behave as if the device had been forcibly
    109  * removed, so the DKIOCSTATE ioctl will return DKIO_DEV_GONE.  When the device
    110  * is last closed, it will be torn down.
    111  *
    112  * If the 'li_cleanup' flag is set for any of the LOFI_UNMAP_* commands, then
    113  * if the device is busy, it is marked for removal at the next time it is
    114  * no longer held open by anybody.  When the device is last closed, it will be
    115  * torn down.
    116  *
    117  * Oh, and last but not least: these ioctls are totally private and only
    118  * for use by lofiadm(1M).
    119  *
    120  */
    121 
    122 typedef enum	iv_method {
    123 	IVM_NONE,	/* no iv needed, iv is null */
    124 	IVM_ENC_BLKNO	/* iv is logical block no. encrypted */
    125 } iv_method_t;
    126 
    127 struct lofi_ioctl {
    128 	uint32_t 	li_minor;
    129 	boolean_t	li_force;
    130 	boolean_t	li_cleanup;
    131 	char	li_filename[MAXPATHLEN];
    132 
    133 	/* the following fields are required for compression support */
    134 	char	li_algorithm[MAXALGLEN];
    135 
    136 	/* the following fields are required for encryption support */
    137 	boolean_t	li_crypto_enabled;
    138 	crypto_mech_name_t	li_cipher;	/* for data */
    139 	uint32_t	li_key_len;		/* for data */
    140 	char		li_key[56];	/* for data: max 448-bit Blowfish key */
    141 	crypto_mech_name_t	li_iv_cipher;	/* for iv derivation */
    142 	uint32_t	li_iv_len;		/* for iv derivation */
    143 	iv_method_t	li_iv_type;		/* for iv derivation */
    144 };
    145 
    146 #define	LOFI_IOC_BASE		(('L' << 16) | ('F' << 8))
    147 
    148 #define	LOFI_MAP_FILE		(LOFI_IOC_BASE | 0x01)
    149 #define	LOFI_MAP_FILE_MINOR	(LOFI_IOC_BASE | 0x02)
    150 #define	LOFI_UNMAP_FILE		(LOFI_IOC_BASE | 0x03)
    151 #define	LOFI_UNMAP_FILE_MINOR	(LOFI_IOC_BASE | 0x04)
    152 #define	LOFI_GET_FILENAME	(LOFI_IOC_BASE | 0x05)
    153 #define	LOFI_GET_MINOR		(LOFI_IOC_BASE | 0x06)
    154 #define	LOFI_GET_MAXMINOR	(LOFI_IOC_BASE | 0x07)
    155 #define	LOFI_CHECK_COMPRESSED	(LOFI_IOC_BASE | 0x08)
    156 
    157 /*
    158  * file types that might be usable with lofi, maybe. Only regular
    159  * files are documented though.
    160  */
    161 #define	S_ISLOFIABLE(mode) \
    162 	(S_ISREG(mode) || S_ISBLK(mode) || S_ISCHR(mode))
    163 
    164 #if defined(_KERNEL)
    165 
    166 
    167 /*
    168  * Cache decompressed data segments for the compressed lofi images.
    169  *
    170  * To avoid that we have to decompress data of a compressed
    171  * segment multiple times when accessing parts of the segment's
    172  * data we cache the uncompressed data, using a simple linked list.
    173  */
    174 struct lofi_comp_cache {
    175 	list_node_t	lc_list;		/* linked list */
    176 	uchar_t		*lc_data;		/* decompressed segment data */
    177 	uint64_t	lc_index;		/* segment index */
    178 };
    179 
    180 /*
    181  * We limit the maximum number of active lofi devices to 128, which seems very
    182  * large. You can tune this by changing lofi_max_files in /etc/system.
    183  * If you change it dynamically, which you probably shouldn't do, make sure
    184  * to only _increase_ it.
    185  */
    186 #define	LOFI_MAX_FILES	128
    187 extern uint32_t lofi_max_files;
    188 
    189 #define	V_ISLOFIABLE(vtype) \
    190 	((vtype == VREG) || (vtype == VBLK) || (vtype == VCHR))
    191 
    192 /*
    193  * Need exactly 6 bytes to identify encrypted lofi image
    194  */
    195 extern const char lofi_crypto_magic[6];
    196 #define	LOFI_CRYPTO_MAGIC	{ 'C', 'F', 'L', 'O', 'F', 'I' }
    197 #define	LOFI_CRYPTO_VERSION	((uint16_t)0)
    198 #define	LOFI_CRYPTO_DATA_SECTOR	((uint32_t)16)		/* for version 0 */
    199 
    200 /*
    201  * Crypto metadata for encrypted lofi images
    202  * The fields here only satisfy initial implementation requirements.
    203  */
    204 struct crypto_meta {
    205 	char		magic[6];		/* LOFI_CRYPTO_MAGIC */
    206 	uint16_t	version;		/* version of encrypted lofi */
    207 	char		reserved1[96];		/* future use */
    208 	uint32_t	data_sector;		/* start of data area */
    209 	char		pad[404];		/* end on DEV_BSIZE bdry */
    210 	/* second header block is not defined at this time */
    211 };
    212 
    213 struct lofi_state {
    214 	char		*ls_filename;	/* filename to open */
    215 	size_t		ls_filename_sz;
    216 	struct vnode	*ls_vp;		/* open vnode */
    217 	kmutex_t	ls_vp_lock;	/* protects ls_vp */
    218 	kcondvar_t	ls_vp_cv;	/* signal changes to ls_vp */
    219 	uint32_t	ls_vp_iocount;	/* # pending I/O requests */
    220 	boolean_t	ls_vp_closereq;	/* force close requested */
    221 	u_offset_t	ls_vp_size;
    222 	uint32_t	ls_blk_open;
    223 	uint32_t	ls_chr_open;
    224 	uint32_t	ls_lyr_open_count;
    225 	int		ls_openflag;
    226 	boolean_t	ls_cleanup;	/* cleanup on close */
    227 	taskq_t		*ls_taskq;
    228 	kstat_t		*ls_kstat;
    229 	kmutex_t	ls_kstat_lock;
    230 	struct dk_geom	ls_dkg;
    231 	struct vtoc	ls_vtoc;
    232 	struct dk_cinfo	ls_ci;
    233 
    234 	/* the following fields are required for compression support */
    235 	int		ls_comp_algorithm_index; /* idx into compress_table */
    236 	char		ls_comp_algorithm[MAXALGLEN];
    237 	uint32_t	ls_uncomp_seg_sz; /* sz of uncompressed segment */
    238 	uint32_t	ls_comp_index_sz; /* number of index entries */
    239 	uint32_t	ls_comp_seg_shift; /* exponent for byte shift */
    240 	uint32_t	ls_uncomp_last_seg_sz; /* sz of last uncomp segment */
    241 	uint64_t	ls_comp_offbase; /* offset of actual compressed data */
    242 	uint64_t	*ls_comp_seg_index; /* array of index entries */
    243 	caddr_t		ls_comp_index_data; /* index pages loaded from file */
    244 	uint32_t	ls_comp_index_data_sz;
    245 	u_offset_t	ls_vp_comp_size; /* actual compressed file size */
    246 
    247 	/* lock and anchor for compressed segment caching */
    248 	kmutex_t	ls_comp_cache_lock;	/* protects ls_comp_cache */
    249 	list_t		ls_comp_cache;		/* cached decompressed segs */
    250 	uint32_t	ls_comp_cache_count;
    251 
    252 	/* the following fields are required for encryption support */
    253 	boolean_t		ls_crypto_enabled;
    254 	u_offset_t		ls_crypto_offset;	/* crypto meta size */
    255 	struct crypto_meta	ls_crypto;
    256 	crypto_mechanism_t	ls_mech;	/* for data encr/decr */
    257 	crypto_key_t		ls_key;		/* for data encr/decr */
    258 	crypto_mechanism_t	ls_iv_mech;	/* for iv derivation */
    259 	size_t			ls_iv_len;	/* for iv derivation */
    260 	iv_method_t		ls_iv_type;	/* for iv derivation */
    261 	kmutex_t		ls_crypto_lock;
    262 	crypto_ctx_template_t	ls_ctx_tmpl;
    263 
    264 };
    265 
    266 #endif	/* _KERNEL */
    267 
    268 /*
    269  * Common signature for all lofi compress functions
    270  */
    271 typedef int lofi_compress_func_t(void *src, size_t srclen, void *dst,
    272 	size_t *destlen, int level);
    273 
    274 /*
    275  * Information about each compression function
    276  */
    277 typedef struct lofi_compress_info {
    278 	lofi_compress_func_t	*l_decompress;
    279 	lofi_compress_func_t	*l_compress;
    280 	int			l_level;
    281 	char			*l_name;	/* algorithm name */
    282 } lofi_compress_info_t;
    283 
    284 enum lofi_compress {
    285 	LOFI_COMPRESS_GZIP = 0,
    286 	LOFI_COMPRESS_GZIP_6 = 1,
    287 	LOFI_COMPRESS_GZIP_9 = 2,
    288 	LOFI_COMPRESS_LZMA = 3,
    289 	LOFI_COMPRESS_FUNCTIONS
    290 };
    291 
    292 #ifdef	__cplusplus
    293 }
    294 #endif
    295 
    296 #endif	/* _SYS_LOFI_H */
    297