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