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