Don't use the block device to read crashdumps, if possible.

This commit is contained in:
ad 2008-01-15 14:26:41 +00:00
parent 416c26d3b8
commit 73e694f404
3 changed files with 53 additions and 21 deletions

View File

@ -1,4 +1,4 @@
/* $NetBSD: savecore.c,v 1.71 2007/11/12 16:04:55 pooka Exp $ */ /* $NetBSD: savecore.c,v 1.72 2008/01/15 14:26:42 ad Exp $ */
/*- /*-
* Copyright (c) 1986, 1992, 1993 * Copyright (c) 1986, 1992, 1993
@ -39,7 +39,7 @@ __COPYRIGHT("@(#) Copyright (c) 1986, 1992, 1993\n\
#if 0 #if 0
static char sccsid[] = "@(#)savecore.c 8.5 (Berkeley) 4/28/95"; static char sccsid[] = "@(#)savecore.c 8.5 (Berkeley) 4/28/95";
#else #else
__RCSID("$NetBSD: savecore.c,v 1.71 2007/11/12 16:04:55 pooka Exp $"); __RCSID("$NetBSD: savecore.c,v 1.72 2008/01/15 14:26:42 ad Exp $");
#endif #endif
#endif /* not lint */ #endif /* not lint */
@ -93,11 +93,13 @@ struct nlist current_nl[] = { /* Namelist for currently running system. */
{ .n_name = "_panicend" }, { .n_name = "_panicend" },
#define X_MSGBUF 10 #define X_MSGBUF 10
{ .n_name = "_msgbufp" }, { .n_name = "_msgbufp" },
#define X_DUMPCDEV 11
{ .n_name = "_dumpcdev" },
{ .n_name = NULL }, { .n_name = NULL },
}; };
int cursyms[] = { X_DUMPDEV, X_DUMPLO, X_VERSION, X_DUMPMAG, -1 }; int cursyms[] = { X_DUMPDEV, X_DUMPLO, X_VERSION, X_DUMPMAG, X_DUMPCDEV, -1 };
int dumpsyms[] = { X_TIME_SECOND, X_TIME, X_DUMPSIZE, X_VERSION, X_PANICSTR, X_DUMPMAG, int dumpsyms[] = { X_TIME_SECOND, X_TIME, X_DUMPSIZE, X_VERSION, X_PANICSTR,
-1 }; X_DUMPMAG, -1 };
struct nlist dump_nl[] = { /* Name list for dumped system. */ struct nlist dump_nl[] = { /* Name list for dumped system. */
{ .n_name = "_dumpdev" }, /* Entries MUST be the same as */ { .n_name = "_dumpdev" }, /* Entries MUST be the same as */
@ -111,6 +113,7 @@ struct nlist dump_nl[] = { /* Name list for dumped system. */
{ .n_name = "_panicstart" }, { .n_name = "_panicstart" },
{ .n_name = "_panicend" }, { .n_name = "_panicend" },
{ .n_name = "_msgbufp" }, { .n_name = "_msgbufp" },
{ .n_name = "_dumpcdev" },
{ .n_name = NULL }, { .n_name = NULL },
}; };
@ -124,8 +127,9 @@ const char *kernel; /* name of used kernel */
char *dirname; /* directory to save dumps in */ char *dirname; /* directory to save dumps in */
char *ddname; /* name of dump device */ char *ddname; /* name of dump device */
dev_t dumpdev; /* dump device */ dev_t dumpdev; /* dump device */
int dumpfd; /* read/write descriptor on block dev */ dev_t dumpcdev = NODEV; /* dump device (char equivalent) */
kvm_t *kd_dump; /* kvm descriptor on block dev */ int dumpfd; /* read/write descriptor on dev */
kvm_t *kd_dump; /* kvm descriptor on dev */
time_t now; /* current date */ time_t now; /* current date */
char panic_mesg[1024]; char panic_mesg[1024];
long panicstr; long panicstr;
@ -266,14 +270,20 @@ kmem_setup(void)
syslog(LOG_ERR, "%s: kvm_nlist: %s", kernel, syslog(LOG_ERR, "%s: kvm_nlist: %s", kernel,
kvm_geterr(kd_kern)); kvm_geterr(kd_kern));
for (i = 0; cursyms[i] != -1; i++) for (i = 0; cursyms[i] != -1; i++) {
if (current_nl[cursyms[i]].n_value == 0 && if (current_nl[cursyms[i]].n_value != 0)
cursyms[i] != X_TIME_SECOND && continue;
cursyms[i] != X_TIME) { switch (cursyms[i]) {
case X_TIME_SECOND:
case X_TIME:
case X_DUMPCDEV:
break;
default:
syslog(LOG_ERR, "%s: %s not in namelist", syslog(LOG_ERR, "%s: %s not in namelist",
kernel, current_nl[cursyms[i]].n_name); kernel, current_nl[cursyms[i]].n_name);
exit(1); exit(1);
} }
}
if (KREAD(kd_kern, current_nl[X_DUMPDEV].n_value, &dumpdev) != 0) { if (KREAD(kd_kern, current_nl[X_DUMPDEV].n_value, &dumpdev) != 0) {
if (verbose) if (verbose)
@ -312,7 +322,17 @@ kmem_setup(void)
sizeof(vers)); sizeof(vers));
vers[sizeof(vers) - 1] = '\0'; vers[sizeof(vers) - 1] = '\0';
ddname = find_dev(dumpdev, S_IFBLK); if (current_nl[X_DUMPCDEV].n_value != 0) {
if (KREAD(kd_kern, current_nl[X_DUMPCDEV].n_value,
&dumpcdev) != 0) {
if (verbose)
syslog(LOG_WARNING, "kvm_read: %s",
kvm_geterr(kd_kern));
exit(1);
}
ddname = find_dev(dumpcdev, S_IFCHR);
} else
ddname = find_dev(dumpdev, S_IFBLK);
dumpfd = Open(ddname, O_RDWR); dumpfd = Open(ddname, O_RDWR);
kd_dump = kvm_openfiles(kernel, ddname, NULL, O_RDWR, errbuf); kd_dump = kvm_openfiles(kernel, ddname, NULL, O_RDWR, errbuf);
@ -489,7 +509,7 @@ void
clear_dump(void) clear_dump(void)
{ {
if (kvm_dump_inval(kd_dump) == -1) if (kvm_dump_inval(kd_dump) == -1)
syslog(LOG_ERR, "%s: kvm_clear_dump: %s", ddname, syslog(LOG_ERR, "%s: kvm_dump_inval: %s", ddname,
kvm_geterr(kd_dump)); kvm_geterr(kd_dump));
} }
@ -544,10 +564,16 @@ err1: syslog(LOG_WARNING, "%s: %m", path);
} }
} }
/* Open the raw device. */ if (dumpcdev == NODEV) {
rawp = rawname(ddname); /* Open the raw device. */
if ((ifd = open(rawp, O_RDONLY)) == -1) { rawp = rawname(ddname);
syslog(LOG_WARNING, "%s: %m; using block device", rawp); if ((ifd = open(rawp, O_RDONLY)) == -1) {
syslog(LOG_WARNING, "%s: %m; using block device",
rawp);
ifd = dumpfd;
}
} else {
rawp = ddname;
ifd = dumpfd; ifd = dumpfd;
} }
@ -587,7 +613,8 @@ err2: syslog(LOG_WARNING,
exit(1); exit(1);
} }
} }
(void)close(ifd); if (dumpcdev == NODEV)
(void)close(ifd);
(void)fclose(fp); (void)fclose(fp);
/* Copy the kernel. */ /* Copy the kernel. */

