Changeset View
Changeset View
Standalone View
Standalone View
head/sys/kern/kern_shutdown.c
Show First 20 Lines • Show All 82 Lines • ▼ Show 20 Lines | |||||
#include <vm/vm.h> | #include <vm/vm.h> | ||||
#include <vm/vm_object.h> | #include <vm/vm_object.h> | ||||
#include <vm/vm_page.h> | #include <vm/vm_page.h> | ||||
#include <vm/vm_pager.h> | #include <vm/vm_pager.h> | ||||
#include <vm/swap_pager.h> | #include <vm/swap_pager.h> | ||||
#include <sys/signalvar.h> | #include <sys/signalvar.h> | ||||
static MALLOC_DEFINE(M_DUMPER, "dumper", "dumper block buffer"); | |||||
#ifndef PANIC_REBOOT_WAIT_TIME | #ifndef PANIC_REBOOT_WAIT_TIME | ||||
#define PANIC_REBOOT_WAIT_TIME 15 /* default to 15 seconds */ | #define PANIC_REBOOT_WAIT_TIME 15 /* default to 15 seconds */ | ||||
#endif | #endif | ||||
static int panic_reboot_wait_time = PANIC_REBOOT_WAIT_TIME; | static int panic_reboot_wait_time = PANIC_REBOOT_WAIT_TIME; | ||||
SYSCTL_INT(_kern, OID_AUTO, panic_reboot_wait_time, CTLFLAG_RWTUN, | SYSCTL_INT(_kern, OID_AUTO, panic_reboot_wait_time, CTLFLAG_RWTUN, | ||||
&panic_reboot_wait_time, 0, | &panic_reboot_wait_time, 0, | ||||
"Seconds to wait before rebooting after a panic"); | "Seconds to wait before rebooting after a panic"); | ||||
▲ Show 20 Lines • Show All 744 Lines • ▼ Show 20 Lines | set_dumper(struct dumperinfo *di, const char *devname, struct thread *td) | ||||
size_t wantcopy; | size_t wantcopy; | ||||
int error; | int error; | ||||
error = priv_check(td, PRIV_SETDUMPER); | error = priv_check(td, PRIV_SETDUMPER); | ||||
if (error != 0) | if (error != 0) | ||||
return (error); | return (error); | ||||
if (di == NULL) { | if (di == NULL) { | ||||
bzero(&dumper, sizeof dumper); | if (dumper.blockbuf != NULL) | ||||
free(dumper.blockbuf, M_DUMPER); | |||||
bzero(&dumper, sizeof(dumper)); | |||||
dumpdevname[0] = '\0'; | dumpdevname[0] = '\0'; | ||||
return (0); | return (0); | ||||
} | } | ||||
if (dumper.dumper != NULL) | if (dumper.dumper != NULL) | ||||
return (EBUSY); | return (EBUSY); | ||||
dumper = *di; | dumper = *di; | ||||
wantcopy = strlcpy(dumpdevname, devname, sizeof(dumpdevname)); | wantcopy = strlcpy(dumpdevname, devname, sizeof(dumpdevname)); | ||||
if (wantcopy >= sizeof(dumpdevname)) { | if (wantcopy >= sizeof(dumpdevname)) { | ||||
printf("set_dumper: device name truncated from '%s' -> '%s'\n", | printf("set_dumper: device name truncated from '%s' -> '%s'\n", | ||||
devname, dumpdevname); | devname, dumpdevname); | ||||
} | } | ||||
dumper.blockbuf = malloc(di->blocksize, M_DUMPER, M_WAITOK | M_ZERO); | |||||
return (0); | return (0); | ||||
} | } | ||||
/* Call dumper with bounds checking. */ | /* Call dumper with bounds checking. */ | ||||
int | int | ||||
dump_write(struct dumperinfo *di, void *virtual, vm_offset_t physical, | dump_write(struct dumperinfo *di, void *virtual, vm_offset_t physical, | ||||
off_t offset, size_t length) | off_t offset, size_t length) | ||||
{ | { | ||||
if (length != 0 && (offset < di->mediaoffset || | if (length != 0 && (offset < di->mediaoffset || | ||||
offset - di->mediaoffset + length > di->mediasize)) { | offset - di->mediaoffset + length > di->mediasize)) { | ||||
printf("Attempt to write outside dump device boundaries.\n" | printf("Attempt to write outside dump device boundaries.\n" | ||||
"offset(%jd), mediaoffset(%jd), length(%ju), mediasize(%jd).\n", | "offset(%jd), mediaoffset(%jd), length(%ju), mediasize(%jd).\n", | ||||
(intmax_t)offset, (intmax_t)di->mediaoffset, | (intmax_t)offset, (intmax_t)di->mediaoffset, | ||||
(uintmax_t)length, (intmax_t)di->mediasize); | (uintmax_t)length, (intmax_t)di->mediasize); | ||||
return (ENOSPC); | return (ENOSPC); | ||||
} | } | ||||
return (di->dumper(di->priv, virtual, physical, offset, length)); | return (di->dumper(di->priv, virtual, physical, offset, length)); | ||||
} | } | ||||
/* Call dumper with bounds checking. */ | |||||
int | |||||
dump_write_pad(struct dumperinfo *di, void *virtual, vm_offset_t physical, | |||||
off_t offset, size_t length, size_t *size) | |||||
{ | |||||
char *temp; | |||||
int ret; | |||||
if (length > di->blocksize) | |||||
return (ENOMEM); | |||||
*size = di->blocksize; | |||||
if (length == di->blocksize) | |||||
temp = virtual; | |||||
else { | |||||
temp = di->blockbuf; | |||||
memset(temp + length, 0, di->blocksize - length); | |||||
memcpy(temp, virtual, length); | |||||
} | |||||
ret = dump_write(di, temp, physical, offset, *size); | |||||
return (ret); | |||||
} | |||||
void | void | ||||
mkdumpheader(struct kerneldumpheader *kdh, char *magic, uint32_t archver, | mkdumpheader(struct kerneldumpheader *kdh, char *magic, uint32_t archver, | ||||
uint64_t dumplen, uint32_t blksz) | uint64_t dumplen, uint32_t blksz) | ||||
{ | { | ||||
bzero(kdh, sizeof(*kdh)); | bzero(kdh, sizeof(*kdh)); | ||||
strlcpy(kdh->magic, magic, sizeof(kdh->magic)); | strlcpy(kdh->magic, magic, sizeof(kdh->magic)); | ||||
Show All 12 Lines |