xref: /onnv-gate/usr/src/uts/common/sys/lofi.h (revision 8996:a09bdbccfe1d)
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 /*
22*8996SAlok.Aggarwal@Sun.COM  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
230Sstevel@tonic-gate  * Use is subject to license terms.
240Sstevel@tonic-gate  */
250Sstevel@tonic-gate 
260Sstevel@tonic-gate 
270Sstevel@tonic-gate #ifndef	_SYS_LOFI_H
280Sstevel@tonic-gate #define	_SYS_LOFI_H
290Sstevel@tonic-gate 
300Sstevel@tonic-gate #include <sys/types.h>
310Sstevel@tonic-gate #include <sys/time.h>
320Sstevel@tonic-gate #include <sys/taskq.h>
330Sstevel@tonic-gate #include <sys/vtoc.h>
340Sstevel@tonic-gate #include <sys/dkio.h>
350Sstevel@tonic-gate #include <sys/vnode.h>
368313SDina.Nimeh@Sun.Com #include <sys/crypto/api.h>
370Sstevel@tonic-gate 
380Sstevel@tonic-gate #ifdef	__cplusplus
390Sstevel@tonic-gate extern "C" {
400Sstevel@tonic-gate #endif
410Sstevel@tonic-gate 
420Sstevel@tonic-gate /*
430Sstevel@tonic-gate  * /dev names:
440Sstevel@tonic-gate  *	/dev/lofictl	- master control device
450Sstevel@tonic-gate  *	/dev/lofi	- block devices, named by minor number
460Sstevel@tonic-gate  *	/dev/rlofi	- character devices, named by minor number
470Sstevel@tonic-gate  */
480Sstevel@tonic-gate #define	LOFI_DRIVER_NAME	"lofi"
490Sstevel@tonic-gate #define	LOFI_CTL_NODE		"ctl"
500Sstevel@tonic-gate #define	LOFI_CTL_NAME		LOFI_DRIVER_NAME LOFI_CTL_NODE
510Sstevel@tonic-gate #define	LOFI_BLOCK_NAME		LOFI_DRIVER_NAME
520Sstevel@tonic-gate #define	LOFI_CHAR_NAME		"r" LOFI_DRIVER_NAME
530Sstevel@tonic-gate 
545643Saalok #define	SEGHDR		1
555643Saalok #define	COMPRESSED	1
565643Saalok #define	UNCOMPRESSED	0
575643Saalok #define	MAXALGLEN	36
585643Saalok 
590Sstevel@tonic-gate /*
600Sstevel@tonic-gate  *
610Sstevel@tonic-gate  * Use is:
620Sstevel@tonic-gate  *	ld = open("/dev/lofictl", O_RDWR | O_EXCL);
630Sstevel@tonic-gate  *
640Sstevel@tonic-gate  * lofi must be opened exclusively. Access is controlled by permissions on
650Sstevel@tonic-gate  * the device, which is 644 by default. Write-access is required for ioctls
660Sstevel@tonic-gate  * that change state, but only read-access is required for the ioctls that
670Sstevel@tonic-gate  * return information. Basically, only root can add and remove files, but
680Sstevel@tonic-gate  * non-root can look at the current lists.
690Sstevel@tonic-gate  *
700Sstevel@tonic-gate  * ioctl usage:
710Sstevel@tonic-gate  *
720Sstevel@tonic-gate  * kernel ioctls
730Sstevel@tonic-gate  *
740Sstevel@tonic-gate  *	strcpy(li.li_filename, "somefilename");
750Sstevel@tonic-gate  *	ioctl(ld, LOFI_MAP_FILE, &li);
760Sstevel@tonic-gate  *	newminor = li.li_minor;
770Sstevel@tonic-gate  *
780Sstevel@tonic-gate  *	strcpy(li.li_filename, "somefilename");
790Sstevel@tonic-gate  *	ioctl(ld, LOFI_UNMAP_FILE, &li);
800Sstevel@tonic-gate  *
810Sstevel@tonic-gate  *	strcpy(li.li_filename, "somefilename");
820Sstevel@tonic-gate  *	li.li_minor = minor_number;
830Sstevel@tonic-gate  *	ioctl(ld, LOFI_MAP_FILE_MINOR, &li);
840Sstevel@tonic-gate  *
850Sstevel@tonic-gate  *	li.li_minor = minor_number;
860Sstevel@tonic-gate  *	ioctl(ld, LOFI_UNMAP_FILE_MINOR, &li);
870Sstevel@tonic-gate  *
880Sstevel@tonic-gate  *	li.li_minor = minor_number;
890Sstevel@tonic-gate  *	ioctl(ld, LOFI_GET_FILENAME, &li);
908313SDina.Nimeh@Sun.Com  *	filename = li.li_filename;
918313SDina.Nimeh@Sun.Com  *	encrypted = li.li_crypto_enabled;
920Sstevel@tonic-gate  *
930Sstevel@tonic-gate  *	strcpy(li.li_filename, "somefilename");
940Sstevel@tonic-gate  *	ioctl(ld, LOFI_GET_MINOR, &li);
958313SDina.Nimeh@Sun.Com  *	minor = li.li_minor;
960Sstevel@tonic-gate  *
970Sstevel@tonic-gate  *	li.li_minor = 0;
980Sstevel@tonic-gate  *	ioctl(ld, LOFI_GET_MAXMINOR, &li);
990Sstevel@tonic-gate  *	maxminor = li.li_minor;
1000Sstevel@tonic-gate  *
1015643Saalok  *	strcpy(li.li_filename, "somefilename");
1025643Saalok  *	li.li_minor = 0;
1035643Saalok  *	ioctl(ld, LOFI_CHECK_COMPRESSED, &li);
1045643Saalok  *
1054451Seschrock  * If the 'li_force' flag is set for any of the LOFI_UNMAP_* commands, then if
1064451Seschrock  * the device is busy, the underlying vnode will be closed, and any subsequent
1074451Seschrock  * operations will fail.  It will behave as if the device had been forcibly
1084451Seschrock  * removed, so the DKIOCSTATE ioctl will return DKIO_DEV_GONE.  When the device
1094451Seschrock  * is last closed, it will be torn down.
1104451Seschrock  *
1116734Sjohnlev  * If the 'li_cleanup' flag is set for any of the LOFI_UNMAP_* commands, then
1126734Sjohnlev  * if the device is busy, it is marked for removal at the next time it is
1136734Sjohnlev  * no longer held open by anybody.  When the device is last closed, it will be
1146734Sjohnlev  * torn down.
1156734Sjohnlev  *
1160Sstevel@tonic-gate  * Oh, and last but not least: these ioctls are totally private and only
1170Sstevel@tonic-gate  * for use by lofiadm(1M).
1180Sstevel@tonic-gate  *
1190Sstevel@tonic-gate  */
1200Sstevel@tonic-gate 
1218313SDina.Nimeh@Sun.Com typedef enum	iv_method {
1228313SDina.Nimeh@Sun.Com 	IVM_NONE,	/* no iv needed, iv is null */
1238313SDina.Nimeh@Sun.Com 	IVM_ENC_BLKNO	/* iv is logical block no. encrypted */
1248313SDina.Nimeh@Sun.Com } iv_method_t;
1258313SDina.Nimeh@Sun.Com 
1260Sstevel@tonic-gate struct lofi_ioctl {
1274451Seschrock 	uint32_t 	li_minor;
1284451Seschrock 	boolean_t	li_force;
1296734Sjohnlev 	boolean_t	li_cleanup;
1308081SDina.Nimeh@Sun.Com 	char	li_filename[MAXPATHLEN];
1318313SDina.Nimeh@Sun.Com 
1328313SDina.Nimeh@Sun.Com 	/* the following fields are required for compression support */
1335643Saalok 	char	li_algorithm[MAXALGLEN];
1348313SDina.Nimeh@Sun.Com 
1358313SDina.Nimeh@Sun.Com 	/* the following fields are required for encryption support */
1368313SDina.Nimeh@Sun.Com 	boolean_t	li_crypto_enabled;
1378313SDina.Nimeh@Sun.Com 	crypto_mech_name_t	li_cipher;	/* for data */
1388313SDina.Nimeh@Sun.Com 	uint32_t	li_key_len;		/* for data */
1398313SDina.Nimeh@Sun.Com 	char		li_key[56];	/* for data: max 448-bit Blowfish key */
1408313SDina.Nimeh@Sun.Com 	crypto_mech_name_t	li_iv_cipher;	/* for iv derivation */
1418313SDina.Nimeh@Sun.Com 	uint32_t	li_iv_len;		/* for iv derivation */
1428313SDina.Nimeh@Sun.Com 	iv_method_t	li_iv_type;		/* for iv derivation */
1430Sstevel@tonic-gate };
1440Sstevel@tonic-gate 
1450Sstevel@tonic-gate #define	LOFI_IOC_BASE		(('L' << 16) | ('F' << 8))
1460Sstevel@tonic-gate 
1470Sstevel@tonic-gate #define	LOFI_MAP_FILE		(LOFI_IOC_BASE | 0x01)
1480Sstevel@tonic-gate #define	LOFI_MAP_FILE_MINOR	(LOFI_IOC_BASE | 0x02)
1490Sstevel@tonic-gate #define	LOFI_UNMAP_FILE		(LOFI_IOC_BASE | 0x03)
1500Sstevel@tonic-gate #define	LOFI_UNMAP_FILE_MINOR	(LOFI_IOC_BASE | 0x04)
1510Sstevel@tonic-gate #define	LOFI_GET_FILENAME	(LOFI_IOC_BASE | 0x05)
1520Sstevel@tonic-gate #define	LOFI_GET_MINOR		(LOFI_IOC_BASE | 0x06)
1530Sstevel@tonic-gate #define	LOFI_GET_MAXMINOR	(LOFI_IOC_BASE | 0x07)
1545643Saalok #define	LOFI_CHECK_COMPRESSED	(LOFI_IOC_BASE | 0x08)
1550Sstevel@tonic-gate 
1560Sstevel@tonic-gate /*
1570Sstevel@tonic-gate  * file types that might be usable with lofi, maybe. Only regular
1580Sstevel@tonic-gate  * files are documented though.
1590Sstevel@tonic-gate  */
1600Sstevel@tonic-gate #define	S_ISLOFIABLE(mode) \
1610Sstevel@tonic-gate 	(S_ISREG(mode) || S_ISBLK(mode) || S_ISCHR(mode))
1620Sstevel@tonic-gate 
1630Sstevel@tonic-gate #if defined(_KERNEL)
1640Sstevel@tonic-gate 
1650Sstevel@tonic-gate /*
1660Sstevel@tonic-gate  * We limit the maximum number of active lofi devices to 128, which seems very
1670Sstevel@tonic-gate  * large. You can tune this by changing lofi_max_files in /etc/system.
1680Sstevel@tonic-gate  * If you change it dynamically, which you probably shouldn't do, make sure
1690Sstevel@tonic-gate  * to only _increase_ it.
1700Sstevel@tonic-gate  */
1710Sstevel@tonic-gate #define	LOFI_MAX_FILES	128
1720Sstevel@tonic-gate extern uint32_t lofi_max_files;
1730Sstevel@tonic-gate 
1740Sstevel@tonic-gate #define	V_ISLOFIABLE(vtype) \
1750Sstevel@tonic-gate 	((vtype == VREG) || (vtype == VBLK) || (vtype == VCHR))
1760Sstevel@tonic-gate 
1778313SDina.Nimeh@Sun.Com /*
1788313SDina.Nimeh@Sun.Com  * Need exactly 6 bytes to identify encrypted lofi image
1798313SDina.Nimeh@Sun.Com  */
1808313SDina.Nimeh@Sun.Com extern const char lofi_crypto_magic[6];
1818313SDina.Nimeh@Sun.Com #define	LOFI_CRYPTO_MAGIC	{ 'C', 'F', 'L', 'O', 'F', 'I' }
1828313SDina.Nimeh@Sun.Com #define	LOFI_CRYPTO_VERSION	((uint16_t)0)
1838313SDina.Nimeh@Sun.Com #define	LOFI_CRYPTO_DATA_SECTOR	((uint32_t)16)		/* for version 0 */
1848313SDina.Nimeh@Sun.Com 
1858313SDina.Nimeh@Sun.Com /*
1868313SDina.Nimeh@Sun.Com  * Crypto metadata for encrypted lofi images
1878313SDina.Nimeh@Sun.Com  * The fields here only satisfy initial implementation requirements.
1888313SDina.Nimeh@Sun.Com  */
1898313SDina.Nimeh@Sun.Com struct crypto_meta {
1908313SDina.Nimeh@Sun.Com 	char		magic[6];		/* LOFI_CRYPTO_MAGIC */
1918313SDina.Nimeh@Sun.Com 	uint16_t	version;		/* version of encrypted lofi */
1928313SDina.Nimeh@Sun.Com 	char		reserved1[96];		/* future use */
1938313SDina.Nimeh@Sun.Com 	uint32_t	data_sector;		/* start of data area */
1948313SDina.Nimeh@Sun.Com 	char		pad[404];		/* end on DEV_BSIZE bdry */
1958313SDina.Nimeh@Sun.Com 	/* second header block is not defined at this time */
1968313SDina.Nimeh@Sun.Com };
1978313SDina.Nimeh@Sun.Com 
1980Sstevel@tonic-gate struct lofi_state {
1994451Seschrock 	char		*ls_filename;	/* filename to open */
2004451Seschrock 	size_t		ls_filename_sz;
2014451Seschrock 	struct vnode	*ls_vp;		/* open vnode */
2024451Seschrock 	kmutex_t	ls_vp_lock;	/* protects ls_vp */
2034451Seschrock 	kcondvar_t	ls_vp_cv;	/* signal changes to ls_vp */
2044451Seschrock 	uint32_t	ls_vp_iocount;	/* # pending I/O requests */
2054451Seschrock 	boolean_t	ls_vp_closereq;	/* force close requested */
2060Sstevel@tonic-gate 	u_offset_t	ls_vp_size;
2070Sstevel@tonic-gate 	uint32_t	ls_blk_open;
2080Sstevel@tonic-gate 	uint32_t	ls_chr_open;
2090Sstevel@tonic-gate 	uint32_t	ls_lyr_open_count;
2100Sstevel@tonic-gate 	int		ls_openflag;
2116734Sjohnlev 	boolean_t	ls_cleanup;	/* cleanup on close */
2120Sstevel@tonic-gate 	taskq_t		*ls_taskq;
2130Sstevel@tonic-gate 	kstat_t		*ls_kstat;
2140Sstevel@tonic-gate 	kmutex_t	ls_kstat_lock;
2150Sstevel@tonic-gate 	struct dk_geom	ls_dkg;
2160Sstevel@tonic-gate 	struct vtoc	ls_vtoc;
2170Sstevel@tonic-gate 	struct dk_cinfo	ls_ci;
2185643Saalok 
2195643Saalok 	/* the following fields are required for compression support */
2205643Saalok 	int		ls_comp_algorithm_index; /* idx into compress_table */
2215643Saalok 	char		ls_comp_algorithm[MAXALGLEN];
2225643Saalok 	uint32_t	ls_uncomp_seg_sz; /* sz of uncompressed segment */
2235643Saalok 	uint32_t	ls_comp_index_sz; /* number of index entries */
2245643Saalok 	uint32_t	ls_comp_seg_shift; /* exponent for byte shift */
2255643Saalok 	uint32_t	ls_uncomp_last_seg_sz; /* sz of last uncomp segment */
2265643Saalok 	uint64_t	ls_comp_offbase; /* offset of actual compressed data */
2275643Saalok 	uint64_t	*ls_comp_seg_index; /* array of index entries */
2285643Saalok 	caddr_t		ls_comp_index_data; /* index pages loaded from file */
2295643Saalok 	uint32_t	ls_comp_index_data_sz;
2305643Saalok 	u_offset_t	ls_vp_comp_size; /* actual compressed file size */
2318313SDina.Nimeh@Sun.Com 
2328313SDina.Nimeh@Sun.Com 	/* the following fields are required for encryption support */
2338313SDina.Nimeh@Sun.Com 	boolean_t		ls_crypto_enabled;
2348313SDina.Nimeh@Sun.Com 	u_offset_t		ls_crypto_offset;	/* crypto meta size */
2358313SDina.Nimeh@Sun.Com 	struct crypto_meta	ls_crypto;
2368313SDina.Nimeh@Sun.Com 	crypto_mechanism_t	ls_mech;	/* for data encr/decr */
2378313SDina.Nimeh@Sun.Com 	crypto_key_t		ls_key;		/* for data encr/decr */
2388313SDina.Nimeh@Sun.Com 	crypto_mechanism_t	ls_iv_mech;	/* for iv derivation */
2398313SDina.Nimeh@Sun.Com 	size_t			ls_iv_len;	/* for iv derivation */
2408313SDina.Nimeh@Sun.Com 	iv_method_t		ls_iv_type;	/* for iv derivation */
2418313SDina.Nimeh@Sun.Com 	kmutex_t		ls_crypto_lock;
2428313SDina.Nimeh@Sun.Com 	crypto_ctx_template_t	ls_ctx_tmpl;
2438313SDina.Nimeh@Sun.Com 
2440Sstevel@tonic-gate };
2450Sstevel@tonic-gate 
2465643Saalok #endif	/* _KERNEL */
2475643Saalok 
2485643Saalok /*
2495643Saalok  * Common signature for all lofi compress functions
2505643Saalok  */
2515643Saalok typedef int lofi_compress_func_t(void *src, size_t srclen, void *dst,
2525643Saalok 	size_t *destlen, int level);
2535643Saalok 
2545643Saalok /*
2555643Saalok  * Information about each compression function
2565643Saalok  */
2575643Saalok typedef struct lofi_compress_info {
2585643Saalok 	lofi_compress_func_t	*l_decompress;
2595643Saalok 	lofi_compress_func_t	*l_compress;
2605643Saalok 	int			l_level;
2615643Saalok 	char			*l_name;	/* algorithm name */
2625643Saalok } lofi_compress_info_t;
2635643Saalok 
2645643Saalok enum lofi_compress {
2655643Saalok 	LOFI_COMPRESS_GZIP = 0,
2665643Saalok 	LOFI_COMPRESS_GZIP_6 = 1,
2675643Saalok 	LOFI_COMPRESS_GZIP_9 = 2,
268*8996SAlok.Aggarwal@Sun.COM 	LOFI_COMPRESS_LZMA = 3,
2695643Saalok 	LOFI_COMPRESS_FUNCTIONS
2705643Saalok };
2710Sstevel@tonic-gate 
2720Sstevel@tonic-gate #ifdef	__cplusplus
2730Sstevel@tonic-gate }
2740Sstevel@tonic-gate #endif
2750Sstevel@tonic-gate 
2760Sstevel@tonic-gate #endif	/* _SYS_LOFI_H */
277