svn commit: r327707 - in head: share/man/man5 sys/conf sys/ddb sys/kern sys/sys

Mark Johnston markj at FreeBSD.org
Mon Jan 8 21:27:43 UTC 2018


Author: markj
Date: Mon Jan  8 21:27:41 2018
New Revision: 327707
URL: https://svnweb.freebsd.org/changeset/base/327707

Log:
  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

Added:
  head/sys/kern/subr_compressor.c
     - copied, changed from r327706, head/sys/kern/kern_gzio.c
  head/sys/sys/compressor.h
     - copied, changed from r327706, head/sys/sys/gzio.h
Deleted:
  head/sys/kern/kern_gzio.c
  head/sys/sys/gzio.h
Modified:
  head/share/man/man5/core.5
  head/sys/conf/files
  head/sys/ddb/db_textdump.c
  head/sys/kern/imgact_elf.c
  head/sys/kern/kern_shutdown.c
  head/sys/kern/kern_sig.c
  head/sys/sys/conf.h
  head/sys/sys/imgact.h

Modified: head/share/man/man5/core.5
==============================================================================
--- head/share/man/man5/core.5	Mon Jan  8 20:14:16 2018	(r327706)
+++ head/share/man/man5/core.5	Mon Jan  8 21:27:41 2018	(r327707)
@@ -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 ,

Modified: head/sys/conf/files
==============================================================================
--- head/sys/conf/files	Mon Jan  8 20:14:16 2018	(r327706)
+++ head/sys/conf/files	Mon Jan  8 21:27:41 2018	(r327707)
@@ -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

Modified: head/sys/ddb/db_textdump.c
==============================================================================
--- head/sys/ddb/db_textdump.c	Mon Jan  8 20:14:16 2018	(r327706)
+++ head/sys/ddb/db_textdump.c	Mon Jan  8 21:27:41 2018	(r327707)
@@ -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;
 }
 
 /*-

Modified: head/sys/kern/imgact_elf.c
==============================================================================
--- head/sys/kern/imgact_elf.c	Mon Jan  8 20:14:16 2018	(r327706)
+++ head/sys/kern/imgact_elf.c	Mon Jan  8 21:27:41 2018	(r327707)
@@ -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 *
 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, 
 		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, 
 }
 
 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, stru
 {
 	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, in
 	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, 
 	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(&notelst);
@@ -1391,7 +1382,7 @@ __elfN(coredump)(struct thread *td, struct vnode *vp, 
 	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, 
 		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, &params);
-		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, &params);
+		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, 
 			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, 
 	}
 
 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(&notelst)) != NULL) {
 		TAILQ_REMOVE(&notelst, ninfo, link);
 		free(ninfo, M_TEMP);

Modified: head/sys/kern/kern_shutdown.c
==============================================================================
--- head/sys/kern/kern_shutdown.c	Mon Jan  8 20:14:16 2018	(r327706)
+++ head/sys/kern/kern_shutdown.c	Mon Jan  8 21:27:41 2018	(r327707)
@@ -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 kerneldumpcr
 }
 #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,
 		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,
 	}
 
 	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,
 			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 *virt
 	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
 		}
 		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 kerneldumphea
 	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 kerneldumphea
 	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 kerneldumphea
 			    2 * di->blocksize - keysize;
 			kdh->dumpextent = htod64(dumpextent);
 		} else
-#endif
 			return (E2BIG);
 	}
 
@@ -1333,7 +1317,7 @@ _dump_append(struct dumperinfo *di, void *virtual, vm_
 	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 kerneldumphe
 	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 kerneldumphe
 		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 k
 	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 k
 		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);
 }
 

Modified: head/sys/kern/kern_sig.c
==============================================================================
--- head/sys/kern/kern_sig.c	Mon Jan  8 20:14:16 2018	(r327706)
+++ head/sys/kern/kern_sig.c	Mon Jan  8 21:27:41 2018	(r327707)
@@ -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,18 +3255,31 @@ SYSCTL_PROC(_debug, OID_AUTO, ncores, CTLTYPE_INT|CTLF
 
 #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, 
 	}
 	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;
 	}

Copied and modified: head/sys/kern/subr_compressor.c (from r327706, head/sys/kern/kern_gzio.c)
==============================================================================
--- head/sys/kern/kern_gzio.c	Mon Jan  8 20:14:16 2018	(r327706, copy source)
+++ head/sys/kern/subr_compressor.c	Mon Jan  8 21:27:41 2018	(r327707)
@@ -1,6 +1,8 @@
 /*-
- * Copyright (c) 2014 Mark Johnston <markj at FreeBSD.org>
+ * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
  *
+ * Copyright (c) 2014, 2017 Mark Johnston <markj at FreeBSD.org>
+ *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions are
  * met:
@@ -24,56 +26,88 @@
  * 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>
-#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_COMPRESS, "compressor", "kernel compression subroutines");
 
-MALLOC_DEFINE(M_GZIO, "gzio", "zlib state");
+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 gzio_stream {
-	uint8_t *	gz_buffer;	/* output buffer */
-	size_t		gz_bufsz;	/* total buffer size */
+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>
+
+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;
-	int error;
 
-	if (bufsz < KERN_GZ_HDRLEN)
-		return (NULL);
-	if (mode != GZIO_DEFLATE)
-		return (NULL);
+	/*
+	 * 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));
+}
 
-	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;
+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;
+
+	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;
 	s->gz_stream.opaque = NULL;
@@ -85,98 +119,57 @@ gzio_init(gzio_cb cb, enum gzio_mode mode, size_t bufs
 	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;
+	s->gz_stream.next_out += hdrlen;
+	s->gz_stream.avail_out -= 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);
-}
-
 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, 
 				((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, 
 			 * 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) {

*** DIFF OUTPUT TRUNCATED AT 1000 LINES ***


More information about the svn-src-all mailing list