diff --git a/debian/rules b/debian/rules index bb3f1d3b..842965e4 100755 --- a/debian/rules +++ b/debian/rules @@ -342,6 +342,12 @@ binary-arch: install install-udeb $(INSTALL) -d ${debdir}/uuid-dev/usr/share/doc/libuuid${UUID_SOVERSION} + if test -f /etc/lsb-release && \ + grep -q DISTRIB_ID=Ubuntu /etc/lsb-release; then \ + $(INSTALL) -p -m 0644 e2fsck/e2fsck.conf.ubuntu \ + ${debdir}/e2fsprogs/etc/e2fsck.conf; \ + fi + dh_installinfo -pcomerr-dev ${stdbuilddir}/lib/et/com_err.info dh_installinfo -pe2fslibs-dev ${stdbuilddir}/doc/libext2fs.info diff --git a/e2fsck/e2fsck.conf.5.in b/e2fsck/e2fsck.conf.5.in index 8c580d23..9d121716 100644 --- a/e2fsck/e2fsck.conf.5.in +++ b/e2fsck/e2fsck.conf.5.in @@ -86,6 +86,20 @@ If this relation is set to a boolean value of true, then if the user interrupts e2fsck using ^C, and the filesystem is not explicitly flagged as containing errors, e2fsck will exit with an exit status of 0 instead of 32. This setting defaults to false. +.TP +.I buggy_init_scripts +Some buggy distributions (such as Ubuntu) have init scripts and/or +installers which fail to correctly set the system clock before running +e2fsck and/or formatting the filesystem initially. Normally this +happens because the hardware clock is ticking localtime, instead of the +more proper and less error-prone UTC time. So while the kernel is +booting, the system time (which in Linux systems always ticks in UTC +time) is set from the hardware clock, but since the hardware clock is +ticking localtime, the system time is incorrect. Unfortunately, some +buggy distributions do not correct this before running e2fsck. If this +option is set to a boolean value of true, we attempt to work around this +situation by allowing the superblock last write time, last mount time, +and last check time to be in the future by up to 24 hours. .TP .I defer_check_on_battery This boolean relation controls whether or not the interval between diff --git a/e2fsck/e2fsck.h b/e2fsck/e2fsck.h index 25a97737..57adb2a7 100644 --- a/e2fsck/e2fsck.h +++ b/e2fsck/e2fsck.h @@ -329,6 +329,7 @@ struct e2fsck_struct { /* misc fields */ time_t now; + time_t time_fudge; /* For working around buggy init scripts */ int ext_attr_ver; profile_t profile; int blocks_per_page; diff --git a/e2fsck/super.c b/e2fsck/super.c index 00a131ce..e90e9610 100644 --- a/e2fsck/super.c +++ b/e2fsck/super.c @@ -463,6 +463,7 @@ void check_super_block(e2fsck_t ctx) int inodes_per_block; int ipg_max; int inode_size; + int buggy_init_scripts; dgrp_t i; blk_t should_be; struct problem_context pctx; @@ -711,18 +712,39 @@ void check_super_block(e2fsck_t ctx) ext2fs_mark_super_dirty(fs); } + /* + * Some buggy distributions (such as Ubuntu) have init scripts + * and/or installers which fail to correctly set the system + * clock before running e2fsck and/or formatting the + * filesystem initially. Normally this happens because the + * hardware clock is ticking localtime, instead of the more + * proper and less error-prone UTC time. So while the kernel + * is booting, the system time (which in Linux systems always + * ticks in UTC time) is set from the hardware clock, but + * since the hardware clock is ticking localtime, the system + * time is incorrect. Unfortunately, some buggy distributions + * do not correct this before running e2fsck. If this option + * is set to a boolean value of true, we attempt to work + * around this situation by allowing the superblock last write + * time, last mount time, and last check time to be in the + * future by up to 24 hours. + */ + profile_get_boolean(ctx->profile, "options", "buggy_init_scripts", + 0, 0, &buggy_init_scripts); + ctx->time_fudge = buggy_init_scripts ? 86400 : 0; + /* * Check to see if the superblock last mount time or last * write time is in the future. */ - if (fs->super->s_mtime > (__u32) ctx->now) { + if (fs->super->s_mtime > (__u32) ctx->now + ctx->time_fudge) { pctx.num = fs->super->s_mtime; if (fix_problem(ctx, PR_0_FUTURE_SB_LAST_MOUNT, &pctx)) { fs->super->s_mtime = ctx->now; ext2fs_mark_super_dirty(fs); } } - if (fs->super->s_wtime > (__u32) ctx->now) { + if (fs->super->s_wtime > (__u32) ctx->now + ctx->time_fudge) { pctx.num = fs->super->s_wtime; if (fix_problem(ctx, PR_0_FUTURE_SB_LAST_WRITE, &pctx)) { fs->super->s_wtime = ctx->now; diff --git a/e2fsck/unix.c b/e2fsck/unix.c index 950e2d4b..72545dab 100644 --- a/e2fsck/unix.c +++ b/e2fsck/unix.c @@ -260,6 +260,7 @@ static void check_if_skip(e2fsck_t ctx) long next_check; int batt = is_on_batt(); int defer_check_on_battery; + time_t lastcheck; profile_get_boolean(ctx->profile, "options", "defer_check_on_battery", 0, 1, @@ -271,6 +272,9 @@ static void check_if_skip(e2fsck_t ctx) cflag || swapfs) return; + lastcheck = fs->super->s_lastcheck; + if (lastcheck > ctx->now) + lastcheck -= ctx->time_fudge; if ((fs->super->s_state & EXT2_ERROR_FS) || !ext2fs_test_valid(fs)) reason = _(" contains a file system with errors"); @@ -285,8 +289,7 @@ static void check_if_skip(e2fsck_t ctx) (unsigned) fs->super->s_max_mnt_count*2)) reason = 0; } else if (fs->super->s_checkinterval && - ((ctx->now - fs->super->s_lastcheck) >= - fs->super->s_checkinterval)) { + ((ctx->now - lastcheck) >= fs->super->s_checkinterval)) { reason = _(" has gone %u days without being checked"); reason_arg = (ctx->now - fs->super->s_lastcheck)/(3600*24); if (batt && ((ctx->now - fs->super->s_lastcheck) <