dumpon(8): Make error messages clearer
authorAaron LI <aly@aaronly.me>
Sun, 23 Sep 2018 04:26:33 +0000 (12:26 +0800)
committerAaron LI <aly@aaronly.me>
Sun, 23 Sep 2018 04:35:28 +0000 (12:35 +0800)
Before this patch, when a dump device is already configured, dumpon(8)
only complains with 'Device busy', which isn't helpful.  Now, dumpon(8)
will tell whether the dump device is already configured or whether need
to run 'dumpoff' first.

Always show verbose information.  The utility still accepts the '-v'
option for backward compatibility, but don't mention the option in the
man page anymore.

Bugs: https://bugs.dragonflybsd.org/issues/3092

sbin/dumpon/dumpon.8
sbin/dumpon/dumpon.c

index ab13f27..c204b73 100644 (file)
@@ -28,7 +28,7 @@
 .\"     From: @(#)swapon.8     8.1 (Berkeley) 6/5/93
 .\" $FreeBSD: src/sbin/dumpon/dumpon.8,v 1.11.2.12 2003/01/26 03:12:04 keramida Exp $
 .\"
-.Dd September 22, 2018
+.Dd September 23, 2018
 .Dt DUMPON 8
 .Os
 .Sh NAME
 .Nd "specify a device for crash dumps"
 .Sh SYNOPSIS
 .Nm
-.Op Fl v
 .Ar special_file
 .Nm
-.Op Fl v
 .Cm off
 .Nm dumpoff
-.Op Fl v
 .Sh DESCRIPTION
 The
 .Nm
@@ -58,18 +55,19 @@ controlled by the
 variable in the boot time configuration file
 .Pa /etc/rc.conf .
 .Pp
+The default type of kernel crash dump is the mini crash dump.
+Mini crash dumps hold only memory pages in use by the kernel.
+Alternatively, full memory dumps can be enabled by setting the
+.Va debug.minidump
+.Xr sysctl 8
+variable to 0.
+.Pp
 For most systems the size of the specified dump device must be at least
 the size of physical memory.
 Even though an additional header is added to the dump,
 the BIOS for a platform typically holds back some memory, so it is not usually
 necessary to size the dump device larger than the actual amount of RAM
 available in the machine.
-.Pp
-The
-.Fl v
-flag causes
-.Nm
-to be verbose about its activity.
 .Sh NOTES
 Since a
 .Xr panic 9
@@ -99,6 +97,10 @@ or if
 is the text string:
 .Dq Li off .
 .Pp
+In order to change the device for crash dumps, one needs to run the
+.Nm dumpoff
+utility to disable the current dump device before configuring the new one.
+.Pp
 Since
 .Nm
 cannot be used during kernel initialization, the
index ea0915e..489683a 100644 (file)
 #include <sys/stat.h>
 #include <sysexits.h>
 
-static void    usage(void) __dead2;
+static const char *sc_name = "kern.dumpdev";
+
+static struct stat *get_dumpdev(void);
+static void usage(void) __dead2;
 
 int
 main(int argc, char **argv)
 {
-       int ch, verbose, rv;
+       int ch;
        struct stat stab;
-       int mib[2];
+       struct stat *stab_old;
        char *path, *p;
        bool is_dumpoff;
 
@@ -60,11 +63,10 @@ main(int argc, char **argv)
                is_dumpoff = false;
        }
 
-       verbose = rv = 0;
        while ((ch = getopt(argc, argv, "v")) != -1) {
                switch (ch) {
                case 'v':
-                       verbose = 1;
+                       /* backward compatibility only */
                        break;
                case '?':
                default:
@@ -82,8 +84,7 @@ main(int argc, char **argv)
                stab.st_rdev = NODEV;
        } else {
                path = getdevpath(path, 0);
-               rv = stat(path, &stab);
-               if (rv)
+               if (stat(path, &stab) != 0)
                        err(EX_OSFILE, "%s", path);
 
                if (!S_ISCHR(stab.st_mode)) {
@@ -93,15 +94,20 @@ main(int argc, char **argv)
                }
        }
 
-       mib[0] = CTL_KERN;
-       mib[1] = KERN_DUMPDEV;
-
-       rv = sysctl(mib, 2, NULL, NULL, &stab.st_rdev, sizeof stab.st_rdev);
-       if (rv) {
-               err(EX_OSERR, "sysctl: kern.dumpdev");
-       }
+       stab_old = get_dumpdev();
 
-       if (verbose) {
+       if (stab.st_rdev == stab_old->st_rdev) {
+               if (stab.st_rdev == NODEV) {
+                       printf("dumpon: crash dumps already disabled.\n");
+               } else {
+                       printf("dumpon: crash dumps already configured "
+                              "to the given device.\n");
+               }
+       } else if (stab.st_rdev == NODEV || stab_old->st_rdev == NODEV) {
+               if (sysctlbyname(sc_name, NULL, NULL,
+                                &stab.st_rdev, sizeof stab.st_rdev) != 0) {
+                       err(EX_OSERR, "sysctl: %s", sc_name);
+               }
                if (stab.st_rdev == NODEV) {
                        printf("dumpon: crash dumps disabled\n");
                } else {
@@ -110,11 +116,35 @@ main(int argc, char **argv)
                               (unsigned long)major(stab.st_rdev),
                               (unsigned long)minor(stab.st_rdev));
                }
+       } else {
+               warnx("crash dumps already configured "
+                     "to another device (%lu, %#lx)",
+                     (unsigned long)major(stab.st_rdev),
+                     (unsigned long)minor(stab.st_rdev));
+               errx(EX_USAGE, "you need to run 'dumpoff' first.");
        }
 
        return 0;
 }
 
+
+static struct stat *
+get_dumpdev(void)
+{
+       struct stat *stab;
+       size_t len;
+
+       if ((stab = malloc(sizeof(*stab))) == NULL)
+               err(EX_OSERR, "malloc");
+
+       memset(stab, 0, sizeof(*stab));
+       len = sizeof(stab->st_rdev);
+       if (sysctlbyname(sc_name, &stab->st_rdev, &len, NULL, 0) != 0)
+               err(EX_OSERR, "sysctl: %s", sc_name);
+
+       return stab;
+}
+
 static void
 usage(void)
 {