X-Git-Url: https://git.subgeniuskitty.com/unix-history/.git/blobdiff_plain/bfda38267fe2ecd29ab6a35c9cfd0ee01a631f96..638231e6203d8d8447c87fcb959bb90da83f521f:/usr/src/sbin/savecore/savecore.c diff --git a/usr/src/sbin/savecore/savecore.c b/usr/src/sbin/savecore/savecore.c index ec8c6bdec5..31ff825bbf 100644 --- a/usr/src/sbin/savecore/savecore.c +++ b/usr/src/sbin/savecore/savecore.c @@ -2,17 +2,33 @@ * Copyright (c) 1980, 1986, 1989 The Regents of the University of California. * All rights reserved. * - * Redistribution and use in source and binary forms are permitted - * provided that the above copyright notice and this paragraph are - * duplicated in all such forms and that any documentation, - * advertising materials, and other materials related to such - * distribution and use acknowledge that the software was developed - * by the University of California, Berkeley. The name of the - * University may not be used to endorse or promote products derived - * from this software without specific prior written permission. - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED - * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. */ #ifndef lint @@ -22,19 +38,16 @@ char copyright[] = #endif /* not lint */ #ifndef lint -static char sccsid[] = "@(#)savecore.c 5.20 (Berkeley) %G%"; +static char sccsid[] = "@(#)savecore.c 5.26 (Berkeley) 4/8/91"; #endif /* not lint */ -/* - * savecore - */ - #include -#include +#include #include #include #include #include +#include #include #include #include @@ -49,9 +62,13 @@ static char sccsid[] = "@(#)savecore.c 5.20 (Berkeley) %G%"; #ifdef tahoe #define ok(number) ((number)&~0xc0000000) #else +#ifdef i386 +#define ok(number) ((number)&~0xfe000000) +#else #define ok(number) (number) #endif #endif +#endif struct nlist current_nl[] = { /* namelist for currently running system */ #define X_DUMPDEV 0 @@ -102,7 +119,7 @@ char panic_mesg[80]; int panicstr; off_t lseek(); off_t Lseek(); -int Verbose; +int verbose; int force; int clear; extern int errno; @@ -111,44 +128,67 @@ main(argc, argv) char **argv; int argc; { + extern char *optarg; + extern int optind; + int ch; char *cp; - argc--, argv++; - while (argc > 0 && argv[0][0] == '-') { - for (cp = &argv[0][1]; *cp; cp++) switch (*cp) { - - case 'f': - force++; + while ((ch = getopt(argc, argv, "cdfv")) != EOF) + switch(ch) { + case 'c': + clear = 1; break; - + case 'd': /* not documented */ case 'v': - case 'd': - Verbose++; + verbose = 1; break; - - case 'c': - clear++; + case 'f': + force = 1; break; - + case '?': default: - usage: - fprintf(stderr, - "usage: savecore [-f] [-v] [-c] dirname [ system ]\n"); - exit(1); + usage(); } - argc--, argv++; + argc -= optind; + argv += optind; + + /* This is wrong, but I want "savecore -c" to work. */ + if (!clear) { + if (argc != 1 && argc != 2) + usage(); + dirname = argv[0]; } - if (argc != 1 && argc != 2) - goto usage; - dirname = argv[0]; if (argc == 2) system = argv[1]; + openlog("savecore", LOG_ODELAY, LOG_AUTH); + + read_kmem(); + if (!dump_exists()) { +/* (void)fprintf(stderr, "savecore: no core dump\n");*/ + if (!force) + exit(0); + } + if (clear) { + clear_dump(); + exit(0); + } + (void) time(&now); + check_kmem(); + if (panicstr) + log(LOG_CRIT, "reboot after panic: %s\n", panic_mesg); + else + syslog(LOG_CRIT, "reboot\n"); + if (access(dirname, W_OK) < 0) { Perror(LOG_ERR, "%s: %m\n", dirname); exit(1); } - read_kmem(); + if ((!get_crashtime() || !check_space()) && !force) + exit(1); + save_core(); + clear_dump(); + exit(0); } dump_exists() @@ -157,7 +197,7 @@ dump_exists() Lseek(dumpfd, (off_t)(dumplo + ok(dump_nl[X_DUMPMAG].n_value)), L_SET); Read(dumpfd, (char *)&word, sizeof (word)); - if (Verbose && word != dumpmag) + if (verbose && word != dumpmag) printf("magic number mismatch: %x != %x\n", word, dumpmag); return (word == dumpmag); } @@ -175,10 +215,15 @@ find_dev(dev, type) register dev_t dev; register int type; { + register DIR *dfd = opendir(_PATH_DEV); + struct dirent *dir; struct stat statb; + static char devname[MAXPATHLEN + 1]; char *dp; strcpy(devname, _PATH_DEV); + while ((dir = readdir(dfd))) { + strcpy(devname + sizeof(_PATH_DEV) - 1, dir->d_name); if (stat(devname, &statb)) { perror(devname); continue; @@ -186,11 +231,13 @@ find_dev(dev, type) if ((statb.st_mode&S_IFMT) != type) continue; if (dev == statb.st_rdev) { + closedir(dfd); dp = malloc(strlen(devname)+1); strcpy(dp, devname); return (dp); } } + closedir(dfd); log(LOG_ERR, "Can't find device %d/%d\n", major(dev), minor(dev)); exit(1); /*NOTREACHED*/ @@ -250,7 +297,7 @@ read_kmem() Read(kmem, (char *)&dumpdev, sizeof (dumpdev)); Lseek(kmem, (long)current_nl[X_DUMPLO].n_value, L_SET); Read(kmem, (char *)&dumplo, sizeof (dumplo)); - if (Verbose) + if (verbose) printf("dumplo = %d (%d * %d)\n", dumplo, dumplo/DEV_BSIZE, DEV_BSIZE); Lseek(kmem, (long)current_nl[X_DUMPMAG].n_value, L_SET); @@ -280,6 +327,7 @@ check_kmem() log(LOG_ERR, "Can't fdopen dumpfd\n"); exit(1); } + fseek(fp, (off_t)(dumplo+ok(dump_nl[X_VERSION].n_value)), L_SET); fgets(core_vers, sizeof (core_vers), fp); if (!eq(vers, core_vers) && system == 0) { @@ -287,6 +335,7 @@ check_kmem() log(LOG_WARNING, "\t%s\n", vers); log(LOG_WARNING, "and\t%s\n", core_vers); } + fseek(fp, (off_t)(dumplo + ok(dump_nl[X_PANICSTR].n_value)), L_SET); fread((char *)&panicstr, sizeof (panicstr), 1, fp); if (panicstr) { @@ -306,7 +355,7 @@ get_crashtime() Lseek(dumpfd, (off_t)(dumplo + ok(dump_nl[X_TIME].n_value)), L_SET); Read(dumpfd, (char *)&dumptime, sizeof dumptime); if (dumptime == 0) { - if (Verbose) + if (verbose) printf("Dump time is zero.\n"); return (0); } @@ -332,26 +381,20 @@ path(file) check_space() { - struct stat dsb; - register char *ddev; - int dfd, spacefree; - struct fs fs; + long minfree, spacefree; + struct statfs fsbuf; - if (stat(dirname, &dsb) < 0) { + if (statfs(dirname, &fsbuf) < 0) { Perror(LOG_ERR, "%s: %m\n", dirname); exit(1); } - ddev = find_dev(dsb.st_dev, S_IFBLK); - dfd = Open(ddev, O_RDONLY); - Lseek(dfd, SBOFF, L_SET); - Read(dfd, (char *)&fs, sizeof (fs)); - close(dfd); - spacefree = freespace(&fs, fs.fs_minfree) * fs.fs_fsize / 1024; - if (spacefree < read_number("minfree")) { + spacefree = fsbuf.f_bavail * fsbuf.f_fsize / 1024; + minfree = read_number("minfree"); + if (minfree > 0 && spacefree - dumpsize < minfree) { log(LOG_WARNING, "Dump omitted, not enough space on device\n"); return (0); } - if (freespace(&fs, fs.fs_minfree) < 0) + if (spacefree - dumpsize < minfree) log(LOG_WARNING, "Dump performed, but free space threshold crossed\n"); return (1); @@ -374,7 +417,8 @@ read_number(fn) return (atoi(lin)); } -#define BUFSIZE (256*1024) /* 1/4 Mb */ +/*#define BUFSIZE (256*1024) /* 1/4 Mb */ +#define BUFSIZE (8*1024) save_core() { @@ -392,6 +436,8 @@ save_core() } bounds = read_number("bounds"); ifd = Open(system ? system : _PATH_UNIX, O_RDONLY); + (void)sprintf(cp, "system.%d", bounds); + ofd = Create(path(cp), 0644); while((n = Read(ifd, cp, BUFSIZE)) > 0) Write(ofd, cp, n); close(ifd); @@ -403,11 +449,11 @@ save_core() } Lseek(dumpfd, (off_t)(dumplo + ok(dump_nl[X_DUMPSIZE].n_value)), L_SET); Read(dumpfd, (char *)&dumpsize, sizeof (dumpsize)); - (void)sprintf(cp, "vmcore.%d", bounds); + (void)sprintf(cp, "ram.%d", bounds); ofd = Create(path(cp), 0644); Lseek(ifd, (off_t)dumplo, L_SET); dumpsize *= NBPG; - log(LOG_NOTICE, "Saving %d bytes of image in vmcore.%d\n", + log(LOG_NOTICE, "Saving %d bytes of image in ram.%d\n", dumpsize, bounds); while (dumpsize > 0) { n = read(ifd, cp, @@ -416,7 +462,7 @@ save_core() if (n == 0) log(LOG_WARNING, "WARNING: EOF on dump device; %s\n", - "vmcore may be incomplete"); + "ram file may be incomplete"); else Perror(LOG_ERR, "read from dumpdev: %m", "read"); @@ -428,7 +474,7 @@ save_core() else log(LOG_ERR, "short write: wrote %d of %d\n", ret, n); - log(LOG_WARNING, "WARNING: vmcore may be incomplete\n"); + log(LOG_WARNING, "WARNING: ram file may be incomplete\n"); break; } dumpsize -= n; @@ -532,7 +578,7 @@ log(level, msg, a1, a2) Perror(level, msg, s) int level; - char *msg; + char *msg, *s; { int oerrno = errno; @@ -540,3 +586,9 @@ Perror(level, msg, s) errno = oerrno; syslog(level, msg, s); } + +usage() +{ + (void)fprintf(stderr, "usage: savecore [-cfv] dirname [system]\n"); + exit(1); +}