summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRafał Miłecki <rafal@milecki.pl>2018-04-16 16:11:47 +0200
committerRafał Miłecki <rafal@milecki.pl>2018-04-16 19:10:17 +0200
commite24368361db166cf369a19cea773bd54f9d854b1 (patch)
tree1f542d6a848d43affde2655168616e288f6b1163
parent3782b59e8f6391134cf146033ebe3baa1fbc0f5a (diff)
downloadfstools-e24368361db166cf369a19cea773bd54f9d854b1.tar.gz
libfstools: move mount points when switching to JFFS2
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 <rafal@milecki.pl> Acked-by: John Crispin <john@phrozen.org>
-rw-r--r--libfstools/overlay.c46
1 files changed, 45 insertions, 1 deletions
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