Changeset View
Changeset View
Standalone View
Standalone View
head/sys/ddb/db_textdump.c
Show First 20 Lines • Show All 421 Lines • ▼ Show 20 Lines | |||||
} | } | ||||
/* | /* | ||||
* Commit text dump to disk. | * Commit text dump to disk. | ||||
*/ | */ | ||||
void | void | ||||
textdump_dumpsys(struct dumperinfo *di) | textdump_dumpsys(struct dumperinfo *di) | ||||
{ | { | ||||
struct kerneldumpcrypto *kdc; | |||||
off_t dumplen, trailer_offset; | off_t dumplen, trailer_offset; | ||||
if (di->blocksize != TEXTDUMP_BLOCKSIZE) { | if (di->blocksize != TEXTDUMP_BLOCKSIZE) { | ||||
printf("Dump partition block size (%ju) not textdump " | printf("Dump partition block size (%ju) not textdump " | ||||
"block size (%ju)", (uintmax_t)di->blocksize, | "block size (%ju)", (uintmax_t)di->blocksize, | ||||
(uintmax_t)TEXTDUMP_BLOCKSIZE); | (uintmax_t)TEXTDUMP_BLOCKSIZE); | ||||
return; | return; | ||||
} | } | ||||
/* | /* | ||||
* We don't know a priori how large the dump will be, but we do know | * We don't know a priori how large the dump will be, but we do know | ||||
* that we need to reserve space for metadata and that we need two | * that we need to reserve space for metadata and that we need two | ||||
* dump headers. Also leave room for one ustar header and one block | * dump headers. Also leave room for one ustar header and one block | ||||
* of data. | * of data. | ||||
*/ | */ | ||||
if (di->mediasize < SIZEOF_METADATA + 2 * sizeof(kdh)) { | if (di->mediasize < SIZEOF_METADATA + 2 * sizeof(kdh)) { | ||||
printf("Insufficient space on dump partition for minimal textdump.\n"); | printf("Insufficient space on dump partition for minimal textdump.\n"); | ||||
return; | return; | ||||
} | } | ||||
textdump_error = 0; | textdump_error = 0; | ||||
/* | /* | ||||
* Disable EKCD because we don't provide encrypted textdumps. | |||||
*/ | |||||
kdc = di->kdc; | |||||
di->kdc = NULL; | |||||
/* | |||||
* Position the start of the dump so that we'll write the kernel dump | * Position the start of the dump so that we'll write the kernel dump | ||||
* trailer immediately before the end of the partition, and then work | * trailer immediately before the end of the partition, and then work | ||||
* our way back. We will rewrite this header later to reflect the | * our way back. We will rewrite this header later to reflect the | ||||
* true size if things go well. | * true size if things go well. | ||||
*/ | */ | ||||
textdump_offset = di->mediasize - sizeof(kdh); | textdump_offset = di->mediasize - sizeof(kdh); | ||||
textdump_saveoff(&trailer_offset); | textdump_saveoff(&trailer_offset); | ||||
mkdumpheader(&kdh, TEXTDUMPMAGIC, KERNELDUMP_TEXT_VERSION, 0, TEXTDUMP_BLOCKSIZE); | mkdumpheader(&kdh, TEXTDUMPMAGIC, KERNELDUMP_TEXT_VERSION, 0, 0, | ||||
TEXTDUMP_BLOCKSIZE); | |||||
(void)textdump_writenextblock(di, (char *)&kdh); | (void)textdump_writenextblock(di, (char *)&kdh); | ||||
/* | /* | ||||
* Write a series of files in ustar format. | * Write a series of files in ustar format. | ||||
*/ | */ | ||||
if (textdump_do_ddb) | if (textdump_do_ddb) | ||||
db_capture_dump(di); | db_capture_dump(di); | ||||
#ifdef INCLUDE_CONFIG_FILE | #ifdef INCLUDE_CONFIG_FILE | ||||
if (textdump_do_config) | if (textdump_do_config) | ||||
textdump_dump_config(di); | textdump_dump_config(di); | ||||
#endif | #endif | ||||
if (textdump_do_msgbuf) | if (textdump_do_msgbuf) | ||||
textdump_dump_msgbuf(di); | textdump_dump_msgbuf(di); | ||||
if (textdump_do_panic && panicstr != NULL) | if (textdump_do_panic && panicstr != NULL) | ||||
textdump_dump_panic(di); | textdump_dump_panic(di); | ||||
if (textdump_do_version) | if (textdump_do_version) | ||||
textdump_dump_version(di); | textdump_dump_version(di); | ||||
/* | /* | ||||
* Now that we know the true size, we can write out the header, then | * Now that we know the true size, we can write out the header, then | ||||
* seek back to the end and rewrite the trailer with the correct | * seek back to the end and rewrite the trailer with the correct | ||||
* size. | * size. | ||||
*/ | */ | ||||
dumplen = trailer_offset - (textdump_offset + TEXTDUMP_BLOCKSIZE); | dumplen = trailer_offset - (textdump_offset + TEXTDUMP_BLOCKSIZE); | ||||
mkdumpheader(&kdh, TEXTDUMPMAGIC, KERNELDUMP_TEXT_VERSION, dumplen, | mkdumpheader(&kdh, TEXTDUMPMAGIC, KERNELDUMP_TEXT_VERSION, dumplen, 0, | ||||
TEXTDUMP_BLOCKSIZE); | TEXTDUMP_BLOCKSIZE); | ||||
(void)textdump_writenextblock(di, (char *)&kdh); | (void)textdump_writenextblock(di, (char *)&kdh); | ||||
textdump_restoreoff(trailer_offset); | textdump_restoreoff(trailer_offset); | ||||
(void)textdump_writenextblock(di, (char *)&kdh); | (void)textdump_writenextblock(di, (char *)&kdh); | ||||
/* | /* | ||||
* Terminate the dump, report any errors, and clear the pending flag. | * Terminate the dump, report any errors, and clear the pending flag. | ||||
*/ | */ | ||||
if (textdump_error == 0) | if (textdump_error == 0) | ||||
(void)dump_write(di, NULL, 0, 0, 0); | (void)dump_write(di, NULL, 0, 0, 0); | ||||
if (textdump_error == ENOSPC) | if (textdump_error == ENOSPC) | ||||
printf("Textdump: Insufficient space on dump partition\n"); | printf("Textdump: Insufficient space on dump partition\n"); | ||||
else if (textdump_error != 0) | else if (textdump_error != 0) | ||||
printf("Textdump: Error %d writing dump\n", textdump_error); | printf("Textdump: Error %d writing dump\n", textdump_error); | ||||
else | else | ||||
printf("Textdump complete.\n"); | printf("Textdump complete.\n"); | ||||
textdump_pending = 0; | textdump_pending = 0; | ||||
/* | |||||
* Restore EKCD status. | |||||
*/ | |||||
di->kdc = kdc; | |||||
} | } | ||||
/*- | /*- | ||||
* DDB(4) command to manage textdumps: | * DDB(4) command to manage textdumps: | ||||
* | * | ||||
* textdump set - request a textdump | * textdump set - request a textdump | ||||
* textdump status - print DDB output textdump status | * textdump status - print DDB output textdump status | ||||
* textdump unset - clear textdump request | * textdump unset - clear textdump request | ||||
Show All 40 Lines |