diff --git a/sbin/savecore/savecore.c b/sbin/savecore/savecore.c index b020b693d273..a736072fe86e 100644 --- a/sbin/savecore/savecore.c +++ b/sbin/savecore/savecore.c @@ -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 @@ -39,7 +39,7 @@ __COPYRIGHT("@(#) Copyright (c) 1986, 1992, 1993\n\ #if 0 static char sccsid[] = "@(#)savecore.c 8.5 (Berkeley) 4/28/95"; #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 /* not lint */ @@ -93,11 +93,13 @@ struct nlist current_nl[] = { /* Namelist for currently running system. */ { .n_name = "_panicend" }, #define X_MSGBUF 10 { .n_name = "_msgbufp" }, +#define X_DUMPCDEV 11 + { .n_name = "_dumpcdev" }, { .n_name = NULL }, }; -int cursyms[] = { X_DUMPDEV, X_DUMPLO, X_VERSION, X_DUMPMAG, -1 }; -int dumpsyms[] = { X_TIME_SECOND, X_TIME, X_DUMPSIZE, X_VERSION, X_PANICSTR, 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, -1 }; struct nlist dump_nl[] = { /* Name list for dumped system. */ { .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 = "_panicend" }, { .n_name = "_msgbufp" }, + { .n_name = "_dumpcdev" }, { .n_name = NULL }, }; @@ -124,8 +127,9 @@ const char *kernel; /* name of used kernel */ char *dirname; /* directory to save dumps in */ char *ddname; /* name of dump device */ dev_t dumpdev; /* dump device */ -int dumpfd; /* read/write descriptor on block dev */ -kvm_t *kd_dump; /* kvm descriptor on block dev */ +dev_t dumpcdev = NODEV; /* dump device (char equivalent) */ +int dumpfd; /* read/write descriptor on dev */ +kvm_t *kd_dump; /* kvm descriptor on dev */ time_t now; /* current date */ char panic_mesg[1024]; long panicstr; @@ -266,14 +270,20 @@ kmem_setup(void) syslog(LOG_ERR, "%s: kvm_nlist: %s", kernel, kvm_geterr(kd_kern)); - for (i = 0; cursyms[i] != -1; i++) - if (current_nl[cursyms[i]].n_value == 0 && - cursyms[i] != X_TIME_SECOND && - cursyms[i] != X_TIME) { + for (i = 0; cursyms[i] != -1; i++) { + if (current_nl[cursyms[i]].n_value != 0) + continue; + switch (cursyms[i]) { + case X_TIME_SECOND: + case X_TIME: + case X_DUMPCDEV: + break; + default: syslog(LOG_ERR, "%s: %s not in namelist", kernel, current_nl[cursyms[i]].n_name); exit(1); } + } if (KREAD(kd_kern, current_nl[X_DUMPDEV].n_value, &dumpdev) != 0) { if (verbose) @@ -312,7 +322,17 @@ kmem_setup(void) sizeof(vers)); 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); kd_dump = kvm_openfiles(kernel, ddname, NULL, O_RDWR, errbuf); @@ -489,7 +509,7 @@ void clear_dump(void) { 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)); } @@ -544,10 +564,16 @@ err1: syslog(LOG_WARNING, "%s: %m", path); } } - /* Open the raw device. */ - rawp = rawname(ddname); - if ((ifd = open(rawp, O_RDONLY)) == -1) { - syslog(LOG_WARNING, "%s: %m; using block device", rawp); + if (dumpcdev == NODEV) { + /* Open the raw device. */ + rawp = rawname(ddname); + if ((ifd = open(rawp, O_RDONLY)) == -1) { + syslog(LOG_WARNING, "%s: %m; using block device", + rawp); + ifd = dumpfd; + } + } else { + rawp = ddname; ifd = dumpfd; } @@ -587,7 +613,8 @@ err2: syslog(LOG_WARNING, exit(1); } } - (void)close(ifd); + if (dumpcdev == NODEV) + (void)close(ifd); (void)fclose(fp); /* Copy the kernel. */ diff --git a/sys/kern/kern_subr.c b/sys/kern/kern_subr.c index d5460f5c75e7..550bc36c6b61 100644 --- a/sys/kern/kern_subr.c +++ b/sys/kern/kern_subr.c @@ -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. @@ -86,7 +86,7 @@ */ #include -__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_md.h" @@ -142,6 +142,8 @@ MALLOC_DEFINE(M_IOV, "iov", "large iov's"); int tftproot_dhcpboot(struct device *); #endif +dev_t dumpcdev; /* for savecore */ + void 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); if (DEV_USES_PARTITIONS(dumpdv)) aprint_normal("%c", DISKPART(dumpdev) + 'a'); @@ -1107,6 +1110,7 @@ setroot(struct device *bootdv, int bootpartition) nodumpdev: dumpdev = NODEV; + dumpcdev = NODEV; aprint_normal("\n"); } diff --git a/sys/sys/systm.h b/sys/sys/systm.h index 0308dd8c2a9c..52bc93aff97d 100644 --- a/sys/sys/systm.h +++ b/sys/sys/systm.h @@ -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 @@ -81,6 +81,7 @@ extern int maxmem; /* max memory per process */ extern int physmem; /* physical memory */ extern dev_t dumpdev; /* dump device */ +extern dev_t dumpcdev; /* dump device (character equivalent) */ extern long dumplo; /* offset into dumpdev */ extern int dumpsize; /* size of dump in pages */ extern const char *dumpspec; /* how dump device was specified */