mke2fs: set error behavior at initialization time

Port tune2fs' -e flag to mke2fs so that we can set error behavior at
format time, and introduce the equivalent errors= setting into
mke2fs.conf.

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 2014-07-25 08:58:29 -04:00 committed by Theodore Ts'o
parent e05a05630a
commit cd32129d89
5 changed files with 231 additions and 2 deletions

View File

@ -113,6 +113,10 @@ mke2fs \- create an ext2/ext3/ext4 filesystem
[
.B \-V
]
[
.B \-e
.I errors-behavior
]
.I device
[
.I blocks-count
@ -206,6 +210,25 @@ lot of buffer cache memory, which may impact other applications running
on a busy server. This option will cause mke2fs to run much more
slowly, however, so there is a tradeoff to using direct I/O.
.TP
.BI \-e " error-behavior"
Change the behavior of the kernel code when errors are detected.
In all cases, a filesystem error will cause
.BR e2fsck (8)
to check the filesystem on the next boot.
.I error-behavior
can be one of the following:
.RS 1.2i
.TP 1.2i
.B continue
Continue normal execution.
.TP
.B remount-ro
Remount filesystem read-only.
.TP
.B panic
Cause a kernel panic.
.RE
.TP
.BI \-E " extended-options"
Set extended options for the filesystem. Extended options are comma
separated, and may take an argument using the equals ('=') sign. The

View File

@ -113,6 +113,8 @@ static profile_t profile;
static int sys_page_size = 4096;
static int errors_behavior = 0;
static void usage(void)
{
fprintf(stderr, _("Usage: %s [-c|-l filename] [-b block-size] "
@ -124,7 +126,7 @@ static void usage(void)
"\t[-g blocks-per-group] [-L volume-label] "
"[-M last-mounted-directory]\n\t[-O feature[,...]] "
"[-r fs-revision] [-E extended-option[,...]]\n"
"\t[-t fs-type] [-T usage-type ] [-U UUID] "
"\t[-t fs-type] [-T usage-type ] [-U UUID] [-e errors_behavior]"
"[-jnqvDFKSV] device [blocks-count]\n"),
program_name);
exit(1);
@ -1547,7 +1549,7 @@ profile_error:
}
while ((c = getopt (argc, argv,
"b:cg:i:jl:m:no:qr:s:t:d:vC:DE:FG:I:J:KL:M:N:O:R:ST:U:V")) != EOF) {
"b:ce:g:i:jl:m:no:qr:s:t:d:vC:DE:FG:I:J:KL:M:N:O:R:ST:U:V")) != EOF) {
switch (c) {
case 'b':
blocksize = parse_num_blocks2(optarg, -1);
@ -1590,6 +1592,20 @@ profile_error:
case 'E':
extended_opts = optarg;
break;
case 'e':
if (strcmp(optarg, "continue") == 0)
errors_behavior = EXT2_ERRORS_CONTINUE;
else if (strcmp(optarg, "remount-ro") == 0)
errors_behavior = EXT2_ERRORS_RO;
else if (strcmp(optarg, "panic") == 0)
errors_behavior = EXT2_ERRORS_PANIC;
else {
com_err(program_name, 0,
_("bad error behavior - %s"),
optarg);
usage();
}
break;
case 'F':
force++;
break;
@ -2622,6 +2638,38 @@ static int create_quota_inodes(ext2_filsys fs)
return 0;
}
static errcode_t set_error_behavior(ext2_filsys fs)
{
char *arg = NULL;
short errors = fs->super->s_errors;
arg = get_string_from_profile(fs_types, "errors", NULL);
if (arg == NULL)
goto try_user;
if (strcmp(arg, "continue") == 0)
errors = EXT2_ERRORS_CONTINUE;
else if (strcmp(arg, "remount-ro") == 0)
errors = EXT2_ERRORS_RO;
else if (strcmp(arg, "panic") == 0)
errors = EXT2_ERRORS_PANIC;
else {
com_err(program_name, 0,
_("bad error behavior in profile - %s"),
arg);
free(arg);
return EXT2_ET_INVALID_ARGUMENT;
}
free(arg);
try_user:
if (errors_behavior)
errors = errors_behavior;
fs->super->s_errors = errors;
return 0;
}
int main (int argc, char *argv[])
{
errcode_t retval = 0;
@ -2686,6 +2734,11 @@ int main (int argc, char *argv[])
}
fs->progress_ops = &ext2fs_numeric_progress_ops;
/* Set the error behavior */
retval = set_error_behavior(fs);
if (retval)
usage();
/* Check the user's mkfs options for metadata checksumming */
if (!quiet &&
EXT2_HAS_RO_COMPAT_FEATURE(fs->super,

View File

@ -317,6 +317,25 @@ whose subsections define the
relation, only the last will be used by
.BR mke2fs (8).
.TP
.I errors
Change the behavior of the kernel code when errors are detected.
In all cases, a filesystem error will cause
.BR e2fsck (8)
to check the filesystem on the next boot.
.I errors
can be one of the following:
.RS 1.2i
.TP 1.2i
.B continue
Continue normal execution.
.TP
.B remount-ro
Remount filesystem read-only.
.TP
.B panic
Cause a kernel panic.
.RE
.TP
.I features
This relation specifies a comma-separated list of features edit
requests which modify the feature set

View File

@ -0,0 +1,24 @@
error default
Errors behavior: Continue
error continue
Errors behavior: Continue
error panic
Errors behavior: Panic
error remount-ro
Errors behavior: Remount read-only
error garbage
error default profile continue
Errors behavior: Continue
error default profile panic
Errors behavior: Panic
error default profile remount-ro
Errors behavior: Remount read-only
error default profile broken
error fs_types profile continue
Errors behavior: Continue
error fs_types profile panic
Errors behavior: Panic
error fs_types profile remount-ro
Errors behavior: Remount read-only
error fs_types profile remount-ro
Errors behavior: Panic

110
tests/t_mke2fs_errors/script Executable file
View File

@ -0,0 +1,110 @@
test_description="mke2fs with error behavior"
conf=$TMPFILE.conf
write_defaults_conf()
{
errors="$1"
cat > $conf << ENDL
[defaults]
errors = $errors
ENDL
}
write_section_conf()
{
errors="$1"
cat > $conf << ENDL
[defaults]
errors = broken
[fs_types]
test_suite = {
errors = $errors
}
ENDL
}
trap "rm -rf $TMPFILE $TMPFILE.conf" EXIT INT QUIT
dd if=/dev/zero of=$TMPFILE bs=1k count=512 > /dev/null 2>&1
OUT=$test_name.log
EXP=$test_dir/expect
rm -rf $OUT
# Test command line option
echo "error default" >> $OUT
$MKE2FS -F $TMPFILE > /dev/null 2>&1
$DUMPE2FS $TMPFILE 2>&1 | grep 'Errors behavior' >> $OUT
echo "error continue" >> $OUT
$MKE2FS -e continue -F $TMPFILE > /dev/null 2>&1
$DUMPE2FS $TMPFILE 2>&1 | grep 'Errors behavior' >> $OUT
echo "error panic" >> $OUT
$MKE2FS -e panic -F $TMPFILE > /dev/null 2>&1
$DUMPE2FS $TMPFILE 2>&1 | grep 'Errors behavior' >> $OUT
echo "error remount-ro" >> $OUT
$MKE2FS -e remount-ro -F $TMPFILE > /dev/null 2>&1
$DUMPE2FS $TMPFILE 2>&1 | grep 'Errors behavior' >> $OUT
echo "error garbage" >> $OUT
dd if=/dev/zero of=$TMPFILE bs=1k count=512 > /dev/null 2>&1
$MKE2FS -e broken -F $TMPFILE > /dev/null 2>&1
$DUMPE2FS $TMPFILE 2>&1 | grep 'Errors behavior' >> $OUT
# Test errors= in default
echo "error default profile continue" >> $OUT
write_defaults_conf continue
MKE2FS_CONFIG=$conf $MKE2FS -F $TMPFILE > /dev/null 2>&1
$DUMPE2FS $TMPFILE 2>&1 | grep 'Errors behavior' >> $OUT
echo "error default profile panic" >> $OUT
write_defaults_conf panic
MKE2FS_CONFIG=$conf $MKE2FS -F $TMPFILE > /dev/null 2>&1
$DUMPE2FS $TMPFILE 2>&1 | grep 'Errors behavior' >> $OUT
echo "error default profile remount-ro" >> $OUT
write_defaults_conf remount-ro
MKE2FS_CONFIG=$conf $MKE2FS -F $TMPFILE > /dev/null 2>&1
$DUMPE2FS $TMPFILE 2>&1 | grep 'Errors behavior' >> $OUT
echo "error default profile broken" >> $OUT
write_defaults_conf broken
dd if=/dev/zero of=$TMPFILE bs=1k count=512 > /dev/null 2>&1
MKE2FS_CONFIG=$conf $MKE2FS -F $TMPFILE > /dev/null 2>&1
$DUMPE2FS $TMPFILE 2>&1 | grep 'Errors behavior' >> $OUT
# Test errors= in a fs type
echo "error fs_types profile continue" >> $OUT
write_section_conf continue
MKE2FS_CONFIG=$conf $MKE2FS -F $TMPFILE -T test_suite > /dev/null 2>&1
$DUMPE2FS $TMPFILE 2>&1 | grep 'Errors behavior' >> $OUT
echo "error fs_types profile panic" >> $OUT
write_section_conf panic
MKE2FS_CONFIG=$conf $MKE2FS -F $TMPFILE -T test_suite > /dev/null 2>&1
$DUMPE2FS $TMPFILE 2>&1 | grep 'Errors behavior' >> $OUT
echo "error fs_types profile remount-ro" >> $OUT
write_section_conf remount-ro
MKE2FS_CONFIG=$conf $MKE2FS -F $TMPFILE -T test_suite > /dev/null 2>&1
$DUMPE2FS $TMPFILE 2>&1 | grep 'Errors behavior' >> $OUT
# Test command line override
echo "error fs_types profile remount-ro" >> $OUT
write_section_conf remount-ro
MKE2FS_CONFIG=$conf $MKE2FS -F $TMPFILE -T test_suite -e panic > /dev/null 2>&1
$DUMPE2FS $TMPFILE 2>&1 | grep 'Errors behavior' >> $OUT
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 $test_name.tmp
fi