-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathinit.sh
More file actions
170 lines (159 loc) · 4.66 KB
/
init.sh
File metadata and controls
170 lines (159 loc) · 4.66 KB
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
#!/bin/sh
# Init script for initramfs
#
# If a rootfs folder can be mounted at root, switches to full user space.
# Else, jumps into a busybox (a)sh shell.
#
# This process can be thought of as:
#
# ( start machine )
# |
# [ BIOS/UEFI firmware ]
# |
# [ load GRUB/bootloader ]
# |
# [ init linux kernel ]
# |
# [ load initramfs ]
# |
# [ /init ]
# |
# ( does rootfs exist? )
# | |
# V V
# [ yes ] [ no ]---> [ /bin/sh ] --> ( stop inside initramfs )
# |
# V
# < Can rootfs fit in memory? >
# | |
# V V
# [ yes ] [ no ]---> [ readonly rootfs! ]
# | |
# V |
# [ copy rootfs to tmpfs ] |
# | |
# |<------------------------------
# V
# < does rootfs contain /sbin/init ? >
# | |
# V V
# [ yes ] [ no ]----------------
# | |
# V |
# [ switch_root rootfs /sbin/init ] |
# | |
# V V
# < Success? > -----[ no ]---> [ chroot rootfs bash]
# | |
# [ yes ] |
# | |
# |<---------------------------
# V
# < Success? > ---[ no ]---> [ /bin/sh ] --> ( stop inside initramfs)
# |
# [ yes ]
# |
# V
# ( stop inside rootfs userspace )
#
#
# Notes:
# * Rootfs may be on the iso directly
# * Alternatively rootfs may be avirtio filesystem named "rootfs"
# * If there is enough space, rootfs will be copied to memory.
# * If there is not enough space, rootfs will be readonly.
# * Either way rootfs will be non-persistant.
# Mount kernel / virtual filesystems
mount -t devtmpfs none /dev
mount -t proc none /proc
mount -t sysfs none /sys
# Make rootfs mountpoint
mkdir -p /mnt/rootfs
# Mount rootfs if stored on /dev/sda (This image)
mkdir -p /mnt/sda
mount /dev/sda /mnt/sda
mount /mnt/sda/rootfs /mnt/rootfs
# Mount rootfs of virtual filesystem if found (libvirt / qemu / virsh / virtmanager)
# This allows for using containers/chroots as root userspace.
mount -t 9p -o trans=virtio,rw,version=9p2000.L rootfs /mnt/rootfs 2>/dev/null
# Usually an init would want to umount these,
# but busybox should handle this for us:
umount /dev
umount /sys
umount /proc
switch_to_rootfs() {
# Chroot to rootfs
# switch_root must run as PID 1
echo 'Attempting to switch root...'
exec busybox switch_root . "/sbin/init" "$@"
}
chroot_to_rootfs() {
# chroot to rootfs
echo 'Attempting to chroot...'
chroot . bash
}
initramfs_shell(){
# Basic shell, silence job control warnings
echo 'Running interactive initramfs.'
clear
sleep 1
clear
cat /etc/hello.ascii
sh +m
}
if [ ! -d /mnt/rootfs/bin ];
then
initramfs_shell
else
echo 'Mount available for userspace root filesystem.'
echo 'Copying rootfs data into memory... (changes will not persist between restarts)'
mkdir -p /tmp/rootfs
mount -t tmpfs tmpfs /tmp/rootfs
n=$(find /mnt/rootfs/ -maxdepth 1 | wc -l)
i=1
rootfs=/mnt/rootfs
for d in /mnt/rootfs/*
do
cp -aR "$d" /tmp/rootfs/ 2>/dev/null || { rootfs=/mnt/rootfs ; break ; }
i=$(( $i + 1 ))
pcnt=$(echo "scale=2; $i / $n * 100" | bc)
echo "Copying rootfs: $pcnt %"
rootfs=/tmp/rootfs
done
if [ "$rootfs" = "/tmp/rootfs" ]
then
echo '...complete.'
else
echo '...not enough space, filesystem will be READ ONLY!'
umount /tmp/rootfs
sleep 5
fi
cd $rootfs
# Modify this file for automated start
echo 'Select mode (within 10 seconds):'
echo 'Default / no selection : 1 -> 2 -> 3'
echo '1) switch_root rootfs /sbin/init'
echo '2) chroot rootfs bash'
echo '3) initramfs /bin/sh'
if read -t 10 input
then
case "$input" in
1)
switch_to_rootfs
;;
2)
chroot_to_rootfs
;;
3)
initramfs_shell
;;
*)
;;
esac
else
echo 'Attempting to switch root...'
exec busybox switch_root . "/sbin/init" "$@" \
|| { echo 'switch_root failed!... trying chroot... ' ; chroot . bash ; } \
|| { echo 'switch and chroot failed!... staying in initramfs! :( ' ; sh +m ; }
fi
fi