xref: /onnv-gate/usr/src/uts/common/sys/lofi.h (revision 13096:b02331b7b26d)
10Sstevel@tonic-gate /*
20Sstevel@tonic-gate  * CDDL HEADER START
30Sstevel@tonic-gate  *
40Sstevel@tonic-gate  * The contents of this file are subject to the terms of the
54451Seschrock  * Common Development and Distribution License (the "License").
64451Seschrock  * You may not use this file except in compliance with the License.
70Sstevel@tonic-gate  *
80Sstevel@tonic-gate  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
90Sstevel@tonic-gate  * or http://www.opensolaris.org/os/licensing.
100Sstevel@tonic-gate  * See the License for the specific language governing permissions
110Sstevel@tonic-gate  * and limitations under the License.
120Sstevel@tonic-gate  *
130Sstevel@tonic-gate  * When distributing Covered Code, include this CDDL HEADER in each
140Sstevel@tonic-gate  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
150Sstevel@tonic-gate  * If applicable, add the following below this CDDL HEADER, with the
160Sstevel@tonic-gate  * fields enclosed by brackets "[]" replaced with your own identifying
170Sstevel@tonic-gate  * information: Portions Copyright [yyyy] [name of copyright owner]
180Sstevel@tonic-gate  *
190Sstevel@tonic-gate  * CDDL HEADER END
200Sstevel@tonic-gate  */
210Sstevel@tonic-gate /*
2212384Salok.aggarwal@oracle.com  * Copyright (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved.
230Sstevel@tonic-gate  */
240Sstevel@tonic-gate 
250Sstevel@tonic-gate 
260Sstevel@tonic-gate #ifndef	_SYS_LOFI_H
270Sstevel@tonic-gate #define	_SYS_LOFI_H
280Sstevel@tonic-gate 
290Sstevel@tonic-gate #include <sys/types.h>
300Sstevel@tonic-gate #include <sys/time.h>
310Sstevel@tonic-gate #include <sys/taskq.h>
320Sstevel@tonic-gate #include <sys/vtoc.h>
330Sstevel@tonic-gate #include <sys/dkio.h>
340Sstevel@tonic-gate #include <sys/vnode.h>
359048Sjrgn.keil@googlemail.com #include <sys/list.h>
368313SDina.Nimeh@Sun.Com #include <sys/crypto/api.h>
3712633Sjohn.levon@sun.com #include <sys/zone.h>
380Sstevel@tonic-gate 
390Sstevel@tonic-gate #ifdef	__cplusplus
400Sstevel@tonic-gate extern "C" {
410Sstevel@tonic-gate #endif
420Sstevel@tonic-gate 
430Sstevel@tonic-gate /*
440Sstevel@tonic-gate  * /dev names:
450Sstevel@tonic-gate  *	/dev/lofictl	- master control device
460Sstevel@tonic-gate  *	/dev/lofi	- block devices, named by minor number
470Sstevel@tonic-gate  *	/dev/rlofi	- character devices, named by minor number
480Sstevel@tonic-gate  */
490Sstevel@tonic-gate #define	LOFI_DRIVER_NAME	"lofi"
500Sstevel@tonic-gate #define	LOFI_CTL_NODE		"ctl"
510Sstevel@tonic-gate #define	LOFI_CTL_NAME		LOFI_DRIVER_NAME LOFI_CTL_NODE
520Sstevel@tonic-gate #define	LOFI_BLOCK_NAME		LOFI_DRIVER_NAME
530Sstevel@tonic-gate #define	LOFI_CHAR_NAME		"r" LOFI_DRIVER_NAME
540Sstevel@tonic-gate 
555643Saalok #define	SEGHDR		1
565643Saalok #define	COMPRESSED	1
575643Saalok #define	UNCOMPRESSED	0
585643Saalok #define	MAXALGLEN	36
595643Saalok 
600Sstevel@tonic-gate /*
610Sstevel@tonic-gate  *
620Sstevel@tonic-gate  * Use is:
630Sstevel@tonic-gate  *	ld = open("/dev/lofictl", O_RDWR | O_EXCL);
640Sstevel@tonic-gate  *
650Sstevel@tonic-gate  * lofi must be opened exclusively. Access is controlled by permissions on
660Sstevel@tonic-gate  * the device, which is 644 by default. Write-access is required for ioctls
670Sstevel@tonic-gate  * that change state, but only read-access is required for the ioctls that
680Sstevel@tonic-gate  * return information. Basically, only root can add and remove files, but
690Sstevel@tonic-gate  * non-root can look at the current lists.
700Sstevel@tonic-gate  *
710Sstevel@tonic-gate  * ioctl usage:
720Sstevel@tonic-gate  *
730Sstevel@tonic-gate  * kernel ioctls
740Sstevel@tonic-gate  *
750Sstevel@tonic-gate  *	strcpy(li.li_filename, "somefilename");
760Sstevel@tonic-gate  *	ioctl(ld, LOFI_MAP_FILE, &li);
770Sstevel@tonic-gate  *	newminor = li.li_minor;
780Sstevel@tonic-gate  *
790Sstevel@tonic-gate  *	strcpy(li.li_filename, "somefilename");
800Sstevel@tonic-gate  *	ioctl(ld, LOFI_UNMAP_FILE, &li);
810Sstevel@tonic-gate  *
820Sstevel@tonic-gate  *	strcpy(li.li_filename, "somefilename");
830Sstevel@tonic-gate  *	li.li_minor = minor_number;
840Sstevel@tonic-gate  *	ioctl(ld, LOFI_MAP_FILE_MINOR, &li);
850Sstevel@tonic-gate  *
860Sstevel@tonic-gate  *	li.li_minor = minor_number;
870Sstevel@tonic-gate  *	ioctl(ld, LOFI_UNMAP_FILE_MINOR, &li);
880Sstevel@tonic-gate  *
890Sstevel@tonic-gate  *	li.li_minor = minor_number;
900Sstevel@tonic-gate  *	ioctl(ld, LOFI_GET_FILENAME, &li);
918313SDina.Nimeh@Sun.Com  *	filename = li.li_filename;
928313SDina.Nimeh@Sun.Com  *	encrypted = li.li_crypto_enabled;
930Sstevel@tonic-gate  *
940Sstevel@tonic-gate  *	strcpy(li.li_filename, "somefilename");
950Sstevel@tonic-gate  *	ioctl(ld, LOFI_GET_MINOR, &li);
968313SDina.Nimeh@Sun.Com  *	minor = li.li_minor;
970Sstevel@tonic-gate  *
980Sstevel@tonic-gate  *	li.li_minor = 0;
990Sstevel@tonic-gate  *	ioctl(ld, LOFI_GET_MAXMINOR, &li);
1000Sstevel@tonic-gate  *	maxminor = li.li_minor;
1010Sstevel@tonic-gate  *
1025643Saalok  *	strcpy(li.li_filename, "somefilename");
1035643Saalok  *	li.li_minor = 0;
1045643Saalok  *	ioctl(ld, LOFI_CHECK_COMPRESSED, &li);
1055643Saalok  *
1064451Seschrock  * If the 'li_force' flag is set for any of the LOFI_UNMAP_* commands, then if
1074451Seschrock  * the device is busy, the underlying vnode will be closed, and any subsequent
1084451Seschrock  * operations will fail.  It will behave as if the device had been forcibly
1094451Seschrock  * removed, so the DKIOCSTATE ioctl will return DKIO_DEV_GONE.  When the device
1104451Seschrock  * is last closed, it will be torn down.
1114451Seschrock  *
1126734Sjohnlev  * If the 'li_cleanup' flag is set for any of the LOFI_UNMAP_* commands, then
1136734Sjohnlev  * if the device is busy, it is marked for removal at the next time it is
1146734Sjohnlev  * no longer held open by anybody.  When the device is last closed, it will be
1156734Sjohnlev  * torn down.
1166734Sjohnlev  *
1170Sstevel@tonic-gate  * Oh, and last but not least: these ioctls are totally private and only
1180Sstevel@tonic-gate  * for use by lofiadm(1M).
1190Sstevel@tonic-gate  *
1200Sstevel@tonic-gate  */
1210Sstevel@tonic-gate 
1228313SDina.Nimeh@Sun.Com typedef enum	iv_method {
1238313SDina.Nimeh@Sun.Com 	IVM_NONE,	/* no iv needed, iv is null */
1248313SDina.Nimeh@Sun.Com 	IVM_ENC_BLKNO	/* iv is logical block no. encrypted */
1258313SDina.Nimeh@Sun.Com } iv_method_t;
1268313SDina.Nimeh@Sun.Com 
1270Sstevel@tonic-gate struct lofi_ioctl {
1284451Seschrock 	uint32_t 	li_minor;
1294451Seschrock 	boolean_t	li_force;
1306734Sjohnlev 	boolean_t	li_cleanup;
1318081SDina.Nimeh@Sun.Com 	char	li_filename[MAXPATHLEN];
1328313SDina.Nimeh@Sun.Com 
1338313SDina.Nimeh@Sun.Com 	/* the following fields are required for compression support */
1345643Saalok 	char	li_algorithm[MAXALGLEN];
1358313SDina.Nimeh@Sun.Com 
1368313SDina.Nimeh@Sun.Com 	/* the following fields are required for encryption support */
1378313SDina.Nimeh@Sun.Com 	boolean_t	li_crypto_enabled;
1388313SDina.Nimeh@Sun.Com 	crypto_mech_name_t	li_cipher;	/* for data */
1398313SDina.Nimeh@Sun.Com 	uint32_t	li_key_len;		/* for data */
1408313SDina.Nimeh@Sun.Com 	char		li_key[56];	/* for data: max 448-bit Blowfish key */
1418313SDina.Nimeh@Sun.Com 	crypto_mech_name_t	li_iv_cipher;	/* for iv derivation */
1428313SDina.Nimeh@Sun.Com 	uint32_t	li_iv_len;		/* for iv derivation */
1438313SDina.Nimeh@Sun.Com 	iv_method_t	li_iv_type;		/* for iv derivation */
1440Sstevel@tonic-gate };
1450Sstevel@tonic-gate 
1460Sstevel@tonic-gate #define	LOFI_IOC_BASE		(('L' << 16) | ('F' << 8))
1470Sstevel@tonic-gate 
1480Sstevel@tonic-gate #define	LOFI_MAP_FILE		(LOFI_IOC_BASE | 0x01)
1490Sstevel@tonic-gate #define	LOFI_MAP_FILE_MINOR	(LOFI_IOC_BASE | 0x02)
1500Sstevel@tonic-gate #define	LOFI_UNMAP_FILE		(LOFI_IOC_BASE | 0x03)
1510Sstevel@tonic-gate #define	LOFI_UNMAP_FILE_MINOR	(LOFI_IOC_BASE | 0x04)
1520Sstevel@tonic-gate #define	LOFI_GET_FILENAME	(LOFI_IOC_BASE | 0x05)
1530Sstevel@tonic-gate #define	LOFI_GET_MINOR		(LOFI_IOC_BASE | 0x06)
1540Sstevel@tonic-gate #define	LOFI_GET_MAXMINOR	(LOFI_IOC_BASE | 0x07)
1555643Saalok #define	LOFI_CHECK_COMPRESSED	(LOFI_IOC_BASE | 0x08)
1560Sstevel@tonic-gate 
1570Sstevel@tonic-gate /*
1580Sstevel@tonic-gate  * file types that might be usable with lofi, maybe. Only regular
1590Sstevel@tonic-gate  * files are documented though.
1600Sstevel@tonic-gate  */
1610Sstevel@tonic-gate #define	S_ISLOFIABLE(mode) \
1620Sstevel@tonic-gate 	(S_ISREG(mode) || S_ISBLK(mode) || S_ISCHR(mode))
1630Sstevel@tonic-gate 
1640Sstevel@tonic-gate #if defined(_KERNEL)
1650Sstevel@tonic-gate 
1669048Sjrgn.keil@googlemail.com 
1679048Sjrgn.keil@googlemail.com /*
1689048Sjrgn.keil@googlemail.com  * Cache decompressed data segments for the compressed lofi images.
1699048Sjrgn.keil@googlemail.com  *
1709048Sjrgn.keil@googlemail.com  * To avoid that we have to decompress data of a compressed
1719048Sjrgn.keil@googlemail.com  * segment multiple times when accessing parts of the segment's
1729048Sjrgn.keil@googlemail.com  * data we cache the uncompressed data, using a simple linked list.
1739048Sjrgn.keil@googlemail.com  */
1749048Sjrgn.keil@googlemail.com struct lofi_comp_cache {
1759048Sjrgn.keil@googlemail.com 	list_node_t	lc_list;		/* linked list */
1769048Sjrgn.keil@googlemail.com 	uchar_t		*lc_data;		/* decompressed segment data */
1779048Sjrgn.keil@googlemail.com 	uint64_t	lc_index;		/* segment index */
1789048Sjrgn.keil@googlemail.com };
1799048Sjrgn.keil@googlemail.com 
1800Sstevel@tonic-gate #define	V_ISLOFIABLE(vtype) \
1810Sstevel@tonic-gate 	((vtype == VREG) || (vtype == VBLK) || (vtype == VCHR))
1820Sstevel@tonic-gate 
1838313SDina.Nimeh@Sun.Com /*
18412384Salok.aggarwal@oracle.com  * Pre-allocated memory buffers for the purpose of compression
18512384Salok.aggarwal@oracle.com  */
18612384Salok.aggarwal@oracle.com struct compbuf {
18712384Salok.aggarwal@oracle.com 	void		*buf;
18812384Salok.aggarwal@oracle.com 	uint32_t	bufsize;
18912384Salok.aggarwal@oracle.com 	int		inuse;
19012384Salok.aggarwal@oracle.com };
19112384Salok.aggarwal@oracle.com 
19212384Salok.aggarwal@oracle.com /*
1938313SDina.Nimeh@Sun.Com  * Need exactly 6 bytes to identify encrypted lofi image
1948313SDina.Nimeh@Sun.Com  */
1958313SDina.Nimeh@Sun.Com extern const char lofi_crypto_magic[6];
1968313SDina.Nimeh@Sun.Com #define	LOFI_CRYPTO_MAGIC	{ 'C', 'F', 'L', 'O', 'F', 'I' }
1978313SDina.Nimeh@Sun.Com #define	LOFI_CRYPTO_VERSION	((uint16_t)0)
1988313SDina.Nimeh@Sun.Com #define	LOFI_CRYPTO_DATA_SECTOR	((uint32_t)16)		/* for version 0 */
1998313SDina.Nimeh@Sun.Com 
2008313SDina.Nimeh@Sun.Com /*
2018313SDina.Nimeh@Sun.Com  * Crypto metadata for encrypted lofi images
2028313SDina.Nimeh@Sun.Com  * The fields here only satisfy initial implementation requirements.
2038313SDina.Nimeh@Sun.Com  */
2048313SDina.Nimeh@Sun.Com struct crypto_meta {
2058313SDina.Nimeh@Sun.Com 	char		magic[6];		/* LOFI_CRYPTO_MAGIC */
2068313SDina.Nimeh@Sun.Com 	uint16_t	version;		/* version of encrypted lofi */
2078313SDina.Nimeh@Sun.Com 	char		reserved1[96];		/* future use */
2088313SDina.Nimeh@Sun.Com 	uint32_t	data_sector;		/* start of data area */
2098313SDina.Nimeh@Sun.Com 	char		pad[404];		/* end on DEV_BSIZE bdry */
2108313SDina.Nimeh@Sun.Com 	/* second header block is not defined at this time */
2118313SDina.Nimeh@Sun.Com };
2128313SDina.Nimeh@Sun.Com 
2130Sstevel@tonic-gate struct lofi_state {
21412633Sjohn.levon@sun.com 	vnode_t		*ls_vp;		/* open real vnode */
21512633Sjohn.levon@sun.com 	vnode_t		*ls_stacked_vp;	/* open vnode */
2164451Seschrock 	kmutex_t	ls_vp_lock;	/* protects ls_vp */
2174451Seschrock 	kcondvar_t	ls_vp_cv;	/* signal changes to ls_vp */
2184451Seschrock 	uint32_t	ls_vp_iocount;	/* # pending I/O requests */
2194451Seschrock 	boolean_t	ls_vp_closereq;	/* force close requested */
2200Sstevel@tonic-gate 	u_offset_t	ls_vp_size;
2210Sstevel@tonic-gate 	uint32_t	ls_blk_open;
2220Sstevel@tonic-gate 	uint32_t	ls_chr_open;
2230Sstevel@tonic-gate 	uint32_t	ls_lyr_open_count;
2240Sstevel@tonic-gate 	int		ls_openflag;
2256734Sjohnlev 	boolean_t	ls_cleanup;	/* cleanup on close */
2260Sstevel@tonic-gate 	taskq_t		*ls_taskq;
2270Sstevel@tonic-gate 	kstat_t		*ls_kstat;
2280Sstevel@tonic-gate 	kmutex_t	ls_kstat_lock;
2290Sstevel@tonic-gate 	struct dk_geom	ls_dkg;
2300Sstevel@tonic-gate 	struct vtoc	ls_vtoc;
2310Sstevel@tonic-gate 	struct dk_cinfo	ls_ci;
232*13096SJordan.Vaughan@Sun.com 	zone_ref_t	ls_zone;
23312633Sjohn.levon@sun.com 	list_node_t	ls_list;	/* all lofis */
23412633Sjohn.levon@sun.com 	dev_t		ls_dev;		/* this node's dev_t */
2355643Saalok 
2365643Saalok 	/* the following fields are required for compression support */
2375643Saalok 	int		ls_comp_algorithm_index; /* idx into compress_table */
2385643Saalok 	char		ls_comp_algorithm[MAXALGLEN];
2395643Saalok 	uint32_t	ls_uncomp_seg_sz; /* sz of uncompressed segment */
2405643Saalok 	uint32_t	ls_comp_index_sz; /* number of index entries */
2415643Saalok 	uint32_t	ls_comp_seg_shift; /* exponent for byte shift */
2425643Saalok 	uint32_t	ls_uncomp_last_seg_sz; /* sz of last uncomp segment */
2435643Saalok 	uint64_t	ls_comp_offbase; /* offset of actual compressed data */
2445643Saalok 	uint64_t	*ls_comp_seg_index; /* array of index entries */
2455643Saalok 	caddr_t		ls_comp_index_data; /* index pages loaded from file */
2465643Saalok 	uint32_t	ls_comp_index_data_sz;
2475643Saalok 	u_offset_t	ls_vp_comp_size; /* actual compressed file size */
2488313SDina.Nimeh@Sun.Com 
24912384Salok.aggarwal@oracle.com 	/* pre-allocated list of buffers for compressed segment data */
25012384Salok.aggarwal@oracle.com 	kmutex_t	ls_comp_bufs_lock;
25112384Salok.aggarwal@oracle.com 	struct compbuf	*ls_comp_bufs;
25212384Salok.aggarwal@oracle.com 
2539048Sjrgn.keil@googlemail.com 	/* lock and anchor for compressed segment caching */
2549048Sjrgn.keil@googlemail.com 	kmutex_t	ls_comp_cache_lock;	/* protects ls_comp_cache */
2559048Sjrgn.keil@googlemail.com 	list_t		ls_comp_cache;		/* cached decompressed segs */
2569048Sjrgn.keil@googlemail.com 	uint32_t	ls_comp_cache_count;
2579048Sjrgn.keil@googlemail.com 
2588313SDina.Nimeh@Sun.Com 	/* the following fields are required for encryption support */
2598313SDina.Nimeh@Sun.Com 	boolean_t		ls_crypto_enabled;
2608313SDina.Nimeh@Sun.Com 	u_offset_t		ls_crypto_offset;	/* crypto meta size */
2618313SDina.Nimeh@Sun.Com 	struct crypto_meta	ls_crypto;
2628313SDina.Nimeh@Sun.Com 	crypto_mechanism_t	ls_mech;	/* for data encr/decr */
2638313SDina.Nimeh@Sun.Com 	crypto_key_t		ls_key;		/* for data encr/decr */
2648313SDina.Nimeh@Sun.Com 	crypto_mechanism_t	ls_iv_mech;	/* for iv derivation */
2658313SDina.Nimeh@Sun.Com 	size_t			ls_iv_len;	/* for iv derivation */
2668313SDina.Nimeh@Sun.Com 	iv_method_t		ls_iv_type;	/* for iv derivation */
2678313SDina.Nimeh@Sun.Com 	kmutex_t		ls_crypto_lock;
2688313SDina.Nimeh@Sun.Com 	crypto_ctx_template_t	ls_ctx_tmpl;
2698313SDina.Nimeh@Sun.Com 
2700Sstevel@tonic-gate };
2710Sstevel@tonic-gate 
2725643Saalok #endif	/* _KERNEL */
2735643Saalok 
2745643Saalok /*
2755643Saalok  * Common signature for all lofi compress functions
2765643Saalok  */
2775643Saalok typedef int lofi_compress_func_t(void *src, size_t srclen, void *dst,
2785643Saalok 	size_t *destlen, int level);
2795643Saalok 
2805643Saalok /*
2815643Saalok  * Information about each compression function
2825643Saalok  */
2835643Saalok typedef struct lofi_compress_info {
2845643Saalok 	lofi_compress_func_t	*l_decompress;
2855643Saalok 	lofi_compress_func_t	*l_compress;
2865643Saalok 	int			l_level;
2875643Saalok 	char			*l_name;	/* algorithm name */
2885643Saalok } lofi_compress_info_t;
2895643Saalok 
2905643Saalok enum lofi_compress {
2915643Saalok 	LOFI_COMPRESS_GZIP = 0,
2925643Saalok 	LOFI_COMPRESS_GZIP_6 = 1,
2935643Saalok 	LOFI_COMPRESS_GZIP_9 = 2,
2948996SAlok.Aggarwal@Sun.COM 	LOFI_COMPRESS_LZMA = 3,
2955643Saalok 	LOFI_COMPRESS_FUNCTIONS
2965643Saalok };
2970Sstevel@tonic-gate 
2980Sstevel@tonic-gate #ifdef	__cplusplus
2990Sstevel@tonic-gate }
3000Sstevel@tonic-gate #endif
3010Sstevel@tonic-gate 
3020Sstevel@tonic-gate #endif	/* _SYS_LOFI_H */
303