summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHans Rosenfeld <hans.rosenfeld@joyent.com>2019-03-21 13:00:19 +0000
committerHans Rosenfeld <hans.rosenfeld@joyent.com>2019-03-21 14:29:57 +0000
commit8e6d083b0f4cf225cf85597a4b87f60d7cc25a4a (patch)
treec9c53f5dad8f249d0f8d6cb34bbe67bac198da41
parentaa302656385001628e17e2a5f29a9b9f9ba70efe (diff)
downloadillumos-joyent-8e6d083b0f4cf225cf85597a4b87f60d7cc25a4a.tar.gz
OS-7607 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> Approved by: John Levon <john.levon@joyent.com>
-rw-r--r--usr/src/cmd/savecore/savecore.c38
-rw-r--r--usr/src/man/man1m/savecore.1m23
2 files changed, 39 insertions, 22 deletions
diff --git a/usr/src/cmd/savecore/savecore.c b/usr/src/cmd/savecore/savecore.c
index e1d3589acc..9b8e43e488 100644
--- a/usr/src/cmd/savecore/savecore.c
+++ b/usr/src/cmd/savecore/savecore.c
@@ -20,7 +20,7 @@
*/
/*
* Copyright (c) 1983, 2010, Oracle and/or its affiliates. All rights reserved.
- * Copyright 2016 Joyent, Inc.
+ * Copyright 2019 Joyent, Inc.
*/
/*
* Copyright 2016 Nexenta Systems, Inc. All rights reserved.
@@ -92,6 +92,7 @@ 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
@@ -164,7 +165,7 @@ static void
usage(void)
{
(void) fprintf(stderr,
- "usage: %s [-Lvd] [-f dumpfile] [dirname]\n", progname);
+ "usage: %s [-L | -r] [-vd] [-f dumpfile] [dirname]\n", progname);
exit(1);
}
@@ -229,7 +230,7 @@ logprint(uint32_t flags, char *message, ...)
* raise if run as savecore -m. If something in the
* raise_event codepath calls logprint avoid recursion.
*/
- if (!mflag && logprint_raised++ == 0)
+ if (!mflag && !rflag && logprint_raised++ == 0)
raise_event(SC_EVENT_SAVECORE_FAILURE, buf);
code = 2;
break;
@@ -240,7 +241,7 @@ logprint(uint32_t flags, char *message, ...)
case SC_EXIT_ERR:
default:
- if (!mflag && logprint_raised++ == 0 && have_dumpfile)
+ if (!mflag && !rflag && logprint_raised++ == 0 && have_dumpfile)
raise_event(SC_EVENT_SAVECORE_FAILURE, buf);
code = 1;
break;
@@ -355,7 +356,7 @@ read_number_from_file(const char *filename, long default_value)
static void
read_dumphdr(void)
{
- if (filemode)
+ if (filemode || rflag)
dumpfd = Open(dumpfile, O_RDONLY, 0644);
else
dumpfd = Open(dumpfile, O_RDWR | O_DSYNC, 0644);
@@ -408,7 +409,7 @@ read_dumphdr(void)
/*
* Clear valid bit so we don't complain on every invocation.
*/
- if (!filemode)
+ if (!filemode && !rflag)
Pwrite(dumpfd, &dumphdr, sizeof (dumphdr), endoff);
logprint(SC_SL_ERR | SC_EXIT_ERR,
"initial dump header corrupt");
@@ -660,7 +661,7 @@ copy_crashfile(const char *corefile)
* Write out the modified dump header to the dump device.
* The dump device has been processed, so DF_VALID is clear.
*/
- if (!filemode)
+ if (!filemode && !rflag)
Pwrite(dumpfd, &dumphdr, sizeof (dumphdr), endoff);
(void) close(corefd);
@@ -1422,7 +1423,7 @@ build_corefile(const char *namelist, const char *corefile)
* Write out the modified dump headers.
*/
Pwrite(corefd, &corehdr, sizeof (corehdr), 0);
- if (!filemode)
+ if (!filemode && !rflag)
Pwrite(dumpfd, &dumphdr, sizeof (dumphdr), endoff);
(void) close(corefd);
@@ -1531,7 +1532,10 @@ stack_retrieve(char *stack)
DUMP_ERPTSIZE);
dumpoff -= DUMP_SUMMARYSIZE;
- dumpfd = Open(dumpfile, O_RDWR | O_DSYNC, 0644);
+ 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);
@@ -1668,7 +1672,7 @@ main(int argc, char *argv[])
if (savedir != NULL)
savedir = strdup(savedir);
- while ((c = getopt(argc, argv, "Lvcdmf:")) != EOF) {
+ while ((c = getopt(argc, argv, "Lvcdmf:r")) != EOF) {
switch (c) {
case 'L':
livedump++;
@@ -1685,6 +1689,9 @@ main(int argc, char *argv[])
case 'm':
mflag++;
break;
+ case 'r':
+ rflag++;
+ break;
case 'f':
dumpfile = optarg;
filebounds = getbounds(dumpfile);
@@ -1709,6 +1716,9 @@ main(int argc, char *argv[])
if (cflag && livedump)
usage();
+ if (rflag && (cflag || mflag || livedump))
+ usage();
+
if (dumpfile == NULL || livedump)
dumpfd = Open("/dev/dump", O_RDONLY, 0444);
@@ -1752,7 +1762,7 @@ main(int argc, char *argv[])
* 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') {
+ if (dumphdr.dump_panicstring[0] != '\0' && !rflag) {
int logfd = Open("/dev/conslog", O_WRONLY, 0644);
log_ctl_t lc;
struct strbuf ctl, dat;
@@ -1801,7 +1811,7 @@ main(int argc, char *argv[])
* for the same event. Also avoid raising an event for a
* livedump, or when we inflating a compressed dump.
*/
- if (!fm_panic && !livedump && !filemode)
+ if (!fm_panic && !livedump && !filemode && !rflag)
raise_event(SC_EVENT_DUMP_PENDING, NULL);
logprint(SC_SL_WARN, "System dump time: %s",
@@ -1857,7 +1867,7 @@ main(int argc, char *argv[])
* has panicked. We know a reasonable amount about the
* condition at this time, but the dump is still compressed.
*/
- if (!livedump && !fm_panic)
+ if (!livedump && !fm_panic && !rflag)
raise_event(SC_EVENT_DUMP_AVAILABLE, NULL);
if (metrics_size > 0) {
@@ -1926,7 +1936,7 @@ main(int argc, char *argv[])
build_corefile(namelist, corefile);
- if (!livedump && !filemode && !fm_panic)
+ if (!livedump && !filemode && !fm_panic && !rflag)
raise_event(SC_EVENT_DUMP_AVAILABLE, NULL);
if (access(METRICSFILE, F_OK) == 0) {
diff --git a/usr/src/man/man1m/savecore.1m b/usr/src/man/man1m/savecore.1m
index e88ffbf8bc..28eee7cbba 100644
--- a/usr/src/man/man1m/savecore.1m
+++ b/usr/src/man/man1m/savecore.1m
@@ -2,17 +2,17 @@
.\" Copyright (c) 2004, Sun Microsystems, Inc. All Rights Reserved.
.\" Copyright (c) 1983 Regents of the University of California. All rights reserved. The Berkeley software License Agreement specifies the terms and conditions for redistribution.
.\" Copyright 2013 Nexenta Systems, Inc. All Rights Reserved.
-.TH SAVECORE 1M "Jan 30, 2013"
+.\" Copyright 2019 Joyent, Inc.
+.TH SAVECORE 1M "February 22, 2019"
.SH NAME
savecore \- save a crash dump of the operating system
.SH SYNOPSIS
.LP
.nf
-\fB/usr/bin/savecore\fR [\fB-Lvd\fR] [\fB-f\fR \fIdumpfile\fR] [\fIdirectory\fR]
+\fB/usr/bin/savecore\fR [\fB-L\fR | \fB-r\fR] [\fB-vd\fR] [\fB-f\fR \fIdumpfile\fR] [\fIdirectory\fR]
.fi
.SH DESCRIPTION
-.sp
.LP
The \fBsavecore\fR utility saves a crash dump of the kernel (assuming that one
was made) and writes a reboot message in the shutdown log. By default, it is
@@ -42,7 +42,6 @@ The \fBsavecore\fR utility also logs a reboot message using facility
\fBLOG_AUTH\fR (see \fBsyslog\fR(3C)). If the system crashed as a result of a
panic, \fBsavecore\fR logs the panic string too.
.SH OPTIONS
-.sp
.LP
The following options are supported:
.sp
@@ -90,6 +89,18 @@ are not fully self-consistent.
.sp
.ne 2
.na
+\fB\fB-r\fR\fR
+.ad
+.RS 15n
+Open the dump device or file as read-only, and don't update the dump header
+or do anything else that might modify the crash dump. This option can be used
+to recover a crash dump from a read-only device. This flag cannot be used in
+conjunction with \fB\fB-L\fR\fR.
+.RE
+
+.sp
+.ne 2
+.na
\fB\fB-v\fR\fR
.ad
.RS 15n
@@ -97,7 +108,6 @@ Verbose. Enables verbose error messages from \fBsavecore\fR.
.RE
.SH OPERANDS
-.sp
.LP
The following operands are supported:
.sp
@@ -112,7 +122,6 @@ specified, \fBsavecore\fR saves the crash dump files to the default
.RE
.SH FILES
-.sp
.ne 2
.na
\fB\fIdirectory\fR\fB/vmdump.\fR\fIn\fR\fR
@@ -167,12 +176,10 @@ default crash dump directory
.RE
.SH SEE ALSO
-.sp
.LP
\fBadb\fR(1), \fBmdb\fR(1), \fBsvcs\fR(1), \fBdd\fR(1M), \fBdumpadm\fR(1M),
\fBsvcadm\fR(1M), \fBsyslog\fR(3C), \fBattributes\fR(5), \fBsmf\fR(5)
.SH NOTES
-.sp
.LP
The system crash dump service is managed by the service management facility,
\fBsmf\fR(5), under the service identifier: