Message ID | 20180416141147.20658-1-zajec5@gmail.com |
---|---|
State | Accepted |
Headers | show |
Series | [LEDE-DEV,fstools] libfstools: move mount points when switching to JFFS2 | expand |
On 16/04/18 16:11, Rafał Miłecki wrote: > From: Rafał Miłecki <rafal@milecki.pl> > > 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> > --- > 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
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