diff options
Diffstat (limited to 'usr/src/uts/common/os/dumpsubr.c')
| -rw-r--r-- | usr/src/uts/common/os/dumpsubr.c | 101 |
1 files changed, 101 insertions, 0 deletions
diff --git a/usr/src/uts/common/os/dumpsubr.c b/usr/src/uts/common/os/dumpsubr.c index 1c766842de..0ae9c3d390 100644 --- a/usr/src/uts/common/os/dumpsubr.c +++ b/usr/src/uts/common/os/dumpsubr.c @@ -107,6 +107,7 @@ int dump_timeout = 120; /* timeout for dumping pages */ int dump_timeleft; /* portion of dump_timeout remaining */ int dump_ioerr; /* dump i/o error */ int dump_check_used; /* enable check for used pages */ +char *dump_stack_scratch; /* scratch area for saving stack summary */ /* * Tunables for dump compression and parallelism. These can be set via @@ -258,6 +259,12 @@ struct cbuf { int off; /* byte offset to first pfn */ }; +static char dump_osimage_uuid[36 + 1]; + +#define isdigit(ch) ((ch) >= '0' && (ch) <= '9') +#define isxdigit(ch) (isdigit(ch) || ((ch) >= 'a' && (ch) <= 'f') || \ + ((ch) >= 'A' && (ch) <= 'F')) + /* * cqueue_t queues: a uni-directional channel for communication * from the master to helper tasks or vice-versa using put and @@ -1103,6 +1110,9 @@ dumphdr_init(void) dumpcfg.pids = kmem_alloc(v.v_proc * sizeof (pid_t), KM_SLEEP); dumpcfg.helpermap = kmem_zalloc(BT_SIZEOFMAP(NCPU), KM_SLEEP); LOCK_INIT_HELD(&dumpcfg.helper_lock); + dump_stack_scratch = kmem_alloc(STACK_BUF_SIZE, KM_SLEEP); + (void) strncpy(dumphdr->dump_uuid, dump_get_uuid(), + sizeof (dumphdr->dump_uuid)); } npages = num_phys_pages(); @@ -1436,6 +1446,48 @@ dump_process(pid_t pid) return (0); } +/* + * The following functions (dump_summary(), dump_ereports(), and + * dump_messages()), write data to an uncompressed area within the + * crashdump. The layout of these is + * + * +------------------------------------------------------------+ + * | compressed pages | summary | ereports | messages | + * +------------------------------------------------------------+ + * + * With the advent of saving a compressed crash dump by default, we + * need to save a little more data to describe the failure mode in + * an uncompressed buffer available before savecore uncompresses + * the dump. Initially this is a copy of the stack trace. Additional + * summary information should be added here. + */ + +void +dump_summary(void) +{ + u_offset_t dumpvp_start; + summary_dump_t sd; + + if (dumpvp == NULL || dumphdr == NULL) + return; + + dumpbuf.cur = dumpbuf.start; + + dumpbuf.vp_limit = dumpvp_size - (DUMP_OFFSET + DUMP_LOGSIZE + + DUMP_ERPTSIZE); + dumpvp_start = dumpbuf.vp_limit - DUMP_SUMMARYSIZE; + dumpbuf.vp_off = dumpvp_start; + + sd.sd_magic = SUMMARY_MAGIC; + sd.sd_ssum = checksum32(dump_stack_scratch, STACK_BUF_SIZE); + dumpvp_write(&sd, sizeof (sd)); + dumpvp_write(dump_stack_scratch, STACK_BUF_SIZE); + + sd.sd_magic = 0; /* indicate end of summary */ + dumpvp_write(&sd, sizeof (sd)); + (void) dumpvp_flush(); +} + void dump_ereports(void) { @@ -2859,6 +2911,10 @@ dumpsys(void) size -= datahdr.dump_metrics; } + /* record in the header whether this is a fault-management panic */ + if (panicstr) + dumphdr->dump_fm_panic = is_fm_panic(); + /* compression info in data header */ datahdr.dump_datahdr_magic = DUMP_DATAHDR_MAGIC; datahdr.dump_datahdr_version = DUMP_DATAHDR_VERSION; @@ -2905,6 +2961,7 @@ dumpsys(void) * thing we do because the dump process itself emits messages. */ if (panicstr) { + dump_summary(); dump_ereports(); dump_messages(); } @@ -2967,3 +3024,47 @@ dumpvp_resize() mutex_exit(&dump_lock); return (0); } + +int +dump_set_uuid(const char *uuidstr) +{ + const char *ptr; + int i; + + if (uuidstr == NULL || strnlen(uuidstr, 36 + 1) != 36) + return (EINVAL); + + /* uuid_parse is not common code so check manually */ + for (i = 0, ptr = uuidstr; i < 36; i++, ptr++) { + switch (i) { + case 8: + case 13: + case 18: + case 23: + if (*ptr != '-') + return (EINVAL); + break; + + default: + if (!isxdigit(*ptr)) + return (EINVAL); + break; + } + } + + if (dump_osimage_uuid[0] != '\0') + return (EALREADY); + + (void) strncpy(dump_osimage_uuid, uuidstr, 36 + 1); + + cmn_err(CE_CONT, "?This Solaris instance has UUID %s", + dump_osimage_uuid); + + return (0); +} + +const char * +dump_get_uuid(void) +{ + return (dump_osimage_uuid[0] != '\0' ? dump_osimage_uuid : ""); +} |
