bug-grub
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Resolving symllinks in grub-install


From: Pavel Roskin
Subject: Re: Resolving symllinks in grub-install
Date: Sat, 9 Feb 2002 00:29:03 -0500 (EST)

On Sat, 9 Feb 2002, Yoshinori K. Okuji wrote:
> > If anybody wants, I can go one step further to include "df" into that
> > function, making it a function to determine the block device for the given
> > file.
> 
> I think that's better. There is no reason for the separation.

Done.  Actually, df is consistent in reporting the old names from
/etc/fstab, but device.map has the new names.  Also I had a chance to look
at FreeBSD 4.3 and found that "test -L" is preferred over "test -h" and
that "readlink" is missing on FreeBSD, so I used "ls" with necessary
precautions.

I also omitted "grep" from the chain after "df" - "sed" now works for
itself and for "grep".  Finally, all internal names begin with "tmp_" now.

========================
--- ChangeLog
+++ ChangeLog
@@ -1 +1,9 @@
+2002-02-09  Pavel Roskin  <address@hidden>
+
+       * util/grub-install.in (find_device): New function - find block
+       device for given file or directory.  Resolve symlinks to fix
+       problem on Linux with devfs and old device names in /etc/fstab.
+       Use find_device() for root_device, bootdir_device and
+       grubdir_device.
+
 2002-02-08  Yoshinori K. Okuji  <address@hidden>
--- util/grub-install.in
+++ util/grub-install.in
@@ -175,6 +175,35 @@
     fi
 }
 
+# Usage: find_device file
+# Find block device on which the file resides.
+find_device () {
+    # For now, this uses the program `df' to get the device name, but is
+    # this really portable?
+    tmp_fname=`df $1/ | sed -n 's%.*\(/dev/[^  ]*\).*%\1%p'`
+
+    if test -z "$tmp_fname"; then
+       echo "Could not find device for $1" 2>&1
+       exit 1
+    fi
+
+    # Resolve symlinks
+    while test -L $tmp_fname; do
+       tmp_new_fname=`ls -al /dev/hda1 | sed -n 's%.*-> *%\1%p'`
+       if test -z "$tmp_new_fname"; then
+           echo "Unrecognized ls output" 2>&1
+           exit 1
+       fi
+
+       # Convert relative symlinks
+       case $tmp_new_fname in
+           /*) tmp_fname="$tmp_new_fname" ;;
+           *) tmp_fname="`echo $tmp_fname | sed 's%/[^/]*$%%'`/$tmp_new_fname" 
;;
+       esac
+    done
+    echo "$tmp_fname"
+}
+
 # Check the arguments.
 for option in "$@"; do
     case "$option" in
@@ -308,12 +337,8 @@
 esac
 
 # Get the root drive.
-# For now, this uses the program `df' to get the device name, but is
-# this really portable?
-root_device=`df ${rootdir}/ | grep /dev/ \
-    | sed 's%.*\(/dev/[^       ]*\).*%\1%'`
-bootdir_device=`df ${bootdir} | grep /dev/ \
-    | sed 's%.*\(/dev/[^       ]*\).*%\1%'`
+root_device=`find_device ${rootdir}`
+bootdir_device=`find_device ${bootdir}`
 
 # Check if the boot directory is in the same device as the root directory.
 if test "x$root_device" != "x$bootdir_device"; then
@@ -330,8 +355,8 @@
 
 # Check if the root directory exists in the same device as the grub
 # directory.
-grubdir_device=`df ${grubdir} | grep /dev/ \
-    | sed 's%.*\(/dev/[^       ]*\).*%\1%'`
+grubdir_device=`find_device ${grubdir}`
+
 if test "x$grubdir_device" != "x$root_device"; then
     # For now, cannot deal with this situation.
     cat <<EOF 1>&2
========================

-- 
Regards,
Pavel Roskin




reply via email to

[Prev in Thread] Current Thread [Next in Thread]