-
Notifications
You must be signed in to change notification settings - Fork 0
/
trivialfs_locate
executable file
·125 lines (122 loc) · 2.74 KB
/
trivialfs_locate
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
#! /bin/sh
HDR_KEY=TrivialFS
HDR_VAL=80a29844-f5e3-11e3-b1c1-b827eb896db5
# Accepts a UUID as argument and scans for a block device containing a
# TrivialFS with a matching "UUID="-line. Option -n includes NBD devices. If
# the -i option is specified, no block devices are searched for automatically,
# and instead a list of block devices or image files is read from standard
# input. If successful, the path to the first image file or block device
# containing the requested UUID is written to standard output.
#
# trivialfs_volume version 15.313
#
# (c) 2014 - 2015 by Guenther Brunthaler.
# This script is free software.
# Distribution is permitted under the terms of the GPLv3.
cleanup() {
rc=$?
for t in "$T" "$T2"
do
test -n "$t" && rm -- "$t"
done
test $rc = 0 || echo "${0##*/} failed!" >& 2
}
set -e
T=; T2=
trap cleanup 0
TARGET_UUID=
LOCATE_NBDs=
LOCATE_NOTHING=
shell=sh
while getopts nis: OPT
do
case $OPT in
s) shell=$OPTARG;;
n) LOCATE_NBDs=y;;
i) LOCATE_NOTHING=y;;
*) fail
esac
done
shift `expr $OPTIND - 1 || :`
test $# != 0 && { TARGET_UUID=$1; shift; }
test $# = 0
test -n "$TARGET_UUID"
tempfile() {
mktemp -- "${TMPDIR:-/tmp}/${0##*/}".XXXXXXXXXX
}
T=`tempfile`; T2=`tempfile`
if test -z "$LOCATE_NOTHING"
then
test -f "$0"
dir=/sys/block
ls -1 -- "$dir" 2> /dev/null | while IFS= read -r dev
do
order=1
case $dev in
nbd*)
test -n "$LOCATE_NBDs" || continue
order=2
esac
devp=$dir/$dev
di=$devp/dev
test -f "$di" || continue
echo $order
cat -- "$di"
ls -1d "$devp/$dev"* 2> /dev/null \
| while IFS= read -r dev
do
di=$dev/dev
test -f "$di" || continue
echo $order
cat -- "$di"
done
done | while read order
do
read dev
echo $dev $order
done | LC_ALL=C sort -k1 > "$T"
find -L /dev/ -type b 2> /dev/null | while IFS= read -r dev
do
case $dev in
/dev/vg*/*) order=1;;
/dev/mapper/*) order=2;;
*) order=3
esac
majmin=`stat -Lc '%t:%T' "$dev"`
maj=${majmin%%:*}; min=${majmin#$maj:}
maj=`printf %d 0x$maj`; min=`printf %d 0x$min`
len=`printf %s: "$dev" | wc -c`
echo "$maj $min $order $len $dev"
done | sort -nk1,4 | {
last=
while read -r maj min dummy dummy dev
do
this=$maj:$min
test x"$this" = x"$last" && continue
echo "$this $dev"
last=$this
done
} | LC_ALL=C sort -k1 > "$T2"
LC_ALL=C join -- "$T" "$T2" | while IFS=: read head tail
do
echo "$head $tail"
done | sort -n -k3 -k1 -k2 | cut -d" " -f4- \
| "$shell" "$0" -i "$TARGET_UUID"
exit
fi
test -z "$LOCATE_NBDs"
cat << EOF > "$T2"
$HDR_KEY=$HDR_VAL
COMPATIBLE_VERSION=3
UUID=$TARGET_UUID
EOF
size=`stat -c %s "$T2"`
test -n "$size"
while IFS= read -r dev
do
dd if="$dev" of="$T" bs=$size count=1 2> /dev/null || continue
cmp -s "$T" "$T2" || continue
printf '%s\n' "$dev"
exit
done
false