e2fsck: add a 'yes to all' response in interactive mode

Provide a mechanism for a user to switch fsck into '-y' mode if they
start an interactive session and then get tired of pressing 'y' in
response to numerous prompts.

Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
Signed-off-by: Theodore Ts'o <tytso@mit.edu>
This commit is contained in:
Darrick J. Wong 2015-02-16 10:41:20 -05:00 committed by Theodore Ts'o
parent ad5d05d645
commit aeb933b3f2
14 changed files with 436 additions and 7 deletions

View File

@ -68,6 +68,19 @@ are not valid if the filesystem is mounted. If
asks whether or not you should check a filesystem which is mounted,
the only correct answer is ``no''. Only experts who really know what
they are doing should consider answering this question in any other way.
.PP
If
.B e2fsck
is run in interactive mode (meaning that none of
.BR \-y ,
.BR \-n ,
or
.BR \-p
are specified), the program will ask the user to fix each problem found in the
filesystem. A response of 'y' will fix the error; 'n' will leave the error
unfixed; and 'a' will fix the problem and all subsequent problems; pressing
Enter will proceed with the default response, which is printed before the
question mark. Pressing Control-C terminates e2fsck immediately.
.SH OPTIONS
.TP
.B \-a

View File

@ -760,7 +760,7 @@ static errcode_t PRS(int argc, char *argv[], e2fsck_t *ret_ctx)
setvbuf(stdout, NULL, _IONBF, BUFSIZ);
setvbuf(stderr, NULL, _IONBF, BUFSIZ);
if (isatty(0) && isatty(1)) {
if (getenv("E2FSCK_FORCE_INTERACTIVE") || (isatty(0) && isatty(1))) {
ctx->interactive = 1;
} else {
ctx->start_meta[0] = '\001';

View File

@ -189,6 +189,10 @@ int ask_yn(e2fsck_t ctx, const char * string, int def)
const char *defstr;
const char *short_yes = _("yY");
const char *short_no = _("nN");
const char *short_yesall = _("aA");
const char *yesall_prompt = _(" ('a' enables 'yes' to all) ");
const char *extra_prompt = "";
static int yes_answers;
#ifdef HAVE_TERMIOS_H
struct termios termios, tmp;
@ -207,7 +211,16 @@ int ask_yn(e2fsck_t ctx, const char * string, int def)
defstr = _(_("<n>"));
else
defstr = _(" (y/n)");
log_out(ctx, "%s%s? ", string, defstr);
/*
* If the user presses 'y' more than 8 (but less than 12) times in
* succession without pressing anything else, display a hint about
* yes-to-all mode.
*/
if (yes_answers > 12)
yes_answers = -1;
else if (yes_answers > 8)
extra_prompt = yesall_prompt;
log_out(ctx, "%s%s%s? ", string, extra_prompt, defstr);
while (1) {
fflush (stdout);
if ((c = read_a_char()) == EOF)
@ -221,20 +234,31 @@ int ask_yn(e2fsck_t ctx, const char * string, int def)
longjmp(e2fsck_global_ctx->abort_loc, 1);
}
log_out(ctx, "%s", _("cancelled!\n"));
yes_answers = 0;
return 0;
}
if (strchr(short_yes, (char) c)) {
def = 1;
if (yes_answers >= 0)
yes_answers++;
break;
}
else if (strchr(short_no, (char) c)) {
} else if (strchr(short_no, (char) c)) {
def = 0;
yes_answers = -1;
break;
} else if (strchr(short_yesall, (char)c)) {
def = 2;
yes_answers = -1;
ctx->options |= E2F_OPT_YES;
break;
} else if ((c == 27 || c == ' ' || c == '\n') && (def != -1)) {
yes_answers = -1;
break;
}
else if ((c == 27 || c == ' ' || c == '\n') && (def != -1))
break;
}
if (def)
if (def == 2)
log_out(ctx, "%s", _("yes to all\n"));
else if (def)
log_out(ctx, "%s", _("yes\n"));
else
log_out(ctx, "%s", _("no\n"));

48
tests/f_no/expect Normal file
View File

