Page MenuHomeFreeBSD

D11723.id31151.diff
No OneTemporary

D11723.id31151.diff

Index: etc/defaults/rc.conf
===================================================================
--- etc/defaults/rc.conf
+++ etc/defaults/rc.conf
@@ -598,6 +598,8 @@
dumpdir="/var/crash" # Directory where crash dumps are to be stored
dumppubkey="" # Public key for encrypted kernel crash dumps.
# See dumpon(8) for more details.
+dumpcompress="NO" # Configure the kernel to compress crash dumps before
+ # writing them to the dump device.
savecore_enable="YES" # Extract core from dump devices if any
savecore_flags="-m 10" # Used if dumpdev is enabled above, and present.
# By default, only the 10 most recent kernel dumps
Index: etc/rc.d/dumpon
===================================================================
--- etc/rc.d/dumpon
+++ etc/rc.d/dumpon
@@ -16,11 +16,15 @@
dumpon_try()
{
+ local flags
+
if [ -n "${dumppubkey}" ]; then
- /sbin/dumpon -k "${dumppubkey}" "${1}"
- else
- /sbin/dumpon "${1}"
+ flags="${flags} -k ${dumppubkey}"
+ fi
+ if checkyesno dumpcompress; then
+ flags="${flags} -c"
fi
+ /sbin/dumpon ${flags} "${1}"
if [ $? -eq 0 ]; then
# Make a symlink in devfs for savecore
ln -fs "${1}" /dev/dumpdev
Index: sbin/dumpon/dumpon.8
===================================================================
--- sbin/dumpon/dumpon.8
+++ sbin/dumpon/dumpon.8
@@ -37,6 +37,7 @@
.Sh SYNOPSIS
.Nm
.Op Fl v
+.Op Fl c
.Op Fl k Ar public_key_file
.Ar special_file
.Nm
@@ -85,6 +86,15 @@
variable.
.Pp
The
+.Op c
+option configures the kernel to write a compressed dump to the dump device.
+This reduces the amount of space required for the dump.
+When compression is enabled, the
+.Nm
+utility will not verify that the dump device is sufficiently large for a full
+dump.
+.Pp
+The
.Op Fl k Ar public_key_file
flag causes
.Nm
Index: sbin/dumpon/dumpon.c
===================================================================
--- sbin/dumpon/dumpon.c
+++ sbin/dumpon/dumpon.c
@@ -71,7 +71,7 @@
usage(void)
{
fprintf(stderr, "%s\n%s\n%s\n",
- "usage: dumpon [-v] [-k public_key_file] special_file",
+ "usage: dumpon [-v] [-c] [-k public_key_file] special_file",
" dumpon [-v] off",
" dumpon [-v] -l");
exit(EX_USAGE);
@@ -190,12 +190,16 @@
int ch;
int i, fd;
int do_listdumpdev = 0;
- bool enable;
+ bool compress, enable;
+ compress = false;
pubkeyfile = NULL;
- while ((ch = getopt(argc, argv, "k:lv")) != -1)
+ while ((ch = getopt(argc, argv, "ck:lv")) != -1)
switch((char)ch) {
+ case 'c':
+ compress = true;
+ break;
case 'k':
pubkeyfile = optarg;
break;
@@ -247,9 +251,11 @@
fd = open(dumpdev, O_RDONLY);
if (fd < 0)
err(EX_OSFILE, "%s", dumpdev);
- check_size(fd, dumpdev);
- bzero(&kda, sizeof(kda));
+ if (!compress)
+ check_size(fd, dumpdev);
+
+ bzero(&kda, sizeof(kda));
kda.kda_enable = 0;
i = ioctl(fd, DIOCSKERNELDUMP, &kda);
explicit_bzero(&kda, sizeof(kda));
@@ -260,6 +266,7 @@
#endif
kda.kda_enable = 1;
+ kda.kda_compress = compress;
i = ioctl(fd, DIOCSKERNELDUMP, &kda);
explicit_bzero(kda.kda_encryptedkey, kda.kda_encryptedkeysize);
free(kda.kda_encryptedkey);
Index: sbin/savecore/savecore.c
===================================================================
--- sbin/savecore/savecore.c
+++ sbin/savecore/savecore.c
@@ -121,6 +121,9 @@
(long long)dumplen);
xo_emit_h(xo, "{P: }{Lwc:Blocksize}{:blocksize/%d}\n",
dtoh32(h->blocksize));
+ xo_emit_h(xo, "{P: }{Lwc:Compression}{:compression/%s}\n",
+ h->compression == KERNELDUMP_COMPRESSION_DEFLATE ?
+ "DEFLATE" : "none");
t = dtoh64(h->dumptime);
xo_emit_h(xo, "{P: }{Lwc:Dumptime}{:dumptime/%s}", ctime(&t));
@@ -357,7 +360,7 @@
#define BLOCKMASK (~(BLOCKSIZE-1))
static int
-DoRegularFile(int fd, bool isencrypted, off_t dumpsize, char *buf,
+DoRegularFile(int fd, off_t dumpsize, u_int sectorsize, bool sparse, char *buf,
const char *device, const char *filename, FILE *fp)
{
int he, hs, nr, nw, wl;
@@ -370,8 +373,8 @@
wl = BUFFERSIZE;
if (wl > dumpsize)
wl = dumpsize;
- nr = read(fd, buf, wl);
- if (nr != wl) {
+ nr = read(fd, buf, roundup(wl, sectorsize));
+ if (nr != (int)roundup(wl, sectorsize)) {
if (nr == 0)
syslog(LOG_WARNING,
"WARNING: EOF on dump device");
@@ -380,7 +383,7 @@
nerr++;
return (-1);
}
- if (compress || isencrypted) {
+ if (!sparse) {
nw = fwrite(buf, 1, wl, fp);
} else {
for (nw = 0; nw < nr; nw = he) {
@@ -506,15 +509,14 @@
char *temp = NULL;
struct kerneldumpheader kdhf, kdhl;
uint8_t *dumpkey;
- off_t mediasize, dumpsize, firsthd, lasthd;
+ off_t mediasize, dumpextent, dumplength, firsthd, lasthd;
FILE *info, *fp;
mode_t oumask;
int fd, fdinfo, error;
int bounds, status;
u_int sectorsize, xostyle;
- int istextdump;
uint32_t dumpkeysize;
- bool isencrypted, ret;
+ bool iscompressed, isencrypted, istextdump, ret;
bounds = getbounds();
dumpkey = NULL;
@@ -582,12 +584,12 @@
goto closefd;
}
memcpy(&kdhl, temp, sizeof(kdhl));
- istextdump = 0;
+ iscompressed = istextdump = false;
if (compare_magic(&kdhl, TEXTDUMPMAGIC)) {
if (verbose)
printf("textdump magic on last dump header on %s\n",
device);
- istextdump = 1;
+ istextdump = true;
if (dtoh32(kdhl.version) != KERNELDUMP_TEXT_VERSION) {
syslog(LOG_ERR,
"unknown version (%d) in last dump header on %s",
@@ -607,6 +609,11 @@
if (force == 0)
goto closefd;
}
+ if (kdhl.compression == KERNELDUMP_COMPRESSION_DEFLATE) {
+ if (compress && verbose)
+ printf("dump is already compressed\n");
+ iscompressed = true;
+ }
} else {
if (verbose)
printf("magic mismatch on last dump header on %s\n",
@@ -619,8 +626,7 @@
if (compare_magic(&kdhl, KERNELDUMPMAGIC_CLEARED)) {
if (verbose)
printf("forcing magic on %s\n", device);
- memcpy(kdhl.magic, KERNELDUMPMAGIC,
- sizeof kdhl.magic);
+ memcpy(kdhl.magic, KERNELDUMPMAGIC, sizeof(kdhl.magic));
} else {
syslog(LOG_ERR, "unable to force dump - bad magic");
goto closefd;
@@ -648,9 +654,10 @@
if (force == 0)
goto closefd;
}
- dumpsize = dtoh64(kdhl.dumplength);
+ dumpextent = dtoh64(kdhl.dumpextent);
+ dumplength = dtoh64(kdhl.dumplength);
dumpkeysize = dtoh32(kdhl.dumpkeysize);
- firsthd = lasthd - dumpsize - sectorsize - dumpkeysize;
+ firsthd = lasthd - dumpextent - sectorsize - dumpkeysize;
if (lseek(fd, firsthd, SEEK_SET) != firsthd ||
read(fd, temp, sectorsize) != (ssize_t)sectorsize) {
syslog(LOG_ERR,
@@ -696,7 +703,7 @@
if (verbose)
printf("Checking for available free space\n");
- if (!check_space(savedir, dumpsize, bounds)) {
+ if (!check_space(savedir, dumplength, bounds)) {
nerr++;
goto closefd;
}
@@ -724,6 +731,10 @@
istextdump ? "textdump.tar" :
(isencrypted ? "vmcore_encrypted" : "vmcore"), bounds);
fp = zopen(corename, "w");
+ } else if (iscompressed && !isencrypted) {
+ /* We compress before encrypting. */
+ snprintf(corename, sizeof(corename), "vmcore.%d.gz", bounds);
+ fp = fopen(corename, "w");
} else {
snprintf(corename, sizeof(corename), "%s.%d",
istextdump ? "textdump.tar" :
@@ -792,11 +803,12 @@
savedir, corename);
if (istextdump) {
- if (DoTextdumpFile(fd, dumpsize, lasthd, buf, device,
+ if (DoTextdumpFile(fd, dumplength, lasthd, buf, device,
corename, fp) < 0)
goto closeall;
} else {
- if (DoRegularFile(fd, isencrypted, dumpsize, buf, device,
+ if (DoRegularFile(fd, dumplength, sectorsize,
+ !(compress || iscompressed || isencrypted), buf, device,
corename, fp) < 0) {
goto closeall;
}
@@ -822,7 +834,7 @@
"key.last");
}
}
- if (compress) {
+ if (compress || (iscompressed && !isencrypted)) {
snprintf(linkname, sizeof(linkname), "%s.last.gz",
istextdump ? "textdump.tar" :
(isencrypted ? "vmcore_encrypted" : "vmcore"));
Index: share/man/man5/rc.conf.5
===================================================================
--- share/man/man5/rc.conf.5
+++ share/man/man5/rc.conf.5
@@ -3409,6 +3409,16 @@
See
.Xr dumpon 8
for more details.
+.It Va dumpcompress
+Set to
+.Dq Li YES
+to enable compression of crash dumps before they are written to the
+dump device.
+This allows larger crash dumps to be saved to the dump device, and
+speeds up recovery of crash dumps following a reboot.
+This feature depends on the
+.Dv GZIO
+kernel option.
.It Va savecore_enable
.Pq Vt bool
If set to
Index: sys/dev/null/null.c
===================================================================
--- sys/dev/null/null.c
+++ sys/dev/null/null.c
@@ -114,7 +114,7 @@
case DIOCSKERNELDUMP_FREEBSD11:
#endif
case DIOCSKERNELDUMP:
- error = set_dumper(NULL, NULL, td, 0, NULL, 0, NULL);
+ error = set_dumper(NULL, NULL, td, false, 0, NULL, 0, NULL);
break;
case FIONBIO:
break;
Index: sys/geom/geom_dev.c
===================================================================
--- sys/geom/geom_dev.c
+++ sys/geom/geom_dev.c
@@ -138,7 +138,7 @@
int error, len;
if (dev == NULL || kda == NULL)
- return (set_dumper(NULL, NULL, td, 0, NULL, 0, NULL));
+ return (set_dumper(NULL, NULL, td, false, 0, NULL, 0, NULL));
cp = dev->si_drv2;
len = sizeof(kd);
@@ -148,8 +148,9 @@
if (error != 0)
return (error);
- error = set_dumper(&kd.di, devtoname(dev), td, kda->kda_encryption,
- kda->kda_key, kda->kda_encryptedkeysize, kda->kda_encryptedkey);
+ error = set_dumper(&kd.di, devtoname(dev), td, kda->kda_compress,
+ kda->kda_encryption, kda->kda_key, kda->kda_encryptedkeysize,
+ kda->kda_encryptedkey);
if (error == 0)
dev->si_flags |= SI_DUMPDEV;
@@ -817,7 +818,8 @@
/* Reset any dump-area set on this device */
if (dev->si_flags & SI_DUMPDEV)
- (void)set_dumper(NULL, NULL, curthread, 0, NULL, 0, NULL);
+ (void)set_dumper(NULL, NULL, curthread, false, 0, NULL, 0,
+ NULL);
/* Destroy the struct cdev *so we get no more requests */
destroy_dev_sched_cb(dev, g_dev_callback, cp);
Index: sys/kern/kern_shutdown.c
===================================================================
--- sys/kern/kern_shutdown.c
+++ sys/kern/kern_shutdown.c
@@ -39,6 +39,7 @@
#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,6 +53,7 @@
#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>
@@ -162,6 +164,20 @@
};
#endif
+#ifdef GZIO
+static struct gzio_stream *dumpgzs;
+static uint8_t *gzbuffer;
+
+static int kerneldump_gz_configure(struct dumperinfo *di);
+static void kerneldump_gz_disable(void);
+static int kerneldump_gz_write_cb(void *cb, size_t len, off_t off, void *arg);
+
+static int kerneldump_gz_level = 6;
+SYSCTL_INT(_kern, OID_AUTO, kerneldump_gz_level, CTLFLAG_RW,
+ &kerneldump_gz_level, 0,
+ "Kernel crash dump compression level");
+#endif /* GZIO */
+
/*
* Variable panicstr contains argument to first call to panic; used as flag
* to indicate that the kernel has already called panic.
@@ -858,6 +874,9 @@
SYSCTL_STRING(_kern_shutdown, OID_AUTO, dumpdevname, CTLFLAG_RD,
dumpdevname, 0, "Device for kernel dumps");
+static int _dump_write(struct dumperinfo *di, void *virtual,
+ vm_offset_t physical, size_t length);
+
#ifdef EKCD
static struct kerneldumpcrypto *
kerneldumpcrypto_create(size_t blocksize, uint8_t encryption,
@@ -948,11 +967,37 @@
}
#endif /* EKCD */
+#ifdef GZIO
+static int
+kerneldump_gz_configure(struct dumperinfo *di)
+{
+
+ dumpgzs = gzio_init(kerneldump_gz_write_cb, GZIO_DEFLATE, di->maxiosize,
+ kerneldump_gz_level, di);
+ if (dumpgzs == NULL)
+ return (EINVAL);
+ gzbuffer = malloc(di->maxiosize, M_DUMPER, M_WAITOK | M_NODUMP);
+ return (0);
+}
+
+static void
+kerneldump_gz_disable(void)
+{
+
+ if (dumpgzs != NULL) {
+ gzio_fini(dumpgzs);
+ dumpgzs = NULL;
+ }
+ free(gzbuffer, M_DUMPER);
+ gzbuffer = NULL;
+}
+#endif /* GZIO */
+
/* Registration of dumpers */
int
set_dumper(struct dumperinfo *di, const char *devname, struct thread *td,
- uint8_t encryption, const uint8_t *key, uint32_t encryptedkeysize,
- const uint8_t *encryptedkey)
+ bool compress, uint8_t encryption, const uint8_t *key,
+ uint32_t encryptedkeysize, const uint8_t *encryptedkey)
{
size_t wantcopy;
int error;
@@ -988,7 +1033,26 @@
wantcopy = strlcpy(dumpdevname, devname, sizeof(dumpdevname));
if (wantcopy >= sizeof(dumpdevname)) {
printf("set_dumper: device name truncated from '%s' -> '%s'\n",
- devname, dumpdevname);
+ devname, dumpdevname);
+ }
+
+ if (compress) {
+#ifdef GZIO
+ /*
+ * We currently can't support simultaneous encryption and
+ * compression.
+ */
+ if (encryption != KERNELDUMP_ENC_NONE) {
+ error = EOPNOTSUPP;
+ goto cleanup;
+ }
+ error = kerneldump_gz_configure(&dumper);
+ if (error != 0)
+ goto cleanup;
+#else
+ error = EOPNOTSUPP;
+ goto cleanup;
+#endif
}
dumper.blockbuf = malloc(di->blocksize, M_DUMPER, M_WAITOK | M_ZERO);
@@ -1001,6 +1065,11 @@
free(dumper.kdc, M_EKCD);
}
#endif
+
+#ifdef GZIO
+ kerneldump_gz_disable();
+#endif
+
if (dumper.blockbuf != NULL) {
explicit_bzero(dumper.blockbuf, dumper.blocksize);
free(dumper.blockbuf, M_DUMPER);
@@ -1104,6 +1173,41 @@
}
#endif /* EKCD */
+#ifdef GZIO
+static int
+kerneldump_gz_write_cb(void *base, size_t length, off_t offset, void *arg)
+{
+ struct dumperinfo *di;
+ size_t rlength;
+ int error;
+
+ di = arg;
+
+ if (length % di->blocksize != 0) {
+ /*
+ * This must be the final write after flushing the compression
+ * stream. Write as many full blocks as possible and stash the
+ * residual data in the dumper's block buffer. It will be
+ * padded and written in dump_finish().
+ */
+ rlength = rounddown(length, di->blocksize);
+ if (rlength != 0) {
+ error = _dump_write(di, base, 0, rlength);
+ if (error != 0)
+ return (error);
+ }
+ di->resid = length - rlength;
+ memmove(di->blockbuf, (uint8_t *)base + rlength, di->resid);
+ return (EAGAIN);
+ }
+ return (_dump_write(di, base, 0, length));
+}
+#endif /* GZIO */
+
+/*
+ * Write a kerneldumpheader at the specified offset. The header structure is 512
+ * bytes in size, but we must pad to the device sector size.
+ */
static int
dump_write_header(struct dumperinfo *di, struct kerneldumpheader *kdh,
vm_offset_t physical, off_t offset)
@@ -1133,19 +1237,17 @@
#define SIZEOF_METADATA (64 * 1024)
/*
- * Do some preliminary setup for a kernel dump: verify that we have enough space
- * on the dump device, write the leading header, and optionally write the crypto
- * key.
+ * Do some preliminary setup for a kernel dump: initialize state for encryption,
+ * if requested, and make sure that we have enough space on the dump device.
*/
int
dump_start(struct dumperinfo *di, struct kerneldumpheader *kdh)
{
- uint64_t dumpsize;
+ uint64_t dumpextent;
uint32_t keysize;
- int error;
#ifdef EKCD
- error = kerneldumpcrypto_init(di->kdc);
+ int error = kerneldumpcrypto_init(di->kdc);
if (error != 0)
return (error);
keysize = kerneldumpcrypto_dumpkeysize(di->kdc);
@@ -1153,33 +1255,40 @@
keysize = 0;
#endif
- dumpsize = dtoh64(kdh->dumplength) + 2 * di->blocksize + keysize;
- if (di->mediasize < SIZEOF_METADATA + dumpsize)
- return (ENOSPC);
+ dumpextent = dtoh64(kdh->dumpextent);
+ if (di->mediasize < SIZEOF_METADATA + dumpextent + 2 * di->blocksize +
+ keysize) {
+#ifdef GZIO
+ if (dumpgzs != NULL) {
+ /*
+ * We don't yet know how much space the compressed dump
+ * will occupy, so try to use the whole swap partition
+ * (minus the first 64KB) in the hope that the
+ * compressed dump will fit. If that doesn't turn out to
+ * be enouch, the bounds checking in dump_raw_write()
+ * will catch us and cause the dump to fail.
+ */
+ dumpextent = di->mediasize - SIZEOF_METADATA -
+ 2 * di->blocksize - keysize;
+ kdh->dumpextent = htod64(dumpextent);
+ } else
+#endif
+ return (ENOSPC);
+ }
- dumpoff = di->mediaoffset + di->mediasize - dumpsize;
+ /*
+ * Set the initial offset at which to begin writing the dump.
+ * This excludes the leading header, and the (optional) key.
+ */
+ dumpoff = di->mediaoffset + di->mediasize - dumpextent - di->blocksize;
- error = dump_write_header(di, kdh, 0, dumpoff);
- if (error != 0)
- return (error);
- dumpoff += di->blocksize;
-
-#ifdef EKCD
- error = dump_write_key(di, 0, dumpoff);
- if (error != 0)
- return (error);
- dumpoff += keysize;
-#endif
+ di->resid = 0;
return (0);
}
-/*
- * Write the trailing kernel dump header and signal to the lower layers that the
- * dump has completed.
- */
-int
-dump_write(struct dumperinfo *di, void *virtual, vm_offset_t physical,
+static int
+_dump_write(struct dumperinfo *di, void *virtual, vm_offset_t physical,
size_t length)
{
int error;
@@ -1196,6 +1305,31 @@
return (error);
}
+/*
+ * Write to the dump device starting at dumpoff. When compression is enabled,
+ * writes to the device will be performed using a callback that gets invoked
+ * when the compression stream's output buffer is full.
+ */
+int
+dump_write(struct dumperinfo *di, void *virtual, vm_offset_t physical,
+ size_t length)
+{
+
+#ifdef GZIO
+ if (dumpgzs != NULL) {
+ /* Bounce through a buffer to avoid gzip CRC errors. */
+ if (length > di->maxiosize)
+ return (EINVAL);
+ memmove(gzbuffer, virtual, length);
+ return (gzio_write(dumpgzs, gzbuffer, length));
+ }
+#endif
+ return (_dump_write(di, virtual, physical, length));
+}
+
+/*
+ * Write to the dump device at the specified offset.
+ */
int
dump_raw_write(struct dumperinfo *di, void *virtual, vm_offset_t physical,
off_t offset, size_t length)
@@ -1209,12 +1343,70 @@
return (di->dumper(di->priv, virtual, physical, offset, length));
}
+/*
+ * Perform kernel dump finalization: flush the compression stream, if necessary,
+ * write the leading and trailing kernel dump headers now that we know the true
+ * length of the dump, and optionally write the encryption key following the
+ * leading header.
+ */
int
dump_finish(struct dumperinfo *di, struct kerneldumpheader *kdh)
{
+ uint64_t extent;
+ uint32_t keysize;
int error;
- error = dump_write_header(di, kdh, 0, dumpoff);
+ extent = dtoh64(kdh->dumpextent);
+
+#ifdef EKCD
+ keysize = kerneldumpcrypto_dumpkeysize(di->kdc);
+#else
+ keysize = 0;
+#endif
+
+#ifdef GZIO
+ if (dumpgzs != NULL) {
+ error = gzio_flush(dumpgzs);
+ if (error == EAGAIN) {
+ /* We have residual data in di->blockbuf. */
+ error = dump_raw_write(di, di->blockbuf, 0, dumpoff,
+ di->blocksize);
+ dumpoff += di->resid;
+ di->resid = 0;
+ }
+ if (error != 0)
+ return (error);
+
+ /*
+ * We now know the size of the compressed dump, so update the
+ * header accordingly and recompute parity.
+ */
+ kdh->dumplength = htod64(dumpoff -
+ (di->mediaoffset + di->mediasize - extent - di->blocksize));
+ kdh->parity = 0;
+ kdh->parity = kerneldump_parity(kdh);
+ }
+#endif
+
+ /*
+ * Write kerneldump headers at the beginning and end of the dump extent.
+ * Write the key after the leading header.
+ */
+ error = dump_write_header(di, kdh, 0,
+ di->mediaoffset + di->mediasize - 2 * di->blocksize - extent -
+ keysize);
+ if (error != 0)
+ return (error);
+
+#ifdef EKCD
+ error = dump_write_key(di, 0,
+ di->mediaoffset + di->mediasize - di->blocksize - extent - keysize);
+ if (error != 0)
+ return (error);
+#endif
+
+ error = dump_write_header(di, kdh, 0,
+ di->mediaoffset + di->mediasize - di->blocksize);
if (error != 0)
return (error);
@@ -1234,6 +1426,7 @@
kdh->version = htod32(KERNELDUMPVERSION);
kdh->architectureversion = htod32(archver);
kdh->dumplength = htod64(dumplen);
+ kdh->dumpextent = kdh->dumplength;
kdh->dumptime = htod64(time_second);
#ifdef EKCD
kdh->dumpkeysize = htod32(kerneldumpcrypto_dumpkeysize(dumper.kdc));
@@ -1247,6 +1440,10 @@
kdh->versionstring[dstsize - 2] = '\n';
if (panicstr != NULL)
strlcpy(kdh->panicstring, panicstr, sizeof(kdh->panicstring));
+#ifdef GZIO
+ if (dumpgzs != NULL)
+ kdh->compression = KERNELDUMP_COMPRESSION_DEFLATE;
+#endif
kdh->parity = kerneldump_parity(kdh);
}
Index: sys/sys/conf.h
===================================================================
--- sys/sys/conf.h
+++ sys/sys/conf.h
@@ -336,12 +336,13 @@
off_t mediaoffset; /* Initial offset in bytes. */
off_t mediasize; /* Space available in bytes. */
void *blockbuf; /* Buffer for padding shorter dump blocks */
+ size_t resid; /* Residual data from compression stream. */
struct kerneldumpcrypto *kdc; /* Kernel dump crypto. */
};
int set_dumper(struct dumperinfo *di, const char *devname, struct thread *td,
- uint8_t encrypt, const uint8_t *key, uint32_t encryptedkeysize,
- const uint8_t *encryptedkey);
+ bool compress, uint8_t encrypt, const uint8_t *key,
+ uint32_t encryptedkeysize, const uint8_t *encryptedkey);
int dump_start(struct dumperinfo *di, struct kerneldumpheader *kdh);
int dump_finish(struct dumperinfo *di, struct kerneldumpheader *kdh);
int dump_write(struct dumperinfo *, void *, vm_offset_t, size_t);
Index: sys/sys/disk.h
===================================================================
--- sys/sys/disk.h
+++ sys/sys/disk.h
@@ -142,6 +142,7 @@
struct diocskerneldump_arg {
uint8_t kda_enable;
+ uint8_t kda_compress;
uint8_t kda_encryption;
uint8_t kda_key[KERNELDUMP_KEY_MAX_SIZE];
uint32_t kda_encryptedkeysize;
Index: sys/sys/kerneldump.h
===================================================================
--- sys/sys/kerneldump.h
+++ sys/sys/kerneldump.h
@@ -75,8 +75,8 @@
#define KERNELDUMPMAGIC_CLEARED "Cleared Kernel Dump"
char architecture[12];
uint32_t version;
-#define KERNELDUMPVERSION 2
-#define KERNELDUMP_TEXT_VERSION 2
+#define KERNELDUMPVERSION 3
+#define KERNELDUMP_TEXT_VERSION 3
uint32_t architectureversion;
#define KERNELDUMP_AARCH64_VERSION 1
#define KERNELDUMP_AMD64_VERSION 2
@@ -86,13 +86,17 @@
#define KERNELDUMP_POWERPC_VERSION 1
#define KERNELDUMP_RISCV_VERSION 1
#define KERNELDUMP_SPARC64_VERSION 1
- uint64_t dumplength; /* excl headers */
+ uint64_t dumplength; /* excl headers; compressed */
+ uint64_t dumpextent; /* space between headers */
uint64_t dumptime;
uint32_t dumpkeysize;
uint32_t blocksize;
+ uint8_t compression;
+#define KERNELDUMP_COMPRESSION_UNCOMPRESSED 0
+#define KERNELDUMP_COMPRESSION_DEFLATE 1
char hostname[64];
char versionstring[192];
- char panicstring[188];
+ char panicstring[179];
uint32_t parity;
};

File Metadata

Mime Type
text/plain
Expires
Mon, Apr 13, 7:33 AM (3 h, 57 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
31367238
Default Alt Text
D11723.id31151.diff (22 KB)

Event Timeline