From bc65f2c6946d34295ff4b7419f3646ebdcc7b2dc Mon Sep 17 00:00:00 2001 From: liushanwen Date: Thu, 20 Apr 2023 17:37:07 +0800 Subject: [PATCH] =?UTF-8?q?=E7=BC=96=E8=AF=91ubuntu=20=E6=9C=80=E6=96=B014?= =?UTF-8?q?0=E7=89=88=E6=9C=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- conf/initramfs.conf | 34 ++-- debian/changelog | 7 + debian/control | 32 +--- debian/initramfs-tools-bin.install | 2 +- debian/initramfs-tools-core.dirs | 7 +- debian/initramfs-tools-core.examples | 2 +- debian/initramfs-tools-core.install | 12 +- debian/initramfs-tools-core.manpages | 4 +- debian/initramfs-tools-core.postinst | 5 + debian/initramfs-tools-core.postrm | 2 +- debian/initramfs-tools.install | 2 +- debian/initramfs-tools.postinst | 4 +- debian/rules | 2 +- debian/salsa-ci.yml | 6 + debian/tests/amd64-ata-only | 22 +++ debian/tests/amd64-busybox | 19 +++ debian/tests/amd64-klibc | 19 +++ debian/tests/amd64-panic-shell | 32 ++++ debian/tests/amd64-separate-usr | 36 +++++ debian/tests/amd64-virtio-only | 22 +++ debian/tests/control | 26 ++- debian/tests/prep-image | 3 +- debian/tests/run-image | 1 + debian/tests/test-common | 100 ++++++++++++ docs/example_script | 13 -- docs/maintainer-notes.md | 59 ++----- hook-functions | 149 +++++++++++++----- hooks/fsck | 16 +- init | 20 +-- initramfs-tools.7 | 19 +-- initramfs.conf.5 | 24 +-- kernel/postinst.d/initramfs-tools | 2 +- kernel/postrm.d/initramfs-tools | 2 +- mkinitramfs | 82 ++++++---- scripts/functions | 110 ++++++++----- scripts/local | 42 +++-- scripts/local-premount/fixrtc | 6 +- scripts/local-premount/resume | 2 +- scripts/nfs | 2 +- src/Makefile | 8 +- .../test_netinfo.d/ipv4/netplan/example1.yaml | 1 - .../ipv4and6/netplan/example1.yaml | 1 - .../ipv4static/netplan/example1.yaml | 1 - .../test_netinfo.d/ipv6/netplan/example1.yaml | 1 - .../vlan/netplan/example1.1.yaml | 1 - unmkinitramfs | 5 + update-initramfs | 39 +---- 47 files changed, 663 insertions(+), 343 deletions(-) create mode 100644 debian/salsa-ci.yml create mode 100755 debian/tests/amd64-ata-only create mode 100755 debian/tests/amd64-busybox create mode 100755 debian/tests/amd64-klibc create mode 100755 debian/tests/amd64-panic-shell create mode 100755 debian/tests/amd64-separate-usr create mode 100755 debian/tests/amd64-virtio-only create mode 100644 debian/tests/test-common mode change 100644 => 100755 mkinitramfs mode change 100644 => 100755 unmkinitramfs mode change 100644 => 100755 update-initramfs diff --git a/conf/initramfs.conf b/conf/initramfs.conf index 70ec614..d76d071 100644 --- a/conf/initramfs.conf +++ b/conf/initramfs.conf @@ -30,31 +30,10 @@ MODULES=most BUSYBOX=auto # -# COMPCACHE_SIZE: [ "x K" | "x M" | "x G" | "x %" ] -# -# Amount of RAM to use for RAM-based compressed swap space. -# -# An empty value - compcache isn't used, or added to the initramfs at all. -# An integer and K (e.g. 65536 K) - use a number of kilobytes. -# An integer and M (e.g. 256 M) - use a number of megabytes. -# An integer and G (e.g. 1 G) - use a number of gigabytes. -# An integer and % (e.g. 50 %) - use a percentage of the amount of RAM. -# -# You can optionally install the compcache package to configure this setting -# via debconf and have userspace scripts to load and unload compcache. +# COMPRESS: [ gzip | bzip2 | lz4 | lzma | lzop | xz | zstd ] # -COMPCACHE_SIZE="" - -# -# COMPRESS: [ gzip | bzip2 | lz4 | lzma | lzop | xz ] -# - -COMPRESS=lz4 - -# -# NFS Section of the config. -# +COMPRESS=zstd # # DEVICE: ... @@ -79,3 +58,12 @@ NFSROOT=auto # RUNSIZE=10% + +# +# FSTYPE: ... +# +# The filesystem type(s) to support, or "auto" to use the current root +# filesystem type +# + +FSTYPE=auto diff --git a/debian/changelog b/debian/changelog index 604337d..f2b0618 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,9 @@ +initramfs-tools (0.140kylin18k0.0) yangtze; urgency=medium + + * build initramfs-tools 140 version + + -- liushanwen Thu, 20 Apr 2023 17:23:19 +0800 + initramfs-tools (0.136-ok3) yangtze; urgency=medium * update version info @@ -16,3 +22,4 @@ initramfs-tools (0.136-ok1) yangtze; urgency=medium * Build for openKylin. -- openKylinBot Mon, 25 Apr 2022 22:03:04 +0800 + diff --git a/debian/control b/debian/control index b2707db..48cefc6 100644 --- a/debian/control +++ b/debian/control @@ -1,16 +1,10 @@ Source: initramfs-tools Section: utils Priority: optional -Uploaders: Michael Prokop , - Ben Hutchings +Uploaders: Michael Prokop , Ben Hutchings Maintainer: Openkylin Developers XSBC-Original-Maintainer: Debian kernel team -Build-Depends: bash-completion, - debhelper-compat (= 12), - libudev-dev, - netplan.io [!i386] , - pkg-config, - shellcheck [!i386] +Build-Depends: debhelper-compat (= 12), bash-completion, shellcheck [!i386] , pkg-config, libudev-dev, netplan.io [!i386] Rules-Requires-Root: no Standards-Version: 4.1.5 Vcs-Browser: https://git.launchpad.net/~ubuntu-kernel/ubuntu/+source/initramfs-tools/ @@ -21,16 +15,11 @@ X-Debian-Vcs-Git: https://salsa.debian.org/kernel-team/initramfs-tools.git Package: initramfs-tools Architecture: all Multi-Arch: foreign -Depends: initramfs-tools-core (= ${binary:Version}), - linux-base, - ${misc:Depends} +Depends: initramfs-tools-core (= ${binary:Version}), linux-base, ${misc:Depends} Suggests: bash-completion Provides: linux-initramfs-tool Conflicts: linux-initramfs-tool, usplash (<< 0.5.50) -Breaks: e2fsprogs (<< 1.42.13), - initscripts (<< 2.88dsf-0), - netplan.io (<< 0.37), - upstart +Breaks: initscripts (<< 2.88dsf-59.3~), upstart, e2fsprogs (<< 1.42.13), netplan.io (<< 0.37) Description: generic modular initramfs generator (automation) This package builds a bootable initramfs for Linux kernel packages. The initramfs is loaded along with the kernel and is responsible for @@ -39,16 +28,7 @@ Description: generic modular initramfs generator (automation) Package: initramfs-tools-core Architecture: all Multi-Arch: foreign -Depends: coreutils (>= 8.24), - cpio (>= 2.12), - initramfs-tools-bin (= ${binary:Version}), - klibc-utils (>= 2.0.4-0), - kmod, - logsave | e2fsprogs (<< 1.45.3-z), - lz4, - udev, - ${busybox:Depends}, - ${misc:Depends} +Depends: ${busybox:Depends}, initramfs-tools-bin (= ${binary:Version}), klibc-utils (>= 2.0.4-8~), cpio (>= 2.12), zstd, kmod, udev, coreutils (>= 8.24), logsave | e2fsprogs (<< 1.45.3-1~), ${misc:Depends} Suggests: bash-completion Breaks: initramfs-tools (<< 0.121~), ${busybox:Breaks} Replaces: initramfs-tools (<< 0.121~) @@ -60,7 +40,7 @@ Description: generic modular initramfs generator (core tools) Package: initramfs-tools-bin Architecture: any -Depends: ${misc:Depends}, ${shlibs:Depends} +Depends: ${shlibs:Depends}, ${misc:Depends} Description: binaries used by initramfs-tools This package contains binaries used inside the initramfs images generated by initramfs-tools. diff --git a/debian/initramfs-tools-bin.install b/debian/initramfs-tools-bin.install index 23dbfe3..feb1d40 100644 --- a/debian/initramfs-tools-bin.install +++ b/debian/initramfs-tools-bin.install @@ -1,2 +1,2 @@ -src/rzscontrol usr/lib/initramfs-tools/bin src/wait-for-root usr/lib/initramfs-tools/bin +src/gcc_s1-stub usr/lib/initramfs-tools/bin diff --git a/debian/initramfs-tools-core.dirs b/debian/initramfs-tools-core.dirs index 935727d..8092c1b 100644 --- a/debian/initramfs-tools-core.dirs +++ b/debian/initramfs-tools-core.dirs @@ -1,6 +1,3 @@ -/var/lib/initramfs-tools -etc/initramfs-tools/conf.d -etc/initramfs-tools/hooks etc/initramfs-tools/scripts/init-bottom etc/initramfs-tools/scripts/init-premount etc/initramfs-tools/scripts/init-top @@ -11,7 +8,9 @@ etc/initramfs-tools/scripts/nfs-bottom etc/initramfs-tools/scripts/nfs-premount etc/initramfs-tools/scripts/nfs-top etc/initramfs-tools/scripts/panic +etc/initramfs-tools/hooks +etc/initramfs-tools/conf.d usr/sbin -usr/share/initramfs-tools/conf-hooks.d usr/share/initramfs-tools/conf.d +usr/share/initramfs-tools/conf-hooks.d usr/share/initramfs-tools/modules.d diff --git a/debian/initramfs-tools-core.examples b/debian/initramfs-tools-core.examples index e1b4bcd..bb28943 100644 --- a/debian/initramfs-tools-core.examples +++ b/debian/initramfs-tools-core.examples @@ -1,4 +1,4 @@ conf/modules -docs/example_hook docs/example_script +docs/example_hook docs/framebuffer diff --git a/debian/initramfs-tools-core.install b/debian/initramfs-tools-core.install index 0e433d3..0c73fa2 100644 --- a/debian/initramfs-tools-core.install +++ b/debian/initramfs-tools-core.install @@ -1,8 +1,8 @@ -conf/initramfs.conf etc/initramfs-tools -conf/modules usr/share/initramfs-tools -hook-functions usr/share/initramfs-tools -hooks usr/share/initramfs-tools -init usr/share/initramfs-tools lsinitramfs usr/bin -scripts usr/share/initramfs-tools unmkinitramfs usr/bin +init usr/share/initramfs-tools +scripts usr/share/initramfs-tools +conf/initramfs.conf etc/initramfs-tools +hooks usr/share/initramfs-tools +hook-functions usr/share/initramfs-tools +conf/modules usr/share/initramfs-tools diff --git a/debian/initramfs-tools-core.manpages b/debian/initramfs-tools-core.manpages index 8db13b9..cb4fc51 100644 --- a/debian/initramfs-tools-core.manpages +++ b/debian/initramfs-tools-core.manpages @@ -1,5 +1,5 @@ -initramfs-tools.7 -initramfs.conf.5 lsinitramfs.8 mkinitramfs.8 unmkinitramfs.8 +initramfs.conf.5 +initramfs-tools.7 diff --git a/debian/initramfs-tools-core.postinst b/debian/initramfs-tools-core.postinst index 395e997..c4d7b75 100644 --- a/debian/initramfs-tools-core.postinst +++ b/debian/initramfs-tools-core.postinst @@ -40,4 +40,9 @@ if [ "$1" = configure ] && dpkg --compare-versions "$2" lt 0.123~; then finish_mv_conffile /etc/initramfs-tools/initramfs.conf initramfs-tools-core fi +# Remove obsolete state directory +if [ "$1" = configure ] && dpkg --compare-versions "$2" lt 0.138~; then + rm -rf /var/lib/initramfs-tools +fi + #DEBHELPER# diff --git a/debian/initramfs-tools-core.postrm b/debian/initramfs-tools-core.postrm index f66e01a..dc13943 100644 --- a/debian/initramfs-tools-core.postrm +++ b/debian/initramfs-tools-core.postrm @@ -2,7 +2,7 @@ set -e -if [ "x${1}" = "xpurge" ]; then +if [ "${1}" = "purge" ]; then rm -f /etc/initramfs-tools/conf.d/resume rm -f /etc/initramfs-tools/modules fi diff --git a/debian/initramfs-tools.install b/debian/initramfs-tools.install index 995e773..4e69147 100644 --- a/debian/initramfs-tools.install +++ b/debian/initramfs-tools.install @@ -1,4 +1,4 @@ conf/update-initramfs.conf etc/initramfs-tools +update-initramfs usr/sbin debian/script usr/share/bug/initramfs-tools kernel etc -update-initramfs usr/sbin diff --git a/debian/initramfs-tools.postinst b/debian/initramfs-tools.postinst index 0f0b96c..7979b2d 100644 --- a/debian/initramfs-tools.postinst +++ b/debian/initramfs-tools.postinst @@ -36,7 +36,7 @@ if [ "$1" = configure ] && [ -n "$2" ] && dpkg --compare-versions "$2" lt 0.123~ fi # Regenerate initramfs whenever we go to dpkg state `installed' -if [ "x$1" != xtriggered ]; then +if [ "$1" != triggered ]; then # this activates the trigger, if triggers are working update-initramfs -u else @@ -50,7 +50,7 @@ fi # - bug only affected users that were upgrading packages # - new users are not affected # - LP: #1515513 took care of removing old dkms together with the kernel -if [ "x$1" = xconfigure ] && [ -n "$2" ] && dpkg --compare-versions "$2" lt "0.131ubuntu11"; then +if [ "$1" = configure ] && [ -n "$2" ] && dpkg --compare-versions "$2" lt "0.131ubuntu11"; then for old_dkms_file in /boot/initrd-*.img.old-dkms \ /boot/initramfs-*.img.old-dkms \ /boot/initrd.img-*.old-dkms \ diff --git a/debian/rules b/debian/rules index 37386a0..da0eb98 100755 --- a/debian/rules +++ b/debian/rules @@ -5,7 +5,7 @@ # On Debian we can use either busybox or busybox-static, but on Ubuntu # and derivatives only busybox-initramfs will work. -BUSYBOX_PACKAGES := $(shell if dpkg-vendor --derives-from openKylin; then echo busybox-initramfs; else echo busybox busybox-static; fi) +BUSYBOX_PACKAGES := $(shell if dpkg-vendor --derives-from openkylin; then echo busybox-initramfs; else echo busybox busybox-static; fi) BUSYBOX_MIN_VERSION := 1:1.30.1-4ok5~ override_dh_gencontrol: diff --git a/debian/salsa-ci.yml b/debian/salsa-ci.yml new file mode 100644 index 0000000..ac7bc44 --- /dev/null +++ b/debian/salsa-ci.yml @@ -0,0 +1,6 @@ +include: + - https://salsa.debian.org/salsa-ci-team/pipeline/raw/master/salsa-ci.yml + - https://salsa.debian.org/salsa-ci-team/pipeline/raw/master/pipeline-jobs.yml + +variables: + RELEASE: 'unstable' diff --git a/debian/tests/amd64-ata-only b/debian/tests/amd64-ata-only new file mode 100755 index 0000000..b91601e --- /dev/null +++ b/debian/tests/amd64-ata-only @@ -0,0 +1,22 @@ +#!/bin/sh -e + +SUPPORTED_FLAVOURS='amd64 generic' +ROOTDISK_QEMU_IF=ide +ROOTDISK_LINUX_NAME=sda +. debian/tests/test-common + +cat >>"${CONFDIR}/initramfs.conf" <"${CONFDIR}/modules" <>"${CONFDIR}/initramfs.conf" <>"${CONFDIR}/initramfs.conf" <>"${CONFDIR}/initramfs.conf" <"${CONFDIR}/modules" <>"${CONFDIR}/initramfs.conf" <"${CONFDIR}/modules" < "${ROOTDIR}/etc/fstab" "/dev/${USRDISK_LINUX_NAME} /usr ext2 defaults 0 2" +USRDIR="$(mktemp -d)" +mv "${ROOTDIR}/usr/"* "${USRDIR}" + +build_rootfs_ext2 +build_fs_ext2 "${USRDIR}" "${USRDISK}" + +run_qemu_amd64 + +# Check that fsck ran on both devices +grep -q "^/dev/${ROOTDISK_LINUX_NAME}: clean," "${OUTPUT}" +grep -q "^/dev/${USRDISK_LINUX_NAME}: clean," "${OUTPUT}" diff --git a/debian/tests/amd64-virtio-only b/debian/tests/amd64-virtio-only new file mode 100755 index 0000000..5cca6da --- /dev/null +++ b/debian/tests/amd64-virtio-only @@ -0,0 +1,22 @@ +#!/bin/sh -e + +SUPPORTED_FLAVOURS='amd64 generic' +ROOTDISK_QEMU_IF=virtio +ROOTDISK_LINUX_NAME=vda +. debian/tests/test-common + +cat >>"${CONFDIR}/initramfs.conf" <"${CONFDIR}/modules" < "${IMAGE}-uuid" mkdir -p mnt diff --git a/debian/tests/run-image b/debian/tests/run-image index 6ae3d48..ef20f4b 100755 --- a/debian/tests/run-image +++ b/debian/tests/run-image @@ -43,6 +43,7 @@ timeout --foreground 10m \ -netdev user,id=net0 -device virtio-net-pci,netdev=net0,bus=pci.0,addr="$NICSLOT" dev=$(losetup -Pf --show "$IMAGE") +partprobe mount "${dev}p1" mnt rm -rf "$OUTPUT" cp -aT mnt/result "$OUTPUT" diff --git a/debian/tests/test-common b/debian/tests/test-common new file mode 100644 index 0000000..d1bf671 --- /dev/null +++ b/debian/tests/test-common @@ -0,0 +1,100 @@ +# -*- mode: sh -*- + +# Find kernel flavour and release +KVER= +for flavour in $SUPPORTED_FLAVOURS; do + KVER="$(dpkg-query -Wf '${Depends}' "linux-image-${flavour}" 2>/dev/null | tr ',' '\n' | sed -n 's/^ *linux-image-\([-a-z0-9+.]*\).*/\1/p')" + if [ "$KVER" ]; then + break + fi +done +if [ -z "$KVER" ]; then + echo >&2 "E: Test must set SUPPORTED_FLAVOURS and depend on those flavours" + exit 2 +fi + +if [ -n "${AUTOPKGTEST_TMP}" ]; then + export TMPDIR="${AUTOPKGTEST_TMP}" +fi + +# Skeleton configuration directory +CONFDIR="$(mktemp -d)" +cp conf/initramfs.conf "${CONFDIR}/initramfs.conf" +echo "RESUME=none" >>"${CONFDIR}/initramfs.conf" +touch "${CONFDIR}/modules" +mkdir "${CONFDIR}/scripts" + +# initramfs image file +INITRAMFS="$(mktemp)" + +# root disk image file +ROOTDISK="$(mktemp)" + +# root disk interface type (for qemu) and device name (for Linux) +test -n "${ROOTDISK_QEMU_IF}" || ROOTDISK_QEMU_IF=virtio +test -n "${ROOTDISK_LINUX_NAME}" || ROOTDISK_LINUX_NAME=vda + +# Create a root fs with a trivial userspace +ROOTDIR="$(mktemp -d)" +INIT_MESSAGE='root fs init system started successfully' +for subdir in bin dev lib proc run sbin sys usr usr/bin; do + mkdir "${ROOTDIR}/${subdir}" +done +cat >"${ROOTDIR}/sbin/init" <&1 -b "${blocks}" -N "${inodes}" -U -d "${dir}" "${disk}" +} + +build_rootfs_ext2() { + build_fs_ext2 "${ROOTDIR}" "${ROOTDISK}" +} + +_run_qemu_amd64() { + local extra_params="$*" + + timeout --foreground 60 qemu-system-x86_64 -m 1G -drive "file=${ROOTDISK},if=${ROOTDISK_QEMU_IF},media=disk,format=raw" ${USRDISK:+-drive "file=${USRDISK},if=${USRDISK_QEMU_IF},media=disk,format=raw"} -nographic -no-reboot -kernel "/boot/vmlinuz-${KVER}" -initrd "${INITRAMFS}" -append "root=/dev/${ROOTDISK_LINUX_NAME} ro console=ttyS0,115200 ${extra_params}" | tee "${OUTPUT}" +} + +run_qemu_nocheck_amd64() { + # hide error messages from autopkgtest + _run_qemu_amd64 2>&1 "$@" +} + +run_qemu_amd64() { + _run_qemu_amd64 "panic=-1" + grep -qF "${INIT_MESSAGE}" "${OUTPUT}" +} diff --git a/docs/example_script b/docs/example_script index b06edf2..accab37 100644 --- a/docs/example_script +++ b/docs/example_script @@ -26,23 +26,10 @@ prereqs) prereqs exit 0 ;; -mountfail) # Called if the script has previously registered a mountroot - # failure. - # Check status, and display any relevant information about the - # failure if there is a problem, then exit with a status of 1. - ;; esac # Do the work here. -# If this script is to be placed in either init-premount, or local-top, -# register a mountroot failure hook, so that further information can be given -# to the user, in the event that the root device cannot be found. - -. /scripts/functions - -add_mountroot_fail_hook - echo "Got here!" exit 0 diff --git a/docs/maintainer-notes.md b/docs/maintainer-notes.md index 0f961ad..3b51046 100644 --- a/docs/maintainer-notes.md +++ b/docs/maintainer-notes.md @@ -1,42 +1,19 @@ -*** - # Maintainer documentation for initramfs-tools -*** - -## Table of Contents - -* [1. Definitions](#definitions) -* [2. Preparations](#preparations) -* [3. Workflow for daily work](#workflow) - * [3.1 Implement new features](#newfeature) - * [3.2 Merge branches](#merge) - * [3.3 Test specific branch](#test) - * [3.4 Build snapshot version](#snapshot) -* [4. Contribute](#contribute) -* [5. Release new version](#release) -* [6. Resources](#resources) -* [7. Credits](#credits) -* [8. License](#license) - -*** +[[_TOC_]] **NOTE:** The most recent version of this document is available at docs/maintainer-notes.md in the [the git repository](#checkout) or online at [salsa.debian.org](https://salsa.debian.org/kernel-team/initramfs-tools/blob/master/docs/maintainer-notes.md). -*** - ## 1. Definitions - - - - - -
$mailaddress:mailaddress of the user
$username:name of the Salsa account
$version:version string
$yourname:your fullname
- -*** +| Name | Meaning | +| --- | --- | +| **`$mailaddress`** | mailaddress of the user | +| **`$username`** | name of the Salsa account | +| **`$version`** | version string | +| **`$yourname`** | your fullname | ## 2. Preparations @@ -64,8 +41,6 @@ or online at [salsa.debian.org](https://salsa.debian.org/kernel-team/initramfs-t % git clone ssh://git@salsa.debian.org/kernel-team/initramfs-tools.git % cd initramfs-tools -*** - ## 3. Workflow for daily work ### 3.1 Implement new features @@ -137,8 +112,6 @@ any stale remote branches locally by executing: % gbp buildpackage --git-ignore-new --git-debian-branch="$(git branch | awk -F\*\ '/^* / { print $2}' )" --post-clean -*** - ### 3.4 Build snapshot version 1. Adjust debian/changelog accordingly: @@ -150,8 +123,6 @@ any stale remote branches locally by executing: % gbp buildpackage --git-debian-branch="$(git branch | awk -F\*\ '/^* / { print $2}' )" --post-clean [-us -uc] -*** - ## 4. Contribute 1. Create patch: @@ -167,8 +138,6 @@ any stale remote branches locally by executing: Discussion of features, bugs and patches are more than welcome on one of these lists. -*** - ## 5. Release new version 1. Creating changelog: @@ -202,8 +171,6 @@ any stale remote branches locally by executing: debian-kernel@lists.debian.org + kernel-team@lists.ubuntu.com - including a shortlog (generated through "git shortlog $TAG.."). -*** - ## 6. Resources * [initramfs-tools git web interface](https://salsa.debian.org/kernel-team/initramfs-tools) @@ -214,21 +181,13 @@ any stale remote branches locally by executing: * [bugreports @ ubuntu](https://bugs.launchpad.net/ubuntu/+source/initramfs-tools) * [qa page @ ubuntu](http://status.qa.ubuntu.com/qapkgstatus/initramfs-tools) -*** - ## 7. Credits -* Thanks to Daniel Baumann for his "[Debian Packaging with Git](http://documentation.debian-projects.org/other/debian-packaging-git/)" which inspired this document. - -*** +* Thanks to Daniel Baumann for his "[Debian Packaging with Git](https://web.archive.org/web/20110528125600/http://documentation.debian-projects.org/other/debian-packaging-git/)" which inspired this document. ## 8. License * This document is licensed under GPL v2 or any later version. -*** - *-- Michael Prokop <[mika@debian.org](mailto:mika@debian.org)>, -Ben Hutchings <[ben@decadent.org.uk](mailto:ben@decadent.org.uk)>* - -*** +Ben Hutchings <[benh@debian.org](mailto:benh@debian.org)>* diff --git a/hook-functions b/hook-functions index 43f27cf..c8efd38 100644 --- a/hook-functions +++ b/hook-functions @@ -50,11 +50,46 @@ add_modules_from_file() done } -# Is this module available? -have_module() +# Locate a firmware file with the given name and copy it into DESTDIR, unless +# DESTDIR already contains such a file. +# Returns an error if no such firmware file can be located and DESTDIR doesn't +# already contain any matching file. (It is up to the caller to figure out +# whether a warning should be printed in that case.) +add_firmware() { - modprobe --set-version="${version?}" --ignore-install \ - --show-depends "${1}" >/dev/null 2>&1 + local firmware fwloc + + firmware="${1}" + + if [ -e "${DESTDIR}/lib/firmware/updates/${version?}/${firmware}" ] \ + || [ -e "${DESTDIR}/lib/firmware/updates/${version?}/${firmware}.xz" ] \ + || [ -e "${DESTDIR}/lib/firmware/updates/${firmware}" ] \ + || [ -e "${DESTDIR}/lib/firmware/updates/${firmware}.xz" ] \ + || [ -e "${DESTDIR}/lib/firmware/${version}/${firmware}" ] \ + || [ -e "${DESTDIR}/lib/firmware/${version}/${firmware}.xz" ] \ + || [ -e "${DESTDIR}/lib/firmware/${firmware}" ] \ + || [ -e "${DESTDIR}/lib/firmware/${firmware}.xz" ]; then + return 0 + fi + + for fwloc in "/lib/firmware/updates/${version}/${firmware}" \ + "/lib/firmware/updates/${firmware}" \ + "/lib/firmware/${version}/${firmware}" \ + "/lib/firmware/${firmware}"; do + if [ -e "${fwloc}" ]; then + copy_file firmware "${fwloc}" + return 0 + elif [ -e "${fwloc}.xz" ]; then + copy_file firmware "${fwloc}.xz" + if command -v xz >/dev/null 2>&1; then + xz -d "${DESTDIR}/${fwloc}.xz" + fi + return 0 + fi + done + + # We can't figure out where to get that firmware from. + return 1 } # Add dependent modules + eventual firmware @@ -83,15 +118,9 @@ manual_add_modules() # Add required firmware for firmware in $(modinfo -k "${version}" -F firmware "${kmod}"); do - if [ -e "${DESTDIR}/lib/firmware/${firmware}" ] \ - || [ -e "${DESTDIR}/lib/firmware/${version}/${firmware}" ]; then - continue - fi - # Only print warning for missing fw of loaded module # or forced loaded module - if [ ! -e "/lib/firmware/${firmware}" ] \ - && [ ! -e "/lib/firmware/${version}/${firmware}" ] ; then + if ! add_firmware "$firmware"; then # Only warn about missing firmware if # /proc/modules exists if [ ! -e /proc/modules ] ; then @@ -105,17 +134,35 @@ manual_add_modules() fi continue fi - - if [ -e "/lib/firmware/${version}/${firmware}" ]; then - copy_file firmware \ - "/lib/firmware/${version}/${firmware}" - else - copy_file firmware "/lib/firmware/${firmware}" - fi done done } +# manual_add_modules() takes care of adding firmware for things that were built +# as modules; but drivers can also be built into the kernel itself. To cover +# that case, we have to look at modules.builtin.modinfo instead. +# This file is generated by the kernel's build process since commit 898490c010b5 +# ("moduleparam: Save information about built-in modules in separate file"), +# which was added in Linux 5.2. +add_builtin_firmware() +{ + local builtin_modinfo_path builtin_modname firmware + + builtin_modinfo_path="/lib/modules/${version?}/modules.builtin.modinfo" + if [ ! -e "$builtin_modinfo_path" ]; then + if linux-version compare "${version}" ge 5.2; then + echo "W: Can't find modules.builtin.modinfo (for locating built-in drivers' firmware, supported in Linux >=5.2)" >&2 + fi + return + fi + + tr '\0' '\n' < "$builtin_modinfo_path" | grep -E '^[^=]*\.firmware=' | sed -n 's/\.firmware=/\t/p' | while read -r builtin_modname firmware; do + if ! add_firmware "$firmware"; then + echo "W: Possible missing firmware /lib/firmware/${firmware} for built-in driver ${builtin_modname}" >&2 + fi + done +} + # $1 = file type (for logging) # $2 = file to copy to initramfs # $3 (optional) Name for the file on the initramfs @@ -159,7 +206,7 @@ copy_file() { esac if [ "${link_target}" != "${target}" ]; then - [ "${verbose?}" = "y" ] && echo "Adding ${type}-link ${src}" + [ "${verbose?}" = "y" ] && echo "Adding ${type}-link ${target}" # Create a relative link so it always points # to the right place @@ -177,7 +224,7 @@ copy_file() { cp -pP "${src}" "${DESTDIR}/${target}" || return $(($? + 1)) } -# $1 = executable to copy to initramfs, with library dependencies +# $1 = executable/shared library to copy to initramfs, with dependencies # $2 (optional) Name for the file on the initramfs # Location of the image dir is assumed to be $DESTDIR # We never overwrite the target if it exists. @@ -209,17 +256,26 @@ copy_exec() { # Handle common dlopen() dependency (Debian bug #950254) case "${x}" in */libpthread.so.*) - copy_exec "/lib/libgcc_s.so.1" || copy_exec "${x%/*}/libgcc_s.so.1" || return + copy_libgcc "${x%/*}" || copy_libgcc "${x%/*}/.." || return ;; esac - copy_file library "${x}" || { + copy_file binary "${x}" || { ret=$? [ ${ret} = 1 ] || return $((ret - 1)) } done } +copy_libgcc() { + local libdir library + + libdir="$1" + for library in "${libdir}"/libgcc_s.so.[1-9]; do + copy_exec "${library}" || return + done +} + # Copy entire subtrees to the initramfs copy_modules_dir() { @@ -474,6 +530,16 @@ dep_add_modules_mount() block_dev_mod_add "$dev_node" } +class_add_modules() +{ + local device + + for device in "/sys/class/$1"/*; do + device="$(readlink -f "$device")" \ + && sys_walk_mod_add "$device" + done +} + dep_add_modules() { local device dev_node @@ -490,11 +556,8 @@ dep_add_modules() fi # sys walk some important device classes - for class in backlight extcon gpio phy pwm regulator rtc; do - for device in "/sys/class/$class"/*; do - device="$(readlink -f "$device")" \ - && sys_walk_mod_add "$device" - done + for class in extcon gpio phy pwm regulator rtc; do + class_add_modules "$class" done # clk, USB-PHY and pinctrl devices are outside the device model (!) so @@ -528,10 +591,8 @@ dep_add_modules() done if [ "$walk_graphics" = "yes" ]; then - for device in /sys/class/graphics/*; do - device="$(readlink -f "$device")" \ - && sys_walk_mod_add "$device" - done + class_add_modules backlight + class_add_modules graphics fi # catch old-style IDE @@ -579,7 +640,7 @@ auto_add_modules() local modules= if [ "$#" -eq 0 ] ; then - set -- base net ide scsi block ata i2o dasd ieee1394 firewire mmc usb_storage fb virtual nx + set -- base hw_random net ide scsi block ata i2o dasd ieee1394 firewire mmc usb_storage fb virtual nx fi for arg in "$@" ; do @@ -639,21 +700,29 @@ auto_add_modules() copy_modules_dir kernel/drivers/i2c/busses copy_modules_dir kernel/drivers/i2c/muxes copy_modules_dir kernel/drivers/mfd + copy_modules_dir kernel/drivers/pci/controller copy_modules_dir kernel/drivers/phy copy_modules_dir kernel/drivers/pinctrl copy_modules_dir kernel/drivers/regulator + copy_modules_dir kernel/drivers/reset copy_modules_dir kernel/drivers/spi copy_modules_dir kernel/drivers/usb/phy # Needed for periodic fsck copy_modules_dir kernel/drivers/rtc ;; + hw_random) + copy_modules_dir kernel/drivers/char/hw_random + ;; net) copy_modules_dir kernel/drivers/net \ appletalk arcnet bonding can dummy.ko \ hamradio hippi ifb.ko irda macvlan.ko \ macvtap.ko pcmcia sb1000.ko team tokenring \ - tun.ko usb veth.ko wan wimax wireless \ + tun.ko veth.ko wan wimax wireless \ + cdc_mbim.ko cdc-phonet.ko hso.ko huawei_cdc_ncm.ko ipheth.ko kalmia.ko \ + lg-vl600.ko qmi_wwan.ko sierra_net.ko cdc_subset.ko gl620a.ko \ + net1080.ko plusb.ko cx82310_eth.ko zaurus.ko \ xen-netback.ko modules="$modules 8021q" ;; @@ -673,6 +742,9 @@ auto_add_modules() block) copy_modules_dir kernel/drivers/block copy_modules_dir kernel/drivers/nvme + copy_modules_dir kernel/drivers/nvdimm + copy_modules_dir kernel/drivers/dax + copy_modules_dir kernel/drivers/acpi/nfit modules="$modules vmd" ;; ubi) @@ -696,6 +768,7 @@ auto_add_modules() fb) # For machines that don't have a generic framebuffer device. modules="$modules rockchipdrm pwm-cros-ec pwm_bl panel-simple" + modules="$modules analogix-anx6345 pwm-sun4i sun4i-drm sun8i-mixer" ;; virtual) # Hyper-V @@ -724,7 +797,9 @@ hidden_dep_add_modules() manual_add_modules $( { cat "${DESTDIR}/lib/modules/${version}/modules.builtin" - find "${DESTDIR}/lib/modules/${version}/kernel" -name '*.ko*' + if [ -d "${DESTDIR}/lib/modules/${version}/kernel" ]; then + find "${DESTDIR}/lib/modules/${version}/kernel" -name '*.ko*' + fi } | while read -r module; do module="${module##*/}" @@ -787,7 +862,7 @@ set_initlist() [ "${si_x}" = "${initdir}/*" ] && return # only allow variable name chars - case ${si_x#${initdir}/} in + case ${si_x#"${initdir}"/} in *[![:alnum:]\._-]*) [ "${verbose}" = "y" ] \ && echo "$si_x ignored: not alphanumeric or '_' file" >&2 @@ -802,7 +877,7 @@ set_initlist() continue fi - si_x="$(get_source "${si_x#${initdir}/}")" + si_x="$(get_source "${si_x#"${initdir}"/}")" # skip non executable scripts if [ ! -x "${si_x}" ]; then @@ -857,7 +932,7 @@ call_scripts() set -e for cs_x in ${runlist}; do [ -f "${initdir}/${cs_x}" ] || continue - if [ x"$call_scripts_optional" = "xy" ]; then + if [ "$call_scripts_optional" = "y" ]; then option=$(sed '/^OPTION=/!d;$d;s/^OPTION=//;s/[[:space:]]*$//' "${initdir}/${cs_x}") # shellcheck disable=SC1083,2086 [ -z "${option}" ] || eval test -n \"\${$option}\" -a \"\${$option}\" != \"n\" || continue diff --git a/hooks/fsck b/hooks/fsck index 4f18fbf..f6348e8 100755 --- a/hooks/fsck +++ b/hooks/fsck @@ -47,7 +47,7 @@ get_fsck_type_fstab () { eval "$(_read_fstab_entry "$1")" # Not found by default. - if [ "$1" = "$MNT_DIR" ] && [ "$MNT_PASS" != 0 ]; then + if [ "$1" = "$MNT_DIR" ]; then # Ignore filesystem type for /, as it is not available and # therefore never used at boot time if [ "${MNT_DIR}" = "/" ] || [ "${MNT_TYPE}" = "auto" ]; then @@ -62,8 +62,18 @@ get_fsck_type_fstab () { } get_fsck_types() { - get_fsck_type_fstab / root - get_fsck_type_fstab /usr /usr + if [ "${FSTYPE:-auto}" = auto ]; then + get_fsck_type_fstab / root + get_fsck_type_fstab /usr usr + else + local IFS=, + local fstype + set -f + for fstype in $FSTYPE; do + echo "$fstype" + done + set +f + fi } case $1 in diff --git a/init b/init index 60e9ceb..b3ef042 100755 --- a/init +++ b/init @@ -37,8 +37,7 @@ export quiet # Note that this only becomes /dev on the real filesystem if udev's scripts # are used; which they will be, but it's worth pointing out -test -x /usr/sbin/v86d && dev_exec="exec" || dev_exec="noexec" -mount -t devtmpfs -o $dev_exec,nosuid,mode=0755 udev /dev +mount -t devtmpfs -o nosuid,mode=0755 udev /dev mkdir /dev/pts mount -t devpts -o noexec,nosuid,gid=5,mode=0620 devpts /dev/pts || true @@ -177,12 +176,6 @@ for x in $(cat /proc/cmdline); do ;; panic=*) panic="${x#panic=}" - case ${panic} in - -1) ;; - *[![:digit:].]*) - panic= - ;; - esac ;; ro) readonly=y @@ -216,7 +209,7 @@ for x in $(cat /proc/cmdline); do ;; netconsole=*) netconsole=${x#netconsole=} - [ "x$debug" = "xy" ] && log_output=/dev/kmsg + [ "$debug" = "y" ] && log_output=/dev/kmsg ;; BOOTIF=*) BOOTIF=${x#BOOTIF=} @@ -260,10 +253,6 @@ fi maybe_break top -# export BOOT variable value for compcache, -# so we know if we run from casper -export BOOT - # Don't do log messages here to avoid confusing graphical boots run_scripts /scripts/init-top @@ -273,6 +262,10 @@ maybe_break modules load_modules [ "$quiet" != "y" ] && log_end_msg +starttime="$(_uptime)" +starttime=$((starttime + 1)) # round up +export starttime + maybe_break premount [ "$quiet" != "y" ] && log_begin_msg "Running /scripts/init-premount" run_scripts /scripts/init-premount @@ -363,6 +356,7 @@ unset noresume unset fastboot unset forcefsck unset fsckfix +unset starttime # Move virtual filesystems over to the real filesystem mount -n -o move /sys ${rootmnt}/sys diff --git a/initramfs-tools.7 b/initramfs-tools.7 index e5996cb..9bdea7d 100644 --- a/initramfs-tools.7 +++ b/initramfs-tools.7 @@ -290,14 +290,14 @@ copy_modules_dir kernel/drivers/ata .RE .SS Including binaries -If you need to copy binaries to the initramfs module, a command like this -should be used: +If you need to copy an executable or shared library to the initramfs +module, use a command like this: .PP .RS copy_exec /sbin/mdadm /sbin .RE -mkinitramfs will automatically detect which libraries the executable depends on +mkinitramfs will automatically detect which libraries it depends on and copy them to the initramfs. This means that most executables, unless compiled with klibc, will automatically include glibc in the image which will increase its size by several hundred kilobytes. @@ -451,15 +451,10 @@ panic "Frobnication failed" .TP \fB\fI -add_mountroot_fail_hook -Registers the script as able to provide possible further information, in the -event that the root device cannot be found. See the example script in the -initramfs-tools examples directory for more information. -.RS -.PP -.B Example: -add_mountroot_fail_hook -.RE +add_mountroot_fail_hook NN-name +\fBDeprecated\fR: This function is now a stub which is effectively a no-op. It +will be removed in a future version; please remove mountroot failure hooks from +existing packages accordingly. .SS Subdirectories Both /usr/share/initramfs-tools/scripts and /etc/initramfs-tools/scripts diff --git a/initramfs.conf.5 b/initramfs.conf.5 index 4817519..712232e 100644 --- a/initramfs.conf.5 +++ b/initramfs.conf.5 @@ -49,24 +49,6 @@ If set to 'n' will build an initramfs without busybox. Beware that many boot scripts need busybox utilities. -.TP -\fB COMPCACHE_SIZE -Amount of RAM to use for RAM-based compressed swap space. -The default is not to use compcache. - -An empty value \- compcache isn't used, or added to the initramfs at all. - -An integer and K (e.g. \fI65536 K\fP) \- use a number of kilobytes. - -An integer and M (e.g. \fI256 M\fP) \- use a number of megabytes. - -An integer and G (e.g. \fI1 G\fP) \- use a number of gigabytes. - -An integer and % (e.g. \fI50 %\fP) \- use a percentage of the amount of RAM. - -You can optionally install the \fIcompcache\fP package to configure this -setting via debconf and have userspace scripts to load and unload compcache. - .TP \fB COMPRESS Specifies the compression method used for the initramfs image. @@ -104,6 +86,12 @@ or is set to \fIauto\fP, will automatically select the largest available swap partition. Set it to \fInone\fP to disable resume from disk. +.TP +\fB FSTYPE +Specifies the filesystem type(s) to support, separated by commas. If +this is not defined or is set to \fIauto\fP, \fBmkinitramfs\fP will +automatically detect the current root and \fI/usr\fP filesystem types. + .SH VARIABLES FOR NFS BOOT .TP \fB DEVICE diff --git a/kernel/postinst.d/initramfs-tools b/kernel/postinst.d/initramfs-tools index 5d02e57..6b6fef3 100755 --- a/kernel/postinst.d/initramfs-tools +++ b/kernel/postinst.d/initramfs-tools @@ -33,4 +33,4 @@ fi # we're good - create initramfs. update runs do_bootloader # shellcheck disable=SC2086 -INITRAMFS_TOOLS_KERNEL_HOOK=1 update-initramfs -c -k "${version}" ${bootopt} >&2 +update-initramfs -c -k "${version}" ${bootopt} >&2 diff --git a/kernel/postrm.d/initramfs-tools b/kernel/postrm.d/initramfs-tools index 471da86..c340beb 100755 --- a/kernel/postrm.d/initramfs-tools +++ b/kernel/postrm.d/initramfs-tools @@ -33,4 +33,4 @@ fi # delete initramfs # shellcheck disable=SC2086 -INITRAMFS_TOOLS_KERNEL_HOOK=1 update-initramfs -d -k "${version}" ${bootopt} >&2 +update-initramfs -d -k "${version}" ${bootopt} >&2 diff --git a/mkinitramfs b/mkinitramfs old mode 100644 new mode 100755 index 637f1d6..f685b54 --- a/mkinitramfs +++ b/mkinitramfs @@ -179,9 +179,8 @@ fi unset COMPRESS if ! command -v "${compress}" >/dev/null 2>&1; then + echo "No ${compress} in ${PATH}, using gzip" compress=gzip - [ "${verbose}" = y ] && \ - echo "No ${compress} in ${PATH}, using gzip" fi case "${compress}" in @@ -193,7 +192,8 @@ gzip) # If we're doing a reproducible build, use gzip -n compress=pigz fi ;; -lz4) compress="lz4 -9 -l" ;; +lz4) compress="lz4 -2 -l" ;; +zstd) compress="zstd -q -1 -T0" ;; xz) compress="xz --check=crc32" # If we're not doing a reproducible build, enable multithreading test -z "${SOURCE_DATE_EPOCH}" && compress="$compress --threads=0" @@ -222,12 +222,16 @@ fi # Prepare to clean up temporary files on exit DESTDIR= __TMPCPIOGZ= +__TMPMAINCPIO= __TMPEARLYCPIO= clean_on_exit() { if [ "${keep}" = "y" ]; then - echo "Working files in ${DESTDIR:-}, early initramfs in ${__TMPEARLYCPIO:-} and overlay in ${__TMPCPIOGZ:-}" + echo "Working files in ${DESTDIR:-}," \ + "early initramfs in ${__TMPEARLYCPIO:-}," \ + "main initramfs in ${__TMPMAINCPIO:-} and" \ + "overlay in ${__TMPCPIOGZ:-}" else - for path in "${DESTDIR}" "${__TMPCPIOGZ}" "${__TMPEARLYCPIO}"; do + for path in "${DESTDIR}" "${__TMPCPIOGZ}" "${__TMPMAINCPIO}" "${__TMPEARLYCPIO}"; do test -z "${path}" || rm -rf "${path}" done fi @@ -240,6 +244,7 @@ trap "exit 1" INT TERM # makes the EXIT trap effective even when killed DESTDIR="$(mktemp -d "${TMPDIR:-/var/tmp}/mkinitramfs_XXXXXX")" || exit 1 chmod 755 "${DESTDIR}" __TMPCPIOGZ="$(mktemp "${TMPDIR:-/var/tmp}/mkinitramfs-OL_XXXXXX")" || exit 1 +__TMPMAINCPIO="$(mktemp "${TMPDIR:-/var/tmp}/mkinitramfs-MAIN_XXXXXX")" || exit 1 __TMPEARLYCPIO="$(mktemp "${TMPDIR:-/var/tmp}/mkinitramfs-FW_XXXXXX")" || exit 1 DPKG_ARCH=$(dpkg --print-architecture) @@ -254,8 +259,8 @@ export DPKG_ARCH export verbose export MODULES export BUSYBOX -export COMPCACHE_SIZE export RESUME +export FSTYPE # Private, used by 'catenate_cpiogz'. export __TMPCPIOGZ @@ -273,10 +278,10 @@ for d in conf/conf.d etc run scripts ${MODULESDIR}; do mkdir -p "${DESTDIR}/${d}" done -# Copy in modules.builtin and modules.order (not generated by depmod) +# Copy in modules.builtin, modules.builtin.modinfo and modules.order (not generated by depmod) # and modules.builtin.bin (generated by depmod, but too late to avoid # error messages as in #948257) -for x in modules.builtin modules.builtin.bin modules.order; do +for x in modules.builtin modules.builtin.bin modules.builtin.modinfo modules.order; do if [ -f "${MODULESDIR}/${x}" ]; then cp -p "${MODULESDIR}/${x}" "${DESTDIR}${MODULESDIR}/${x}" fi @@ -314,6 +319,9 @@ esac # Resolve hidden dependencies hidden_dep_add_modules +# Add firmware for built-in code +add_builtin_firmware + # First file executed by linux cp -p /usr/share/initramfs-tools/init "${DESTDIR}/init" @@ -360,6 +368,9 @@ fi touch "${DESTDIR}/etc/fstab" ln -s /proc/mounts "${DESTDIR}/etc/mtab" +# Install libc6, pthreads, and dlopened gcc_s.so.1 (Debian bug #950254) LP: #1880853 LP: #1958594 +copy_exec /usr/lib/initramfs-tools/bin/gcc_s1-stub /usr/lib/initramfs-tools/bin/gcc_s1-stub + # install wait-for-root binary. copy_exec /usr/lib/initramfs-tools/bin/wait-for-root /sbin @@ -381,6 +392,24 @@ for b in $(cd "${DESTDIR}/scripts" && find . -mindepth 1 -type d); do cache_run_scripts "${DESTDIR}" "/scripts/${b#./}" done +# decompress modules for boot speed, if possible +find "${DESTDIR}/${MODULESDIR}" -name '*.ko.*' | while read -r ko; do + case "$ko" in + *.xz) + if ! command -v xz >/dev/null 2>&1; then + break + fi + xz -d "${ko}" + ;; + *.zst) + if ! command -v zstd >/dev/null 2>&1; then + break + fi + zstd -q -d --rm "${ko}" + ;; + esac +done + # generate module deps depmod -a -b "${DESTDIR}" "${version}" rm -f "${DESTDIR}/lib/modules/${version}"/modules.*map @@ -414,13 +443,6 @@ esac [ "${verbose}" = y ] && echo "Building cpio ${outfile} initramfs" -if [ -s "${__TMPEARLYCPIO}" ]; then - cat "${__TMPEARLYCPIO}" >"${outfile}" || exit 1 -else - # truncate - true > "${outfile}" -fi - ( # preserve permissions if root builds the image, see #633582 [ "$(id -ru)" != 0 ] && cpio_owner_root="-R 0:0" @@ -436,10 +458,9 @@ if [ -n "${SOURCE_DATE_EPOCH}" ]; then fi # work around lack of "set -o pipefail" for the following pipe: -# cd "${DESTDIR}" && find . | LC_ALL=C sort | cpio --quiet $cpio_owner_root $cpio_reproducible -o -H newc | gzip >>"${outfile}" || exit 1 +# cd "${DESTDIR}" && find . | LC_ALL=C sort | cpio --quiet $cpio_owner_root $cpio_reproducible -o -H newc >>"${outfile}" || exit 1 ec1=1 ec2=1 -ec3=1 exec 3>&1 eval "$( # http://cfaj.freeshell.org/shell/cus-faq-2.html @@ -451,26 +472,31 @@ eval "$( LC_ALL=C sort } | { # shellcheck disable=SC2086 - cpio --quiet $cpio_owner_root $cpio_reproducible -o -H newc 4>&-; echo "ec2=$?;" >&4 - } | ${compress} >>"${outfile}" - echo "ec3=$?;" >&4 + cpio --quiet $cpio_owner_root $cpio_reproducible -o -H newc 4>&- >"${__TMPMAINCPIO}" + echo "ec2=$?;" >&4 + } )" if [ "$ec1" -ne 0 ]; then - echo "E: mkinitramfs failure find $ec1 cpio $ec2 $compress $ec3" >&2 + echo "E: mkinitramfs failure find $ec1 cpio $ec2" >&2 exit "$ec1" fi if [ "$ec2" -ne 0 ]; then - echo "E: mkinitramfs failure cpio $ec2 $compress $ec3" >&2 + echo "E: mkinitramfs failure cpio $ec2" >&2 exit "$ec2" fi -if [ "$ec3" -ne 0 ]; then - echo "E: mkinitramfs failure $compress $ec3" >&2 - exit "$ec3" -fi ) || exit 1 -if [ -s "${__TMPCPIOGZ}" ]; then - cat "${__TMPCPIOGZ}" >>"${outfile}" || exit 1 +{ +if [ -s "${__TMPEARLYCPIO}" ]; then + cat "${__TMPEARLYCPIO}" || exit 1 fi +$compress -c "${__TMPMAINCPIO}" || + { echo "E: mkinitramfs failure $compress $?" >&2; exit 1; } + +if [ -s "${__TMPCPIOGZ}" ]; then + cat "${__TMPCPIOGZ}" || exit 1 +fi +} >"${outfile}" || exit 1 + exit 0 diff --git a/scripts/functions b/scripts/functions index 722554e..9f0ab86 100644 --- a/scripts/functions +++ b/scripts/functions @@ -5,6 +5,7 @@ _log_msg() if [ "${quiet?}" = "y" ]; then return; fi # shellcheck disable=SC2059 printf "$@" + return 0 # Prevents error carry over in case of unavailable console } log_success_msg() @@ -35,33 +36,9 @@ log_end_msg() # Add failure hook add_mountroot_fail_hook() { - mkdir -p /tmp/mountroot-fail-hooks.d - ln -s "$0" /tmp/mountroot-fail-hooks.d/"$0" -} - -# Run failure hooks. -# When a failure hook exits "1", it has not done anything to correct the -# system. Exiting "0" means that something has been attempted to resolve -# the lack of a root filesystem. -# Hooks are run in lexigraphical order, and are responsible for removing -# themselves if they should not re-run in a later cycle. When one exits -# "0", the stack is stopped, so the caller can return to the main rootfs -# wait loop. -try_failure_hooks() -{ - local hook - - chvt 1 - if [ -x /bin/plymouth ] && plymouth --ping; then - /bin/plymouth hide-splash > /dev/null 2>&1 - fi - - for hook in /tmp/mountroot-fail-hooks.d/*; do - if [ -x "${hook}" ] && "${hook}" mountfail; then - return 0 - fi - done - return 1 + # DEPRECATED; this definition remains as a stub but any packages + # calling this function should be revised to remove references to it + return 0 } panic() @@ -73,11 +50,30 @@ panic() fi echo "$@" - # Disallow console access + + # The panic= parameter implies we should disallow console access if [ -n "${panic?}" ]; then - echo "Rebooting automatically due to panic= boot argument" - [ "$panic" = "-1" ] || sleep "${panic}" - reboot -f + delay= + case "${panic?}" in + -*[![:digit:].]*) # invalid: wait forever + ;; + -*) # timeout < 0: reboot immediately + delay=0 + ;; + 0 | *[![:digit:].]*) # timeout = 0 or invalid: wait forever + ;; + *) # timeout > 0: seconds before rebooting + delay="${panic}" + ;; + esac + if [ -n "${delay}" ]; then + echo "Rebooting automatically due to panic= boot argument" + sleep "${delay}" + reboot -f + else + echo "Halting automatically due to panic= boot argument" + halt -f + fi exit # in case reboot fails, force kernel panic fi @@ -156,6 +152,25 @@ load_modules() fi } +_uptime() { + local uptime + uptime="$(cat /proc/uptime)" + uptime="${uptime%%[. ]*}" + echo "$uptime" +} + +time_elapsed() { + # shellcheck disable=SC2154 + if [ -z "$starttime" ]; then + log_failure_msg "time_elapsed() called before \$starttime initialized" + echo 0 + fi + local delta + delta="$(_uptime)" + delta=$((delta - starttime)) + echo "$delta" +} + # lilo compatibility parse_numeric() { case $1 in @@ -314,10 +329,17 @@ configure_networking() for v in $VLAN; do VLAN_LINK="$VLAN_LINK ${v##*:}" + VLAN_NAMES="$VLAN_NAMES ${v%:*}" done # activate non-autoconfigured s390x devices for dev in $DEVICE $DEVICE6 $IP6 $VLAN_LINK; do + # do not chzdev $dev if it is a not-yet-created vlan interface + for vlan_name in $VLAN_NAMES; do + if [ "$dev" = "$vlan_name" ]; then + continue 2 + fi + done case ${dev} in enc*) zdev=${dev#enc} @@ -334,6 +356,21 @@ configure_networking() ip link add name "$vname" link "$vlink" type vlan id "$vid" done + if [ -n "${DEVICE}" ]; then + local netdevwait=180 + log_begin_msg "Waiting up to ${netdevwait} secs for ${DEVICE} to become available" + while [ "$(time_elapsed)" -lt "$netdevwait" ]; do + if [ -e "/sys/class/net/${DEVICE}" ]; then + break + fi + sleep 1 + done + if [ ! -e "/sys/class/net/${DEVICE}" ]; then + log_failure_msg "Interface ${DEVICE} did not appear in time" + fi + log_end_msg + fi + wait_for_udev 10 # support ip options see linux sources @@ -487,7 +524,7 @@ mask2cidr() { # Assumes there's no "255." after a non-255 byte in the mask local x=${1##*255.} set -- 0^^^128^192^224^240^248^252^254^ $(( (${#1} - ${#x})*2 )) "${x%%.*}" - x=${1%%$3*} + x=${1%%"$3"*} echo $(( $2 + (${#x}/4) )) } @@ -539,7 +576,6 @@ _render_netplan() { fi echo "network:" echo " version: 2" - echo " renderer: networkd" echo " ethernets:" echo " $name:" if [ -n "$mac" ] && grep -q net.ifnames=0 /proc/cmdline 2>/dev/null; then @@ -566,7 +602,7 @@ _render_netplan() { found="," for n in $addrs; do # remove dups - [ "${found#*,$n,}" = "${found}" ] || continue + [ "${found#*,"$n",}" = "${found}" ] || continue found="${found}$n," echo " - \"$n\"" done @@ -578,7 +614,7 @@ _render_netplan() { local alist="[" slist="" for n in $ns_addrs; do # do not put in duplicates - [ "${alist#*\"$n\"}" = "$alist" ] || continue + [ "${alist#*\""$n"\"}" = "$alist" ] || continue alist="${alist}\"$n\", "; done alist="${alist%, }]" @@ -587,7 +623,7 @@ _render_netplan() { slist="[" for n in ${ns_search}; do # do not put in duplicates - [ "${slist#*\"$n\"}" = "$slist" ] || continue + [ "${slist#*\""$n"\"}" = "$slist" ] || continue slist="${slist}\"$n\", "; done slist="${slist%, }]" @@ -826,11 +862,13 @@ _checkfs_once() if [ "${quiet}" = n ] then log_begin_msg "Will now check $NAME file system" + # shellcheck disable=SC2086 logsave -a -s $FSCK_LOGFILE fsck $spinner $force $fix -V -t "$TYPE" "$DEV" FSCKCODE=$? log_end_msg else log_begin_msg "Checking $NAME file system" + # shellcheck disable=SC2086 logsave -a -s $FSCK_LOGFILE fsck $spinner $force $fix -T -t "$TYPE" "$DEV" FSCKCODE=$? log_end_msg diff --git a/scripts/local b/scripts/local index f2d6e15..38f6021 100644 --- a/scripts/local +++ b/scripts/local @@ -8,14 +8,6 @@ local_top() [ "$quiet" != "y" ] && log_end_msg fi local_top_used=yes - - # Start time for measuring elapsed time in local_device_setup - if [ -z "${local_top_time}" ]; then - local_top_time="$(cat /proc/uptime)" - local_top_time="${local_top_time%%[. ]*}" - local_top_time=$((local_top_time + 1)) # round up - export local_top_time - fi } local_block() @@ -44,7 +36,6 @@ local_bottom() fi local_premount_used=no local_top_used=no - unset local_top_time } # $1=device ID to mount @@ -115,15 +106,14 @@ local_device_setup() while true; do sleep 1 - time_elapsed="$(cat /proc/uptime)" - time_elapsed="${time_elapsed%%[. ]*}" - time_elapsed=$((time_elapsed - local_top_time)) + time_elapsed="$(time_elapsed)" local_block "${dev_id}" # If mdadm's local-block script counts the # number of times it is run, make sure to # run it the expected number of times. + mdadm_exec=0 while true; do if [ -f /run/count.mdadm.initrd ]; then count="$(cat /run/count.mdadm.initrd)" @@ -134,19 +124,42 @@ local_device_setup() else break fi - if [ ${count} -ge ${time_elapsed} ]; then + if [ "${count}" -ge "${time_elapsed}" ]; then break; fi + + # Track that mdadm was executed to force + # cryptroot execution after the loop, see + # LP #1879980. + mdadm_exec=1 /scripts/local-block/mdadm "${dev_id}" + + # Cryptroot must run here, see LP #1879980. + # The counter is inc/dec on cryptroot script! + if [ -f /run/cryptroot.initrd.cnt ]; then + crypt_cnt=$(cat /run/cryptroot.initrd.cnt) + if [ "${crypt_cnt}" -gt 0 ]; then + /scripts/local-block/cryptroot "${dev_id}" + fi + fi done + # Extra cryptroot run after mdadm loop in order to + # start encrypted volumes on top of RAID arrays. + if [ -f /run/cryptroot.initrd.cnt ]; then + crypt_cnt=$(cat /run/cryptroot.initrd.cnt) + if [ "${crypt_cnt}" -gt 0 ] || [ ${mdadm_exec} -ne 0 ]; then + /scripts/local-block/cryptroot "${dev_id}" + fi + fi + if real_dev=$(resolve_device "${dev_id}") && get_fstype "${real_dev}" >/dev/null; then wait_for_udev 10 log_end_msg 0 break fi - if [ ${time_elapsed} -ge "${slumber}" ]; then + if [ "${time_elapsed}" -ge "${slumber}" ]; then log_end_msg 1 || true break fi @@ -229,6 +242,7 @@ able to reboot again and resume the installation. done # Get the loop filesystem type if not set + # shellcheck disable=SC2153 FSTYPE="$LOOPFSTYPE" if [ -z "$FSTYPE" ] || [ "$FSTYPE" = "unknown" ]; then FSTYPE=$(/sbin/blkid -s TYPE -o value "/host/${LOOP#/}") diff --git a/scripts/local-premount/fixrtc b/scripts/local-premount/fixrtc index bcc0b55..422b02f 100755 --- a/scripts/local-premount/fixrtc +++ b/scripts/local-premount/fixrtc @@ -79,17 +79,19 @@ if [ -n "$BROKEN_CLOCK" ] && [ -n "$ROOTDEV" ]; then # need udev settle for /dev/disk/by-* symlinks to be added udevadm settle - wait-for-root "$ROOTDEV" "${ROOTDELAY:-180}" + wait-for-root "$ROOTDEV" "${ROOTDELAY:-180}" >/dev/null ROOTDISK=$(readlink -f "$ROOTDEV") MOUNTDATESTR=$(dumpe2fs -h "$ROOTDISK" 2>/dev/null|grep "Last mount time") # Trim whitespace for busybox MOUNTDATE="${MOUNTDATESTR#*:}" + MOUNTDATE="${MOUNTDATE#"${MOUNTDATE%%[![:space:]]*}"}" CREATEDATESTR=$(dumpe2fs -h "$ROOTDISK" 2>/dev/null|grep "Filesystem created") || true # Trim whitespace for busybox CREATEDATE="${CREATEDATESTR#*:}" + CREATEDATE="${CREATEDATE#"${CREATEDATE%%[![:space:]]*}"}" # Hide stderr to avoid ugly message: # can't open '/dev/misc/rtc': No such file or directory @@ -100,7 +102,7 @@ if [ -n "$BROKEN_CLOCK" ] && [ -n "$ROOTDEV" ]; then # make sure we're also compatible with busybox, if available DATE="/bin/date -D%c" - date -D%c 2>/dev/null || DATE=/bin/date + date -D%c 2>/dev/null 2>&1 || DATE=/bin/date if [ "$MOUNTDATE" = "n/a" ]; then # some versions of mkfs set n/a now, date is not happy with this so diff --git a/scripts/local-premount/resume b/scripts/local-premount/resume index 272a728..6bd98e8 100755 --- a/scripts/local-premount/resume +++ b/scripts/local-premount/resume @@ -32,7 +32,7 @@ if ! local_device_setup "${resume}" "suspend/resume device" false; then exit 0 fi -DEV=$(readlink "$resume") +DEV=$(readlink -f "$resume") DEV=/sys/class/block/${DEV##*/}/dev if [ -r "$DEV" ]; then read -r MAJMIN < "$DEV" diff --git a/scripts/nfs b/scripts/nfs index 40c92c7..06b140f 100644 --- a/scripts/nfs +++ b/scripts/nfs @@ -39,7 +39,7 @@ nfs_mount_root_impl() configure_networking # get nfs root from dhcp - if [ "x${NFSROOT}" = "xauto" ]; then + if [ "${NFSROOT}" = "auto" ]; then # check if server ip is part of dhcp root-path if [ "${ROOTPATH#*:}" = "${ROOTPATH}" ]; then NFSROOT=${ROOTSERVER}:${ROOTPATH} diff --git a/src/Makefile b/src/Makefile index c7ac39e..fed7abd 100644 --- a/src/Makefile +++ b/src/Makefile @@ -8,14 +8,14 @@ LDFLAGS = .PHONY: all -all: wait-for-root rzscontrol +all: wait-for-root gcc_s1-stub wait-for-root: wait-for-root.o $(CC) $(LDFLAGS) -o $@ $< $(UDEV_LIBS) -rzscontrol: rzscontrol.o - $(CC) $(LDFLAGS) -o $@ $< +gcc_s1-stub: + gcc -Wl,--no-as-needed -shared -l:libpthread.so.0 -l:libgcc_s.so.1 -o $@ .PHONY: clean clean: - rm -f wait-for-root.o wait-for-root rzscontrol.o rzscontrol core *~ + rm -f wait-for-root.o wait-for-root gcc_s1-stub core *~ diff --git a/tests/test_netinfo.d/ipv4/netplan/example1.yaml b/tests/test_netinfo.d/ipv4/netplan/example1.yaml index 0dc0b4f..fabdccb 100644 --- a/tests/test_netinfo.d/ipv4/netplan/example1.yaml +++ b/tests/test_netinfo.d/ipv4/netplan/example1.yaml @@ -1,6 +1,5 @@ network: version: 2 - renderer: networkd ethernets: example1: dhcp4: true diff --git a/tests/test_netinfo.d/ipv4and6/netplan/example1.yaml b/tests/test_netinfo.d/ipv4and6/netplan/example1.yaml index 258a1c6..8460f06 100644 --- a/tests/test_netinfo.d/ipv4and6/netplan/example1.yaml +++ b/tests/test_netinfo.d/ipv4and6/netplan/example1.yaml @@ -1,6 +1,5 @@ network: version: 2 - renderer: networkd ethernets: example1: dhcp4: true diff --git a/tests/test_netinfo.d/ipv4static/netplan/example1.yaml b/tests/test_netinfo.d/ipv4static/netplan/example1.yaml index 00aef41..bf671af 100644 --- a/tests/test_netinfo.d/ipv4static/netplan/example1.yaml +++ b/tests/test_netinfo.d/ipv4static/netplan/example1.yaml @@ -1,6 +1,5 @@ network: version: 2 - renderer: networkd ethernets: example1: addresses: diff --git a/tests/test_netinfo.d/ipv6/netplan/example1.yaml b/tests/test_netinfo.d/ipv6/netplan/example1.yaml index 915b478..e355d2b 100644 --- a/tests/test_netinfo.d/ipv6/netplan/example1.yaml +++ b/tests/test_netinfo.d/ipv6/netplan/example1.yaml @@ -1,6 +1,5 @@ network: version: 2 - renderer: networkd ethernets: example1: dhcp6: true diff --git a/tests/test_netinfo.d/vlan/netplan/example1.1.yaml b/tests/test_netinfo.d/vlan/netplan/example1.1.yaml index e83f85f..c4fd269 100644 --- a/tests/test_netinfo.d/vlan/netplan/example1.1.yaml +++ b/tests/test_netinfo.d/vlan/netplan/example1.1.yaml @@ -1,6 +1,5 @@ network: version: 2 - renderer: networkd ethernets: example1: {} diff --git a/unmkinitramfs b/unmkinitramfs old mode 100644 new mode 100755 index 3f8c75d..a966a45 --- a/unmkinitramfs +++ b/unmkinitramfs @@ -31,6 +31,8 @@ xcpio() if gzip -t "$archive" >/dev/null 2>&1 ; then gzip -c -d "$archive" + elif zstd -q -c -t "$archive" >/dev/null 2>&1 ; then + zstd -q -c -d "$archive" elif xzcat -t "$archive" >/dev/null 2>&1 ; then xzcat "$archive" elif lz4cat -t < "$archive" >/dev/null 2>&1 ; then @@ -110,6 +112,7 @@ splitinitramfs() fi dd < "$initramfs" skip=$start count=$((end - start)) iflag=skip_bytes 2> /dev/null | ( + # shellcheck disable=SC2030 if [ -n "$dir" ]; then mkdir -p -- "$dir/$subdir" cd -- "$dir/$subdir" @@ -125,9 +128,11 @@ splitinitramfs() trap 'rm -f "$subarchive"' EXIT dd < "$initramfs" skip=$end iflag=skip_bytes 2> /dev/null \ > "$subarchive" + # shellcheck disable=SC2030,SC2031 xcpio "$subarchive" "${dir:+$dir/main}" -i "$@" else # Don't use subdirectories (for backward compatibility) + # shellcheck disable=SC2031 xcpio "$initramfs" "$dir" -i "$@" fi } diff --git a/update-initramfs b/update-initramfs old mode 100644 new mode 100755 index 3c1d9c4..c67ca8e --- a/update-initramfs +++ b/update-initramfs @@ -1,6 +1,5 @@ #!/bin/sh -STATEDIR=/var/lib/initramfs-tools BOOTDIR=/boot CONF=/etc/initramfs-tools/update-initramfs.conf mode="" @@ -12,26 +11,12 @@ set -e [ -r ${CONF} ] && . ${CONF} -case "$DPKG_MAINTSCRIPT_PACKAGE" in -linux-image-*) - if [ -z "$INITRAMFS_TOOLS_KERNEL_HOOK" ]; then - # kernel maintainer script called us directly; ignore - # it and let the hook script handle it instead - echo "update-initramfs: deferring update (hook will be called later)" +if [ -n "$DPKG_MAINTSCRIPT_PACKAGE" ] && [ $# = 1 ] && [ "$1" = '-u' ]; then + if dpkg-trigger --no-await update-initramfs; then + echo "update-initramfs: deferring update (trigger activated)" exit 0 fi - ;; -?*) - if [ $# = 1 ] \ - && [ x"$1" = x-u ] - then - if dpkg-trigger --no-await update-initramfs; then - echo "update-initramfs: deferring update (trigger activated)" - exit 0 - fi - fi - ;; -esac +fi usage() { @@ -156,7 +141,6 @@ generate_initramfs() # shellcheck disable=SC2086 if mkinitramfs ${OPTS} "${initramfs}.new" "${version}"; then mv -f "${initramfs}.new" "${initramfs}" - set_sha1 # Guard against an unclean shutdown sync -f "${initramfs}" else @@ -173,23 +157,12 @@ run_bootloader() { # invoke policy conformant bootloader hooks if [ -d /etc/initramfs/post-update.d/ ]; then - run-parts --arg=${version} --arg=${initramfs} \ + run-parts --arg="${version}" --arg="${initramfs}" \ /etc/initramfs/post-update.d/ return 0 fi } -# 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() { @@ -317,8 +290,6 @@ delete() echo "update-initramfs: Deleting ${initramfs}" - delete_sha1 - rm -f "${initramfs}" "${initramfs}.bak" }