diff options
author | Miod Vallat <miod@cvs.openbsd.org> | 2001-06-29 17:08:16 +0000 |
---|---|---|
committer | Miod Vallat <miod@cvs.openbsd.org> | 2001-06-29 17:08:16 +0000 |
commit | 5a3f5236bbe90f0f671991e7ce5b892c21d46661 (patch) | |
tree | 14930be9d8b0760494690807cacd604af41c047f /sbin | |
parent | 49b3799ff115945d5ed7999d59f9e21a62e84a75 (diff) |
More libkvm.old relics
Diffstat (limited to 'sbin')
-rw-r--r-- | sbin/savecore/Makefile | 10 | ||||
-rw-r--r-- | sbin/savecore/savecore_old.c | 717 |
2 files changed, 2 insertions, 725 deletions
diff --git a/sbin/savecore/Makefile b/sbin/savecore/Makefile index 7083d37bab3..abb7069df73 100644 --- a/sbin/savecore/Makefile +++ b/sbin/savecore/Makefile @@ -1,16 +1,10 @@ -# $OpenBSD: Makefile,v 1.16 2000/04/15 20:35:57 mickey Exp $ +# $OpenBSD: Makefile,v 1.17 2001/06/29 17:08:14 miod Exp $ PROG= savecore -# XXX Temporarily until pmax is able to use libkvm -.if (${MACHINE} == "pmax") -SRCS= savecore_old.c -.else -SRCS= savecore.c +SRCS= savecore.c zopen.c LDADD= -lkvm DPADD= ${LIBKVM} -.endif -SRCS+= zopen.c MAN= savecore.8 .PATH: ${.CURDIR}/../../usr.bin/compress diff --git a/sbin/savecore/savecore_old.c b/sbin/savecore/savecore_old.c deleted file mode 100644 index 2d64cebcaf9..00000000000 --- a/sbin/savecore/savecore_old.c +++ /dev/null @@ -1,717 +0,0 @@ -/* $OpenBSD: savecore_old.c,v 1.18 2001/06/04 14:59:49 mickey Exp $ */ -/* $NetBSD: savecore_old.c,v 1.1.1.1 1996/03/16 10:25:11 leo Exp $ */ - -/*- - * Copyright (c) 1986, 1992, 1993 - * The Regents of the University of California. All rights reserved. - * - * 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 -static char copyright[] = -"@(#) Copyright (c) 1986, 1992, 1993\n\ - The Regents of the University of California. All rights reserved.\n"; -#endif /* not lint */ - -#ifndef lint -#if 0 -static char sccsid[] = "@(#)savecore.c 8.3 (Berkeley) 1/2/94"; -#else -static char rcsid[] = "$OpenBSD: savecore_old.c,v 1.18 2001/06/04 14:59:49 mickey Exp $"; -#endif -#endif /* not lint */ - -#include <sys/param.h> -#include <sys/stat.h> -#include <sys/mount.h> -#include <sys/syslog.h> -#include <sys/types.h> -#include <sys/time.h> -#include <sys/resource.h> - -#include <dirent.h> -#include <errno.h> -#include <fcntl.h> -#include <nlist.h> -#include <paths.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <tzfile.h> -#include <unistd.h> -#include <vis.h> - -extern FILE *zopen __P((const char *fname, const char *mode, int bits)); - -#define ok(number) ((number) - KERNBASE) - -struct nlist current_nl[] = { /* Namelist for currently running system. */ -#define X_DUMPDEV 0 - { "_dumpdev" }, -#define X_DUMPLO 1 - { "_dumplo" }, -#define X_TIME 2 - { "_time" }, -#define X_DUMPSIZE 3 - { "_dumpsize" }, -#define X_VERSION 4 - { "_version" }, -#define X_PANICSTR 5 - { "_panicstr" }, -#define X_DUMPMAG 6 - { "_dumpmag" }, - { "" }, -}; -int cursyms[] = { X_DUMPDEV, X_DUMPLO, X_VERSION, X_DUMPMAG, -1 }; -int dumpsyms[] = { X_TIME, X_DUMPSIZE, X_VERSION, X_PANICSTR, X_DUMPMAG, -1 }; - -struct nlist dump_nl[] = { /* Name list for dumped system. */ - { "_dumpdev" }, /* Entries MUST be the same as */ - { "_dumplo" }, /* those in current_nl[]. */ - { "_time" }, - { "_dumpsize" }, - { "_version" }, - { "_panicstr" }, - { "_dumpmag" }, - { "" }, -}; - -/* Types match kernel declarations. */ -long dumplo; /* where dump starts on dumpdev */ -int dumpmag; /* magic number in dump */ -int dumpsize; /* amount of memory dumped */ - -char *kernel; -char *dirname; /* directory to save dumps in */ -char *ddname; /* name of dump device */ -dev_t dumpdev; /* dump device */ -int dumpfd; /* read/write descriptor on block dev */ -time_t now; /* current date */ -char panic_mesg[1024]; -int panicstr; -char vers[1024]; - -int clear, compress, force, verbose; /* flags */ - -void check_kmem __P((void)); -int check_space __P((void)); -void clear_dump __P((void)); -int Create __P((char *, int)); -int dump_exists __P((void)); -char *find_dev __P((dev_t, int)); -int get_crashtime __P((void)); -void kmem_setup __P((void)); -void log __P((int, char *, ...)); -void Lseek __P((int, off_t, int)); -int Open __P((char *, int rw)); -int Read __P((int, void *, int)); -char *rawname __P((char *s)); -void save_core __P((void)); -void usage __P((void)); -void Write __P((int, void *, int)); - -int -main(argc, argv) - int argc; - char *argv[]; -{ - struct rlimit rl; - int ch; - - openlog("savecore", LOG_PERROR, LOG_DAEMON); - - /* Increase our data size to the max if we can. */ - if (getrlimit(RLIMIT_DATA, &rl) == 0) { - rl.rlim_cur = rl.rlim_max; - if (setrlimit(RLIMIT_DATA, &rl) < 0) - syslog(LOG_WARNING, "can't set rlimit data size: %m"); - } - - while ((ch = getopt(argc, argv, "cdfN:vz")) != -1) - switch(ch) { - case 'c': - clear = 1; - break; - case 'd': /* Not documented. */ - case 'v': - verbose = 1; - break; - case 'f': - force = 1; - break; - case 'N': - kernel = optarg; - break; - case 'z': - compress = 1; - break; - case '?': - default: - usage(); - } - argc -= optind; - argv += optind; - - if (!clear) { - if (argc != 1 && argc != 2) - usage(); - dirname = argv[0]; - } - if (argc == 2) - kernel = argv[1]; - - (void)time(&now); - kmem_setup(); - - if (clear) { - clear_dump(); - return (0); - } - - if (!dump_exists() && !force) - return (1); - - check_kmem(); - - if (panicstr) - syslog(LOG_ALERT, "reboot after panic: %s", panic_mesg); - else - syslog(LOG_ALERT, "reboot"); - - if ((!get_crashtime() || !check_space()) && !force) - return (1); - - save_core(); - - clear_dump(); - return (0); -} - -void -kmem_setup() -{ - FILE *fp; - int kmem, i; - char *dump_sys, *current_sys; - - /* - * Some names we need for the currently running system, others for - * the system that was running when the dump was made. The values - * obtained from the current system are used to look for things in - * /dev/kmem that cannot be found in the dump_sys namelist, but are - * presumed to be the same (since the disk partitions are probably - * the same!) - */ - if ((i = open(_PATH_KSYMS, O_RDONLY)) != -1) { - current_sys = _PATH_KSYMS; - (void)close(i); - } else { - current_sys = _PATH_UNIX; - } - if ((nlist(current_sys, current_nl)) == -1) { - syslog(LOG_ERR, "%s: nlist: %m", current_sys); - if (errno == ENOENT) - exit(1); - } - for (i = 0; cursyms[i] != -1; i++) - if (current_nl[cursyms[i]].n_value == 0) { - syslog(LOG_ERR, "%s: %s not in namelist", - _PATH_UNIX, current_nl[cursyms[i]].n_name); - exit(1); - } - - dump_sys = kernel ? kernel : _PATH_UNIX; - - if ((nlist(dump_sys, dump_nl)) == -1) { - syslog(LOG_ERR, "%s: nlist: %m", dump_sys); - if (errno == ENOENT) - exit(1); - } - for (i = 0; dumpsyms[i] != -1; i++) - if (dump_nl[dumpsyms[i]].n_value == 0) { - syslog(LOG_ERR, "%s: %s not in namelist", - dump_sys, dump_nl[dumpsyms[i]].n_name); - exit(1); - } - - kmem = Open(_PATH_KMEM, O_RDONLY); - Lseek(kmem, (off_t)current_nl[X_DUMPDEV].n_value, SEEK_SET); - (void)Read(kmem, &dumpdev, sizeof(dumpdev)); - if (dumpdev == NODEV) { - syslog(LOG_WARNING, "no core dump (no dumpdev)"); - exit(1); - } - Lseek(kmem, (off_t)current_nl[X_DUMPLO].n_value, SEEK_SET); - (void)Read(kmem, &dumplo, sizeof(dumplo)); - dumplo *= DEV_BSIZE; - if (verbose) - (void)printf("dumplo = %d (%d * %d)\n", - dumplo, dumplo / DEV_BSIZE, DEV_BSIZE); - Lseek(kmem, (off_t)current_nl[X_DUMPMAG].n_value, SEEK_SET); - (void)Read(kmem, &dumpmag, sizeof(dumpmag)); - ddname = find_dev(dumpdev, S_IFBLK); - dumpfd = Open(ddname, O_RDWR); - fp = fdopen(kmem, "r"); - if (fp == NULL) { - syslog(LOG_ERR, "%s: fdopen: %m", _PATH_KMEM); - exit(1); - } - if (kernel) - return; - (void)fseek(fp, (off_t)current_nl[X_VERSION].n_value, SEEK_SET); - (void)fgets(vers, sizeof(vers), fp); - - /* Don't fclose(fp), we use dumpfd later. */ -} - -void -check_kmem() -{ - register char *cp; - FILE *fp; - char core_vers[1024]; - - fp = fdopen(dumpfd, "r"); - if (fp == NULL) { - syslog(LOG_ERR, "%s: fdopen: %m", ddname); - exit(1); - } - fseek(fp, (off_t)(dumplo + ok(dump_nl[X_VERSION].n_value)), SEEK_SET); - fgets(core_vers, sizeof(core_vers), fp); - - if (strcmp(vers, core_vers) && kernel == 0) { - char *p; - - p = strchr(vers, '\n'); - if (p) - *p = '\0'; - p = strchr(core_vers, '\n'); - if (p) - *p = '\0'; - syslog(LOG_WARNING, - "warning: %s version mismatch:\n\t%s\nand\t%s\n", - _PATH_UNIX, vers, core_vers); - } - - (void)fseek(fp, - (off_t)(dumplo + ok(dump_nl[X_PANICSTR].n_value)), SEEK_SET); - (void)fread(&panicstr, sizeof(panicstr), 1, fp); - if (panicstr) { - char c, visout[5]; - size_t vislen; - - cp = panic_mesg; - (void)fseek(fp, dumplo + ok(panicstr), SEEK_SET); - for (;;) { - c = getc(fp); - if (c == EOF || c == '\0') - break; - - vis(visout, c, VIS_SAFE|VIS_NOSLASH, 0); - vislen = strlen(visout); - if (cp - panic_mesg + vislen >= sizeof(panic_mesg)) - break; - strcat(cp, visout); - cp += vislen; - } - } - /* Don't fclose(fp), we use dumpfd later. */ -} - -void -clear_dump() -{ - long newdumplo; - - newdumplo = 0; - Lseek(dumpfd, (off_t)(dumplo + ok(dump_nl[X_DUMPMAG].n_value)), - SEEK_SET); - Write(dumpfd, &newdumplo, sizeof(newdumplo)); -} - -int -dump_exists() -{ - int newdumpmag; - - Lseek(dumpfd, (off_t)(dumplo + ok(dump_nl[X_DUMPMAG].n_value)), - SEEK_SET); - (void)Read(dumpfd, &newdumpmag, sizeof(newdumpmag)); - - /* Read the dump size. */ - Lseek(dumpfd, (off_t)(dumplo + ok(dump_nl[X_DUMPSIZE].n_value)), - SEEK_SET); - (void)Read(dumpfd, &dumpsize, sizeof(dumpsize)); - dumpsize *= getpagesize(); - - /* - * Return zero if core dump doesn't seem to be there, and note - * it for syslog. This check and return happens after the dump size - * is read, so dumpsize is whether or not the core is valid (for -f). - */ - if (newdumpmag != dumpmag) { - if (verbose) - syslog(LOG_WARNING, "magic number mismatch (%x != %x)", - newdumpmag, dumpmag); - syslog(LOG_WARNING, "no core dump"); - return (0); - } - return (1); -} - -char buf[1024 * 1024]; - -void -save_core() -{ - register FILE *fp; - register int bounds, ifd, nr, nw, ofd; - char *rawp, path[MAXPATHLEN]; - mode_t um; - - um = umask(S_IRWXG|S_IRWXO); - - /* - * Get the current number and update the bounds file. Do the update - * now, because may fail later and don't want to overwrite anything. - */ - (void)snprintf(path, sizeof(path), "%s/bounds", dirname); - if ((fp = fopen(path, "r")) == NULL) - goto err1; - if (fgets(buf, sizeof(buf), fp) == NULL) { - if (ferror(fp)) -err1: syslog(LOG_WARNING, "%s: %m", path); - bounds = 0; - } else - bounds = atoi(buf); - if (fp != NULL) - (void)fclose(fp); - if ((fp = fopen(path, "w")) == NULL) - syslog(LOG_ERR, "%s: %m", path); - else { - (void)fprintf(fp, "%d\n", bounds + 1); - (void)fclose(fp); - } - - /* Create the core file. */ - (void)snprintf(path, sizeof(path), "%s%s.%d.core%s", - dirname, _PATH_UNIX, bounds, compress ? ".Z" : ""); - if (compress) { - if ((fp = zopen(path, "w", 0)) == NULL) { - syslog(LOG_ERR, "%s: %m", path); - exit(1); - } - } else - ofd = Create(path, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH); - - /* Open the raw device. */ - rawp = rawname(ddname); - if ((ifd = open(rawp, O_RDONLY)) == -1) { - syslog(LOG_WARNING, "%s: %m; using block device", rawp); - ifd = dumpfd; - } - - /* Seek to the start of the core. */ - Lseek(ifd, (off_t)dumplo, SEEK_SET); - - /* Copy the core file. */ - syslog(LOG_NOTICE, "writing %score to %s", - compress ? "compressed " : "", path); - for (; dumpsize > 0; dumpsize -= nr) { - (void)printf("%8dK\r", dumpsize / 1024); - (void)fflush(stdout); - nr = read(ifd, buf, MIN(dumpsize, sizeof(buf))); - if (nr <= 0) { - if (nr == 0) - syslog(LOG_WARNING, - "WARNING: EOF on dump device"); - else - syslog(LOG_ERR, "%s: %m", rawp); - goto err2; - } - if (compress) - nw = fwrite(buf, 1, nr, fp); - else - nw = write(ofd, buf, nr); - if (nw != nr) { - syslog(LOG_ERR, "%s: %s", - path, strerror(nw == 0 ? EIO : errno)); -err2: syslog(LOG_WARNING, - "WARNING: core may be incomplete"); - (void)printf("\n"); - exit(1); - } - } - (void)close(ifd); - if (compress) - (void)fclose(fp); - else - (void)close(ofd); - - /* Copy the kernel. */ - ifd = Open(kernel ? kernel : _PATH_UNIX, O_RDONLY); - (void)snprintf(path, sizeof(path), "%s%s.%d%s", - dirname, _PATH_UNIX, bounds, compress ? ".Z" : ""); - if (compress) { - if ((fp = zopen(path, "w", 0)) == NULL) { - syslog(LOG_ERR, "%s: %m", path); - exit(1); - } - } else - ofd = Create(path, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH); - syslog(LOG_NOTICE, "writing %skernel to %s", - compress ? "compressed " : "", path); - while ((nr = read(ifd, buf, sizeof(buf))) > 0) { - if (compress) - nw = fwrite(buf, 1, nr, fp); - else - nw = write(ofd, buf, nr); - if (nw != nr) { - syslog(LOG_ERR, "%s: %s", - path, strerror(nw == 0 ? EIO : errno)); - syslog(LOG_WARNING, - "WARNING: kernel may be incomplete"); - exit(1); - } - } - if (nr < 0) { - syslog(LOG_ERR, "%s: %m", kernel ? kernel : _PATH_UNIX); - syslog(LOG_WARNING, "WARNING: kernel may be incomplete"); - exit(1); - } - if (compress) - (void)fclose(fp); - else - (void)close(ofd); - (void)umask(um); -} - -char * -find_dev(dev, type) - register dev_t dev; - register int type; -{ - register DIR *dfd; - struct dirent *dir; - struct stat sb; - char *dp, devname[MAXPATHLEN + 1]; - - if ((dfd = opendir(_PATH_DEV)) == NULL) { - syslog(LOG_ERR, "%s: %m", _PATH_DEV); - exit(1); - } - (void)strcpy(devname, _PATH_DEV); - while ((dir = readdir(dfd))) { - (void)strcpy(devname + sizeof(_PATH_DEV) - 1, dir->d_name); - if (lstat(devname, &sb)) { - syslog(LOG_ERR, "%s: %m", devname); - continue; - } - if ((sb.st_mode & S_IFMT) != type) - continue; - if (dev == sb.st_rdev) { - closedir(dfd); - if ((dp = strdup(devname)) == NULL) { - syslog(LOG_ERR, "%s", strerror(ENOMEM)); - exit(1); - } - return (dp); - } - } - closedir(dfd); - syslog(LOG_ERR, "can't find device %d/%d", major(dev), minor(dev)); - exit(1); -} - -char * -rawname(s) - char *s; -{ - char *sl, name[MAXPATHLEN]; - - if ((sl = strrchr(s, '/')) == NULL || sl[1] == '0') { - syslog(LOG_ERR, - "can't make raw dump device name from %s", s); - return (s); - } - (void)snprintf(name, sizeof(name), "%.*s/r%s", sl - s, s, sl + 1); - if ((sl = strdup(name)) == NULL) { - syslog(LOG_ERR, "%s", strerror(ENOMEM)); - exit(1); - } - return (sl); -} - -int -get_crashtime() -{ - time_t dumptime; /* Time the dump was taken. */ - - Lseek(dumpfd, (off_t)(dumplo + ok(dump_nl[X_TIME].n_value)), SEEK_SET); - (void)Read(dumpfd, &dumptime, sizeof(dumptime)); - if (dumptime == 0) { - if (verbose) - syslog(LOG_ERR, "dump time is zero"); - return (0); - } - (void)printf("savecore: system went down at %s", ctime(&dumptime)); -#define LEEWAY (7 * SECSPERDAY) - if (dumptime < now - LEEWAY || dumptime > now + LEEWAY) { - (void)printf("dump time is unreasonable\n"); - return (0); - } - return (1); -} - -int -check_space() -{ - register FILE *fp; - char *tkernel; - off_t minfree, spacefree, kernelsize, needed; - struct stat st; - struct statfs fsbuf; - char buf[100], path[MAXPATHLEN]; - - tkernel = kernel ? kernel : _PATH_UNIX; - if (stat(tkernel, &st) < 0) { - syslog(LOG_ERR, "%s: %m", tkernel); - exit(1); - } - kernelsize = st.st_blocks * S_BLKSIZE; - if (statfs(dirname, &fsbuf) < 0) { - syslog(LOG_ERR, "%s: %m", dirname); - exit(1); - } - spacefree = (fsbuf.f_bavail * fsbuf.f_bsize) / 1024; - - (void)snprintf(path, sizeof(path), "%s/minfree", dirname); - if ((fp = fopen(path, "r")) == NULL) - minfree = 0; - else { - if (fgets(buf, sizeof(buf), fp) == NULL) - minfree = 0; - else - minfree = atoi(buf); - (void)fclose(fp); - } - - needed = (dumpsize + kernelsize) / 1024; - if (minfree > 0 && spacefree - needed < minfree) { - syslog(LOG_WARNING, - "no dump, not enough free space on device"); - return (0); - } - if (spacefree - needed < minfree) - syslog(LOG_WARNING, - "dump performed, but free space threshold crossed"); - return (1); -} - -int -Open(name, rw) - char *name; - int rw; -{ - int fd; - - if ((fd = open(name, rw, 0)) < 0) { - syslog(LOG_ERR, "%s: %m", name); - exit(1); - } - return (fd); -} - -int -Read(fd, bp, size) - int fd, size; - void *bp; -{ - int nr; - - nr = read(fd, bp, size); - if (nr != size) { - syslog(LOG_ERR, "read: %m"); - exit(1); - } - return (nr); -} - -void -Lseek(fd, off, flag) - int fd, flag; - off_t off; -{ - off_t ret; - - ret = lseek(fd, off, flag); - if (ret == -1) { - syslog(LOG_ERR, "lseek: %m"); - exit(1); - } -} - -int -Create(file, mode) - char *file; - int mode; -{ - register int fd; - - fd = open(file, O_WRONLY | O_CREAT | O_TRUNC, mode); - if (fd < 0) { - syslog(LOG_ERR, "%s: %m", file); - exit(1); - } - return (fd); -} - -void -Write(fd, bp, size) - int fd, size; - void *bp; -{ - int n; - - if ((n = write(fd, bp, size)) < size) { - syslog(LOG_ERR, "write: %s", strerror(n == -1 ? errno : EIO)); - exit(1); - } -} - -void -usage() -{ - extern char *__progname; - - fprintf(stderr, "usage: %s [-cfvz] [-N system] directory\n", - __progname); - exit(1); -} |