diff options
Diffstat (limited to 'usr/src/uts/common/os/dumpsubr.c')
-rw-r--r-- | usr/src/uts/common/os/dumpsubr.c | 70 |
1 files changed, 68 insertions, 2 deletions
diff --git a/usr/src/uts/common/os/dumpsubr.c b/usr/src/uts/common/os/dumpsubr.c index b8dba61893..b1c90e0eac 100644 --- a/usr/src/uts/common/os/dumpsubr.c +++ b/usr/src/uts/common/os/dumpsubr.c @@ -19,7 +19,7 @@ * 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. */ @@ -62,6 +62,7 @@ #include <sys/vtoc.h> #include <sys/errorq.h> #include <sys/fm/util.h> +#include <sys/fs/zfs.h> #include <vm/hat.h> #include <vm/as.h> @@ -269,6 +270,17 @@ dumpinit(vnode_t *vp, char *name, int justchecking) dump_iosize = dki.dki_maxtransfer * blk_size; dumpbuf_resize(); } + /* + * If we are working with a zvol then call into + * it to dumpify itself. + */ + if (strcmp(dki.dki_dname, ZVOL_DRIVER) == 0) { + if ((error = VOP_IOCTL(cdev_vp, + DKIOCDUMPINIT, NULL, FKIOCTL, kcred, + NULL, NULL)) != 0) { + dumpfini(); + } + } (void) VOP_CLOSE(cdev_vp, FREAD | FWRITE, 1, 0, kcred, NULL); @@ -279,16 +291,43 @@ dumpinit(vnode_t *vp, char *name, int justchecking) cmn_err(CE_CONT, "?dump on %s size %llu MB\n", name, dumpvp_size >> 20); - return (0); + return (error); } void dumpfini(void) { + vattr_t vattr; + boolean_t is_zfs = B_FALSE; + vnode_t *cdev_vp; ASSERT(MUTEX_HELD(&dump_lock)); kmem_free(dumppath, strlen(dumppath) + 1); + /* + * Determine if we are using zvols for our dump device + */ + vattr.va_mask = AT_RDEV; + if (VOP_GETATTR(dumpvp, &vattr, 0, kcred, NULL) == 0) { + is_zfs = (getmajor(vattr.va_rdev) == + ddi_name_to_major(ZFS_DRIVER)) ? B_TRUE : B_FALSE; + } + + /* + * If we have a zvol dump device then we call into zfs so + * that it may have a chance to cleanup. + */ + if (is_zfs && + (cdev_vp = makespecvp(VTOS(dumpvp)->s_dev, VCHR)) != NULL) { + if (VOP_OPEN(&cdev_vp, FREAD | FWRITE, kcred, NULL) == 0) { + (void) VOP_IOCTL(cdev_vp, DKIOCDUMPFINI, NULL, FKIOCTL, + kcred, NULL, NULL); + (void) VOP_CLOSE(cdev_vp, FREAD | FWRITE, 1, 0, + kcred, NULL); + } + VN_RELE(cdev_vp); + } + (void) VOP_CLOSE(dumpvp, FREAD | FWRITE, 1, (offset_t)0, kcred, NULL); VN_RELE(dumpvp); @@ -798,3 +837,30 @@ dump_resize() dumpbuf_resize(); mutex_exit(&dump_lock); } + +/* + * This function allows for dynamic resizing of a dump area. It assumes that + * the underlying device has update its appropriate size(9P). + */ +int +dumpvp_resize() +{ + int error; + vattr_t vattr; + + mutex_enter(&dump_lock); + vattr.va_mask = AT_SIZE; + if ((error = VOP_GETATTR(dumpvp, &vattr, 0, kcred, NULL)) != 0) { + mutex_exit(&dump_lock); + return (error); + } + + if (error == 0 && vattr.va_size < 2 * DUMP_LOGSIZE + DUMP_ERPTSIZE) { + mutex_exit(&dump_lock); + return (ENOSPC); + } + + dumpvp_size = vattr.va_size & -DUMP_OFFSET; + mutex_exit(&dump_lock); + return (0); +} |