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 + -
显示快捷键?