summaryrefslogtreecommitdiff
path: root/src/initrd/grok-block
diff options
context:
space:
mode:
Diffstat (limited to 'src/initrd/grok-block')
-rwxr-xr-xsrc/initrd/grok-block182
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
4DEVNAME=$1
5case "$DEVNAME" in /dev/loop*|/dev/ram*|/dev/dm-*|/dev/md*|/dev/fd*) exit ;; esac
6[ -b "$DEVNAME" ] || exit
7
8debug_log "grok-block.${DEVNAME##*/}"
9
10addmenu_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
19addmenu_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
30addmenu_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
39addmenu_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
49retry_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
72gpg_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}
77is_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
85grok_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
163eval "$(PATH=$PATH:/lib/udev vol_id "$DEVNAME" |
164 sed "s/'/'\\\\''/; s/=\(.*\)/='\1'/"
165)"
166
167CDROM_ID_FS_UUID_ENC='73256269-4002-4e42-adbd-0e49ed1c7438'
168CDROM_ID_FS_LABEL_ENC=$(sed 's/ /\\x20/g' /lib/samizdat/vol_id.txt)
169if [ "$ID_FS_UUID_ENC" = "$CDROM_ID_FS_UUID_ENC" -o \
170 "$ID_FS_LABEL_ENC" = "$CDROM_ID_FS_LABEL_ENC" ]
171then
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
178else
179 grok_block &
180fi
181
182# vim:set et sw=2: