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