summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rwxr-xr-xdebian/rules6
-rw-r--r--e2fsck/e2fsck.conf.5.in14
-rw-r--r--e2fsck/e2fsck.h1
-rw-r--r--e2fsck/super.c26
-rw-r--r--e2fsck/unix.c7
5 files changed, 50 insertions, 4 deletions
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) <