[Top][All Lists]

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

Re: [PATCH] prevent duplicated entries due to symlinks

From: Andreas Born
Subject: Re: [PATCH] prevent duplicated entries due to symlinks
Date: Tue, 05 May 2009 23:11:00 +0200
User-agent: Thunderbird (X11/20090325)

Pavel Roskin schrieb:
Suppose I have Linux 2.6.29 and 2.6.28.  Your script makes entries for
"Linux default" and "Linux 2.6.28".  Then I install Linux 2.6.30 and
don't run grub-mkconfig.  Then I can boot Linux 2.6.30 and 2.6.28 form
the menu, but not 2.6.29.

Even if I run grub-mkconfig, there is still something I lose.  By
selecting "Linux default" I still don't know it it's Linux 2.6.30 or
something else.

For me, the convenience of not having to rerun grub-mkconfig doesn't
outweigh the convenience of knowing what I'm loading.

I know, it's have to argue about preferences, but if you want you
changes to be accepted, you need to present a good case.
It's also that kind of discussion which eventually separates the wheat from the chaff. Thus I welcome it.
I would consider placing the kernel pointed to by the vmlinuz link to
the first position of the Linux kernels.  Another approach would be to
have an entry for the link without suppressing any versioned entries.
Ok, I understand and if it is a preference why don't make it a preference. :) You can find attached a new version of the patch, which per default will read the symlink and create an entry for the target, not the symlink. You can change this behaviour with "GRUB_USE_LINUX_SYMLINK=yes". If you define this environment variable with that value, it will use the behaviour I implemented before. This means it uses the symlink and ignores the kernel the symlink is currently pointing at. I think this is the best solution, because it prevents duplicated entries (only one entry for symlink or symlink target) and it gives the user the choice which behaviour he wants (rerun of grub-mkconfig needed or not needed).
Is that solution all right?

Please specify where those names are used.  Can you give the
distribution name and version where such names are used?
Zenwalk, Slackware for example. I think more Slackware derivates are using it too.

Let's add support for more versioned names first.  That should be rather
I see no more versioned names which could be added for the existing extension(s). There is initrd-<version>.<ext> and initrd.<ext>-<version>. Whereas <version> can either be $version or $alt_version and <ext> can be "img" or "gz" ("gz" is new) and at the very end as a last resort initrd.img initrd.gz and initrd.splash are tried in that order (that's also new). Roughly speaking only new fallback options.
Do you see a problem there or do you have a concrete versioned name to add?

diff --git a/ChangeLog b/ChangeLog
index 2203b68..f1606ba 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -0,0 +1,12 @@
+2009-05-05  Andreas Born  <address@hidden>
+    * util/grub.d/ Prevent duplicated entries because both
+    symlink and symlinked kernel are detected.
+    Default: use only target of the symlink
+    GRUB_USE_LINUX_SYMLINK=yes: use only the symlink
+    Detect also kernels without a hyphen in a name and use an
+    empty version for those kernels.
+    Don't display ', linux <kernelver>' in the menuentry title if
+    version is empty.
+    Detect more initrds e.g. initrd.gz.
diff --git a/util/grub.d/ b/util/grub.d/
index c2da413..f2649be 100644
--- a/util/grub.d/
+++ b/util/grub.d/
@@ -112,9 +112,32 @@ EOF
-list=`for i in /boot/vmlinu[xz]-* /vmlinu[xz]-* ; do
+list=`for i in /boot/vmlinu[xz]* /vmlinu[xz]* ; do
         if grub_file_is_not_garbage "$i" ; then echo -n "$i " ; fi
+for i in $list ; do
+  if ! test -h $i ; then
+    continue # no symlink
+  fi
+  target="`readlink -f $i`"
+  if test ! -f $target ; then
+    # inexistent target
+    list=`echo $list | tr ' ' '\n' | grep -vx $i | grep -vx $target \
+           | tr '\n' ' '`
+    continue
+  fi
+  # default: use the target, not the symlink
+  if [ "${GRUB_USE_LINUX_SYMLINK}" = "yes" ] ; then
+    list=`echo $list | tr ' ' '\n' | grep -vx $target | tr '\n' ' '`
+  else
+    list=`echo $list | tr ' ' '\n' | grep -vx $i | tr '\n' ' '`
+    if ! echo $list | grep -qw $target ; then
+      list="$list $target"
+    fi
+  fi
 while [ "x$list" != "x" ] ; do
   linux=`find_latest $list`
@@ -122,13 +145,16 @@ while [ "x$list" != "x" ] ; do
   basename=`basename $linux`
   dirname=`dirname $linux`
   rel_dirname=`make_system_path_relative_to_its_root $dirname`
-  version=`echo $basename | sed -e "s,^[^0-9]*-,,g"`
+  version=`echo $basename | sed -e "s,^[^\-]*-*,,"`
   alt_version=`echo $version | sed -e "s,\.old$,,g"`
   for i in "initrd.img-${version}" "initrd-${version}.img" \
-          "initrd.img-${alt_version}" "initrd-${alt_version}.img"; do
+       "initrd.img-${alt_version}" "initrd-${alt_version}.img" \
+       "initrd.gz-${version}" "initrd-${version}.gz" \
+       "initrd.gz-${alt_version}" "initrd-${alt_version}.gz" \
+       "initrd.img" "initrd.gz" "initrd.splash"; do
     if test -e "${dirname}/${i}" ; then
@@ -140,10 +166,16 @@ while [ "x$list" != "x" ] ; do
     # "UUID=" magic is parsed by initrds.  Since there's no initrd, it can't 
work here.
+  if test -n "${version}" ; then
+    title="${OS}, linux ${version}"
+  else
+    title="${OS}"
+  fi
-  linux_entry "${OS}, linux ${version}" \
+  linux_entry "${title}" \
-  linux_entry "${OS}, linux ${version} (recovery mode)" \
+  linux_entry "${title} (recovery mode)" \
       "single ${GRUB_CMDLINE_LINUX}"
   list=`echo $list | tr ' ' '\n' | grep -vx $linux | tr '\n' ' '`

reply via email to

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