Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F140121297
D19996.id56625.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
21 KB
Referenced Files
None
Subscribers
None
D19996.id56625.diff
View Options
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
Details
Attached
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)
Attached To
Mode
D19996: List-ify kernel dump device configuration
Attached
Detach File
Event Timeline
Log In to Comment