Page MenuHomeFreeBSD

D19996.id56625.diff
No OneTemporary

D19996.id56625.diff

Index: sbin/dumpon/dumpon.8
===================================================================
--- sbin/dumpon/dumpon.8
+++ sbin/dumpon/dumpon.8
@@ -28,7 +28,7 @@
.\" From: @(#)swapon.8 8.1 (Berkeley) 6/5/93
.\" $FreeBSD$
.\"
-.Dd November 17, 2018
+.Dd April 20, 2019
.Dt DUMPON 8
.Os
.Sh NAME
@@ -36,12 +36,16 @@
.Nd "specify a device for crash dumps"
.Sh SYNOPSIS
.Nm
+.Op Fl i Ar index
+.Op Fl r
.Op Fl v
.Op Fl k Ar pubkey
.Op Fl Z
.Op Fl z
.Ar device
.Nm
+.Op Fl i Ar index
+.Op Fl r
.Op Fl v
.Op Fl k Ar pubkey
.Op Fl Z
@@ -72,8 +76,35 @@
.Va dumpon_flags .
For more information on this usage, see
.Xr rc.conf 5 .
+.Pp
+Starting in
+.Fx 13.0 ,
+.Nm
+can configure a series of fallback dump devices.
+For example, an administrator may prefer netdump by default, but if the netdump
+service cannot be reached or some other failure occurs, they might choose a
+local disk dump as a second choice option.
.Ss General options
.Bl -tag -width _k_pubkey
+.It Fl i Ar index
+Insert the specified dump configuration into the prioritized fallback dump
+device list at the specified index, starting at zero.
+.Pp
+If
+.Fl i
+is not specified, the configured dump device is appended to the prioritized
+list.
+.It Fl r
+Remove the specified dump device configuration or configurations from the
+fallback dump device list rather than inserting or appending it.
+In contrast,
+.Do
+.Nm
+off
+.Dc
+removes all configured devices.
+Conflicts with
+.Fl i .
.It Fl k Ar pubkey
Configure encrypted kernel dumps.
.Pp
@@ -96,7 +127,7 @@
.Va pubkey
file should be a PEM-formatted RSA key of at least 1024 bits.
.It Fl l
-List the currently configured dump device, or /dev/null if no device is
+List the currently configured dump device(s), or /dev/null if no devices are
configured.
.It Fl v
Enable verbose mode.
Index: sbin/dumpon/dumpon.c
===================================================================
--- sbin/dumpon/dumpon.c
+++ sbin/dumpon/dumpon.c
@@ -86,8 +86,8 @@
usage(void)
{
fprintf(stderr,
- "usage: dumpon [-v] [-k <pubkey>] [-Zz] <device>\n"
- " dumpon [-v] [-k <pubkey>] [-Zz]\n"
+ "usage: dumpon [-i index] [-r] [-v] [-k <pubkey>] [-Zz] <device>\n"
+ " dumpon [-i index] [-r] [-v] [-k <pubkey>] [-Zz]\n"
" [-g <gateway>] -s <server> -c <client> <iface>\n"
" dumpon [-v] off\n"
" dumpon [-v] -l\n");
@@ -308,9 +308,17 @@
if (strlen(dumpdev) == 0)
(void)strlcpy(dumpdev, _PATH_DEVNULL, sizeof(dumpdev));
- if (verbose)
- printf("kernel dumps on ");
- printf("%s\n", dumpdev);
+ if (verbose) {
+ char *ctx, *dd;
+ unsigned idx;
+
+ printf("kernel dumps on priority: device\n");
+ idx = 0;
+ ctx = dumpdev;
+ while ((dd = strsep(&ctx, ",")) != NULL)
+ printf("%u: %s\n", idx++, dd);
+ } else
+ printf("%s\n", dumpdev);
/* If netdump is enabled, print the configuration parameters. */
if (verbose) {
@@ -364,14 +372,16 @@
struct addrinfo hints, *res;
const char *dev, *pubkeyfile, *server, *client, *gateway;
int ch, error, fd;
- bool enable, gzip, list, netdump, zstd;
+ bool gzip, list, netdump, zstd, insert, remove;
+ uint8_t ins_idx;
- gzip = list = netdump = zstd = false;
+ gzip = list = netdump = zstd = insert = remove = false;
kdap = NULL;
pubkeyfile = NULL;
server = client = gateway = NULL;
+ ins_idx = KDA_APPEND;
- while ((ch = getopt(argc, argv, "c:g:k:ls:vZz")) != -1)
+ while ((ch = getopt(argc, argv, "c:g:i:k:lrs:vZz")) != -1)
switch ((char)ch) {
case 'c':
client = optarg;
@@ -379,12 +389,28 @@
case 'g':
gateway = optarg;
break;
+ case 'i':
+ {
+ int i;
+
+ i = atoi(optarg);
+ if (i < 0 || i >= KDA_APPEND - 1)
+ errx(EX_USAGE,
+ "-i index must be between zero and %d.",
+ (int)KDA_APPEND - 2);
+ insert = true;
+ ins_idx = i + 1;
+ }
+ break;
case 'k':
pubkeyfile = optarg;
break;
case 'l':
list = true;
break;
+ case 'r':
+ remove = true;
+ break;
case 's':
server = optarg;
break;
@@ -404,6 +430,9 @@
if (gzip && zstd)
errx(EX_USAGE, "The -z and -Z options are mutually exclusive.");
+ if (insert && remove)
+ errx(EX_USAGE, "The -i and -r options are mutually exclusive.");
+
argc -= optind;
argv += optind;
@@ -422,31 +451,31 @@
#endif
if (server != NULL && client != NULL) {
- enable = true;
dev = _PATH_NETDUMP;
netdump = true;
kdap = &ndconf.ndc_kda;
} else if (server == NULL && client == NULL && argc > 0) {
- enable = strcmp(argv[0], "off") != 0;
- dev = enable ? argv[0] : _PATH_DEVNULL;
+ if (strcmp(argv[0], "off") == 0) {
+ remove = true;
+ dev = _PATH_DEVNULL;
+ } else
+ dev = argv[0];
netdump = false;
kdap = &_kda;
} else
usage();
fd = opendumpdev(dev, dumpdev);
- if (!netdump && !gzip)
+ if (!netdump && !gzip && !remove)
check_size(fd, dumpdev);
bzero(kdap, sizeof(*kdap));
- kdap->kda_enable = 0;
- if (ioctl(fd, DIOCSKERNELDUMP, kdap) != 0)
- err(EX_OSERR, "ioctl(DIOCSKERNELDUMP)");
- if (!enable)
- exit(EX_OK);
- explicit_bzero(kdap, sizeof(*kdap));
- kdap->kda_enable = 1;
+ if (remove)
+ kdap->kda_index = KDA_REMOVE;
+ else
+ kdap->kda_index = ins_idx;
+
kdap->kda_compression = KERNELDUMP_COMP_NONE;
if (zstd)
kdap->kda_compression = KERNELDUMP_COMP_ZSTD;
@@ -517,7 +546,7 @@
errc(EX_OSERR, error, "ioctl(DIOCSKERNELDUMP)");
}
if (verbose)
- printf("kernel dumps on %s\n", dumpdev);
+ listdumpdev();
exit(EX_OK);
}
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 = clear_dumper(td);
+ error = remove_dumper(NULL, NULL);
break;
case FIONBIO:
break;
Index: sys/geom/geom_dev.c
===================================================================
--- sys/geom/geom_dev.c
+++ sys/geom/geom_dev.c
@@ -135,15 +135,20 @@
}
static int
-g_dev_setdumpdev(struct cdev *dev, struct diocskerneldump_arg *kda,
- struct thread *td)
+g_dev_setdumpdev(struct cdev *dev, struct diocskerneldump_arg *kda)
{
struct g_kerneldump kd;
struct g_consumer *cp;
int error, len;
+ uint8_t idx;
- if (dev == NULL || kda == NULL)
- return (clear_dumper(td));
+ MPASS(dev != NULL && kda != NULL);
+ MPASS(kda->kda_index != KDA_REMOVE);
+
+ idx = kda->kda_index;
+ /* Adjust from 1-index to 0-index */
+ if (idx != KDA_APPEND)
+ idx--;
cp = dev->si_drv2;
len = sizeof(kd);
@@ -154,9 +159,9 @@
if (error != 0)
return (error);
- error = set_dumper(&kd.di, devtoname(dev), td, kda->kda_compression,
- kda->kda_encryption, kda->kda_key, kda->kda_encryptedkeysize,
- kda->kda_encryptedkey);
+ error = insert_dumper(&kd.di, devtoname(dev), idx,
+ kda->kda_compression, kda->kda_encryption, kda->kda_key,
+ kda->kda_encryptedkeysize, kda->kda_encryptedkey);
if (error == 0)
dev->si_flags |= SI_DUMPDEV;
@@ -173,7 +178,7 @@
size_t len;
bzero(&kda, sizeof(kda));
- kda.kda_enable = 1;
+ kda.kda_index = KDA_APPEND;
if (dumpdev == NULL)
return (0);
@@ -190,7 +195,7 @@
if (error != 0)
return (error);
- error = g_dev_setdumpdev(dev, &kda, curthread);
+ error = g_dev_setdumpdev(dev, &kda);
if (error == 0) {
freeenv(dumpdev);
dumpdev = NULL;
@@ -549,11 +554,11 @@
bzero(&kda, sizeof(kda));
kda.kda_encryption = KERNELDUMP_ENC_NONE;
- kda.kda_enable = (uint8_t)*(u_int *)data;
- if (kda.kda_enable == 0)
- error = g_dev_setdumpdev(NULL, NULL, td);
+ kda.kda_index = (uint8_t)*(u_int *)data;
+ if (kda.kda_index == KDA_REMOVE)
+ error = remove_dumper(devtoname(dev), &kda);
else
- error = g_dev_setdumpdev(dev, &kda, td);
+ error = g_dev_setdumpdev(dev, &kda);
break;
}
#endif
@@ -563,8 +568,9 @@
uint8_t *encryptedkey;
kda = (struct diocskerneldump_arg *)data;
- if (kda->kda_enable == 0) {
- error = g_dev_setdumpdev(NULL, NULL, td);
+ if (kda->kda_index == KDA_REMOVE) {
+ error = remove_dumper(devtoname(dev), kda);
+ explicit_bzero(kda, sizeof(*kda));
break;
}
@@ -583,7 +589,7 @@
}
if (error == 0) {
kda->kda_encryptedkey = encryptedkey;
- error = g_dev_setdumpdev(dev, kda, td);
+ error = g_dev_setdumpdev(dev, kda);
}
if (encryptedkey != NULL) {
explicit_bzero(encryptedkey, kda->kda_encryptedkeysize);
@@ -860,7 +866,7 @@
/* Reset any dump-area set on this device */
if (dev->si_flags & SI_DUMPDEV)
- (void)clear_dumper(curthread);
+ (void)remove_dumper(devtoname(dev), NULL);
/* Destroy the struct cdev *so we get no more requests */
delist_dev(dev);
Index: sys/kern/kern_shutdown.c
===================================================================
--- sys/kern/kern_shutdown.c
+++ sys/kern/kern_shutdown.c
@@ -43,6 +43,7 @@
#include "opt_ekcd.h"
#include "opt_kdb.h"
#include "opt_panic.h"
+#include "opt_printf.h"
#include "opt_sched.h"
#include "opt_watchdog.h"
@@ -53,6 +54,7 @@
#include <sys/conf.h>
#include <sys/compressor.h>
#include <sys/cons.h>
+#include <sys/disk.h>
#include <sys/eventhandler.h>
#include <sys/filedesc.h>
#include <sys/jail.h>
@@ -69,6 +71,7 @@
#include <sys/reboot.h>
#include <sys/resourcevar.h>
#include <sys/rwlock.h>
+#include <sys/sbuf.h>
#include <sys/sched.h>
#include <sys/smp.h>
#include <sys/sysctl.h>
@@ -209,7 +212,16 @@
int dumping; /* system is dumping */
int rebooting; /* system is rebooting */
-static struct dumperinfo dumper; /* our selected dumper */
+/*
+ * Only used to serialize between unprotected sysctl kern.shutdown.dumpdevname
+ * and list modifications.
+ */
+static struct mtx dumpconf_list_lk;
+MTX_SYSINIT(dumper_configs, &dumpconf_list_lk, "dumper config list", MTX_DEF);
+
+/* our selected dumper(s) */
+static TAILQ_HEAD(dumpconflist, dumperinfo) dumper_configs =
+ TAILQ_HEAD_INITIALIZER(dumper_configs);
/* Context information for dump-debuggers. */
static struct pcb dumppcb; /* Registers. */
@@ -364,7 +376,7 @@
error = 0;
if (dumping)
return (EBUSY);
- if (dumper.dumper == NULL)
+ if (TAILQ_EMPTY(&dumper_configs))
return (ENXIO);
savectx(&dumppcb);
@@ -375,11 +387,18 @@
#ifdef DDB
if (textdump && textdump_pending) {
coredump = FALSE;
- textdump_dumpsys(&dumper);
+ textdump_dumpsys(TAILQ_FIRST(&dumper_configs));
}
#endif
- if (coredump)
- error = dumpsys(&dumper);
+ if (coredump) {
+ struct dumperinfo *di;
+
+ TAILQ_FOREACH(di, &dumper_configs, di_next) {
+ error = dumpsys(di);
+ if (error == 0)
+ break;
+ }
+ }
dumping--;
return (error);
@@ -952,9 +971,43 @@
printf("done\n");
}
-static char dumpdevname[sizeof(((struct cdev*)NULL)->si_name)];
-SYSCTL_STRING(_kern_shutdown, OID_AUTO, dumpdevname, CTLFLAG_RD,
- dumpdevname, 0, "Device for kernel dumps");
+static int
+dumpdevname_sysctl_handler(SYSCTL_HANDLER_ARGS)
+{
+ char buf[PRINTF_BUFR_SIZE];
+ struct dumperinfo *di;
+ struct sbuf sb;
+ bool first;
+ int error;
+
+ /* Arbitrarily restrict size of wired output buffer */
+ if (req->oldlen > PAGE_SIZE)
+ return (EINVAL);
+
+ error = sysctl_wire_old_buffer(req, 0);
+ if (error != 0)
+ return (error);
+
+ sbuf_new_for_sysctl(&sb, buf, sizeof(buf), req);
+
+ mtx_lock(&dumpconf_list_lk);
+ first = true;
+ TAILQ_FOREACH(di, &dumper_configs, di_next) {
+ if (first)
+ first = false;
+ else
+ sbuf_putc(&sb, ',');
+ sbuf_cat(&sb, di->di_devname);
+ }
+ mtx_unlock(&dumpconf_list_lk);
+
+ error = sbuf_finish(&sb);
+ sbuf_delete(&sb);
+ return (error);
+}
+SYSCTL_PROC(_kern_shutdown, OID_AUTO, dumpdevname, CTLTYPE_STRING | CTLFLAG_RD,
+ &dumper_configs, 0, dumpdevname_sysctl_handler, "A",
+ "Device(s) for kernel dumps");
static int _dump_append(struct dumperinfo *di, void *virtual,
vm_offset_t physical, size_t length);
@@ -1092,31 +1145,62 @@
free(kdcomp, M_DUMPER);
}
+/*
+ * Must not be present on global list.
+ */
+static void
+free_single_dumper(struct dumperinfo *di)
+{
+
+ if (di == NULL)
+ return;
+
+ if (di->blockbuf != NULL) {
+ explicit_bzero(di->blockbuf, di->blocksize);
+ free(di->blockbuf, M_DUMPER);
+ }
+
+ kerneldumpcomp_destroy(di);
+
+#ifdef EKCD
+ if (di->kdcrypto != NULL) {
+ explicit_bzero(di->kdcrypto, sizeof(*di->kdcrypto) +
+ di->kdcrypto->kdc_dumpkeysize);
+ free(di->kdcrypto, M_EKCD);
+ }
+#endif
+
+ explicit_bzero(di, sizeof(*di));
+ free(di, M_DUMPER);
+}
+
/* Registration of dumpers */
int
-set_dumper(struct dumperinfo *di, const char *devname, struct thread *td,
- uint8_t compression, uint8_t encryption, const uint8_t *key,
+insert_dumper(const struct dumperinfo *di_template, const char *devname,
+ uint8_t index, uint8_t compression, uint8_t encryption, const uint8_t *key,
uint32_t encryptedkeysize, const uint8_t *encryptedkey)
{
- size_t wantcopy;
+ struct dumperinfo *newdi, *listdi;
+ bool inserted;
int error;
- error = priv_check(td, PRIV_SETDUMPER);
+ error = priv_check(curthread, PRIV_SETDUMPER);
if (error != 0)
return (error);
- if (dumper.dumper != NULL)
- return (EBUSY);
- dumper = *di;
- dumper.blockbuf = NULL;
- dumper.kdcrypto = NULL;
- dumper.kdcomp = NULL;
+ newdi = malloc(sizeof(*newdi) + strlen(devname) + 1, M_DUMPER, M_WAITOK
+ | M_ZERO);
+ *newdi = *di_template;
+ newdi->blockbuf = NULL;
+ newdi->kdcrypto = NULL;
+ newdi->kdcomp = NULL;
+ strcpy(newdi->di_devname, devname);
if (encryption != KERNELDUMP_ENC_NONE) {
#ifdef EKCD
- dumper.kdcrypto = kerneldumpcrypto_create(di->blocksize,
+ newdi->kdcrypto = kerneldumpcrypto_create(di_template->blocksize,
encryption, key, encryptedkeysize, encryptedkey);
- if (dumper.kdcrypto == NULL) {
+ if (newdi->kdcrypto == NULL) {
error = EINVAL;
goto cleanup;
}
@@ -1125,66 +1209,116 @@
goto cleanup;
#endif
}
-
- wantcopy = strlcpy(dumpdevname, devname, sizeof(dumpdevname));
- if (wantcopy >= sizeof(dumpdevname)) {
- printf("set_dumper: device name truncated from '%s' -> '%s'\n",
- devname, dumpdevname);
- }
-
if (compression != KERNELDUMP_COMP_NONE) {
/*
* We currently can't support simultaneous encryption and
- * compression.
+ * compression because our only encryption mode is an unpadded
+ * block cipher, go figure. This is low hanging fruit to fix.
*/
if (encryption != KERNELDUMP_ENC_NONE) {
error = EOPNOTSUPP;
goto cleanup;
}
- dumper.kdcomp = kerneldumpcomp_create(&dumper, compression);
- if (dumper.kdcomp == NULL) {
+ newdi->kdcomp = kerneldumpcomp_create(newdi, compression);
+ if (newdi->kdcomp == NULL) {
error = EINVAL;
goto cleanup;
}
}
- dumper.blockbuf = malloc(di->blocksize, M_DUMPER, M_WAITOK | M_ZERO);
+ newdi->blockbuf = malloc(newdi->blocksize, M_DUMPER, M_WAITOK | M_ZERO);
+
+ /* Add the new configuration to the queue */
+ mtx_lock(&dumpconf_list_lk);
+ inserted = false;
+ TAILQ_FOREACH(listdi, &dumper_configs, di_next) {
+ if (index == 0) {
+ TAILQ_INSERT_BEFORE(listdi, newdi, di_next);
+ inserted = true;
+ break;
+ }
+ index--;
+ }
+ if (!inserted)
+ TAILQ_INSERT_TAIL(&dumper_configs, newdi, di_next);
+ mtx_unlock(&dumpconf_list_lk);
+
return (0);
cleanup:
- (void)clear_dumper(td);
+ free_single_dumper(newdi);
return (error);
}
-int
-clear_dumper(struct thread *td)
+static bool
+dumper_config_match(const struct dumperinfo *di, const char *devname,
+ const struct diocskerneldump_arg *kda)
{
- int error;
+ /* Special wildcard: NULL for /dev/null removes everything. */
+ if (devname == NULL)
+ return (true);
- error = priv_check(td, PRIV_SETDUMPER);
- if (error != 0)
- return (error);
+ if (strcmp(di->di_devname, devname) != 0)
+ return (false);
-#ifdef NETDUMP
- netdump_mbuf_drain();
-#endif
+ /*
+ * Allow wildcard removal of configs matching a device on g_dev_orphan.
+ */
+ if (kda == NULL)
+ return (true);
+ if (di->kdcomp != NULL) {
+ if (di->kdcomp->kdc_format != kda->kda_compression)
+ return (false);
+ } else if (kda->kda_compression != KERNELDUMP_COMP_NONE)
+ return (false);
#ifdef EKCD
- if (dumper.kdcrypto != NULL) {
- explicit_bzero(dumper.kdcrypto, sizeof(*dumper.kdcrypto) +
- dumper.kdcrypto->kdc_dumpkeysize);
- free(dumper.kdcrypto, M_EKCD);
- }
+ if (di->kdcrypto != NULL) {
+ if (di->kdcrypto->kdc_encryption != kda->kda_encryption)
+ return (false);
+ /*
+ * Do we care to verify keys match to delete? It seems weird
+ * to expect multiple fallback dump configurations on the same
+ * device that only differ in crypto key.
+ */
+ } else
#endif
+ if (kda->kda_encryption != KERNELDUMP_ENC_NONE)
+ return (false);
- kerneldumpcomp_destroy(&dumper);
+ return (true);
+}
+
+int
+remove_dumper(const char *devname, const struct diocskerneldump_arg *kda)
+{
+ struct dumperinfo *di, *sdi;
+ bool found;
+ int error;
- if (dumper.blockbuf != NULL) {
- explicit_bzero(dumper.blockbuf, dumper.blocksize);
- free(dumper.blockbuf, M_DUMPER);
+ error = priv_check(curthread, PRIV_SETDUMPER);
+ if (error != 0)
+ return (error);
+
+ /*
+ * Try to find a matching configuration, and kill it.
+ *
+ * NULL 'kda' indicates remove any configuration matching 'devname',
+ * which may remove multiple configurations in atypical configurations.
+ */
+ found = false;
+ mtx_lock(&dumpconf_list_lk);
+ TAILQ_FOREACH_SAFE(di, &dumper_configs, di_next, sdi) {
+ if (dumper_config_match(di, devname, kda)) {
+ found = true;
+ TAILQ_REMOVE(&dumper_configs, di, di_next);
+ free_single_dumper(di);
+ }
}
- explicit_bzero(&dumper, sizeof(dumper));
- dumpdevname[0] = '\0';
+ mtx_unlock(&dumpconf_list_lk);
+
+ if (!found)
+ return (ENOENT);
return (0);
}
Index: sys/netinet/netdump/netdump_client.c
===================================================================
--- sys/netinet/netdump/netdump_client.c
+++ sys/netinet/netdump/netdump_client.c
@@ -1144,7 +1144,7 @@
struct diocskerneldump_arg *kda;
struct dumperinfo dumper;
struct netdump_conf *conf;
- uint8_t *encryptedkey;
+ uint8_t *encryptedkey, idx;
int error;
#ifdef COMPAT_FREEBSD11
u_int u;
@@ -1167,7 +1167,7 @@
#endif
case DIOCSKERNELDUMP:
kda = (void *)addr;
- if (kda->kda_enable != 0) {
+ if (kda->kda_index != KDA_REMOVE) {
error = ENXIO;
break;
}
@@ -1195,9 +1195,9 @@
kda = &conf->ndc_kda;
conf->ndc_iface[sizeof(conf->ndc_iface) - 1] = '\0';
- if (kda->kda_enable == 0) {
+ if (kda->kda_index == KDA_REMOVE) {
if (nd_enabled) {
- error = clear_dumper(td);
+ error = remove_dumper(conf->ndc_iface, kda);
if (error == 0) {
nd_enabled = 0;
netdump_mbuf_drain();
@@ -1206,6 +1206,11 @@
break;
}
+ idx = kda->kda_index;
+ /* Adjust from 1-index to 0-index */
+ if (idx != KDA_APPEND)
+ idx--;
+
error = netdump_configure(conf, td);
if (error != 0)
break;
@@ -1235,7 +1240,7 @@
dumper.mediaoffset = 0;
dumper.mediasize = 0;
- error = set_dumper(&dumper, conf->ndc_iface, td,
+ error = insert_dumper(&dumper, conf->ndc_iface, idx,
kda->kda_compression, kda->kda_encryption,
kda->kda_key, kda->kda_encryptedkeysize,
encryptedkey);
@@ -1305,12 +1310,13 @@
}
break;
case MOD_UNLOAD:
- destroy_dev(netdump_cdev);
if (nd_enabled) {
printf("netdump: disabling dump device for unload\n");
- (void)clear_dumper(curthread);
+ netdump_mbuf_drain();
+ (void)remove_dumper(nd_conf.ndc_iface, NULL);
nd_enabled = 0;
}
+ destroy_dev(netdump_cdev);
break;
default:
error = EOPNOTSUPP;
Index: sys/sys/conf.h
===================================================================
--- sys/sys/conf.h
+++ sys/sys/conf.h
@@ -352,15 +352,20 @@
off_t origdumpoff; /* Starting dump offset. */
struct kerneldumpcrypto *kdcrypto; /* Kernel dump crypto. */
struct kerneldumpcomp *kdcomp; /* Kernel dump compression. */
+
+ TAILQ_ENTRY(dumperinfo) di_next;
+
+ char di_devname[];
};
extern int dumping; /* system is dumping */
int doadump(boolean_t);
-int set_dumper(struct dumperinfo *di, const char *devname, struct thread *td,
- uint8_t compression, uint8_t encryption, const uint8_t *key,
+int insert_dumper(const struct dumperinfo *di_template, const char *devname,
+ uint8_t index, uint8_t compression, uint8_t encryption, const uint8_t *key,
uint32_t encryptedkeysize, const uint8_t *encryptedkey);
-int clear_dumper(struct thread *td);
+struct diocskerneldump_arg;
+int remove_dumper(const char *devname, const struct diocskerneldump_arg *kda);
int dump_start(struct dumperinfo *di, struct kerneldumpheader *kdh);
int dump_append(struct dumperinfo *, void *, vm_offset_t, size_t);
Index: sys/sys/disk.h
===================================================================
--- sys/sys/disk.h
+++ sys/sys/disk.h
@@ -143,8 +143,22 @@
#define DIOCZONECMD _IOWR('d', 143, struct disk_zone_args)
+/*
+ * Sentinel values for kda_index.
+ *
+ * If kda_index is KDA_REMOVE, the specified dump configuration for the given
+ * device is removed from the list of fallback dump configurations.
+ *
+ * If kda_index is KDA_APPEND, the dump configuration is added after all
+ * existing dump configurations.
+ *
+ * Otherwise, the new configuration is inserted into the fallback dump list at
+ * index 'kda_index - 1'.
+ */
+#define KDA_REMOVE 0
+#define KDA_APPEND UINT8_MAX
struct diocskerneldump_arg {
- uint8_t kda_enable;
+ uint8_t kda_index;
uint8_t kda_compression;
uint8_t kda_encryption;
uint8_t kda_key[KERNELDUMP_KEY_MAX_SIZE];

File Metadata

Mime Type
text/plain
Expires
Sun, Dec 21, 12:49 PM (20 h, 13 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
27113292
Default Alt Text
D19996.id56625.diff (21 KB)

Event Timeline