Any views expressed within media held on this service are those of the contributors, should not be taken as approved or endorsed by the University, and do not necessarily reflect the views of the University in respect of any particular issue.

LCFG Project

LCFG Project

Recent Activity for the LCFG project

Ubuntu grub config management

For some time now in Informatics we have occasionally seen problems with Ubuntu desktop machines not successfully rebooting. It hasn’t been a widespread problem, affecting something like just 1% of machines whenever package updates require a reboot, so diagnosis has been difficult. We think we may finally have a proper solution …

A while back we tracked down the issue to the way in which the grub configuration was updated when certain packages (e.g. grub-pc, memtest86+ and systemd-sysv on my machine) are upgraded.

The standard way of updating the grub configuration on Debian and Ubuntu is to run the /usr/sbin/update-grub script and that is usually done from the post-install script when a relevant package is upgraded. The problem we have is that this can (and often does) generate a configuration that doesn’t fit with the way we currently want to manage it using the LCFG grub2 component. In an attempt to ensure the grub configuration is correct, the apt component calls the grub2 component configure method whenever a package is updated that requires a reboot. We also always regenerate the grub configuration when the grub2 component is stopped which usually only happens when the system is rebooted or powered-off. The problem is that this can leave a window of some time when the configuration is in an incorrect state, if the machine crashes or is uncleanly forced off then it won’t be fixed before the next reboot.

Having tried various solutions, including package triggers, it eventually became clear that the only option was to replace the standard update-grub script, which is provided in the grub2-common package, with a local LCFG-aware equivalent. That poses the challenge of replacing the script in such a way that when the grub2-common package is upgraded at some later time the local version is not overwritten. Debian supports this approach with diversions which are managed using the dpkg-divert command. This creates a situation where effectively both the grub2-common and lcfg-grub2 packages simultaneously provide the /usr/sbin/update-grub file (which would normally be considered a file conflict) with the original being diverted to another location.

The diversion is created in the pre-install script for the lcfg-grub2 package (lcfg-grub2.preinst) like this:

if [ upgrade != "$1" ] || dpkg --compare-versions "$2" lt 0.15.0-1; then
    dpkg-divert --package lcfg-grub2 --rename \
                --divert "/usr/sbin/update-grub-debian" \
                --add    "/usr/sbin/update-grub"
fi

Where 0.15.0-1 is the first version of the lcfg-grub2 package which provided the file. The original file is renamed to /usr/sbin/update-grub-debian and can still be used if necessary.

For correctness, support should also be added to the pre-removal script (lcfg-grub2.postrm) in case the lcfg-grub2 package is ever completely removed. That way the original from grub2-common package would be restored to the standard location. That is done like this:

if [ remove = "$1" -o abort-install = "$1" -o disappear = "$1" ] ; then

    dpkg-divert --no-rename --package lcfg-grub2 --rename \
                --remove "/usr/sbin/update-grub"

fi

if [ abort-upgrade = "$1" ] && dpkg --compare-versions "$2" lt 0.15.0; then

       dpkg-divert --no-rename --package lcfg-grub2 --rename \
                   --remove "/usr/sbin/update-grub"

fi

This handles various cases beyond just full removal, such as failure to upgrade to the new version.

The script itself is quite simple:

if om grub2 isstarted -q; then
    echo "Configuring grub using LCFG component"
    om grub2 configure
else
    # Call the standard script if component is not running
    /usr/sbin/update-grub-debian "$@"
fi

If the component is started, the configure method will be called otherwise the standard script (in its diverted location) will be run.

See the lcfg-grub2 code in our subversion repository for complete details. For further examples see the Debian wiki.

Dpkg diversions are a powerful tool but they do have some limitations, in particular, they don’t work well with configuration files (typically things in the /etc directory) which are managed with other tools (e.g. debconf or ucf). There are also risks associated with replacing files from essential packages where a failure might make it impossible to fix the system.

Leave a reply

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>

css.php

Report this page

To report inappropriate content on this page, please use the form below. Upon receiving your report, we will be in touch as per the Take Down Policy of the service.

Please note that personal data collected through this form is used and stored for the purposes of processing this report and communication with you.

If you are unable to report a concern about content via this form please contact the Service Owner.

Please enter an email address you wish to be contacted on. Please describe the unacceptable content in sufficient detail to allow us to locate it, and why you consider it to be unacceptable.
By submitting this report, you accept that it is accurate and that fraudulent or nuisance complaints may result in action by the University.

  Cancel