]> git.pld-linux.org Git - projects/geninitrd.git/blob - mod-md.sh
Timeout here is not a good idea. rootfs cannot be mounted and kernel oopses due to...
[projects/geninitrd.git] / mod-md.sh
1 #!/bin/sh
2 # geninitrd mod: mdadm
3 USE_MD=${USE_MD:-yes}
4
5 # if we should init md (softraid) at boot
6 have_md=no
7
8 # setup geninitrd module
9 # @access       public
10 setup_mod_md() {
11         mdadm=$(find_tool /sbin/mdadm $initrd_dir/mdadm /sbin/initrd-mdadm)
12         if [ ! -x "$mdadm" ]; then
13                 USE_MD=no
14         fi
15 }
16
17 # return true if mdadm is set on $devpath
18 # @param        string $devpath device node to be examined
19 # @access       public
20 is_md() {
21         local devpath="$1"
22
23         # mdadm disabled
24         if ! is_yes "$USE_MD"; then
25                 return 1
26         fi
27
28         if [[ "$devpath" == /dev/md* ]]; then
29                 return 0
30         fi
31
32         return 1
33 }
34
35 # find md modules for $devpath
36 # @param        $devpath        device to be examined
37 # @return       false if $devpath is not on md
38 # @access       public
39 find_modules_md() {
40         local found raidlevel
41
42         if [ -f /etc/mdadm.conf ]; then
43                 verbose "Finding RAID details using mdadm for rootdev=$1"
44                 eval `($mdadm -v --examine --scan --config=/etc/mdadm.conf 2> /dev/null;$mdadm -v --detail --scan --config=/etc/mdadm.conf 2> /dev/null) | awk -v rootdev="$1" '
45                 BEGIN {
46                         found = "no";
47                         dev_list = "";
48                         raidlevel = ""
49                         rootdev_new = rootdev
50                         rootdev_alias = rootdev;
51                         # alternative name: normalize from /dev/md/X to /dev/mdX
52                         if (rootdev_alias ~ /\/dev\/md\/[0-9]+/) {
53                                 gsub(/\/dev\/md\//,"/dev/md",rootdev_alias);
54                         }
55                         # alternative name: normalize from /dev/mdXpY to /dev/mdX
56                         if (rootdev_alias ~/\/dev\/md[0-9]+p[0-9]+/) {
57                                 gsub(/p[0-9]+/,"",rootdev_alias);
58                         }
59                 }
60
61                 /^ARRAY/ {
62                         arr_device = $2
63                         # normalize to /dev/mdX form
64                         if (arr_device ~ /\/dev\/md\/[0-9]+/) {
65                                 gsub(/\/dev\/md\//,"/dev/md",arr_device);
66                         }
67                         if ((arr_device == rootdev) || (arr_device == rootdev_alias)) {
68                                 raidlevel=$3;
69                                 rootdev_new=arr_device
70                                 gsub(/level=/,NUL,raidlevel);
71                                 if (raidlevel ~ /^raid([0-6]|10)/) {
72                                         gsub(/raid/,NUL,raidlevel);
73                                 };
74                                 found="yes";
75                                 getline x;
76                                 if (x ~ /devices=/) {
77                                         dev_list = x;
78                                         gsub(".*devices=", NUL, dev_list);
79                                         gsub(",", " ", dev_list);
80                                 }
81                         }
82                 }
83
84                 END {
85                         print "rootdev_new=" rootdev_new;
86                         print "have_md=" found;
87                         print "raidlevel=" raidlevel;
88                         print "dev_list=\"" dev_list "\"";
89                 }'`
90         fi
91
92         if [ "$have_md" != "yes" -a -f /etc/raidtab ]; then
93                 die "raidtools are not longer supported. Please migrate to mdadm setup!"
94         fi
95
96         if is_yes "$have_md"; then
97                 case "$raidlevel" in
98                 [01]|10)
99                         find_module "raid$raidlevel"
100                         ;;
101                 [456])
102                         find_module "-raid$raidlevel"
103                         find_module "-raid456"
104                         ;;
105                 linear)
106                         find_module "linear"
107                         ;;
108                 *)
109                         warn "raid level $number (in mdadm config) not recognized"
110                         ;;
111                 esac
112         else
113                 die "RAID devices not found for \"$1\", check your configuration!"
114         fi
115
116         verbose "md: found rootdev=$1 on device $rootdev_new with devices list ${dev_list}"
117
118         rootdev_nr=$(( $rootdev_nr + 1 ))
119         eval "rootdev${rootdev_nr}=\"$rootdev_new\""
120         eval "dev_list${rootdev_nr}=\"${dev_list}\""
121
122         for device in $dev_list; do
123                 find_modules_for_devpath $device
124         done
125 }
126
127
128 # generate initrd fragment for md
129 # @access       public
130 initrd_gen_md() {
131         if ! is_yes "$have_md"; then
132                 return
133         fi
134         verbose "Setting up mdadm..."
135
136         inst_exec $mdadm /sbin/mdadm
137
138         echo "DEVICE partitions containers" >> "$DESTDIR/etc/mdadm.conf"
139
140         # LVM on RAID case
141         local dev_list_extra ex_dev
142         dev_list_extra=$(awk '/^DEVICE / { for (i=2; i<=NF; i++) { printf "%s ", $i; }; } ' /etc/mdadm.conf | xargs)
143         new_dev_list_extra=""
144         for ex_dev in $dev_list_extra; do
145                 if [ "$ex_dev" = "partitions" -o "$ex_dev" = "containers" ]; then
146                         echo "DEVICE $ex_dev" >> "$DESTDIR/etc/mdadm.conf"
147                         # FIXME: find and copy partition devices from /proc/partitions
148                         #        - best if done at runtime, now initrd gen time
149                         continue
150                 fi
151                 echo "DEVICE $ex_dev" >> "$DESTDIR/etc/mdadm.conf"
152                 new_dev_list_extra="$new_dev_list_extra $ex_dev"
153         done
154         dev_list_extra=$new_dev_list_extra
155
156         local cr_rootdev cr_dev_list do_md0=1 nr cr_dev_list_md f cr_md_conf
157         for nr in `seq 1 $rootdev_nr`; do
158                 eval cr_rootdev="\$rootdev${nr}"
159                 eval cr_dev_list="\$dev_list${nr}"
160                 verbose "Setting up array ($cr_rootdev = $cr_dev_list)"
161
162                 [ "$cr_rootdev" = "/dev/md0" ] && do_md0=0
163
164                 echo "DEVICE $cr_dev_list" >> "$DESTDIR/etc/mdadm.conf"
165                 cr_dev_list_md="$(echo "$cr_dev_list" | xargs | awk ' { gsub(/ +/,",",$0); print $0; }')"
166                 cr_md_conf=$($mdadm --detail --brief --config=/etc/mdadm.conf $cr_rootdev | awk ' { gsub(/spares=[0-9]+/, "", $0); print $0; }')
167                 if [ -n "$cr_md_conf" ]; then
168                         echo "$cr_md_conf" >> "$DESTDIR/etc/mdadm.conf"
169                 else
170                         echo "ARRAY $cr_rootdev devices=$cr_dev_list_md" >> "$DESTDIR/etc/mdadm.conf"
171                 fi
172
173                 for f in $cr_dev_list $cr_rootdev $dev_list_extra; do
174                         # mkdir in case of devfs name
175                         inst_d $(dirname $f)
176                         [ -e "$DESTDIR/$f" ] && continue
177                         # this works fine with and without devfs
178                         inst $f $f
179                 done
180         done
181
182         echo "wait_for_files $cr_dev_list" | add_linuxrc
183         add_linuxrc <<-'EOF'
184         /sbin/mdadm --assemble --scan
185
186         if [ "$DEBUGINITRD" ]; then
187                 [ -e /proc/mdstat ] && echo "/proc/mdstat contents:" && cat /proc/mdstat
188         fi
189         EOF
190
191         # needed to determine md-version
192         if [ "$do_md0" -eq 1 ]; then
193                 mknod -m 660 $DESTDIR/dev/md0 b 9 0
194         fi
195 }
This page took 0.369021 seconds and 3 git commands to generate.