blob: 863093407fda84a22244ca4a7ef969d2d2959f92 (
plain)
1 #!/bin/bash
2
3 export DEBUG=0
4 export INTERRACTIVE=0
5 export ROOTDEV=''
6
7 function screen_init {
8 # Clear screen
9 clear
10
11 # Output message file if it exists
12 [[ -f /etc/msg ]] && cat /etc/msg
13 }
14
15
16 #
17 # Mounts the fakeroot from the kernel "root" param
18 #
19 function mount_fakeroot {
20 local rootdev=${1}
21 local fakeroot=${2}
22
23 mount -o ro ${rootdev} ${fakeroot}
24 }
25
26
27 function log {
28 local msg="${1}"
29 echo -e "${msg}"
30 if [[ ${DEBUG} -ne 0 ]]; then
31 echo "Press enter to continue"
32 read
33 fi
34 }
35
36
37 #
38 # Resolves the path to the root device from the cmdline root= syntax.
39 # Currently handles UUID syntax and /dev/sdx syntax
40 #
41 function parse_cmdline {
42 local cmdline=${1}
43
44 for i in ${cmdline[@]}; do
45 case "${i}" in
46 root=*)
47 if [[ ${i:5:4} == 'UUID' ]]; then
48 # mount by uuid
49 local uuid=$(echo ${i} | cut -d '=' -f 3)
50 ROOTDEV="$(blkid -U ${uuid})"
51 elif [[ ${i:5:5} == 'LABEL' ]]; then
52 # mount by label
53 local label=$(echo ${i} | cut -d '=' -f 3)
54 ROOTDEV="$(blkid -L ${label})"
55 else
56 # mount by dev
57 ROOTDEV="$(echo ${i} | cut -d '=' -f 2)"
58 fi
59 ;;
60 initdebug)
61 # Enable debug mode (this is gonna be slow)
62 DEBUG=1
63 ;;
64 interractive)
65 # Enable interractive mode
66 INTERRACTIVE=1
67 ;;
68 esac
69 done
70 }
71
72
73 #
74 # Returns type of partition. If part is LUKS encrypted, returns 'luks'. If
75 # anything else, returns 'fs'.
76 #
77 # Most installations of the mount command don't require specification of the
78 # filesystem, but won't automatically detect luks partitions and prompt for a
79 # password. This allows the script to be smarter about encrypted partitions.
80 #
81 function get_part_type {
82 path=${1}
83 typestr=$(blkid -s TYPE ${path})
84 if [[ $(echo ${typestr} | grep 'crypto_LUKS') ]]; then
85 echo 'luks'
86 else
87 echo 'fs'
88 fi
89 }
90
91
92 #
93 # Takes an encrypted device path and executes cryptsetup luksOpen. Returns path
94 # to the new decrypted block device. This path takes the rough form of
95 # /dev/mapper/_dev_sdx
96 #
97 function setup_encrypted {
98 path=${1}
99 name=$(echo ${path} | tr / _)
100
101 # Decrypted block dev path is /dev/mapper/${name}
102 cryptsetup luksOpen ${path} ${name}
103
104 # Notify user and wait for input on failure
105 if [[ $? -gt 0 ]]; then
106 echo "An error was detected mounting the encrypted root." >&2
107 echo "Pausing. Press enter to continue." >&2
108 read
109 fi
110
111 # Success. Return the path of the decrypted root device
112 echo "/dev/mapper/${name}"
113 }
114
115
116 #
117 # Main function to keep the main operations code nicely separated from the
118 # rest.
119 #
120 function main {
121 # display fanciful boot image
122 screen_init
123
124 # Mount the /proc and /sys filesystems.
125 mount -t devtmpfs none /dev
126 mount -t proc none /proc
127 mount -t tmpfs none /run
128 mount -t sysfs none /sys
129
130 local fakeroot='/mnt/root'
131
132 if [[ ! -d ${fakeroot} ]]; then
133 log "Fake root location ${fakeroot} does not exist. Creating."
134 mkdir ${fakeroot}
135 fi
136
137 log "Parsing cmdline arguments"
138
139 parse_cmdline "$(cat /proc/cmdline)"
140
141 log "Root device: ${ROOTDEV}"
142
143 if [[ $(get_part_type ${ROOTDEV}) == 'luks' ]]; then
144 # Set new rootdev location (/dev/mapper/something). This will update it to
145 # the decrypted block device path.
146 log "Root device ${ROOTDEV} is encrypted."
147 ROOTDEV=$(setup_encrypted ${ROOTDEV})
148 log "New rootdev: ${ROOTDEV}"
149 fi
150
151 # Drop to interractive shell if requested
152 if [[ ${INTERRACTIVE} == 1 ]]; then
153 log "Interractive shell requested. Type 'exit' to continue boot sequence."
154 bash --norc
155 fi
156
157 # Mount the fakeroot.
158 log "Mounting fakeroot"
159 mount_fakeroot ${ROOTDEV} ${fakeroot}
160
161 # Clean up.
162 # We actually don't do this because switch_root does this for us
163 umount /proc
164 umount /sys
165 umount /run
166
167 # Boot the real McCoy
168 exec switch_root ${fakeroot} /sbin/init
169 if [[ $? -gt 0 ]]; then
170 log "There was an error performing switch_root to ${fakeroot}."
171 log "Starting recovery shell."
172 /bin/bash
173 fi
174 }
175
176 main ${@}
|