]> git.pld-linux.org Git - projects/geninitrd.git/blame - functions
Timeout here is not a good idea. rootfs cannot be mounted and kernel oopses due to...
[projects/geninitrd.git] / functions
CommitLineData
1cea325b
ER
1#!/bin/sh
2#
3# geninitrd functions
4
52c1e558
AM
5# Get device name from UUID/LABEL
6# @param string device path or UUID/LABEL name
1cea325b 7# @return false on failure
c3b4c8c8 8#
52c1e558
AM
9find_devname() {
10 local outname name="$1"
11 local function="${PROGRAM:+$PROGRAM: }find_devname"
1cea325b 12
52c1e558
AM
13 outname="$name"
14 case $name in
1cea325b
ER
15 LABEL=*)
16 if [ ! -x /sbin/blkid ]; then
17 echo >&2 "$function: /sbin/blkid is missing"
18 return 2
19 fi
20
52c1e558 21 local label=${name#"LABEL="}
10d8618c 22 local dev=$(/sbin/blkid -l -t LABEL="$label" -o device)
8bc082c8
ER
23 if [ "$dev" ]; then
24 if [ ! -r "$dev" ]; then
25 echo >&2 "$function: blkid returned device $dev which doesn't exist"
26 return 2
27 fi
52c1e558 28 outname=$dev
1cea325b
ER
29 fi
30 ;;
31
32 UUID=*)
33 if [ ! -x /sbin/blkid ]; then
34 echo >&2 "$function: /sbin/blkid is missing"
35 return 2
36 fi
37
52c1e558 38 local uuid=${name#"UUID="}
10d8618c 39 local dev=$(/sbin/blkid -l -t UUID="$uuid" -o device)
1cea325b 40
8bc082c8
ER
41 if [ "$dev" ]; then
42 if [ ! -r "$dev" ]; then
43 echo >&2 "$function: blkid returned device $dev which doesn't exist"
44 return 2
45 fi
52c1e558 46 outname=$dev
1cea325b
ER
47 fi
48 ;;
f2581979 49 esac
52c1e558
AM
50 echo $outname
51}
52
53# Find root device from fstab.
54#
55# @param string $fstab location of /etc/fstab
56# @return false on failure
57#
58# Sets global variables:
59# - $rootdev
60# - $rootdev_add
61# - $rootFS
62#
63find_root() {
64 local fstab="$1"
65 local function="${PROGRAM:+$PROGRAM: }find_root"
66 local rootopt
67
68 eval $(awk '!/^[\t ]*#/ && $2 == "/" {printf("rootdev=\"%s\"\nrootFs=\"%s\"\nrootopt=\"%s\"\n", $1, $3, $4)}' $fstab)
69 if [ -z "$rootdev" ]; then
70 echo >&2 "$function: can't find fstab entry for root mountpoint"
71 return 1
72 fi
73
74 # additional devices needed (xfs logdev)
75 rootdev_add=$(echo "$rootopt" | awk -F',' '{ for (i=1; i<=NF; i++) { if ($i ~ /^logdev=/) { gsub(/^logdev=/, NIL, $i); print $i; } } }')
f2581979 76
52c1e558 77 rootdev=$(find_devname "$rootdev")
f2581979 78 case $rootdev in
28bd482b 79 /dev/dm-*)
b6c4aab1 80 local node
d2cb46cf 81 node=$(dm_node "$rootdev") || return 1
b6c4aab1
ER
82 if [ "$node" ]; then
83 rootdev="$node"
84 fi
d348a28e 85 ;;
86 esac
b6c4aab1 87
28bd482b
AF
88 case $rootdev in
89 /dev/mapper/*)
f595ec04
AF
90 local dm_subsystem=$(dm_subsystem "$rootdev")
91 case $dm_subsystem in
92 LVM)
28bd482b
AF
93 local node
94 node=$(dm_lvm2_name "$rootdev") || return 1
95 if [ "$node" ]; then
96 rootdev="$node"
97 fi
98 return 0
99 ;;
f595ec04 100 CRYPT)
28bd482b
AF
101 return 0
102 ;;
103 esac
104 esac
105
6d2c63ed
ER
106 if [ "$rootFs" = "nfs" ]; then
107 rootdev="/dev/nfs"
108 return 0
109 fi
110
1cea325b 111 if [ ! -r "$rootdev" ]; then
dd3e4c24 112 echo >&2 "$function: rootfs device file $rootdev doesn't exist"
1cea325b
ER
113 return 1
114 fi
115
116 return 0
117}
b6c4aab1
ER
118
119# resolve /dev/dm-0 to lvm2 node
dc006e4d 120# which they got from blkid program fs was specifed as UUID= in fstab
b6c4aab1
ER
121dm_lvm2_name() {
122 local node="$1"
22cc635e 123 local dm_minor stat
e211ded9
ER
124
125 if [ ! -b "$node" ]; then
126 echo >&2 "dm_lvm2_name: $node is not a block device"
127 return 1
128 fi
129
edecd1e2
ER
130 case $node in
131 /dev/dm-*)
132 dm_minor=${node#/dev/dm-}
133 ;;
134 /dev/mapper/*)
ebd1ffc3 135 stat=$(stat -L -c %T "$node") || die "stat failed: $node"
22cc635e 136 dm_minor=$((0x$stat))
edecd1e2
ER
137 ;;
138 esac
139
8bc082c8
ER
140 local lvm_path=$(/sbin/lvdisplay -c 2>/dev/null | awk -F: -vn=$dm_minor '{node=$1; major=$12; minor=$13; if (n == minor) print node}' | xargs)
141 if [ -z "$lvm_path" ]; then
142 # XXX: this could happen also for non-lvm nodes?
a14a054a
ER
143 cat >&2 <<-EOF
144 LVM doesn't recognize device-mapper node with minor $dm_minor
145
146 In case your Physical Volumes are device mapper nodes, you should add to lvm.conf:
147 types = [ "device-mapper", 254 ]
148
149 In case the LVM nodes are not present yet, it could be fixed by running:
150 # vgscan --mknodes
151 EOF
8bc082c8
ER
152 return 2
153 fi
154 if [ ! -r "$lvm_path" ]; then
155 echo >&2 "lvdisplay returned $lvm_path which doesn't exist in filesystem; try running 'vgscan --mknodes'."
156 return 2
157 fi
18a69561 158 echo $lvm_path
b6c4aab1 159}
bc0d6f2d 160
d2cb46cf
ER
161# resolve /dev/dm-0, /dev/mapper/name
162# @return DM name
163dm_name() {
bc0d6f2d 164 local node="$1"
202b8e4c 165 dmsetup info -c --noheadings -o name $node
d2cb46cf
ER
166}
167
f595ec04 168# get subsystem name for DM node
d2cb46cf 169# node can be /dev/dm-0, /dev/mapper/name
f595ec04
AF
170# @return subsystem name
171dm_subsystem() {
7b924576
ER
172 local node="$1" out
173 out=$(dmsetup info -c --noheadings -o subsystem $node)
61ecb7f3 174 if [ $? -eq 0 -a -n "$out" ]; then
7b924576
ER
175 echo "$out"
176 return
177 fi
178
179 # for very old kernels (2.6.16), subsystem is empty, assume LVM
180 # TODO: fix this if needed to have crypt as well
181 echo "LVM"
d2cb46cf
ER
182}
183
184# resolve any dm node to it's full path in /dev/mapper
185dm_node() {
186 local node="$1"
187 printf "/dev/mapper/%s" $(dm_name "$node")
bc0d6f2d 188}
cefcd7bb 189
d967e9de 190# find modules by class
cefcd7bb
AM
191# find_modules_by_class 0106 - finds modules for SATA devices in the system
192# find_modules_by_class 0c03 - finds modules for USB controllers
193find_modules_by_class() {
c3b4c8c8 194 if modprobe --version | grep -q "^kmod"; then
d967e9de
AM
195 find_modules_by_class_kmod $@
196 else
197 find_modules_by_class_mit $@
198 fi
199}
200
201# find modules by class (kmod version)
202# find_modules_by_class 0106 - finds modules for SATA devices in the system
203# find_modules_by_class 0c03 - finds modules for USB controllers
204find_modules_by_class_kmod() {
a1548180 205 local req_class="$1" i j modaliases
cefcd7bb 206
a1548180
AM
207 if [ ! -d "/sys/devices" ]; then
208 warn "No /sys/devices/ found. Is /sys mounted?"
cefcd7bb
AM
209 return
210 fi
211
a1548180
AM
212 for i in $(grep -li "^0x${req_class}" /sys/devices/pci*/*/class); do
213 j=$(dirname $i)
214 modaliases="$modaliases $(cat $j/modalias)"
215 done
fbd21a62
AM
216
217 if [ -z "$modaliases" ]; then
218 return
219 fi
220
9fc71a60 221 echo $modaliases | xargs modprobe --set-version $kernel -aRn | awk '
909e88b4 222 BEGIN { skip_modules[notexisting_module]=""; modules[1]=""; xhci=""; ehci_pci=""; ehci_hcd=""; ehci_platform=""; ohci=""; uhci="" }
a1548180
AM
223 {
224 module=$1
225 if (module == "xhci_hcd") {
226 xhci="xhci_hcd"
909e88b4
AM
227 } else if (module == "ehci_hcd") {
228 ehci_hcd="ehci_hcd"
dc76af38
AM
229 } else if (module == "ehci_pci") {
230 ehci_pci="ehci_pci"
909e88b4
AM
231 } else if (module == "ehci_platform") {
232 ehci_platform="ehci_platform"
a1548180
AM
233 } else if (module == "ohci_hcd") {
234 ohci="ohci_hcd"
235 } else if (module == "uhci_hcd") {
236 uhci="uhci_hcd"
237 } else if (!(module in skip_modules)) {
238 modules[cnt]=module
239 }
240 skip_modules[module]=1;
241 }
242 END {
909e88b4
AM
243 # ehci/ohci/uhci/xhci hack to preserve such order
244 printf "%s %s %s %s %s %s ", ehci_hcd, ehci_pci, ehci_platform, ohci, uhci, xhci;
a1548180
AM
245 for (i in modules) { printf "%s ", modules[i]; };
246 }
a4dcea34 247 '
cefcd7bb 248}
d967e9de
AM
249
250# find modules by class (module-init-tools version)
251# find_modules_by_class 0106 - finds modules for SATA devices in the system
252# find_modules_by_class 0c03 - finds modules for USB controllers
253find_modules_by_class_mit() {
a8e24440 254 local req_class="$1" pcimap lspci
d967e9de
AM
255
256 pcimap="/lib/modules/$kernel/modules.pcimap"
257
258 lspci=$(find_tool /sbin/lspci)
259 if [ ! -x "$lspci" ]; then
260 warn "Failed to execute lspci. Is pciutils package installed?"
261 fi
262
263 # no pcimap, nothing to lookup from
264 if [ ! -f "$pcimap" ]; then
c3b4c8c8 265 warn "No $pcimap file. Cannot find modules for desired class!"
d967e9de
AM
266 return
267 fi
268
269 if [ -z "$lspci" ]; then
270 return
271 fi
272
273 LC_ALL=C lspci -p "$pcimap" -kvmmn | awk -vreq_class="${req_class}" '
909e88b4 274 BEGIN { skip_modules[notexisting_module]=""; modules[1]=""; xhci=""; ehci_pci=""; ehci_hcd=""; ehci_platform=""; ohci=""; uhci="" }
c3b4c8c8
ER
275 /^Slot:/ { found=0 }
276 /^Class:/ { if (req_class == $2) { found = 1 } }
277 /^Driver:/ { if (found) {
278 module = $2;
279 if (module == "xhci_hcd") {
280 xhci = "xhci_hcd"
909e88b4
AM
281 } else if (module == "ehci_hcd") {
282 ehci_hcd = "ehci_hcd"
dc76af38
AM
283 } else if (module == "ehci_pci") {
284 ehci_pci="ehci_pci"
909e88b4
AM
285 } else if (module == "ehci_platform") {
286 ehci_platform="ehci_platform"
c3b4c8c8
ER
287 } else if (module == "ohci_hcd") {
288 ohci = "ohci_hcd"
289 } else if (module == "uhci_hcd") {
290 uhci = "uhci_hcd"
291 } else if (!(module in skip_modules)) {
292 modules[cnt] = module
293 }
294 skip_modules[module] = 1;
295 }
296 found=0
297 }
298 END {
909e88b4
AM
299 # ehci/ohci/uhci/xhci hack to preserve such order
300 printf "%s %s %s %s %s %s ", ehci_hcd, ehci_pci, ehci_platform, ohci, uhci, xhci;
c3b4c8c8
ER
301 for (i in modules) { printf "%s ", modules[i]; }
302 }
d967e9de
AM
303 '
304}
305
54c9f5ee
AM
306# get possible paths for specifed patter containing LIBDIR
307get_libdir() {
308 for dir in lib lib64 libx32; do
309 echo -n "${1/LIBDIR/$dir} "
310 done
311}
This page took 1.830881 seconds and 4 git commands to generate.