summaryrefslogtreecommitdiffstats
path: root/recipes-core/initrdscripts/files/init-readonly-rootfs-overlay-boot.sh
diff options
context:
space:
mode:
Diffstat (limited to 'recipes-core/initrdscripts/files/init-readonly-rootfs-overlay-boot.sh')
-rw-r--r--recipes-core/initrdscripts/files/init-readonly-rootfs-overlay-boot.sh160
1 files changed, 160 insertions, 0 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
new file mode 100644
index 0000000..315da9b
--- /dev/null
+++ b/recipes-core/initrdscripts/files/init-readonly-rootfs-overlay-boot.sh
@@ -0,0 +1,160 @@
1#!/bin/sh
2
3PATH=/sbin:/bin:/usr/sbin:/usr/bin
4
5ROOT_MOUNT="/rootfs"
6MOUNT="/bin/mount"
7UMOUNT="/bin/umount"
8ROOT_RWDEVICE="tmpfs"
9ROOT_ROMOUNT="/rfs/ro"
10ROOT_RWMOUNT="/rfs/rw"
11
12# Copied from initramfs-framework. The core of this script probably should be
13# turned into initramfs-framework modules to reduce duplication.
14udev_daemon() {
15 OPTIONS="/sbin/udev/udevd /sbin/udevd /lib/udev/udevd /lib/systemd/systemd-udevd"
16
17 for o in $OPTIONS; do
18 if [ -x "$o" ]; then
19 echo $o
20 return 0
21 fi
22 done
23
24 return 1
25}
26
27_UDEV_DAEMON=`udev_daemon`
28
29early_setup() {
30 mkdir -p /proc
31 mkdir -p /sys
32 $MOUNT -t proc proc /proc
33 $MOUNT -t sysfs sysfs /sys
34 $MOUNT -t devtmpfs none /dev
35
36 # support modular kernel
37 modprobe isofs 2> /dev/null
38
39 mkdir -p /run
40 mkdir -p /var/run
41
42 $_UDEV_DAEMON --daemon
43 udevadm trigger --action=add
44}
45
46read_args() {
47 [ -z "$CMDLINE" ] && CMDLINE=`cat /proc/cmdline`
48 for arg in $CMDLINE; do
49 optarg=`expr "x$arg" : 'x[^=]*=\(.*\)'`
50 case $arg in
51 root=*)
52 ROOT_DEVICE=$optarg ;;
53 rootfstype=*)
54 modprobe $optarg 2> /dev/null ;;
55 rootrw=*)
56 ROOT_RWDEVICE=$optarg ;;
57 rootrwfstype=*)
58 modprobe $optarg 2> /dev/null ;;
59 video=*)
60 video_mode=$arg ;;
61 vga=*)
62 vga_mode=$arg ;;
63 console=*)
64 if [ -z "${console_params}" ]; then
65 console_params=$arg
66 else
67 console_params="$console_params $arg"
68 fi ;;
69 esac
70 done
71}
72
73fatal() {
74 echo $1 >$CONSOLE
75 echo >$CONSOLE
76 exec sh
77}
78
79early_setup
80
81[ -z "$CONSOLE" ] && CONSOLE="/dev/console"
82
83read_args
84
85mount_and_boot() {
86 mkdir -p $ROOT_MOUNT $ROOT_ROMOUNT $ROOT_RWMOUNT
87 mknod /dev/loop0 b 7 0 2>/dev/null
88
89 # Mount read-only root filesystem into initramfs rootfs
90 if ! $MOUNT -o ro,noatime,nodiratime $ROOT_DEVICE $ROOT_ROMOUNT ; then
91 fatal "Could not mount read-only rootfs"
92 fi
93
94 # determine which unification filesystem to use
95 union_fs_type=""
96 if grep -w "overlay" /proc/filesystems; then
97 union_fs_type="overlay"
98 elif grep -w "aufs" /proc/filesystems; then
99 union_fs_type="aufs"
100 else
101 union_fs_type=""
102 fi
103
104 # Build mount options for read write root filesystem.
105 # If no read-write device was specified via kernel commandline, use tmpfs.
106 if [ "tmpfs" == $ROOT_RWDEVICE ]; then
107 ROOT_RWMOUNTOPTIONS="-t tmpfs -o rw,noatime,mode=755"
108 else
109 ROOT_RWMOUNTOPTIONS="-o rw,noatime,mode=755"
110 fi
111
112 # Mount read-write filesystem into initram rootfs
113 if ! $MOUNT $ROOT_RWMOUNTOPTIONS $ROOT_RWDEVICE $ROOT_RWMOUNT ; then
114 fatal "Could not mount read-write rootfs"
115 fi
116
117 # Create/Mount overlay root filesystem
118 case $union_fs_type in
119 "overlay")
120 mkdir -p $ROOT_RWMOUNT/upperdir $ROOT_RWMOUNT/work
121 $MOUNT -t overlay overlay -o "lowerdir=$ROOT_ROMOUNT,upperdir=$ROOT_RWMOUNT/upperdir,workdir=$ROOT_RWMOUNT/work" $ROOT_MOUNT
122 ;;
123 "aufs")
124 $MOUNT -t aufs -o "dirs=$ROOT_RWMOUNT=rw:$ROOT_ROMOUNT=ro" aufs $ROOT_MOUNT
125 ;;
126 "")
127 fatal "No overlay filesystem type available"
128 ;;
129 esac
130
131 # Move read-only and read-write root filesystem into the overlay filesystem
132 mkdir -p $ROOT_MOUNT/$ROOT_ROMOUNT $ROOT_MOUNT/$ROOT_RWMOUNT
133 $MOUNT --move $ROOT_ROMOUNT $ROOT_MOUNT/$ROOT_ROMOUNT
134 $MOUNT --move $ROOT_RWMOUNT $ROOT_MOUNT/$ROOT_RWMOUNT
135
136 # Watches the udev event queue, and exits if all current events are handled
137 udevadm settle --timeout=3 --quiet
138 # Kills the current udev running processes, which survived after
139 # device node creation events were handled, to avoid unexpected behavior
140 killall -9 "${_UDEV_DAEMON##*/}" 2>/dev/null
141
142 # Move the mount points of some filesystems over to
143 # the corresponding directories under the real root filesystem.
144 for dir in `awk '/\/dev.* \/run\/media/{print $2}' /proc/mounts`; do
145 mkdir -p ${ROOT_MOUNT}/media/${dir##*/}
146 $MOUNT -n --move $dir ${ROOT_MOUNT}/media/${dir##*/}
147 done
148 $MOUNT -n --move /proc ${ROOT_MOUNT}/proc
149 $MOUNT -n --move /sys ${ROOT_MOUNT}/sys
150 $MOUNT -n --move /dev ${ROOT_MOUNT}/dev
151
152 cd $ROOT_MOUNT
153
154 # busybox switch_root supports -c option
155 exec switch_root -c /dev/console $ROOT_MOUNT /sbin/init $CMDLINE ||
156 fatal "Couldn't switch_root, dropping to shell"
157}
158
159mount_and_boot
160