@ -0,0 +1,48 @@
Pass 1: Checking inodes, blocks, and sizes
Inode 12 has an invalid extent
(logical block 0, invalid physical block 999999999, len 1)
Clear<y>? no
Inode 12 has an invalid extent
(logical block 1, invalid physical block 9999999999, len 1)
Clear<y>? no
Inode 13 is in use, but has dtime set. Fix<y>? no
Inode 13 has an invalid extent
(logical block 1, invalid physical block 8888888888888, len 1)
Clear<y>? no
Inode 13 has an invalid extent
(logical block 0, invalid physical block 888888888888, len 1)
Clear<y>? no
Inode 14 is in use, but has dtime set. Fix<y>? no
Inode 14 has an invalid extent
(logical block 300, invalid physical block 777777777777, len 300)
Clear<y>? no
Inode 14 has an invalid extent
(logical block 0, invalid physical block 7777777777, len 1)
Clear<y>? no
Inode 14, i_blocks is 52574694748113, should be 0. Fix<y>? no
Pass 2: Checking directory structure
Extended attribute block for inode 12 (/a) is invalid (999999).
Clear<y>? no
Extended attribute block for inode 13 (/b) is invalid (298954296).
Clear<y>? no
Extended attribute block for inode 14 (/c) is invalid (388697201).
Clear<y>? no
Pass 3: Checking directory connectivity
Pass 4: Checking reference counts
Inode 12 ref count is 34463, should be 1. Fix<y>? no
Inode 13 ref count is 9999, should be 1. Fix<y>? no
Inode 14 ref count is 12241, should be 1. Fix<y>? no
Pass 5: Checking group summary information
Block bitmap differences: -202 -381 -457
Fix<y>? no
Free blocks count wrong for group #0 (0, counted=491).
Fix<y>? no
Free blocks count wrong (494, counted=491).
Fix<y>? no
Free inodes count wrong for group #0 (4294967293, counted=114).
Fix<y>? no
test_filesys: ********** WARNING: Filesystem still has errors **********
test_filesys: 14/128 files (0.0% non-contiguous), 18/512 blocks
Exit status is 4

27
tests/f_no/script Normal file
View File

@ -0,0 +1,27 @@
test_description="e2fsck with repeated no"
FSCK_OPT=-f
OUT=$test_name.log
EXP=$test_dir/expect
gunzip < $test_dir/../f_yesall/image.gz > $TMPFILE
rm -rf $OUT
echo "nnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnn" | E2FSCK_FORCE_INTERACTIVE=y $FSCK $FSCK_OPT -N test_filesys $TMPFILE > $OUT.new 2>&1
status=$?
echo Exit status is $status >> $OUT.new
sed -f $cmd_dir/filter.sed $OUT.new >> $OUT
rm -f $OUT.new
cmp -s $OUT $EXP
status=$?
if [ "$status" = 0 ] ; then
echo "$test_name: $test_description: ok"
touch $test_name.ok
else
echo "$test_name: $test_description: failed"
diff $DIFF_OPTS $EXP $OUT > $test_name.failed
rm -f tmp_expect
fi
unset IMAGE FSCK_OPT OUT EXP

45
tests/f_yes/expect Normal file
View File

