Generalize the gzio API.
We currently use a set of subroutines in kern_gzio.c to perform compression of user and kernel core dumps. In the interest of adding support for other compression algorithms (zstd) in this role without complicating the API consumers, add a simple compressor API which can be used to select an algorithm. Also change the (non-default) GZIO kernel option to not enable compressed user cores by default. It's not clear that such a default would be desirable with support for multiple algorithms implemented, and it's inconsistent in that it isn't applied to kernel dumps. Reviewed by: cem Differential Revision: https://reviews.freebsd.org/D13632
This commit is contained in:
parent
28ef16535c
commit
8b210be68e
@ -28,7 +28,7 @@
|
||||
.\" @(#)core.5 8.3 (Berkeley) 12/11/93
|
||||
.\" $FreeBSD$
|
||||
.\"
|
||||
.Dd October 5, 2015
|
||||
.Dd January 8, 2018
|
||||
.Dt CORE 5
|
||||
.Os
|
||||
.Sh NAME
|
||||
@ -67,8 +67,8 @@ generating it).
|
||||
.Pp
|
||||
The following format specifiers may be used in the
|
||||
.Va kern.corefile
|
||||
sysctl to insert additional information into the resulting core file
|
||||
name:
|
||||
sysctl to insert additional information into the resulting core
|
||||
filename:
|
||||
.Bl -tag -width "1234567890" -compact -offset "12345"
|
||||
.It Em \&%H
|
||||
Machine hostname.
|
||||
@ -108,17 +108,17 @@ is included in the kernel configuration file:
|
||||
GZIO
|
||||
.El
|
||||
.Pp
|
||||
When the GZIO option is included, the following sysctls control whether core
|
||||
files will be compressed:
|
||||
.Bl -tag -width "kern.compress_user_cores_gzlevel" -compact -offset "12345"
|
||||
.It Em kern.compress_user_cores_gzlevel
|
||||
Gzip compression level.
|
||||
Defaults to 6.
|
||||
The following sysctl control core file compression:
|
||||
.Bl -tag -width "kern.compress_user_cores_level" -compact -offset "12345"
|
||||
.It Em kern.compress_user_cores
|
||||
Actually compress user cores.
|
||||
Compressed core files will have a suffix of
|
||||
Enable compression of user cores.
|
||||
A value of 1 configures gzip compression.
|
||||
gzip-compressed core files will have a suffix of
|
||||
.Ql .gz
|
||||
appended to them.
|
||||
appended to their filenames.
|
||||
.It Em kern.compress_user_cores_level
|
||||
Compression level.
|
||||
Defaults to 6.
|
||||
.El
|
||||
.Sh NOTES
|
||||
Corefiles are written with open file descriptor information as an ELF note.
|
||||
@ -153,6 +153,7 @@ command can be used:
|
||||
.Dl sysctl kern.corefile=/var/coredumps/\&%U/\&%N.core
|
||||
.Sh SEE ALSO
|
||||
.Xr gdb 1 ,
|
||||
.Xr gzip 1 ,
|
||||
.Xr kgdb 1 ,
|
||||
.Xr setrlimit 2 ,
|
||||
.Xr sigaction 2 ,
|
||||
|
@ -3767,7 +3767,6 @@ kern/kern_exit.c standard
|
||||
kern/kern_fail.c standard
|
||||
kern/kern_ffclock.c standard
|
||||
kern/kern_fork.c standard
|
||||
kern/kern_gzio.c optional gzio
|
||||
kern/kern_hhook.c standard
|
||||
kern/kern_idle.c standard
|
||||
kern/kern_intr.c standard
|
||||
@ -3843,6 +3842,7 @@ kern/subr_bus_dma.c standard
|
||||
kern/subr_bufring.c standard
|
||||
kern/subr_capability.c standard
|
||||
kern/subr_clock.c standard
|
||||
kern/subr_compressor.c standard
|
||||
kern/subr_counter.c standard
|
||||
kern/subr_devstat.c standard
|
||||
kern/subr_disk.c standard
|
||||
|
@ -454,8 +454,8 @@ textdump_dumpsys(struct dumperinfo *di)
|
||||
/*
|
||||
* Disable EKCD because we don't provide encrypted textdumps.
|
||||
*/
|
||||
kdc = di->kdc;
|
||||
di->kdc = NULL;
|
||||
kdc = di->kdcrypto;
|
||||
di->kdcrypto = NULL;
|
||||
|
||||
/*
|
||||
* Position the start of the dump so that we'll write the kernel dump
|
||||
@ -512,7 +512,7 @@ textdump_dumpsys(struct dumperinfo *di)
|
||||
/*
|
||||
* Restore EKCD status.
|
||||
*/
|
||||
di->kdc = kdc;
|
||||
di->kdcrypto = kdc;
|
||||
}
|
||||
|
||||
/*-
|
||||
|
@ -36,13 +36,12 @@ __FBSDID("$FreeBSD$");
|
||||
|
||||
#include "opt_capsicum.h"
|
||||
#include "opt_compat.h"
|
||||
#include "opt_gzio.h"
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/capsicum.h>
|
||||
#include <sys/compressor.h>
|
||||
#include <sys/exec.h>
|
||||
#include <sys/fcntl.h>
|
||||
#include <sys/gzio.h>
|
||||
#include <sys/imgact.h>
|
||||
#include <sys/imgact_elf.h>
|
||||
#include <sys/jail.h>
|
||||
@ -1185,9 +1184,12 @@ struct coredump_params {
|
||||
struct ucred *file_cred;
|
||||
struct thread *td;
|
||||
struct vnode *vp;
|
||||
struct gzio_stream *gzs;
|
||||
struct compressor *comp;
|
||||
};
|
||||
|
||||
extern int compress_user_cores;
|
||||
extern int compress_user_cores_level;
|
||||
|
||||
static void cb_put_phdr(vm_map_entry_t, void *);
|
||||
static void cb_size_segment(vm_map_entry_t, void *);
|
||||
static int core_write(struct coredump_params *, const void *, size_t, off_t,
|
||||
@ -1219,9 +1221,6 @@ static void note_procstat_rlimit(void *, struct sbuf *, size_t *);
|
||||
static void note_procstat_umask(void *, struct sbuf *, size_t *);
|
||||
static void note_procstat_vmmap(void *, struct sbuf *, size_t *);
|
||||
|
||||
#ifdef GZIO
|
||||
extern int compress_user_cores_gzlevel;
|
||||
|
||||
/*
|
||||
* Write out a core segment to the compression stream.
|
||||
*/
|
||||
@ -1241,7 +1240,7 @@ compress_chunk(struct coredump_params *p, char *base, char *buf, u_int len)
|
||||
error = copyin(base, buf, chunk_len);
|
||||
if (error != 0)
|
||||
bzero(buf, chunk_len);
|
||||
error = gzio_write(p->gzs, buf, chunk_len);
|
||||
error = compressor_write(p->comp, buf, chunk_len);
|
||||
if (error != 0)
|
||||
break;
|
||||
base += chunk_len;
|
||||
@ -1251,13 +1250,12 @@ compress_chunk(struct coredump_params *p, char *base, char *buf, u_int len)
|
||||
}
|
||||
|
||||
static int
|
||||
core_gz_write(void *base, size_t len, off_t offset, void *arg)
|
||||
core_compressed_write(void *base, size_t len, off_t offset, void *arg)
|
||||
{
|
||||
|
||||
return (core_write((struct coredump_params *)arg, base, len, offset,
|
||||
UIO_SYSSPACE));
|
||||
}
|
||||
#endif /* GZIO */
|
||||
|
||||
static int
|
||||
core_write(struct coredump_params *p, const void *base, size_t len,
|
||||
@ -1275,10 +1273,9 @@ core_output(void *base, size_t len, off_t offset, struct coredump_params *p,
|
||||
{
|
||||
int error;
|
||||
|
||||
#ifdef GZIO
|
||||
if (p->gzs != NULL)
|
||||
if (p->comp != NULL)
|
||||
return (compress_chunk(p, base, tmpbuf, len));
|
||||
#endif
|
||||
|
||||
/*
|
||||
* EFAULT is a non-fatal error that we can get, for example,
|
||||
* if the segment is backed by a file but extends beyond its
|
||||
@ -1323,11 +1320,9 @@ sbuf_drain_core_output(void *arg, const char *data, int len)
|
||||
locked = PROC_LOCKED(p->td->td_proc);
|
||||
if (locked)
|
||||
PROC_UNLOCK(p->td->td_proc);
|
||||
#ifdef GZIO
|
||||
if (p->gzs != NULL)
|
||||
error = gzio_write(p->gzs, __DECONST(char *, data), len);
|
||||
if (p->comp != NULL)
|
||||
error = compressor_write(p->comp, __DECONST(char *, data), len);
|
||||
else
|
||||
#endif
|
||||
error = core_write(p, __DECONST(void *, data), len, p->offset,
|
||||
UIO_SYSSPACE);
|
||||
if (locked)
|
||||
@ -1362,11 +1357,7 @@ __elfN(coredump)(struct thread *td, struct vnode *vp, off_t limit, int flags)
|
||||
struct note_info *ninfo;
|
||||
void *hdr, *tmpbuf;
|
||||
size_t hdrsize, notesz, coresize;
|
||||
#ifdef GZIO
|
||||
boolean_t compress;
|
||||
|
||||
compress = (flags & IMGACT_CORE_COMPRESS) != 0;
|
||||
#endif
|
||||
hdr = NULL;
|
||||
tmpbuf = NULL;
|
||||
TAILQ_INIT(¬elst);
|
||||
@ -1391,7 +1382,7 @@ __elfN(coredump)(struct thread *td, struct vnode *vp, off_t limit, int flags)
|
||||
params.file_cred = NOCRED;
|
||||
params.td = td;
|
||||
params.vp = vp;
|
||||
params.gzs = NULL;
|
||||
params.comp = NULL;
|
||||
|
||||
#ifdef RACCT
|
||||
if (racct_enable) {
|
||||
@ -1409,18 +1400,17 @@ __elfN(coredump)(struct thread *td, struct vnode *vp, off_t limit, int flags)
|
||||
goto done;
|
||||
}
|
||||
|
||||
#ifdef GZIO
|
||||
/* Create a compression stream if necessary. */
|
||||
if (compress) {
|
||||
params.gzs = gzio_init(core_gz_write, GZIO_DEFLATE,
|
||||
CORE_BUF_SIZE, compress_user_cores_gzlevel, ¶ms);
|
||||
if (params.gzs == NULL) {
|
||||
if (compress_user_cores != 0) {
|
||||
params.comp = compressor_init(core_compressed_write,
|
||||
compress_user_cores, CORE_BUF_SIZE,
|
||||
compress_user_cores_level, ¶ms);
|
||||
if (params.comp == NULL) {
|
||||
error = EFAULT;
|
||||
goto done;
|
||||
}
|
||||
tmpbuf = malloc(CORE_BUF_SIZE, M_TEMP, M_WAITOK | M_ZERO);
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Allocate memory for building the header, fill it up,
|
||||
@ -1446,10 +1436,8 @@ __elfN(coredump)(struct thread *td, struct vnode *vp, off_t limit, int flags)
|
||||
offset += php->p_filesz;
|
||||
php++;
|
||||
}
|
||||
#ifdef GZIO
|
||||
if (error == 0 && compress)
|
||||
error = gzio_flush(params.gzs);
|
||||
#endif
|
||||
if (error == 0 && params.comp != NULL)
|
||||
error = compressor_flush(params.comp);
|
||||
}
|
||||
if (error) {
|
||||
log(LOG_WARNING,
|
||||
@ -1458,13 +1446,9 @@ __elfN(coredump)(struct thread *td, struct vnode *vp, off_t limit, int flags)
|
||||
}
|
||||
|
||||
done:
|
||||
#ifdef GZIO
|
||||
if (compress) {
|
||||
free(tmpbuf, M_TEMP);
|
||||
if (params.gzs != NULL)
|
||||
gzio_fini(params.gzs);
|
||||
}
|
||||
#endif
|
||||
free(tmpbuf, M_TEMP);
|
||||
if (params.comp != NULL)
|
||||
compressor_fini(params.comp);
|
||||
while ((ninfo = TAILQ_FIRST(¬elst)) != NULL) {
|
||||
TAILQ_REMOVE(¬elst, ninfo, link);
|
||||
free(ninfo, M_TEMP);
|
||||
|
@ -41,7 +41,6 @@ __FBSDID("$FreeBSD$");
|
||||
|
||||
#include "opt_ddb.h"
|
||||
#include "opt_ekcd.h"
|
||||
#include "opt_gzio.h"
|
||||
#include "opt_kdb.h"
|
||||
#include "opt_panic.h"
|
||||
#include "opt_sched.h"
|
||||
@ -52,10 +51,10 @@ __FBSDID("$FreeBSD$");
|
||||
#include <sys/bio.h>
|
||||
#include <sys/buf.h>
|
||||
#include <sys/conf.h>
|
||||
#include <sys/compressor.h>
|
||||
#include <sys/cons.h>
|
||||
#include <sys/eventhandler.h>
|
||||
#include <sys/filedesc.h>
|
||||
#include <sys/gzio.h>
|
||||
#include <sys/jail.h>
|
||||
#include <sys/kdb.h>
|
||||
#include <sys/kernel.h>
|
||||
@ -174,23 +173,21 @@ struct kerneldumpcrypto {
|
||||
};
|
||||
#endif
|
||||
|
||||
#ifdef GZIO
|
||||
struct kerneldumpgz {
|
||||
struct gzio_stream *kdgz_stream;
|
||||
uint8_t *kdgz_buf;
|
||||
size_t kdgz_resid;
|
||||
struct kerneldumpcomp {
|
||||
struct compressor *kdc_stream;
|
||||
uint8_t *kdc_buf;
|
||||
size_t kdc_resid;
|
||||
};
|
||||
|
||||
static struct kerneldumpgz *kerneldumpgz_create(struct dumperinfo *di,
|
||||
static struct kerneldumpcomp *kerneldumpcomp_create(struct dumperinfo *di,
|
||||
uint8_t compression);
|
||||
static void kerneldumpgz_destroy(struct dumperinfo *di);
|
||||
static int kerneldumpgz_write_cb(void *cb, size_t len, off_t off, void *arg);
|
||||
static void kerneldumpcomp_destroy(struct dumperinfo *di);
|
||||
static int kerneldumpcomp_write_cb(void *base, size_t len, off_t off, void *arg);
|
||||
|
||||
static int kerneldump_gzlevel = 6;
|
||||
SYSCTL_INT(_kern, OID_AUTO, kerneldump_gzlevel, CTLFLAG_RWTUN,
|
||||
&kerneldump_gzlevel, 0,
|
||||
"Kernel crash dump gzip compression level");
|
||||
#endif /* GZIO */
|
||||
"Kernel crash dump compression level");
|
||||
|
||||
/*
|
||||
* Variable panicstr contains argument to first call to panic; used as flag
|
||||
@ -986,39 +983,37 @@ kerneldumpcrypto_dumpkeysize(const struct kerneldumpcrypto *kdc)
|
||||
}
|
||||
#endif /* EKCD */
|
||||
|
||||
#ifdef GZIO
|
||||
static struct kerneldumpgz *
|
||||
kerneldumpgz_create(struct dumperinfo *di, uint8_t compression)
|
||||
static struct kerneldumpcomp *
|
||||
kerneldumpcomp_create(struct dumperinfo *di, uint8_t compression)
|
||||
{
|
||||
struct kerneldumpgz *kdgz;
|
||||
struct kerneldumpcomp *kdcomp;
|
||||
|
||||
if (compression != KERNELDUMP_COMP_GZIP)
|
||||
return (NULL);
|
||||
kdgz = malloc(sizeof(*kdgz), M_DUMPER, M_WAITOK | M_ZERO);
|
||||
kdgz->kdgz_stream = gzio_init(kerneldumpgz_write_cb, GZIO_DEFLATE,
|
||||
di->maxiosize, kerneldump_gzlevel, di);
|
||||
if (kdgz->kdgz_stream == NULL) {
|
||||
free(kdgz, M_DUMPER);
|
||||
kdcomp = malloc(sizeof(*kdcomp), M_DUMPER, M_WAITOK | M_ZERO);
|
||||
kdcomp->kdc_stream = compressor_init(kerneldumpcomp_write_cb,
|
||||
COMPRESS_GZIP, di->maxiosize, kerneldump_gzlevel, di);
|
||||
if (kdcomp->kdc_stream == NULL) {
|
||||
free(kdcomp, M_DUMPER);
|
||||
return (NULL);
|
||||
}
|
||||
kdgz->kdgz_buf = malloc(di->maxiosize, M_DUMPER, M_WAITOK | M_NODUMP);
|
||||
return (kdgz);
|
||||
kdcomp->kdc_buf = malloc(di->maxiosize, M_DUMPER, M_WAITOK | M_NODUMP);
|
||||
return (kdcomp);
|
||||
}
|
||||
|
||||
static void
|
||||
kerneldumpgz_destroy(struct dumperinfo *di)
|
||||
kerneldumpcomp_destroy(struct dumperinfo *di)
|
||||
{
|
||||
struct kerneldumpgz *kdgz;
|
||||
struct kerneldumpcomp *kdcomp;
|
||||
|
||||
kdgz = di->kdgz;
|
||||
if (kdgz == NULL)
|
||||
kdcomp = di->kdcomp;
|
||||
if (kdcomp == NULL)
|
||||
return;
|
||||
gzio_fini(kdgz->kdgz_stream);
|
||||
explicit_bzero(kdgz->kdgz_buf, di->maxiosize);
|
||||
free(kdgz->kdgz_buf, M_DUMPER);
|
||||
free(kdgz, M_DUMPER);
|
||||
compressor_fini(kdcomp->kdc_stream);
|
||||
explicit_bzero(kdcomp->kdc_buf, di->maxiosize);
|
||||
free(kdcomp->kdc_buf, M_DUMPER);
|
||||
free(kdcomp, M_DUMPER);
|
||||
}
|
||||
#endif /* GZIO */
|
||||
|
||||
/* Registration of dumpers */
|
||||
int
|
||||
@ -1041,14 +1036,14 @@ set_dumper(struct dumperinfo *di, const char *devname, struct thread *td,
|
||||
return (EBUSY);
|
||||
dumper = *di;
|
||||
dumper.blockbuf = NULL;
|
||||
dumper.kdc = NULL;
|
||||
dumper.kdgz = NULL;
|
||||
dumper.kdcrypto = NULL;
|
||||
dumper.kdcomp = NULL;
|
||||
|
||||
if (encryption != KERNELDUMP_ENC_NONE) {
|
||||
#ifdef EKCD
|
||||
dumper.kdc = kerneldumpcrypto_create(di->blocksize, encryption,
|
||||
key, encryptedkeysize, encryptedkey);
|
||||
if (dumper.kdc == NULL) {
|
||||
dumper.kdcrypto = kerneldumpcrypto_create(di->blocksize,
|
||||
encryption, key, encryptedkeysize, encryptedkey);
|
||||
if (dumper.kdcrypto == NULL) {
|
||||
error = EINVAL;
|
||||
goto cleanup;
|
||||
}
|
||||
@ -1065,7 +1060,6 @@ set_dumper(struct dumperinfo *di, const char *devname, struct thread *td,
|
||||
}
|
||||
|
||||
if (compression != KERNELDUMP_COMP_NONE) {
|
||||
#ifdef GZIO
|
||||
/*
|
||||
* We currently can't support simultaneous encryption and
|
||||
* compression.
|
||||
@ -1074,31 +1068,25 @@ set_dumper(struct dumperinfo *di, const char *devname, struct thread *td,
|
||||
error = EOPNOTSUPP;
|
||||
goto cleanup;
|
||||
}
|
||||
dumper.kdgz = kerneldumpgz_create(&dumper, compression);
|
||||
if (dumper.kdgz == NULL) {
|
||||
dumper.kdcomp = kerneldumpcomp_create(&dumper, compression);
|
||||
if (dumper.kdcomp == NULL) {
|
||||
error = EINVAL;
|
||||
goto cleanup;
|
||||
}
|
||||
#else
|
||||
error = EOPNOTSUPP;
|
||||
goto cleanup;
|
||||
#endif
|
||||
}
|
||||
|
||||
dumper.blockbuf = malloc(di->blocksize, M_DUMPER, M_WAITOK | M_ZERO);
|
||||
return (0);
|
||||
cleanup:
|
||||
#ifdef EKCD
|
||||
if (dumper.kdc != NULL) {
|
||||
explicit_bzero(dumper.kdc, sizeof(*dumper.kdc) +
|
||||
dumper.kdc->kdc_dumpkeysize);
|
||||
free(dumper.kdc, M_EKCD);
|
||||
if (dumper.kdcrypto != NULL) {
|
||||
explicit_bzero(dumper.kdcrypto, sizeof(*dumper.kdcrypto) +
|
||||
dumper.kdcrypto->kdc_dumpkeysize);
|
||||
free(dumper.kdcrypto, M_EKCD);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef GZIO
|
||||
kerneldumpgz_destroy(&dumper);
|
||||
#endif
|
||||
kerneldumpcomp_destroy(&dumper);
|
||||
|
||||
if (dumper.blockbuf != NULL) {
|
||||
explicit_bzero(dumper.blockbuf, dumper.blocksize);
|
||||
@ -1168,7 +1156,7 @@ dump_encrypted_write(struct dumperinfo *di, void *virtual,
|
||||
int error;
|
||||
size_t nbytes;
|
||||
|
||||
kdc = di->kdc;
|
||||
kdc = di->kdcrypto;
|
||||
|
||||
while (length > 0) {
|
||||
nbytes = MIN(length, sizeof(buf));
|
||||
@ -1194,7 +1182,7 @@ dump_write_key(struct dumperinfo *di, off_t offset)
|
||||
{
|
||||
struct kerneldumpcrypto *kdc;
|
||||
|
||||
kdc = di->kdc;
|
||||
kdc = di->kdcrypto;
|
||||
if (kdc == NULL)
|
||||
return (0);
|
||||
return (dump_write(di, kdc->kdc_dumpkey, 0, offset,
|
||||
@ -1202,9 +1190,8 @@ dump_write_key(struct dumperinfo *di, off_t offset)
|
||||
}
|
||||
#endif /* EKCD */
|
||||
|
||||
#ifdef GZIO
|
||||
static int
|
||||
kerneldumpgz_write_cb(void *base, size_t length, off_t offset, void *arg)
|
||||
kerneldumpcomp_write_cb(void *base, size_t length, off_t offset, void *arg)
|
||||
{
|
||||
struct dumperinfo *di;
|
||||
size_t resid, rlength;
|
||||
@ -1227,12 +1214,11 @@ kerneldumpgz_write_cb(void *base, size_t length, off_t offset, void *arg)
|
||||
}
|
||||
resid = length - rlength;
|
||||
memmove(di->blockbuf, (uint8_t *)base + rlength, resid);
|
||||
di->kdgz->kdgz_resid = resid;
|
||||
di->kdcomp->kdc_resid = resid;
|
||||
return (EAGAIN);
|
||||
}
|
||||
return (_dump_append(di, base, 0, length));
|
||||
}
|
||||
#endif /* GZIO */
|
||||
|
||||
/*
|
||||
* Write a kerneldumpheader at the specified offset. The header structure is 512
|
||||
@ -1290,10 +1276,10 @@ dump_start(struct dumperinfo *di, struct kerneldumpheader *kdh)
|
||||
uint32_t keysize;
|
||||
|
||||
#ifdef EKCD
|
||||
int error = kerneldumpcrypto_init(di->kdc);
|
||||
int error = kerneldumpcrypto_init(di->kdcrypto);
|
||||
if (error != 0)
|
||||
return (error);
|
||||
keysize = kerneldumpcrypto_dumpkeysize(di->kdc);
|
||||
keysize = kerneldumpcrypto_dumpkeysize(di->kdcrypto);
|
||||
#else
|
||||
keysize = 0;
|
||||
#endif
|
||||
@ -1301,8 +1287,7 @@ dump_start(struct dumperinfo *di, struct kerneldumpheader *kdh)
|
||||
dumpextent = dtoh64(kdh->dumpextent);
|
||||
if (di->mediasize < SIZEOF_METADATA + dumpextent + 2 * di->blocksize +
|
||||
keysize) {
|
||||
#ifdef GZIO
|
||||
if (di->kdgz != NULL) {
|
||||
if (di->kdcomp != NULL) {
|
||||
/*
|
||||
* We don't yet know how much space the compressed dump
|
||||
* will occupy, so try to use the whole swap partition
|
||||
@ -1315,7 +1300,6 @@ dump_start(struct dumperinfo *di, struct kerneldumpheader *kdh)
|
||||
2 * di->blocksize - keysize;
|
||||
kdh->dumpextent = htod64(dumpextent);
|
||||
} else
|
||||
#endif
|
||||
return (E2BIG);
|
||||
}
|
||||
|
||||
@ -1333,7 +1317,7 @@ _dump_append(struct dumperinfo *di, void *virtual, vm_offset_t physical,
|
||||
int error;
|
||||
|
||||
#ifdef EKCD
|
||||
if (di->kdc != NULL)
|
||||
if (di->kdcrypto != NULL)
|
||||
error = dump_encrypted_write(di, virtual, physical, di->dumpoff,
|
||||
length);
|
||||
else
|
||||
@ -1353,18 +1337,16 @@ int
|
||||
dump_append(struct dumperinfo *di, void *virtual, vm_offset_t physical,
|
||||
size_t length)
|
||||
{
|
||||
#ifdef GZIO
|
||||
void *buf;
|
||||
|
||||
if (di->kdgz != NULL) {
|
||||
/* Bounce through a buffer to avoid gzip CRC errors. */
|
||||
if (di->kdcomp != NULL) {
|
||||
/* Bounce through a buffer to avoid CRC errors. */
|
||||
if (length > di->maxiosize)
|
||||
return (EINVAL);
|
||||
buf = di->kdgz->kdgz_buf;
|
||||
buf = di->kdcomp->kdc_buf;
|
||||
memmove(buf, virtual, length);
|
||||
return (gzio_write(di->kdgz->kdgz_stream, buf, length));
|
||||
return (compressor_write(di->kdcomp->kdc_stream, buf, length));
|
||||
}
|
||||
#endif
|
||||
return (_dump_append(di, virtual, physical, length));
|
||||
}
|
||||
|
||||
@ -1399,20 +1381,19 @@ dump_finish(struct dumperinfo *di, struct kerneldumpheader *kdh)
|
||||
extent = dtoh64(kdh->dumpextent);
|
||||
|
||||
#ifdef EKCD
|
||||
keysize = kerneldumpcrypto_dumpkeysize(di->kdc);
|
||||
keysize = kerneldumpcrypto_dumpkeysize(di->kdcrypto);
|
||||
#else
|
||||
keysize = 0;
|
||||
#endif
|
||||
|
||||
#ifdef GZIO
|
||||
if (di->kdgz != NULL) {
|
||||
error = gzio_flush(di->kdgz->kdgz_stream);
|
||||
if (di->kdcomp != NULL) {
|
||||
error = compressor_flush(di->kdcomp->kdc_stream);
|
||||
if (error == EAGAIN) {
|
||||
/* We have residual data in di->blockbuf. */
|
||||
error = dump_write(di, di->blockbuf, 0, di->dumpoff,
|
||||
di->blocksize);
|
||||
di->dumpoff += di->kdgz->kdgz_resid;
|
||||
di->kdgz->kdgz_resid = 0;
|
||||
di->dumpoff += di->kdcomp->kdc_resid;
|
||||
di->kdcomp->kdc_resid = 0;
|
||||
}
|
||||
if (error != 0)
|
||||
return (error);
|
||||
@ -1426,9 +1407,8 @@ dump_finish(struct dumperinfo *di, struct kerneldumpheader *kdh)
|
||||
kdh->parity = 0;
|
||||
kdh->parity = kerneldump_parity(kdh);
|
||||
|
||||
gzio_reset(di->kdgz->kdgz_stream);
|
||||
compressor_reset(di->kdcomp->kdc_stream);
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Write kerneldump headers at the beginning and end of the dump extent.
|
||||
@ -1471,7 +1451,7 @@ dump_init_header(const struct dumperinfo *di, struct kerneldumpheader *kdh,
|
||||
kdh->dumpextent = kdh->dumplength;
|
||||
kdh->dumptime = htod64(time_second);
|
||||
#ifdef EKCD
|
||||
kdh->dumpkeysize = htod32(kerneldumpcrypto_dumpkeysize(di->kdc));
|
||||
kdh->dumpkeysize = htod32(kerneldumpcrypto_dumpkeysize(di->kdcrypto));
|
||||
#else
|
||||
kdh->dumpkeysize = 0;
|
||||
#endif
|
||||
@ -1482,10 +1462,8 @@ dump_init_header(const struct dumperinfo *di, struct kerneldumpheader *kdh,
|
||||
kdh->versionstring[dstsize - 2] = '\n';
|
||||
if (panicstr != NULL)
|
||||
strlcpy(kdh->panicstring, panicstr, sizeof(kdh->panicstring));
|
||||
#ifdef GZIO
|
||||
if (di->kdgz != NULL)
|
||||
if (di->kdcomp != NULL)
|
||||
kdh->compression = KERNELDUMP_COMP_GZIP;
|
||||
#endif
|
||||
kdh->parity = kerneldump_parity(kdh);
|
||||
}
|
||||
|
||||
|
@ -40,7 +40,6 @@
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
#include "opt_compat.h"
|
||||
#include "opt_gzio.h"
|
||||
#include "opt_ktrace.h"
|
||||
|
||||
#include <sys/param.h>
|
||||
@ -51,6 +50,7 @@ __FBSDID("$FreeBSD$");
|
||||
#include <sys/acct.h>
|
||||
#include <sys/bus.h>
|
||||
#include <sys/capsicum.h>
|
||||
#include <sys/compressor.h>
|
||||
#include <sys/condvar.h>
|
||||
#include <sys/event.h>
|
||||
#include <sys/fcntl.h>
|
||||
@ -3255,17 +3255,30 @@ SYSCTL_PROC(_debug, OID_AUTO, ncores, CTLTYPE_INT|CTLFLAG_RW,
|
||||
|
||||
#define GZ_SUFFIX ".gz"
|
||||
|
||||
#ifdef GZIO
|
||||
static int compress_user_cores = 1;
|
||||
SYSCTL_INT(_kern, OID_AUTO, compress_user_cores, CTLFLAG_RWTUN,
|
||||
&compress_user_cores, 0, "Compression of user corefiles");
|
||||
int compress_user_cores = 0;
|
||||
|
||||
int compress_user_cores_gzlevel = 6;
|
||||
SYSCTL_INT(_kern, OID_AUTO, compress_user_cores_gzlevel, CTLFLAG_RWTUN,
|
||||
&compress_user_cores_gzlevel, 0, "Corefile gzip compression level");
|
||||
#else
|
||||
static int compress_user_cores = 0;
|
||||
#endif
|
||||
static int
|
||||
sysctl_compress_user_cores(SYSCTL_HANDLER_ARGS)
|
||||
{
|
||||
int error, val;
|
||||
|
||||
val = compress_user_cores;
|
||||
error = sysctl_handle_int(oidp, &val, 0, req);
|
||||
if (error != 0 || req->newptr == NULL)
|
||||
return (error);
|
||||
if (val != 0 && !compressor_avail(val))
|
||||
return (EINVAL);
|
||||
compress_user_cores = val;
|
||||
return (error);
|
||||
}
|
||||
SYSCTL_PROC(_kern, OID_AUTO, compress_user_cores, CTLTYPE_INT | CTLFLAG_RWTUN,
|
||||
0, sizeof(int), sysctl_compress_user_cores, "I",
|
||||
"Enable compression of user corefiles (" __XSTRING(COMPRESS_GZIP) " = gzip)");
|
||||
|
||||
int compress_user_cores_level = 6;
|
||||
SYSCTL_INT(_kern, OID_AUTO, compress_user_cores_level, CTLFLAG_RWTUN,
|
||||
&compress_user_cores_level, 0,
|
||||
"Corefile compression level");
|
||||
|
||||
/*
|
||||
* Protect the access to corefilename[] by allproc_lock.
|
||||
@ -3363,7 +3376,7 @@ corefile_open(const char *comm, uid_t uid, pid_t pid, struct thread *td,
|
||||
}
|
||||
sx_sunlock(&corefilename_lock);
|
||||
free(hostname, M_TEMP);
|
||||
if (compress)
|
||||
if (compress == COMPRESS_GZIP)
|
||||
sbuf_printf(&sb, GZ_SUFFIX);
|
||||
if (sbuf_error(&sb) != 0) {
|
||||
log(LOG_ERR, "pid %ld (%s), uid (%lu): corename is too "
|
||||
@ -3529,8 +3542,7 @@ coredump(struct thread *td)
|
||||
PROC_UNLOCK(p);
|
||||
|
||||
if (p->p_sysent->sv_coredump != NULL) {
|
||||
error = p->p_sysent->sv_coredump(td, vp, limit,
|
||||
compress_user_cores ? IMGACT_CORE_COMPRESS : 0);
|
||||
error = p->p_sysent->sv_coredump(td, vp, limit, 0);
|
||||
} else {
|
||||
error = ENOSYS;
|
||||
}
|
||||
|
@ -1,5 +1,7 @@
|
||||
/*-
|
||||
* Copyright (c) 2014 Mark Johnston <markj@FreeBSD.org>
|
||||
* SPDX-License-Identifier: BSD-2-Clause-FreeBSD
|
||||
*
|
||||
* Copyright (c) 2014, 2017 Mark Johnston <markj@FreeBSD.org>
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
@ -24,55 +26,87 @@
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Subroutines used for writing compressed user process and kernel core dumps.
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
#include "opt_gzio.h"
|
||||
|
||||
#include <sys/param.h>
|
||||
|
||||
#include <sys/gzio.h>
|
||||
#include <sys/compressor.h>
|
||||
#include <sys/kernel.h>
|
||||
#include <sys/linker_set.h>
|
||||
#include <sys/malloc.h>
|
||||
|
||||
MALLOC_DEFINE(M_COMPRESS, "compressor", "kernel compression subroutines");
|
||||
|
||||
struct compressor_methods {
|
||||
int format;
|
||||
void *(* const init)(size_t, int);
|
||||
void (* const reset)(void *);
|
||||
int (* const write)(void *, void *, size_t, compressor_cb_t, void *);
|
||||
void (* const fini)(void *);
|
||||
};
|
||||
|
||||
struct compressor {
|
||||
const struct compressor_methods *methods;
|
||||
compressor_cb_t cb;
|
||||
void *priv;
|
||||
void *arg;
|
||||
};
|
||||
|
||||
SET_DECLARE(compressors, struct compressor_methods);
|
||||
|
||||
#ifdef GZIO
|
||||
|
||||
#include <sys/zutil.h>
|
||||
|
||||
#define KERN_GZ_HDRLEN 10 /* gzip header length */
|
||||
#define KERN_GZ_TRAILERLEN 8 /* gzip trailer length */
|
||||
#define KERN_GZ_MAGIC1 0x1f /* first magic byte */
|
||||
#define KERN_GZ_MAGIC2 0x8b /* second magic byte */
|
||||
|
||||
MALLOC_DEFINE(M_GZIO, "gzio", "zlib state");
|
||||
|
||||
struct gzio_stream {
|
||||
uint8_t * gz_buffer; /* output buffer */
|
||||
size_t gz_bufsz; /* total buffer size */
|
||||
struct gz_stream {
|
||||
uint8_t *gz_buffer; /* output buffer */
|
||||
size_t gz_bufsz; /* output buffer size */
|
||||
off_t gz_off; /* offset into the output stream */
|
||||
enum gzio_mode gz_mode; /* stream mode */
|
||||
uint32_t gz_crc; /* stream CRC32 */
|
||||
gzio_cb gz_cb; /* output callback */
|
||||
void * gz_arg; /* private callback arg */
|
||||
z_stream gz_stream; /* zlib state */
|
||||
};
|
||||
|
||||
static void * gz_alloc(void *, u_int, u_int);
|
||||
static void gz_free(void *, void *);
|
||||
static int gz_write(struct gzio_stream *, void *, u_int, int);
|
||||
static void *gz_init(size_t maxiosize, int level);
|
||||
static void gz_reset(void *stream);
|
||||
static int gz_write(void *stream, void *data, size_t len, compressor_cb_t,
|
||||
void *);
|
||||
static void gz_fini(void *stream);
|
||||
|
||||
struct gzio_stream *
|
||||
gzio_init(gzio_cb cb, enum gzio_mode mode, size_t bufsz, int level, void *arg)
|
||||
static void *
|
||||
gz_alloc(void *arg __unused, u_int n, u_int sz)
|
||||
{
|
||||
struct gzio_stream *s;
|
||||
|
||||
/*
|
||||
* Memory for zlib state is allocated using M_NODUMP since it may be
|
||||
* used to compress a kernel dump, and we don't want zlib to attempt to
|
||||
* compress its own state.
|
||||
*/
|
||||
return (malloc(n * sz, M_COMPRESS, M_WAITOK | M_ZERO | M_NODUMP));
|
||||
}
|
||||
|
||||
static void
|
||||
gz_free(void *arg __unused, void *ptr)
|
||||
{
|
||||
|
||||
free(ptr, M_COMPRESS);
|
||||
}
|
||||
|
||||
static void *
|
||||
gz_init(size_t maxiosize, int level)
|
||||
{
|
||||
struct gz_stream *s;
|
||||
int error;
|
||||
|
||||
if (bufsz < KERN_GZ_HDRLEN)
|
||||
return (NULL);
|
||||
if (mode != GZIO_DEFLATE)
|
||||
return (NULL);
|
||||
|
||||
s = gz_alloc(NULL, 1, sizeof(*s));
|
||||
s->gz_bufsz = bufsz;
|
||||
s->gz_buffer = gz_alloc(NULL, 1, s->gz_bufsz);
|
||||
s->gz_mode = mode;
|
||||
s->gz_cb = cb;
|
||||
s->gz_arg = arg;
|
||||
s = gz_alloc(NULL, 1, roundup2(sizeof(*s), PAGE_SIZE));
|
||||
s->gz_buffer = gz_alloc(NULL, 1, maxiosize);
|
||||
s->gz_bufsz = maxiosize;
|
||||
|
||||
s->gz_stream.zalloc = gz_alloc;
|
||||
s->gz_stream.zfree = gz_free;
|
||||
@ -85,98 +119,57 @@ gzio_init(gzio_cb cb, enum gzio_mode mode, size_t bufsz, int level, void *arg)
|
||||
if (error != 0)
|
||||
goto fail;
|
||||
|
||||
gzio_reset(s);
|
||||
gz_reset(s);
|
||||
|
||||
return (s);
|
||||
|
||||
fail:
|
||||
gz_free(NULL, s->gz_buffer);
|
||||
gz_free(NULL, s);
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
void
|
||||
gzio_reset(struct gzio_stream *s)
|
||||
static void
|
||||
gz_reset(void *stream)
|
||||
{
|
||||
struct gz_stream *s;
|
||||
uint8_t *hdr;
|
||||
const size_t hdrlen = 10;
|
||||
|
||||
(void)deflateReset(&s->gz_stream);
|
||||
|
||||
s = stream;
|
||||
s->gz_off = 0;
|
||||
s->gz_crc = ~0U;
|
||||
|
||||
(void)deflateReset(&s->gz_stream);
|
||||
s->gz_stream.avail_out = s->gz_bufsz;
|
||||
s->gz_stream.next_out = s->gz_buffer;
|
||||
|
||||
/* Write the gzip header to the output buffer. */
|
||||
hdr = s->gz_buffer;
|
||||
memset(hdr, 0, KERN_GZ_HDRLEN);
|
||||
hdr[0] = KERN_GZ_MAGIC1;
|
||||
hdr[1] = KERN_GZ_MAGIC2;
|
||||
memset(hdr, 0, hdrlen);
|
||||
hdr[0] = 0x1f;
|
||||
hdr[1] = 0x8b;
|
||||
hdr[2] = Z_DEFLATED;
|
||||
hdr[9] = OS_CODE;
|
||||
s->gz_stream.next_out += KERN_GZ_HDRLEN;
|
||||
s->gz_stream.avail_out -= KERN_GZ_HDRLEN;
|
||||
}
|
||||
|
||||
int
|
||||
gzio_write(struct gzio_stream *s, void *data, u_int len)
|
||||
{
|
||||
|
||||
return (gz_write(s, data, len, Z_NO_FLUSH));
|
||||
}
|
||||
|
||||
int
|
||||
gzio_flush(struct gzio_stream *s)
|
||||
{
|
||||
|
||||
return (gz_write(s, NULL, 0, Z_FINISH));
|
||||
}
|
||||
|
||||
void
|
||||
gzio_fini(struct gzio_stream *s)
|
||||
{
|
||||
|
||||
(void)deflateEnd(&s->gz_stream);
|
||||
gz_free(NULL, s->gz_buffer);
|
||||
gz_free(NULL, s);
|
||||
}
|
||||
|
||||
static void *
|
||||
gz_alloc(void *arg __unused, u_int n, u_int sz)
|
||||
{
|
||||
|
||||
/*
|
||||
* Memory for zlib state is allocated using M_NODUMP since it may be
|
||||
* used to compress a kernel dump, and we don't want zlib to attempt to
|
||||
* compress its own state.
|
||||
*/
|
||||
return (malloc(n * sz, M_GZIO, M_WAITOK | M_ZERO | M_NODUMP));
|
||||
}
|
||||
|
||||
static void
|
||||
gz_free(void *arg __unused, void *ptr)
|
||||
{
|
||||
|
||||
free(ptr, M_GZIO);
|
||||
s->gz_stream.next_out += hdrlen;
|
||||
s->gz_stream.avail_out -= hdrlen;
|
||||
}
|
||||
|
||||
static int
|
||||
gz_write(struct gzio_stream *s, void *buf, u_int len, int zflag)
|
||||
gz_write(void *stream, void *data, size_t len, compressor_cb_t cb,
|
||||
void *arg)
|
||||
{
|
||||
uint8_t trailer[KERN_GZ_TRAILERLEN];
|
||||
struct gz_stream *s;
|
||||
uint8_t trailer[8];
|
||||
size_t room;
|
||||
int error, zerror;
|
||||
int error, zerror, zflag;
|
||||
|
||||
KASSERT(zflag == Z_FINISH || zflag == Z_NO_FLUSH,
|
||||
("unexpected flag %d", zflag));
|
||||
KASSERT(s->gz_mode == GZIO_DEFLATE,
|
||||
("invalid stream mode %d", s->gz_mode));
|
||||
s = stream;
|
||||
zflag = data == NULL ? Z_FINISH : Z_NO_FLUSH;
|
||||
|
||||
if (len > 0) {
|
||||
s->gz_stream.avail_in = len;
|
||||
s->gz_stream.next_in = buf;
|
||||
s->gz_crc = crc32_raw(buf, len, s->gz_crc);
|
||||
s->gz_stream.next_in = data;
|
||||
s->gz_crc = crc32_raw(data, len, s->gz_crc);
|
||||
} else
|
||||
s->gz_crc ^= ~0U;
|
||||
|
||||
@ -202,14 +195,13 @@ gz_write(struct gzio_stream *s, void *buf, u_int len, int zflag)
|
||||
((uint32_t *)trailer)[0] = s->gz_crc;
|
||||
((uint32_t *)trailer)[1] =
|
||||
s->gz_stream.total_in;
|
||||
room = MIN(KERN_GZ_TRAILERLEN,
|
||||
room = MIN(sizeof(trailer),
|
||||
s->gz_bufsz - len);
|
||||
memcpy(s->gz_buffer + len, trailer, room);
|
||||
len += room;
|
||||
}
|
||||
|
||||
error = s->gz_cb(s->gz_buffer, len, s->gz_off,
|
||||
s->gz_arg);
|
||||
error = cb(s->gz_buffer, len, s->gz_off, arg);
|
||||
if (error != 0)
|
||||
break;
|
||||
|
||||
@ -221,13 +213,103 @@ gz_write(struct gzio_stream *s, void *buf, u_int len, int zflag)
|
||||
* If we couldn't pack the trailer into the output
|
||||
* buffer, write it out now.
|
||||
*/
|
||||
if (zerror == Z_STREAM_END && room < KERN_GZ_TRAILERLEN)
|
||||
error = s->gz_cb(trailer + room,
|
||||
KERN_GZ_TRAILERLEN - room, s->gz_off,
|
||||
s->gz_arg);
|
||||
if (zerror == Z_STREAM_END && room < sizeof(trailer))
|
||||
error = cb(trailer + room,
|
||||
sizeof(trailer) - room, s->gz_off, arg);
|
||||
}
|
||||
} while (zerror != Z_STREAM_END &&
|
||||
(zflag == Z_FINISH || s->gz_stream.avail_in > 0));
|
||||
|
||||
return (error);
|
||||
}
|
||||
|
||||
static void
|
||||
gz_fini(void *stream)
|
||||
{
|
||||
struct gz_stream *s;
|
||||
|
||||
s = stream;
|
||||
(void)deflateEnd(&s->gz_stream);
|
||||
gz_free(NULL, s->gz_buffer);
|
||||
gz_free(NULL, s);
|
||||
}
|
||||
|
||||
struct compressor_methods gzip_methods = {
|
||||
.format = COMPRESS_GZIP,
|
||||
.init = gz_init,
|
||||
.reset = gz_reset,
|
||||
.write = gz_write,
|
||||
.fini = gz_fini,
|
||||
};
|
||||
DATA_SET(compressors, gzip_methods);
|
||||
|
||||
#endif /* GZIO */
|
||||
|
||||
bool
|
||||
compressor_avail(int format)
|
||||
{
|
||||
struct compressor_methods **iter;
|
||||
|
||||
SET_FOREACH(iter, compressors) {
|
||||
if ((*iter)->format == format)
|
||||
return (true);
|
||||
}
|
||||
return (false);
|
||||
}
|
||||
|
||||
struct compressor *
|
||||
compressor_init(compressor_cb_t cb, int format, size_t maxiosize, int level,
|
||||
void *arg)
|
||||
{
|
||||
struct compressor_methods **iter;
|
||||
struct compressor *s;
|
||||
void *priv;
|
||||
|
||||
SET_FOREACH(iter, compressors) {
|
||||
if ((*iter)->format == format)
|
||||
break;
|
||||
}
|
||||
if (iter == NULL)
|
||||
return (NULL);
|
||||
|
||||
priv = (*iter)->init(maxiosize, level);
|
||||
if (priv == NULL)
|
||||
return (NULL);
|
||||
|
||||
s = malloc(sizeof(*s), M_COMPRESS, M_WAITOK | M_ZERO);
|
||||
s->methods = (*iter);
|
||||
s->priv = priv;
|
||||
s->cb = cb;
|
||||
s->arg = arg;
|
||||
return (s);
|
||||
}
|
||||
|
||||
void
|
||||
compressor_reset(struct compressor *stream)
|
||||
{
|
||||
|
||||
stream->methods->reset(stream->priv);
|
||||
}
|
||||
|
||||
int
|
||||
compressor_write(struct compressor *stream, void *data, size_t len)
|
||||
{
|
||||
|
||||
return (stream->methods->write(stream->priv, data, len, stream->cb,
|
||||
stream->arg));
|
||||
}
|
||||
|
||||
int
|
||||
compressor_flush(struct compressor *stream)
|
||||
{
|
||||
|
||||
return (stream->methods->write(stream->priv, NULL, 0, stream->cb,
|
||||
stream->arg));
|
||||
}
|
||||
|
||||
void
|
||||
compressor_fini(struct compressor *stream)
|
||||
{
|
||||
|
||||
stream->methods->fini(stream->priv);
|
||||
}
|
@ -1,7 +1,7 @@
|
||||
/*-
|
||||
* SPDX-License-Identifier: BSD-2-Clause-FreeBSD
|
||||
*
|
||||
* Copyright (c) 2014 Mark Johnston <markj@FreeBSD.org>
|
||||
* Copyright (c) 2014, 2017 Mark Johnston <markj@FreeBSD.org>
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
@ -28,25 +28,26 @@
|
||||
* $FreeBSD$
|
||||
*/
|
||||
|
||||
#ifndef _SYS__GZIO_H_
|
||||
#define _SYS__GZIO_H_
|
||||
#ifndef _SYS__COMPRESSOR_H_
|
||||
#define _SYS__COMPRESSOR_H_
|
||||
|
||||
#ifdef _KERNEL
|
||||
|
||||
enum gzio_mode {
|
||||
GZIO_DEFLATE,
|
||||
};
|
||||
/* Supported formats. */
|
||||
#define COMPRESS_GZIP 1
|
||||
|
||||
typedef int (*gzio_cb)(void *, size_t, off_t, void *);
|
||||
typedef int (*compressor_cb_t)(void *, size_t, off_t, void *);
|
||||
|
||||
struct gzio_stream;
|
||||
struct compressor;
|
||||
|
||||
struct gzio_stream *gzio_init(gzio_cb cb, enum gzio_mode, size_t, int, void *);
|
||||
void gzio_reset(struct gzio_stream *);
|
||||
int gzio_write(struct gzio_stream *, void *, u_int);
|
||||
int gzio_flush(struct gzio_stream *);
|
||||
void gzio_fini(struct gzio_stream *);
|
||||
bool compressor_avail(int format);
|
||||
struct compressor *compressor_init(compressor_cb_t cb, int format,
|
||||
size_t maxiosize, int level, void *arg);
|
||||
void compressor_reset(struct compressor *stream);
|
||||
int compressor_write(struct compressor *stream, void *data,
|
||||
size_t len);
|
||||
int compressor_flush(struct compressor *stream);
|
||||
void compressor_fini(struct compressor *stream);
|
||||
|
||||
#endif /* _KERNEL */
|
||||
|
||||
#endif /* _SYS__GZIO_H_ */
|
||||
#endif /* _SYS__COMPRESSOR_H_ */
|
@ -339,8 +339,8 @@ struct dumperinfo {
|
||||
off_t mediasize; /* Space available in bytes. */
|
||||
void *blockbuf; /* Buffer for padding shorter dump blocks */
|
||||
off_t dumpoff; /* Offset of ongoing kernel dump. */
|
||||
struct kerneldumpcrypto *kdc; /* Kernel dump crypto. */
|
||||
struct kerneldumpgz *kdgz; /* Kernel dump compression. */
|
||||
struct kerneldumpcrypto *kdcrypto; /* Kernel dump crypto. */
|
||||
struct kerneldumpcomp *kdcomp; /* Kernel dump compression. */
|
||||
};
|
||||
|
||||
extern int dumping; /* system is dumping */
|
||||
|
@ -96,8 +96,6 @@ struct sysentvec;
|
||||
struct thread;
|
||||
struct vmspace;
|
||||
|
||||
#define IMGACT_CORE_COMPRESS 0x01
|
||||
|
||||
int exec_alloc_args(struct image_args *);
|
||||
int exec_check_permissions(struct image_params *);
|
||||
register_t *exec_copyout_strings(struct image_params *);
|
||||
|
Loading…
x
Reference in New Issue
Block a user