• updategrub for openSUSE Legacy Grub (not update-grub!)

    This document has been modified since pages 1 & 2 were created. Please click HERE for the most recent and up to date information on 'updategrub'.

    updategrub is a script which aims to solve all your boot problems ...

    As I just advised somebody to try it, I think I have to post the code now, so that users and others can have a look at it.

    More seriously, it works similarly to Grub2's update-grub under Ubuntu, using the same helper scripts : os-prober and linux-bootprober. I don't know why os-prober wasn't available for openSUSE. So I packaged it from a Fedora/ArchLinux port (which in turn ported the original Ubuntu/Debian script). os-prober will be installed as dependency when you install updategrub from my repo.

    Like update-grub, updategrub allows to append custom boot entries written in /etc/updategrub/custom (Ubuntu uses /etc/grub.d/40_custom). This file doesn't exist by default. It has a couple options that can be turned on/off in /etc/updategrub/defaults. This file is installed with defaults values. The options are explained in details in /usr/share/doc/packages/updategrub/README.

    As a consequence of installing os-prober, Grub2 users under openSUSE will be able to update Grub2 menu entries as well (assuming they use Grub2 under openSUSE). I added such an option, although updategrub isn't originally intended to work with Grub2.

    If - as I read many times - the advantage of Grub2 over Legacy Grub is that it can update Grub menu boot entries:
    • it wasn't entirely true since it is not the job of Grub2 but the fact of os-prober/linux-bootprober
    • it might not be true anymore since updategrub does it better (I hope so) and with more features.

    updategrub will be installed in /usr/bin and is actually a symlink to /usr/bin/updateLegacyGrub (to avoid future conflicts ?).
    I also added the old good findgrub and cfindgrub scripts to the updategrub package.

    Installation from repo:

    su -l
    zypper ar http://download.opensuse.org/reposit...openSUSE_11.4/ PTA
    zypper refresh -r PTA
    zypper in updategrub

    updategrub     # updtate /boot/grub/menu.lst
    updategrub -l  # display boot entries which could be added but don't write menu.lst
    updategrub -a  # activate Grub primary partition (same as findgrub -a)
    updategrub -r  # restore previous menu.lst
    updategrub -2  # update Grub2 menu.
    Some of updategrub's options in /etc/updategrub/defaults include:

    CHAINLOADGRUB (default yes)
    add other Grubs chainload entries

    (default is no and should remain NO!)
    make Windows partition active

    SETBOOTFLAG (default is no)
    (set bootflag on Grub primary partition if any, same as updategrub -a)

    You may also influence the order in which other Linux boot entries will be added in linux_order and ignore failsafe like boot entries as well as entries containing specific keywords, as in the example:
    linux_ignore="Gutsy Hardy"

    I don't guarantee it is bugfree. First versions rarely are. I hope you'll tell me if you find some.
    To Windows users - and I do not intend to work for them, please! - the entries that updategrub will add are the ones found and identified by os-prober, basically the same ones you would see in Ubuntu while running update-grub. Since openSUSE already adds those entries (sometimes also wrong ones), at least one (probably the right one) will appear twice. I guess I'll have to add a windows_ignore option in the next release to avoid duplicates.

    updategrub does not modify the part of menu.lst written by openSUSE YaST or zypper. It does not add other openSUSE's kernel boot entries, since os-prober doesn't check the /boot partition of the current OS. However it will add other openSUSE kernel boot entries if they are installed in other partitions (other openSUSE versions or several installs of the same version).

    Quote Added for detail:
    The script is not intended to be 'destructive'. But it's also possible to harm a system, even with non destructive tools. In any case, updategrub -l will print the entries that could be added to standard output without writing menu.lst. I would first run the script with that option. If it displays nothing or garbage, there is no point to run updategrub, as it will write exactly the same thing in Grub menu.

    Whithout the option "-l", updategrub will look for the string "
    Added by updategrub" in menu.lst and delete everything after that point. It will then add a comment "# *** Don't change this comment - Added by updategrub" followed by the date. Obviously if someone came to the idea to write "Added by updategrub" on the top on menu.lst, the whole menu would get deleted, including the openSUSE boot entries.

    To keep it safe, the first time it is executed, updategrub will copy menu.lst in menu.lst.dist once and never touch this copy. Then, each time it is ran, it will save menu.lst in menu.lst.updg, so that the previous menu can be restored with
    updategrub -r

    updategrub -h
    displays the command line options as well as the list of distros known by os-prober. If you want to apply Grub commands to specific boot entries, you would use these names followed by "_options". I would call that "advanced usage". I can not think of anyone (except myself) who would use options for Linux Grub entries. But the feature is there because I needed it.
    Get the script here: updategrub at susepaste

    Grub2 and Legacy Grub
    Grub is the bootmanager used to boot Linux. Although it is not specific to Linux and not part of the core, it has become the default bootmanager, having supplanted the original Linux loader (LiLo) for several years, and is now installed with every Linux distribution. Grub2, the next generation of the bootmanager, is used on Ubuntu and its derivatives as well as on the latest Debian, Squeeze. Other distros, including openSUSE, Fedora, and Mandriva, still use their own (sometimes patched) version of the original Grub, also called "Legacy Grub". The syntaxes of Grub2 and Legacy Grub are by and large very different.

    The Grub menu
    One of the most popular features of Grub2 is the ability to automatically rewrite the boot menu - the menu you see at boot, which presents you with a choice of Linux kernels or other operating systems to start. Legacy Grub users still have to become root and edit a config file manually, adding or removing boot entries, after figuring out the location and the name of the partition containing the Linux kernel of the other distros they want to add, or which of the 2 or 3 Windows partitions is the right one. The file containing the boot menu configuration and entries is located in the directory /boot/grub and is traditionnaly called 'menu.lst'. Under openSUSE, each entry in /boot/grub/menu.lst ist preceeded by a comment with 3 leading and trailing "#", as in the example below:


    ###Don't change this comment - YaST2 identifier: Original name: linux### title openSUSE 11.4 - root (hd0,10) kernel /boot/vmlinuz- root=/dev/disk/by-uuid/e15f9b1d-d2e4-404f-aac6-79e46b016eb9 resume=/dev/disk/by-uuid/50089717-8b5e-482a-8686-7d47d88b7402 splash=silent quiet showopts vga=0x31a initrd /boot/initrd-
    Except for the comment line required by YaST, most Linux kernel boot entries from other distros are of the same form, consisting of at least these 4 lines, starting with title, root, kernel and initrd, with a few exceptions and some differences in device notations.

    Actually the purpose of updategrub is to do the job for you. So you shouldn't have to edit /boot/grub/menu.lst. But it still doesn't hurt to know how a boot entry looks like.

    update-grub and os-prober
    Before explaining updategrub's usage in detail, a few more words about update-grub, the tool used on Ubuntu to refresh the boot menu. update-grub (see below) consists of a single command which executes another script, grub-mkconfig.


    #!/bin/sh set -e exec grub-mkconfig -o /boot/grub/grub.cfg "$@"
    grub-mkconfig runs different tests and executes the scripts found in /etc/grub.d. This also applies to the version of Grub2 available for openSUSE, except that grub-mkconfig is named grub2-mkconfig on openSUSE. One of these scripts is /etc/grub.d/30_os-prober, which uses a helper programm called os-prober to scan the hard disks for other installed operating systems that grub-mkconfig will then add to the grub menu. If os-prober is missing, the script /etc/grub.d/30_os-prober will exit and grub-mkconfig will run the next script in the /etc/grub.d directory.

    /etc/grub.d/30_os-prober is part of Grub2. os-prober is a separate programm which is not available (yet) from openSUSE official repos. I found a port for Fedora (which was ported from Debian) and created a package for openSUSE. It is available in my repo and will be installed by dependencies with updategrub.


    Now back to updategrub and Legacy grub! As you might have guessed, updategrub uses os-prober (as well as linux-boot-prober, another script in this package) to find installed operating systems, and it parses the output of those scripts in a suitable form to be added in /boot/grub/menu.lst as selectable boot entries. The script also has several features and options that I will describe later.


    • adding and refreshing the repo:


      sudo zypper ar http://download.opensuse.org/reposit...openSUSE_11.4/ PTA sudo zypper refresh -r PTA
    • installing the package:


      sudo zypper in updategrub
    • There have been several versions in the past few days. If you installed updategrub already, please upgrade to the latest version by refreshing the repo and reinstalling the package:


      sudo zypper refresh -r PTA sudo zypper in updategrub
    • disabling the repo
      You can disable the repo afterwards if you like, following the motto that the less repos you have, the better. To disable the repo:


      sudo zypper mr -d PTA
    • reenabling the repo
      You can reenable the repo anytime if needed:

      sudo zypper mr -e PTA

    running as root

    Only root is allowed to modify system files, and /boot/grub/menu.lst is one of them. Thus, as for the zypper commands above, you'll have either to precede updategrub by sudo or type it in a root terminal. You can also open a root login bash session in your current terminal by typing: su -l. I won't specify that in the following commands. But any time you see "updategrub", it means in fact "sudo updategrub" or opening a root terminal and typing "updategrub".


    To scan for other operating systems and add them to the Grub menu, simply type:


    To print the list of available operating systems in your terminal without adding them to the Grub menu - meaning without modifying /boot/grub/menu.lst at all - use the -l or --list option:


    updategrub -l
    As for many Unix or Linux tools, each option of this script has a short form and a long form.

    Often updategrub will add more boot entries than you like to see in your boot menu. When run with the option -i or --interactive, updategrub will first scan and add other OSes, then display a checklist where you can deselect boot entries.


    updategrub -i
    However, since updategrub rescans other operating systems every time it is run, all boot entries will be reenabled after scanning. update-grub on Ubuntu works exactly the same way. However, updategrub can permanently ignore specific boot entries and never add them to the Grub menu nor display them in the checklist, using configuration options (explained later).

    You can also enable/disable boot entries without running the os-prober. In that case, the file /boot/grub/menu.lst won't be rewritten before displaying the checklist, and boot entries will appear as they were, either checked or unchecked. The option -m or --menu serves this purpose and can be used any time you want to enable or disable a boot entry.


    updategrub -m
    As this feature is pretty handy and can be useful on many occasions, without necessarily scanning for operating systems, it can also be called with the command:



    updategrub -m and grubmenu are two different names of the same command.

    Every time you run updategrub, the file /boot/grub/menu.lst is saved as /boot/grub/menu.lst.updg. In case something goes wrong, you can restore the previous menu with the option -r or --restore:


    updategrub -r
    Of course, if you run updategrub twice and things go wrong twice, this copy won't help. That's why updategrub will also save a copy of /boot/grub/menu.lst in /boot/grub/menu.lst.dist the first time it is run and never touch it after that. However be aware that this copy won't contain the right boot entries for the openSUSE kernel anymore as soon as this one will get updated.

    As a consequence of installing os-prober, Grub2 users under openSUSE will be able to update Grub2 menu as well by running

    /usr/sbin/grub2-mkconfig -o /boot/grub2/grub.cfg
    which could be abreviated in

    updategrub -2
    Last but not least, the option -a or --activate sets the bootflag of the primary partition containing the Grub bootloader, provided it is on the first BIOS drive and it is the only primary bootable Grub partition. The extended partition counts as a primary.


    updategrub -a
    This should save you the use of gparted or fdisk to reactivate the Grub partition after Windows stole the bootflag.

    updategrub has several options which can be set in its configuration file /etc/updategrub/defaults. This file is installed with default values. All options are commented out with the opposite value to their default, meaning you just need to uncomment them to move from the default behaviour.

    The following options can be set to yes or no.

    Add other Grubs' chainloading entries. Default is yes.
    When you installed other Linux distros, you probably also installed their own Grub, most likely in their root partition or in the MBR (first sector of the disk)... although if you had another Grub in the MBR, you would notice as this Grub will be the one booting. Chainloading entries don't start an operating system kernel directly but call another bootmanager instead. Windows boot entries are other examples of chainloading entries since they pass the control to the Windows bootloader, which in turn starts the Windows operating system. By default, updategrub adds chainloading entries for other Linux distros, whenever it finds Grub installed in other partitions' bootsector.

    Ignore failsafe, recovery and single user mode boot entries. Default is yes.
    Most Linux distros have at least one safe mode boot entry, also called failsafe, recovery, rescue or single user mode. By default these entries don't get added, since they should already be available in each distro's Grub menu. Set NOFAILSAFE to no by uncommenting this option line if you want failsafe boot entries to be added.

    Uncomment this line to launch the interactive menu where you can enable/disable boot entries. Default is no.
    This option has the same effect as the command line option -i or --interactive.

    This option sets the bootflag on the Windows partition, with the consequence that if you boot Grub from another primary or from the extended partition, it won't boot anymore. The default is no and should remain no! There is normally no need to activate the Windows partition.

    This option sets the bootflag on the Grub partition everytime the script is run. It only makes sense if MAKEACTIVE is on. To set the bootflag on the Grub partition once, use the command line option -a or --activate.

    This option places Windows chainloading entries before Linux kernel entries in Grub menu. Default is no.

    ignoring boot entries
    In addition to failsafe kernels, you can exclude from Grub menu entries containing given keywords by writing these keywords in the variable linux_ignore
    The items are case insensitive and must be separated by spaces. Example:
    linux_ignore="Gutsy Hardy"

    sorting boot entries
    You can sort boot entries in the order you wish them to appear in Grub menu by putting the distro identifiers in the variable linux_order, as in the example below:
    linux_order="ubuntu suse fedora mandrivalinux gentoo arch debian"
    The descriptor used to identify each Linux distro is the lowercased short name (third field) from os-prober output, or, if it is "unknownlsb", as for Arch Linux in the example below, the first word of the OS long description, in lowercase:


    /dev/sda1:Windows NT/2000/XP (loader):Windows:chain /dev/sda15:Arch Linux:UnknownLSB:linux => arch /dev/sda19ebian GNU/Linux (squeeze/sid):Debian:linux => debian /dev/sda6:Ubuntu 10.10 (10.10):Ubuntu:linux => ubuntu /dev/sdb1:Windows NT/2000/XP (loader):Windows1:chain /dev/sdb6:Mandriva Linux 2010.2 (2010.2):MandrivaLinux:linux => mandrivalinux
    A list of recognized Linux distros can be displayed with:


    updagrub -h
    However this list in neither complete nor reliable, as the short name corresponding to the distributor ID (as given by lsb_release -si), can be missing on distros which don't follow the LSB standard and would be easy to fake anyway.

    Appending custom boot entries
    You can define other boot entries, such as ones for undetected operating systems (like BSDs), in the file /etc/updategrub/custom. This file is not provided by default. If it exists, updategrub will append its content to the Grub menu every time it is run (without applying any syntax checking to the boot entries!). This file is the equivalent of Grub2's /etc/grub.d/40_custom. You'll still have the possibility to enable/disable custom boot entries, like any other boot entries, by running grubmenu.

    advanced options
    Finally you can assign any Grub menu option to any boot entry, by writing them in a variable whose name consists of the OS descriptor followed by "_options". You don't need to add device mapping options for Windows entries, as they should be added by updategrub according to /boot/grub/device.map if Windows is not located on the first BIOS drive. See the examples in /usr/share/doc/packages/updategrub/README. It is very unlikely that you'll ever use this feature.
    This article was originally published in forum thread: updategrub for openSUSE Legacy Grub (not update-grub!) started by please_try_again View original post