46#include "opt_printf.h"
48#include "opt_watchdog.h"
53#include <sys/boottrace.h>
56#include <sys/compressor.h>
59#include <sys/eventhandler.h>
60#include <sys/filedesc.h>
63#include <sys/kernel.h>
64#include <sys/kerneldump.h>
65#include <sys/kthread.h>
67#include <sys/malloc.h>
72#include <sys/reboot.h>
73#include <sys/resourcevar.h>
74#include <sys/rwlock.h>
78#include <sys/sysctl.h>
79#include <sys/sysproto.h>
80#include <sys/taskqueue.h>
82#include <sys/watchdog.h>
84#include <crypto/chacha20/chacha.h>
85#include <crypto/rijndael/rijndael-api-fst.h>
86#include <crypto/sha2/sha256.h>
90#include <machine/cpu.h>
91#include <machine/dump.h>
92#include <machine/pcb.h>
93#include <machine/smp.h>
95#include <security/mac/mac_framework.h>
98#include <vm/vm_object.h>
99#include <vm/vm_page.h>
100#include <vm/vm_pager.h>
101#include <vm/swap_pager.h>
103#include <sys/signalvar.h>
107#ifndef PANIC_REBOOT_WAIT_TIME
108#define PANIC_REBOOT_WAIT_TIME 15
113 "Seconds to wait before rebooting after a panic");
119#include <machine/stdarg.h>
123int debugger_on_panic = 0;
125int debugger_on_panic = 1;
127SYSCTL_INT(_debug, OID_AUTO, debugger_on_panic,
128 CTLFLAG_RWTUN | CTLFLAG_SECURE,
129 &debugger_on_panic, 0,
"Run debugger on kernel panic");
131static bool debugger_on_recursive_panic =
false;
132SYSCTL_BOOL(_debug, OID_AUTO, debugger_on_recursive_panic,
133 CTLFLAG_RWTUN | CTLFLAG_SECURE,
134 &debugger_on_recursive_panic, 0,
"Run debugger on recursive kernel panic");
136int debugger_on_trap = 0;
138 CTLFLAG_RWTUN | CTLFLAG_SECURE,
139 &debugger_on_trap, 0,
"Run debugger on kernel trap before panic");
142static int trace_on_panic = 1;
143static bool trace_all_panics =
true;
145static int trace_on_panic = 0;
146static bool trace_all_panics =
false;
149 CTLFLAG_RWTUN | CTLFLAG_SECURE,
150 &trace_on_panic, 0,
"Print stack trace on kernel panic");
151SYSCTL_BOOL(_debug, OID_AUTO, trace_all_panics, CTLFLAG_RWTUN,
152 &trace_all_panics, 0,
"Print stack traces on secondary kernel panics");
157 &
sync_on_panic, 0,
"Do a sync before rebooting from a panic");
168 "Shutdown environment");
177 "Show busy buffers during shutdown");
184FEATURE(ekcd,
"Encrypted kernel crash dumps support");
186MALLOC_DEFINE(M_EKCD,
"ekcd",
"Encrypted kernel crash dumps data");
188struct kerneldumpcrypto {
189 uint8_t kdc_encryption;
190 uint8_t kdc_iv[KERNELDUMP_IV_MAX_SIZE];
194 cipherInstance aes_ci;
196 struct chacha_ctx u_chacha;
198#define kdc_ki u.u_aes.aes_ki
199#define kdc_ci u.u_aes.aes_ci
200#define kdc_chacha u.u_chacha
201 uint32_t kdc_dumpkeysize;
202 struct kerneldumpkey kdc_dumpkey[];
214 uint8_t compression);
221 "Kernel crash dump compression level");
241 TAILQ_HEAD_INITIALIZER(dumper_configs);
244static struct pcb dumppcb;
247static struct cdevsw reroot_cdevsw = {
248 .d_version = D_VERSION,
266 SHUTDOWN_PRI_LAST + 100);
268 SHUTDOWN_PRI_LAST + 100);
270 SHUTDOWN_PRI_LAST + 200);
285 error =
make_dev_p(MAKEDEV_CHECKNAME | MAKEDEV_WAITOK, &cdev,
286 &reroot_cdevsw, NULL, UID_ROOT, GID_WHEEL, 0600,
"reroot/reroot");
288 printf(
"%s: failed to create device node, error %d",
306 error = mac_system_check_reboot(td->td_ucred, uap->opt);
311 if (uap->opt & RB_REROOT)
324 howto = (uintptr_t)arg;
327 if ((howto & RB_POWEROFF) != 0) {
328 BOOTTRACE(
"SIGUSR2 to init(8)");
330 }
else if ((howto & RB_POWERCYCLE) != 0) {
331 BOOTTRACE(
"SIGWINCH to init(8)");
333 }
else if ((howto & RB_HALT) != 0) {
334 BOOTTRACE(
"SIGUSR1 to init(8)");
337 BOOTTRACE(
"SIGINT to init(8)");
353 if (
initproc != NULL && !SCHEDULER_STOPPED()) {
354 BOOTTRACE(
"shutdown initiated");
375 if (
ts.tv_sec >= 86400) {
376 printf(
"%ldd", (
long)
ts.tv_sec / 86400);
380 if (f ||
ts.tv_sec >= 3600) {
381 printf(
"%ldh", (
long)
ts.tv_sec / 3600);
385 if (f ||
ts.tv_sec >= 60) {
386 printf(
"%ldm", (
long)
ts.tv_sec / 60);
402 if (TAILQ_EMPTY(&dumper_configs))
406 dumptid = curthread->td_tid;
411 if (textdump && textdump_pending) {
413 textdump_dumpsys(TAILQ_FIRST(&dumper_configs));
417 struct dumperinfo *di;
419 TAILQ_FOREACH(di, &dumper_configs, di_next) {
436 if ((howto & RB_DUMP) != 0) {
437 if ((howto & RB_HALT) != 0)
438 BOOTTRACE(
"system panic: halting...");
439 if ((howto & RB_POWEROFF) != 0)
440 BOOTTRACE(
"system panic: powering off...");
441 if ((howto & (RB_HALT|RB_POWEROFF)) == 0)
442 BOOTTRACE(
"system panic: rebooting...");
444 if ((howto & RB_HALT) != 0)
445 BOOTTRACE(
"system halting...");
446 if ((howto & RB_POWEROFF) != 0)
447 BOOTTRACE(
"system powering off...");
448 if ((howto & (RB_HALT|RB_POWEROFF)) == 0)
449 BOOTTRACE(
"system rebooting...");
463 BOOTTRACE(
"kernel shutdown (dirty) started");
465 BOOTTRACE(
"kernel shutdown (clean) started");
475 while (mtx_owned(&
Giant))
484 if (!SCHEDULER_STOPPED()) {
485 thread_lock(curthread);
487 thread_unlock(curthread);
488 KASSERT(PCPU_GET(cpuid) == CPU_FIRST(),
489 (
"%s: not running on cpu 0", __func__));
502 EVENTHANDLER_INVOKE(shutdown_pre_sync, howto);
503 BOOTTRACE(
"shutdown pre sync complete");
508 if (!cold && (howto & RB_NOSYNC) == 0 && once == 0) {
510 BOOTTRACE(
"bufshutdown begin");
512 BOOTTRACE(
"bufshutdown end");
523 EVENTHANDLER_INVOKE(shutdown_post_sync, howto);
524 BOOTTRACE(
"shutdown post sync complete");
526 if ((howto & (RB_HALT|RB_DUMP)) == RB_DUMP && !cold && !
dumping)
530 BOOTTRACE(
"shutdown final begin");
535 EVENTHANDLER_INVOKE(shutdown_final, howto);
547 struct vnode *oldrootvnode, *vp;
548 struct mount *mp, *devmp;
558 vp = curproc->p_textvp;
559 error = vn_lock(vp, LK_SHARED);
568 vn_lock(vp, LK_SHARED | LK_RETRY);
574 if (VN_IS_DOOMED(vp)) {
597 TAILQ_REMOVE(&
mountlist, devmp, mnt_list);
611 TAILQ_INSERT_HEAD(&
mountlist, devmp, mnt_list);
630 TAILQ_INSERT_TAIL(&
mountlist, mp, mnt_list);
644 if (howto & RB_HALT) {
646 printf(
"The operating system has halted.\n");
647 printf(
"Please press any key to reboot.\n\n");
649 wdog_kern_pat(WD_TO_NEVER);
670 if (howto & RB_DUMP) {
673 printf(
"Automatic reboot in %d seconds - "
674 "press a key on the console to abort\n",
689 printf(
"--> Press a key on the console to reboot,\n");
690 printf(
"--> or switch off the system now.\n");
717 mtx_lock_spin(&smp_ipi_mtx);
726#if defined(WITNESS) || defined(INVARIANT_SUPPORT)
727static int kassert_warn_only = 0;
729static int kassert_do_kdb = 0;
732static int kassert_do_ktr = 0;
734static int kassert_do_log = 1;
735static int kassert_log_pps_limit = 4;
736static int kassert_log_mute_at = 0;
737static int kassert_log_panic_at = 0;
738static int kassert_suppress_in_panic = 0;
739static int kassert_warnings = 0;
741SYSCTL_NODE(_debug, OID_AUTO, kassert, CTLFLAG_RW | CTLFLAG_MPSAFE, NULL,
744#ifdef KASSERT_PANIC_OPTIONAL
745#define KASSERT_RWTUN CTLFLAG_RWTUN
747#define KASSERT_RWTUN CTLFLAG_RDTUN
750SYSCTL_INT(_debug_kassert, OID_AUTO, warn_only, KASSERT_RWTUN,
751 &kassert_warn_only, 0,
752 "KASSERT triggers a panic (0) or just a warning (1)");
755SYSCTL_INT(_debug_kassert, OID_AUTO, do_kdb, KASSERT_RWTUN,
756 &kassert_do_kdb, 0,
"KASSERT will enter the debugger");
760SYSCTL_UINT(_debug_kassert, OID_AUTO, do_ktr, KASSERT_RWTUN,
762 "KASSERT does a KTR, set this to the KTRMASK you want");
765SYSCTL_INT(_debug_kassert, OID_AUTO, do_log, KASSERT_RWTUN,
767 "If warn_only is enabled, log (1) or do not log (0) assertion violations");
769SYSCTL_INT(_debug_kassert, OID_AUTO, warnings, CTLFLAG_RD | CTLFLAG_STATS,
770 &kassert_warnings, 0,
"number of KASSERTs that have been triggered");
772SYSCTL_INT(_debug_kassert, OID_AUTO, log_panic_at, KASSERT_RWTUN,
773 &kassert_log_panic_at, 0,
"max number of KASSERTS before we will panic");
775SYSCTL_INT(_debug_kassert, OID_AUTO, log_pps_limit, KASSERT_RWTUN,
776 &kassert_log_pps_limit, 0,
"limit number of log messages per second");
778SYSCTL_INT(_debug_kassert, OID_AUTO, log_mute_at, KASSERT_RWTUN,
779 &kassert_log_mute_at, 0,
"max number of KASSERTS to log");
781SYSCTL_INT(_debug_kassert, OID_AUTO, suppress_in_panic, KASSERT_RWTUN,
782 &kassert_suppress_in_panic, 0,
783 "KASSERTs will be suppressed while handling a panic");
786static int kassert_sysctl_kassert(SYSCTL_HANDLER_ARGS);
789 CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_SECURE | CTLFLAG_MPSAFE, NULL, 0,
790 kassert_sysctl_kassert,
"I",
791 "set to trigger a test kassert");
794kassert_sysctl_kassert(SYSCTL_HANDLER_ARGS)
803 if (error != 0 || req->newptr == NULL)
805 KASSERT(0, (
"kassert_sysctl_kassert triggered kassert %d", i));
809#ifdef KASSERT_PANIC_OPTIONAL
815kassert_panic(
const char *fmt, ...)
817 static char buf[256];
828 if (
panicstr != NULL && kassert_suppress_in_panic) {
829 if (kassert_do_log) {
832 if (trace_all_panics && trace_on_panic)
843 if (!kassert_warn_only ||
844 (kassert_log_panic_at > 0 &&
845 kassert_warnings >= kassert_log_panic_at)) {
857 if (kassert_do_log &&
858 (kassert_log_mute_at == 0 ||
859 kassert_warnings < kassert_log_mute_at)) {
860 static struct timeval lasterr;
863 if (
ppsratecheck(&lasterr, &curerr, kassert_log_pps_limit)) {
869 if (kassert_do_kdb) {
873 atomic_add_int(&kassert_warnings, 1);
898 struct thread *td = curthread;
899 int bootopt, newpanic;
900 static char buf[256];
912 CPU_CLR(PCPU_GET(cpuid), &other_cpus);
913 stop_cpus_hard(other_cpus);
921 td->td_stopsched = 1;
923 bootopt = RB_AUTOBOOT;
926 bootopt |= RB_NOSYNC;
945 printf(
"cpuid = %d\n", PCPU_GET(cpuid));
949 if ((newpanic || trace_all_panics) && trace_on_panic)
951 if (debugger_on_panic)
953 else if (!newpanic && debugger_on_recursive_panic)
957 td->td_flags |= TDF_INPANIC;
960 bootopt |= RB_NOSYNC;
962 bootopt |= RB_POWEROFF;
964 bootopt |= RB_POWERCYCLE;
975#ifndef POWEROFF_DELAY
976# define POWEROFF_DELAY 5000
981 &
poweroff_delay, 0,
"Delay before poweroff to write disk caches (msec)");
987 if ((howto & (RB_POWEROFF | RB_POWERCYCLE)) == 0 ||
poweroff_delay <= 0)
1012 p = (
struct proc *)arg;
1013 printf(
"Waiting (max %d seconds) for system process `%s' to stop... ",
1017 if (error == EWOULDBLOCK)
1032 td = (
struct thread *)arg;
1033 printf(
"Waiting (max %d seconds) for system thread `%s' to stop... ",
1037 if (error == EWOULDBLOCK)
1047 struct dumperinfo *di;
1058 TAILQ_FOREACH(di, &dumper_configs, di_next) {
1059 if (di != TAILQ_FIRST(&dumper_configs))
1070 CTLTYPE_STRING | CTLFLAG_RD | CTLFLAG_MPSAFE, &dumper_configs, 0,
1072 "Device(s) for kernel dumps");
1074static int _dump_append(
struct dumperinfo *di,
void *
virtual,
1075 vm_offset_t physical,
size_t length);
1078static struct kerneldumpcrypto *
1079kerneldumpcrypto_create(
size_t blocksize, uint8_t encryption,
1080 const uint8_t *key, uint32_t encryptedkeysize,
const uint8_t *encryptedkey)
1082 struct kerneldumpcrypto *kdc;
1083 struct kerneldumpkey *kdk;
1084 uint32_t dumpkeysize;
1086 dumpkeysize = roundup2(
sizeof(*kdk) + encryptedkeysize, blocksize);
1087 kdc =
malloc(
sizeof(*kdc) + dumpkeysize, M_EKCD, M_WAITOK | M_ZERO);
1089 arc4rand(kdc->kdc_iv,
sizeof(kdc->kdc_iv), 0);
1091 kdc->kdc_encryption = encryption;
1092 switch (kdc->kdc_encryption) {
1093 case KERNELDUMP_ENC_AES_256_CBC:
1094 if (rijndael_makeKey(&kdc->kdc_ki, DIR_ENCRYPT, 256, key) <= 0)
1097 case KERNELDUMP_ENC_CHACHA20:
1098 chacha_keysetup(&kdc->kdc_chacha, key, 256);
1104 kdc->kdc_dumpkeysize = dumpkeysize;
1105 kdk = kdc->kdc_dumpkey;
1106 kdk->kdk_encryption = kdc->kdc_encryption;
1107 memcpy(kdk->kdk_iv, kdc->kdc_iv,
sizeof(kdk->kdk_iv));
1108 kdk->kdk_encryptedkeysize = htod32(encryptedkeysize);
1109 memcpy(kdk->kdk_encryptedkey, encryptedkey, encryptedkeysize);
1118kerneldumpcrypto_init(
struct kerneldumpcrypto *kdc)
1120 uint8_t hash[SHA256_DIGEST_LENGTH];
1122 struct kerneldumpkey *kdk;
1135 SHA256_Update(&ctx, kdc->kdc_iv,
sizeof(kdc->kdc_iv));
1136 SHA256_Final(hash, &ctx);
1137 bcopy(hash, kdc->kdc_iv,
sizeof(kdc->kdc_iv));
1139 switch (kdc->kdc_encryption) {
1140 case KERNELDUMP_ENC_AES_256_CBC:
1141 if (rijndael_cipherInit(&kdc->kdc_ci, MODE_CBC,
1142 kdc->kdc_iv) <= 0) {
1147 case KERNELDUMP_ENC_CHACHA20:
1148 chacha_ivsetup(&kdc->kdc_chacha, kdc->kdc_iv, NULL);
1155 kdk = kdc->kdc_dumpkey;
1156 memcpy(kdk->kdk_iv, kdc->kdc_iv,
sizeof(kdk->kdk_iv));
1158 explicit_bzero(hash,
sizeof(hash));
1163kerneldumpcrypto_dumpkeysize(
const struct kerneldumpcrypto *kdc)
1168 return (kdc->kdc_dumpkeysize);
1178 switch (compression) {
1179 case KERNELDUMP_COMP_GZIP:
1180 format = COMPRESS_GZIP;
1182 case KERNELDUMP_COMP_ZSTD:
1183 format = COMPRESS_ZSTD;
1189 kdcomp =
malloc(
sizeof(*kdcomp), M_DUMPER, M_WAITOK | M_ZERO);
1194 free(kdcomp, M_DUMPER);
1197 kdcomp->
kdc_buf =
malloc(di->maxiosize, M_DUMPER, M_WAITOK | M_NODUMP);
1206 kdcomp = di->kdcomp;
1211 free(kdcomp, M_DUMPER);
1224 zfree(di->blockbuf, M_DUMPER);
1229 zfree(di->kdcrypto, M_EKCD);
1231 zfree(di, M_DUMPER);
1237 const struct diocskerneldump_arg *kda)
1239 struct dumperinfo *newdi, *listdi;
1244 index = kda->kda_index;
1245 MPASS(index != KDA_REMOVE && index != KDA_REMOVE_DEV &&
1246 index != KDA_REMOVE_ALL);
1248 error =
priv_check(curthread, PRIV_SETDUMPER);
1252 newdi =
malloc(
sizeof(*newdi) + strlen(devname) + 1, M_DUMPER, M_WAITOK
1254 memcpy(newdi, di_template,
sizeof(*newdi));
1255 newdi->blockbuf = NULL;
1256 newdi->kdcrypto = NULL;
1257 newdi->kdcomp = NULL;
1258 strcpy(newdi->di_devname, devname);
1260 if (kda->kda_encryption != KERNELDUMP_ENC_NONE) {
1262 newdi->kdcrypto = kerneldumpcrypto_create(di_template->blocksize,
1263 kda->kda_encryption, kda->kda_key,
1264 kda->kda_encryptedkeysize, kda->kda_encryptedkey);
1265 if (newdi->kdcrypto == NULL) {
1274 if (kda->kda_compression != KERNELDUMP_COMP_NONE) {
1282 if (kda->kda_encryption == KERNELDUMP_ENC_AES_256_CBC) {
1288 kda->kda_compression);
1289 if (newdi->kdcomp == NULL) {
1295 newdi->blockbuf =
malloc(newdi->blocksize, M_DUMPER, M_WAITOK | M_ZERO);
1300 TAILQ_FOREACH(listdi, &dumper_configs, di_next) {
1302 TAILQ_INSERT_BEFORE(listdi, newdi, di_next);
1309 TAILQ_INSERT_TAIL(&dumper_configs, newdi, di_next);
1321dumper_ddb_insert(
struct dumperinfo *newdi)
1323 TAILQ_INSERT_HEAD(&dumper_configs, newdi, di_next);
1327dumper_ddb_remove(
struct dumperinfo *di)
1329 TAILQ_REMOVE(&dumper_configs, di, di_next);
1335 const struct diocskerneldump_arg *kda)
1337 if (kda->kda_index == KDA_REMOVE_ALL)
1340 if (strcmp(di->di_devname, devname) != 0)
1346 if (kda->kda_index == KDA_REMOVE_DEV)
1349 if (di->kdcomp != NULL) {
1350 if (di->kdcomp->kdc_format != kda->kda_compression)
1352 }
else if (kda->kda_compression != KERNELDUMP_COMP_NONE)
1355 if (di->kdcrypto != NULL) {
1356 if (di->kdcrypto->kdc_encryption != kda->kda_encryption)
1365 if (kda->kda_encryption != KERNELDUMP_ENC_NONE)
1374 struct dumperinfo *di, *sdi;
1378 error =
priv_check(curthread, PRIV_SETDUMPER);
1390 TAILQ_FOREACH_SAFE(di, &dumper_configs, di_next, sdi) {
1393 TAILQ_REMOVE(&dumper_configs, di, di_next);
1400 if (!found && kda->kda_index == KDA_REMOVE)
1409 if (di->mediasize > 0 && length != 0 && (offset < di->mediaoffset ||
1410 offset - di->mediaoffset + length > di->mediasize)) {
1411 if (di->kdcomp != NULL && offset >= di->mediaoffset) {
1413 "Compressed dump failed to fit in device boundaries.\n");
1417 printf(
"Attempt to write outside dump device boundaries.\n"
1418 "offset(%jd), mediaoffset(%jd), length(%ju), mediasize(%jd).\n",
1419 (intmax_t)offset, (intmax_t)di->mediaoffset,
1420 (uintmax_t)length, (intmax_t)di->mediasize);
1423 if (length % di->blocksize != 0) {
1424 printf(
"Attempt to write partial block of length %ju.\n",
1428 if (offset % di->blocksize != 0) {
1429 printf(
"Attempt to write at unaligned offset %jd.\n",
1439dump_encrypt(
struct kerneldumpcrypto *kdc, uint8_t *
buf,
size_t size)
1442 switch (kdc->kdc_encryption) {
1443 case KERNELDUMP_ENC_AES_256_CBC:
1444 if (rijndael_blockEncrypt(&kdc->kdc_ci, &kdc->kdc_ki,
buf,
1445 8 * size,
buf) <= 0) {
1448 if (rijndael_cipherInit(&kdc->kdc_ci, MODE_CBC,
1449 buf + size - 16 ) <= 0) {
1453 case KERNELDUMP_ENC_CHACHA20:
1454 chacha_encrypt_bytes(&kdc->kdc_chacha,
buf,
buf, size);
1465dump_encrypted_write(
struct dumperinfo *di,
void *
virtual,
1466 vm_offset_t physical, off_t offset,
size_t length)
1468 static uint8_t
buf[KERNELDUMP_BUFFER_SIZE];
1469 struct kerneldumpcrypto *kdc;
1475 while (length > 0) {
1479 if (dump_encrypt(kdc,
buf,
nbytes) != 0)
1487 virtual = (
void *)((uint8_t *)
virtual +
nbytes);
1498 struct dumperinfo *di;
1499 size_t resid, rlength;
1504 if (length % di->blocksize != 0) {
1511 rlength = rounddown(length, di->blocksize);
1517 resid = length - rlength;
1518 memmove(di->blockbuf, (uint8_t *)base + rlength, resid);
1519 bzero((uint8_t *)di->blockbuf + resid, di->blocksize - resid);
1520 di->kdcomp->kdc_resid = resid;
1535 struct kerneldumpcrypto *kdc;
1543 hdrsz =
sizeof(*kdh);
1544 if (hdrsz > di->blocksize)
1549 keysize = kerneldumpcrypto_dumpkeysize(kdc);
1558 if (di->dumper_hdr != NULL)
1559 return (di->dumper_hdr(di, kdh));
1561 if (hdrsz == di->blocksize)
1565 memset(
buf, 0, di->blocksize);
1566 memcpy(
buf, kdh, hdrsz);
1569 extent = dtoh64(kdh->dumpextent);
1573 di->mediaoffset + di->mediasize - di->blocksize - extent -
1581 di->mediaoffset + di->mediasize - 2 * di->blocksize - extent -
1582 keysize, di->blocksize);
1584 error =
dump_write(di,
buf, 0, di->mediaoffset + di->mediasize -
1585 di->blocksize, di->blocksize);
1593#define SIZEOF_METADATA (64 * 1024)
1619 struct kerneldumpcrypto *kdc;
1622 uint64_t dumpextent, span;
1629 error = kerneldumpcrypto_init(kdc);
1632 keysize = kerneldumpcrypto_dumpkeysize(kdc);
1633 key = keysize > 0 ? kdc->kdc_dumpkey : NULL;
1640 if (di->dumper_start != NULL) {
1641 error = di->dumper_start(di, key, keysize);
1643 dumpextent = dtoh64(kdh->dumpextent);
1646 if (di->mediasize < span) {
1647 if (di->kdcomp == NULL)
1658 dumpextent = di->mediasize - span + dumpextent;
1659 kdh->dumpextent = htod64(dumpextent);
1665 di->dumpoff = di->mediaoffset + di->mediasize - di->blocksize -
1668 di->origdumpoff = di->dumpoff;
1679 if (di->kdcrypto != NULL)
1680 error = dump_encrypted_write(di,
virtual, physical, di->dumpoff,
1684 error =
dump_write(di,
virtual, physical, di->dumpoff, length);
1686 di->dumpoff += length;
1696dump_append(
struct dumperinfo *di,
void *
virtual, vm_offset_t physical,
1701 if (di->kdcomp != NULL) {
1703 if (length > di->maxiosize)
1705 buf = di->kdcomp->kdc_buf;
1706 memmove(
buf,
virtual, length);
1716dump_write(
struct dumperinfo *di,
void *
virtual, vm_offset_t physical,
1717 off_t offset,
size_t length)
1724 return (di->dumper(di->priv,
virtual, physical, offset, length));
1738 if (di->kdcomp != NULL) {
1740 if (error == EAGAIN) {
1742 error =
_dump_append(di, di->blockbuf, 0, di->blocksize);
1745 di->dumpoff -= di->blocksize - di->kdcomp->kdc_resid;
1746 di->kdcomp->kdc_resid = 0;
1755 kdh->dumplength = htod64(di->dumpoff - di->origdumpoff);
1757 kdh->parity = kerneldump_parity(kdh);
1772 const char *magic, uint32_t archver, uint64_t dumplen)
1776 bzero(kdh,
sizeof(*kdh));
1777 strlcpy(kdh->magic, magic,
sizeof(kdh->magic));
1778 strlcpy(kdh->architecture, MACHINE_ARCH,
sizeof(kdh->architecture));
1779 kdh->version = htod32(KERNELDUMPVERSION);
1780 kdh->architectureversion = htod32(archver);
1781 kdh->dumplength = htod64(dumplen);
1782 kdh->dumpextent = kdh->dumplength;
1785 kdh->dumpkeysize = htod32(kerneldumpcrypto_dumpkeysize(di->kdcrypto));
1787 kdh->dumpkeysize = 0;
1789 kdh->blocksize = htod32(di->blocksize);
1790 strlcpy(kdh->hostname,
prison0.pr_hostname,
sizeof(kdh->hostname));
1791 dstsize =
sizeof(kdh->versionstring);
1792 if (strlcpy(kdh->versionstring, version, dstsize) >= dstsize)
1793 kdh->versionstring[dstsize - 2] =
'\n';
1795 strlcpy(kdh->panicstring,
panicstr,
sizeof(kdh->panicstring));
1796 if (di->kdcomp != NULL)
1797 kdh->compression = di->kdcomp->kdc_format;
1798 kdh->parity = kerneldump_parity(kdh);
1802DB_SHOW_COMMAND(
panic, db_show_panic)
1806 db_printf(
"panicstr not set\n");
1808 db_printf(
"panic: %s\n",
panicstr);
METHOD int shutdown
Called during system shutdown.
int __elfN() coredump(struct thread *td, struct vnode *vp, off_t limit, int flags)
void boottrace_dump_console(void)
SYSCTL_UINT(_kern_eventtimer, OID_AUTO, idletick, CTLFLAG_RWTUN, &idletick, 0, "Run periodic events when idle")
int make_dev_p(int flags, struct cdev **cdev, struct cdevsw *devsw, struct ucred *cr, uid_t uid, gid_t gid, int mode, const char *fmt,...)
void mountcheckdirs(struct vnode *olddp, struct vnode *newdp)
FEATURE(kdtrace_hooks, "Kernel DTrace hooks which are required to load DTrace kernel modules")
int kproc_suspend(struct proc *p, int timo)
int kthread_suspend(struct thread *td, int timo)
void *() malloc(size_t size, struct malloc_type *mtp, int flags)
void zfree(void *addr, struct malloc_type *mtp)
void free(void *addr, struct malloc_type *mtp)
struct mtx __exclusive_cache_line Giant
int priv_check(struct thread *td, int priv)
static bool powercycle_on_panic
static bool dumper_config_match(const struct dumperinfo *di, const char *devname, const struct diocskerneldump_arg *kda)
static MALLOC_DEFINE(M_DUMPER, "dumper", "dumper block buffer")
static int poweroff_delay
static struct kerneldumpcomp * kerneldumpcomp_create(struct dumperinfo *di, uint8_t compression)
int sys_reboot(struct thread *td, struct reboot_args *uap)
#define PANIC_REBOOT_WAIT_TIME
static void shutdown_conf(void *unused)
static int dump_check_bounds(struct dumperinfo *di, off_t offset, size_t length)
static struct task shutdown_nice_task
SYSCTL_PROC(_kern_shutdown, OID_AUTO, dumpdevname, CTLTYPE_STRING|CTLFLAG_RD|CTLFLAG_MPSAFE, &dumper_configs, 0, dumpdevname_sysctl_handler, "A", "Device(s) for kernel dumps")
static int kerneldumpcomp_write_cb(void *base, size_t len, off_t off, void *arg)
static int kern_reroot(void)
static void reroot_conf(void *unused)
static void print_uptime(void)
static void shutdown_nice_task_fn(void *arg, int pending __unused)
bool __read_frequently panicked
int dump_finish(struct dumperinfo *di, struct kerneldumpheader *kdh)
static int dump_write_headers(struct dumperinfo *di, struct kerneldumpheader *kdh)
static bool poweroff_on_panic
void kthread_shutdown(void *arg, int howto)
int dumper_remove(const char *devname, const struct diocskerneldump_arg *kda)
int dump_start(struct dumperinfo *di, struct kerneldumpheader *kdh)
static void reboottrace(int howto)
static void free_single_dumper(struct dumperinfo *di)
int dump_write(struct dumperinfo *di, void *virtual, vm_offset_t physical, off_t offset, size_t length)
static SYSCTL_NODE(_kern, OID_AUTO, shutdown, CTLFLAG_RW|CTLFLAG_MPSAFE, 0, "Shutdown environment")
int __read_mostly dumping
static void kerneldumpcomp_destroy(struct dumperinfo *di)
void dump_init_header(const struct dumperinfo *di, struct kerneldumpheader *kdh, const char *magic, uint32_t archver, uint64_t dumplen)
void shutdown_nice(int howto)
static void shutdown_reset(void *junk, int howto)
static struct mtx dumpconf_list_lk
void kproc_shutdown(void *arg, int howto)
static TAILQ_HEAD(dumpconflist, dumperinfo)
int doadump(boolean_t textdump)
int dumper_insert(const struct dumperinfo *di_template, const char *devname, const struct diocskerneldump_arg *kda)
static int dumpdevname_sysctl_handler(SYSCTL_HANDLER_ARGS)
static void shutdown_panic(void *junk, int howto)
SYSCTL_INT(_kern, OID_AUTO, panic_reboot_wait_time, CTLFLAG_RWTUN, &panic_reboot_wait_time, 0, "Seconds to wait before rebooting after a panic")
void kern_reboot(int howto)
static int _dump_append(struct dumperinfo *di, void *virtual, vm_offset_t physical, size_t length)
SYSCTL_BOOL(_kern, OID_AUTO, poweroff_on_panic, CTLFLAG_RWTUN, &poweroff_on_panic, 0, "Do a power off instead of a reboot on a panic")
static int kproc_shutdown_wait
SYSINIT(shutdown_conf, SI_SUB_INTRINSIC, SI_ORDER_ANY, shutdown_conf, NULL)
void panic(const char *fmt,...)
int dump_append(struct dumperinfo *di, void *virtual, vm_offset_t physical, size_t length)
void vpanic(const char *fmt, va_list ap)
static int panic_reboot_wait_time
static void poweroff_wait(void *, int)
MTX_SYSINIT(dumper_configs, &dumpconf_list_lk, "dumper config list", MTX_DEF)
static void shutdown_halt(void *junk, int howto)
static int kerneldump_gzlevel
void kern_psignal(struct proc *p, int sig)
int sysctl_wire_old_buffer(struct sysctl_req *req, size_t len)
int sysctl_handle_int(SYSCTL_HANDLER_ARGS)
struct sbuf * sbuf_new_for_sysctl(struct sbuf *s, char *buf, int length, struct sysctl_req *req)
void getnanouptime(struct timespec *tsp)
volatile time_t time_second
int ppsratecheck(struct timeval *lasttime, int *curpps, int maxpps)
void sched_bind(struct thread *td, int cpu)
struct compressor * kdc_stream
static bool kasan_enabled __read_mostly
int compressor_flush(struct compressor *stream)
void compressor_reset(struct compressor *stream)
void compressor_fini(struct compressor *stream)
int compressor_write(struct compressor *stream, void *data, size_t len)
struct compressor * compressor_init(compressor_cb_t cb, int format, size_t maxiosize, int level, void *arg)
u_char __read_frequently kdb_active
void kdb_enter(const char *why, const char *msg)
int vsnprintf(char *str, size_t size, const char *format, va_list ap)
int printf(const char *fmt,...)
int vprintf(const char *fmt, va_list ap)
int sbuf_finish(struct sbuf *s)
int sbuf_putc(struct sbuf *s, int c)
void sbuf_delete(struct sbuf *s)
int sbuf_cat(struct sbuf *s, const char *str)
int taskqueue_enqueue(struct taskqueue *queue, struct task *task)
void bufshutdown(int show_busybufs)
struct mtx_padalign __exclusive_cache_line mountlist_mtx
void vfs_rel(struct mount *mp)
void vfs_ref(struct mount *mp)
void vfs_unmountall(void)
void vfs_unbusy(struct mount *mp)
int vfs_busy(struct mount *mp, int flags)