From e24368361db166cf369a19cea773bd54f9d854b1 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Rafa=C5=82=20Mi=C5=82ecki?= Date: Mon, 16 Apr 2018 16:11:47 +0200 Subject: [PATCH] libfstools: move mount points when switching to JFFS2 MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit Switching from "tmpfs" to "jffs2" happens after JFFS2 formatting is done. During that time user can use filesystem (thanks to RAM) and the role of switch2jffs() is to copy all changes to the JFFS2 overlay partition. What wasn't handled so far was moving mount points. User can create custom mounts, cp command won't copy them and umounting "tmpfs" will cause these mounts to go away. To preserve them switch2jffs() has to find all custom mount points and move them to the new filesystem. Signed-off-by: Rafał Miłecki Acked-by: John Crispin --- libfstools/overlay.c | 46 +++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 45 insertions(+), 1 deletion(-) diff --git a/libfstools/overlay.c b/libfstools/overlay.c index a41364c..ebc43f7 100644 --- a/libfstools/overlay.c +++ b/libfstools/overlay.c @@ -112,6 +112,24 @@ foreachdir(const char *dir, int (*cb)(const char*)) cb(dir); } +static void foreach_mount(int (*cb)(const char *, const char *)) +{ + FILE *fp = fopen("/proc/mounts", "r"); + static char line[256]; + + if (!fp) + return; + + while (fgets(line, sizeof(line), fp)) { + char device[32], mount_point[32]; + + if (sscanf(line, "%31s %31s %*s %*s %*u %*u", device, mount_point) == 2) + cb(device, mount_point); + } + + fclose(fp); +} + void overlay_delete(const char *dir, bool _keep_sysupgrade) { @@ -135,6 +153,19 @@ overlay_mount(struct volume *v, char *fs) return 0; } +/** + * move_mount - move mount point to the new root + */ +static int move_mount(const char *device, const char *mount_point) +{ + static const char *prefix = "/tmp/root/"; + + if (strncmp(mount_point, prefix, strlen(prefix))) + return 0; + + return mount_move(prefix, "/", mount_point + strlen(prefix)); +} + static int switch2jffs(struct volume *v) { @@ -174,7 +205,20 @@ switch2jffs(struct volume *v) return -1; } - return fopivot("/overlay", "/rom"); + ret = fopivot("/overlay", "/rom"); + + /* + * Besides copying overlay data from "tmpfs" to "jffs2" we should also + * move mount points that user could create during JFFS2 formatting. + * This has to happen after fopivot call because: + * 1) It's trivial to find mount points to move then (/tmp/root/...). + * 2) We can't do that earlier using /rom/overlay/upper/ as overlay(fs) + * doesn't support mounts. Mounting to upper dir don't make overlay + * /propagate/ files to the target dir. + */ + foreach_mount(move_mount); + + return ret; } int -- 2.30.2