diff options
author | Krishnendu Sadhukhan - Sun Microsystems <Krishnendu.Sadhukhan@Sun.COM> | 2008-10-16 10:02:23 -0700 |
---|---|---|
committer | Krishnendu Sadhukhan - Sun Microsystems <Krishnendu.Sadhukhan@Sun.COM> | 2008-10-16 10:02:23 -0700 |
commit | 1d7f3fadeebf3754e3f042d91e7a4439755dc598 (patch) | |
tree | c031aeaaf4bf0f84ed5b91791551f45a93c20525 | |
parent | e66c2924ff28146fcc085fb48930b624cf64a36e (diff) | |
download | illumos-joyent-1d7f3fadeebf3754e3f042d91e7a4439755dc598.tar.gz |
6755292 Fast reboot should support failsafe
-rw-r--r-- | usr/src/cmd/boot/fiocompress/fiocompress.c | 10 | ||||
-rw-r--r-- | usr/src/uts/common/fs/dcfs/dc_vnops.c | 5 | ||||
-rw-r--r-- | usr/src/uts/common/krtld/kobj.c | 108 | ||||
-rw-r--r-- | usr/src/uts/common/sys/fs/decomp.h | 7 | ||||
-rw-r--r-- | usr/src/uts/common/zmod/zmod.c | 12 |
5 files changed, 120 insertions, 22 deletions
diff --git a/usr/src/cmd/boot/fiocompress/fiocompress.c b/usr/src/cmd/boot/fiocompress/fiocompress.c index cef348b158..f63683c2e5 100644 --- a/usr/src/cmd/boot/fiocompress/fiocompress.c +++ b/usr/src/cmd/boot/fiocompress/fiocompress.c @@ -19,12 +19,10 @@ * CDDL HEADER END */ /* - * Copyright 2007 Sun Microsystems, Inc. All rights reserved. + * Copyright 2008 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ -#pragma ident "%Z%%M% %I% %E% SMI" - /* * fiocompress - a utility to compress files with a filesystem. * Used to build compressed boot archives to reduce memory @@ -188,7 +186,7 @@ do_comp(size_t blksize) exit(-1); } - hdr->ch_magic = CH_MAGIC; + hdr->ch_magic = CH_MAGIC_ZLIB; hdr->ch_version = CH_VERSION; hdr->ch_algorithm = CH_ALG_ZLIB; hdr->ch_fsize = srclen; @@ -255,9 +253,9 @@ do_decomp() int ret; hdr = (struct comphdr *)(void *)srcaddr; - if (hdr->ch_magic != CH_MAGIC) { + if (hdr->ch_magic != CH_MAGIC_ZLIB) { (void) fprintf(stderr, BAD_MAGIC, - srcfile, (uint64_t)hdr->ch_magic, CH_MAGIC); + srcfile, (uint64_t)hdr->ch_magic, CH_MAGIC_ZLIB); exit(-1); } if (hdr->ch_version != CH_VERSION) { diff --git a/usr/src/uts/common/fs/dcfs/dc_vnops.c b/usr/src/uts/common/fs/dcfs/dc_vnops.c index f3cd915a49..1e30887d7f 100644 --- a/usr/src/uts/common/fs/dcfs/dc_vnops.c +++ b/usr/src/uts/common/fs/dcfs/dc_vnops.c @@ -37,9 +37,6 @@ * contributors. */ - -#pragma ident "%Z%%M% %I% %E% SMI" - #include <sys/types.h> #include <sys/thread.h> #include <sys/t_lock.h> @@ -930,7 +927,7 @@ decompvp(struct vnode *vp, cred_t *cred, caller_context_t *ctp) hdr = &thdr; error = vn_rdwr(UIO_READ, vp, (caddr_t)hdr, sizeof (struct comphdr), 0, UIO_SYSSPACE, 0, 0, cred, NULL); - if (error || hdr->ch_magic != CH_MAGIC || + if (error || hdr->ch_magic != CH_MAGIC_ZLIB || hdr->ch_version != CH_VERSION || hdr->ch_algorithm != CH_ALG_ZLIB || hdr->ch_fsize == 0 || hdr->ch_blksize < PAGESIZE || hdr->ch_blksize > ptob(DCCACHESIZE) || diff --git a/usr/src/uts/common/krtld/kobj.c b/usr/src/uts/common/krtld/kobj.c index 64a8ffecba..562c515279 100644 --- a/usr/src/uts/common/krtld/kobj.c +++ b/usr/src/uts/common/krtld/kobj.c @@ -23,8 +23,6 @@ * Use is subject to license terms. */ -#pragma ident "%Z%%M% %I% %E% SMI" - /* * Kernel's linker/loader */ @@ -126,6 +124,7 @@ static Sym *sym_lookup(struct module *, Sym *); static struct kobjopen_tctl *kobjopen_alloc(char *filename); static void kobjopen_free(struct kobjopen_tctl *ltp); static void kobjopen_thread(struct kobjopen_tctl *ltp); +static int kobj_is_compressed(intptr_t); extern int kcopy(const void *, void *, size_t); extern int elf_mach_ok(Ehdr *); @@ -213,7 +212,6 @@ struct lib_macro_info { char *boot_cpu_compatible_list; /* make $CPU available */ - char *kobj_module_path; /* module search path */ vmem_t *text_arena; /* module text arena */ static vmem_t *data_arena; /* module data & bss arena */ @@ -3728,6 +3726,11 @@ kobj_open_file(char *name) if (_modrootloaded) { file->_base = kobj_zalloc(MAXBSIZE, KM_WAIT); file->_bsize = MAXBSIZE; + + /* Check if the file is compressed */ + if (kobj_is_compressed(fd)) { + file->_iscmp = 1; + } } else { if (kobj_boot_compinfo(fd, &cbuf) != 0) { kobj_close_file(file); @@ -3764,7 +3767,7 @@ kobj_comp_setup(struct _buf *file, struct compinfo *cip) } hdr = kobj_comphdr(file); - if (hdr->ch_magic != CH_MAGIC || hdr->ch_version != CH_VERSION || + if (hdr->ch_magic != CH_MAGIC_ZLIB || hdr->ch_version != CH_VERSION || hdr->ch_algorithm != CH_ALG_ZLIB || hdr->ch_fsize == 0 || (hdr->ch_blksize & (hdr->ch_blksize - 1)) != 0) { kobj_free(file->_dbuf, cip->fsize); @@ -3801,6 +3804,54 @@ kobj_read_file(struct _buf *file, char *buf, uint_t size, uint_t off) _kobj_printf(ops, " buf=%x\n", buf); } + /* + * Handle compressed (gzip for now) file here. First get the + * compressed size, then read the image into memory and finally + * call zlib to decompress the image at the supplied memory buffer. + */ + if (file->_iscmp) { + ulong_t dlen; + vattr_t vattr; + struct vnode *vp = (struct vnode *)file->_fd; + ssize_t resid; + int err = 0; + + if (VOP_GETATTR(vp, &vattr, 0, kcred, NULL) != 0) + return (-1); + + file->_dbuf = kobj_alloc(vattr.va_size, KM_WAIT|KM_TMP); + file->_dsize = vattr.va_size; + + /* Read the compressed file into memory */ + if ((err = vn_rdwr(UIO_READ, vp, file->_dbuf, vattr.va_size, + (offset_t)(0), UIO_SYSSPACE, 0, (rlim64_t)0, CRED(), + &resid)) != 0) { + + _kobj_printf(ops, "kobj_read_file :vn_rdwr() failed, " + "error code 0x%x\n", err); + return (-1); + } + + dlen = size; + + /* Decompress the image at the supplied memory buffer */ + if ((err = z_uncompress(buf, &dlen, file->_dbuf, + vattr.va_size)) != Z_OK) { + _kobj_printf(ops, "kobj_read_file: z_uncompress " + "failed, error code : 0x%x\n", err); + return (-1); + } + + if (dlen != size) { + _kobj_printf(ops, "kobj_read_file: z_uncompress " + "failed to uncompress (size returned 0x%x , " + "expected size: 0x%x)\n", dlen, size); + return (-1); + } + + return (0); + } + while (size) { page_addr = F_PAGE(file, off); b_size = file->_size; @@ -4107,12 +4158,34 @@ kobj_gethashsize(uint_t n) int kobj_get_filesize(struct _buf *file, uint64_t *size) { + int err = 0; + ssize_t resid; + uint32_t buf; + if (_modrootloaded) { struct bootstat bst; if (kobj_fstat(file->_fd, &bst) != 0) return (EIO); *size = bst.st_size; + + if (file->_iscmp) { + /* + * Read the last 4 bytes of the compressed (gzip) + * image to get the size of its uncompressed + * version. + */ + if ((err = vn_rdwr(UIO_READ, (struct vnode *)file->_fd, + (char *)(&buf), 4, (offset_t)(*size - 4), + UIO_SYSSPACE, 0, (rlim64_t)0, CRED(), &resid)) + != 0) { + _kobj_printf(ops, "kobj_get_filesize: " + "vn_rdwr() failed with error 0x%x\n", err); + return (-1); + } + + *size = (uint64_t)buf; + } } else { #if defined(_OBP) @@ -4548,3 +4621,30 @@ kobj_boot_compinfo(int fd, struct compinfo *cb) { return (boot_compinfo(fd, cb)); } + +/* + * Check if the file is compressed (for now we handle only gzip). + * It returns 1 if the file is compressed and 0 otherwise. + */ +static int +kobj_is_compressed(intptr_t fd) +{ + struct vnode *vp = (struct vnode *)fd; + ssize_t resid; + uint16_t magic_buf; + int err = 0; + + if ((err = vn_rdwr(UIO_READ, vp, (caddr_t)((intptr_t)&magic_buf), + sizeof (magic_buf), (offset_t)(0), + UIO_SYSSPACE, 0, (rlim64_t)0, CRED(), &resid)) != 0) { + + _kobj_printf(ops, "kobj_is_compressed: vn_rdwr() failed, " + "error code 0x%x\n", err); + return (0); + } + + if (magic_buf == CH_MAGIC_GZIP) + return (1); + + return (0); +} diff --git a/usr/src/uts/common/sys/fs/decomp.h b/usr/src/uts/common/sys/fs/decomp.h index 035a5ab6c8..81708156be 100644 --- a/usr/src/uts/common/sys/fs/decomp.h +++ b/usr/src/uts/common/sys/fs/decomp.h @@ -19,20 +19,19 @@ * CDDL HEADER END */ /* - * Copyright 2007 Sun Microsystems, Inc. All rights reserved. + * Copyright 2008 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ #ifndef _SYS_DECOMP_H #define _SYS_DECOMP_H -#pragma ident "%Z%%M% %I% %E% SMI" - #ifdef __cplusplus extern "C" { #endif -#define CH_MAGIC 0x5a636d70 /* Zcmp */ +#define CH_MAGIC_ZLIB 0x5a636d70 /* ZLIB compression */ +#define CH_MAGIC_GZIP 0x8B1F /* GZIP compression */ #define CH_VERSION 1 diff --git a/usr/src/uts/common/zmod/zmod.c b/usr/src/uts/common/zmod/zmod.c index d1b0636a97..d22f595082 100644 --- a/usr/src/uts/common/zmod/zmod.c +++ b/usr/src/uts/common/zmod/zmod.c @@ -20,16 +20,15 @@ */ /* - * Copyright 2007 Sun Microsystems, Inc. All rights reserved. + * Copyright 2008 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ -#pragma ident "%Z%%M% %I% %E% SMI" - #include <sys/modctl.h> #include <sys/zmod.h> #include "zlib.h" +#include "zutil.h" /* * Uncompress the buffer 'src' into the buffer 'dst'. The caller must store @@ -49,7 +48,12 @@ z_uncompress(void *dst, size_t *dstlen, const void *src, size_t srclen) zs.next_out = dst; zs.avail_out = *dstlen; - if ((err = inflateInit(&zs)) != Z_OK) + /* + * Call inflateInit2() specifying a window size of DEF_WBITS + * with the 6th bit set to indicate that the compression format + * type (zlib or gzip) should be automatically detected. + */ + if ((err = inflateInit2(&zs, DEF_WBITS | 0x20)) != Z_OK) return (err); if ((err = inflate(&zs, Z_FINISH)) != Z_STREAM_END) { |