[Top][All Lists]
[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