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

📄 extract.c

📁 在Linux内核从2.4升级到2.6时需要升级的软件包
💻 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 *//* *   COMPONENT_NAME: jfs_fscklog (formerly xchklog) * *      The jfs_fscklog tool provides 2 basic functions - fsck.jfs *      service log extraction and display.  The code here extracts *      the log. * */#include <config.h>#include <fcntl.h>#include <stdio.h>#include <string.h>#include <unistd.h>#include "devices.h"#include "diskmap.h"#include "fsckwsp.h"#include "fsck_message.h"#include "jfs_endian.h"#include "jfs_fscklog.h"#include "super.h"#include "utilsubs.h"#include "xfsck.h"#define fsck_READ  1#define fsck_WRITE 2extern char file_name[128];FILE *outfp;extern struct fscklog_record fscklog_record;extern struct fscklog_record *local_recptr; /* + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +  *  * superblock I/O buffer and pointer  *  */struct superblock aggr_superblock;struct superblock *sb_ptr; /* + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +  *  * input:  fsck service log I/O buffer  * output: fsck extracted service log I/O buffer  *  */char fscklog_buffer[FSCKLOG_BUFSIZE];char xchklog_buffer[XCHKLOG_BUFSIZE]; /* + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +  *  * For message processing  *  *    values are assigned by the main jfs_fscklog routine  */extern char *Vol_Label; /* + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +  *  * Device information.  *  *     values are assigned when (if) the device is opened.  */FILE *Dev_IOPort;unsigned Dev_blksize;int Dev_SectorSize;/* VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV * * The following are internal to this file * */void extract_service_log(void);int xchklog_final_processing(void);int xchklog_fscklog_fill_buffer(void);int xchklog_initial_processing(struct fscklog_record *);int open_device_read(const char *);int open_outfile(void);int readwrite_device(int64_t, unsigned, unsigned *, void *, int);void record_msg(char *);int validate_super(int);int validate_superblock(void);/***************************************************************************** * NAME: xchklog * * FUNCTION: Entry point for jfs read aggregate fsck service log * * PARAMETERS: *           local_recptr - fscklog record * * RETURNS: *      success: 0 *      failure: something else */int xchklog(struct fscklog_record *local_recptr){	int rc = 0;	/*	 * some basic initializations	 */	sb_ptr = &aggr_superblock;	rc = xchklog_initial_processing(local_recptr);	if (rc == 0) {		/* we have a buffer and the device is open */		extract_service_log();	}	if (rc == 0) {		rc = xchklog_final_processing();	} else {		xchklog_final_processing();	}	return (rc);}/*************************************************************************** * NAME: extract_service_log * * FUNCTION: * * PARAMETERS:  none * * RETURNS: *      success: 0 *      failure: something else */void extract_service_log(){	char *msg_txt;	int dsl_rc = 0;	char *log_entry;	int log_entry_pos;	int bytes_left;	struct fscklog_entry_hdr *hdptr;	local_recptr->fscklog_last_read = 0;	while ((!local_recptr->fscklog_last_read) && (dsl_rc == 0)) {		dsl_rc = xchklog_fscklog_fill_buffer();		local_recptr->this_buffer_last_message = 0;		while ((!local_recptr->this_buffer_last_message)		       && (dsl_rc == 0)) {			hdptr = (struct fscklog_entry_hdr *)			    (local_recptr->infile_buf_ptr +			     local_recptr->infile_buf_data_len);			if (hdptr->entry_length == 0) {				/* no more entries in this buffer */				local_recptr->this_buffer_last_message = -1;			} else {				/* this entry_length != 0 */				/* swap if on big endian machine */				ujfs_swap_fscklog_entry_hdr(hdptr);				log_entry = (char *) hdptr;				log_entry_pos =				    sizeof (struct fscklog_entry_hdr);				/*				 * Each FSCKLOG_BUFSIZE boundary starts a new				 * log record.  Otherwise, we depend on a valid				 * entry_length to locate the next message.				 */				bytes_left = local_recptr->infile_buf_length -				    local_recptr->infile_buf_data_len;				if ((bytes_left < 0)				    || (hdptr->entry_length < 0)				    || (hdptr->entry_length > bytes_left)) {					/* this isn't a valid log record length */					send_msg(fsck_CHKLOGINVALRCD);					local_recptr->this_buffer_last_message =					    -1;				} else {					/* the log record length looks ok */					msg_txt = &log_entry[log_entry_pos];					/*					 * record the message in the output file					 */					record_msg(msg_txt);					/*					 * set up for the next record					 */					local_recptr->infile_buf_data_len +=					    hdptr->entry_length;					/*if (hdptr->msg_num == fsck_SESSEND) {						local_recptr->						    this_buffer_last_message =						    -1;						    }*/					if (local_recptr->infile_buf_data_len >=					    local_recptr->infile_buf_length) {						local_recptr->						    this_buffer_last_message =						    -1;					}				}			}		}	}	return;}/*************************************************************************** * NAME: xchklog_final_processing * * FUNCTION:  If processing read/write, replicate the superblock and the *            aggregate inode structures (i.e., the Aggregate Inode Map *            and the Aggregate Inode Table). * *            Notify the user about various things. * * PARAMETERS:  none * * RETURNS: *      success: 0 *      failure: something else */int xchklog_final_processing(){	int pf_rc = 0;	/*	 * Close the device	 */	if (local_recptr->device_is_open) {		pf_rc = fclose(Dev_IOPort);	}	/*	 * Close the output file	 */	if (local_recptr->outfile_is_open) {		/*		 * flush the buffer if necessary		 */		if (local_recptr->outfile_buf_data_len != 0) {			fwrite((const void *) (local_recptr->outfile_buf_ptr),			       sizeof (char), local_recptr->outfile_buf_length,			       outfp);		}		fclose(outfp);	}	return (pf_rc);}/***************************************************************************** * NAME: fscklog_fill_buffer * * FUNCTION:  If the current fsck session has write access to the aggregate, *            and if the in-aggregate fsck log is not full, write the *            contents of the current fscklog buffer into the in-aggregate *            fsck log. * * PARAMETERS:  none * * NOTES:  o Unlike most _put_ routines in this module, fscklog_put_buffer *           actually writes to the device.  This is done because the fsck *           log contains information which provides crucial serviceability *           should the fsck session be interrupted. * *         o Errors here are recorded in the control page of the fsck *           in-aggregate workspace but never affect other fsck processing. * * RETURNS: *      success: 0 *      failure: something else */int xchklog_fscklog_fill_buffer(){	int flfb_rc = 0;	int io_rc = 0;	unsigned bytes_read = 0;	unsigned log_bytes_left;	io_rc = readwrite_device(local_recptr->infile_agg_offset,				 local_recptr->infile_buf_length,				 &bytes_read,				 (void *) local_recptr->infile_buf_ptr,				 fsck_READ);	if ((io_rc != 0)	    || (bytes_read != (unsigned) local_recptr->infile_buf_length)) {		/*		 * write failed or didn't read		 * correct number of bytes		 */		send_msg(fsck_URCVWRT, fsck_ref_msg(fsck_metadata), Vol_Label);		send_msg(fsck_ERRONLOG, FSCK_BADREAD_FSCKLOG, io_rc, fsck_READ,			 (long long) local_recptr->infile_agg_offset,			 (long int) local_recptr->infile_buf_length,			 (long int) bytes_read);	}	/*	 * We want to reset the buffer no matter what.  If is useful	 * to keep going because the next section may be readable.	 */	local_recptr->infile_agg_offset += local_recptr->infile_buf_length;	local_recptr->infile_log_offset += local_recptr->infile_buf_length;	local_recptr->infile_buf_data_len = 0;	log_bytes_left = (local_recptr->ondev_fscklog_byte_length / 2) -	    local_recptr->infile_log_offset;	if (log_bytes_left < local_recptr->infile_buf_length) {		/* this is the last one */		local_recptr->fscklog_last_read = -1;	}	return (flfb_rc);}/***************************************************************************** * NAME: xchklog_initial_processing * * FUNCTION: Parse and verify invocation parameters. *           Open the device and verify that it contains a JFS file system. *           Read the chkdsk workspace control page. *           Calculate interesting aggregate offsets. * * * PARAMETERS:  as specified to main() * * NOTES: * * RETURNS: *      success: 0 *      failure: something else */int xchklog_initial_processing(struct fscklog_record *local_recptr){	int pi_rc = 0;	/*	 * Initialize the fscklog control block	 */	local_recptr->infile_buf_length = FSCKLOG_BUFSIZE;	local_recptr->infile_buf_ptr = fscklog_buffer;	local_recptr->outfile_buf_length = XCHKLOG_BUFSIZE;	local_recptr->outfile_buf_ptr = xchklog_buffer;	/*	 * Open the device and verify that it contains a valid JFS aggregate	 * If it does, check/repair the superblock.	 */	pi_rc = open_device_read(Vol_Label);	if (pi_rc != 0) {		/*device open failed */		send_msg(fsck_CNTRESUPB);	} else {		/* device is open */		local_recptr->device_is_open = 1;		pi_rc = validate_superblock();		if (pi_rc == 0) {			/* a valid superblock */			/*			 * add some stuff to the local record which is based on			 * superblock fields			 */			/* length of the on-device fsck service log */			local_recptr->ondev_fscklog_byte_length =			    sb_ptr->s_fsckloglen * sb_ptr->s_bsize;			/* length of the on-device fsck service log */			local_recptr->ondev_fscklog_fsblk_length =			    sb_ptr->s_fsckloglen;			/* length of the on-device fsck workspace */			local_recptr->ondev_wsp_fsblk_length =			    lengthPXD(&(sb_ptr->s_fsckpxd)) -			    local_recptr->ondev_fscklog_fsblk_length;			/* length of the on-device fsck workspace */			local_recptr->ondev_wsp_byte_length =			    local_recptr->ondev_wsp_fsblk_length *			    sb_ptr->s_bsize;			/* aggregate block offset of the on-device fsck workspace */			local_recptr->ondev_wsp_fsblk_offset =			    addressPXD(&(sb_ptr->s_fsckpxd));			/* byte offset of the on-device fsck workspace */			local_recptr->ondev_wsp_byte_offset =			    local_recptr->ondev_wsp_fsblk_offset *			    sb_ptr->s_bsize;			/* aggregate block offset of the on-device fsck workspace */			local_recptr->ondev_fscklog_fsblk_offset =			    local_recptr->ondev_wsp_fsblk_offset +			    local_recptr->ondev_wsp_fsblk_length;			/* byte offset of the on-device fsck workspace */			local_recptr->ondev_fscklog_byte_offset =			    local_recptr->ondev_wsp_byte_offset +			    local_recptr->ondev_wsp_byte_length;			/*			 * The offsets now assume the most recent log is 1st in the			 * aggregate fsck service log space.  Adjust if needed.			 */			if (local_recptr->which_log == NEWLOG) {				/* most recent wanted */				if (sb_ptr->s_fscklog == 2) {					/* the 2nd is most recent */					local_recptr->					    ondev_fscklog_fsblk_offset +=					    local_recptr->					    ondev_fscklog_fsblk_length / 2;					local_recptr->					    ondev_fscklog_byte_offset +=					    local_recptr->					    ondev_fscklog_byte_length / 2;				}			} else {				/* previous log wanted */				if (sb_ptr->s_fscklog != 2) {					/* the 2nd is not most recent */					local_recptr->					    ondev_fscklog_fsblk_offset +=					    local_recptr->					    ondev_fscklog_fsblk_length / 2;					local_recptr->					    ondev_fscklog_byte_offset +=					    local_recptr->					    ondev_fscklog_byte_length / 2;				}			}			local_recptr->infile_agg_offset =			    local_recptr->ondev_fscklog_byte_offset;			pi_rc = open_outfile();		}	}	if (local_recptr->which_log == NEWLOG) {		send_msg(fsck_CHKLOGNEW);	} else {		send_msg(fsck_CHKLOGOLD);	}	return (pi_rc);}/***************************************************************************** * NAME: open_device_read * * FUNCTION:  Open the specified device for read access. * * PARAMETERS: *      Device  - input - the device specification * * NOTES: * * RETURNS: *      success: 0 *      failure: something else */int open_device_read(const char *Device){	Dev_IOPort = fopen(Device, "r");

⌨️ 快捷键说明

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