Modificirano da ne briĊĦe konfiguraciju
[kernel-cn.git] / grub-functions.sh
1 #!/bin/bash
2 #
3 # Insert a list of installed kernels in a grub config file
4 #   Copyright 2001 Wichert Akkerman <wichert@linux.com>
5 #
6 # This file is free software; you can redistribute it and/or modify it
7 # under the terms of the GNU General Public License as published by
8 # the Free Software Foundation; either version 2 of the License, or
9 # (at your option) any later version.
10 #
11 # This program is distributed in the hope that it will be useful, but
12 # WITHOUT ANY WARRANTY; without even the implied warranty of
13 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14 # General Public License for more details.
15 #
16 # You should have received a copy of the GNU General Public License
17 # along with this program; if not, write to the Free Software
18 # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
19 #
20 # Contributors:
21 #       Jason Thomas <jason@debian.org>
22 #       David B.Harris <dbarclay10@yahoo.ca>
23 #       Marc Haber <mh@zugschlus.de>
24 #       Crispin Flowerday <crispin@zeus.com>
25
26 # Abort on errors
27 set -e
28
29 host_os=`uname -s | tr '[A-Z]' '[a-z]'`
30
31 find_grub_dir ()
32 {
33         for d in $grub_dirs ; do
34                 if [ -d "$d" ] ; then
35                         grub_dir="$d"
36                         break
37                 fi
38         done
39         
40         if [ -z "$grub_dir" ] ; then
41         grub_dir="/boot/grub"
42         fi
43
44         echo $grub_dir
45 }
46
47 find_device ()
48 {
49         mount_point=$1
50
51         # Autodetect current root device
52         device=
53         if [ -f /etc/fstab ] ; then
54                 while read DEV MNT FOO; do
55                         if `echo "$DEV" | grep -q "^#"`; then
56                                 continue
57                         fi
58                         if [ "$MNT" = "$mount_point" ]; then
59                                 device="$DEV";
60                         fi
61                 done < /etc/fstab
62         fi
63
64         if [ -n "$device" ] ; then
65                 case "$device" in
66                         LABEL=* | UUID=*)
67                                 device=`readlink -f "$(findfs $device)"`
68                         ;;
69                         *)
70                                 device=`readlink -f "$device"`
71                         ;;
72                 esac
73         fi
74
75         echo $device
76 }
77
78 find_device_nonresolved ()
79 {
80         mount_point=$1
81
82         # Autodetect current root device
83         device=
84         if [ -f /etc/fstab ] ; then
85                 while read DEV MNT FOO; do
86                         if `echo "$DEV" | grep -q "^#"`; then
87                                 continue
88                         fi
89                         if [ "$MNT" = "$mount_point" ]; then
90                                 device="$DEV";
91                         fi
92                 done < /etc/fstab
93         fi
94
95         if [ -n "$device" ] ; then
96                 case "$device" in
97                         LABEL=* | UUID=*)
98                                 device=`findfs $device`
99                         ;;
100                 esac
101         fi
102
103         echo $device
104 }
105
106 find_root_device ()
107 {
108         device=$(find_device "/")
109
110         if [ -z "$device" ]; then
111                 echo "Cannot determine root device.  Assuming /dev/hda1" >&2
112                 echo "This error is probably caused by an invalid /etc/fstab" >&2
113                 device=/dev/hda1
114         fi
115
116         echo $device
117 }
118
119 # Usage: convert_raid1 os_device
120 # Checks if os_device is a software raid1.
121 # If so, converts to first physical device in array.
122 convert_raid1 ()
123 {
124     case $1 in
125         /dev/md[0-9])
126             : ;; # Continue
127         *)
128             return 1 ;;
129     esac
130
131     [ -x /sbin/mdadm ] || return 1
132
133     # Check that the raid device is raid1
134     raidlevel=$(mdadm -D -b $1 | grep "^ARRAY" | \
135             sed "s/^.*level=//" | cut -d" " -f1)
136     [ "$raidlevel" = "raid1" ] || return 1
137     
138     # Take only the first device that makes up the raid
139     raiddev=$(mdadm -D $1 | grep -A1 "Number" | grep "dev" \
140                           | sed "s/^.*\(\/dev\/.*\)$/\1/")
141     [ -n "$raiddev" ] || return 1
142
143     echo $raiddev
144     return 0
145 }
146
147 # Usage: convert os_device
148 # Convert an OS device to the corresponding GRUB drive.
149 # This part is OS-specific.
150 convert () {
151     # First, check if the device file exists.
152     if test -e "$1"; then
153                 :
154     else
155                 echo "$1: Not found or not a block device." 1>&2
156                 exit 1
157     fi
158
159         host_os=`uname -s | tr '[[:upper:]]' '[[:lower:]]'`
160
161     # Break the device name into the disk part and the partition part.
162     case "$host_os" in
163     linux)
164                 tmp_disk=`echo "$1" | sed -e 's%\([sh]d[[:lower:]]\)[0-9]*$%\1%' \
165                                   -e 's%\(fd[0-9]*\)$%\1%' \
166                                   -e 's%/part[0-9]*$%/disc%' \
167                                   -e 's%\(c[0-7]d[0-9]*\).*$%\1%'`
168                 tmp_part=`echo "$1" | sed -e 's%.*/[sh]d[[:lower:]]\([0-9]*\)$%\1%' \
169                                   -e 's%.*/fd[0-9]*$%%' \
170                                   -e 's%.*/floppy/[0-9]*$%%' \
171                                   -e 's%.*/\(disc\|part\([0-9]*\)\)$%\2%' \
172                                   -e 's%.*c[0-7]d[0-9]*p*%%'`
173         ;;
174     gnu)
175                 tmp_disk=`echo "$1" | sed 's%\([sh]d[0-9]*\).*%\1%'`
176                 tmp_part=`echo "$1" | sed "s%$tmp_disk%%"` ;;
177     freebsd|*/kfreebsd)
178                 tmp_disk=`echo "$1" | sed 's%r\{0,1\}\([saw]d[0-9]*\).*$%\1%' \
179                             | sed 's%r\{0,1\}\(da[0-9]*\).*$%\1%'`
180                 tmp_part=`echo "$1" \
181                         | sed "s%.*/r\{0,1\}[saw]d[0-9]\(s[0-9]*[a-h]\)%\1%" \
182                 | sed "s%.*/r\{0,1\}da[0-9]\(s[0-9]*[a-h]\)%\1%"`
183         ;;
184     netbsd|*/knetbsd)
185                 tmp_disk=`echo "$1" | sed 's%r\{0,1\}\([sw]d[0-9]*\).*$%r\1d%' \
186                         | sed 's%r\{0,1\}\(fd[0-9]*\).*$%r\1a%'`
187                 tmp_part=`echo "$1" \
188                         | sed "s%.*/r\{0,1\}[sw]d[0-9]\([abe-p]\)%\1%"`
189         ;;
190     *)
191                 echo "update-grub does not support your OS yet." 1>&2
192                 exit 1 ;;
193     esac
194
195     # Get the drive name.
196     tmp_drive=`grep -v '^#' $device_map | grep "$tmp_disk *$" \
197                         | sed 's%.*\(([hf]d[0-9][a-z0-9,]*)\).*%\1%'`
198
199     # If not found, print an error message and exit.
200     if test "x$tmp_drive" = x; then
201                 echo "$1 does not have any corresponding BIOS drive." 1>&2
202                 exit 1
203     fi
204
205     if test "x$tmp_part" != x; then
206                 # If a partition is specified, we need to translate it into the
207                 # GRUB's syntax.
208                 case "$host_os" in
209                 linux)
210                   echo "$tmp_drive" | sed "s%)$%,`expr $tmp_part - 1`)%" ;;
211                 gnu)
212                   if echo $tmp_part | grep "^s" >/dev/null; then
213                                 tmp_pc_slice=`echo $tmp_part \
214                                 | sed "s%s\([0-9]*\)[a-z]*$%\1%"`
215                                 tmp_drive=`echo "$tmp_drive" \
216                                 | sed "s%)%,\`expr "$tmp_pc_slice" - 1\`)%"`
217                   fi
218                   if echo $tmp_part | grep "[a-z]$" >/dev/null; then
219                                 tmp_bsd_partition=`echo "$tmp_part" \
220                                 | sed "s%[^a-z]*\([a-z]\)$%\1%"`
221                                 tmp_drive=`echo "$tmp_drive" \
222                                 | sed "s%)%,$tmp_bsd_partition)%"`
223                   fi
224                   echo "$tmp_drive" ;;
225                 freebsd|*/kfreebsd)
226                   if echo $tmp_part | grep "^s" >/dev/null; then
227                                 tmp_pc_slice=`echo $tmp_part \
228                                 | sed "s%s\([0-9]*\)[a-h]*$%\1%"`
229                                 tmp_drive=`echo "$tmp_drive" \
230                                 | sed "s%)%,\`expr "$tmp_pc_slice" - 1\`)%"`
231                   fi
232                   if echo $tmp_part | grep "[a-h]$" >/dev/null; then
233                                 tmp_bsd_partition=`echo "$tmp_part" \
234                                 | sed "s%s\{0,1\}[0-9]*\([a-h]\)$%\1%"`
235                                 tmp_drive=`echo "$tmp_drive" \
236                                 | sed "s%)%,$tmp_bsd_partition)%"`
237                   fi
238                   echo "$tmp_drive" ;;
239                 netbsd|*/knetbsd)
240                   if echo $tmp_part | grep "^[abe-p]$" >/dev/null; then
241                                 tmp_bsd_partition=`echo "$tmp_part" \
242                                 | sed "s%\([a-p]\)$%\1%"`
243                                 tmp_drive=`echo "$tmp_drive" \
244                                 | sed "s%)%,$tmp_bsd_partition)%"`
245                   fi
246                   echo "$tmp_drive" ;;
247                 esac
248     else
249                 # If no partition is specified, just print the drive name.
250                 echo "$tmp_drive"
251     fi
252 }
253
254 # Usage: convert_default os_device
255 # Convert an OS device to the corresponding GRUB drive.
256 # Calls OS-specific convert, and returns a default of
257 # (hd0,0) if anything goes wrong
258 convert_default () {
259         # Check if device is software raid1 array
260         if tmp_dev=$(convert_raid1 $1 2>/dev/null) ; then
261                 : # Use device returned by convert_raid1
262         else
263                 tmp_dev=$1
264         fi
265
266         if tmp=$(convert $tmp_dev 2>/dev/null) ; then
267                 echo $tmp
268         else
269                 echo "(hd0,0)"
270         fi
271 }
272
273 # Usage: resolve_symlink file
274 # Find the real file/device that file points at
275 resolve_symlink () {
276         tmp_fname=$1
277         # Resolve symlinks
278         while test -L $tmp_fname; do
279                 tmp_new_fname=`ls -al $tmp_fname | sed -n 's%.*-> \(.*\)%\1%p'`
280                 if test -z "$tmp_new_fname"; then
281                         echo "Unrecognized ls output" 2>&1
282                         exit 1
283                 fi
284
285                 # Convert relative symlinks
286                 case $tmp_new_fname in
287                         /*) tmp_fname="$tmp_new_fname"
288                         ;;
289                         *) tmp_fname="`echo $tmp_fname | sed 's%/[^/]*$%%'`/$tmp_new_fname"
290                         ;;
291                 esac
292         done
293         echo "$tmp_fname"
294 }
295
296 ## Configuration Options
297 # directory's to look for the grub installation and the menu file
298 grub_dirs="/boot/grub /boot/boot/grub"
299
300 # The grub installation directory
301 grub_dir=$(find_grub_dir)
302
303 # Full path to the menu.lst
304 menu_file_basename=menu.lst
305 menu_file=$grub_dir/$menu_file_basename
306
307 # Full path to the default file
308 default_file_basename=default
309 default_file=$grub_dir/$default_file_basename
310
311 # the device for the / filesystem
312 root_device=$(find_root_device)
313
314 # the device for the /boot filesystem
315 boot_device=$(find_device "/boot")
316
317 # Full path to the device.map
318 device_map=$grub_dir/device.map
319
320 # Default kernel options, overidden by the kopt statement in the menufile.
321 kopt="root=$root_device ro"
322
323 # Title
324 title="Debian GNU/`uname -s | sed -e s,GNU/,,g`"
325
326 # should update-grub remember the default entry
327 updatedefaultentry="false"
328
329 # Drive(in GRUB terms) where the kernel is located. Overridden by the
330 # kopt statement in menufile.
331 # if we don't have a device.map then we can't use the convert function.
332 if test -f "$device_map" ; then
333         if test -z "$boot_device" ; then
334                 grub_root_device=$(convert_default "$root_device")
335         else
336                 grub_root_device=$(convert_default "$boot_device")
337         fi
338 else
339         grub_root_device="(hd0,0)"
340 fi