I've generated the following test patch which I think can be used to
paper over the bug in the Ubuntu init scripts by adding to
/etc/e2fsck.conf:
[options]
buggy_init_scripts = 1
I've not checked it into the e2fsprogs git tree yet --- could you
please confirm what you said earlier about the Ubuntu installer? I
had trouble believing it....
- Ted
commit 6e58cc20281e09a4b78b8537e351ea7ce87c60f5
Author: Theodore Ts'o <[EMAIL PROTECTED]>
Date: Fri Sep 7 20:36:04 2007 -0400
Work around lame Ubuntu init scripts / installer bugs
The Ubuntu init scripts don't properly set the system time correctly
from hardware clock if the hardware clock is configured to tick local
time instead of GMT time. Worse yet, the Ubuntu installer seems to be
unable to figure this out correctly, and apparently is deliberately
not asking the User to set the time correctly --- apparently leaving
the system clock insane is preferable to simply asking the user to
give the correct time and timezone. Craziness.
Work around this as best as we can by providing an option in
/etc/e2fsck.conf which can be set on Ubuntu systems:
[options]
buggy_init_scripts = 1
Addresses-Debian-Bug: #441093
Addresses-Ubuntu-Bug: #131201
Signed-off-by: "Theodore Ts'o" <[EMAIL PROTECTED]>
diff --git a/e2fsck/e2fsck.conf.5.in b/e2fsck/e2fsck.conf.5.in
index 8c580d2..002c29e 100644
--- a/e2fsck/e2fsck.conf.5.in
+++ b/e2fsck/e2fsck.conf.5.in
@@ -86,6 +86,19 @@ 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 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 GMT time. So while the kernel is booting,
+the system time is set from the hardware clock, but since the hardware
+clock is ticking localtime, the system clock is set incorrectly, and the
+distribution init scripts don't fix the system clock before running
+e2fsck. If this option is set, 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 25a9773..57adb2a 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 00a131c..d64d38d 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,60 @@ void check_super_block(e2fsck_t ctx)
ext2fs_mark_super_dirty(fs);
}
+ /*
+ * Some buggy distributions (such as Ubuntu) have init scripts
+ * and/or installers 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 GMT time. So while the kernel is booting,
+ * the system time is set from the hardware clock, but since
+ * the hardware clock is ticking localtime, the system clock
+ * is set incorrectly, and the distribution init scripts don't
+ * fix the system clock before running e2fsck. If this option
+ * is set, 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.
+ *
+ * Even worse, because the Ubuntu installer doesn't want to
+ * bother the user to ask him/her to set the time (!?!?!), if
+ * the hardware clock is totally insane when Ubuntu is being
+ * installed, if the machine is not on the network, it could
+ * run indefinitely with an incorrect system clock. In this
+ * case, you can't trust inode times at all, and then when the
+ * system time *is* set correctly, the system time could
+ * potentially warp by years, thus forcing erroneous
+ * filesystem checks. Total craziness. The
+ * buggy_init_scripts workaround will NOT fix this problem in
+ * this case; the only way to fix this is in the Ubuntu
+ * installer by asking the user to set the time correctly.
+ * (Is that really too much to ask?)
+ *
+ * <rant>Darn it, the distribution should be doing its best to
+ * make sure system time is correct, either by asking the user
+ * if it can't contact the NTP servers, and/or by making sure
+ * the hardware clock is ticking GMT, and/or by adjusting for
+ * timezones if the system owner insists on being
+ * bug-compatible with Windows by making the hardware clock
+ * tick localtime early enough in the boot sequence so that
+ * e2fsck can run with a sane system clock.</rant>
+ */
+ 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 950e2d4..2eb595d 100644
--- a/e2fsck/unix.c
+++ b/e2fsck/unix.c
@@ -285,7 +285,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) >=
+ ((ctx->now - (fs->super->s_lastcheck - ctx->time_fudge)) >=
fs->super->s_checkinterval)) {
reason = _(" has gone %u days without being checked");
reason_arg = (ctx->now - fs->super->s_lastcheck)/(3600*24);
--
To UNSUBSCRIBE, email to [EMAIL PROTECTED]
with a subject of "unsubscribe". Trouble? Contact [EMAIL PROTECTED]