From patchwork Fri May 19 00:20:32 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Darrick J. Wong" X-Patchwork-Id: 9735371 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id D72F1602C8 for ; Fri, 19 May 2017 00:20:44 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id C1843288EE for ; Fri, 19 May 2017 00:20:44 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id A690128922; Fri, 19 May 2017 00:20:44 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-6.9 required=2.0 tests=BAYES_00, RCVD_IN_DNSWL_HI, UNPARSEABLE_RELAY autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 43ECF288F6 for ; Fri, 19 May 2017 00:20:44 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1754435AbdESAUh (ORCPT ); Thu, 18 May 2017 20:20:37 -0400 Received: from aserp1040.oracle.com ([141.146.126.69]:28747 "EHLO aserp1040.oracle.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1754048AbdESAUg (ORCPT ); Thu, 18 May 2017 20:20:36 -0400 Received: from aserv0021.oracle.com (aserv0021.oracle.com [141.146.126.233]) by aserp1040.oracle.com (Sentrion-MTA-4.3.2/Sentrion-MTA-4.3.2) with ESMTP id v4J0KZoA016642 (version=TLSv1 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK); Fri, 19 May 2017 00:20:35 GMT Received: from userv0122.oracle.com (userv0122.oracle.com [156.151.31.75]) by aserv0021.oracle.com (8.13.8/8.14.4) with ESMTP id v4J0KYt9015710 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK); Fri, 19 May 2017 00:20:35 GMT Received: from abhmp0012.oracle.com (abhmp0012.oracle.com [141.146.116.18]) by userv0122.oracle.com (8.14.4/8.14.4) with ESMTP id v4J0KYSm023730; Fri, 19 May 2017 00:20:34 GMT Received: from localhost (/10.145.179.24) by default (Oracle Beehive Gateway v4.0) with ESMTP ; Thu, 18 May 2017 17:20:34 -0700 Date: Thu, 18 May 2017 17:20:32 -0700 From: "Darrick J. Wong" To: xfs Cc: linux-fsdevel , linux-ext4 Subject: [PATCH] vfs: freeze filesystems just prior to reboot Message-ID: <20170519002032.GA21202@birch.djwong.org> MIME-Version: 1.0 Content-Disposition: inline User-Agent: Mutt/1.5.24 (2015-08-30) X-Source-IP: aserv0021.oracle.com [141.146.126.233] Sender: linux-xfs-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-xfs@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP Apparently, there users out there with a single gigantic journalled rootfs and some gnarly system software. If the user reboots into "offline system update" mode to install a kernel update, the system control software has no provision to kick the cute splash screen off its writable file descriptor down in /var/log somewhere before unmounting, remount-ro'ing, and thus reboots the system... with a live rw rootfs! Since the journal may not have been checkpointed immediately prior to the reboot, a subsequent invocation of the hapless user's grubby bootloader sees obsolete metadata because the newest data is safely in the log, but the log needs to be replayed. Weirdly, the bootloader is fine with reading files off a dirty filesystem (though really, can you imagine log replay in x86 real mode?) but still tries to read files and the boot fails until someone intervenes to replay the journal. Therefore, add a reboot hook to freeze all filesystems (which in general will induce ext4/xfs/btrfs to checkpoint the log) just prior to reboot. This is an unfortunate and insufficient workaround for multiple layers of inadequate external software, but at least it will reduce boot time surprises for the "OS updater failed to disengage the filesystem before rebooting" case. Seeing as the world has been drifting towards grubbiness (except for those booting straight off a flabby unjournalled fs via firmware), this seems like the least crappy solution to this problem. Yes, you're still screwed in grub if the system crashes. :) Signed-off-by: Darrick J. Wong --- fs/super.c | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) -- To unsubscribe from this list: send the line "unsubscribe linux-xfs" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html diff --git a/fs/super.c b/fs/super.c index adb0c0d..4a9deaa 100644 --- a/fs/super.c +++ b/fs/super.c @@ -34,6 +34,7 @@ #include #include #include +#include #include "internal.h" @@ -1529,3 +1530,32 @@ int thaw_super(struct super_block *sb) return 0; } EXPORT_SYMBOL(thaw_super); + +static void fsreboot_freeze_sb(struct super_block *sb, void *priv) +{ + int error; + + up_read(&sb->s_umount); + error = freeze_super(sb); + down_read(&sb->s_umount); + if (error && error != -EBUSY) + printk(KERN_NOTICE "%s (%s): Unable to freeze, error=%d", + sb->s_type->name, sb->s_id, error); +} + +static int fsreboot_freeze(struct notifier_block *nb, ulong event, void *buf) +{ + iterate_supers(fsreboot_freeze_sb, NULL); + return NOTIFY_DONE; +} + +static struct notifier_block fsreboot_notifier = { + .notifier_call = fsreboot_freeze, + .priority = INT_MAX, +}; + +static int __init fsreboot_init(void) +{ + return register_reboot_notifier(&fsreboot_notifier); +} +__initcall(fsreboot_init);