📄 xchkdsk.c
字号:
fsck_ref_msg(msg_info_ptr->msg_inopfx), this_ext->inonum); } } } if (!other_adjustments) { this_inorec->adj_entries = 0; } else { this_inorec->adj_entries = 1; agg_recptr->corrections_needed = 1; } } if ((rc == FSCK_OK) && (this_inorec->cant_chkea)) { /* * wasn't able to check the EA format */ fsck_send_msg(fsck_CANTCHKEA); } if ((rc == FSCK_OK) && (this_inorec->rebuild_dirtable)) { if (agg_recptr->processing_readwrite) { /* we can fix this */ agg_recptr->corrections_approved = 1; fsck_send_msg(fsck_WILLFIX_DI_TABLE); } else { /* we don't have write access */ this_inorec->rebuild_dirtable = 0; agg_recptr->ag_dirty = 1; fsck_send_msg(fsck_DI_TABLE); } } rpsr_next: if (rc == FSCK_OK) { rc = get_inorecptr_next(aggregate_inode, &ino_idx, &this_inorec); } } return (rc);}/***************************************************************************** * NAME: initial_processing * * FUNCTION: Parse and verify invocation parameters. Open the device and * verify that it contains a JFS file system. Check and repair * the superblock. Initialize the fsck aggregate record. Refresh * the boot sector on the volume. Issue some opening messages. * * * PARAMETERS: as specified to main() * * NOTES: sets exit_value if other than OK * * RETURNS: * success: FSCK_OK * failure: something else */int initial_processing(int argc, char **argv){ int pi_rc = FSCK_OK; int iml_rc = FSCK_OK; int64_t fsblk_offset_bak; int64_t byte_offset_bak; time_t Current_Time; char message_parm[MAXPARMLEN]; /* * Initiate fsck service logging */ iml_rc = fscklog_start(); /* * Log the beginning of the fsck session */ Current_Time = time(NULL); fsck_DateTime = localtime(&Current_Time); sprintf(message_parm, "%d/%d/%d %d.%d.%d", fsck_DateTime->tm_mon + 1, fsck_DateTime->tm_mday, (fsck_DateTime->tm_year + 1900), fsck_DateTime->tm_hour, fsck_DateTime->tm_min, fsck_DateTime->tm_sec); fsck_send_msg(fsck_SESSSTART, message_parm); /* * Process the parameters given by the user */ /* parse the parms and record them in the aggregate wsp record */ parse_parms(argc, argv); if ((pi_rc = Is_Device_Mounted(Vol_Label)) != FSCK_OK) { switch (pi_rc) { case MSG_JFS_VOLUME_IS_MOUNTED_RO: /* is mounted read only */ if ((agg_recptr->parm_options[UFS_CHKDSK_DEBUG]) || (agg_recptr->parm_options[UFS_CHKDSK_VERBOSE])) printf("\nFSCK Device %s is currently mounted " "READ ONLY.\n", Vol_Label); break; case MSG_JFS_MNT_LIST_ERROR: /* setmntent failed */ if ((agg_recptr->parm_options[UFS_CHKDSK_DEBUG]) || (agg_recptr->parm_options[UFS_CHKDSK_VERBOSE])) printf("\njfs_fsck cannot access file system " "description file to determine mount\n" "status and file system type of device " "%s. jfs_fsck will continue.\n\n", Vol_Label); break; case MSG_JFS_VOLUME_IS_MOUNTED: if (agg_recptr->parm_options[UFS_CHKDSK_LEVEL0]) { /* read only */ fsck_send_msg(fsck_FSMNTD); fsck_send_msg(fsck_MNTFSYS2); } else { /* is mounted */ printf("\n%s is mounted.\n\nWARNING!!!\n" "Running fsck on a mounted file system\n" "may cause SEVERE file system damage." "\n\n", Vol_Label); ask_continue(); } break; case MSG_JFS_NOT_JFS: /* is not JFS */ printf("\n%s is mounted and the file system is not type" " JFS.\n\nWARNING!!!\nRunning jfs_fsck on a " "mounted file system\nor on a file system other " "than JFS\nmay cause SEVERE file system damage." "\n\n", Vol_Label); ask_continue(); break; default: ask_continue(); break; } } /* the parms are good */ pi_rc = verify_parms(); /* * Open the device and verify that it contains a valid JFS aggregate * If it does, check/repair the superblock. */ if (pi_rc != FSCK_OK) { /* verify_parms returned bad rc */ exit_value = FSCK_USAGE_ERROR; goto ip_exit; } /* parms are good */ fsck_send_msg(fsck_DRIVEID, Vol_Label); pi_rc = open_volume(Vol_Label); if (pi_rc != FSCK_OK) { /* device open failed */ fsck_send_msg(fsck_CNTRESUPB); exit_value = FSCK_OP_ERROR; goto ip_exit; } /* device is open */ agg_recptr->device_is_open = 1; pi_rc = validate_repair_superblock(); if (pi_rc != FSCK_OK) { /* superblock invalid */ exit_value = FSCK_OP_ERROR; goto ip_exit; } fsck_send_msg(fsck_DRIVETYPE); /* * add some stuff to the agg_record which is based on * superblock fields */ agg_recptr->log2_blksize = log2shift(sb_ptr->s_bsize); agg_recptr->blksperpg = BYTESPERPAGE / sb_ptr->s_bsize; agg_recptr->log2_blksperpg = log2shift(agg_recptr->blksperpg); agg_recptr->log2_blksperag = log2shift(sb_ptr->s_agsize); /*highest is the last one before the in-aggregate journal log */ agg_recptr->highest_valid_fset_datablk = addressPXD(&(sb_ptr->s_fsckpxd)) - 1; /* lowest is the first after the secondary aggreg inode table */ agg_recptr->lowest_valid_fset_datablk = addressPXD(&(sb_ptr->s_ait2)) + (INODE_EXTENT_SIZE / sb_ptr->s_bsize) + 1; /* * agg size in logical blks is * (size in phys blks times phys blk size divided by log blk size) * number of AGs in the aggregate: * (agg size in log blks plus AG size in log blks minus 1) * divided by (AG size in log blks) */ agg_recptr->num_ag = ((sb_ptr->s_size * sb_ptr->s_pbsize / sb_ptr->s_bsize) + sb_ptr->s_agsize - 1) / sb_ptr->s_agsize; agg_recptr->sb_agg_fsblk_length = sb_ptr->s_size * sb_ptr->s_pbsize / sb_ptr->s_bsize; /* length of the on-device journal log */ agg_recptr->ondev_jlog_fsblk_length = lengthPXD(&(sb_ptr->s_logpxd)); /* aggregate block offset of the on-device journal log */ agg_recptr->ondev_jlog_fsblk_offset = addressPXD(&(sb_ptr->s_logpxd)); ondev_jlog_byte_offset = agg_recptr->ondev_jlog_fsblk_offset * sb_ptr->s_bsize; /* length of the on-device fsck service log */ agg_recptr->ondev_fscklog_byte_length = sb_ptr->s_fsckloglen * sb_ptr->s_bsize; /* length of the on-device fsck service log */ agg_recptr->ondev_fscklog_fsblk_length = sb_ptr->s_fsckloglen; /* length of the on-device fsck workspace */ agg_recptr->ondev_wsp_fsblk_length = lengthPXD(&(sb_ptr->s_fsckpxd)) - agg_recptr->ondev_fscklog_fsblk_length; /* length of the on-device fsck workspace */ agg_recptr->ondev_wsp_byte_length = agg_recptr->ondev_wsp_fsblk_length * sb_ptr->s_bsize; /* aggregate block offset of the on-device fsck workspace */ agg_recptr->ondev_wsp_fsblk_offset = addressPXD(&(sb_ptr->s_fsckpxd)); /* byte offset of the on-device fsck workspace */ agg_recptr->ondev_wsp_byte_offset = agg_recptr->ondev_wsp_fsblk_offset * sb_ptr->s_bsize; /* aggregate block offset of the on-device fsck workspace */ agg_recptr->ondev_fscklog_fsblk_offset = agg_recptr->ondev_wsp_fsblk_offset + agg_recptr->ondev_wsp_fsblk_length; /* byte offset of the on-device fsck workspace */ agg_recptr->ondev_fscklog_byte_offset = agg_recptr->ondev_wsp_byte_offset + agg_recptr->ondev_wsp_byte_length; /* * The offsets now assume the prior log (the one to overwrite) is * 1st in the aggregate fsck service log space. Adjust if needed. */ if (sb_ptr->s_fscklog == 0) { /* first time ever for this aggregate */ fsblk_offset_bak = agg_recptr->ondev_fscklog_fsblk_offset; byte_offset_bak = agg_recptr->ondev_fscklog_byte_offset; /* * initialize the 2nd service log space * * (we'll actually write the log to the 1st space, so * we'll initialize it below) */ agg_recptr->ondev_fscklog_fsblk_offset += agg_recptr->ondev_fscklog_fsblk_length / 2; agg_recptr->ondev_fscklog_byte_offset += agg_recptr->ondev_fscklog_byte_length / 2; agg_recptr->fscklog_agg_offset = agg_recptr->ondev_fscklog_byte_offset; fscklog_init(); sb_ptr->s_fscklog = 1; agg_recptr->ondev_fscklog_fsblk_offset = fsblk_offset_bak; agg_recptr->ondev_fscklog_byte_offset = byte_offset_bak; } else if (sb_ptr->s_fscklog == 1) { /* the 1st is most recent */ sb_ptr->s_fscklog = 2; agg_recptr->ondev_fscklog_fsblk_offset += agg_recptr->ondev_fscklog_fsblk_length / 2; agg_recptr->ondev_fscklog_byte_offset += agg_recptr->ondev_fscklog_byte_length / 2; } else { /* the 1st is the one to overwrite */ sb_ptr->s_fscklog = 1; } agg_recptr->fscklog_agg_offset = agg_recptr->ondev_fscklog_byte_offset; /* * Initialize the service log */ fscklog_init(); /* from the user's perspective, these are in use (by jfs) */ agg_recptr->blocks_used_in_aggregate = agg_recptr->ondev_wsp_fsblk_length + agg_recptr->ondev_fscklog_fsblk_length + agg_recptr->ondev_jlog_fsblk_length; agg_recptr->superblk_ok = 1; if ((!agg_recptr->parm_options[UFS_CHKDSK_LEVEL0]) && (agg_recptr->processing_readonly)) { /* user did not specify check only but we can only * do check because we don't have write access */ fsck_send_msg(fsck_WRSUP); } ip_exit: return (pi_rc);}/***************************************************************************** * NAME: parse_parms * * FUNCTION: Parse the invocation parameters. If any unrecognized * parameters are detected, or if any required parameter is * omitted, issue a message and exit. * * PARAMETERS: as specified to main() * * RETURNS: If there is an error in parse_parms, it calls fsck_usage() * to remind the user of command format and proper options. * fsck_usage then exits with exit code FSCK_USAGE_ERROR. */void parse_parms(int argc, char **argv){ int c; char *device_name = NULL; FILE *file_p = NULL; char *short_opts = "adfj:noprvVy"; struct option long_opts[] = { { "omit_journal_replay", no_argument, NULL, 'o'}, { "replay_journal_only", no_argument, NULL, 'J'}, { NULL, 0, NULL, 0} }; while ((c = getopt_long(argc, argv, short_opts, long_opts, NULL)) != EOF) { switch (c) { case 'r': /************************* * interactive autocheck * *************************/ /* * jfs_fsck does not support interactive checking, * so -r is undocumented. However, for backwards * compatibility, -r is supported here and functions * similarly as -p. */ case 'a': case 'p': /******************* * preen autocheck * *******************/ agg_recptr->parm_options[UFS_CHKDSK_LEVEL2] = -1; agg_recptr->parm_options[UFS_CHKDSK_IFDIRTY] = -1; break;#if 0 case 'b': /******************************************* * Clear LVM Bad Block List utility option * *******************************************/ agg_recptr->parm_options[UFS_CHKDSK_CLRBDBLKLST] = -1; break; case 'c': /****************** * IfDirty option * ******************/ agg_recptr->parm_options[UFS_CHKDSK_IFDIRTY] = -1; break;#endif case 'f': /******************************** * Force check after log replay * ********************************/ agg_recptr->parm_options[UFS_CHKDSK_LEVEL3] = -1; break; case 'j': /************************** * Specify journal device * **************************/ strncpy(log_device, optarg, sizeof (log_device) - 1); break; case 'J': /*********************** * Replay journal only * ***********************/ agg_recptr->parm_options_logredo_only = 1; break; case 'n': /*********************************** * Level0 (no write access) option * ***********************************/ agg_recptr->parm_options[UFS_CHKDSK_LEVEL0] = -1; break; case 'o': /************************************ * Omit logredo() processing option * ************************************/ agg_recptr->parm_options[UFS_CHKDSK_SKIPLOGREDO] = -1; agg_recptr->parm_options_nologredo = 1; break; case 'd': /**************** * Debug option * ****************/ /* undocumented at this point, it is similar to -v */ dbg_output = 1; case 'v': /****************** * Verbose option * ******************/ agg_recptr->parm_options[UFS_CHKDSK_VERBOSE] = -1; break; case 'V': /********************** * print version only * **********************/ exit(FSCK_OK); break; case 'y': /****************************** * 'yes to everything' option * ******************************/ /* * jfs_fsck does not support interactive checking, * so the -y option isn't necessary here. However, * in striving to have options similar to those * of e2fsck, we will let -y be the same as the * default -p (unless it is overridden), since * the functionality is similar for both -y and -p. */ break; default: fsck_usage(); } } if (agg_recptr->parm_options_logredo_only && (agg_recptr->parm_options_nologredo || agg_recptr->parm_options[UFS_CHKDSK_LEVEL3] || agg_recptr->parm_options[UFS_CHKDSK_LEVEL0]) ) { printf("\nError: --replay_journal_only cannot be used " "with -f, -n, or --omit_journal_replay.\n"); fsck_usage(); } if (optind != argc - 1) { printf("\nError: Device not specified or command format error\n"); fsck_usage(); } device_name = argv[optind]; file_p = fopen(device_name, "r"); if (file_p) { fclose(file_p); } else { printf("\nError: Cannot open device %s\n", device_name); fsck_usage(); } Vol_Label = device_name; return;}/***************************************************************************** * NAME: phase0_processing * * FUNCTION: Log Redo processing.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -