diff options
-rw-r--r-- | recipes-core/initrdscripts/files/init-readonly-rootfs-overlay-boot.sh | 225 |
1 files changed, 115 insertions, 110 deletions
diff --git a/recipes-core/initrdscripts/files/init-readonly-rootfs-overlay-boot.sh b/recipes-core/initrdscripts/files/init-readonly-rootfs-overlay-boot.sh index 9b53e40..c777eec 100644 --- a/recipes-core/initrdscripts/files/init-readonly-rootfs-overlay-boot.sh +++ b/recipes-core/initrdscripts/files/init-readonly-rootfs-overlay-boot.sh | |||
@@ -19,41 +19,44 @@ ROOT_RWMOUNT="/media/rfs/rw" | |||
19 | ROOT_RWRESET="no" | 19 | ROOT_RWRESET="no" |
20 | 20 | ||
21 | early_setup() { | 21 | early_setup() { |
22 | mkdir -p /proc | 22 | mkdir -p /proc |
23 | mkdir -p /sys | 23 | mkdir -p /sys |
24 | $MOUNT -t proc proc /proc | 24 | $MOUNT -t proc proc /proc |
25 | $MOUNT -t sysfs sysfs /sys | 25 | $MOUNT -t sysfs sysfs /sys |
26 | grep -w "/dev" /proc/mounts >/dev/null || $MOUNT -t devtmpfs none /dev | 26 | grep -w "/dev" /proc/mounts >/dev/null || $MOUNT -t devtmpfs none /dev |
27 | } | 27 | } |
28 | 28 | ||
29 | read_args() { | 29 | read_args() { |
30 | [ -z "${CMDLINE+x}" ] && CMDLINE=`cat /proc/cmdline` | 30 | [ -z "${CMDLINE+x}" ] && CMDLINE=`cat /proc/cmdline` |
31 | for arg in $CMDLINE; do | 31 | for arg in $CMDLINE; do |
32 | # Set optarg to option parameter, and '' if no parameter was given | 32 | # Set optarg to option parameter, and '' if no parameter was |
33 | optarg=`expr "x$arg" : 'x[^=]*=\(.*\)' || echo ''` | 33 | # given |
34 | case $arg in | 34 | optarg=`expr "x$arg" : 'x[^=]*=\(.*\)' || echo ''` |
35 | root=*) | 35 | case $arg in |
36 | ROOT_RODEVICE=$optarg ;; | 36 | root=*) |
37 | rootfstype=*) | 37 | ROOT_RODEVICE=$optarg ;; |
38 | modprobe $optarg 2> /dev/null || true;; | 38 | rootfstype=*) |
39 | rootinit=*) | 39 | modprobe $optarg 2> /dev/null || \ |
40 | ROOT_ROINIT=$optarg ;; | 40 | echo "Could not load $optarg module";; |
41 | rootrw=*) | 41 | rootinit=*) |
42 | ROOT_RWDEVICE=$optarg ;; | 42 | ROOT_ROINIT=$optarg ;; |
43 | rootrwfstype=*) | 43 | rootrw=*) |
44 | modprobe $optarg 2> /dev/null || true;; | 44 | ROOT_RWDEVICE=$optarg ;; |
45 | rootrwreset=*) | 45 | rootrwfstype=*) |
46 | ROOT_RWRESET=$optarg ;; | 46 | modprobe $optarg 2> /dev/null || \ |
47 | init=*) | 47 | echo "Could not load $optarg module";; |
48 | INIT=$optarg ;; | 48 | rootrwreset=*) |
49 | esac | 49 | ROOT_RWRESET=$optarg ;; |
50 | done | 50 | init=*) |
51 | INIT=$optarg ;; | ||
52 | esac | ||
53 | done | ||
51 | } | 54 | } |
52 | 55 | ||
53 | fatal() { | 56 | fatal() { |
54 | echo $1 >$CONSOLE | 57 | echo $1 >$CONSOLE |
55 | echo >$CONSOLE | 58 | echo >$CONSOLE |
56 | exec sh | 59 | exec sh |
57 | } | 60 | } |
58 | 61 | ||
59 | early_setup | 62 | early_setup |
@@ -63,88 +66,90 @@ early_setup | |||
63 | read_args | 66 | read_args |
64 | 67 | ||
65 | mount_and_boot() { | 68 | mount_and_boot() { |
66 | mkdir -p $ROOT_MOUNT $ROOT_ROMOUNT $ROOT_RWMOUNT | 69 | mkdir -p $ROOT_MOUNT $ROOT_ROMOUNT $ROOT_RWMOUNT |
67 | 70 | ||
68 | # Build mount options for read only root filesystem. | 71 | # Build mount options for read only root file system. |
69 | # If no read-only device was specified via kernel commandline, use current | 72 | # If no read-only device was specified via kernel command line, use |
70 | # rootfs via bind mount. | 73 | # current root file system via bind mount. |
71 | ROOT_ROMOUNTOPTIONS_BIND="-o bind,ro /" | 74 | ROOT_ROMOUNTOPTIONS_BIND="-o bind,ro /" |
72 | if [ -z "${ROOT_RODEVICE}" ]; then | 75 | if [ -z "${ROOT_RODEVICE}" ]; then |
73 | ROOT_ROMOUNTOPTIONS="${ROOT_ROMOUNTOPTIONS_BIND}" | 76 | ROOT_ROMOUNTOPTIONS="${ROOT_ROMOUNTOPTIONS_BIND}" |
74 | else | 77 | else |
75 | ROOT_ROMOUNTOPTIONS="-o ro,noatime,nodiratime $ROOT_RODEVICE" | 78 | ROOT_ROMOUNTOPTIONS="-o ro,noatime,nodiratime $ROOT_RODEVICE" |
76 | fi | 79 | fi |
77 | 80 | ||
78 | # Mount rootfs as read-only to mount-point, if unsuccessful, | 81 | # Mount root file system as read-only to mount-point, if unsuccessful, |
79 | # try bind mount current rootfs | 82 | # try bind mount current rootfs |
80 | if ! $MOUNT $ROOT_ROMOUNTOPTIONS $ROOT_ROMOUNT && \ | 83 | if ! $MOUNT $ROOT_ROMOUNTOPTIONS $ROOT_ROMOUNT && \ |
81 | ! $MOUNT $ROOT_ROMOUNTOPTIONS_BIND $ROOT_ROMOUNT; then | 84 | ! $MOUNT $ROOT_ROMOUNTOPTIONS_BIND $ROOT_ROMOUNT; then |
82 | fatal "Could not mount read-only rootfs" | 85 | fatal "Could not mount read-only rootfs" |
83 | fi | 86 | fi |
84 | 87 | ||
85 | # If future init is the same as current file, use $ROOT_ROINIT | 88 | # If future init is the same as current file, use $ROOT_ROINIT |
86 | # Tries to avoid loop to infinity if init is set to current file via | 89 | # Tries to avoid loop to infinity if init is set to current file via |
87 | # kernel commandline | 90 | # kernel command line |
88 | if cmp -s "$0" "$INIT"; then | 91 | if cmp -s "$0" "$INIT"; then |
89 | INIT="$ROOT_ROINIT" | 92 | INIT="$ROOT_ROINIT" |
90 | fi | 93 | fi |
91 | 94 | ||
92 | # Build mount options for read write root filesystem. | 95 | # Build mount options for read write root file system. |
93 | # If no read-write device was specified via kernel commandline, use tmpfs. | 96 | # If no read-write device was specified via kernel command line, use |
94 | if [ -z "${ROOT_RWDEVICE}" ]; then | 97 | # tmpfs. |
95 | ROOT_RWMOUNTOPTIONS="-t tmpfs -o rw,noatime,mode=755 tmpfs" | 98 | if [ -z "${ROOT_RWDEVICE}" ]; then |
96 | else | 99 | ROOT_RWMOUNTOPTIONS="-t tmpfs -o rw,noatime,mode=755 tmpfs" |
97 | ROOT_RWMOUNTOPTIONS="-o rw,noatime,mode=755 $ROOT_RWDEVICE" | 100 | else |
98 | fi | 101 | ROOT_RWMOUNTOPTIONS="-o rw,noatime,mode=755 $ROOT_RWDEVICE" |
99 | 102 | fi | |
100 | # Mount read-write filesystem into initram rootfs | 103 | |
101 | if ! $MOUNT $ROOT_RWMOUNTOPTIONS $ROOT_RWMOUNT ; then | 104 | # Mount read-write file system into initram root file system |
102 | fatal "Could not mount read-write rootfs" | 105 | if ! $MOUNT $ROOT_RWMOUNTOPTIONS $ROOT_RWMOUNT ; then |
103 | fi | 106 | fatal "Could not mount read-write rootfs" |
104 | 107 | fi | |
105 | # Reset read-write filesystem if specified | 108 | |
106 | if [ "yes" == "$ROOT_RWRESET" -a -n "${ROOT_RWMOUNT}" ]; then | 109 | # Reset read-write file system if specified |
107 | rm -rf $ROOT_RWMOUNT/* | 110 | if [ "yes" == "$ROOT_RWRESET" -a -n "${ROOT_RWMOUNT}" ]; then |
108 | fi | 111 | rm -rf $ROOT_RWMOUNT/* |
109 | 112 | fi | |
110 | # Determine which unification filesystem to use | 113 | |
111 | union_fs_type="" | 114 | # Determine which unification file system to use |
112 | if grep -w "overlay" /proc/filesystems >/dev/null; then | ||
113 | union_fs_type="overlay" | ||
114 | elif grep -w "aufs" /proc/filesystems >/dev/null; then | ||
115 | union_fs_type="aufs" | ||
116 | else | ||
117 | union_fs_type="" | 115 | union_fs_type="" |
118 | fi | 116 | if grep -w "overlay" /proc/filesystems >/dev/null; then |
119 | 117 | union_fs_type="overlay" | |
120 | # Create/Mount overlay root filesystem | 118 | elif grep -w "aufs" /proc/filesystems >/dev/null; then |
121 | case $union_fs_type in | 119 | union_fs_type="aufs" |
122 | "overlay") | 120 | else |
123 | mkdir -p $ROOT_RWMOUNT/upperdir $ROOT_RWMOUNT/work | 121 | union_fs_type="" |
124 | $MOUNT -t overlay overlay -o "lowerdir=$ROOT_ROMOUNT,upperdir=$ROOT_RWMOUNT/upperdir,workdir=$ROOT_RWMOUNT/work" $ROOT_MOUNT | 122 | fi |
125 | ;; | 123 | |
126 | "aufs") | 124 | # Create/Mount overlay root file system |
127 | $MOUNT -t aufs -o "dirs=$ROOT_RWMOUNT=rw:$ROOT_ROMOUNT=ro" aufs $ROOT_MOUNT | 125 | case $union_fs_type in |
128 | ;; | 126 | "overlay") |
129 | "") | 127 | mkdir -p $ROOT_RWMOUNT/upperdir $ROOT_RWMOUNT/work |
130 | fatal "No overlay filesystem type available" | 128 | $MOUNT -t overlay overlay -o "lowerdir=$ROOT_ROMOUNT,upperdir=$ROOT_RWMOUNT/upperdir,workdir=$ROOT_RWMOUNT/work" $ROOT_MOUNT |
131 | ;; | 129 | ;; |
132 | esac | 130 | "aufs") |
133 | 131 | $MOUNT -t aufs -o "dirs=$ROOT_RWMOUNT=rw:$ROOT_ROMOUNT=ro" aufs $ROOT_MOUNT | |
134 | # Move read-only and read-write root filesystem into the overlay filesystem | 132 | ;; |
135 | mkdir -p $ROOT_MOUNT/$ROOT_ROMOUNT $ROOT_MOUNT/$ROOT_RWMOUNT | 133 | "") |
136 | $MOUNT -n --move $ROOT_ROMOUNT ${ROOT_MOUNT}/$ROOT_ROMOUNT | 134 | fatal "No overlay filesystem type available" |
137 | $MOUNT -n --move $ROOT_RWMOUNT ${ROOT_MOUNT}/$ROOT_RWMOUNT | 135 | ;; |
138 | 136 | esac | |
139 | $MOUNT -n --move /proc ${ROOT_MOUNT}/proc | 137 | |
140 | $MOUNT -n --move /sys ${ROOT_MOUNT}/sys | 138 | # Move read-only and read-write root file system into the overlay |
141 | $MOUNT -n --move /dev ${ROOT_MOUNT}/dev | 139 | # file system |
142 | 140 | mkdir -p $ROOT_MOUNT/$ROOT_ROMOUNT $ROOT_MOUNT/$ROOT_RWMOUNT | |
143 | cd $ROOT_MOUNT | 141 | $MOUNT -n --move $ROOT_ROMOUNT ${ROOT_MOUNT}/$ROOT_ROMOUNT |
144 | 142 | $MOUNT -n --move $ROOT_RWMOUNT ${ROOT_MOUNT}/$ROOT_RWMOUNT | |
145 | # busybox switch_root supports -c option | 143 | |
146 | exec chroot $ROOT_MOUNT $INIT || | 144 | $MOUNT -n --move /proc ${ROOT_MOUNT}/proc |
147 | fatal "Couldn't chroot, dropping to shell" | 145 | $MOUNT -n --move /sys ${ROOT_MOUNT}/sys |
146 | $MOUNT -n --move /dev ${ROOT_MOUNT}/dev | ||
147 | |||
148 | cd $ROOT_MOUNT | ||
149 | |||
150 | # switch to actual init in the overlay root file system | ||
151 | exec chroot $ROOT_MOUNT $INIT || | ||
152 | fatal "Couldn't chroot, dropping to shell" | ||
148 | } | 153 | } |
149 | 154 | ||
150 | mount_and_boot | 155 | mount_and_boot |