Index: etc/rc.d/dumpon =================================================================== RCS file: /mnt/space/cvsroot/src/etc/rc.d/dumpon,v retrieving revision 1.11 diff -u -p -r1.11 dumpon --- etc/rc.d/dumpon 10 Dec 2005 20:21:45 -0000 1.11 +++ etc/rc.d/dumpon 17 Feb 2008 13:16:27 -0000 @@ -37,13 +37,9 @@ dumpon_start() dumpon_try "${dev}" return $? fi - while read dev mp type more ; do - [ "${type}" = "swap" ] || continue - [ -c "${dev}" ] || continue - dumpon_try "${dev}" 2>/dev/null && return 0 - done &2 - return 1 + dumpdev=`dumpon -av` || return 1 + echo "${dumpdev}" + ln -fs "${dumpdev##* }" /dev/dumpdev ;; *) dumpon_try "${dumpdev}" Index: include/fstab.h =================================================================== RCS file: /mnt/space/cvsroot/src/include/fstab.h,v retrieving revision 1.4 diff -u -p -r1.4 fstab.h --- include/fstab.h 7 Apr 2003 12:54:59 -0000 1.4 +++ include/fstab.h 13 Jan 2009 00:34:39 -0000 @@ -55,6 +55,7 @@ #define FSTAB_RQ "rq" /* read/write with quotas */ #define FSTAB_RO "ro" /* read-only device */ #define FSTAB_SW "sw" /* swap device */ +#define FSTAB_DP "dp" /* dump device */ #define FSTAB_XX "xx" /* ignore totally */ struct fstab { Index: lib/libc/gen/fstab.c =================================================================== RCS file: /mnt/space/cvsroot/src/lib/libc/gen/fstab.c,v retrieving revision 1.15 diff -u -p -r1.15 fstab.c --- lib/libc/gen/fstab.c 9 Jan 2007 00:27:53 -0000 1.15 +++ lib/libc/gen/fstab.c 13 Jan 2009 00:35:23 -0000 @@ -196,6 +196,10 @@ fstabscan() _fs_fstab.fs_type = FSTAB_SW; break; } + if (!strcmp(cp, FSTAB_DP)) { + _fs_fstab.fs_type = FSTAB_DP; + break; + } if (!strcmp(cp, FSTAB_XX)) { _fs_fstab.fs_type = FSTAB_XX; typexx++; Index: sbin/dumpon/dumpon.8 =================================================================== RCS file: /mnt/space/cvsroot/src/sbin/dumpon/dumpon.8,v retrieving revision 1.35 diff -u -p -r1.35 dumpon.8 --- sbin/dumpon/dumpon.8 27 Feb 2006 00:15:53 -0000 1.35 +++ sbin/dumpon/dumpon.8 13 Jan 2009 00:36:53 -0000 @@ -36,10 +36,14 @@ .Nd "specify a device for crash dumps" .Sh SYNOPSIS .Nm +.Op Fl f .Op Fl v .Ar special_file .Nm .Op Fl v +-a +.Nm +.Op Fl v .Cm off .Sh DESCRIPTION The @@ -70,6 +74,25 @@ total amount of physical memory as repor .Va hw.physmem .Xr sysctl 8 variable. +It will also check that +.Ar special_file +is referenced in +.Xr fstab 5 +with either type ``dp'' or ``sw''. +The +.Fl f +flag causes +.Nm +to bypass this check. +.Pp +The +.Fl a +flag causes +.Nm +to automatically determine a suitable dump device by scanning +.Xr fstab 5 . +It does so by first looking for the first suitable device of type ``dp'' +and falling back to a device of type ``sw''. .Pp The .Fl v Index: sbin/dumpon/dumpon.c =================================================================== RCS file: /mnt/space/cvsroot/src/sbin/dumpon/dumpon.c,v retrieving revision 1.24 diff -u -p -r1.24 dumpon.c --- sbin/dumpon/dumpon.c 31 Oct 2006 22:36:49 -0000 1.24 +++ sbin/dumpon/dumpon.c 13 Jan 2009 00:38:09 -0000 @@ -47,6 +47,7 @@ __FBSDID("$FreeBSD: src/sbin/dumpon/dump #include #include +#include #include #include #include @@ -60,13 +61,14 @@ static int verbose; static void usage(void) { - fprintf(stderr, "%s\n%s\n", - "usage: dumpon [-v] special_file", + fprintf(stderr, "%s\n%s\n%s\n", + "usage: dumpon [-fv] special_file", + " dumpon [-v] -a", " dumpon [-v] off"); exit(EX_USAGE); } -static void +static int check_size(int fd, const char *fn) { int name[] = { CTL_HW, HW_PHYSMEM }; @@ -79,28 +81,84 @@ check_size(int fd, const char *fn) len = sizeof(minidump); if (sysctlbyname("debug.minidump", &minidump, &len, NULL, 0) == 0 && minidump == 1) - return; + return (EX_OK); len = sizeof(physmem); if (sysctl(name, namelen, &physmem, &len, NULL, 0) != 0) err(EX_OSERR, "can't get memory size"); - if (ioctl(fd, DIOCGMEDIASIZE, &mediasize) != 0) - err(EX_OSERR, "%s: can't get size", fn); + if (ioctl(fd, DIOCGMEDIASIZE, &mediasize) != 0) { + warn("%s: can't get size", fn); + return (EX_OSERR); + } if ((uintmax_t)mediasize < (uintmax_t)physmem) { if (verbose) printf("%s is smaller than physical memory\n", fn); - exit(EX_IOERR); + return (EX_IOERR); } + return (EX_OK); +} + +static int +scan_fstab(const char *type, const char **dumpdev) +{ + struct fstab *fsp; + int fd, ret; + + for (;;) { + fsp = getfsent(); + if (fsp == NULL) + break; + if (strcmp(fsp->fs_type, type)) + continue; + fd = open(fsp->fs_spec, O_RDONLY); + if (fd < 0) { + warn("%s", fsp->fs_spec); + continue; + } + ret = check_size(fd, fsp->fs_spec); + if (ret == EX_OK) { + *dumpdev = fsp->fs_spec; + return (fd); + } + close(fd); + } + + return (-1); +} + +static int +enable_dump(int fd, const char *dumpdev) +{ + int i; + u_int u; + + u = 0; + i = ioctl(fd, DIOCSKERNELDUMP, &u); + u = 1; + i = ioctl(fd, DIOCSKERNELDUMP, &u); + if (i == 0 && verbose) + printf("kernel dumps on %s\n", dumpdev); + return (i); } int main(int argc, char *argv[]) { + const char *dumpdev; + struct fstab *fsp; + int automatic, force; int ch; int i, fd; u_int u; - while ((ch = getopt(argc, argv, "v")) != -1) + automatic = force = 0; + while ((ch = getopt(argc, argv, "afv")) != -1) switch((char)ch) { + case 'a': + automatic = 1; + break; + case 'f': + force = 1; + break; case 'v': verbose = 1; break; @@ -111,20 +169,42 @@ main(int argc, char *argv[]) argc -= optind; argv += optind; - if (argc != 1) + if (argc != 1 && !automatic) usage(); - if (strcmp(argv[0], "off") != 0) { - fd = open(argv[0], O_RDONLY); + if (automatic) { + fd = scan_fstab(FSTAB_DP, &dumpdev); + if (fd < 0) { + setfsent(); + fd = scan_fstab(FSTAB_SW, &dumpdev); + } if (fd < 0) - err(EX_OSFILE, "%s", argv[0]); - check_size(fd, argv[0]); - u = 0; - i = ioctl(fd, DIOCSKERNELDUMP, &u); - u = 1; - i = ioctl(fd, DIOCSKERNELDUMP, &u); - if (i == 0 && verbose) - printf("kernel dumps on %s\n", argv[0]); + errx(EX_UNAVAILABLE, "no suitable device found"); + i = enable_dump(fd, dumpdev); + + } else if (strcmp(argv[0], "off") != 0) { + dumpdev = argv[0]; + fsp = getfsspec(dumpdev); + /* + * Allow special files referenced in fstab(5) as FSTAB_DP + * and FSTAB_SW entries. + */ + if (!force && (fsp == NULL || + (strcmp(fsp->fs_type, FSTAB_DP) && + strcmp(fsp->fs_type, FSTAB_SW) && + /* XXX Backward compatibility. */ + strcmp(fsp->fs_vfstype, "swap") && + strcmp(fsp->fs_vfstype, "dump")))) + errx(EX_OSFILE, "%s: not a dump or swap device", + dumpdev); + fd = open(dumpdev, O_RDONLY); + if (fd < 0) + err(EX_OSFILE, "%s", dumpdev); + i = check_size(fd, dumpdev); + if (i != EX_OK) + exit(i); + i = enable_dump(fd, dumpdev); + } else { fd = open(_PATH_DEVNULL, O_RDONLY); if (fd < 0) Index: sbin/savecore/savecore.8 =================================================================== RCS file: /mnt/space/cvsroot/src/sbin/savecore/savecore.8,v retrieving revision 1.26 diff -u -p -r1.26 savecore.8 --- sbin/savecore/savecore.8 26 Dec 2007 11:42:10 -0000 1.26 +++ sbin/savecore/savecore.8 13 Jan 2009 00:39:05 -0000 @@ -90,10 +90,10 @@ looks for dumps on each device specified .Ar device argument(s), or on each device in .Pa /etc/fstab -marked as -.Dq dump +with a type of +.Dq dp or -.Dq swap . +.Dq sw . The .Nm utility Index: sbin/savecore/savecore.c =================================================================== RCS file: /mnt/space/cvsroot/src/sbin/savecore/savecore.c,v retrieving revision 1.80 diff -u -p -r1.80 savecore.c --- sbin/savecore/savecore.c 27 Dec 2007 21:28:48 -0000 1.80 +++ sbin/savecore/savecore.c 13 Jan 2009 00:42:05 -0000 @@ -692,7 +692,10 @@ main(int argc, char **argv) fsp = getfsent(); if (fsp == NULL) break; - if (strcmp(fsp->fs_vfstype, "swap") && + if (strcmp(fsp->fs_type, FSTAB_SW) && + strcmp(fsp->fs_type, FSTAB_DP) && + /* XXX Backward compatibility. */ + strcmp(fsp->fs_vfstype, "swap") && strcmp(fsp->fs_vfstype, "dump")) continue; DoFile(savedir, fsp->fs_spec); Index: share/man/man5/fstab.5 =================================================================== RCS file: /mnt/space/cvsroot/src/share/man/man5/fstab.5,v retrieving revision 1.30 diff -u -p -r1.30 fstab.5 --- share/man/man5/fstab.5 11 Feb 2008 09:36:43 -0000 1.30 +++ share/man/man5/fstab.5 13 Jan 2009 00:57:07 -0000 @@ -156,7 +156,13 @@ is ``sw'' then the special file is made space by the .Xr swapon 8 command at the end of the system reboot procedure. -The fields other than +If +.Fa fs_type +is ``dp'' then the special file is intended to be made the dump device +by the +.Xr dumpon 8 +command. +In both cases, the fields other than .Fa fs_spec and .Fa fs_type @@ -250,6 +256,7 @@ within #define FSTAB_RQ "rq" /* read/write with quotas */ #define FSTAB_RO "ro" /* read-only device */ #define FSTAB_SW "sw" /* swap device */ +#define FSTAB_DP "dp" /* dump device */ #define FSTAB_XX "xx" /* ignore totally */ struct fstab { @@ -284,6 +291,7 @@ resides in .Xr getvfsbyname 3 , .Xr ccd 4 , .Xr dump 8 , +.Xr dumpon 8 , .Xr fsck 8 , .Xr mount 8 , .Xr quotacheck 8 , Index: share/man/man5/rc.conf.5 =================================================================== RCS file: /mnt/space/cvsroot/src/share/man/man5/rc.conf.5,v retrieving revision 1.334 diff -u -p -r1.334 rc.conf.5 --- share/man/man5/rc.conf.5 27 Jan 2008 15:15:12 -0000 1.334 +++ share/man/man5/rc.conf.5 17 Feb 2008 15:45:01 -0000 @@ -2917,9 +2917,9 @@ Indicates the device (usually a swap par should be written in the event of a system crash. If the value of this variable is .Dq Li AUTO , -the first suitable swap device listed in -.Pa /etc/fstab -will be used as dump device. +.Xr dumpon 8 +will try to find a suitable dump device according to +.Pa /etc/fstab . Otherwise, the value of this variable is passed as the argument to .Xr dumpon 8 . To disable crash dumps, set this variable to