-
Notifications
You must be signed in to change notification settings - Fork 12
/
init-bottom_overlay
176 lines (149 loc) · 3.57 KB
/
init-bottom_overlay
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
#!/bin/sh
# based on https://gist.github.com/mutability/6cc944bde1cf4f61908e316befd42bc4
# goes in /etc/initramfs-tools/scripts/init-bottom/overlay
PREREQ=""
prereqs()
{
echo "$PREREQ"
}
case $1 in
prereqs)
prereqs
exit 0
;;
esac
. /scripts/functions
RW_SIZE=256m
# Should we run at all?
OVERLAY="no"
for arg in $(cat /proc/cmdline)
do
case "$arg" in
overlay=*)
OVERLAY=${arg#overlay=}
;;
*)
;;
esac
done
if [ "$OVERLAY" != "yes" ]
then
log_warning_msg "overlay not enabled, leaving the root fs alone"
exit 0
fi
log_begin_msg "Remounting root fs in overlay mode"
if ! modprobe -qb overlay
then
log_failure_msg "can't load overlay module"
exit 0
fi
# initially we have:
# / initramfs
# ${rootmnt} readonly-mounted real root FS (mounted from device ${ROOT})
#
# We want:
#
# / initramfs
# ${rootmnt} overlayfs using ${rootmnt}/ro and ${rootmnt}/rw
# ${rootmnt}/ro readonly-mounted real root FS (mounted from device ${ROOT})
# ${rootmnt}/rw tmpfs that will be used for changes
# ${rootmnt}/rw/upper overlayfs upper dir
# ${rootmnt}/rw/work overlayfs work dir
#
# create and mount /ro and /rw on the initramfs, we will move them later
for dir in /ro /rw
do
[ -d "${dir}" ] || mkdir -p "${dir}"
if [ $? -ne 0 ]
then
log_failure_msg "can't create ${dir}"
exit 0
fi
done
# set up /rw
if ! mount -t tmpfs -o "size=${RW_SIZE}" overlay-rw /rw
then
log_failure_msg "can't mount tmpfs on /rw"
exit 0
fi
for dir in /rw/upper /rw/work
do
if ! mkdir -p ${dir}
then
log_failure_msg "overlay: can't create ${dir}"
exit 0
fi
done
# set up /ro
if ! mount -o move "${rootmnt}" /ro
then
log_failure_msg "can't move root fs to /ro"
exit 0
fi
# set up an overlayfs on rootmnt
if ! mount -t overlay -o lowerdir=/ro,upperdir=/rw/upper,workdir=/rw/work overlay-root "${rootmnt}"
then
log_failure_msg "can't move root fs to /ro"
# try to recover
if ! mount -o move /ro "${rootmnt}"
then
panic "recovering the old root fs failed, panicking"
exit 0
fi
log_warning_msg "overlay: moved regular rootfs back into place and continuing"
exit 0
fi
for dir in "${rootmnt}/ro" "${rootmnt}/rw"
do
[ -d "${dir}" ] || mkdir -p "${dir}"
if [ $? -ne 0 ]
then
log_failure_msg "can't create ${dir}"
exit 0
fi
done
# move /ro and /rw into place so we can access them later
if ! mount -o move /ro "${rootmnt}/ro"
then
log_failure_msg "can't move /ro to ${rootmnt}/ro"
exit 0
fi
if ! mount -o move /rw "${rootmnt}/rw"
then
log_failure_msg "can't move /rw to ${rootmnt}/rw"
exit 0
fi
# populate fstab on the new root
{
cat <<EOF
# overlayfs mount is in use; changes to the root FS are
# written to tmpfs and will be discarded on reboot.
#
# to disable, pass "overlay=no" on the kernel command line
# (in /boot/cmdline.txt)
#
# the underlying root FS is mounted readonly on /ro
# temporary changes are written to /rw
EOF
{
while read dev dir fstype fsopts freq pass
do
if [ "${dir}" = "${rootmnt}" ]
then
echo "${dev} / ${fstype} ${fsopts} ${freq} ${pass}"
fi
done
} </proc/mounts
echo "# original fstab follows"
{
while read dev dir fstype fsopts freq pass
do
if [ "${dir}" != "/" ]
then
echo "${dev} ${dir} ${fstype} ${fsopts} ${freq} ${pass}"
fi
done
} <"${rootmnt}/ro/etc/fstab"
} >"${rootmnt}/etc/fstab"
log_end_msg
exit 0