aboutsummaryrefslogtreecommitdiffstats
path: root/sbin/savecore
diff options
context:
space:
mode:
authorDavid E. O'Brien <obrien@FreeBSD.org>2005-02-24 02:45:10 +0000
committerDavid E. O'Brien <obrien@FreeBSD.org>2005-02-24 02:45:10 +0000
commit5fb7027c82a7f2bf22ada18693be6b9a940eb801 (patch)
tree75fdb61e6cf764c1603d1ffa2b1a1e9ce83a4b33 /sbin/savecore
parent183551b925220feb06f5dde5d4e2e2c4bdcdfbbd (diff)
downloadsrc-5fb7027c82a7f2bf22ada18693be6b9a940eb801.tar.gz
src-5fb7027c82a7f2bf22ada18693be6b9a940eb801.zip
Allow a forced dump even if the dump header information is inconsistent.
Output more verbosity with additional -v's. Submitted by: seanc
Notes
Notes: svn path=/head/; revision=142359
Diffstat (limited to 'sbin/savecore')
-rw-r--r--sbin/savecore/savecore.84
-rw-r--r--sbin/savecore/savecore.c75
2 files changed, 61 insertions, 18 deletions
diff --git a/sbin/savecore/savecore.8 b/sbin/savecore/savecore.8
index c15c724f3ef2..aa6dcb73f3fe 100644
--- a/sbin/savecore/savecore.8
+++ b/sbin/savecore/savecore.8
@@ -71,11 +71,13 @@ Clear the dump, so that future invocations of
.Nm
will ignore it.
.It Fl f
-Force a dump to be taken even if the dump was cleared.
+Force a dump to be taken even if either the dump was cleared or if the
+dump header information is inconsistent.
.It Fl k
Do not clear the dump after saving it.
.It Fl v
Print out some additional debugging information.
+Speicify twice for more information.
.It Fl z
Compress the core dump and kernel (see
.Xr gzip 1 ) .
diff --git a/sbin/savecore/savecore.c b/sbin/savecore/savecore.c
index f4e26d2cecb2..03fc162a491a 100644
--- a/sbin/savecore/savecore.c
+++ b/sbin/savecore/savecore.c
@@ -88,6 +88,10 @@ __FBSDID("$FreeBSD$");
/* The size of the buffer used for I/O. */
#define BUFFERSIZE (1024*1024)
+#define STATUS_BAD 0
+#define STATUS_GOOD 1
+#define STATUS_UNKNOWN 2
+
static int checkfor, compress, clear, force, keep, verbose; /* flags */
static int nfound, nsaved, nerr; /* statistics */
@@ -95,25 +99,39 @@ extern FILE *zopen(const char *, const char *);
static void
printheader(FILE *f, const struct kerneldumpheader *h, const char *device,
- int bounds)
+ int bounds, const int status)
{
uint64_t dumplen;
time_t t;
+ const char *stat_str;
- fprintf(f, "Good dump found on device %s\n", device);
+ fprintf(f, "Dump header from device %s\n", device);
fprintf(f, " Architecture: %s\n", h->architecture);
- fprintf(f, " Architecture version: %d\n",
- dtoh32(h->architectureversion));
+ fprintf(f, " Architecture Version: %u\n", h->architectureversion);
dumplen = dtoh64(h->dumplength);
- fprintf(f, " Dump length: %lldB (%lld MB)\n", (long long)dumplen,
+ fprintf(f, " Dump Length: %lldB (%lld MB)\n", (long long)dumplen,
(long long)(dumplen >> 20));
fprintf(f, " Blocksize: %d\n", dtoh32(h->blocksize));
t = dtoh64(h->dumptime);
fprintf(f, " Dumptime: %s", ctime(&t));
fprintf(f, " Hostname: %s\n", h->hostname);
- fprintf(f, " Versionstring: %s", h->versionstring);
- fprintf(f, " Panicstring: %s\n", h->panicstring);
+ fprintf(f, " Magic: %s\n", h->magic);
+ fprintf(f, " Version String: %s", h->versionstring);
+ fprintf(f, " Panic String: %s\n", h->panicstring);
+ fprintf(f, " Dump Parity: %u\n", h->parity);
fprintf(f, " Bounds: %d\n", bounds);
+
+ switch(status) {
+ case STATUS_BAD:
+ stat_str = "bad";
+ break;
+ case STATUS_GOOD:
+ stat_str = "good";
+ break;
+ default:
+ stat_str = "unknown";
+ }
+ fprintf(f, " Dump Status: %s\n", stat_str);
fflush(f);
}
@@ -214,12 +232,14 @@ DoFile(char *savedir, const char *device)
FILE *info, *fp;
int fd, fdinfo, error, wl;
int nr, nw, hs, he = 0;
- int bounds;
+ int bounds, status;
u_int sectorsize;
mode_t oumask;
+ bounds = getbounds();
dmpcnt = 0;
mediasize = 0;
+ status = STATUS_UNKNOWN;
if (buf == NULL) {
buf = malloc(BUFFERSIZE);
@@ -266,6 +286,7 @@ DoFile(char *savedir, const char *device)
printf("magic mismatch on last dump header on %s\n",
device);
+ status = STATUS_BAD;
if (force == 0)
goto closefd;
@@ -284,7 +305,10 @@ DoFile(char *savedir, const char *device)
syslog(LOG_ERR,
"unknown version (%d) in last dump header on %s",
dtoh32(kdhl.version), device);
- goto closefd;
+
+ status = STATUS_BAD;
+ if (force == 0)
+ goto closefd;
}
nfound++;
@@ -295,7 +319,9 @@ DoFile(char *savedir, const char *device)
syslog(LOG_ERR,
"parity error on last dump header on %s", device);
nerr++;
- goto closefd;
+ status = STATUS_BAD;
+ if (force == 0)
+ goto closefd;
}
dumpsize = dtoh64(kdhl.dumplength);
firsthd = lasthd - dumpsize - sizeof kdhf;
@@ -308,11 +334,25 @@ DoFile(char *savedir, const char *device)
nerr++;
goto closefd;
}
+
+ if (verbose >= 2) {
+ printf("First dump headers:\n");
+ printheader(stdout, &kdhf, device, bounds, -1);
+
+ printf("\nLast dump headers:\n");
+ printheader(stdout, &kdhl, device, bounds, -1);
+ printf("\n");
+ }
+
if (memcmp(&kdhl, &kdhf, sizeof kdhl)) {
syslog(LOG_ERR,
"first and last dump headers disagree on %s", device);
nerr++;
- goto closefd;
+ status = STATUS_BAD;
+ if (force == 0)
+ goto closefd;
+ } else {
+ status = STATUS_GOOD;
}
if (checkfor) {
@@ -333,12 +373,10 @@ DoFile(char *savedir, const char *device)
goto closefd;
}
- bounds = getbounds();
-
sprintf(buf, "info.%d", bounds);
/*
- * Create or overwrite any existing files.
+ * Create or overwrite any existing dump header files.
*/
fdinfo = open(buf, O_WRONLY | O_CREAT | O_TRUNC, 0600);
if (fdinfo < 0) {
@@ -365,9 +403,9 @@ DoFile(char *savedir, const char *device)
info = fdopen(fdinfo, "w");
if (verbose)
- printheader(stdout, &kdhl, device, bounds);
+ printheader(stdout, &kdhl, device, bounds, status);
- printheader(info, &kdhl, device, bounds);
+ printheader(info, &kdhl, device, bounds, status);
fclose(info);
syslog(LOG_NOTICE, "writing %score to %s",
@@ -492,6 +530,9 @@ main(int argc, char **argv)
struct fstab *fsp;
char *savedir;
+ checkfor = compress = clear = force = keep = verbose = 0;
+ nfound = nsaved = nerr = 0;
+
openlog("savecore", LOG_PERROR, LOG_DAEMON);
savedir = strdup(".");
@@ -511,7 +552,7 @@ main(int argc, char **argv)
keep = 1;
break;
case 'v':
- verbose = 1;
+ verbose++;
break;
case 'f':
force = 1;