1263648Sbapt/* 2262395Sbapt * Copyright (c) 1980, 1993 3263648Sbapt * The Regents of the University of California. All rights reserved. 4263648Sbapt * 5263648Sbapt * Redistribution and use in source and binary forms, with or without 6263648Sbapt * modification, are permitted provided that the following conditions 7263648Sbapt * are met: 8263648Sbapt * 1. Redistributions of source code must retain the above copyright 9263648Sbapt * notice, this list of conditions and the following disclaimer. 10263648Sbapt * 2. Redistributions in binary form must reproduce the above copyright 11263648Sbapt * notice, this list of conditions and the following disclaimer in the 12263648Sbapt * documentation and/or other materials provided with the distribution. 13263648Sbapt * 4. Neither the name of the University nor the names of its contributors 14263648Sbapt * may be used to endorse or promote products derived from this software 15263648Sbapt * without specific prior written permission. 16263648Sbapt * 17263648Sbapt * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 18263648Sbapt * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 19263648Sbapt * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 20263648Sbapt * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 21263648Sbapt * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 22263648Sbapt * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 23263648Sbapt * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 24263648Sbapt * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 25263648Sbapt * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 26263648Sbapt * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 27263648Sbapt * SUCH DAMAGE. 28263648Sbapt */ 29263648Sbapt 30263648Sbapt#if 0 31263648Sbapt#ifndef lint 32263648Sbaptstatic const char copyright[] = 33263648Sbapt"@(#) Copyright (c) 1980, 1993\n\ 34263648Sbapt The Regents of the University of California. All rights reserved.\n"; 35263648Sbapt#endif /* not lint */ 36263648Sbapt 37263648Sbapt#ifndef lint 38263648Sbaptstatic char sccsid[] = "From: @(#)swapon.c 8.1 (Berkeley) 6/5/93"; 39263648Sbapt#endif /* not lint */ 40263648Sbapt#endif 41263648Sbapt#include <sys/cdefs.h> 42263648Sbapt__FBSDID("$FreeBSD$"); 43262395Sbapt 44262395Sbapt#include <sys/param.h> 45263648Sbapt#include <sys/disk.h> 46262395Sbapt#include <sys/sysctl.h> 47262395Sbapt 48262395Sbapt#include <err.h> 49262395Sbapt#include <errno.h> 50263648Sbapt#include <fcntl.h> 51262395Sbapt#include <paths.h> 52262395Sbapt#include <stdint.h> 53263648Sbapt#include <stdio.h> 54262395Sbapt#include <stdlib.h> 55268831Sbapt#include <string.h> 56268831Sbapt#include <sysexits.h> 57263648Sbapt#include <unistd.h> 58263648Sbapt 59262395Sbaptstatic int verbose; 60263648Sbapt 61262395Sbaptstatic void 62262395Sbaptusage(void) 63268831Sbapt{ 64262395Sbapt fprintf(stderr, "%s\n%s\n%s\n", 65262395Sbapt "usage: dumpon [-v] special_file", 66263648Sbapt " dumpon [-v] off", 67262395Sbapt " dumpon [-v] -l"); 68263648Sbapt exit(EX_USAGE); 69263648Sbapt} 70263648Sbapt 71262395Sbaptstatic void 72263648Sbaptcheck_size(int fd, const char *fn) 73262395Sbapt{ 74262395Sbapt int name[] = { CTL_HW, HW_PHYSMEM }; 75262395Sbapt size_t namelen = sizeof(name) / sizeof(*name); 76262395Sbapt unsigned long physmem; 77262395Sbapt size_t len; 78262395Sbapt off_t mediasize; 79262395Sbapt int minidump; 80262395Sbapt 81262395Sbapt len = sizeof(minidump); 82262395Sbapt if (sysctlbyname("debug.minidump", &minidump, &len, NULL, 0) == 0 && 83262395Sbapt minidump == 1) 84262395Sbapt return; 85262395Sbapt len = sizeof(physmem); 86262395Sbapt if (sysctl(name, namelen, &physmem, &len, NULL, 0) != 0) 87262395Sbapt err(EX_OSERR, "can't get memory size"); 88263648Sbapt if (ioctl(fd, DIOCGMEDIASIZE, &mediasize) != 0) 89262395Sbapt err(EX_OSERR, "%s: can't get size", fn); 90262395Sbapt if ((uintmax_t)mediasize < (uintmax_t)physmem) { 91262395Sbapt if (verbose) 92262395Sbapt printf("%s is smaller than physical memory\n", fn); 93262395Sbapt exit(EX_IOERR); 94262395Sbapt } 95262395Sbapt} 96262395Sbapt 97262395Sbaptstatic void 98262395Sbaptlistdumpdev(void) 99262395Sbapt{ 100262395Sbapt char dumpdev[PATH_MAX]; 101262395Sbapt size_t len; 102262395Sbapt const char *sysctlname = "kern.shutdown.dumpdevname"; 103262395Sbapt 104262395Sbapt len = sizeof(dumpdev); 105262395Sbapt if (sysctlbyname(sysctlname, &dumpdev, &len, NULL, 0) != 0) { 106262395Sbapt if (errno == ENOMEM) { 107262395Sbapt err(EX_OSERR, "Kernel returned too large of a buffer for '%s'\n", 108262395Sbapt sysctlname); 109262395Sbapt } else { 110262395Sbapt err(EX_OSERR, "Sysctl get '%s'\n", sysctlname); 111262395Sbapt } 112262395Sbapt } 113262395Sbapt if (verbose) { 114262395Sbapt printf("kernel dumps on "); 115262395Sbapt } 116262395Sbapt if (strlen(dumpdev) == 0) { 117262395Sbapt printf("%s\n", _PATH_DEVNULL); 118262395Sbapt } else { 119262395Sbapt printf("%s\n", dumpdev); 120262395Sbapt } 121262395Sbapt} 122262395Sbapt 123262395Sbaptint 124262395Sbaptmain(int argc, char *argv[]) 125262395Sbapt{ 126262395Sbapt int ch; 127262395Sbapt int i, fd; 128262395Sbapt u_int u; 129262395Sbapt int do_listdumpdev = 0; 130262395Sbapt 131262395Sbapt while ((ch = getopt(argc, argv, "lv")) != -1) 132262395Sbapt switch((char)ch) { 133262395Sbapt case 'l': 134262395Sbapt do_listdumpdev = 1; 135262395Sbapt break; 136263648Sbapt case 'v': 137263648Sbapt verbose = 1; 138263648Sbapt break; 139263648Sbapt default: 140263648Sbapt usage(); 141263648Sbapt } 142263648Sbapt 143263648Sbapt argc -= optind; 144262395Sbapt argv += optind; 145262395Sbapt 146262395Sbapt if (do_listdumpdev) { 147262395Sbapt listdumpdev(); 148262395Sbapt exit(EX_OK); 149262395Sbapt } 150262395Sbapt 151268831Sbapt if (argc != 1) 152262395Sbapt usage(); 153262395Sbapt 154262395Sbapt if (strcmp(argv[0], "off") != 0) { 155262395Sbapt char tmp[PATH_MAX]; 156262395Sbapt char *dumpdev; 157262395Sbapt 158262395Sbapt if (strncmp(argv[0], _PATH_DEV, sizeof(_PATH_DEV) - 1) == 0) { 159262395Sbapt dumpdev = argv[0]; 160262395Sbapt } else { 161262395Sbapt i = snprintf(tmp, PATH_MAX, "%s%s", _PATH_DEV, argv[0]); 162262395Sbapt if (i < 0) { 163262395Sbapt err(EX_OSERR, "%s", argv[0]); 164262395Sbapt } else if (i >= PATH_MAX) { 165262395Sbapt errno = EINVAL; 166262395Sbapt err(EX_DATAERR, "%s", argv[0]); 167262395Sbapt } 168262395Sbapt dumpdev = tmp; 169262395Sbapt } 170262395Sbapt fd = open(dumpdev, O_RDONLY); 171262395Sbapt if (fd < 0) 172262395Sbapt err(EX_OSFILE, "%s", dumpdev); 173262395Sbapt check_size(fd, dumpdev); 174262395Sbapt u = 0; 175262395Sbapt i = ioctl(fd, DIOCSKERNELDUMP, &u); 176262395Sbapt u = 1; 177262395Sbapt i = ioctl(fd, DIOCSKERNELDUMP, &u); 178262395Sbapt if (i == 0 && verbose) 179262395Sbapt printf("kernel dumps on %s\n", dumpdev); 180262395Sbapt } else { 181262395Sbapt fd = open(_PATH_DEVNULL, O_RDONLY); 182262395Sbapt if (fd < 0) 183262395Sbapt err(EX_OSFILE, "%s", _PATH_DEVNULL); 184262395Sbapt u = 0; 185262395Sbapt i = ioctl(fd, DIOCSKERNELDUMP, &u); 186262395Sbapt if (i == 0 && verbose) 187262395Sbapt printf("kernel dumps disabled\n"); 188262395Sbapt } 189262395Sbapt if (i < 0) 190262395Sbapt err(EX_OSERR, "ioctl(DIOCSKERNELDUMP)"); 191262395Sbapt 192262395Sbapt exit (0); 193262395Sbapt} 194262395Sbapt