@ -0,0 +1,45 @@
Pass 1: Checking inodes, blocks, and sizes
Inode 12 has an invalid extent
(logical block 0, invalid physical block 999999999, len 1)
Clear<y>? yes
Inode 12 has an invalid extent
(logical block 1, invalid physical block 9999999999, len 1)
Clear<y>? yes
Inode 13 is in use, but has dtime set. Fix<y>? yes
Inode 13 has an invalid extent
(logical block 1, invalid physical block 8888888888888, len 1)
Clear<y>? yes
Inode 13 has an invalid extent
(logical block 0, invalid physical block 888888888888, len 1)
Clear<y>? yes
Inode 14 is in use, but has dtime set. Fix<y>? yes
Inode 14 has an invalid extent
(logical block 300, invalid physical block 777777777777, len 300)
Clear<y>? yes
Inode 14 has an invalid extent
(logical block 0, invalid physical block 7777777777, len 1)
Clear<y>? yes
Inode 14, i_blocks is 52574694748113, should be 0. Fix<y>? yes
Pass 2: Checking directory structure
Extended attribute block for inode 12 (/a) is invalid (999999).
Clear ('a' enables 'yes' to all) <y>? yes
Extended attribute block for inode 13 (/b) is invalid (298954296).
Clear ('a' enables 'yes' to all) <y>? yes
Extended attribute block for inode 14 (/c) is invalid (388697201).
Clear ('a' enables 'yes' to all) <y>? yes
Pass 3: Checking directory connectivity
Pass 4: Checking reference counts
Inode 12 ref count is 34463, should be 1. Fix ('a' enables 'yes' to all) <y>? yes
Inode 13 ref count is 9999, should be 1. Fix<y>? yes
Inode 14 ref count is 12241, should be 1. Fix<y>? yes
Pass 5: Checking group summary information
Block bitmap differences: -202 -381 -457
Fix<y>? yes
Free blocks count wrong for group #0 (0, counted=494).
Fix<y>? yes
Free inodes count wrong for group #0 (4294967293, counted=114).
Fix<y>? yes
test_filesys: ***** FILE SYSTEM WAS MODIFIED *****
test_filesys: 14/128 files (0.0% non-contiguous), 18/512 blocks
Exit status is 1

27
tests/f_yes/script Normal file
View File

@ -0,0 +1,27 @@
test_description="e2fsck with repeated yes"
FSCK_OPT=-f
OUT=$test_name.log
EXP=$test_dir/expect
gunzip < $test_dir/../f_yesall/image.gz > $TMPFILE
rm -rf $OUT
echo "yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy" | E2FSCK_FORCE_INTERACTIVE=y $FSCK $FSCK_OPT -N test_filesys $TMPFILE > $OUT.new 2>&1
status=$?
echo Exit status is $status >> $OUT.new
sed -f $cmd_dir/filter.sed $OUT.new >> $OUT
rm -f $OUT.new
cmp -s $OUT $EXP
status=$?
if [ "$status" = 0 ] ; then
echo "$test_name: $test_description: ok"
touch $test_name.ok
else
echo "$test_name: $test_description: failed"
diff $DIFF_OPTS $EXP $OUT > $test_name.failed
rm -f tmp_expect
fi
unset IMAGE FSCK_OPT OUT EXP

62
tests/f_yesall/expect Normal file
View File

@ -0,0 +1,62 @@
Pass 1: Checking inodes, blocks, and sizes
Inode 12 has an invalid extent
(logical block 0, invalid physical block 999999999, len 1)
Clear<y>? yes to all
Inode 12 has an invalid extent
(logical block 1, invalid physical block 9999999999, len 1)
Clear? yes
Inode 13 is in use, but has dtime set. Fix? yes
Inode 13 has an invalid extent
(logical block 1, invalid physical block 8888888888888, len 1)
Clear? yes
Inode 13 has an invalid extent
(logical block 0, invalid physical block 888888888888, len 1)
Clear? yes
Inode 14 is in use, but has dtime set. Fix? yes
Inode 14 has an invalid extent
(logical block 300, invalid physical block 777777777777, len 300)
Clear? yes
Inode 14 has an invalid extent
(logical block 0, invalid physical block 7777777777, len 1)
Clear? yes
Inode 14, i_blocks is 52574694748113, should be 0. Fix? yes
Pass 2: Checking directory structure
Extended attribute block for inode 12 (/a) is invalid (999999).
Clear? yes
Extended attribute block for inode 13 (/b) is invalid (298954296).
Clear? yes
Extended attribute block for inode 14 (/c) is invalid (388697201).
Clear? yes
Pass 3: Checking directory connectivity
Pass 4: Checking reference counts
Inode 12 ref count is 34463, should be 1. Fix? yes
Inode 13 ref count is 9999, should be 1. Fix? yes
Inode 14 ref count is 12241, should be 1. Fix? yes
Pass 5: Checking group summary information
Block bitmap differences: -202 -381 -457
Fix? yes
Free blocks count wrong for group #0 (0, counted=494).
Fix? yes
Free inodes count wrong for group #0 (4294967293, counted=114).
Fix? yes
test_filesys: ***** FILE SYSTEM WAS MODIFIED *****
test_filesys: 14/128 files (0.0% non-contiguous), 18/512 blocks
Exit status is 1

