Adding live-initramfs 1.87.2-1.
[live-boot-grml.git] / scripts / live-helpers
1 ## Casper helper functions, used by casper on boot and by casper-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 setup_loop() {
112     local fspath=$1
113     local module=$2
114     local pattern=$3
115     local offset=$4
116
117     modprobe ${MP_QUIET} -b "$module"
118     udevsettle
119
120     for loopdev in $pattern; do
121         if [ "$(cat $loopdev/size)" -eq 0 ]; then
122             dev=$(sys2dev "${loopdev}")
123             if [ -n "$offset" ]; then
124                 losetup -o "$offset" "$dev" "$fspath"
125             else
126                 losetup "$dev" "$fspath"
127             fi
128             echo "$dev"
129             return 0
130         fi
131     done
132     panic "No loop devices available"
133 }
134
135 try_mount ()
136 {
137     dev="${1}"
138     mountp="${2}"
139     opts="${3}"
140
141     if where_is_mounted ${dev} > /dev/null; then
142         mount -o remount,"${opts}" ${dev} $(where_is_mounted ${dev}) || panic "Remounting failed"
143         mount -o bind $(where_is_mounted ${dev}) ${mountp} || panic "Cannot bind-mount"
144     else
145         mount -t $(get_fstype "${dev}") -o "${opts}" "${dev}" "${mountp}" || panic "Cannot mount ${dev} on ${mountp}"
146     fi
147 }
148
149 find_cow_device() {
150     pers_label="${1}"
151     cow_backing="/${pers_label}-backing"
152     for sysblock in $(echo /sys/block/* | tr ' ' '\n' | grep -v loop); do
153         for dev in $(subdevices "${sysblock}"); do
154             devname=$(sys2dev "${dev}")
155             if [ "$(/lib/udev/vol_id -l $devname 2>/dev/null)" = "${pers_label}" ]; then
156                 echo "$devname"
157                 return
158             elif [ "$(get_fstype ${devname})" = "vfat" ]; then # FIXME: all supported block devices should be scanned
159                 mkdir -p "${cow_backing}"
160                 try_mount "${devname}" "${cow_backing}" "rw"
161                 if [ -e "${cow_backing}/${pers_label}" ]; then
162                     echo $(setup_loop "${cow_backing}/${pers_label}" "loop" "/sys/block/loop*")
163                     return 0
164                 else
165                     umount ${cow_backing}
166                 fi
167             fi
168         done
169     done
170 }
171
172 find_files()
173 # return the first of $filenames found on vfat and ext2 devices
174 # FIXME: merge with above function
175 {
176     filenames="${1}"
177     snap_backing="/snap-backing"
178     for sysblock in $(echo /sys/block/* | tr ' ' '\n' | grep -v loop); do
179         for dev in $(subdevices "${sysblock}"); do
180             devname=$(sys2dev "${dev}")
181             devfstype="$(get_fstype ${devname})"
182             if [ "${devfstype}" = "vfat" ] ||  [ "${devfstype}" = "ext2" ] ; then # FIXME: all supported block devices should be scanned
183                 mkdir -p "${snap_backing}"
184                 try_mount "${devname}" "${snap_backing}" "ro"
185                 for filename in ${filenames}; do
186                     if [ -e "${snap_backing}/${filename}" ]; then
187                         echo "${devname} ${snap_backing} ${filename}"
188                         return 0
189                     fi
190                 done
191                 umount ${snap_backing}
192             fi
193         done
194     done
195 }
196
197