savecore.c
来自「<B>Digital的Unix操作系统VAX 4.2源码</B>」· C语言 代码 · 共 1,460 行 · 第 1/3 页
C
1,460 行
#ifndef lintstatic char *sccsid = "@(#)savecore.c 4.2 ULTRIX 10/9/90";#endif lint/************************************************************************ * * * Copyright (c) 1985,86 by * * Digital Equipment Corporation, Maynard, MA * * All rights reserved. * * * * This software is furnished under a license and may be used and * * copied only in accordance with the terms of such license and * * with the inclusion of the above copyright notice. This * * software or any other copies thereof may not be provided or * * otherwise made available to any other person. No title to and * * ownership of the software is hereby transferred. * * * * This software is derived from software received from the * * University of California, Berkeley, and from Bell * * Laboratories. Use, duplication, or disclosure is subject to * * restrictions under license agreements with University of * * California and with AT&T. * * * * The information in this software is subject to change without * * notice and should not be construed as a commitment by Digital * * Equipment Corporation. * * * * Digital assumes no responsibility for the use or reliability * * of its software on equipment which is not supplied by Digital. * * * ************************************************************************//************************************************************************ * * Modification History * * JAW 17-Sep-90 * Sync out a crash dump after it has been saved but before the * dump partition has been cleared. * * Alan Frechette 09-Nov-89 * Check for bad or failed dumps by making sure all the dump * descriptors are valid by examining the PFN's and by checking * the last dump descriptor for magic numbers. This sanity checking * is needed to determine whether a dump succeeded or failed. Also * added logging of all dumps that succeeded or failed in the file * "/usr/adm/shutdownlog". * * Alan Frechette 22-Sep-89 * Check for EOF in save_core() when saving the core image. If * we reach EOF on the dump device then break out of the loop * otherwise we will be stuck in an infinite loop. Needed for * dumps that failed. * * Alan Frechette 15-Aug-89 * Fixed bug in savecore to read the partial dump magic number * and the full dump magic number from /dev/kmem instead of from * the dump device. Save the error logger buffer before saving * the core image. * * Alan Frechette 04-Aug-89 * Fixed a minor bug so savecore would work as it did before * when the system image that crashed was not "/vmunix". When * savecore is run on a different system image it assumes the * running system image is "/vmunix". * * Alan Frechette 24-July-89 * New savecore utility which handles the new crash dump strategy. * System now does selective dumping of physical memory. Now only * one savecore utility for both VAX and MIPS architectures. Removed * lots of code that was no longer needed. Changed entire utility to * read and write in DEV_BSIZE byte increments. * * Alan Frechette 27-June-89 * Added a new option "-d" to specify the dump device and the * dump device offset when running savecore on a system image * other then the currently running system image. This is needed * because the dump device and the dump device offset of the * running system image may be different from the that of the * system image that crashed. Changed several routines for this * to work correctly. * * Paul Shaughnessy, 03-Feb-89 * Changed clear_dump() to read and write in DEV_BSIZE byte * increments. Some disk drivers do not support operations on * non sector boundaries. * * Mark Parenti, 27-Feb-89 * Modified include of ufs/fs.h to be <ufs/fs.h> instead of * dot relative through the sys link. * * Joe Amato, 12-May-87 * Modified to use statfs(path, buf) instead of getmnt(). * * Paul Shaughnessy, 08-April-87 * Added logic to handle saving of the core file on a NFS * mounted file system. * * Paul Shaughnessy, 19-Mar-87 * Added -f flag for a network crash dump. The core image for * network crash client will reside in a file on the server, * not a disk partition. Also fixed clearing of the dump logic. * * pete keilty 12-Feb-87 * Added printf stating checking for dump. Bar * * Paul Shaughnessy, 22-May-86 * Added saving of the u_area support to save_core. This * required writing a new procedure save_uarea, which * users raw i/o for accesses to the dump device. * * Barb Glover, 05-May-86 * Changed savecore to use raw i/o to solve "I/O error" problem, * because of file system read past the end of the partition. * Also, append to end of elbuffer file. * * Paul Shaughnessy, 09-Apr-86 * Changed initialization of namelist values because of the * addition on the include file a.out.h. Added partial * crash dump support, including modifying the namelist * entry for elbuf. Also added a print statement to print * out when saving core. * * Barbara Glover, 05-Mar-86 * Store elbuf base addr at beg. of elbuffer file * Added include of errlog.h for DUMPSIZE * * Barbara Glover, 19-Feb-86 * Added save of error log bufffer; added -e switch to * save error log buffer(only). * * Stephen Reilly, 22-Apr-85 * 001- Added the -c switch to enable the user to clear the dump flag * on the dump device. * ***********************************************************************//* * savecore */#include <stdio.h>#ifdef vax#include <a.out.h>#endif vax#ifdef mips#include <nlist.h>#endif mips#include <stab.h>#include <errno.h>#include <sys/param.h>#include <sys/dir.h>#include <sys/stat.h>#include <sys/file.h>#include <sys/user.h>#include <sys/dump.h>#include <ufs/fs.h>#include <sys/errlog.h>#include <sys/types.h>#include <sys/un.h>#include <elcsd.h>#include <machine/param.h>#include <machine/pte.h>#include <sys/mount.h>#include <sys/fs_types.h>#define DAY (60L*60L*24L)#define LEEWAY (3*DAY)#define BLOCK 0#define RAW 1#ifdef vax#define ok(number) ((number)&0x7fffffff)#endif vax#ifdef mips#define ok(number) ((number)&0x1fffffff)#endif mips#define SHUTDOWNLOG "/usr/adm/shutdownlog"#define X_DUMPDEV 0#define X_DUMPLO 1#define X_TIME 2#define X_DUMPSIZE 3#define X_DUMPSIZE2 4#define X_VERSION 5#define X_PANICSTR 6#define X_DUMPMAG 7#define X_FULLDUMPMAG 8#define X_PARTDUMPMAG 9#define X_NUMDUMPDESC 10#define X_ELBUF 11#define X_DUMPSOFTPGSZ 12#define X_DUMPHARDPGSZ 13#define X_SBR 14#define X_CPU 15#define X_PHYSMEM 16#define NUM_IN_TAB 17#define RAWBUFSZ 2048#define MSIZE (NMOUNT * sizeof (struct fs_data))struct nlist nlsystem[NUM_IN_TAB + 1];struct nlist nl[NUM_IN_TAB +1];char *system;char *dirname; /* directory to save dumps in */char *ddname; /* name of dump device */char *corefile; /* core file name for network dump */char *find_dev();dev_t dumpdev; /* dump device */time_t dumptime; /* time the dump was taken */int dumplo; /* where dump starts on dumpdev */int dumpsize; /* initial size of memory dumped */int dumpsize2; /* additional size of memory dumped */int dumpdescriptors; /* number of dump descriptor blocks */int dumpsoftpgsize; /* system software pagesize */int dumphardpgsize; /* system hardware pagesize */int dumpmag; /* magic number in dump */int physmem; /* physical memory size */int full_dumpmag; /* full dump magic number */int partial_dumpmag; /* partial dump magic number */int kerrsize; /* size of error log buffer in pages */int partial_dump; /* switch for partial or full dump */int old_bounds; /* temp hold for original bounds */time_t now; /* current date */char *path();char *malloc();char *ctime();char vers[80];char core_vers[80];char panic_mesg[80];int panicstr;off_t lseek();off_t Lseek();int tstdebug = 0;int cflag = 0; /* Used for the -c switch */int dflag = 0; /* Used for the -d switch */int eflag = 0; /* Used for the -e switch */int fflag = 0; /* Used for the -f switch */int dirname_notlocal = -1; /* 0 - dirname on local file system 1 - dirname on a NFS mounted file system */char rbuf[RAWBUFSZ]; /* buffer for raw i/o */struct stat dsb;main(argc, argv) char **argv; int argc;{ struct fs_data fsdbuf; argv++; argc--; while (argc > 0 && argv[0][0] == '-') { switch (argv[0][1]) { case 'c': cflag++; break; case 'd': dflag++; argc--; argv++; if(argc < 2) { usage(); exit(1); } if((strncmp(argv[0], "0x", 2) == 0) || (strncmp(argv[0], "0X", 2) == 0)) sscanf(&argv[0][2], "%x", &dumpdev); else sscanf(argv[0], "%d", &dumpdev); argc--; argv++; if((strncmp(argv[0], "0x", 2) == 0) || (strncmp(argv[0], "0X", 2) == 0)) sscanf(&argv[0][2], "%x", &dumplo); else sscanf(argv[0], "%d", &dumplo); break; case 'e': eflag++; break; case 'f': fflag++; argc--; argv++; corefile = argv[0]; if (access(corefile, 2) < 0) { perror(corefile); exit(1); } break; default: usage(); exit(1); } argc--; argv++; } if (!eflag && !cflag && argc != 1 && argc != 2) { usage(); exit(1); } /* * We don't need the directory path if -e or -c flag was given -afd */ if (!eflag && !cflag) { dirname = argv[0]; if (argc == 2) system = argv[1]; if (access(dirname, 2) < 0) { perror(dirname); exit(1); } /* * stat the dirname */ if (stat(dirname, &dsb) < 0) { perror(dirname); exit(1); } if(statfs(dirname, &fsdbuf) == 0){ fprintf(stderr, "savecore: statfs %s failed\n", dirname); exit(1); } dirname_notlocal = (fsdbuf.fd_fstype == GT_NFS ? 1 : 0); } /* * Initialize the name list tables. */ init_nlist(); read_kmem(); printf("savecore: checking for dump..."); if (dump_exists()) { /* * if cflag set then clear the dump flag */ if (cflag) { clear_dump(); printf("dump cleared\n"); exit(0); } if (partial_dump) printf("partial dump exists\n"); else printf("full dump exists\n"); (void) time(&now); check_kmem(); log_entry(); if (get_crashtime() && check_space()) { if (eflag) { printf("saving elbuf\n"); save_elbuf(); sync(); sync(); clear_dump(); } else { printf("saving elbuf\n"); save_elbuf(); printf("saving core\n"); save_core(); sync(); sync(); clear_dump(); } } else { printf("crashtime or space problem\n"); exit(1); } } else printf("dump does not exist\n"); exit(0);}usage(){ fprintf(stderr, "usage: savecore [-c] [-d dumpdev dumplo] [-e] [-f corename] dirname [ system ]\n");}init_nlist(){#ifdef vax nl[X_DUMPDEV].n_un.n_name = nlsystem[X_DUMPDEV].n_un.n_name = "_dumpdev"; nl[X_DUMPLO].n_un.n_name = nlsystem[X_DUMPLO].n_un.n_name = "_dumplo"; nl[X_TIME].n_un.n_name = nlsystem[X_TIME].n_un.n_name = "_time"; nl[X_DUMPSIZE].n_un.n_name = nlsystem[X_DUMPSIZE].n_un.n_name = "_dumpsize"; nl[X_DUMPSIZE2].n_un.n_name = nlsystem[X_DUMPSIZE2].n_un.n_name = "_dumpsize2"; nl[X_VERSION].n_un.n_name = nlsystem[X_VERSION].n_un.n_name = "_version"; nl[X_PANICSTR].n_un.n_name = nlsystem[X_PANICSTR].n_un.n_name = "_panicstr"; nl[X_DUMPMAG].n_un.n_name = nlsystem[X_DUMPMAG].n_un.n_name = "_dumpmag"; nl[X_FULLDUMPMAG].n_un.n_name = nlsystem[X_FULLDUMPMAG].n_un.n_name = "_full_dumpmag"; nl[X_PARTDUMPMAG].n_un.n_name = nlsystem[X_PARTDUMPMAG].n_un.n_name = "_partial_dumpmag"; nl[X_NUMDUMPDESC].n_un.n_name = nlsystem[X_NUMDUMPDESC].n_un.n_name = "_dumpdescriptors"; nl[X_ELBUF].n_un.n_name = nlsystem[X_ELBUF].n_un.n_name = "_elbuf"; nl[X_DUMPSOFTPGSZ].n_un.n_name = nlsystem[X_DUMPSOFTPGSZ].n_un.n_name = "_dumpsoftpgsize"; nl[X_DUMPHARDPGSZ].n_un.n_name = nlsystem[X_DUMPHARDPGSZ].n_un.n_name = "_dumphardpgsize"; nl[X_SBR].n_un.n_name = nlsystem[X_SBR].n_un.n_name = "_Sysmap"; nl[X_CPU].n_un.n_name = nlsystem[X_CPU].n_un.n_name = "_cpudata"; nl[X_PHYSMEM].n_un.n_name = nlsystem[X_PHYSMEM].n_un.n_name = "_physmem"; nl[NUM_IN_TAB].n_un.n_name = nlsystem[NUM_IN_TAB].n_un.n_name = "" ;#endif vax#ifdef mips nl[X_DUMPDEV].n_name = nlsystem[X_DUMPDEV].n_name = "_dumpdev"; nl[X_DUMPLO].n_name = nlsystem[X_DUMPLO].n_name = "_dumplo"; nl[X_TIME].n_name = nlsystem[X_TIME].n_name = "_time"; nl[X_DUMPSIZE].n_name = nlsystem[X_DUMPSIZE].n_name = "_dumpsize"; nl[X_DUMPSIZE2].n_name = nlsystem[X_DUMPSIZE2].n_name = "_dumpsize2"; nl[X_VERSION].n_name = nlsystem[X_VERSION].n_name = "_version"; nl[X_PANICSTR].n_name = nlsystem[X_PANICSTR].n_name = "_panicstr"; nl[X_DUMPMAG].n_name = nlsystem[X_DUMPMAG].n_name = "_dumpmag"; nl[X_FULLDUMPMAG].n_name = nlsystem[X_FULLDUMPMAG].n_name = "_full_dumpmag"; nl[X_PARTDUMPMAG].n_name = nlsystem[X_PARTDUMPMAG].n_name = "_partial_dumpmag"; nl[X_NUMDUMPDESC].n_name = nlsystem[X_NUMDUMPDESC].n_name = "_dumpdescriptors"; nl[X_ELBUF].n_name = nlsystem[X_ELBUF].n_name = "_elbuf"; nl[X_DUMPSOFTPGSZ].n_name = nlsystem[X_DUMPSOFTPGSZ].n_name = "_dumpsoftpgsize"; nl[X_DUMPHARDPGSZ].n_name = nlsystem[X_DUMPHARDPGSZ].n_name = "_dumphardpgsize"; nl[X_SBR].n_name = nlsystem[X_SBR].n_name = "_Sysmap"; nl[X_CPU].n_name = nlsystem[X_CPU].n_name = "_cpudata"; nl[X_PHYSMEM].n_name = nlsystem[X_PHYSMEM].n_name = "_physmem"; nl[NUM_IN_TAB].n_name = nlsystem[NUM_IN_TAB].n_name = "" ;#endif mips}intdump_exists(){ register int dumpfd; int word; int seektot,seekval,seekrem; char *rptr; dumpfd = Open(ddname, 0); seektot = (off_t) (dumplo + ok(nlsystem[X_DUMPMAG].n_value)); seekval = (seektot / DEV_BSIZE) * DEV_BSIZE; seekrem = seektot % DEV_BSIZE; Lseek(dumpfd, (off_t) seekval, 0); Read(dumpfd, rbuf, round(seekrem + 4)); close(dumpfd); rptr = rbuf + seekrem; word = *(int *)rptr; if (word == full_dumpmag) { partial_dump = 0; return(1); } else if (word == partial_dumpmag) { partial_dump = 1; return(1);
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?