Changeset View
Changeset View
Standalone View
Standalone View
head/sbin/savecore/savecore.c
Show First 20 Lines • Show All 430 Lines • ▼ Show 20 Lines | DoTextdumpFile(int fd, off_t dumpsize, off_t lasthd, char *buf, | ||||
return (0); | return (0); | ||||
} | } | ||||
static void | static void | ||||
DoFile(const char *savedir, const char *device) | DoFile(const char *savedir, const char *device) | ||||
{ | { | ||||
xo_handle_t *xostdout, *xoinfo; | xo_handle_t *xostdout, *xoinfo; | ||||
static char infoname[PATH_MAX], corename[PATH_MAX], linkname[PATH_MAX]; | static char infoname[PATH_MAX], corename[PATH_MAX], linkname[PATH_MAX]; | ||||
static char *buf = NULL; | static char *buf = NULL, *temp = NULL; | ||||
struct kerneldumpheader kdhf, kdhl; | struct kerneldumpheader kdhf, kdhl; | ||||
off_t mediasize, dumpsize, firsthd, lasthd; | off_t mediasize, dumpsize, firsthd, lasthd; | ||||
FILE *info, *fp; | FILE *info, *fp; | ||||
mode_t oumask; | mode_t oumask; | ||||
int fd, fdinfo, error; | int fd, fdinfo, error; | ||||
int bounds, status; | int bounds, status; | ||||
u_int sectorsize, xostyle; | u_int sectorsize, xostyle; | ||||
int istextdump; | int istextdump; | ||||
Show All 37 Lines | if (error) { | ||||
goto closefd; | goto closefd; | ||||
} | } | ||||
if (verbose) { | if (verbose) { | ||||
printf("mediasize = %lld\n", (long long)mediasize); | printf("mediasize = %lld\n", (long long)mediasize); | ||||
printf("sectorsize = %u\n", sectorsize); | printf("sectorsize = %u\n", sectorsize); | ||||
} | } | ||||
if (sectorsize < sizeof(kdhl)) { | |||||
syslog(LOG_ERR, | |||||
"Sector size is less the kernel dump header %zu", | |||||
sizeof(kdhl)); | |||||
goto closefd; | |||||
} | |||||
lasthd = mediasize - sectorsize; | lasthd = mediasize - sectorsize; | ||||
if (temp == NULL) { | |||||
temp = malloc(sectorsize); | |||||
if (temp == NULL) { | |||||
syslog(LOG_ERR, "%m"); | |||||
return; | |||||
} | |||||
} | |||||
if (lseek(fd, lasthd, SEEK_SET) != lasthd || | if (lseek(fd, lasthd, SEEK_SET) != lasthd || | ||||
read(fd, &kdhl, sizeof(kdhl)) != sizeof(kdhl)) { | read(fd, temp, sectorsize) != sectorsize) { | ||||
syslog(LOG_ERR, | syslog(LOG_ERR, | ||||
"error reading last dump header at offset %lld in %s: %m", | "error reading last dump header at offset %lld in %s: %m", | ||||
(long long)lasthd, device); | (long long)lasthd, device); | ||||
goto closefd; | goto closefd; | ||||
} | } | ||||
memcpy(&kdhl, temp, sizeof(kdhl)); | |||||
istextdump = 0; | istextdump = 0; | ||||
if (strncmp(kdhl.magic, TEXTDUMPMAGIC, sizeof kdhl) == 0) { | if (strncmp(kdhl.magic, TEXTDUMPMAGIC, sizeof kdhl) == 0) { | ||||
if (verbose) | if (verbose) | ||||
printf("textdump magic on last dump header on %s\n", | printf("textdump magic on last dump header on %s\n", | ||||
device); | device); | ||||
istextdump = 1; | istextdump = 1; | ||||
if (dtoh32(kdhl.version) != KERNELDUMP_TEXT_VERSION) { | if (dtoh32(kdhl.version) != KERNELDUMP_TEXT_VERSION) { | ||||
syslog(LOG_ERR, | syslog(LOG_ERR, | ||||
▲ Show 20 Lines • Show All 53 Lines • ▼ Show 20 Lines | if (kerneldump_parity(&kdhl)) { | ||||
syslog(LOG_ERR, | syslog(LOG_ERR, | ||||
"parity error on last dump header on %s", device); | "parity error on last dump header on %s", device); | ||||
nerr++; | nerr++; | ||||
status = STATUS_BAD; | status = STATUS_BAD; | ||||
if (force == 0) | if (force == 0) | ||||
goto closefd; | goto closefd; | ||||
} | } | ||||
dumpsize = dtoh64(kdhl.dumplength); | dumpsize = dtoh64(kdhl.dumplength); | ||||
firsthd = lasthd - dumpsize - sizeof kdhf; | firsthd = lasthd - dumpsize - sectorsize; | ||||
if (lseek(fd, firsthd, SEEK_SET) != firsthd || | if (lseek(fd, firsthd, SEEK_SET) != firsthd || | ||||
read(fd, &kdhf, sizeof(kdhf)) != sizeof(kdhf)) { | read(fd, temp, sectorsize) != sectorsize) { | ||||
syslog(LOG_ERR, | syslog(LOG_ERR, | ||||
"error reading first dump header at offset %lld in %s: %m", | "error reading first dump header at offset %lld in %s: %m", | ||||
(long long)firsthd, device); | (long long)firsthd, device); | ||||
nerr++; | nerr++; | ||||
goto closefd; | goto closefd; | ||||
} | } | ||||
memcpy(&kdhf, temp, sizeof(kdhf)); | |||||
if (verbose >= 2) { | if (verbose >= 2) { | ||||
printf("First dump headers:\n"); | printf("First dump headers:\n"); | ||||
printheader(xostdout, &kdhf, device, bounds, -1); | printheader(xostdout, &kdhf, device, bounds, -1); | ||||
printf("\nLast dump headers:\n"); | printf("\nLast dump headers:\n"); | ||||
printheader(xostdout, &kdhl, device, bounds, -1); | printheader(xostdout, &kdhl, device, bounds, -1); | ||||
printf("\n"); | printf("\n"); | ||||
} | } | ||||
if (memcmp(&kdhl, &kdhf, sizeof kdhl)) { | if (memcmp(&kdhl, &kdhf, sizeof(kdhl))) { | ||||
syslog(LOG_ERR, | syslog(LOG_ERR, | ||||
"first and last dump headers disagree on %s", device); | "first and last dump headers disagree on %s", device); | ||||
nerr++; | nerr++; | ||||
status = STATUS_BAD; | status = STATUS_BAD; | ||||
if (force == 0) | if (force == 0) | ||||
goto closefd; | goto closefd; | ||||
} else { | } else { | ||||
status = STATUS_GOOD; | status = STATUS_GOOD; | ||||
} | } | ||||
if (checkfor) { | if (checkfor) { | ||||
printf("A dump exists on %s\n", device); | printf("A dump exists on %s\n", device); | ||||
close(fd); | close(fd); | ||||
exit(0); | exit(0); | ||||
} | } | ||||
if (kdhl.panicstring[0]) | if (kdhl.panicstring[0] != '\0') | ||||
syslog(LOG_ALERT, "reboot after panic: %*s", | syslog(LOG_ALERT, "reboot after panic: %*s", | ||||
(int)sizeof(kdhl.panicstring), kdhl.panicstring); | (int)sizeof(kdhl.panicstring), kdhl.panicstring); | ||||
else | else | ||||
syslog(LOG_ALERT, "reboot"); | syslog(LOG_ALERT, "reboot"); | ||||
if (verbose) | if (verbose) | ||||
printf("Checking for available free space\n"); | printf("Checking for available free space\n"); | ||||
▲ Show 20 Lines • Show All 104 Lines • ▼ Show 20 Lines | DoFile(const char *savedir, const char *device) | ||||
if (verbose) | if (verbose) | ||||
printf("dump saved\n"); | printf("dump saved\n"); | ||||
nuke: | nuke: | ||||
if (!keep) { | if (!keep) { | ||||
if (verbose) | if (verbose) | ||||
printf("clearing dump header\n"); | printf("clearing dump header\n"); | ||||
memcpy(kdhl.magic, KERNELDUMPMAGIC_CLEARED, sizeof kdhl.magic); | memcpy(kdhl.magic, KERNELDUMPMAGIC_CLEARED, sizeof(kdhl.magic)); | ||||
memcpy(temp, &kdhl, sizeof(kdhl)); | |||||
if (lseek(fd, lasthd, SEEK_SET) != lasthd || | if (lseek(fd, lasthd, SEEK_SET) != lasthd || | ||||
write(fd, &kdhl, sizeof(kdhl)) != sizeof(kdhl)) | write(fd, temp, sectorsize) != sectorsize) | ||||
syslog(LOG_ERR, | syslog(LOG_ERR, | ||||
"error while clearing the dump header: %m"); | "error while clearing the dump header: %m"); | ||||
} | } | ||||
xo_close_container_h(xostdout, "crashdump"); | xo_close_container_h(xostdout, "crashdump"); | ||||
xo_finish_h(xostdout); | xo_finish_h(xostdout); | ||||
close(fd); | close(fd); | ||||
return; | return; | ||||
▲ Show 20 Lines • Show All 124 Lines • Show Last 20 Lines |