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