diff --git a/factory/usr/lib/core/extra-paths b/factory/usr/lib/core/extra-paths index 70b2877a..8b1401f2 100755 --- a/factory/usr/lib/core/extra-paths +++ b/factory/usr/lib/core/extra-paths @@ -4,6 +4,4 @@ set -eu cat <>/sysroot/etc/fstab /run/mnt/data /writable none bind,x-initrd.mount 0 0 -/run/mnt/kernel/firmware /usr/lib/firmware none bind,x-initrd.mount 0 0 -/run/mnt/kernel/modules /usr/lib/modules none bind,x-initrd.mount 0 0 EOF diff --git a/factory/usr/lib/core/kernel-mounts b/factory/usr/lib/core/kernel-mounts new file mode 100755 index 00000000..7ad25acb --- /dev/null +++ b/factory/usr/lib/core/kernel-mounts @@ -0,0 +1,81 @@ +#!/bin/sh + +set -eux + +# Prepare kernel modules/firmware tree if it does not exist + +ksnap_d=/run/mnt/kernel +core=false +data_d=/run/mnt/data +if [ -d /run/mnt/base ]; then + core=true + data_d=/run/mnt/data/system-data +fi + +kernelVer= +for f in "$ksnap_d"/System.map-*; do + kernelVer=${f##"$ksnap_d"/System.map-} +done +mod_root_d="$data_d"/usr/lib/modules +mod_d="$mod_root_d"/"$kernelVer" +ksnap_mod_d="$ksnap_d"/modules/"$kernelVer" + +if [ ! -d "$mod_d" ]; then + for d in initrd kernel vdso updates; do + mkdir -p "$mod_d"/"$d" + done + # Copy modinfo files + cp "$ksnap_mod_d"/modules.* "$mod_d" +fi + +fw_root_d="$data_d"/usr/lib/firmware/updates +mkdir -p "$fw_root_d" + +sysinit_wants=/run/systemd/system/sysinit.target.wants +mkdir -p "$sysinit_wants" + +conf_mount_dir() { + what=$1 + where=$2 + options=$3 + before_deps= + if [ $# -gt 3 ]; then + before_deps=$4 + fi + + unit=$(systemd-escape -p --suffix=mount "$where") + unit_path=/run/systemd/system/"$unit" + cat < "$unit_path" +[Unit] +ConditionPathExists=!/etc/initrd-release +DefaultDependencies=no +After=systemd-remount-fs.service +Before=systemd-udev.service systemd-modules-load.service $before_deps +Before=sysinit.target +Before=umount.target +Conflicts=umount.target + +[Mount] +What=$what +Options=$options +EOF + + ln -s "$unit_path" "$sysinit_wants"/"$unit" +} + +mod_unit_dep= +if [ "$core" = true ]; then + # For classic we are actually working on the rootfs, for core + # we need to bind mount to the base that is the rootfs. + mod_where=/usr/lib/modules + mod_unit_dep=$(systemd-escape -p --suffix=mount "$mod_where") + conf_mount_dir "$mod_root_d" "$mod_where" rbind,ro +fi +conf_mount_dir "$ksnap_mod_d"/kernel "$mod_d"/kernel bind,ro "$mod_unit_dep" +conf_mount_dir "$ksnap_mod_d"/vdso "$mod_d"/vdso bind,ro "$mod_unit_dep" + +fw_where=/usr/lib/firmware +fw_unit=$(systemd-escape -p --suffix=mount "$fw_where") +conf_mount_dir "$ksnap_d"/firmware "$fw_where" rbind,ro +# Note that this will fail if the kernel snap does not have a firmware/updates dir +conf_mount_dir "$fw_root_d" /usr/lib/firmware/updates rbind,ro "$fw_unit" diff --git a/factory/usr/lib/systemd/system-generators/kernel-snap-generator b/factory/usr/lib/systemd/system-generators/kernel-snap-generator deleted file mode 100755 index e9b8dcf4..00000000 --- a/factory/usr/lib/systemd/system-generators/kernel-snap-generator +++ /dev/null @@ -1,57 +0,0 @@ -#!/bin/sh - -set -eu - -: "${KERNEL_MNT_POINT:=/run/mnt/kernel}" - -if ! mountpoint -q "${KERNEL_MNT_POINT}"; then - exit 0 -fi - -# FIXME use SYSTEMD_IN_INITRD when using systemd 251+ -if [ -f /etc/initrd-release ]; then - sysroot=/sysroot - sysroot_unit=sysroot - target=initrd-fs.target -else - sysroot= - sysroot_unit= - target=local-fs.target -fi - -: "${OS_RELEASE:="${sysroot}/etc/os-release"}" - -# Note that /sysroot/etc/os-release is accessible when generators are -# re-executed due to "daemon-reload" called by -# initrd-parse-etc.service - -# We generate the kernel bind mount units only -# if we are on Ubuntu Classic - -# Ubuntu Core will have those mounts declared in /etc/fstab, thus -# using systemd-fstab-generator instead. - -if ! grep -q "^ID=ubuntu$" "${OS_RELEASE}"; then - exit 0 -fi - -for entry in firmware modules; do - what="${KERNEL_MNT_POINT}/${entry}" - where="${sysroot}/usr/lib/${entry}" - unit="usr-lib-${entry}.mount" - if [ -n "${sysroot_unit}" ]; then - unit="${sysroot_unit}-${unit}" - fi - mkdir -p "${1}/${target}.requires" - ln -sf "../${unit}" "${1}/${target}.requires/${unit}" - cat <"${1}/${unit}" -[Unit] -Before=${target} - -[Mount] -What=${what} -Where=${where} -Options=bind -Type=none -EOF -done diff --git a/factory/usr/lib/systemd/system/classic-mounts.service b/factory/usr/lib/systemd/system/classic-mounts.service index d5f46931..1df74275 100644 --- a/factory/usr/lib/systemd/system/classic-mounts.service +++ b/factory/usr/lib/systemd/system/classic-mounts.service @@ -11,6 +11,5 @@ Before=initrd-fs.target [Service] Type=oneshot -# We force re-running kernel-snap-generator -ExecStart=systemctl daemon-reload +ExecStart=/usr/lib/core/kernel-mounts StandardError=journal+console diff --git a/factory/usr/lib/systemd/system/detect-classic-sysroot.service b/factory/usr/lib/systemd/system/detect-classic-sysroot.service index c80e7908..5c202590 100644 --- a/factory/usr/lib/systemd/system/detect-classic-sysroot.service +++ b/factory/usr/lib/systemd/system/detect-classic-sysroot.service @@ -3,7 +3,6 @@ Description=Detect Ubuntu classic sysroot DefaultDependencies=no Before=initrd-root-device.target After=snap-initramfs-mounts.service -Wants=classic-mounts.service ConditionPathIsMountPoint=!/run/mnt/base @@ -11,3 +10,4 @@ ConditionPathIsMountPoint=!/run/mnt/base Type=oneshot RemainAfterExit=yes ExecStart=/bin/ln -s data /run/mnt/sysroot +ExecStart=/usr/lib/core/kernel-mounts diff --git a/factory/usr/lib/systemd/system/populate-writable.service b/factory/usr/lib/systemd/system/populate-writable.service index 764ff8fd..bc5e0c55 100644 --- a/factory/usr/lib/systemd/system/populate-writable.service +++ b/factory/usr/lib/systemd/system/populate-writable.service @@ -25,3 +25,4 @@ ExecStart=/usr/bin/chroot /sysroot /usr/lib/core/handle-writable-paths / /etc/sy # TODO:UC20: move the-modeenv implementation to snap-bootstrap too ExecStart=/usr/lib/the-modeenv ExecStart=/usr/lib/core/extra-paths +ExecStart=/usr/lib/core/kernel-mounts