View File

@ -1,4 +1,4 @@
/* $NetBSD: kern_subr.c,v 1.174 2008/01/10 16:29:17 ad Exp $ */ /* $NetBSD: kern_subr.c,v 1.175 2008/01/15 14:26:42 ad Exp $ */
/*- /*-
* Copyright (c) 1997, 1998, 1999, 2002, 2007, 2006 The NetBSD Foundation, Inc. * Copyright (c) 1997, 1998, 1999, 2002, 2007, 2006 The NetBSD Foundation, Inc.
@ -86,7 +86,7 @@
*/ */
#include <sys/cdefs.h> #include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: kern_subr.c,v 1.174 2008/01/10 16:29:17 ad Exp $"); __KERNEL_RCSID(0, "$NetBSD: kern_subr.c,v 1.175 2008/01/15 14:26:42 ad Exp $");
#include "opt_ddb.h" #include "opt_ddb.h"
#include "opt_md.h" #include "opt_md.h"
@ -142,6 +142,8 @@ MALLOC_DEFINE(M_IOV, "iov", "large iov's");
int tftproot_dhcpboot(struct device *); int tftproot_dhcpboot(struct device *);
#endif #endif
dev_t dumpcdev; /* for savecore */
void void
uio_setup_sysspace(struct uio *uio) uio_setup_sysspace(struct uio *uio)
{ {
@ -1099,6 +1101,7 @@ setroot(struct device *bootdv, int bootpartition)
} }
} }
dumpcdev = devsw_blk2chr(dumpdev);
aprint_normal(" dumps on %s", dumpdv->dv_xname); aprint_normal(" dumps on %s", dumpdv->dv_xname);
if (DEV_USES_PARTITIONS(dumpdv)) if (DEV_USES_PARTITIONS(dumpdv))
aprint_normal("%c", DISKPART(dumpdev) + 'a'); aprint_normal("%c", DISKPART(dumpdev) + 'a');
@ -1107,6 +1110,7 @@ setroot(struct device *bootdv, int bootpartition)
nodumpdev: nodumpdev:
dumpdev = NODEV; dumpdev = NODEV;
dumpcdev = NODEV;
aprint_normal("\n"); aprint_normal("\n");
} }

View File

@ -1,4 +1,4 @@
/* $NetBSD: systm.h,v 1.211 2008/01/14 22:47:22 yamt Exp $ */ /* $NetBSD: systm.h,v 1.212 2008/01/15 14:26:41 ad Exp $ */
/*- /*-
* Copyright (c) 1982, 1988, 1991, 1993 * Copyright (c) 1982, 1988, 1991, 1993
@ -81,6 +81,7 @@ extern int maxmem; /* max memory per process */
extern int physmem; /* physical memory */ extern int physmem; /* physical memory */
extern dev_t dumpdev; /* dump device */ extern dev_t dumpdev; /* dump device */
extern dev_t dumpcdev; /* dump device (character equivalent) */
extern long dumplo; /* offset into dumpdev */ extern long dumplo; /* offset into dumpdev */
extern int dumpsize; /* size of dump in pages */ extern int dumpsize; /* size of dump in pages */
extern const char *dumpspec; /* how dump device was specified */ extern const char *dumpspec; /* how dump device was specified */