⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 log_dump.c

📁 jfs 源码
💻 C
📖 第 1 页 / 共 2 页
字号:
/* *   Copyright (c) International Business Machines Corp., 2000-2002 * *   This program is free software;  you can redistribute it and/or modify *   it under the terms of the GNU General Public License as published by *   the Free Software Foundation; either version 2 of the License, or  *   (at your option) any later version. *  *   This program is distributed in the hope that it will be useful, *   but WITHOUT ANY WARRANTY;  without even the implied warranty of *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See *   the GNU General Public License for more details. * *   You should have received a copy of the GNU General Public License *   along with this program;  if not, write to the Free Software  *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */#include "jfs_types.h"#include <time.h>#include <stdio.h>#include <stdlib.h>#include <memory.h>#include <string.h>#include <fcntl.h>#include <errno.h>#include "jfs_endian.h"#include "jfs_filsys.h"#include "jfs_superblock.h"#include "jfs_dinode.h"#include "jfs_dtree.h"#include "jfs_xtree.h"#include "jfs_logmgr.h"#include "jfs_dmap.h"#include "jfs_imap.h"#include "logredo.h"#include "devices.h"#include "debug.h"extern int LogOpenMode;#define LOGDMP_OK 	0#define LOGDMP_FAILED	-1#define MAKEDEV(__x,__y)        (dev_t)(((__x)<<16) | (__y))#define LOGPNTOB(x)  ((x)<<L2LOGPSIZE)#define LOG2NUM(NUM, L2NUM)\{\        if ((NUM) <= 0)\                L2NUM = -1;\        else\        if ((NUM) == 1)\                L2NUM = 0;\        else\        {\                L2NUM = 0;\                while ( (NUM) > 1 )\                {\                        L2NUM++;\                        (NUM) >>= 1;\                }\        }\}/* + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + * *       things for the log. */int32_t logend;			/* address of the end of last log record */struct logsuper logsup;		/* log super block */int32_t numdoblk;		/* number of do blocks used     */int32_t numnodofile;		/* number of nodo file blocks used  *//* + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + * * The output file. * */FILE *outfp;#define  output_filename  "./jfslog.dmp"int logdmp_outfile_is_open = 0;/* + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + * *      open file system aggregate/lv array * * logredo() processes a single log. * at the first release, logredo will process a single log * related to one aggregate. But the future release, logredo needs to * to process one single log related to multiple agreegates. * In both cases, the aggregate(logical volume) where the log stays * will be different from  the file system aggregate/lv. * * There will be one imap for the aggregate inode allocation map * and a list of imap pointers to multiple fileset inode allocation maps. * * There is one block allocation map per aggregate and shared by all the * filesets within the aggregate. * * the log and related aggregates (logical volumes) are all in * the same volume group, i.e., each logical volume is uniquely specified * by their minor number with the same major number, * the maximum number of lvs in a volume group is NUMMINOR (256). *//* * We only deal with the log here.  No need for vopen array */struct vopen volume;/* + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + * *      file system page buffer cache * * for k > 0, bufhdr[k] describes contents of buffer[k-1]. * bufhdr[0] is reserved as anchor for free/lru list: * bufhdr[0].next points to the MRU buffer (head), * bufhdr[0].prev points to the LRU buffer (tail); *//* buffer header table */struct bufhdr {	int16_t next;		/* 2: next on free/lru list */	int16_t prev;		/* 2: previous on free/lru list */	int16_t hnext;		/* 2: next on hash chain */	int16_t hprev;		/* 2: previous on hash chain */	char modify;		/* 1: buffer was modified */	char inuse;		/* 1: buffer on hash chain */	int16_t reserve;	/* 2 */	int32_t vol;		/* 4: minor of agrregate/lv number */	pxd_t pxd;		/* 8: on-disk page pxd */} bufhdr[NBUFPOOL];		/* (24) *//* buffer table */struct bufpool {	char bytes[PSIZE];} buffer[NBUFPOOL - 1];/* *      log page buffer cache * * log has its own 4 page buffer pool. */uint8_t afterdata[LOGPSIZE * 2];	/* buffer to read in redopage data *//* * Miscellaneous */caddr_t prog;			/* Program name */int32_t mntcnt, bufsize;char *mntinfo;int32_t retcode;		/* return code from logredo    *//* * external references */extern char *optarg;extern int optind;extern int initMaps(int32_t);extern int updateMaps(int);extern int findEndOfLog(void);extern int logRead(int32_t, struct lrd *, char *);extern int logredoInit(void);extern int alloc_wrksp(uint32_t, int, int, void **);	/* defined in fsckwsp.c *//* * forward references */int open_outfile(void);int ldmp_readSuper(int32_t, struct superblock *);int ldmp_isLogging(caddr_t, int32_t, char *, int32_t);int ldmp_logError(int, int);int usage(void);int disp_updatemap(struct lrd *);int disp_redopage(struct lrd *);int disp_noredopage(struct lrd *);int disp_noredoinoext(struct lrd *);void ldmp_xdump(char *, int);int ldmp_x_scmp(char *, char *);void ldmp_x_scpy(char *, char *);int prtdesc(struct lrd *);/* -------------------------------------------------------------------- * * NAME:        jfs_logdump() * * FUNCTION: * */int jfs_logdump(caddr_t pathname, int32_t fd, int32_t dump_all){	int rc;	int32_t logaddr, nextaddr, lastaddr, nlogrecords;	struct lrd ld;	int32_t lowest_lr_byte = 2 * LOGPSIZE + LOGPHDRSIZE;	int32_t highest_lr_byte = 0;	int log_has_wrapped = 0;	int in_use;	rc = open_outfile();	if (rc == 0) {		/* output file is open */		/*		 * loop until we get enough memory to read vmount struct		 */		mntinfo = (char *) &bufsize;		bufsize = sizeof (int);		/*		 * Find and open the log		 */		LogOpenMode = O_RDONLY;		rc = findLog(fd, &in_use);		if (rc < 0) {			printf("JFS_LOGDUMP:Error occurred when open/read device\n");			fprintf(outfp, "??????????????????????????????????????????????????????\n");			fprintf(outfp, "JFS_LOGDUMP:Error occurred when open/read device\n");			fprintf(outfp, "??????????????????????????????????????????????????????\n");			return (rc);		}		/*		 * validate log superblock		 *		 * aggregate block size is for log file as well.		 */		rc = ujfs_rw_diskblocks(log.fd,					(uint64_t) (log.xaddr + LOGPNTOB(LOGSUPER_B)),					(unsigned) sizeof (struct logsuper), (char *) &logsup, GET);		if (rc != 0) {			printf("JFS_LOGDUMP:couldn't read log superblock:failure in %s\n", prog);			fprintf(outfp, "??????????????????????????????????????????????????????\n");			fprintf(outfp, "JFS_LOGDUMP:couldn't read log superblock:failure in %s\n",				prog);			fprintf(outfp, "??????????????????????????????????????????????????????\n");			return (LOGSUPER_READ_ERROR);		}		ujfs_swap_logsuper(&logsup);		fprintf(outfp, "JOURNAL SUPERBLOCK: \n");		fprintf(outfp, "------------------------------------------------------\n");		fprintf(outfp, "   magic number: x %x \n", logsup.magic);		fprintf(outfp, "   version     : x %x \n", logsup.version);		fprintf(outfp, "   serial      : x %x \n", logsup.serial);		fprintf(outfp, "   size        : t %d pages (4096 bytes/page)\n", logsup.size);		fprintf(outfp, "   bsize       : t %d bytes/block\n", logsup.bsize);		fprintf(outfp, "   l2bsize     : t %d \n", logsup.l2bsize);		fprintf(outfp, "   flag        : x %x \n", logsup.flag);		fprintf(outfp, "   state       : x %x \n", logsup.state);		fprintf(outfp, "   end         : x %x \n", logsup.end);		fprintf(outfp, "\n");		fprintf(outfp, "======================================================\n");		fprintf(outfp, "\n");		if (logsup.magic != LOGMAGIC) {			fprintf(outfp, "\n");			fprintf(outfp, "**WARNING** %s: %s is not a log file\n", prog, pathname);			fprintf(outfp, "\n");			fprintf(outfp, "======================================================\n");			fprintf(outfp, "\n");		}		if (logsup.version != LOGVERSION) {			fprintf(outfp, "\n");			fprintf(outfp, "**WARNING** %s and log file %s version mismatch\n", prog,				pathname);			fprintf(outfp, "\n");			fprintf(outfp, "======================================================\n");			fprintf(outfp, "\n");		}		if (logsup.state == LOGREDONE) {			fprintf(outfp, "\n");			fprintf(outfp, "**WARNING** %s and log file %s state is LOGREDONE\n", prog,				pathname);			fprintf(outfp, "\n");			fprintf(outfp, "======================================================\n");			fprintf(outfp, "\n");		}		log.size = logsup.size;		log.serial = logsup.serial;		/*		 * find the end of log		 */		logend = findEndOfLog();		if (logend < 0) {			printf("logend < 0\n");			ldmp_logError(LOGEND, 0);			ujfs_swap_logsuper(&logsup);			rc = ujfs_rw_diskblocks(log.fd,						(uint64_t) (log.xaddr + LOGPNTOB(LOGSUPER_B)),						(unsigned long) LOGPSIZE, (char *) &logsup, PUT);			rc = logend;			goto loopexit;		}		highest_lr_byte = logsup.size * LOGPSIZE - LOGRDSIZE;		if ((logend < lowest_lr_byte) || (logend > highest_lr_byte)) {			fprintf(outfp, "\n");			fprintf(outfp,				"**ERROR** logend address is not valid for a logrec. logend: 0x0%x\n",				logend);			fprintf(outfp, "\n");			fprintf(outfp, "======================================================\n");			fprintf(outfp, "\n");			return (INVALID_LOGEND);		}		/*		 *      replay log		 *		 * read log backwards and process records as we go.		 * reading stops at place specified by first SYNCPT we		 * encounter.		 */		nlogrecords = lastaddr = 0;		nextaddr = logend;		do {			logaddr = nextaddr;			nextaddr = logRead(logaddr, &ld, afterdata);			fprintf(outfp,				"logrec d %d   Logaddr= x %x   Nextaddr= x %x   Backchain = x %x\n",				nlogrecords, logaddr, nextaddr, ld.backchain);			fprintf(outfp, "\n");			nlogrecords += 1;			/*			 *			 * Validate the nextaddr as much as possible			 *			 */			if (nextaddr < 0) {				ldmp_logError(READERR, logaddr);				if (nextaddr == REFORMAT_ERROR) {					rc = nextaddr;					goto loopexit;				}				break;			}			/*			 * Certain errors we'll assume signal the end of the log			 * since we're just dumping everything from the latest			 * commit record to the earliest valid record.			 */			if ((nextaddr < lowest_lr_byte) || (nextaddr > highest_lr_byte)) {				lastaddr = logaddr;			}			if (nextaddr == logaddr) {				lastaddr = logaddr;			}			if (nextaddr > logaddr) {				if (log_has_wrapped) {					fprintf(outfp, "\n");					fprintf(outfp,						"**ERROR** log wrapped twice. logaddr:0x0%x nextaddr:0x0%x\n",						logaddr, nextaddr);					fprintf(outfp, "\n");					fprintf(outfp,						"======================================================\n");					fprintf(outfp, "\n");					lastaddr = logaddr;				} else {					log_has_wrapped = -1;				}			}			/*			 *			 * The addresses seem ok.  Process the current record.			 *			 */			if (lastaddr != logaddr) {				switch (ld.type) {				case LOG_COMMIT:					fprintf(outfp,						"LOG_COMMIT   (type = d %d)   logtid = d %d   aggregate = d %d\n",						ld.type, ld.logtid, ld.aggregate);					fprintf(outfp, "\n");					fprintf(outfp, "\tdata length = d %d\n", ld.length);					break;				case LOG_MOUNT:					fprintf(outfp,						"++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\n");					fprintf(outfp,						"LOG_MOUNT   (type = d %d)   logtid = d %d   aggregate = d %d\n",						ld.type, ld.logtid, ld.aggregate);					fprintf(outfp, "\n");					fprintf(outfp, "\tdata length = d %d\n", ld.length);					fprintf(outfp,						"++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\n");					break;				case LOG_SYNCPT:					fprintf(outfp,						"****************************************************************\n");					fprintf(outfp,						"LOG_SYNCPT   (type = d %d)   logtid = d %d    aggregate = d %d\n",						ld.type, ld.logtid, ld.aggregate);					fprintf(outfp, "\n");					fprintf(outfp, "\tdata length = d %d\n", ld.length);					fprintf(outfp, "\tsync = x %x\n", ld.log.syncpt.sync);					fprintf(outfp,						"****************************************************************\n");					rc = 0;					if (!dump_all) {	/* user just wants from last synch point forward */						if (lastaddr == 0) {							lastaddr = (ld.log.syncpt.sync == 0)							    ? logaddr : ld.log.syncpt.sync;						}					}	/* end user just wants from last synch point forward */					break;				case LOG_REDOPAGE:					fprintf(outfp,						"LOG_REDOPAGE   (type = d %d)   logtid = d %d    aggregate = d %d\n",						ld.type, ld.logtid, ld.aggregate);					fprintf(outfp, "\n");					fprintf(outfp, "\tdata length = d %d    ", ld.length);					disp_redopage(&ld);					break;				case LOG_NOREDOPAGE:					fprintf(outfp,						"LOG_NOREDOPAGE   (type = d %d)   logtid = d %d   aggregate = d %d\n",						ld.type, ld.logtid, ld.aggregate);					fprintf(outfp, "\n");					fprintf(outfp, "\tdata length = d %d    ", ld.length);					disp_noredopage(&ld);					break;				case LOG_NOREDOINOEXT:					fprintf(outfp,						"LOG_NOREDOINOEXT (type = d %d)   logtid = d %d   aggregate = d %d\n",						ld.type, ld.logtid, ld.aggregate);					fprintf(outfp, "\n");					fprintf(outfp, "\tdata length = d %d    ", ld.length);					disp_noredoinoext(&ld);					break;				case LOG_UPDATEMAP:					fprintf(outfp,						"LOG_UPDATEMAP   (type = d %d)   logtid = d %d   aggregate = d %d\n",						ld.type, ld.logtid, ld.aggregate);					fprintf(outfp, "\n");					fprintf(outfp, "\tdata length = d %d    ", ld.length);					disp_updatemap(&ld);					break;				default:					fprintf(outfp,						"*UNRECOGNIZED*   (type = d %d)   logtid = d %d   aggregate = d %d\n",						ld.type, ld.logtid, ld.aggregate);					fprintf(outfp, "\n");					fprintf(outfp, "\tdata length = d %d\n", ld.length);					fprintf(outfp, "\n");					fprintf(outfp, "**ERROR** unrecognized log record type\n");					fprintf(outfp, "\n");					fprintf(outfp,						"======================================================\n");					fprintf(outfp, "\n");					return (UNRECOG_LOGRECTYP);				}				if (rc == 0) {					fprintf(outfp, "\n");					if (ld.length > 0) {						ldmp_xdump((char *) afterdata, ld.length);					}				}				fprintf(outfp, "\n");				fprintf(outfp,					"----------------------------------------------------------------------\n");			}			/* end if( lastaddr != logaddr )  */		} while (logaddr != lastaddr);	      loopexit:		/*		 * Close the output file		 */		if (logdmp_outfile_is_open) {			fclose(outfp);		}		if (rc == 0) {	/* log has been dumped successfully */			printf			    ("JFS_LOGDUMP: The current JFS log has been dumped into ./jfslog.dmp\n");		} else {			printf("JFS_LOGDUMP:Failed in %s\n", prog);			fprintf(outfp, "??????????????????????????????????????????????????????\n");			fprintf(outfp, "JFS_LOGDUMP:Failed in %s\n", prog);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -