From patchwork Tue May 15 09:02:58 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Andrzej Lossowsk X-Patchwork-Id: 913467 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=none (mailfrom) smtp.mailfrom=lists.infradead.org (client-ip=2607:7c80:54:e::133; helo=bombadil.infradead.org; envelope-from=lede-dev-bounces+incoming=patchwork.ozlabs.org@lists.infradead.org; receiver=) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=wp.pl Authentication-Results: ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=lists.infradead.org header.i=@lists.infradead.org header.b="aPmzM/eZ"; dkim=fail reason="signature verification failed" (1024-bit key; unprotected) header.d=wp.pl header.i=@wp.pl header.b="BZw4IjQ4"; dkim-atps=neutral Received: from bombadil.infradead.org (bombadil.infradead.org [IPv6:2607:7c80:54:e::133]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 40lVTq5WXVz9s0q for ; Tue, 15 May 2018 18:04:47 +1000 (AEST) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20170209; h=Sender: Content-Transfer-Encoding:Content-Type:List-Subscribe:List-Help:List-Post: List-Archive:List-Unsubscribe:List-Id:Subject:MIME-Version:Message-ID:To:From :Date:Reply-To:Cc:Content-ID:Content-Description:Resent-Date:Resent-From: Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:In-Reply-To:References: List-Owner; bh=V379PyIAse+2EesHzGvVAdhBin9Hk0OU0m7vdQe+7uo=; b=aPmzM/eZqkj2hq 1MFjiso9hkXfefg3Ii7Arxo5eMBvyQAKDutI+wJ2FOmCS4dWfdJ38O34jL6IPJqcFVI1Rl0tmwHwL WrPYEm9e67ChKjORyqraa094VSK6YStGavh5Af/5/79TpN+oWQfMsu52SUQ7hDVt/bcWmArjcb4Oo /k9zSbMKJZtcBv0aQsJSrjCyqCenj41c6jFQOS6aIjjRyj3L+NqzHvIS1yq9TGIFWbOkGs8HFgPCK Dl6H2r9Ros3C1EO2vTaNLdJLleDGLyXPiNkDk051oAZuk+CDol7lZQwpCun4S0AP+Oq2fi2hpMCwy r4RiGiJYSExKgXCme1JA==; Received: from localhost ([127.0.0.1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.90_1 #2 (Red Hat Linux)) id 1fIUwt-00018F-HR; Tue, 15 May 2018 08:04:43 +0000 Received: from mx3.wp.pl ([212.77.101.9]) by bombadil.infradead.org with esmtps (Exim 4.90_1 #2 (Red Hat Linux)) id 1fIUwj-00014y-Oo for lede-dev@lists.infradead.org; Tue, 15 May 2018 08:04:41 +0000 Received: (wp-smtpd smtp.wp.pl 30098 invoked from network); 15 May 2018 10:04:15 +0200 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=wp.pl; s=1024a; t=1526371455; bh=5JBUKWpFkUdqBXyJQUiw3i0Jvp4FYiJ53eGIZfs6QeA=; h=From:Sender:To:Subject; b=BZw4IjQ4MSGoEN/bkzZnXkvuGLn/g3JNfxSL9+dExzFIqLSUSMV4rTgy3uoTbqzDJ bDsOiZPSNCoUhRQLOPUkaeB4qvVFqL6h14dHHPUeARQgo+ig6VHgEuOTPbZiZTSghn kmzKdwEhILqWApdT5bjvmk00hTE8UWwCggoZcSXY= Received: from c205-90.icpnet.pl (HELO akosowski.local) (alossek@wp.pl@[85.221.205.90]) (envelope-sender ) by smtp.wp.pl (WP-SMTPD) with ECDHE-RSA-AES256-SHA encrypted SMTP for ; 15 May 2018 10:04:15 +0200 Date: Tue, 15 May 2018 10:02:58 +0100 From: Andrzej Lossowsk To: lede-dev@lists.infradead.org Message-ID: X-Mailer: TortoiseGit MIME-Version: 1.0 X-WP-MailID: 9f6fddd6b727e0c4b2b366393bfa4930 X-WP-AV: skaner antywirusowy Poczty Wirtualnej Polski X-WP-SPAM: NO 000000A [cYP0] X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20180515_010434_171720_15BF8C7D X-CRM114-Status: GOOD ( 10.67 ) X-Spam-Score: -0.7 (/) X-Spam-Report: SpamAssassin version 3.4.1 on bombadil.infradead.org summary: Content analysis details: (-0.7 points) pts rule name description ---- ---------------------- -------------------------------------------------- -0.0 RCVD_IN_DNSWL_NONE RBL: Sender listed at http://www.dnswl.org/, no trust [212.77.101.9 listed in list.dnswl.org] 0.0 FREEMAIL_FROM Sender email is commonly abused enduser mail provider (alossek[at]wp.pl) -0.6 RCVD_IN_MSPIKE_H2 RBL: Average reputation (+2) [212.77.101.9 listed in wl.mailspike.net] -0.0 SPF_PASS SPF: sender matches SPF record 0.1 DKIM_SIGNED Message has a DKIM or DK signature, not necessarily valid -0.1 DKIM_VALID Message has at least one valid DKIM or DK signature -0.1 DKIM_VALID_AU Message has a valid DKIM or DK signature from author's domain Subject: [LEDE-DEV] [PATCH] fstools: add middle layer (original root overlay) to overlayfs when pivot the /overlay to the USB disk. X-BeenThere: lede-dev@lists.infradead.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: "Lede-dev" Errors-To: lede-dev-bounces+incoming=patchwork.ozlabs.org@lists.infradead.org Currently after pivot to the USB disk (extroot), configuration and data from original root overlay are gone. Still accessible, but all previous configuration steps must be repeated (or data from original root overlay must be copied to new USB disk overlay). The idea is to "merge" original root overlay with overlay from the USB disk. Using overlayfs multiple lower layers it can be done. All data from original root overlay will be accessible (as readonly layer) after pivot to the USB disk. Original root overlay (for exmaple /dev/mtdblock3) will be mounted to /overlay/internal (as readonly) Upper directory from original root overlay (/dev/mtdblock3/upper) will be the top (readonly layer), then "/" will be the bottom layer (readonly layer), an extroot still will be upper (writable layer). Signed-off-by: Andrzej Lossowski --- libfstools/extroot.c | 73 ++++++++++++++++++++++++++++++++++++++++++++++++- libfstools/libfstools.h | 3 +- libfstools/mount.c | 21 +++++++++----- libfstools/overlay.c | 6 ++-- libfstools/snapshot.c | 2 +- 5 files changed, 92 insertions(+), 13 deletions(-) diff --git a/libfstools/extroot.c b/libfstools/extroot.c index 418df94..d7590eb 100644 --- a/libfstools/extroot.c +++ b/libfstools/extroot.c @@ -22,6 +22,7 @@ #include #include "libfstools.h" +#include "volume.h" char const *extroot_prefix = NULL; @@ -104,7 +105,7 @@ int mount_extroot(void) if (mount_move("/tmp/extroot", "", "/overlay")) { ULOG_ERR("moving extroot failed - continue normal boot\n"); umount("/tmp/extroot/overlay"); - } else if (fopivot("/overlay", "/rom")) { + } else if (fopivot_multi("/overlay", "/rom")) { ULOG_ERR("switching to extroot failed - continue normal boot\n"); umount("/overlay"); } else { @@ -119,3 +120,73 @@ int mount_extroot(void) } return -1; } + +static int mount_internal_overlay() +{ + struct volume *v = volume_find("rootfs_data"); + char *mp; + char *fstype; + + if (!v) + return -1; + + volume_init(v); + mp = find_mount_point(v->blk, 0); + if (mp) { + ULOG_ERR("rootfs_data:%s is already mounted as %s\n", v->blk, mp); + return -1; + } + + switch (volume_identify(v)) { + case FS_EXT4: + fstype = "ext4"; + break; + case FS_F2FS: + fstype = "f2fs"; + break; + case FS_UBIFS: + fstype = "ubifs"; + break; + case FS_JFFS2: + default: + fstype = "jffs2"; + break; + } + + if (mkdir("/tmp/overlay", 0755)) { + ULOG_ERR("failed to mkdir /tmp/overlay: %m\n"); + return -1; + } + + if (mount(v->blk, "/tmp/overlay", fstype, MS_NOATIME | MS_RDONLY, NULL)) { + ULOG_ERR("failed to mount -t %s %s /tmp/overlay: %m\n", fstype, v->blk); + return -1; + } + + return 0; +} + +int fopivot_multi(char *rw_root, char *ro_root) +{ + if (mount_internal_overlay()) { + ULOG_ERR("mounting /tmp/overlay failed\n"); + return -1; + } + + if (mkdir("/overlay/internal", 0755)) { + ULOG_ERR("failed to mkdir /overlay/internal: %m\n"); + return -1; + } + + if (mount_move("/tmp/overlay", "/overlay/internal", "")) { + umount("/tmp/overlay"); + return -1; + } + + if (fopivot(rw_root, ro_root, "/overlay/internal/upper")) { + umount("/overlay/internal"); + return -1; + } + + return 0; +} \ No newline at end of file diff --git a/libfstools/libfstools.h b/libfstools/libfstools.h index f27307a..8554f4c 100644 --- a/libfstools/libfstools.h +++ b/libfstools/libfstools.h @@ -45,7 +45,8 @@ extern int mount_overlay(struct volume *v); extern int mount_move(const char *oldroot, const char *newroot, const char *dir); extern int pivot(char *new, char *old); -extern int fopivot(char *rw_root, char *ro_root); +extern int fopivot(char *rw_root, char *ro_lowerlevel0, char *ro_lowerlevel1); +extern int fopivot_multi(char *rw_root, char *ro_root); extern int ramoverlay(void); extern int find_overlay_mount(char *overlay); diff --git a/libfstools/mount.c b/libfstools/mount.c index c7f2789..619ac20 100644 --- a/libfstools/mount.c +++ b/libfstools/mount.c @@ -89,12 +89,13 @@ pivot(char *new, char *old) * fopivot - switch to overlay using passed dir as upper one * * @rw_root: writable directory that will be used as upper dir - * @ro_root: directory where old root will be put + * @ro_root: directory where old root will be put + * @ro_lowerlevel1: directory where internal overlay will be put */ int -fopivot(char *rw_root, char *ro_root) +fopivot(char *rw_root, char *ro_root, char *ro_lowerlevel1) { - char overlay[64], mount_options[64]; + char overlay[64], mount_options[128]; if (find_filesystem("overlay")) { ULOG_ERR("BUG: no suitable fs found\n"); @@ -110,15 +111,21 @@ fopivot(char *rw_root, char *ro_root) */ snprintf(mount_options, sizeof(mount_options), "lowerdir=/,upperdir=%s", rw_root); if (mount(overlay, "/mnt", "overlayfs", MS_NOATIME, mount_options)) { - char upperdir[64], workdir[64], upgrade[64], upgrade_dest[64]; + char upperdir[64], workdir[64], upgrade[64], upgrade_dest[64], lowerdir[64]; struct stat st; snprintf(upperdir, sizeof(upperdir), "%s/upper", rw_root); snprintf(workdir, sizeof(workdir), "%s/work", rw_root); snprintf(upgrade, sizeof(upgrade), "%s/sysupgrade.tgz", rw_root); snprintf(upgrade_dest, sizeof(upgrade_dest), "%s/sysupgrade.tgz", upperdir); - snprintf(mount_options, sizeof(mount_options), "lowerdir=/,upperdir=%s,workdir=%s", - upperdir, workdir); + + if (ro_lowerlevel1) + snprintf(lowerdir, sizeof(lowerdir), "%s:/", ro_lowerlevel1); + else + snprintf(lowerdir, sizeof(lowerdir), "/"); + + snprintf(mount_options, sizeof(mount_options), "lowerdir=%s,upperdir=%s,workdir=%s", + lowerdir, upperdir, workdir); /* * Overlay FS v23 and later requires both a upper and @@ -154,5 +161,5 @@ ramoverlay(void) mkdir("/tmp/root", 0755); mount("tmpfs", "/tmp/root", "tmpfs", MS_NOATIME, "mode=0755"); - return fopivot("/tmp/root", "/rom"); + return fopivot("/tmp/root", "/rom", NULL); } diff --git a/libfstools/overlay.c b/libfstools/overlay.c index ebc43f7..10444e1 100644 --- a/libfstools/overlay.c +++ b/libfstools/overlay.c @@ -205,7 +205,7 @@ switch2jffs(struct volume *v) return -1; } - ret = fopivot("/overlay", "/rom"); + ret = fopivot("/overlay", "/rom", NULL); /* * Besides copying overlay data from "tmpfs" to "jffs2" we should also @@ -320,7 +320,7 @@ jffs2_switch(struct volume *v) case FS_UBIFS: if (overlay_mount(v, fs_name)) return -1; - if (mount_move("/tmp", "", "/overlay") || fopivot("/overlay", "/rom")) { + if (mount_move("/tmp", "", "/overlay") || fopivot("/overlay", "/rom", NULL)) { ULOG_ERR("switching to %s failed\n", fs_name); return -1; } @@ -428,7 +428,7 @@ int mount_overlay(struct volume *v) fs_name = overlay_fs_name(volume_identify(v)); ULOG_INFO("switching to %s overlay\n", fs_name); - if (mount_move("/tmp", "", "/overlay") || fopivot("/overlay", "/rom")) { + if (mount_move("/tmp", "", "/overlay") || fopivot("/overlay", "/rom", NULL)) { ULOG_ERR("switching to %s failed - fallback to ramoverlay\n", fs_name); return ramoverlay(); } diff --git a/libfstools/snapshot.c b/libfstools/snapshot.c index 4870cf7..c22cdc0 100644 --- a/libfstools/snapshot.c +++ b/libfstools/snapshot.c @@ -320,7 +320,7 @@ static int _ramoverlay(char *rom, char *overlay) { mount("tmpfs", overlay, "tmpfs", MS_NOATIME, "mode=0755"); - return fopivot(overlay, rom); + return fopivot(overlay, rom, NULL); } int