[PATCH 1/2] Debian support: Add dracut-update-initramfs

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

 



This script is necessary to integrate dracut into the initramfs-
infrastructure of debian.

The file itself is just a copy from initramfs-tools' update-initramfs,
with a few lines modified to run dracut instead of mkinitramfs.
---
 dracut-update-initramfs |  558 +++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 558 insertions(+), 0 deletions(-)
 create mode 100755 dracut-update-initramfs

diff --git a/dracut-update-initramfs b/dracut-update-initramfs
new file mode 100755
index 0000000..36a98a2
--- /dev/null
+++ b/dracut-update-initramfs
@@ -0,0 +1,558 @@
+#!/bin/sh
+
+STATEDIR=/var/lib/dracut
+BOOTDIR=/boot
+CONF=/etc/dracut.conf
+KPKGCONF=/etc/kernel-img.conf
+USETRIGGERS=true
+mode=""
+version=""
+
+set -e
+
+if        $USETRIGGERS                                         \
+       && [ x"$DPKG_MAINTSCRIPT_PACKAGE" != x ]                \
+       && [ $# = 1 ]                                           \
+       && [ x"$1" = x-u ]                                      \
+       && dpkg-trigger --check-supported 2>/dev/null
+then
+       if dpkg-trigger --no-await update-initramfs; then
+               echo "dracut-update-initramfs: deferring update (trigger activated)"
+               exit 0
+       fi
+fi
+
+usage()
+{
+       if [ -n "${1}" ]; then
+               printf "${@}\n\n" >&2
+       fi
+       cat >&2 << EOF
+Usage: ${0} [OPTION]...
+
+Options:
+ -k [version]  Specify kernel version or 'all'
+ -c            Create a new initramfs
+ -u            Update an existing initramfs
+ -d            Remove an existing initramfs
+ -t            Take over a custom initramfs with this one
+ -b            Set alternate boot directory
+ -v            Be verbose
+ -h            This message
+
+EOF
+       exit 1
+}
+
+# chroot check
+chrooted()
+{
+        # borrowed from udev's postinst
+        if [ "$(stat -c %d/%i /)" = "$(stat -Lc %d/%i /proc/1/root 2>/dev/null)" ]; then
+                # the devicenumber/inode pair of / is the same as that of
+                # /sbin/init's root, so we're *not* in a chroot and hence
+                # return false.
+                return 1
+        fi
+        return 0
+}
+
+mild_panic()
+{
+       if [ -n "${1}" ]; then
+               printf "${@}\n" >&2
+       fi
+       exit 0
+}
+
+panic()
+{
+       if [ -n "${1}" ]; then
+               printf "${@}\n" >&2
+       fi
+       exit 1
+}
+
+verbose()
+{
+       if [ "${verbose}" = 1 ]; then
+               printf "${@}\n"
+       fi
+}
+
+version_exists()
+{
+       [ -e "${STATEDIR}/${1}" ] && [ -e "${initramfs}" ]
+       return $?
+}
+
+set_initramfs()
+{
+       initramfs="${BOOTDIR}/dracut.img-${version}"
+}
+
+
+# backup initramfs while running
+backup_initramfs()
+{
+       [ ! -r "${initramfs}" ] && return 0
+       initramfs_bak="${initramfs}.dpkg-bak"
+       [ -r "${initramfs_bak}" ] && rm -f "${initramfs_bak}"
+       ln -f "${initramfs}" "${initramfs_bak}" \
+               || cp -a "${initramfs}" "${initramfs_bak}"
+       verbose "Keeping ${initramfs_bak}"
+}
+
+# keep booted initramfs
+backup_booted_initramfs()
+{
+       initramfs_bak="${initramfs}.dpkg-bak"
+
+       # first time run thus no backup
+       [ ! -r "${initramfs_bak}" ] && return 0
+
+       # chroot with no /proc
+       [ ! -r /proc/uptime ] && rm -f "${initramfs_bak}" && return 0
+
+       # no kept backup wanted
+       [ "${backup_initramfs}" = "no" ] && rm -f "${initramfs_bak}" && return 0
+
+       # no backup yet
+       if [ ! -r "${initramfs}.bak" ]; then
+               mv -f ${initramfs_bak} "${initramfs}.bak"
+               verbose "Backup ${initramfs}.bak"
+               return 0
+       fi
+
+       # keep booted initramfs
+       uptime_days=$(awk '{printf "%d", $1 / 3600 / 24}' /proc/uptime)
+       if [ -n "$uptime_days" ]; then
+               boot_initramfs=$(find "${initramfs}.bak" -mtime +${uptime_days})
+       fi
+       if [ -n "${boot_initramfs}" ]; then
+               mv -f "${initramfs_bak}" "${initramfs}.bak"
+               verbose "Backup ${initramfs}.bak"
+               return 0
+       fi
+       verbose "Removing current backup ${initramfs_bak}"
+       rm -f ${initramfs_bak}
+}
+
+# nuke generated copy
+remove_initramfs()
+{
+       [ -z "${initramfs_bak}" ] && return 0
+       rm -f "${initramfs_bak}"
+       verbose "Removing ${initramfs_bak}"
+}
+
+
+generate_initramfs()
+{
+       echo "dracut-update-initramfs: Generating ${initramfs}"
+       OPTS=""
+       if [ "${verbose}" = 1 ]; then
+               OPTS="-v ${OPTS}"
+       fi
+       ##WORK HERE!
+       if dracut ${OPTS} "${initramfs}.new" "${version}"; then
+               mv -f "${initramfs}.new" "${initramfs}"
+               set_sha1
+       else
+               mkinitramfs_return="$?"
+               remove_initramfs
+               rm -f "${initramfs}.new"
+               if [ "$mkinitramfs_return" = "2" ]; then
+                       # minversion wasn't met, exit 0
+                       exit 0
+               fi
+               echo "update-initramfs: failed for ${initramfs}"
+               exit $mkinitramfs_return
+       fi
+}
+
+# lilo call
+run_lilo()
+{
+       # show lilo errors on failure
+       if ! lilo -t  > /dev/null 2>&1 ; then
+               echo "ERROR lilo fails for new ${initramfs}:"
+               echo
+               lilo -t
+       fi
+       lilo
+}
+
+# check if lilo is on mbr
+mbr_check()
+{
+       # try to discover grub|grub2 and be happy
+       [ -r /boot/grub/grub.cfg ] \
+               && groot=$(awk '/^set root=/{print substr($2, 7, 3); exit}' \
+                       /boot/grub/grub.cfg)
+       [ -r /boot/grub/menu.lst ] \
+               && groot=$(awk '/^root/{print substr($2, 2, 3); exit}' \
+                       /boot/grub/menu.lst)
+       [ -e /boot/grub/device.map ] && [ -n "${groot}" ] \
+               && dev=$(awk "/${groot}/{ print \$NF}" /boot/grub/device.map)
+       [ -n "${dev}" ] && [ -r ${dev} ] \
+               && dd if="${dev}" bs=512 skip=0 count=1 2> /dev/null \
+               | grep -q GRUB && return 0
+
+       # check out lilo.conf for validity
+       boot=$(awk -F = '/^boot=/{ print $2}' /etc/lilo.conf)
+       [ -z "${boot}" ] && return 0
+       case ${boot} in
+       /dev/md/*)
+               if [ -r /proc/mdstat ]; then
+                       MD=${boot#/dev/md/}
+                       boot="/dev/$(awk "/^md${MD}/{print substr(\$5, 1, 3)}" \
+                       /proc/mdstat)"
+               fi
+               ;;
+       /dev/md*)
+               if [ -r /proc/mdstat ]; then
+                       MD=${boot#/dev/}
+                       boot="/dev/$(awk "/^${MD}/{print substr(\$5, 1, 3)}" \
+                       /proc/mdstat)"
+               fi
+               ;;
+       esac
+       [ ! -r "${boot}" ] && return 0
+       dd if="${boot}" bs=512 skip=0 count=1 2> /dev/null | grep -q LILO \
+               && run_lilo && return 0
+
+       # no idea which bootloader is used
+       echo
+       echo "WARNING: grub and lilo installed."
+       echo "If you use grub as bootloader everything is fine."
+       echo "If you use lilo as bootloader you must run lilo!"
+       echo
+}
+
+# Invoke bootloader
+run_bootloader()
+{
+       # if both lilo and grub around, figure out if lilo needs to be run
+       if ( command -v update-grub >/dev/null 2>&1 \
+               || [ -e /boot/grub/menu.lst ] || [ -e /boot/grub/grub.cfg ] ) \
+       && ( [ -e /etc/lilo.conf ] && command -v lilo >/dev/null 2>&1 ); then
+               [ -r "${KPKGCONF}" ] && \
+               do_b=$(awk  '/^do_bootloader/{print $3}' "${KPKGCONF}")
+               if [ "${do_b}" = "yes" ] || [ "${do_b}" = "Yes" ] \
+               || [ "${do_b}" = "YES" ]; then
+                       run_lilo
+                       return 0
+               elif [ "${do_b}" = "no" ] || [ "${do_b}" = "No" ] \
+               || [ "${do_b}" = "NO" ]; then
+                       return 0
+               fi
+
+               # do_bootloader unconfigured
+               mbr_check
+               return 0
+       fi
+       if [ -r /etc/lilo.conf ] && command -v lilo >/dev/null 2>&1; then
+               run_lilo
+               return 0
+       fi
+       if command -v elilo >/dev/null 2>&1; then
+               elilo
+               return 0
+       fi
+       if [ -r /etc/zipl.conf ]; then
+               zipl
+       fi
+       if flash-kernel --supported >/dev/null 2>&1; then
+               flash-kernel ${version}
+       fi
+}
+
+compare_sha1()
+{
+       sha1sum "${initramfs}" | diff "${STATEDIR}/${version}" - >/dev/null 2>&1
+       return $?
+}
+
+# Note that this must overwrite so that updates work.
+set_sha1()
+{
+       sha1sum "${initramfs}" > "${STATEDIR}/${version}"
+}
+
+delete_sha1()
+{
+       rm -f "${STATEDIR}/${version}"
+}
+
+# ro /boot is not modified
+ro_boot_check()
+{
+       # check irrelevant inside of a chroot
+       if [ ! -r /proc/mounts ] || chrooted; then
+               return 0
+       fi
+
+       boot_opts=$(awk '/boot/{if ((match($4, /^ro/) || match($4, /,ro/)) \
+               && $2 == "/boot") print "ro"}' /proc/mounts)
+       if [ -n "${boot_opts}" ]; then
+               echo "WARNING: /boot is ro mounted."
+               echo "update-initramfs: Not updating ${initramfs}"
+               exit 0
+       fi
+}
+
+get_sorted_versions()
+{
+       version_list=""
+
+       for gsv_x in "${STATEDIR}"/*; do
+               gsv_x="$(basename "${gsv_x}")"
+               if [ "${gsv_x}" = '*' ]; then
+                       return 0
+               fi
+               worklist=""
+               for gsv_i in $version_list; do
+                       if dpkg --compare-versions "${gsv_x}" '>' "${gsv_i}"; then
+                               worklist="${worklist} ${gsv_x} ${gsv_i}"
+                               gsv_x=""
+                       else
+                               worklist="${worklist} ${gsv_i}"
+                       fi
+               done
+               if [ "${gsv_x}" != "" ]; then
+                       worklist="${worklist} ${gsv_x}"
+               fi
+               version_list="${worklist}"
+       done
+
+       verbose "Available versions: ${version_list}"
+}
+
+set_current_version()
+{
+       if [ -f /boot/dracut.img-`uname -r` ]; then
+               version=`uname -r`
+       fi
+}
+
+set_linked_version()
+{
+       if [ -e /initrd.img ] && [ -L /initrd.img ]; then
+               linktarget="$(basename "$(readlink /initrd.img)")"
+       fi
+
+       if [ -e /boot/initrd.img ] && [ -L /boot/initrd.img ]; then
+               linktarget="$(basename "$(readlink /boot/initrd.img)")"
+       fi
+
+       if [ -z "${linktarget}" ]; then
+               return
+       fi
+
+       version="${linktarget##*img-}"
+}
+
+set_highest_version()
+{
+       get_sorted_versions
+       set -- ${version_list}
+       version=${1}
+}
+
+create()
+{
+       if [ -z "${version}" ]; then
+               usage "Create mode requires a version argument"
+       fi
+
+       set_initramfs
+
+       if [ "${takeover}" = 0 ]; then
+               if version_exists "${version}"; then
+                       panic "Cannot create version ${version}: already exists"
+               fi
+
+               if [ -e "${initramfs}" ]; then
+                       panic "${initramfs} already exists, cannot create."
+               fi
+       fi
+
+       generate_initramfs
+}
+
+update()
+{
+       if [ "${update_initramfs}" = "no" ]; then
+               echo "update-initramfs: Not updating initramfs."
+               exit 0
+       fi
+
+       if [ -z "${version}" ]; then
+               set_highest_version
+       fi
+
+       if [ -z "${version}" ]; then
+               set_linked_version
+       fi
+
+       if [ -z "${version}" ]; then
+               set_current_version
+       fi
+
+       if [ -z "${version}" ]; then
+               verbose "Nothing to do, exiting."
+               exit 0
+       fi
+
+       set_initramfs
+
+       ro_boot_check
+
+       altered_check
+
+       backup_initramfs
+
+       generate_initramfs
+
+       run_bootloader
+
+       backup_booted_initramfs
+}
+
+delete()
+{
+       if [ -z "${version}" ]; then
+               usage "Delete mode requires a version argument"
+       fi
+
+       set_initramfs
+
+       if [ ! -e "${initramfs}" ]; then
+               panic "Cannot delete ${initramfs}, doesn't exist."
+       fi
+
+       if ! version_exists "${version}"; then
+               panic "Cannot delete version ${version}: Not created by this utility."
+       fi
+
+       altered_check
+
+       echo "update-initramfs: Deleting ${initramfs}"
+
+       delete_sha1
+
+       rm -f "${initramfs}"
+}
+
+# Check for update mode on existing and modified initramfs
+altered_check()
+{
+       # No check on takeover
+       [ "${takeover}" = 1 ] && return 0
+       if [ ! -e "${initramfs}" ]; then
+               mild_panic "${initramfs} does not exist. Cannot update."
+       fi
+       if ! compare_sha1; then
+               echo "update-initramfs: ${initramfs} has been altered." >&2
+               mild_panic "update-initramfs: Cannot update. Override with -t option."
+       fi
+}
+
+# Defaults
+verbose=0
+yes=0
+# We default to takeover=1 in Ubuntu, but not Debian
+takeover=0
+
+##
+
+while getopts "k:cudyvtb:h?" flag; do
+       case "${flag}" in
+       k)
+               version="${OPTARG}"
+               ;;
+       c)
+               mode="c"
+               ;;
+       d)
+               mode="d"
+               ;;
+       u)
+               mode="u"
+               ;;
+       v)
+               verbose="1"
+               ;;
+       y)
+               yes="1"
+               ;;
+       t)
+               takeover="1"
+               ;;
+       b)
+               BOOTDIR="${OPTARG}"
+               if [ ! -d "${BOOTDIR}" ]; then
+                       echo "Error: ${BOOTDIR} is not a directory."
+                       exit 1
+               fi
+               ;;
+       h|?)
+               usage
+               ;;
+       esac
+done
+
+shift $((${OPTIND} - 1))
+
+if [ $# -ne 0 ]; then
+       echo "Invalid argument for option -k."
+       usage
+fi
+
+# Validate arguments
+if [ -z "${mode}" ]; then
+       usage "You must specify at least one of -c, -u, or -d."
+fi
+
+if [ "${version}" = "all" ] \
+       || ( [ "${update_initramfs}" = "all" ] && [ -z "${version}" ] ); then
+       : FIXME check for --yes, and if not ask are you sure
+       get_sorted_versions
+       if [ -z "${version_list}" ]; then
+               verbose "Nothing to do, exiting."
+               exit 0
+       fi
+
+       OPTS="-b ${BOOTDIR}"
+       if [ "${verbose}" = "1" ]; then
+               OPTS="${OPTS} -v"
+       fi
+       if [ "${takeover}" = "1" ]; then
+               OPTS="${OPTS} -t"
+       fi
+       if [ "${yes}" = "1" ]; then
+               OPTS="${OPTS} -y"
+       fi
+       for u_version in ${version_list}; do
+               # Don't stop if one version doesn't work.
+               set +e
+               verbose "Execute: ${0} -${mode} -k \"${u_version}\" ${OPTS}"
+               "${0}" -${mode} -k "${u_version}" ${OPTS}
+               set -e
+       done
+       exit 0
+fi
+
+
+case "${mode}" in
+       c)
+               create
+               ;;
+       d)
+               delete
+               ;;
+       u)
+               update
+               ;;
+esac
-- 
1.6.5.3

--
To unsubscribe from this list: send the line "unsubscribe initramfs" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html

[Index of Archives]     [Linux Kernel]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite News]     [Linux SCSI]

  Powered by Linux