From 2312598ba51500cf947ba27368b910d9b30ab5c6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ladislav=20Slez=C3=A1k?= Date: Thu, 28 Nov 2024 10:16:07 +0100 Subject: [PATCH] Live: less aggressive kernel driver cleanup Keep the multimedia drivers which are needed as dependencies of other drivers (usually graphic card drivers) (gh#agama-project/agama#1665) --- live/Makefile | 3 +- live/root/tmp/driver_cleanup.rb | 93 ++++++++++++++++++++++++++++++++ live/src/agama-installer.changes | 7 +++ live/src/config.sh | 9 ++-- 4 files changed, 107 insertions(+), 5 deletions(-) create mode 100755 live/root/tmp/driver_cleanup.rb diff --git a/live/Makefile b/live/Makefile index fdec9d7b13..cb1535e0d9 100644 --- a/live/Makefile +++ b/live/Makefile @@ -14,6 +14,7 @@ FLAVOR = openSUSE # the default OBS project, # to use a different project run "make build OBS_PROJECT=" OBS_PROJECT = "systemsmanagement:Agama:Devel" +OBS_PACKAGE = "agama-installer" # files to copy from src/ COPY_FILES = $(patsubst $(SRCDIR)/%,$(DESTDIR)/%,$(wildcard $(SRCDIR)/*)) @@ -52,7 +53,7 @@ $(DESTDIR)/%.tar.xz: % $$(shell find % -type f,l) # build the ISO locally build: $(DESTDIR) - if [ ! -e $(DESTDIR)/.osc ]; then make clean; osc co -o $(DESTDIR) $(OBS_PROJECT) agama-installer-openSUSE; fi + if [ ! -e $(DESTDIR)/.osc ]; then make clean; osc co -o $(DESTDIR) $(OBS_PROJECT) $(OBS_PACKAGE); fi $(MAKE) all (cd $(DESTDIR) && osc build -M $(FLAVOR) images) diff --git a/live/root/tmp/driver_cleanup.rb b/live/root/tmp/driver_cleanup.rb new file mode 100755 index 0000000000..d122a4f68d --- /dev/null +++ b/live/root/tmp/driver_cleanup.rb @@ -0,0 +1,93 @@ +#! /usr/bin/env ruby + +# This script removes not needed multimedia drivers (sound cards, TV cards,...). +# +# By default the script runs in safe mode and only lists the drivers to delete, +# use the "--delete" argument to really delete the drivers. + +require "find" +require "shellwords" + +# class holding the kernel driver data +class Driver + # the driver name, full file path, dependencies + attr_reader :name, :path, :deps + + def initialize(name, path, deps) + @name = name + @path = path + @deps = deps + end + + # load the kernel driver data from the given path recursively + def self.find(dir) + drivers = [] + puts "Scanning kernel modules in #{dir}..." + + return drivers unless File.directory?(dir) + + Find.find(dir) do |path| + if File.file?(path) && path.end_with?(".ko", ".ko.xz", ".ko.zst") + name = File.basename(path).sub(/\.ko(\.xz|\.zst|)\z/, "") + deps = `/usr/sbin/modinfo -F depends #{path.shellescape}`.chomp.split(",") + drivers << Driver.new(name, path, deps) + end + end + + return drivers + end +end + +# delete the kernel drivers in these subdirectories, but keep the drivers used by +# dependencies from other drivers +delete = [ + "kernel/sound", + "kernel/drivers/media", + "kernel/drivers/staging/media" +] + +# in the Live ISO there should be just one kernel installed +dir = Dir["/lib/modules/*"].first + +# drivers to delete +delete_drivers = [] + +# scan the drivers in the delete subdirectories +delete.each do |d| + delete_drivers += Driver.find(File.join(dir, d)) +end + +all_drivers = Driver.find(dir) + +# remove the possibly deleted drivers +all_drivers.reject!{|a| delete_drivers.any?{|d| d.name == a.name}} + +puts "Skipping dependent drivers:" + +# iteratively find the dependant drivers (dependencies of dependencies...) +loop do + referenced = delete_drivers.select do |dd| + all_drivers.any?{|ad| ad.deps.include?(dd.name)} + end + + # no more new dependencies, end of the dependency chain reached + break if referenced.empty? + + puts referenced.map(&:path).sort.join("\n") + + # move the referenced drivers from the "delete" list to the "keep" list + all_drivers += referenced + delete_drivers.reject!{|a| referenced.any?{|d| d.name == a.name}} +end + +puts "Drivers to delete:" +delete = ARGV[0] == "--delete" + +delete_drivers.each do |d| + if (delete) + puts "Deleting #{d.path}" + File.delete(d.path) + else + puts d.path + end +end diff --git a/live/src/agama-installer.changes b/live/src/agama-installer.changes index 1f62f5f957..71d025fd50 100644 --- a/live/src/agama-installer.changes +++ b/live/src/agama-installer.changes @@ -1,3 +1,10 @@ +------------------------------------------------------------------- +Thu Nov 28 08:58:21 UTC 2024 - Ladislav Slezák + +- Less aggressive kernel driver cleanup, keep the multimedia + drivers which are needed as dependencies of other drivers + (usually graphic card drivers) (gh#agama-project/agama#1665) + ------------------------------------------------------------------- Wed Nov 13 12:20:23 UTC 2024 - Lubos Kocman diff --git a/live/src/config.sh b/live/src/config.sh index bd42866886..24605fedec 100644 --- a/live/src/config.sh +++ b/live/src/config.sh @@ -160,10 +160,11 @@ rpm -e --nodeps alsa alsa-utils alsa-ucm-conf || true # and remove the drivers for sound cards and TV cards instead. Those do not # make sense on a server. du -h -s /lib/modules /lib/firmware -# delete sound drivers -rm -rfv /lib/modules/*/kernel/sound -# delete TV cards and radio cards -rm -rfv /lib/modules/*/kernel/drivers/media/ + +# remove the multimedia drivers +/tmp/driver_cleanup.rb --delete +# remove the script, not needed anymore +rm /tmp/driver_cleanup.rb # remove the unused firmware (not referenced by kernel drivers) /tmp/fw_cleanup.rb --delete