diff options
author | Ken Sumrall <ksumrall@android.com> | 2011-06-22 18:34:28 -0700 |
---|---|---|
committer | Ken Sumrall <ksumrall@android.com> | 2011-06-22 18:34:28 -0700 |
commit | 7e5ff13c55eb29748c07768bd7134819cbcbd4b0 (patch) | |
tree | 2b308ab9bd2e66a0372e34f92a43cfaef63dcf6e | |
parent | 97fc910ce0e05862888fd1d9e1938feba40f7539 (diff) | |
download | extras-7e5ff13c55eb29748c07768bd7134819cbcbd4b0.tar.gz |
Add test/debugging code to ext4fixup
Add debugging test code to specify where to bail partway through
Add a script to drive the test code for automated testing. This
found 4 bugs!
Change-Id: I14dc8b1e2c9d2d2f332346958d488feaf768d396
-rw-r--r-- | ext4_utils/ext4fixup.c | 28 | ||||
-rw-r--r-- | ext4_utils/ext4fixup.h | 3 | ||||
-rw-r--r-- | ext4_utils/ext4fixup_main.c | 8 | ||||
-rwxr-xr-x | ext4_utils/test_ext4fixup | 71 |
4 files changed, 105 insertions, 5 deletions
diff --git a/ext4_utils/ext4fixup.c b/ext4_utils/ext4fixup.c index cb596371..5e04602a 100644 --- a/ext4_utils/ext4fixup.c +++ b/ext4_utils/ext4fixup.c @@ -56,6 +56,12 @@ #define STATE_UPDATING_INUMS 2 #define STATE_UPDATING_SB 3 +/* Used for automated testing of this programs ability to stop and be restarted wthout error */ +static int bail_phase = 0; +static int bail_loc = 0; +static int bail_count = 0; +static int count = 0; + /* global flags */ static int verbose = 0; static int no_write = 0; @@ -432,6 +438,9 @@ static int update_superblocks_and_bg_desc(int fd, int state) critical_error("failed to write all of block group descriptors"); } } + if ((bail_phase == 4) && ((unsigned int)bail_count == i)) { + critical_error("bailing at phase 4\n"); + } } return 0; @@ -663,6 +672,7 @@ static int recurse_dir(int fd, struct ext4_inode *inode, char *dirbuf, int dirsi dirp = (struct ext4_dir_entry_2 *)dirbuf; while (dirp < (struct ext4_dir_entry_2 *)(dirbuf + dirsize)) { + count++; leftover_space = (char *)(dirbuf + dirsize) - (char *)dirp; if (((mode == SANITY_CHECK_PASS) || (mode == UPDATE_INODE_NUMS)) && (leftover_space <= 8) && prev_dirp) { @@ -743,6 +753,10 @@ static int recurse_dir(int fd, struct ext4_inode *inode, char *dirbuf, int dirsi } } + if ((bail_phase == mode) && (bail_loc == 1) && (bail_count == count)) { + critical_error("Bailing at phase %d, loc 1 and count %d\n", mode, count); + } + /* Point dirp at the next entry */ prev_dirp = dirp; dirp = (struct ext4_dir_entry_2*)((char *)dirp + dirp->rec_len); @@ -751,6 +765,9 @@ static int recurse_dir(int fd, struct ext4_inode *inode, char *dirbuf, int dirsi /* Write out all the blocks for this directory */ for (i = 0; i < num_blocks; i++) { write_block(fd, block_list[i], dirbuf + (i * info.block_size)); + if ((bail_phase == mode) && (bail_loc == 2) && (bail_count <= count)) { + critical_error("Bailing at phase %d, loc 2 and count %d\n", mode, count); + } } free(block_list); @@ -760,10 +777,11 @@ static int recurse_dir(int fd, struct ext4_inode *inode, char *dirbuf, int dirsi int ext4fixup(char *fsdev) { - return ext4fixup_internal(fsdev, 0, 0); + return ext4fixup_internal(fsdev, 0, 0, 0, 0, 0); } -int ext4fixup_internal(char *fsdev, int v_flag, int n_flag) +int ext4fixup_internal(char *fsdev, int v_flag, int n_flag, + int stop_phase, int stop_loc, int stop_count) { int fd; struct ext4_inode root_inode; @@ -776,6 +794,10 @@ int ext4fixup_internal(char *fsdev, int v_flag, int n_flag) verbose = v_flag; no_write = n_flag; + bail_phase = stop_phase; + bail_loc = stop_loc; + bail_count = stop_count; + fd = open(fsdev, O_RDWR); if (fd < 0) @@ -845,12 +867,14 @@ int ext4fixup_internal(char *fsdev, int v_flag, int n_flag) } if (get_fs_fixup_state(fd) == STATE_MARKING_INUMS) { + count = 0; /* Reset debugging counter */ if (!recurse_dir(fd, &root_inode, dirbuf, dirsize, MARK_INODE_NUMS)) { set_fs_fixup_state(fd, STATE_UPDATING_INUMS); } } if (get_fs_fixup_state(fd) == STATE_UPDATING_INUMS) { + count = 0; /* Reset debugging counter */ if (!recurse_dir(fd, &root_inode, dirbuf, dirsize, UPDATE_INODE_NUMS)) { set_fs_fixup_state(fd, STATE_UPDATING_SB); } diff --git a/ext4_utils/ext4fixup.h b/ext4_utils/ext4fixup.h index 94395e7b..6ea21132 100644 --- a/ext4_utils/ext4fixup.h +++ b/ext4_utils/ext4fixup.h @@ -15,5 +15,6 @@ */ int ext4fixup(char *fsdev); -int ext4fixup_internal(char *fsdev, int v_flag, int n_flag); +int ext4fixup_internal(char *fsdev, int v_flag, int n_flag, + int stop_phase, int stop_loc, int stop_count); diff --git a/ext4_utils/ext4fixup_main.c b/ext4_utils/ext4fixup_main.c index 8b069712..47c7e659 100644 --- a/ext4_utils/ext4fixup_main.c +++ b/ext4_utils/ext4fixup_main.c @@ -32,10 +32,11 @@ int main(int argc, char **argv) int no_write = 0; char *fsdev; char *me; + int stop_phase = 0, stop_loc = 0, stop_count = 0; me = basename(argv[0]); - while ((opt = getopt(argc, argv, "vn")) != -1) { + while ((opt = getopt(argc, argv, "vnd:")) != -1) { switch (opt) { case 'v': verbose = 1; @@ -43,6 +44,9 @@ int main(int argc, char **argv) case 'n': no_write = 1; break; + case 'd': + sscanf(optarg, "%d,%d,%d", &stop_phase, &stop_loc, &stop_count); + break; } } @@ -60,5 +64,5 @@ int main(int argc, char **argv) exit(EXIT_FAILURE); } - return ext4fixup_internal(fsdev, verbose, no_write); + return ext4fixup_internal(fsdev, verbose, no_write, stop_phase, stop_loc, stop_count); } diff --git a/ext4_utils/test_ext4fixup b/ext4_utils/test_ext4fixup new file mode 100755 index 00000000..a920a59d --- /dev/null +++ b/ext4_utils/test_ext4fixup @@ -0,0 +1,71 @@ +#!/bin/bash + +typeset -i I ITERATIONS PHASE LOC COUNT MAXCOUNT + +ME=`basename $0` + +if [ "$#" -ne 3 ] +then + echo "$ME: Usage: $ME <iterations> <maxcount> <filesystem_image>" >&2 + exit 1; +fi + +ITERATIONS="$1" +MAXCOUNT="$2" +ORIG_FS_IMAGE="$3" +FIXED_FS_IMAGE="/tmp/fixedfsimage.$$" +NEW_FS_IMAGE="/tmp/newfsimage.$$" + +if [ ! -f "$ORIG_FS_IMAGE" ] +then + echo "$ME: Filesystem image $NEW_FS_IMAGE does not exist" >&2 + exit 1 +fi + +trap "rm -f $NEW_FS_IMAGE $FIXED_FS_IMAGE" 0 1 2 3 15 + +rm -f "$NEW_FS_IMAGE" "$FIXED_FS_IMAGE" + +# Create the fixed image to compare against +cp "$ORIG_FS_IMAGE" "$FIXED_FS_IMAGE" +ext4fixup "$FIXED_FS_IMAGE" + +if [ "$?" -ne 0 ] +then + echo "$ME: ext4fixup failed!\n" + exit 1 +fi + +I=0 +while [ "$I" -lt "$ITERATIONS" ] +do + # There is also a phase 4, which is writing out the updated superblocks and + # block group descriptors. Test the with a separate script. + let PHASE="$RANDOM"%3 # 0 to 2 + let PHASE++ # 1 to 3 + let LOC="$RANDOM"%2 # 0 to 1 + let LOC++ # 1 to 2 + let COUNT="$RANDOM"%"$MAXCOUNT" + + # Make a copy of the original image to fixup + cp "$ORIG_FS_IMAGE" "$NEW_FS_IMAGE" + + # Run the fixup tool, but die partway through to see if we can recover + ext4fixup -d "$PHASE,$LOC,$COUNT" "$NEW_FS_IMAGE" 2>/dev/null + + # run it again without -d to have it finish the job + ext4fixup "$NEW_FS_IMAGE" + + if cmp "$FIXED_FS_IMAGE" "$NEW_FS_IMAGE" + then + : + else + echo "$ME: test failed with parameters $PHASE, $LOC, $COUNT" + exit 1 + fi + + rm -f "$NEW_FS_IMAGE" + + let I++ +done + |