From 71289ec3e01e1d7dfcd21537bb1ccfa9aa5c3212 Mon Sep 17 00:00:00 2001 From: Matthew Dillon Date: Sat, 25 Mar 2006 07:46:58 +0000 Subject: [PATCH] Add options to allow the dump offset or system memory size (for the purposes of dump recovery) to be specified. Submitted-by: Csaba Henk --- sbin/savecore/savecore.8 | 13 ++++++- sbin/savecore/savecore.c | 82 ++++++++++++++++++++++++++++++++++++---- 2 files changed, 86 insertions(+), 9 deletions(-) diff --git a/sbin/savecore/savecore.8 b/sbin/savecore/savecore.8 index ff934d733a..d90700ce25 100644 --- a/sbin/savecore/savecore.8 +++ b/sbin/savecore/savecore.8 @@ -31,7 +31,7 @@ .\" .\" From: @(#)savecore.8 8.1 (Berkeley) 6/5/93 .\" $FreeBSD: src/sbin/savecore/savecore.8,v 1.8.2.6 2002/06/20 23:09:09 charnier Exp $ -.\" $DragonFly: src/sbin/savecore/savecore.8,v 1.3 2006/02/17 19:33:33 swildner Exp $ +.\" $DragonFly: src/sbin/savecore/savecore.8,v 1.4 2006/03/25 07:46:58 dillon Exp $ .\" .Dd September 23, 1994 .Dt SAVECORE 8 @@ -45,6 +45,8 @@ .Nm .Op Fl fkvz .Op Fl N Ar system +.Op Fl P Ar physmem +.Op Fl B Ar blkno .Ar directory .Sh DESCRIPTION The @@ -71,6 +73,12 @@ Use .Ar system as the kernel instead of the running kernel (as determined from .Xr getbootfile 3 ) . +.It Fl P +Specify physical memory size used at dumptime (cf. the +.Va hw.physmem +kernel environment variable). +.It Fl B +Specify offset of dump in blocks (as printed at dumptime). .It Fl v Print out some additional debugging information. .It Fl z @@ -123,7 +131,8 @@ is meant to be called near the end of the initialization file .Xr gzip 1 , .Xr getbootfile 3 , .Xr dumpon 8 , -.Xr syslogd 8 +.Xr syslogd 8 , +.Xr loader 8 .Sh HISTORY The .Nm diff --git a/sbin/savecore/savecore.c b/sbin/savecore/savecore.c index 180e416810..8e0cb0bfdd 100644 --- a/sbin/savecore/savecore.c +++ b/sbin/savecore/savecore.c @@ -33,10 +33,15 @@ * @(#) Copyright (c) 1986, 1992, 1993 The Regents of the University of California. All rights reserved. * @(#)savecore.c 8.3 (Berkeley) 1/2/94 * $FreeBSD: src/sbin/savecore/savecore.c,v 1.28.2.14 2005/01/05 09:14:34 maxim Exp $ - * $DragonFly: src/sbin/savecore/savecore.c,v 1.11 2005/12/15 22:20:49 corecode Exp $ + * $DragonFly: src/sbin/savecore/savecore.c,v 1.12 2006/03/25 07:46:58 dillon Exp $ */ +#define _KERNEL_STRUCTURES + #include + +#undef _KERNEL_STRUCTURES + #include #include #include @@ -54,6 +59,7 @@ #include #include #include +#include extern FILE *zopen(const char *fname, const char *mode); @@ -76,6 +82,8 @@ struct nlist current_nl[] = { /* Namelist for currently running system. */ { "_dumpmag", 0, 0, 0, 0 }, #define X_KERNBASE 6 { "_kernbase", 0, 0, 0, 0 }, +#define X_MAXMEM 7 + { "_Maxmem", 0, 0, 0, 0 }, { "", 0, 0, 0, 0 }, }; int cursyms[] = { X_DUMPLO, X_VERSION, X_DUMPMAG, -1 }; @@ -89,6 +97,7 @@ struct nlist dump_nl[] = { /* Name list for dumped system. */ { "_panicstr", 0, 0, 0, 0 }, { "_dumpmag", 0, 0, 0, 0 }, { "_kernbase", 0, 0, 0, 0 }, + { "_Maxmem", 0, 0, 0, 0 }, { "", 0, 0, 0, 0 }, }; @@ -108,12 +117,14 @@ time_t now; /* current date */ char panic_mesg[1024]; /* panic message */ int panicstr; /* flag: dump was caused by panic */ char vers[1024]; /* version of kernel that crashed */ +char *physmem; /* physmem value used with dumped session */ +long dkdumplo; /* directly specified kernel dumplo value */ #ifdef __i386__ u_long kernbase; /* offset of kvm to core file */ #endif -static int clear, compress, force, verbose; /* flags */ +static int clear, compress, force, verbose, directdumplo; /* flags */ static int keep; /* keep dump on device */ static void check_kmem(void); @@ -133,15 +144,17 @@ static void save_core(void); static void usage(void); static int verify_dev(char *, dev_t); static void Write(int, void *, int); +static void kdumplo_adjust(char *cp, int kmem, long *kdumplop); int main(int argc, char **argv) { int ch; + char *ep; openlog("savecore", LOG_PERROR, LOG_DAEMON); - while ((ch = getopt(argc, argv, "cdfkN:vz")) != -1) + while ((ch = getopt(argc, argv, "cdfkN:vzP:B:")) != -1) switch(ch) { case 'c': clear = 1; @@ -162,6 +175,15 @@ main(int argc, char **argv) case 'z': compress = 1; break; + case 'P': + physmem = optarg; + break; + case 'B': + directdumplo = 1; + dkdumplo = strtol(optarg, &ep, 10); + if (*ep != '\0') + errx(1, "invalid offset: '%s'", optarg); + break; case '?': default: usage(); @@ -262,9 +284,15 @@ kmem_setup(void) } kmem = Open(_PATH_KMEM, O_RDONLY); - Lseek(kmem, (off_t)current_nl[X_DUMPLO].n_value, L_SET); - Read(kmem, &kdumplo, sizeof(kdumplo)); - dumplo = (off_t)kdumplo * DEV_BSIZE; + if (directdumplo) + kdumplo = dkdumplo; + else { + Lseek(kmem, (off_t)current_nl[X_DUMPLO].n_value, L_SET); + Read(kmem, &kdumplo, sizeof(kdumplo)); + if (physmem) + kdumplo_adjust(physmem, kmem, &kdumplo); + } + dumplo = (off_t)kdumplo * DEV_BSIZE; if (verbose) printf("dumplo = %lld (%ld * %d)\n", (long long)dumplo, kdumplo, DEV_BSIZE); @@ -753,9 +781,49 @@ Write(int fd, void *bp, int size) } } +static void +kdumplo_adjust(char *cp, int kmem, long *kdumplop) +{ + uint64_t AllowMem, sanity, Maxmem, CurrMaxmem; + char *ep; + + /* based on getmemsize() in i386/i386/machdep.c */ + sanity = AllowMem = strtouq(cp, &ep, 0); + if ((ep != cp) && (*ep != 0)) { + switch(*ep) { + case 'g': + case 'G': + AllowMem <<= 10; + case 'm': + case 'M': + AllowMem <<= 10; + case 'k': + case 'K': + AllowMem <<= 10; + break; + default: + AllowMem = 0; + } + if (AllowMem < sanity) + AllowMem = 0; + } + if (AllowMem == 0) + errx(1, "invalid memory size: '%s'\n", cp); + else + Maxmem = atop(AllowMem); + + Lseek(kmem, (off_t)current_nl[X_MAXMEM].n_value, L_SET); + Read(kmem, &CurrMaxmem, sizeof(CurrMaxmem)); + + /* based on setdumpdev() in kern_shutdown.c */ + *kdumplop += CurrMaxmem * (PAGE_SIZE / DEV_BSIZE); + *kdumplop -= Maxmem * (PAGE_SIZE / DEV_BSIZE); +} + static void usage(void) { - syslog(LOG_ERR, "usage: savecore [-cfkvz] [-N system] directory"); + syslog(LOG_ERR, + "usage: savecore [-cfkvz] [-N system] [-P physmem|-B blkno] directory"); exit(1); } -- 2.41.0