Print this page
10654 savecore(1M) should be able to work on read-only dump devices
Reviewed by: Robert Mustacchi <rm@joyent.com>
Reviewed by: John Levon <john.levon@joyent.com>
Reviewed by: Andy Stormont <astormont@racktopsystems.com>
Reviewed by: Gergő Doma <domag02@gmail.com>
Reviewed by: Toomas Soome <tsoome@me.com>

*** 18,28 **** * * CDDL HEADER END */ /* * Copyright (c) 1983, 2010, Oracle and/or its affiliates. All rights reserved. ! * Copyright 2016 Joyent, Inc. */ /* * Copyright 2016 Nexenta Systems, Inc. All rights reserved. */ --- 18,28 ---- * * CDDL HEADER END */ /* * Copyright (c) 1983, 2010, Oracle and/or its affiliates. All rights reserved. ! * Copyright 2019 Joyent, Inc. */ /* * Copyright 2016 Nexenta Systems, Inc. All rights reserved. */
*** 90,99 **** --- 90,100 ---- static volatile uint64_t zpages; /* count of zero pages not written */ static dumpdatahdr_t datahdr; /* compression info */ static long coreblksize; /* preferred write size (st_blksize) */ static int cflag; /* run as savecore -c */ static int mflag; /* run as savecore -m */ + static int rflag; /* run as savecore -r */ /* * Payload information for the events we raise. These are used * in raise_event to determine what payload to include. */
*** 162,172 **** static void usage(void) { (void) fprintf(stderr, ! "usage: %s [-Lvd] [-f dumpfile] [dirname]\n", progname); exit(1); } #define SC_SL_NONE 0x0001 /* no syslog */ #define SC_SL_ERR 0x0002 /* syslog if !interactive, LOG_ERR */ --- 163,173 ---- static void usage(void) { (void) fprintf(stderr, ! "usage: %s [-L | -r] [-vd] [-f dumpfile] [dirname]\n", progname); exit(1); } #define SC_SL_NONE 0x0001 /* no syslog */ #define SC_SL_ERR 0x0002 /* syslog if !interactive, LOG_ERR */
*** 227,237 **** /* * Raise an ireport saying why we are exiting. Do not * raise if run as savecore -m. If something in the * raise_event codepath calls logprint avoid recursion. */ ! if (!mflag && logprint_raised++ == 0) raise_event(SC_EVENT_SAVECORE_FAILURE, buf); code = 2; break; case SC_EXIT_FM: --- 228,238 ---- /* * Raise an ireport saying why we are exiting. Do not * raise if run as savecore -m. If something in the * raise_event codepath calls logprint avoid recursion. */ ! if (!mflag && !rflag && logprint_raised++ == 0) raise_event(SC_EVENT_SAVECORE_FAILURE, buf); code = 2; break; case SC_EXIT_FM:
*** 238,248 **** code = 3; break; case SC_EXIT_ERR: default: ! if (!mflag && logprint_raised++ == 0 && have_dumpfile) raise_event(SC_EVENT_SAVECORE_FAILURE, buf); code = 1; break; } --- 239,249 ---- code = 3; break; case SC_EXIT_ERR: default: ! if (!mflag && !rflag && logprint_raised++ == 0 && have_dumpfile) raise_event(SC_EVENT_SAVECORE_FAILURE, buf); code = 1; break; }
*** 353,363 **** } static void read_dumphdr(void) { ! if (filemode) dumpfd = Open(dumpfile, O_RDONLY, 0644); else dumpfd = Open(dumpfile, O_RDWR | O_DSYNC, 0644); endoff = llseek(dumpfd, -DUMP_OFFSET, SEEK_END) & -DUMP_OFFSET; Pread(dumpfd, &dumphdr, sizeof (dumphdr), endoff); --- 354,364 ---- } static void read_dumphdr(void) { ! if (filemode || rflag) dumpfd = Open(dumpfile, O_RDONLY, 0644); else dumpfd = Open(dumpfile, O_RDWR | O_DSYNC, 0644); endoff = llseek(dumpfd, -DUMP_OFFSET, SEEK_END) & -DUMP_OFFSET; Pread(dumpfd, &dumphdr, sizeof (dumphdr), endoff);
*** 406,416 **** if (memcmp(&corehdr, &dumphdr, sizeof (dumphdr_t)) != 0) { /* * Clear valid bit so we don't complain on every invocation. */ ! if (!filemode) Pwrite(dumpfd, &dumphdr, sizeof (dumphdr), endoff); logprint(SC_SL_ERR | SC_EXIT_ERR, "initial dump header corrupt"); } } --- 407,417 ---- if (memcmp(&corehdr, &dumphdr, sizeof (dumphdr_t)) != 0) { /* * Clear valid bit so we don't complain on every invocation. */ ! if (!filemode && !rflag) Pwrite(dumpfd, &dumphdr, sizeof (dumphdr), endoff); logprint(SC_SL_ERR | SC_EXIT_ERR, "initial dump header corrupt"); } }
*** 658,668 **** /* * Write out the modified dump header to the dump device. * The dump device has been processed, so DF_VALID is clear. */ ! if (!filemode) Pwrite(dumpfd, &dumphdr, sizeof (dumphdr), endoff); (void) close(corefd); } --- 659,669 ---- /* * Write out the modified dump header to the dump device. * The dump device has been processed, so DF_VALID is clear. */ ! if (!filemode && !rflag) Pwrite(dumpfd, &dumphdr, sizeof (dumphdr), endoff); (void) close(corefd); }
*** 1420,1430 **** /* * Write out the modified dump headers. */ Pwrite(corefd, &corehdr, sizeof (corehdr), 0); ! if (!filemode) Pwrite(dumpfd, &dumphdr, sizeof (dumphdr), endoff); (void) close(corefd); } --- 1421,1431 ---- /* * Write out the modified dump headers. */ Pwrite(corefd, &corehdr, sizeof (corehdr), 0); ! if (!filemode && !rflag) Pwrite(dumpfd, &dumphdr, sizeof (dumphdr), endoff); (void) close(corefd); }
*** 1529,1538 **** --- 1530,1542 ---- summary_dump_t sd; offset_t dumpoff = -(DUMP_OFFSET + DUMP_LOGSIZE + DUMP_ERPTSIZE); dumpoff -= DUMP_SUMMARYSIZE; + if (rflag) + dumpfd = Open(dumpfile, O_RDONLY, 0644); + else dumpfd = Open(dumpfile, O_RDWR | O_DSYNC, 0644); dumpoff = llseek(dumpfd, dumpoff, SEEK_END) & -DUMP_OFFSET; Pread(dumpfd, &sd, sizeof (summary_dump_t), dumpoff); dumpoff += sizeof (summary_dump_t);
*** 1666,1676 **** (void) defopen("/etc/dumpadm.conf"); savedir = defread("DUMPADM_SAVDIR="); if (savedir != NULL) savedir = strdup(savedir); ! while ((c = getopt(argc, argv, "Lvcdmf:")) != EOF) { switch (c) { case 'L': livedump++; break; case 'v': --- 1670,1680 ---- (void) defopen("/etc/dumpadm.conf"); savedir = defread("DUMPADM_SAVDIR="); if (savedir != NULL) savedir = strdup(savedir); ! while ((c = getopt(argc, argv, "Lvcdmf:r")) != EOF) { switch (c) { case 'L': livedump++; break; case 'v':
*** 1683,1692 **** --- 1687,1699 ---- disregard_valid_flag++; break; case 'm': mflag++; break; + case 'r': + rflag++; + break; case 'f': dumpfile = optarg; filebounds = getbounds(dumpfile); break; case '?':
*** 1707,1716 **** --- 1714,1726 ---- interactive = isatty(STDOUT_FILENO); if (cflag && livedump) usage(); + if (rflag && (cflag || mflag || livedump)) + usage(); + if (dumpfile == NULL || livedump) dumpfd = Open("/dev/dump", O_RDONLY, 0444); if (dumpfile == NULL) { dumpfile = Zalloc(MAXPATHLEN);
*** 1750,1760 **** * We want this message to go to the log file, but not the console. * There's no good way to do that with the existing syslog facility. * We could extend it to handle this, but there doesn't seem to be * a general need for it, so we isolate the complexity here instead. */ ! if (dumphdr.dump_panicstring[0] != '\0') { int logfd = Open("/dev/conslog", O_WRONLY, 0644); log_ctl_t lc; struct strbuf ctl, dat; char msg[DUMP_PANICSIZE + 100]; char fmt[] = "reboot after panic: %s"; --- 1760,1770 ---- * We want this message to go to the log file, but not the console. * There's no good way to do that with the existing syslog facility. * We could extend it to handle this, but there doesn't seem to be * a general need for it, so we isolate the complexity here instead. */ ! if (dumphdr.dump_panicstring[0] != '\0' && !rflag) { int logfd = Open("/dev/conslog", O_WRONLY, 0644); log_ctl_t lc; struct strbuf ctl, dat; char msg[DUMP_PANICSIZE + 100]; char fmt[] = "reboot after panic: %s";
*** 1799,1809 **** * ereports off the dump device independently of savecore and * will make a diagnosis, so we don't want to open two cases * for the same event. Also avoid raising an event for a * livedump, or when we inflating a compressed dump. */ ! if (!fm_panic && !livedump && !filemode) raise_event(SC_EVENT_DUMP_PENDING, NULL); logprint(SC_SL_WARN, "System dump time: %s", ctime(&dumphdr.dump_crashtime)); --- 1809,1819 ---- * ereports off the dump device independently of savecore and * will make a diagnosis, so we don't want to open two cases * for the same event. Also avoid raising an event for a * livedump, or when we inflating a compressed dump. */ ! if (!fm_panic && !livedump && !filemode && !rflag) raise_event(SC_EVENT_DUMP_PENDING, NULL); logprint(SC_SL_WARN, "System dump time: %s", ctime(&dumphdr.dump_crashtime));
*** 1855,1865 **** /* * Raise a fault management event that indicates the system * has panicked. We know a reasonable amount about the * condition at this time, but the dump is still compressed. */ ! if (!livedump && !fm_panic) raise_event(SC_EVENT_DUMP_AVAILABLE, NULL); if (metrics_size > 0) { int sec = (gethrtime() - startts) / 1000 / 1000 / 1000; FILE *mfile = fopen(METRICSFILE, "a"); --- 1865,1875 ---- /* * Raise a fault management event that indicates the system * has panicked. We know a reasonable amount about the * condition at this time, but the dump is still compressed. */ ! if (!livedump && !fm_panic && !rflag) raise_event(SC_EVENT_DUMP_AVAILABLE, NULL); if (metrics_size > 0) { int sec = (gethrtime() - startts) / 1000 / 1000 / 1000; FILE *mfile = fopen(METRICSFILE, "a");
*** 1924,1934 **** "saving system crash dump in %s/{unix,vmcore}.%ld", savedir, bounds); build_corefile(namelist, corefile); ! if (!livedump && !filemode && !fm_panic) raise_event(SC_EVENT_DUMP_AVAILABLE, NULL); if (access(METRICSFILE, F_OK) == 0) { int sec = (gethrtime() - startts) / 1000 / 1000 / 1000; FILE *mfile = fopen(METRICSFILE, "a"); --- 1934,1944 ---- "saving system crash dump in %s/{unix,vmcore}.%ld", savedir, bounds); build_corefile(namelist, corefile); ! if (!livedump && !filemode && !fm_panic && !rflag) raise_event(SC_EVENT_DUMP_AVAILABLE, NULL); if (access(METRICSFILE, F_OK) == 0) { int sec = (gethrtime() - startts) / 1000 / 1000 / 1000; FILE *mfile = fopen(METRICSFILE, "a");