Index: sys/kern/kern_vnodedumper.c =================================================================== --- sys/kern/kern_vnodedumper.c +++ sys/kern/kern_vnodedumper.c @@ -60,6 +60,37 @@ EVENTHANDLER_DECLARE(livedumper_dump, livedump_dump_fn); EVENTHANDLER_DECLARE(livedumper_finish, livedump_fn); +static uint8_t livedump_comp = KERNELDUMP_COMP_NONE; + +static int +livedump_set_compression(SYSCTL_HANDLER_ARGS) +{ + int error; + uint8_t comp; + + comp = livedump_comp; + error = sysctl_handle_8(oidp, &comp, 0, req); + if (error != 0 || req->newptr == NULL) + return (error); + + switch (comp) { + case KERNELDUMP_COMP_NONE: + case KERNELDUMP_COMP_GZIP: + case KERNELDUMP_COMP_ZSTD: + livedump_comp = comp; + break; + default: + error = EINVAL; + break; + } + + return (error); +} +SYSCTL_PROC(_kern, OID_AUTO, livedump_compression, + CTLTYPE_U8 | CTLFLAG_RW | CTLFLAG_CAPRW, NULL, 0, + livedump_set_compression, "U8", + "Compression to apply for kern.livedump"); + /* * Invoke a live minidump on the system. */ @@ -67,7 +98,8 @@ sysctl_live_dump(SYSCTL_HANDLER_ARGS) { #if MINIDUMP_PAGE_TRACKING == 1 - struct dumperinfo di; + struct diocskerneldump_arg kda; + struct dumperinfo di, *livedi; struct vnode *vp; struct file *fp; void *rl_cookie; @@ -96,6 +128,12 @@ di.mediaoffset = 0; di.priv = vp; /* To be used by callback functions. */ + bzero(&kda, sizeof(kda)); + kda.kda_compression = livedump_comp; + error = dumper_create(&di, "livedump", &kda, &livedi); + if (error != 0) + return (error); + /* Lock the vnode and the entire file range. */ vn_lock(vp, LK_EXCLUSIVE | LK_RETRY); rl_cookie = vn_rangelock_wlock(vp, 0, OFF_MAX); @@ -108,13 +146,14 @@ goto out; dump_savectx(); - error = minidumpsys(&di, true); + error = minidumpsys(livedi, true); /* XXX: may clobber error. */ EVENTHANDLER_INVOKE(livedumper_finish, &error); out: sx_xunlock(&livedump_sx); vn_rangelock_unlock(vp, rl_cookie); VOP_UNLOCK(vp); + dumper_destroy(livedi); return (error); #else return (EOPNOTSUPP);