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");