diff options
Diffstat (limited to 'src/initrd/grok-block')
-rwxr-xr-x | src/initrd/grok-block | 182 |
1 files changed, 182 insertions, 0 deletions
diff --git a/src/initrd/grok-block b/src/initrd/grok-block new file mode 100755 index 0000000..75d5120 --- /dev/null +++ b/src/initrd/grok-block | |||
@@ -0,0 +1,182 @@ | |||
1 | #!/bin/sh | ||
2 | . common.sh | ||
3 | |||
4 | DEVNAME=$1 | ||
5 | case "$DEVNAME" in /dev/loop*|/dev/ram*|/dev/dm-*|/dev/md*|/dev/fd*) exit ;; esac | ||
6 | [ -b "$DEVNAME" ] || exit | ||
7 | |||
8 | debug_log "grok-block.${DEVNAME##*/}" | ||
9 | |||
10 | addmenu_choosekey() | ||
11 | { | ||
12 | dev=$1 | ||
13 | dir=$2 | ||
14 | addmenu "$dev//$dir" \ | ||
15 | "[ Use the GPG key on $dev ]" \ | ||
16 | "menu-select boot-gpg $dev $dir" | ||
17 | } | ||
18 | |||
19 | addmenu_repairhfs() | ||
20 | { | ||
21 | local device="$1" | ||
22 | addmenu "$device//reboot" \ | ||
23 | "[ Reboot into Mac OS X in order to repair disk $device ]" \ | ||
24 | "eject /cdrom; sleep 2; reboot -f" | ||
25 | addmenu "$device//fsck" \ | ||
26 | "[ (DANGEROUS) Try to repair errors on $device with fsck.hfsplus ]" \ | ||
27 | "/bin/openvt -sw -- sh -c 'fsck.hfsplus $device && remenu'" | ||
28 | } | ||
29 | |||
30 | addmenu_chooseroot() | ||
31 | { | ||
32 | local device="$1" loopfile="$2" | ||
33 | |||
34 | addmenu "$device//$loopfile" \ | ||
35 | "[ Boot the system on $device${loopfile:+ in file $(basename $loopfile)} ]" \ | ||
36 | "menu-select --fs=$ID_FS_TYPE boot-luks $device ${loopfile:-$device}" | ||
37 | } | ||
38 | |||
39 | addmenu_makeroot() | ||
40 | { | ||
41 | local device="$1" loopfile="$2" megs="$3" copy_cdrom="$4" | ||
42 | ( | ||
43 | addmenu "$device//$loopfile" \ | ||
44 | "[ Install Samizdat to $device (in file $(basename $loopfile)) ]" \ | ||
45 | "menu-select --fs=$ID_FS_TYPE boot-new $device $loopfile $megs $copy_cdrom" | ||
46 | ) & | ||
47 | } | ||
48 | |||
49 | retry_mount() | ||
50 | { | ||
51 | tries=20 | ||
52 | until mntout="$(mount "$@" 2>&1)" | ||
53 | do | ||
54 | tries=$(( tries - 1 )) | ||
55 | case "$mntout" in | ||
56 | *"Device or resource busy"*) | ||
57 | if [ $tries -le 0 ]; then | ||
58 | warn "mount $@ failed: $mntout" | ||
59 | return 1 | ||
60 | else | ||
61 | sleep 1 | ||
62 | continue | ||
63 | fi | ||
64 | ;; | ||
65 | *) | ||
66 | warn "mount $@ failed: $mntout" | ||
67 | break ;; | ||
68 | esac | ||
69 | done | ||
70 | } | ||
71 | |||
72 | gpg_verify() | ||
73 | { | ||
74 | bootwait samizdat-cdrom | ||
75 | gpg2 --lock-never --no-permission-warning --no-auto-check-trustdb --no-options --homedir /cdrom/gnupghome --verify "$1" | ||
76 | } | ||
77 | is_lvm() | ||
78 | { | ||
79 | for n in 0 1 2 3; do | ||
80 | [ "LVM2 001" = "$(dd if="$1" bs=1 skip=$((512*n+24)) count=8 2>/dev/null)" ] && return 0 | ||
81 | done | ||
82 | return 1 | ||
83 | } | ||
84 | |||
85 | grok_block() | ||
86 | { | ||
87 | local mountpoint="/mnt/${DEVNAME##*/}" | ||
88 | |||
89 | mkdir -p "$mountpoint" | ||
90 | |||
91 | case "$ID_FS_TYPE" in | ||
92 | ntfs) mount_type='-t ntfs-3g' ;; | ||
93 | "") mount_type= ;; | ||
94 | *) mount_type="-t $ID_FS_TYPE" ;; | ||
95 | esac | ||
96 | |||
97 | if [ "$ID_FS_TYPE" = hfsplus ] && ! fsck.hfsplus -q "$DEVNAME"; then | ||
98 | (if fsck.hfsplus "$DEVNAME"; then | ||
99 | grok-block "$DEVNAME" | ||
100 | else | ||
101 | addmenu_repairhfs "$DEVNAME" | ||
102 | fi) & | ||
103 | return | ||
104 | fi | ||
105 | |||
106 | if ! mountpoint -q "$mountpoint"; then | ||
107 | retry_mount $mount_type -o ro "$DEVNAME" "$mountpoint" | ||
108 | fi | ||
109 | |||
110 | if mountpoint -q "$mountpoint"; then | ||
111 | umount=true | ||
112 | # Device has an unencrypted filesystem on it. | ||
113 | # So we mount it and look for loop-back overlays. | ||
114 | |||
115 | if [ -d "$mountpoint/samizdat.gpg" ]; then | ||
116 | # check the key somehow? | ||
117 | addmenu_choosekey "$DEVNAME" "$mountpoint/samizdat.gpg" | ||
118 | fi | ||
119 | |||
120 | N=1; while [ -e "$mountpoint/samizdat.$N" ] | ||
121 | do | ||
122 | if gpg_verify "$mountpoint/samizdat.$N"k; then | ||
123 | addmenu_chooseroot "$DEVNAME" "$mountpoint/samizdat.$N" | ||
124 | # this menu entry chooses the root fs, and should prompt and wait for the matching key | ||
125 | umount=false | ||
126 | fi | ||
127 | N=$((N+1)) | ||
128 | done | ||
129 | |||
130 | freeblocks=$(stat -f -c %f "$mountpoint") | ||
131 | blocksize=$(stat -f -c %S "$mountpoint") | ||
132 | freemegs=$((freeblocks * blocksize / 1024 / 1024)) | ||
133 | |||
134 | if [ "$freemegs" -ge 300 ]; then | ||
135 | |||
136 | umount=false | ||
137 | bootwait samizdat-cdrom | ||
138 | cdromblocks=$(stat -f -c %b /cdrom) | ||
139 | cdromblocksize=$(stat -f -c %S /cdrom) | ||
140 | cdrommegs=$((cdromblocks * cdromblocksize / 1024 / 1024)) | ||
141 | |||
142 | if [ "$freemegs" -ge "$((cdrommegs * 3))" ]; then | ||
143 | addmenu_makeroot "$DEVNAME" "${mountpoint}/samizdat.$N" "$((cdrommegs * 3))" 1 | ||
144 | elif [ "$freemegs" -ge "$((cdrommegs * 2))" ]; then | ||
145 | addmenu_makeroot "$DEVNAME" "${mountpoint}/samizdat.$N" "$((cdrommegs * 2))" 1 | ||
146 | elif [ "$freemegs" -ge "$cdrommegs" ]; then | ||
147 | addmenu_makeroot "$DEVNAME" "${mountpoint}/samizdat.$N" "$((freemegs / 2))" 0 | ||
148 | else | ||
149 | addmenu_makeroot "$DEVNAME" "${mountpoint}/samizdat.$N" 256 0 | ||
150 | fi | ||
151 | fi | ||
152 | |||
153 | if $umount; then | ||
154 | umount "$mountpoint" | ||
155 | rmdir "$mountpoint" | ||
156 | fi | ||
157 | else | ||
158 | rmdir "$mountpoint" | ||
159 | fi | ||
160 | } | ||
161 | |||
162 | # Get me all them nice udev variables | ||
163 | eval "$(PATH=$PATH:/lib/udev vol_id "$DEVNAME" | | ||
164 | sed "s/'/'\\\\''/; s/=\(.*\)/='\1'/" | ||
165 | )" | ||
166 | |||
167 | CDROM_ID_FS_UUID_ENC='73256269-4002-4e42-adbd-0e49ed1c7438' | ||
168 | CDROM_ID_FS_LABEL_ENC=$(sed 's/ /\\x20/g' /lib/samizdat/vol_id.txt) | ||
169 | if [ "$ID_FS_UUID_ENC" = "$CDROM_ID_FS_UUID_ENC" -o \ | ||
170 | "$ID_FS_LABEL_ENC" = "$CDROM_ID_FS_LABEL_ENC" ] | ||
171 | then | ||
172 | # Recognize and mount the Samizdat | ||
173 | if ! mountpoint -q /cdrom; then | ||
174 | mkdir -p /cdrom | ||
175 | . mdadm-dup.sh | ||
176 | dup_mount_cdrom "$DEVNAME" /cdrom && bootdone samizdat-cdrom | ||
177 | fi | ||
178 | else | ||
179 | grok_block & | ||
180 | fi | ||
181 | |||
182 | # vim:set et sw=2: | ||