dumpon.c revision 330897
1/*-
2 * SPDX-License-Identifier: BSD-3-Clause
3 *
4 * Copyright (c) 1980, 1993
5 *	The Regents of the University of California.  All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 *    notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 *    notice, this list of conditions and the following disclaimer in the
14 *    documentation and/or other materials provided with the distribution.
15 * 4. Neither the name of the University nor the names of its contributors
16 *    may be used to endorse or promote products derived from this software
17 *    without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE.
30 */
31
32#if 0
33#ifndef lint
34static const char copyright[] =
35"@(#) Copyright (c) 1980, 1993\n\
36	The Regents of the University of California.  All rights reserved.\n";
37#endif /* not lint */
38
39#ifndef lint
40static char sccsid[] = "From: @(#)swapon.c	8.1 (Berkeley) 6/5/93";
41#endif /* not lint */
42#endif
43#include <sys/cdefs.h>
44__FBSDID("$FreeBSD: stable/11/sbin/dumpon/dumpon.c 330897 2018-03-14 03:19:51Z eadler $");
45
46#include <sys/param.h>
47#include <sys/disk.h>
48#include <sys/sysctl.h>
49
50#include <err.h>
51#include <errno.h>
52#include <fcntl.h>
53#include <paths.h>
54#include <stdint.h>
55#include <stdio.h>
56#include <stdlib.h>
57#include <string.h>
58#include <sysexits.h>
59#include <unistd.h>
60
61static int	verbose;
62
63static void
64usage(void)
65{
66	fprintf(stderr, "%s\n%s\n%s\n",
67	    "usage: dumpon [-v] special_file",
68	    "       dumpon [-v] off",
69	    "       dumpon [-v] -l");
70	exit(EX_USAGE);
71}
72
73static void
74check_size(int fd, const char *fn)
75{
76	int name[] = { CTL_HW, HW_PHYSMEM };
77	size_t namelen = nitems(name);
78	unsigned long physmem;
79	size_t len;
80	off_t mediasize;
81	int minidump;
82
83	len = sizeof(minidump);
84	if (sysctlbyname("debug.minidump", &minidump, &len, NULL, 0) == 0 &&
85	    minidump == 1)
86		return;
87	len = sizeof(physmem);
88	if (sysctl(name, namelen, &physmem, &len, NULL, 0) != 0)
89		err(EX_OSERR, "can't get memory size");
90	if (ioctl(fd, DIOCGMEDIASIZE, &mediasize) != 0)
91		err(EX_OSERR, "%s: can't get size", fn);
92	if ((uintmax_t)mediasize < (uintmax_t)physmem) {
93		if (verbose)
94			printf("%s is smaller than physical memory\n", fn);
95		exit(EX_IOERR);
96	}
97}
98
99static void
100listdumpdev(void)
101{
102	char dumpdev[PATH_MAX];
103	size_t len;
104	const char *sysctlname = "kern.shutdown.dumpdevname";
105
106	len = sizeof(dumpdev);
107	if (sysctlbyname(sysctlname, &dumpdev, &len, NULL, 0) != 0) {
108		if (errno == ENOMEM) {
109			err(EX_OSERR, "Kernel returned too large of a buffer for '%s'\n",
110				sysctlname);
111		} else {
112			err(EX_OSERR, "Sysctl get '%s'\n", sysctlname);
113		}
114	}
115	if (verbose) {
116		printf("kernel dumps on ");
117	}
118	if (strlen(dumpdev) == 0) {
119		printf("%s\n", _PATH_DEVNULL);
120	} else {
121		printf("%s\n", dumpdev);
122	}
123}
124
125int
126main(int argc, char *argv[])
127{
128	int ch;
129	int i, fd;
130	u_int u;
131	int do_listdumpdev = 0;
132
133	while ((ch = getopt(argc, argv, "lv")) != -1)
134		switch((char)ch) {
135		case 'l':
136			do_listdumpdev = 1;
137			break;
138		case 'v':
139			verbose = 1;
140			break;
141		default:
142			usage();
143		}
144
145	argc -= optind;
146	argv += optind;
147
148	if (do_listdumpdev) {
149		listdumpdev();
150		exit(EX_OK);
151	}
152
153	if (argc != 1)
154		usage();
155
156	if (strcmp(argv[0], "off") != 0) {
157		char tmp[PATH_MAX];
158		char *dumpdev;
159
160		if (strncmp(argv[0], _PATH_DEV, sizeof(_PATH_DEV) - 1) == 0) {
161			dumpdev = argv[0];
162		} else {
163			i = snprintf(tmp, PATH_MAX, "%s%s", _PATH_DEV, argv[0]);
164			if (i < 0) {
165				err(EX_OSERR, "%s", argv[0]);
166			} else if (i >= PATH_MAX) {
167				errno = EINVAL;
168				err(EX_DATAERR, "%s", argv[0]);
169			}
170			dumpdev = tmp;
171		}
172		fd = open(dumpdev, O_RDONLY);
173		if (fd < 0)
174			err(EX_OSFILE, "%s", dumpdev);
175		check_size(fd, dumpdev);
176		u = 0;
177		i = ioctl(fd, DIOCSKERNELDUMP, &u);
178		u = 1;
179		i = ioctl(fd, DIOCSKERNELDUMP, &u);
180		if (i == 0 && verbose)
181			printf("kernel dumps on %s\n", dumpdev);
182	} else {
183		fd = open(_PATH_DEVNULL, O_RDONLY);
184		if (fd < 0)
185			err(EX_OSFILE, "%s", _PATH_DEVNULL);
186		u = 0;
187		i = ioctl(fd, DIOCSKERNELDUMP, &u);
188		if (i == 0 && verbose)
189			printf("kernel dumps disabled\n");
190	}
191	if (i < 0)
192		err(EX_OSERR, "ioctl(DIOCSKERNELDUMP)");
193
194	exit (0);
195}
196