BIN
tests/f_yesall/image.gz Normal file

Binary file not shown.

27
tests/f_yesall/script Normal file
View File

@ -0,0 +1,27 @@
test_description="e2fsck with yes-to-all"
FSCK_OPT=-f
OUT=$test_name.log
EXP=$test_dir/expect
gunzip < $test_dir/image.gz > $TMPFILE
rm -rf $OUT
echo "annnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnn" | E2FSCK_FORCE_INTERACTIVE=y $FSCK $FSCK_OPT -N test_filesys $TMPFILE > $OUT.new 2>&1
status=$?
echo Exit status is $status >> $OUT.new
sed -f $cmd_dir/filter.sed $OUT.new >> $OUT
rm -f $OUT.new
cmp -s $OUT $EXP
status=$?
if [ "$status" = 0 ] ; then
echo "$test_name: $test_description: ok"
touch $test_name.ok
else
echo "$test_name: $test_description: failed"
diff $DIFF_OPTS $EXP $OUT > $test_name.failed
rm -f tmp_expect
fi
unset IMAGE FSCK_OPT OUT EXP

52
tests/f_yesthenall/expect Normal file
View File

@ -0,0 +1,52 @@
Pass 1: Checking inodes, blocks, and sizes
Inode 12 has an invalid extent
(logical block 0, invalid physical block 999999999, len 1)
Clear<y>? yes
Inode 12 has an invalid extent
(logical block 1, invalid physical block 9999999999, len 1)
Clear<y>? yes
Inode 13 is in use, but has dtime set. Fix<y>? yes
Inode 13 has an invalid extent
(logical block 1, invalid physical block 8888888888888, len 1)
Clear<y>? yes
Inode 13 has an invalid extent
(logical block 0, invalid physical block 888888888888, len 1)
Clear<y>? yes
Inode 14 is in use, but has dtime set. Fix<y>? yes
Inode 14 has an invalid extent
(logical block 300, invalid physical block 777777777777, len 300)
Clear<y>? yes
Inode 14 has an invalid extent
(logical block 0, invalid physical block 7777777777, len 1)
Clear<y>? yes
Inode 14, i_blocks is 52574694748113, should be 0. Fix<y>? yes
Pass 2: Checking directory structure
Extended attribute block for inode 12 (/a) is invalid (999999).
Clear ('a' enables 'yes' to all) <y>? yes
Extended attribute block for inode 13 (/b) is invalid (298954296).
Clear ('a' enables 'yes' to all) <y>? yes to all
Extended attribute block for inode 14 (/c) is invalid (388697201).
Clear? yes
Pass 3: Checking directory connectivity
Pass 4: Checking reference counts
Inode 12 ref count is 34463, should be 1. Fix? yes
Inode 13 ref count is 9999, should be 1. Fix? yes
Inode 14 ref count is 12241, should be 1. Fix? yes
Pass 5: Checking group summary information
Block bitmap differences: -202 -381 -457
Fix? yes
Free blocks count wrong for group #0 (0, counted=494).
Fix? yes
Free inodes count wrong for group #0 (4294967293, counted=114).
Fix? yes
test_filesys: ***** FILE SYSTEM WAS MODIFIED *****
test_filesys: 14/128 files (0.0% non-contiguous), 18/512 blocks
Exit status is 1

27
tests/f_yesthenall/script Normal file
View File

