Removing ubuntu support.
[live-boot-grml.git] / scripts / live-helpers
1 #!/bin/sh
2 # live-initramfs helper functions, used by live-initramfs on boot and by live-snapshot
3
4 if [ ! -x "/bin/fstype" ]
5 then
6         # klibc not in path -> not in initramfs
7         export PATH="${PATH}:/usr/lib/klibc/bin"
8 fi
9
10 sys2dev ()
11 {
12         sysdev=${1#/sys}
13         echo "/dev/$(udevinfo -q name -p ${sysdev} 2>/dev/null|| echo ${sysdev##*/})"
14 }
15
16 subdevices ()
17 {
18         sysblock=${1}
19         r=""
20
21         for dev in "${sysblock}" "${sysblock}"/*
22         do
23                 if [ -e "${dev}/dev" ]
24                 then
25                         r="${r} ${dev}"
26                 fi
27         done
28
29         echo ${r}
30 }
31
32 get_fstype ()
33 {
34         local FSTYPE
35         local FSSIZE
36
37         eval $(fstype < ${1})
38
39         if [ "${FSTYPE}" != "unknown" ]
40         then
41                 echo ${FSTYPE}
42                 return 0
43         fi
44
45         /lib/udev/vol_id -t ${1} 2>/dev/null
46 }
47
48 where_is_mounted ()
49 {
50         device=${1}
51
52         if grep -q "^${device} " /proc/mounts
53         then
54                 grep "^${device} " /proc/mounts | read d mountpoint rest
55                 echo ${mountpoint}
56                 return 0
57         fi
58
59         return 1
60 }
61
62 lastline ()
63 {
64         while read lines
65         do
66                 line=${lines}
67         done
68
69         echo "${line}"
70 }
71
72 base_path ()
73 {
74         testpath="${1}"
75         mounts="$(awk '{print $2}' /proc/mounts)"
76         testpath="$(busybox realpath ${testpath})"
77
78         while true
79         do
80                 if echo "${mounts}" | grep -qs "^${testpath}"
81                 then
82                         set -- $(echo "${mounts}" | grep "^${testpath}" | lastline)
83                         echo ${1}
84                         break
85                 else
86                         testpath=$(dirname $testpath)
87                 fi
88         done
89 }
90
91 fs_size ()
92 {
93         # Returns used/free fs kbytes + 5% more
94         # You could pass a block device as ${1} or the mount point as ${2}
95
96         dev="${1}"
97         mountp="${2}"
98         used="${3}"
99
100         if [ -z "${mountp}" ]
101         then
102                 mountp=$(where_is_mounted "${dev}")
103
104                 if [ "${?}" -gt 0 ]
105                 then
106                         mountp="/mnt/tmp_fs_size"
107
108                         mkdir -p "${mountp}"
109                         mount -t $(get_fstype "${dev}") -o ro "${dev}" "${mountp}"
110
111                         doumount=1
112                 fi
113         fi
114
115         if [ "${used}" = "used" ]
116         then
117                 size=$(du -ks ${mountp} | cut -f1)
118                 size=$(expr ${size} + ${size} / 20 ) # FIXME: 5% more to be sure
119         else
120                 # free space
121                 size="$(df -k | grep -s ${mountp} | awk '{print $4}')"
122         fi
123
124         if [ -n "${doumount}" ]
125         then
126                 umount "${mountp}"
127                 rmdir "${mountp}"
128         fi
129
130         echo "${size}"
131 }
132
133 load_keymap ()
134 {
135         # Load custom keymap
136         if [ -x /bin/loadkeys -a -r /etc/boottime.kmap.gz ]
137         then
138                 loadkeys /etc/boottime.kmap.gz
139         fi
140 }
141
142 setup_loop ()
143 {
144         local fspath=${1}
145         local module=${2}
146         local pattern=${3}
147         local offset=${4}
148         local encryption=${5}
149
150         modprobe -q -b "${module}"
151         udevsettle
152
153         for loopdev in ${pattern}
154         do
155                 if [ "$(cat ${loopdev}/size)" -eq 0 ]
156                 then
157                         dev=$(sys2dev "${loopdev}")
158                         options=''
159
160                         if [ 0 -lt "${offset}" ]
161                         then
162                                 options="${options} -o ${offset}"
163                         fi
164
165                         if [ -z "${encryption}" ]
166                         then
167                                 losetup ${options} "${dev}" "${fspath}"
168                         else
169                                 # Loop AES encryption
170                                 while true
171                                 do
172                                         load_keymap
173
174                                         echo -n "Enter passphrase for ${fspath}: " >&6
175                                         read -s passphrase
176                                         echo "${passphrase}" > /tmp/passphrase
177                                         exec 9</tmp/passphrase
178                                         /sbin/losetup ${options} -e "${encryption}" -p 9 "${dev}" "${fspath}"
179                                         error=${?}
180                                         exec 9<&-
181                                         rm -f /tmp/passphrase
182
183                                         if [ 0 -eq ${error} ]
184                                         then
185                                                 unset error
186                                                 break
187                                         fi
188
189                                         echo -n "Something went wrong... Retry? [YES/no] " >&6
190                                         read answer
191
192                                         if [ 'no' = "${answer}" ]
193                                         then
194                                                 unset answer
195                                                 break
196                                         fi
197                                 done
198                         fi
199
200                         echo "${dev}"
201                         return 0
202                 fi
203         done
204
205         panic "No loop devices available"
206 }
207
208 try_mount ()
209 {
210         dev="${1}"
211         mountp="${2}"
212         opts="${3}"
213
214         if where_is_mounted ${dev} > /dev/null
215         then
216                 mount -o remount,"${opts}" ${dev} $(where_is_mounted ${dev}) || panic "Remounting failed"
217                 mount -o bind $(where_is_mounted ${dev}) ${mountp} || panic "Cannot bind-mount"
218         else
219                 mount -t $(get_fstype "${dev}") -o "${opts}" "${dev}" "${mountp}" || panic "Cannot mount ${dev} on ${mountp}"
220         fi
221 }
222
223 find_cow_device ()
224 {
225         pers_label="${1}"
226         cow_backing="/${pers_label}-backing"
227
228         for sysblock in $(echo /sys/block/* | tr ' ' '\n' | grep -v loop)
229         do
230                 for dev in $(subdevices "${sysblock}")
231                 do
232                         devname=$(sys2dev "${dev}")
233
234                         if [ "$(/lib/udev/vol_id -l ${devname} 2>/dev/null)" = "${pers_label}" ]
235                         then
236                                 echo "${devname}"
237                                 return
238                         elif [ "$(get_fstype ${devname})" = "vfat" ]
239                         then
240                                 # FIXME: all supported block devices should be scanned
241                                 mkdir -p "${cow_backing}"
242                                 try_mount "${devname}" "${cow_backing}" "rw"
243
244                                 if [ -e "${cow_backing}/${pers_label}" ]
245                                 then
246                                         echo $(setup_loop "${cow_backing}/${pers_label}" "loop" "/sys/block/loop*")
247                                         return 0
248                                 else
249                                         umount ${cow_backing}
250                                 fi
251                         fi
252                 done
253         done
254 }
255
256 find_files ()
257 {
258         # return the first of ${filenames} found on vfat and ext2/ext3 devices
259         # FIXME: merge with above function
260
261         filenames="${1}"
262         snap_backing="/snap-backing"
263
264         for sysblock in $(echo /sys/block/* | tr ' ' '\n' | grep -v loop)
265         do
266                 for dev in $(subdevices "${sysblock}")
267                 do
268                         devname=$(sys2dev "${dev}")
269                         devfstype="$(get_fstype ${devname})"
270
271                         if [ "${devfstype}" = "vfat" ] ||  [ "${devfstype}" = "ext2" ] || [ "${devfstype}" = "ext3" ]
272                         then
273                                 # FIXME: all supported block devices should be scanned
274                                 mkdir -p "${snap_backing}"
275                                 try_mount "${devname}" "${snap_backing}" "ro"
276
277                                 for filename in ${filenames}
278                                 do
279                                         if [ -e "${snap_backing}/${filename}" ]
280                                         then
281                                                 echo "${devname} ${snap_backing} ${filename}"
282                                                 return 0
283                                         fi
284                                 done
285
286                                 umount ${snap_backing}
287                         fi
288                 done
289         done
290 }