diff options
Diffstat (limited to 'sbin/savecore')
-rw-r--r-- | sbin/savecore/savecore.8 | 4 | ||||
-rw-r--r-- | sbin/savecore/savecore.c | 75 |
2 files changed, 61 insertions, 18 deletions
diff --git a/sbin/savecore/savecore.8 b/sbin/savecore/savecore.8 index c15c724..aa6dcb7 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 f4e26d2..03fc162 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; |