Home | History | Annotate | Download | only in fiocompress
      1  5648       setje /*
      2  5648       setje  * CDDL HEADER START
      3  5648       setje  *
      4  5648       setje  * The contents of this file are subject to the terms of the
      5  5648       setje  * Common Development and Distribution License (the "License").
      6  5648       setje  * You may not use this file except in compliance with the License.
      7  5648       setje  *
      8  5648       setje  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
      9  5648       setje  * or http://www.opensolaris.org/os/licensing.
     10  5648       setje  * See the License for the specific language governing permissions
     11  5648       setje  * and limitations under the License.
     12  5648       setje  *
     13  5648       setje  * When distributing Covered Code, include this CDDL HEADER in each
     14  5648       setje  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
     15  5648       setje  * If applicable, add the following below this CDDL HEADER, with the
     16  5648       setje  * fields enclosed by brackets "[]" replaced with your own identifying
     17  5648       setje  * information: Portions Copyright [yyyy] [name of copyright owner]
     18  5648       setje  *
     19  5648       setje  * CDDL HEADER END
     20  5648       setje  */
     21  5648       setje /*
     22  7858  Krishnendu  * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
     23  5648       setje  * Use is subject to license terms.
     24  5648       setje  */
     25  5648       setje 
     26  5648       setje /*
     27  5648       setje  * fiocompress - a utility to compress files with a filesystem.
     28  5648       setje  * Used to build compressed boot archives to reduce memory
     29  5648       setje  * requirements for booting.
     30  5648       setje  */
     31  5648       setje 
     32  5648       setje #include <stdio.h>
     33  5648       setje #include <errno.h>
     34  5648       setje #include <stdlib.h>
     35  5648       setje #include <fcntl.h>
     36  5648       setje #include <sys/types.h>
     37  5648       setje #include <sys/stat.h>
     38  5648       setje #include <sys/mman.h>
     39  5648       setje #include <unistd.h>
     40  5648       setje #include <utility.h>
     41  5648       setje #include <zlib.h>
     42  5648       setje 
     43  5648       setje #include <sys/filio.h>
     44  5648       setje #include <sys/fs/decomp.h>
     45  5648       setje 
     46  5648       setje #include "message.h"
     47  5648       setje 
     48  5648       setje static void	setup_infile(char *);
     49  5648       setje static void	setup_outfile(char *);
     50  5648       setje static void	do_comp(size_t);
     51  5648       setje static void	do_decomp(void);
     52  5648       setje 
     53  5648       setje static caddr_t	srcaddr;
     54  5648       setje static size_t	srclen;
     55  5648       setje 
     56  5648       setje static int	dstfd;
     57  5648       setje 
     58  5648       setje static char	*srcfile;
     59  5648       setje static char	*dstfile;
     60  5648       setje 
     61  5648       setje 
     62  5648       setje int
     63  5648       setje main(int argc, char **argv)
     64  5648       setje {
     65  5648       setje 	int compress = 0;
     66  5648       setje 	int decompress = 0;
     67  5648       setje 	int doioc = 0;
     68  5648       setje 	size_t	blksize = 8192;
     69  5648       setje 	char c;
     70  5648       setje 
     71  5648       setje 	while ((c = getopt(argc, argv, "mcdb:")) != -1) {
     72  5648       setje 		switch (c) {
     73  5648       setje 		case 'm':
     74  5648       setje 			doioc++;
     75  5648       setje 			break;
     76  5648       setje 		case 'c':
     77  5648       setje 			if (decompress) {
     78  5648       setje 				(void) fprintf(stderr, OPT_DC_EXCL);
     79  5648       setje 				exit(-1);
     80  5648       setje 			}
     81  5648       setje 			compress = 1;
     82  5648       setje 			break;
     83  5648       setje 		case 'd':
     84  5648       setje 			if (compress) {
     85  5648       setje 				(void) fprintf(stderr, OPT_DC_EXCL);
     86  5648       setje 				exit(-1);
     87  5648       setje 			}
     88  5648       setje 			decompress = 1;
     89  5648       setje 			break;
     90  5648       setje 		case 'b':
     91  5648       setje 			blksize = atoi(optarg);
     92  5648       setje 			if (blksize == 0 || (blksize & (blksize-1))) {
     93  5648       setje 				(void) fprintf(stderr, INVALID_BLKSZ);
     94  5648       setje 				exit(-1);
     95  5648       setje 			}
     96  5648       setje 			break;
     97  5648       setje 		case '?':
     98  5648       setje 			(void) fprintf(stderr, UNKNOWN_OPTION, optopt);
     99  5648       setje 			exit(-1);
    100  5648       setje 		}
    101  5648       setje 	}
    102  5648       setje 	if (argc - optind != 2) {
    103  5648       setje 		(void) fprintf(stderr, MISS_FILES);
    104  5648       setje 		exit(-1);
    105  5648       setje 	}
    106  5648       setje 
    107  5648       setje 	setup_infile(argv[optind]);
    108  5648       setje 	setup_outfile(argv[optind + 1]);
    109  5648       setje 
    110  5648       setje 	if (decompress)
    111  5648       setje 		do_decomp();
    112  5648       setje 	else {
    113  5648       setje 		do_comp(blksize);
    114  5648       setje 		if (doioc) {
    115  5648       setje 			if (ioctl(dstfd, _FIO_COMPRESSED, 0) == -1) {
    116  5648       setje 				(void) fprintf(stderr, FIO_COMP_FAIL,
    117  5648       setje 				    dstfile, strerror(errno));
    118  5648       setje 				exit(-1);
    119  5648       setje 			}
    120  5648       setje 		}
    121  5648       setje 	}
    122  5648       setje 	return (0);
    123  5648       setje }
    124  5648       setje 
    125  5648       setje static void
    126  5648       setje setup_infile(char *file)
    127  5648       setje {
    128  5648       setje 	int fd;
    129  5648       setje 	void *addr;
    130  5648       setje 	struct stat stbuf;
    131  5648       setje 
    132  5648       setje 	srcfile = file;
    133  5648       setje 
    134  5648       setje 	fd = open(srcfile, O_RDONLY, 0);
    135  5648       setje 	if (fd == -1) {
    136  5648       setje 		(void) fprintf(stderr, CANT_OPEN,
    137  5648       setje 		    srcfile, strerror(errno));
    138  5648       setje 		exit(-1);
    139  5648       setje 	}
    140  5648       setje 
    141  5648       setje 	if (fstat(fd, &stbuf) == -1) {
    142  5648       setje 		(void) fprintf(stderr, STAT_FAIL,
    143  5648       setje 		    srcfile, strerror(errno));
    144  5648       setje 		exit(-1);
    145  5648       setje 	}
    146  5648       setje 	srclen = stbuf.st_size;
    147  5648       setje 
    148  5648       setje 	addr = mmap(0, srclen, PROT_READ, MAP_SHARED, fd, 0);
    149  5648       setje 	if (addr == MAP_FAILED) {
    150  5648       setje 		(void) fprintf(stderr, MMAP_FAIL, srcfile, strerror(errno));
    151  5648       setje 		exit(-1);
    152  5648       setje 	}
    153  5648       setje 	srcaddr = addr;
    154  5648       setje }
    155  5648       setje 
    156  5648       setje static void
    157  5648       setje setup_outfile(char *file)
    158  5648       setje {
    159  5648       setje 	int fd;
    160  5648       setje 
    161  5648       setje 	dstfile = file;
    162  5648       setje 
    163  5648       setje 	fd = open(dstfile, O_WRONLY | O_CREAT | O_TRUNC,
    164  5648       setje 	    S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
    165  5648       setje 	if (fd == -1) {
    166  5648       setje 		(void) fprintf(stderr, OPEN_FAIL, dstfile, strerror(errno));
    167  5648       setje 		exit(-1);
    168  5648       setje 	}
    169  5648       setje 	dstfd = fd;
    170  5648       setje }
    171  5648       setje 
    172  5648       setje static void
    173  5648       setje do_comp(size_t blksize)
    174  5648       setje {
    175  5648       setje 	struct comphdr *hdr;
    176  5648       setje 	off_t offset;
    177  5648       setje 	size_t blks, dstlen, hlen;
    178  5648       setje 	void *dstbuf;
    179  5648       setje 	int i;
    180  5648       setje 
    181  5648       setje 	blks = ((srclen - 1) / blksize) + 1;
    182  5648       setje 	hlen = offset = sizeof (struct comphdr) + blks * sizeof (uint64_t);
    183  5648       setje 	hdr = malloc(hlen);
    184  5648       setje 	if (hdr == NULL) {
    185  5648       setje 		(void) fprintf(stderr, HDR_ALLOC, hlen);
    186  5648       setje 		exit(-1);
    187  5648       setje 	}
    188  5648       setje 
    189  7858  Krishnendu 	hdr->ch_magic = CH_MAGIC_ZLIB;
    190  5648       setje 	hdr->ch_version = CH_VERSION;
    191  5648       setje 	hdr->ch_algorithm = CH_ALG_ZLIB;
    192  5648       setje 	hdr->ch_fsize = srclen;
    193  5648       setje 	hdr->ch_blksize = blksize;
    194  5648       setje 
    195  5648       setje 	dstlen = ZMAXBUF(blksize);
    196  5648       setje 	dstbuf = malloc(dstlen);
    197  5648       setje 	if (dstbuf == NULL) {
    198  5648       setje 		(void) fprintf(stderr, BUF_ALLOC, dstlen);
    199  5648       setje 		exit(-1);
    200  5648       setje 	}
    201  5648       setje 
    202  5648       setje 	if (lseek(dstfd, offset, SEEK_SET) == (off_t)-1) {
    203  5648       setje 		(void) fprintf(stderr, SEEK_ERR,
    204  5648       setje 		    offset, dstfile, strerror(errno));
    205  5648       setje 		exit(-1);
    206  5648       setje 	}
    207  5648       setje 
    208  5648       setje 	for (i = 0; i < blks; i++) {
    209  5648       setje 		ulong_t slen, dlen;
    210  5648       setje 		int ret;
    211  5648       setje 
    212  5648       setje 		hdr->ch_blkmap[i] = offset;
    213  5648       setje 		slen = MIN(srclen, blksize);
    214  5648       setje 		dlen = dstlen;
    215  5648       setje 		ret = compress2(dstbuf, &dlen, (Bytef *)srcaddr, slen, 9);
    216  5648       setje 		if (ret != Z_OK) {
    217  5648       setje 			(void) fprintf(stderr, COMP_ERR, srcfile, ret);
    218  5648       setje 			exit(-1);
    219  5648       setje 		}
    220  5648       setje 
    221  5648       setje 		if (write(dstfd, dstbuf, dlen) != dlen) {
    222  5648       setje 			(void) fprintf(stderr, WRITE_ERR,
    223  5648       setje 			    dlen, dstfile, strerror(errno));
    224  5648       setje 			exit(-1);
    225  5648       setje 		}
    226  5648       setje 
    227  5648       setje 		offset += dlen;
    228  5648       setje 		srclen -= slen;
    229  5648       setje 		srcaddr += slen;
    230  5648       setje 	}
    231  5648       setje 
    232  5648       setje 	if (lseek(dstfd, 0, SEEK_SET) == (off_t)-1) {
    233  5648       setje 		(void) fprintf(stderr, SEEK_ERR,
    234  5648       setje 		    0, dstfile, strerror(errno));
    235  5648       setje 		exit(-1);
    236  5648       setje 	}
    237  5648       setje 
    238  5648       setje 	if (write(dstfd, hdr, hlen) != hlen) {
    239  5648       setje 		(void) fprintf(stderr, WRITE_ERR,
    240  5648       setje 		    hlen, dstfile, strerror(errno));
    241  5648       setje 		exit(-1);
    242  5648       setje 	}
    243  5648       setje }
    244  5648       setje 
    245  5648       setje static void
    246  5648       setje do_decomp()
    247  5648       setje {
    248  5648       setje 	struct comphdr *hdr;
    249  5648       setje 	size_t blks, blksize;
    250  5648       setje 	void *dstbuf;
    251  5648       setje 	int i;
    252  5648       setje 	ulong_t slen, dlen;
    253  5648       setje 	int ret;
    254  5648       setje 
    255  5648       setje 	hdr = (struct comphdr *)(void *)srcaddr;
    256  7858  Krishnendu 	if (hdr->ch_magic != CH_MAGIC_ZLIB) {
    257  5648       setje 		(void) fprintf(stderr, BAD_MAGIC,
    258  7858  Krishnendu 		    srcfile, (uint64_t)hdr->ch_magic, CH_MAGIC_ZLIB);
    259  5648       setje 		exit(-1);
    260  5648       setje 	}
    261  5648       setje 	if (hdr->ch_version != CH_VERSION) {
    262  5648       setje 		(void) fprintf(stderr, BAD_VERS,
    263  5648       setje 		    srcfile, (uint64_t)hdr->ch_version, CH_VERSION);
    264  5648       setje 		exit(-1);
    265  5648       setje 	}
    266  5648       setje 	if (hdr->ch_algorithm != CH_ALG_ZLIB) {
    267  5648       setje 		(void) fprintf(stderr, BAD_ALG,
    268  5648       setje 		    srcfile, (uint64_t)hdr->ch_algorithm, CH_ALG_ZLIB);
    269  5648       setje 		exit(-1);
    270  5648       setje 	}
    271  5648       setje 
    272  5648       setje 	blksize = hdr->ch_blksize;
    273  5648       setje 	dstbuf = malloc(blksize);
    274  5648       setje 	if (dstbuf == NULL) {
    275  5648       setje 		(void) fprintf(stderr, HDR_ALLOC, blksize);
    276  5648       setje 		exit(-1);
    277  5648       setje 	}
    278  5648       setje 
    279  5648       setje 	blks = (hdr->ch_fsize - 1) / blksize;
    280  5648       setje 	srcaddr += hdr->ch_blkmap[0];
    281  5648       setje 	for (i = 0; i < blks; i++) {
    282  5648       setje 		dlen = blksize;
    283  5648       setje 		slen = hdr->ch_blkmap[i + 1] - hdr->ch_blkmap[i];
    284  5648       setje 		ret = uncompress(dstbuf, &dlen, (Bytef *)srcaddr, slen);
    285  5648       setje 		if (ret != Z_OK) {
    286  5648       setje 			(void) fprintf(stderr, DECOMP_ERR, srcfile, ret);
    287  5648       setje 			exit(-1);
    288  5648       setje 		}
    289  5648       setje 
    290  5648       setje 		if (dlen != blksize) {
    291  5648       setje 			(void) fprintf(stderr, CORRUPT, srcfile);
    292  5648       setje 			exit(-1);
    293  5648       setje 		}
    294  5648       setje 		if (write(dstfd, dstbuf, dlen) != dlen) {
    295  5648       setje 			(void) fprintf(stderr, WRITE_ERR,
    296  5648       setje 			    dlen, dstfile, strerror(errno));
    297  5648       setje 			exit(-1);
    298  5648       setje 		}
    299  5648       setje 		srcaddr += slen;
    300  5648       setje 	}
    301  5648       setje 
    302  5648       setje 	dlen = blksize;
    303  5648       setje 	slen = hdr->ch_fsize - hdr->ch_blkmap[i];
    304  5648       setje 	if ((ret = uncompress(dstbuf, &dlen, (Bytef *)srcaddr, slen)) != Z_OK) {
    305  5648       setje 		(void) fprintf(stderr, DECOMP_ERR, dstfile, ret);
    306  5648       setje 		exit(-1);
    307  5648       setje 	}
    308  5648       setje 
    309  5648       setje 	if (write(dstfd, dstbuf, dlen) != dlen) {
    310  5648       setje 		(void) fprintf(stderr, WRITE_ERR,
    311  5648       setje 		    dlen, dstfile, strerror(errno));
    312  5648       setje 		exit(-1);
    313  5648       setje 	}
    314  5648       setje }
    315