2 * Copyright (C) 2014 John Crispin <blogic@openwrt.org>
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU Lesser General Public License version 2.1
6 * as published by the Free Software Foundation
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
14 #include <sys/types.h>
16 #include <sys/mount.h>
23 #include "libfstools.h"
25 /* this is a raw syscall - man 2 pivot_root */
26 extern int pivot_root(const char *new_root
, const char *put_old
);
29 mount_move(char *oldroot
, char *newroot
, char *dir
)
32 #define MS_MOVE (1 << 13)
39 snprintf(olddir
, sizeof(olddir
), "%s%s", oldroot
, dir
);
40 snprintf(newdir
, sizeof(newdir
), "%s%s", newroot
, dir
);
42 if (stat(olddir
, &s
) || !S_ISDIR(s
.st_mode
))
45 if (stat(newdir
, &s
) || !S_ISDIR(s
.st_mode
))
48 ret
= mount(olddir
, newdir
, NULL
, MS_NOATIME
| MS_MOVE
, NULL
);
51 fprintf(stderr, "failed %s %s: %s\n", olddir, newdir, strerror(errno));*/
57 pivot(char *new, char *old
)
62 if (mount_move("", new, "/proc"))
65 snprintf(pivotdir
, sizeof(pivotdir
), "%s%s", new, old
);
67 ret
= pivot_root(new, pivotdir
);
70 fprintf(stderr
, "pivot_root failed %s %s: %s\n", new, pivotdir
, strerror(errno
));
74 mount_move(old
, "", "/dev");
75 mount_move(old
, "", "/tmp");
76 mount_move(old
, "", "/sys");
77 mount_move(old
, "", "/overlay");
83 fopivot(char *rw_root
, char *ro_root
)
85 char overlay
[64], lowerdir
[64];
87 if (find_filesystem("overlay")) {
88 fprintf(stderr
, "BUG: no suitable fs found\n");
92 snprintf(overlay
, sizeof(overlay
), "overlayfs:%s", rw_root
);
93 snprintf(lowerdir
, sizeof(lowerdir
), "lowerdir=/,upperdir=%s", rw_root
);
95 if (mount(overlay
, "/mnt", "overlayfs", MS_NOATIME
, lowerdir
)) {
96 fprintf(stderr
, "mount failed: %s\n", strerror(errno
));
100 return pivot("/mnt", ro_root
);
106 mkdir("/tmp/root", 0755);
107 mount("tmpfs", "/tmp/root", "tmpfs", MS_NOATIME
, "mode=0755");
109 return fopivot("/tmp/root", "/rom");