savecore(8): add options to specify dumptime physmem / device block offset
Csaba Henk
csaba.henk at creo.hu
Thu Mar 23 23:03:23 PST 2006
diff -r bb073eb2a5f1 sbin/savecore/savecore.8
--- a/sbin/savecore/savecore.8 Tue Mar 21 18:14:43 2006 +0000
+++ b/sbin/savecore/savecore.8 Fri Mar 24 02:38:23 2006 +0100
@@ -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 th
.Xr gzip 1 ,
.Xr getbootfile 3 ,
.Xr dumpon 8 ,
-.Xr syslogd 8
+.Xr syslogd 8 ,
+.Xr loader 8
.Sh HISTORY
The
.Nm
diff -r bb073eb2a5f1 sbin/savecore/savecore.c
--- a/sbin/savecore/savecore.c Tue Mar 21 18:14:43 2006 +0000
+++ b/sbin/savecore/savecore.c Fri Mar 24 02:38:23 2006 +0100
@@ -36,7 +36,12 @@
* $DragonFly: src/sbin/savecore/savecore.c,v 1.11 2005/12/15 22:20:49 corecode Exp $
*/
+#define _KERNEL_STRUCTURES
+
#include <sys/param.h>
+
+#undef _KERNEL_STRUCTURES
+
#include <sys/stat.h>
#include <sys/mount.h>
#include <sys/syslog.h>
@@ -54,6 +59,7 @@
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
+#include <err.h>
extern FILE *zopen(const char *fname, const char *mode);
@@ -76,6 +82,8 @@ struct nlist current_nl[] = { /* Namelis
{ "_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[] = {
{ "_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 @@ char panic_mesg[1024]; /* panic message
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 usage(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;
@@ -161,6 +174,15 @@ main(int argc, char **argv)
break;
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:
@@ -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);
@@ -754,8 +782,48 @@ 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);
}
More information about the Submit
mailing list