-
Notifications
You must be signed in to change notification settings - Fork 0
/
ro_init.sh
executable file
·118 lines (102 loc) · 4 KB
/
ro_init.sh
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
#!/bin/bash
# Based on https://github.com/firecracker-microvm/firecracker-containerd/blob/main/tools/image-builder/files_debootstrap/sbin/overlay-init
# Trigger timestamp in FireCracker log file on the host to get boot time
echo "Trigger FireCracker timestamp" > /dev/kmsg
/opt/tools/fc_log_timestamp
# The directory where the overlay file system will be mounted to
overlay_dir=${overlay_dir:-'/overlay'}
if [ ! -d "$overlay_dir" ]; then
echo -n "FATAL: "
echo "Overlay directory $overlay_dir does not exist"
exit 1
fi
# The directory where the original, read-only root file system will be mounted to
rom_dir=${rom_dir:-'/rom'}
if [ ! -d "$rom_dir" ]; then
echo -n "FATAL: "
echo "Directory for mounting the read-only root file system $rom_dir does not exist"
exit 1
fi
# If we're given an overlay, ensure that it really exists. Panic if not.
if [ -n "$overlay_root" ] &&
[ "$overlay_root" != ram ] &&
[ ! -b "/dev/$overlay_root" ]; then
echo -n "FATAL: "
echo "Overlay root given as $overlay_root but /dev/$overlay_root does not exist"
exit 1
else
overlay_root="ram"
fi
if [ -z "$tempfs_size" ]; then
# Default size of tempfs
tempfs_size="128m"
fi
# Parameters:
# 1. rw_root -- path where the read/write root is mounted
# 2. work_dir -- path to the overlay workdir (must be on same filesystem as rw_root)
# Overlay will be set up on /mnt, original root on /mnt/rom
pivot() {
local rw_root work_dir
rw_root="$1"
work_dir="$2"
/bin/mount \
-o noatime,lowerdir=/,upperdir=${rw_root},workdir=${work_dir} \
-t overlay "overlayfs:${rw_root}" /mnt
pivot_root /mnt /mnt/rom
# We have to move the devtmpfs file system to the new root
# because it won't work from the overlay file system.
mount --move /rom/dev /dev
# Now that we have a new root, we can also mount the proc file system
mount -t proc proc /proc
}
# Overlay is configured under /overlay
# Global variable $overlay_root is expected to be set to either:
# "ram", which configures a tmpfs as the rw overlay layer (this is
# the default, if the variable is unset)
# - or -
# A block device name, relative to /dev, in which case it is assumed
# to contain an ext4 filesystem suitable for use as a rw overlay
# layer. e.g. "vdb"
do_overlay() {
local overlay_dir="/overlay"
if [ "$overlay_root" = ram ] ||
[ -z "$overlay_root" ]; then
/bin/mount -t tmpfs -o noatime,mode=0755,size=$tempfs_size tmpfs /overlay
else
/bin/mount -t ext4 "/dev/$overlay_root" /overlay
fi
mkdir -p /overlay/root /overlay/work
pivot /overlay/root /overlay/work
}
do_overlay
# Mount sysfs in case we need more insights int othe kernel
mount -t sysfs sysfs /sys
if [ -d /sys/kernel/debug ]; then
mount -t debugfs debugfs /sys/kernel/debug/
else
: # Need to configure kernel with CONFIG_DEBUG_FS=y
fi
export PATH=/opt/tools:/opt/jdk/bin:$PATH
if [[ -n "$sshd" && ( "$sshd" == "true" || "$sshd" == "on" || "$sshd" == "1" ) ]]; then
# Start ssh daemon for debugging
echo "Starting ssh daemon" > /dev/kmsg
# Also mount the devpts file system such that sshd can assign pseudo terminals (PTYs).
mkdir -p /dev/pts
mount -t devpts devpts /dev/pts
/sbin/sshd -o "SetEnv=PATH=$PATH"
fi
init_script=${init_script:-'/opt/tools/crac_init.sh'}
echo "Successfully overlayed read-only rootfs with /dev/$overlay_root" > /dev/kmsg
echo "Now starting $init_script $@" > /dev/kmsg
# Required to get correct line wrap in bash
TERM=ansi
# If we use a simple 'exec' here, we wont have "job control" in the spawned process:
# bash: cannot set terminal process group (-1): Inappropriate ioctl for device
# bash: no job control in this shell
# We have to make the spawned process a process group leader and assign it a terminal.
# See e.g. https://www.linux.it/~rubini/docs/init/init.html
# or https://www.busybox.net/FAQ.html#job_control
#
# This can be achieved with the help of the 'setsid' utility:
# https://github.com/util-linux/util-linux/blob/master/sys-utils/setsid.c
/usr/bin/setsid -c $init_script $@