@ -0,0 +1,27 @@
test_description="e2fsck with yes then yes-to-all"
FSCK_OPT=-f
OUT=$test_name.log
EXP=$test_dir/expect
gunzip < $test_dir/../f_yesall/image.gz > $TMPFILE
rm -rf $OUT
echo "yyyyyyyyyyannnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnn" | E2FSCK_FORCE_INTERACTIVE=y $FSCK $FSCK_OPT -N test_filesys $TMPFILE > $OUT.new 2>&1
status=$?
echo Exit status is $status >> $OUT.new
sed -f $cmd_dir/filter.sed $OUT.new >> $OUT
rm -f $OUT.new
cmp -s $OUT $EXP
status=$?
if [ "$status" = 0 ] ; then
echo "$test_name: $test_description: ok"
touch $test_name.ok
else
echo "$test_name: $test_description: failed"
diff $DIFF_OPTS $EXP $OUT > $test_name.failed
rm -f tmp_expect
fi
unset IMAGE FSCK_OPT OUT EXP

50
tests/f_yesthenno/expect Normal file
View File

@ -0,0 +1,50 @@
Pass 1: Checking inodes, blocks, and sizes
Inode 12 has an invalid extent
(logical block 0, invalid physical block 999999999, len 1)
Clear<y>? yes
Inode 12 has an invalid extent
(logical block 1, invalid physical block 9999999999, len 1)
Clear<y>? yes
Inode 13 is in use, but has dtime set. Fix<y>? yes
Inode 13 has an invalid extent
(logical block 1, invalid physical block 8888888888888, len 1)
Clear<y>? yes
Inode 13 has an invalid extent
(logical block 0, invalid physical block 888888888888, len 1)
Clear<y>? yes
Inode 14 is in use, but has dtime set. Fix<y>? yes
Inode 14 has an invalid extent
(logical block 300, invalid physical block 777777777777, len 300)
Clear<y>? yes
Inode 14 has an invalid extent
(logical block 0, invalid physical block 7777777777, len 1)
Clear<y>? yes
Inode 14, i_blocks is 52574694748113, should be 0. Fix<y>? yes
Pass 2: Checking directory structure
Extended attribute block for inode 12 (/a) is invalid (999999).
Clear ('a' enables 'yes' to all) <y>? yes
Extended attribute block for inode 13 (/b) is invalid (298954296).
Clear ('a' enables 'yes' to all) <y>? no
Extended attribute block for inode 14 (/c) is invalid (388697201).
Clear<y>? no
Pass 3: Checking directory connectivity
Pass 4: Checking reference counts
Inode 12 ref count is 34463, should be 1. Fix<y>? no
Inode 13 ref count is 9999, should be 1. Fix<y>? no
Inode 14 ref count is 12241, should be 1. Fix<y>? no
Pass 5: Checking group summary information
Block bitmap differences: -202 -381 -457
Fix<y>? no
Free blocks count wrong for group #0 (0, counted=491).
Fix<y>? no
Free blocks count wrong (494, counted=491).
Fix<y>? no
Free inodes count wrong for group #0 (4294967293, counted=114).
Fix<y>? no
test_filesys: ***** FILE SYSTEM WAS MODIFIED *****
test_filesys: ********** WARNING: Filesystem still has errors **********
test_filesys: 14/128 files (0.0% non-contiguous), 18/512 blocks
Exit status is 4

27
tests/f_yesthenno/script Normal file
View File

@ -0,0 +1,27 @@
test_description="e2fsck with yes then no"
FSCK_OPT=-f
OUT=$test_name.log
EXP=$test_dir/expect
gunzip < $test_dir/../f_yesall/image.gz > $TMPFILE
rm -rf $OUT
echo "yyyyyyyyyynnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnn" | E2FSCK_FORCE_INTERACTIVE=y $FSCK $FSCK_OPT -N test_filesys $TMPFILE > $OUT.new 2>&1
status=$?
echo Exit status is $status >> $OUT.new
sed -f $cmd_dir/filter.sed $OUT.new >> $OUT
rm -f $OUT.new
cmp -s $OUT $EXP
status=$?
if [ "$status" = 0 ] ; then
echo "$test_name: $test_description: ok"
touch $test_name.ok
else
echo "$test_name: $test_description: failed"
diff $DIFF_OPTS $EXP $OUT > $test_name.failed
rm -f tmp_expect
fi
unset IMAGE FSCK_OPT OUT EXP