1
0

Accepting request 647026 from Base:System

- Update to version 15.0.1 (git 5c63319):
- Use /etc/modules-load.d/sg.conf for sg driver autoloading
  (bsc#1036463)
  * added /etc/modules-load.d/sg.conf (forwarded request 647025 from mwilck)

OBS-URL: https://build.opensuse.org/request/show/647026
OBS-URL: https://build.opensuse.org/package/show/openSUSE:Factory/suse-module-tools?expand=0&rev=23
This commit is contained in:
Dominique Leuenberger 2018-11-19 22:27:53 +00:00 committed by Git OBS Bridge
commit 5d99db34a7
18 changed files with 161 additions and 2281 deletions

View File

@ -1,10 +0,0 @@
#
# Every kernel module has a flag 'supported'. If this flag is not set loading
# this module will taint your kernel. You will not get much help with a kernel
# problem if your kernel is marked as tainted. In this case you firstly have
# to avoid loading of unsupported modules.
#
# Setting allow_unsupported_modules 1 enables loading of unsupported modules
# by modprobe, setting allow_unsupported_modules 0 disables it. This can
# be overriden using the --allow-unsupported-modules commandline switch.
allow_unsupported_modules 1

View File

@ -1,5 +0,0 @@
[Unit]
RequiresMountsFor=/boot
[Service]
ExecStartPre=-/usr/lib/systemd/systemd-sysctl /boot/sysctl.conf-%v

View File

@ -1,19 +0,0 @@
Please don't edit /etc/modprobe.conf. Place your settings into
/etc/modprobe.conf.local instead.
To avoid loading backup files of various tools and editors, modprobe skips
files under /etc/modprobe.d/ that have the following prefixes
"."
"~"
and the following suffixes
".rpmsave"
".rpmorig"
".rpmnew"
".bak"
".YaST2save"
".-"
"~"

16
_service Normal file
View File

@ -0,0 +1,16 @@
<services>
<service mode="disabled" name="tar_scm">
<param name="url">https://github.com/openSUSE/suse-module-tools.git</param>
<param name="scm">git</param>
<param name="changesgenerate">enable</param>
<param name="filename">suse-module-tools</param>
<param name="version">15.0.1</param>
<param name="revision">15.0.1</param>
<param name="exclude">*.spec</param>
<param name="exclude">*.rpmlintrc</param>
</service>
<service mode="disabled" name="recompress">
<param name="file">*.tar</param>
<param name="compression">xz</param>
</service>
</services>

4
_servicedata Normal file
View File

@ -0,0 +1,4 @@
<servicedata>
<service name="tar_scm">
<param name="url">https://github.com/openSUSE/suse-module-tools.git</param>
<param name="changesrevision">5c6331938afd2e9250b60450d458bd9297f0d2cf</param></service></servicedata>

View File

@ -1,18 +0,0 @@
#
# /etc/depmod.conf - configuration file for the depmod(8) command,
# for its format see depmod.conf(5).
#
# Please don't edit this file, place your settings into the /etc/depmod.d
# directory.
# search order:
# 1 updates/ (KMPs)
# 2 extra/ (KMPs or manually compiled modules)
# 3 weak-updates/ (KMPs built for older kernels)
# 4 kgraft/ (kgraft patches)
# 5 everything else
search updates extra weak-updates kgraft built-in
# do not generate modules.*map files
make_map_files no

View File

@ -1,314 +0,0 @@
#!/bin/bash
VERSION="0.5"
MAINTAINER="Michal Marek <mmarek@suse.cz>"
USAGE="Usage: ${0##*/} [-o|--out output-file]"
errors=0
warnings=0
trap 'rm -rf "$tmp"' EXIT
tmp=$(mktemp -d)
rpm()
{
# rpm tends to send localized error messages to stdout :-(
LC_ALL=C command rpm "$@"
}
file_owner()
{
local f=$1
if (cd "$tmp/rpms"; grep -lFx "$f" *); then
return
fi
rpm -qf "$f"
}
_explain_called=()
explain()
{
local caller=${BASH_LINENO[0]}
if test -n "${_explain_called[$caller]}"; then
return
fi
_explain_called[$caller]=1
echo "$*"
}
error()
{
echo "ERROR: $*"
let errors++
}
warning()
{
echo "warning: $*" >&2
let warnings++
}
check_system()
{
if test ! -x /usr/lib/module-init-tools/weak-modules2; then
echo "This tool only works on SLE11 and later systems" >&2
exit 1
fi
if ! zypper search >/dev/null; then
echo "Cannot run zypper, please correct the above problem" >&2
exit 1
fi
}
check_rpm()
{
local rpm=$1 name=${1%-*-*}
# ignore changes to %config and %doc files and ignore changed mtimes
if rpm -V "$rpm" | grep -Ev '^[^ ]{8,} [cd] |^\.{7}T\.* '; then
error "$rpm was not installed correctly (see above)"
fi
# this is ugly. Apparently zypper insist on the progress messages and
# the ascii table, so grep for the table row.
if ! LC_ALL=C zypper -A search -t package -u -s --match-exact "$name" \
| grep -qe ---; then
error "$rpm: no update repositories found"
fi
}
check_kernel_package()
{
local kernel=$1
if ! rpm -q --qf '%{description}\n' "$kernel" | grep -q '^GIT '; then
error "$kernel does not look like a SUSE kernel package (no commit id)"
fi
if ! rpm -q --qf '%{postin}\n' "$kernel" | grep -q 'weak-modules2'; then
error "$kernel does not look like a SUSE kernel package (wrong %post script)"
fi
}
check_krel()
{
local krel=$1 system_map module_symvers msg res args bad=false
local mit_version
system_map="/boot/System.map-$krel"
module_symvers="/boot/symvers-$krel.gz"
if ! test -e "$system_map"; then
error "$system_map not found"
bad=true
fi
if ! test -e "$module_symvers"; then
error "$module_symvers not found"
bad=true
fi
if $bad; then
explain "Each kernel must install /boot/System.map-\$version and /boot/symvers-\$version.gz to be able to check module dependencies."
return
fi
set -- $(/sbin/depmod --version | sed -rn 's/.* ([0-9]+)\.([0-9]+)(\..*)?/\1 \2/p')
if test -n "$1" -a -n "$2"; then
let "mit_version = $1 * 100 + $2"
else
warning "Cannot determine module-init-tools version, this is a bug in the script"
mit_version=0
fi
# depmod -E was introduced in 3.10
if test "$mit_version" -ge 310; then
gzip -cd <"$module_symvers" >"$tmp/symvers"
args=(-E "$tmp/symvers")
else
args=(-F "$system_map")
fi
msg=$(/sbin/depmod -n -e "${args[@]}" "$krel" 2>&1 >/dev/null)
res=$?
if test -n "$msg" -o "$res" -ne 0; then
echo "$msg"
error "depmod $krel returned errors (exit code $res)"
explain "depmod must pass without errors otherwise KMP scripts will break"
fi
}
req_re='^(kernel\([^:]*:kernel[[:alnum:]_]*\)|ksym\([^:]*:(struct_module|module_layout)\)) = [0-9a-f]+'
check_kmp()
{
local kmp=$1 prefix prev_krel krel path found_module=false
if ! rpm -q --qf '%{postin}\n' "$kmp" | grep -q 'weak-modules2'; then
error "$kmp does not look like a SUSE kernel module package (wrong %post)"
fi
if ! rpm -q -R "$kmp" | grep -Eq "$req_re"; then
error "$kmp does not have proper dependencies"
fi
exec 3< <(sed -rn 's:^(/lib/modules)?/([^/]*)/(.*\.ko)$:\1 \2 \3:p' \
"$tmp/rpms/$kmp")
while read prefix krel path <&3; do
found_module=true
if test "$prefix" != "/lib/modules"; then
error "$kmp installs modules outside of /lib/modules"
continue
fi
if test -z "$prev_krel"; then
prev_krel=$krel
elif test "$prev_krel" != "$krel"; then
error "$kmp installs modules for multiple kernel versions"
fi
case "$path" in
updates/* | extra/*)
;;
weak-updates/*)
error "$kmp installs modules in weak-updates/ instead of updates/ or extra/"
explain "The weak-modules directory is reserved for automatically generated symlinks"
;;
*)
error "$kmp installs modules in an invalid directory"
explain \
"KMPs must install modules in the updates/ or extra/ subdirectories for the
weak-modules2 script to work"
;;
esac
done
if ! $found_module; then
error "$kmp does not contain any modules"
explain \
"A KMP must contain it's modules in the rpm filelist, otherwise weak-modules2
will not work"
fi
}
check_ko()
{
local ko=$1 kmp bad=false
case "$ko" in
*/weak-updates/*)
if test -L "$ko"; then
return
fi
esac
kmp=$(file_owner "$ko")
case "$kmp" in
kernel-* | *-kmp-*) ;;
*not\ owned\ by\ any\ package)
error "$ko is not owned by any package"
bad=true
;;
*)
error "$ko is not packaged as a KMP"
bad=true
;;
esac
if $bad; then
explain \
"External kernel modules must be packaged as KMPs, see
http://developer.novell.com/wiki/index.php/Kernel_Module_Packages_Manuals"
fi
}
options=$(getopt -n "${0##*/}" -o o:h --long out:,help -- "$@")
if test "$?" -ne 0; then
echo "$USAGE" >&2
exit 1
fi
eval set -- "$options"
logfile="driver-check-report.txt"
while :; do
case "$1" in
-o | --out)
logfile="$2"
shift 2
;;
-h | --help)
echo "${0##*/} $VERSION"
echo "$USAGE"
echo
echo "Please report bugs and enhancement requests to $MAINTAINER"
exit 0
;;
--)
shift
break
;;
esac
done
if test $# -gt 0; then
echo "Unrecognized arguments: $*" >&2
echo "$USAGE" >&2
exit 1
fi
check_system
# set up redirection
if test $logfile != "-"; then
if test -e "$logfile"; then
mv -f "$logfile" "$logfile~"
fi
if test -e /proc/self; then
exec 99> >(cat >"$logfile")
exec 1>&99
exec 2> >(tee -a /proc/self/fd/99 >&2)
else
exec 1>"$logfile"
exec 2>"$logfile"
warning "/proc not mounted"
fi
fi
echo "${0##*/} $VERSION started at $(date -R)" >&2
check_rpm $(rpm -q --qf '%{n}-%{v}-%{r}\n' module-init-tools)
mkdir -p "$tmp/rpms"
found_kernel=false
for rpm in $(rpm -qa --qf '%{n}-%{v}-%{r}\n' 'kernel-*' '*-kmp-*' | \
/usr/lib/rpm/rpmsort); do
case "$rpm" in
kernel-source-* | kernel-syms-* | kernel-*-debug* | kernel-*-man-* | \
kernel-*-devel-* | kernel-firmware-* | kernel-coverage-* | \
kernel-docs-* | kernel-devel-*)
continue
esac
# store the filelist to speed up file_owner()
rpm -ql "$rpm" >"$tmp/rpms/$rpm"
check_rpm "$rpm"
case "$rpm" in
kernel-*)
check_kernel_package "$rpm"
found_kernel=true
;;
*-kmp-*)
check_kmp "$rpm"
;;
esac
done
if ! $found_kernel; then
warning "no kernel package found"
fi
for krel in /lib/modules/*/kernel; do
krel=${krel%/kernel}
krel=${krel##*/}
check_krel "$krel"
done
modules=($(find /lib/modules/ -name '*.ko'))
for module in "${modules[@]}"; do
check_ko "$module"
done
echo "Found $errors error(s) and $warnings warning(s)" >&2
if test "$logfile" != -; then
echo "Report written to $logfile at $(date -R)" >&2
else
echo "Report finished at $(date -R)" >&2
fi
if test $errors -eq 0; then
exit 0
else
exit 1
fi

View File

@ -1,317 +0,0 @@
#!/usr/bin/perl
#
# KMP-INSTALL: Install specified kernel module packages and automatically
# remove packages providing same-named modules.
#
# Copyright (c) 2014 SUSE
#
# Permission is hereby granted, free of charge, to any person obtaining
# a copy of this software and associated documentation files (the
# "Software"), to deal in the Software without restriction, including
# without limitation the rights to use, copy, modify, merge, publish,
# distribute, sublicense, and/or sell copies of the Software, and to
# permit persons to whom the Software is furnished to do so, subject to
# the following conditions:
#
# The above copyright notice and this permission notice shall be
# included in all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
# IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
# CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
# TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
# SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
use strict;
use warnings;
use IO::Handle;
use File::Find;
my @zypper_cmd = qw(zypper);
sub print_help {
print
"Usage: $0 [options] <package> ...
Installs given packages and removes any KMPs that contain conficting module
names. Run 'zypper help install' for the list of valid options. Additionally,
the options --non-interactive and --non-interactive-include-reboot-patches
can be used\n";
}
sub add_package {
my ($list, $attr) = @_;
return unless $attr->[0] =~ /-kmp-/;
my $new = {
name => $attr->[0],
version => $attr->[1],
arch => $attr->[2],
};
$new->{repo} = $attr->[3] if defined($attr->[3]);
# old-version -> new-version
$new->{version} =~ s/.*->\s*//;
push(@$list, $new);
}
sub add_module {
my ($package, $path) = @_;
return unless $path =~ m@^/lib/modules/([^/]+)/.*/([^/]+\.ko)$@;
my ($version, $name) = ($1, $2);
$name =~ s/-/_/g;
$package->{modules} ||= [];
push(@{$package->{modules}}, "$version/$name");
}
sub query_installed_kmps {
my $res = shift;
my %seen;
open(my $pipe, '-|', "rpm", "-qa", "--qf", '[%{n} %{v} %{r} %{arch} %{filenames}\n]', "*-kmp-*");
while (<$pipe>) {
chomp;
my ($n, $v, $r, $a, $file) = split(' ');
next unless $file =~ m@^/lib/modules/.*/.*/.*\.ko$@;
my $nvra = "$n-$v-$r.$a";
if (!exists($seen{$nvra})) {
add_package($res, [$n, "$v-$r", $a]);
$seen{$nvra} = $res->[$#$res];
}
add_module($seen{$nvra}, $file);
}
}
sub fetch_packages {
my $interactive = shift;
my $new_pkgs = shift;
my $remove_pkgs = shift;
my @cmd = @zypper_cmd;
push(@cmd, "--non-interactive") if !$interactive;
push(@cmd, qw(-vv install --download-only));
push(@cmd, @_);
pipe(READ, WRITE);
my $pid = fork();
if (!$pid) {
# child
close(READ);
open(STDOUT, ">&WRITE");
if (!$interactive) {
open(NULL, '<', "/dev/null");
open(STDIN, "<&NULL");
close(NULL);
open(NULL, '>', "/dev/null");
open(STDERR, ">&NULL");
close(NULL);
}
exec(@cmd);
}
# parent
close(WRITE);
my ($len, $buf, $last_line);
my ($state, @cur_pkg);
$state = 0;
$last_line = "";
my $list;
STDOUT->autoflush(1);
while (($len = sysread(READ, $buf, 4096))) {
print $buf if $interactive;
my @lines = split(/\n/, $buf, -1);
$lines[0] = $last_line . $lines[0];
# XXX: Assumes that the very last line is terminated by \n
$last_line = pop(@lines);
for my $l (@lines) {
if ($state == 0 && $l =~ /^The following.* package.* going to be (installed|upgraded|downgraded|REMOVED):/) {
if ($1 eq "REMOVED") {
$list = $remove_pkgs;
} else {
$list = $new_pkgs;
}
$state = 1;
next;
}
next unless $state == 1;
if ($l eq "") {
$state = 0;
if (@cur_pkg) {
add_package($list, \@cur_pkg);
}
@cur_pkg = ();
next;
}
$l =~ s/ *$//;
if ($l =~ /^[^ ]/) {
if (@cur_pkg) {
add_package($list, \@cur_pkg);
}
@cur_pkg = ($l);
}
if ($l =~ /^ /) {
$l =~ s/^ *//;
push(@cur_pkg, $l);
}
}
}
STDOUT->autoflush(0);
close(READ);
waitpid($pid, 0);
return $?;
}
my %repo_cache;
sub get_repo_cache {
my $name = shift;
my $res;
if (exists($repo_cache{$name})) {
return $repo_cache{$name};
}
open(my $pipe, '-|', "zypper", "repos", $name);
while (<$pipe>) {
chomp;
if (m@^MD Cache Path\s*:\s*(/.*)@) {
$res = $1;
$res =~ s:/raw/:/packages/:;
$res =~ s/\s*$//;
}
}
close($pipe);
$repo_cache{$name} = $res;
return $res;
}
sub find_fetched {
my $packages = shift;
my %local_packages;
for $a (@_) {
if ($a =~ /\.rpm$/ && -e $a) {
open(my $pipe, '-|', "rpm", "-qp", "--qf",
'%{n}-%{v}-%{r}.%{arch}', $a);
my $nvra = <$pipe>;
close($pipe);
if (defined($nvra)) {
$local_packages{$nvra} = $a;
}
}
}
for my $p (@$packages) {
my $nvra = "$p->{name}-$p->{version}.$p->{arch}";
if ($p->{repo} eq "Plain RPM files cache") {
if (exists($local_packages{$nvra})) {
$p->{path} = $local_packages{$nvra};
} else {
print STDERR "Cannot find package $p->{name}\n";
}
next;
}
my $dir = get_repo_cache($p->{repo});
if (!$dir) {
print STDERR "Cannot find zypp cache for repository $p->{repo} (package $p->{name})\n";
next;
}
my $file = "$nvra.rpm";
my $wanted = sub {
$p->{path} = $File::Find::name if $_ eq $file;
};
find($wanted, $dir);
if (!$p->{path}) {
print STDERR "Cannot find $file in zypp cache ($dir)\n";
next;
}
}
for my $p (@$packages) {
next unless $p->{path};
open(my $pipe, '-|', "rpm", "-qlp", $p->{path});
my @files = <$pipe>;
close($pipe);
for my $f (@files) {
add_module($p, $f);
}
}
}
# treat -n, --non-interactive, -0 and --non-interactive-include-reboot-patches
# as global zypper options
my @save_argv = @ARGV;
@ARGV=();
for my $a (@save_argv) {
if ($a =~ /^-(h|-help)$/) {
print_help();
exit 0;
} elsif ($a =~ /^-(n$|-non-interactive$|0$|-non-interactive-)/) {
push(@zypper_cmd, $a);
} else {
push(@ARGV, $a);
}
}
if (!@ARGV) {
print_help();
exit 1;
}
print "Fetching packages\n";
my (@new_pkgs, @remove_pkgs, @installed_pkgs);
my $ret = fetch_packages(0, \@new_pkgs, \@remove_pkgs, @ARGV);
if ($ret != 0) {
print "zypper returned an error, retrying in interactive mode\n";
@new_pkgs = ();
@remove_pkgs = ();
$ret = fetch_packages(1, \@new_pkgs, \@remove_pkgs, @ARGV);
}
if ($ret != 0) {
exit 1;
}
find_fetched(\@new_pkgs, @ARGV);
query_installed_kmps(\@installed_pkgs);
# Do not check packages to be updated/removed for module conflicts
my (%new_pkgs, %remove_pkgs);
for my $p (@remove_pkgs) {
my $nvra = "$p->{name}-$->{version}.$p->{arch}";
$remove_pkgs{$nvra} = 1;
}
for my $p (@new_pkgs) {
$new_pkgs{$p->{name}} = 1;
}
my @tmp = @installed_pkgs;
@installed_pkgs = ();
for my $p (@tmp) {
my $nvra = "$p->{name}-$->{version}.$p->{arch}";
next if $new_pkgs{$p->{name}} || $remove_pkgs{$nvra};
push(@installed_pkgs, $p);
}
# check for conflicts
my %new_modules;
for my $p (@new_pkgs) {
next unless $p->{modules};
for my $m (@{$p->{modules}}) {
$new_modules{$m} = $p->{name};
}
}
my @conflicting_pkgs;
for my $p (@installed_pkgs) {
next unless $p->{modules};
for my $m (@{$p->{modules}}) {
next unless exists($new_modules{$m});
print "Package $p->{name} conflicts with new package $new_modules{$m}\n";
push(@conflicting_pkgs, $p);
last;
}
}
# Install new packages, removing conflicting installed packages
my @cmd = (@zypper_cmd, "install", @ARGV);
for my $p (@conflicting_pkgs) {
push(@cmd, "!$p->{name}.$p->{arch}=$p->{version}");
}
print join(" ", "Running", @cmd), "\n";
if (system(@cmd) != 0) {
exit 1;
}
exit 0;

View File

@ -1,15 +0,0 @@
# Packages installing files and binaries that end up in the initrd should
# call these macros in their post(trans) scriptlets to have the initrd
# regenerated
# See also fate#313506
%regenerate_initrd_post \
mkdir -p /run/regenerate-initrd/ \
touch /run/regenerate-initrd/all \
%nil
%regenerate_initrd_posttrans \
if test -x /usr/lib/module-init-tools/regenerate-initrd-posttrans; then \
/bin/bash -${-/e/} /usr/lib/module-init-tools/regenerate-initrd-posttrans \
fi \
%nil

149
modhash
View File

@ -1,149 +0,0 @@
#!/usr/bin/perl
#
# Calculate the digest of the kernel module
# It will strip kernel modules signature before calculation.
#
# Based on modsign-verify, written by Michal Marek
# Authors:
# Gary Lin <GLin@suse.com>
# Joey Lee <JLee@suse.com>
#
my $USAGE = "Usage: modhash [-v] [-q] [-d <digest algorithm>] <module>\n";
use strict;
use warnings;
use IPC::Open2;
use Getopt::Long;
use File::Temp qw(tempfile);
my $verbose = 1;
my $dgst = "sha256";
GetOptions(
"d=s" => \$dgst,
"q|quiet" => sub { $verbose-- if $verbose; },
"v|verbose" => sub { $verbose++; },
"h|help" => sub {
print $USAGE;
exit(0);
}
) or die($USAGE);
sub _verbose {
my $level = shift;
return if $verbose < $level;
print STDERR @_;
}
sub info { _verbose(1, @_); }
sub verbose { _verbose(2, @_); }
sub debug { _verbose(3, @_); }
if (@ARGV > 1) {
print STDERR "Excess arguments\n";
die($USAGE);
} elsif (@ARGV < 1) {
print STDERR "No module supplied\n";
die($USAGE);
}
my $module_name = shift(@ARGV);
if ($dgst ne "sha" and $dgst ne "sha1" and $dgst ne "sha256" and
$dgst ne "sha384" and $dgst ne "sha512") {
die("unsupported algorithm: $dgst");
}
#
# Function to read the contents of a file into a variable.
#
sub read_file($)
{
my ($file) = @_;
my $contents;
my $len;
open(FD, "<$file") || die $file;
binmode FD;
my @st = stat(FD);
die $file if (!@st);
$len = read(FD, $contents, $st[7]) || die $file;
close(FD) || die $file;
die "$file: Wanted length ", $st[7], ", got ", $len, "\n"
if ($len != $st[7]);
return $contents;
}
sub openssl_pipe($$) {
my ($input, $cmd) = @_;
my ($pid, $res);
$pid = open2(*read_from, *write_to, $cmd) || die $cmd;
binmode write_to;
if (defined($input) && $input ne "") {
print write_to $input || die "$cmd: $!";
}
close(write_to) || die "$cmd: $!";
binmode read_from;
read(read_from, $res, 4096) || die "$cmd: $!";
close(read_from) || die "$cmd: $!";
waitpid($pid, 0) || die;
die "$cmd died: $?" if ($? >> 8);
return $res;
}
my $module = read_file($module_name);
my $module_len = length($module);
my $magic_number = "~Module signature appended~\n";
my $magic_len = length($magic_number);
my $info_len = 12;
if ($module_len < $magic_len) {
die "Module size too short\n";
}
sub eat
{
my $length = shift;
if ($module_len < $length) {
die "Module size too short\n";
}
my $res = substr($module, -$length);
$module = substr($module, 0, $module_len - $length);
$module_len -= $length;
return $res;
}
if (substr($module, -$magic_len) eq $magic_number) {
$module = substr($module, 0, $module_len - $magic_len);
$module_len -= $magic_len;
my $info = eat($info_len);
my ($algo, $hash, $id_type, $name_len, $key_len, $sig_len) =
unpack("CCCCCxxxN", $info);
my $signature = eat($sig_len);
if ($id_type == 1) {
if (unpack("n", $signature) == $sig_len - 2) {
verbose ("signed module (X.509)\n");
} else {
die "Invalid signature format\n";
}
if ($algo != 1) {
die "Unsupported signature algorithm\n";
}
$signature = substr($signature, 2);
my $key_id = eat($key_len);
my $name = eat($name_len);
} elsif ($id_type == 2) {
verbose ("signed module (PKCS#7)\n");
}
} else {
verbose ("unsigned module\n");
}
verbose("Hash algorithm: $dgst\n");
my $digest = openssl_pipe($module, "openssl dgst -$dgst");
$digest =~ s/\(stdin\)= //;
print "$module_name: $digest"

View File

@ -1,3 +0,0 @@
version https://git-lfs.github.com/spec/v1
oid sha256:d03505c1dd1af76e6c012e5e774458fd89a15990696c63c6d44bfc57ca3d7a69
size 3243

View File

@ -1,252 +0,0 @@
#!/usr/bin/perl
#
# Verify kernel module signature generated by /usr/src/linux/scripts/sign-file
#
# Parts of this script were copied from sign-file, written by David Howels
#
my $USAGE = "Usage: modsign-verify [-v] [-q] [--certificate <x509> | --cert-dir <dir>] <module>\n";
use strict;
use warnings;
use IPC::Open2;
use Getopt::Long;
use File::Temp qw(tempfile);
my $cert;
my $cert_dir;
my $verbose = 1;
GetOptions(
"certificate=s" => \$cert,
"cert-dir=s" => \$cert_dir,
"q|quiet" => sub { $verbose-- if $verbose; },
"v|verbose" => sub { $verbose++; },
"h|help" => sub {
print $USAGE;
print "Return codes: 0 good signature\n";
print " 1 bad signature\n";
print " 2 certificate not found\n";
print " 3 module not signed\n";
print " >3 other error\n";
exit(0);
}
) or die($USAGE);
sub _verbose {
my $level = shift;
return if $verbose < $level;
print STDERR @_;
}
sub info { _verbose(1, @_); }
sub verbose { _verbose(2, @_); }
sub debug { _verbose(3, @_); }
if (@ARGV > 1) {
print STDERR "Excess arguments\n";
die($USAGE);
} elsif (@ARGV < 1) {
print STDERR "No module supplied\n";
die($USAGE);
} elsif ($cert && $cert_dir) {
print STDERR "Please specify either --certificate or --cert-dir, not both.\n";
die($USAGE);
}
my $module_name = shift(@ARGV);
if (!$cert && !$cert_dir) {
$cert_dir = "/etc/uefi/certs";
verbose("Using default certificate directory $cert_dir\n");
}
my @certs;
if ($cert) {
push(@certs, $cert);
} else {
my $dh;
if (!opendir($dh, $cert_dir)) {
print STDERR "$cert_dir: $!\n";
exit(2);
}
while (my $entry = readdir($dh)) {
next if $entry =~ /^\./;
next if !-f "$cert_dir/$entry";
push(@certs, "$cert_dir/$entry");
}
closedir($dh);
if (!@certs) {
print STDERR "No certificates found in $cert_dir\n";
exit(2);
}
}
#
# Function to read the contents of a file into a variable.
#
sub read_file($)
{
my ($file) = @_;
my $contents;
my $len;
open(FD, "<$file") || die $file;
binmode FD;
my @st = stat(FD);
die $file if (!@st);
$len = read(FD, $contents, $st[7]) || die $file;
close(FD) || die $file;
die "$file: Wanted length ", $st[7], ", got ", $len, "\n"
if ($len != $st[7]);
return $contents;
}
sub openssl_pipe($$) {
my ($input, $cmd) = @_;
my ($pid, $res);
$pid = open2(*read_from, *write_to, $cmd) || die $cmd;
binmode write_to;
if (defined($input) && $input ne "") {
print write_to $input || die "$cmd: $!";
}
close(write_to) || die "$cmd: $!";
binmode read_from;
read(read_from, $res, 4096) || die "$cmd: $!";
close(read_from) || die "$cmd: $!";
waitpid($pid, 0) || die;
die "$cmd died: $?" if ($? >> 8);
return $res;
}
sub cert_matches {
my ($cert, $subject_key_id, $subject_name) = @_;
open(my $pipe, '-|', "openssl", "x509", "-noout", "-text",
"-inform", "DER", "-in", $cert) or die "openssl x509: $!\n";
my $found = 0;
my $found_key_id;
while (<$pipe>) {
chomp;
if (/^\s*X509v3 Subject Key Identifier:/) {
$found = 1;
next;
}
if ($found) {
s/[\s:]*//g;
$found_key_id = pack("H*", $_);
last;
}
}
if (!$found_key_id) {
print STDERR "Warning: no subject key identifier in $cert\n";
return 0;
}
debug("$cert has hey id " . unpack("H*", $found_key_id));
# FIXME: Also check subject_name
return ($found_key_id eq $subject_key_id);
}
my $module = read_file($module_name);
my $module_len = length($module);
my $magic_number = "~Module signature appended~\n";
my $magic_len = length($magic_number);
my $info_len = 12;
sub eat
{
my $length = shift;
if ($module_len < $length) {
die "Module size too short\n";
}
my $res = substr($module, -$length);
$module = substr($module, 0, $module_len - $length);
$module_len -= $length;
return $res;
}
if (eat($magic_len) ne $magic_number) {
print "$module_name: module not signed\n";
exit(3);
}
my $info = eat($info_len);
my ($algo, $hash, $id_type, $name_len, $key_len, $sig_len) =
unpack("CCCCCxxxN", $info);
my $signature = eat($sig_len);
if (unpack("n", $signature) != $sig_len - 2) {
die "Invalid signature format\n";
}
$signature = substr($signature, 2);
my $key_id = eat($key_len);
my $name = eat($name_len);
if ($algo != 1) {
die "Unsupported signature algorithm\n";
}
#
# Digest the data
#
my ($prologue, $dgst);
if ($hash == 2) {
$prologue = pack("C*",
0x30, 0x21, 0x30, 0x09, 0x06, 0x05,
0x2B, 0x0E, 0x03, 0x02, 0x1A,
0x05, 0x00, 0x04, 0x14);
$dgst = "sha1";
} elsif ($hash == 7) {
$prologue = pack("C*",
0x30, 0x2d, 0x30, 0x0d, 0x06, 0x09,
0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x04,
0x05, 0x00, 0x04, 0x1C);
$dgst = "sha224";
} elsif ($hash == 4) {
$prologue = pack("C*",
0x30, 0x31, 0x30, 0x0d, 0x06, 0x09,
0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01,
0x05, 0x00, 0x04, 0x20);
$dgst = "sha256";
} elsif ($hash == 5) {
$prologue = pack("C*",
0x30, 0x41, 0x30, 0x0d, 0x06, 0x09,
0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x02,
0x05, 0x00, 0x04, 0x30);
$dgst = "sha384";
} elsif ($hash == 6) {
$prologue = pack("C*",
0x30, 0x51, 0x30, 0x0d, 0x06, 0x09,
0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x03,
0x05, 0x00, 0x04, 0x40);
$dgst = "sha512";
} else {
die "Unsupported hash algorithm\n";
}
verbose("Signed by: $name\n");
verbose("Key id: " . unpack("H*", $key_id) . "\n");
verbose("Hash algorithm: $dgst\n");
my $digest = openssl_pipe($module, "openssl dgst -$dgst -binary");
my $original_message = $prologue . $digest;
for my $cert (sort @certs) {
debug("Trying $cert\n");
next unless cert_matches($cert, $key_id, $name);
verbose("Found certificate $cert\n");
my ($fh, $filename) = tempfile() or die "Cannot create temporary file: $!\n";
my $pubkey = openssl_pipe("",
"openssl x509 -noout -in $cert -inform DER -pubkey");
print $fh $pubkey;
close($fh);
my $verified_message = openssl_pipe($signature,
"openssl rsautl -verify -inkey $filename -keyform PEM -pubin");
unlink($filename);
if ($original_message ne $verified_message) {
print "$module_name: bad signature\n";
exit(1);
}
print "$module_name: good signature\n";
exit(0);
}
print "certificate not found\n";
exit(2);

View File

@ -1,63 +0,0 @@
#!/bin/bash
#
# Packages that install kernels or kernel-modules create a flag
#
# /run/regenerate-initrd/<kernel image>
#
# to have the initrd for <kernel image> generated, or
#
# /run/regenerate-initrd/all
#
# to have all initrds generated. This script is called from posttrans
# and takes care of generating the initrds
shopt -s nullglob
dir=/run/regenerate-initrd
did_mkinitrd_setup=false
run_mkinitrd_setup()
{
if ! $did_mkinitrd_setup; then
if test -x /sbin/mkinitrd_setup; then
/sbin/mkinitrd_setup
fi
did_mkinitrd_setup=true
fi
}
if ! test -d "$dir"; then
exit 0
fi
for f in "$dir"/*; do
# check if we are in a build chroot
if ! [ -f /etc/fstab -a ! -e /.buildenv -a -x /sbin/mkinitrd ] ; then
echo "Please run mkinitrd as soon as your system is complete." >&2
rm "$dir"/*
exit 0
fi
break
done
if test -e "$dir/all"; then
rm "$dir"/*
run_mkinitrd_setup
/sbin/mkinitrd
exit
fi
err=0
for f in "$dir"/*; do
rm "$f"
image=${f##*/}
initrd=initrd-${image#*-}
if ! test -e "/boot/$image"; then
echo "$0: /boot/$image does not exist, initrd won't be generated"
continue
fi
run_mkinitrd_setup
if ! /sbin/mkinitrd -k "/boot/$image" -i "/boot/$initrd"; then
err=$?
fi
done
exit $err

View File

@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:0f090075efe7f9f414eec855dde3c2355ca6621db036adecbee5694adacb6531
size 27980

View File

@ -1,3 +1,40 @@
-------------------------------------------------------------------
Wed Nov 07 14:53:52 UTC 2018 - mwilck@suse.com
- Update to version 15.0.1 (git 5c63319):
- Use /etc/modules-load.d/sg.conf for sg driver autoloading
(bsc#1036463)
* added /etc/modules-load.d/sg.conf
-------------------------------------------------------------------
Mon Nov 05 10:08:19 UTC 2018 - mwilck@suse.com
- version 15.0 (git 6ce3011)
- modsign-verify: support for parsing PKCS#7 signatures
(bsc#1111300, bsc#1105495)
- Fix logic for unsupported modules (bsc#1111183)
* SLES15: allow unsupported modules only if kernel-default-extra
from SLE-WE module is installed
* Always allow unsupported modules on Leap 15 and Factory
* No change for SLE12 / Leap 42.x and below
* 10-unsupported-modules.conf: improved comments
* fix %config(noreplace) logic for 10-unsupported-modules.conf
- added udev rule 81-sg.rules to make sure the sg module is
always loaded (bsc#1036463)
-------------------------------------------------------------------
Wed Jul 26 08:07:29 UTC 2017 - tchvatal@suse.com
- Use path dependency that is not parsed by obs to ensure we
are not pulling systemd everywhere
-------------------------------------------------------------------
Mon Jun 19 12:58:04 UTC 2017 - tchvatal@suse.com
- Set url to github project and repack using obs service
- Cleanup a bit with spec-cleaner
- Grep os-release and not deprecated SuSE-release
-------------------------------------------------------------------
Thu Sep 8 08:55:50 UTC 2016 - dmueller@suse.com

View File

@ -1,7 +1,7 @@
#
# spec file for package suse-module-tools
#
# Copyright (c) 2016 SUSE LINUX GmbH, Nuernberg, Germany.
# Copyright (c) 2018 SUSE LINUX GmbH, Nuernberg, Germany.
#
# All modifications and additions to the file contributed by third parties
# remain the property of their copyright owners, unless otherwise agreed
@ -12,42 +12,29 @@
# license that conforms to the Open Source Definition (Version 1.9)
# published by the Open Source Initiative.
# Please submit bugfixes or comments via http://bugs.opensuse.org/
# Please submit bugfixes or comments via https://bugs.opensuse.org/
#
Name: suse-module-tools
Version: 12.4
Version: 15.0.1
Release: 0
Requires: /sbin/depmod
Requires: /sbin/mkinitrd
Requires: findutils
Requires: gzip
# for grepping /etc/SUSE-release
PreReq: grep
# nm and rpmsort (rpm) are required by the weak-modules script which is invoked
# in post, it also requires getopt (coreutils) and sed
PreReq: coreutils rpm
# XXX: this should be nm OR eu-nm, the script works with both
PreReq: /usr/bin/eu-nm /bin/sed
Summary: Configuration for module loading and SUSE-specific utilities for KMPs
License: GPL-2.0+
License: GPL-2.0-or-later
Group: System/Base
Source: README.SUSE
Source2: modprobe.conf.tar.bz2
Source3: depmod-00-system.conf
Source4: 10-unsupported-modules.conf
Source5: weak-modules
Source6: weak-modules2
Source7: driver-check.sh
Source8: suse-module-tools.rpmlintrc
Source9: modsign-verify
Source10: kmp-install
Source11: macros.initrd
Source12: regenerate-initrd-posttrans
Source13: 50-kernel-uname_r.conf
Source14: modhash
BuildRoot: %{_tmppath}/%{name}-%{version}-build
Url: https://github.com/openSUSE/suse-module-tools
Source0: %{name}-%{version}.tar.xz
Source1: %{name}.rpmlintrc
Requires: /sbin/mkinitrd
Requires: binutils
Requires: coreutils
Requires: findutils
Requires: grep
Requires: gzip
# module-init-tools in older distros, kmod-compat in later ones
Requires: /sbin/depmod
Requires: rpm
Requires: sed
%description
This package contains helper scripts for KMP installation and
@ -56,53 +43,68 @@ modprobe. These utilities are provided by kmod-compat or
module-init-tools, whichever implementation you choose to install.
%prep
%setup -Tcqa2
%setup -q
%build
%if 0%{?is_opensuse} == 0
sed -ri 's/^( *allow_unsupported_modules *) 1/\1 0/' \
10-unsupported-modules.conf
%endif
%install
b="%buildroot"
mkdir -p "$b/%_docdir/module-init-tools"
install -pm644 "%_sourcedir/README.SUSE" "$b/%_docdir/module-init-tools"
#
# now assemble the parts for modprobe.conf
#
cd modprobe.conf
cp modprobe.conf.common 00-system.conf
if [ -f "modprobe.conf.$RPM_ARCH" ]; then
cat "modprobe.conf.$RPM_ARCH" >>00-system.conf
cp modprobe.conf/modprobe.conf.common 00-system.conf
if [ -f "modprobe.conf/modprobe.conf.$RPM_ARCH" ]; then
cat "modprobe.conf/modprobe.conf.$RPM_ARCH" >>00-system.conf
fi
install -d -m 755 "$b/etc/modprobe.d"
install -pm644 "%_sourcedir/10-unsupported-modules.conf" \
"$b/etc/modprobe.d/"
install -pm644 00-system.conf "$b/etc/modprobe.d/"
install -pm644 modprobe.conf.local "$b/etc/modprobe.d/99-local.conf"
install -d -m 755 "$b/etc/depmod.d"
install -pm 644 "%_sourcedir/depmod-00-system.conf" \
"$b/etc/depmod.d/00-system.conf"
install -d -m 755 "%{buildroot}%{_sysconfdir}/modprobe.d"
install -pm644 "10-unsupported-modules.conf" \
"%{buildroot}%{_sysconfdir}/modprobe.d/"
install -pm644 00-system.conf "%{buildroot}%{_sysconfdir}/modprobe.d/"
install -pm644 modprobe.conf/modprobe.conf.local "%{buildroot}%{_sysconfdir}/modprobe.d/99-local.conf"
install -d -m 755 "%{buildroot}%{_sysconfdir}/depmod.d"
install -pm 644 "depmod-00-system.conf" \
"%{buildroot}%{_sysconfdir}/depmod.d/00-system.conf"
# "module-init-tools" name hardcoded in KMPs, mkinitrd, etc.
install -d -m 755 "$b/usr/lib/module-init-tools"
install -pm 755 %_sourcedir/weak-modules{,2} "$b/usr/lib/module-init-tools/"
install -pm 755 %_sourcedir/driver-check.sh "$b/usr/lib/module-init-tools/"
install -d -m 755 "%{buildroot}%{_libexecdir}/module-init-tools"
install -pm 755 weak-modules{,2} "%{buildroot}%{_libexecdir}/module-init-tools/"
install -pm 755 driver-check.sh "%{buildroot}%{_libexecdir}/module-init-tools/"
# rpm macros and helper
install -d -m 755 "$b/etc/rpm"
install -pm 644 "%_sourcedir/macros.initrd" "$b/etc/rpm/"
install -pm 755 "%_sourcedir/regenerate-initrd-posttrans" "$b/usr/lib/module-init-tools/"
install -d -m 755 "%{buildroot}%{_sysconfdir}/rpm"
install -pm 644 "macros.initrd" "%{buildroot}%{_sysconfdir}/rpm/"
install -pm 755 "regenerate-initrd-posttrans" "%{buildroot}%{_libexecdir}/module-init-tools/"
# modsign-verify for verifying module signatures
install -d -m 755 "$b/usr/bin"
install -pm 755 %_sourcedir/modsign-verify "$b/usr/bin/"
install -pm 755 %_sourcedir/kmp-install "$b/usr/bin/"
install -d -m 755 "%{buildroot}%{_prefix}/bin"
install -pm 755 modsign-verify "%{buildroot}%{_bindir}/"
install -pm 755 kmp-install "%{buildroot}%{_bindir}/"
# modhash for calculating hash of signed kernel module
install -pm 755 %_sourcedir/modhash "$b/usr/bin/"
install -pm 755 modhash "%{buildroot}%{_bindir}/"
# systemd service to load /boot/sysctl.conf-`uname -r`
install -d -m 755 "$b/usr/lib/systemd/system/systemd-sysctl.service.d"
install -pm 644 %_sourcedir/50-kernel-uname_r.conf "$b/usr/lib/systemd/system/systemd-sysctl.service.d"
install -d -m 755 "%{buildroot}%{_libexecdir}/systemd/system/systemd-sysctl.service.d"
install -pm 644 50-kernel-uname_r.conf "%{buildroot}%{_libexecdir}/systemd/system/systemd-sysctl.service.d"
# Ensure that the sg driver is loaded early (bsc#1036463)
# Not needed in SLE11, where sg is loaded via udev rule.
install -d -m 755 "%{buildroot}%{_sysconfdir}/modules-load.d"
install -pm 644 sg.conf "%{buildroot}%{_sysconfdir}/modules-load.d"
mkdir -p %{buildroot}%{_defaultlicensedir}
%post
%if 0%{?sle_version} >= 150000
# Delete obsolete unsupported-modules file from SLE11
rm -f %{_sysconfdir}/modprobe.d/unsupported-modules
%else
# Logic for releases below CODE 15
%if 0%{?is_opensuse} == 1
allowed=1
%else
allowed=0
%endif
test_allow_on_install()
{
# configure handling of unsupported modules
@ -110,20 +112,21 @@ test_allow_on_install()
allow=1
# if the obsolete LOAD_UNSUPPORTED_MODULES_AUTOMATICALLY variable is
# set to no, don't allow (this was used in SLES 9 and 10)
if test -e /etc/sysconfig/hardware/config; then
. /etc/sysconfig/hardware/config
if test -e %{_sysconfdir}/sysconfig/hardware/config; then
. %{_sysconfdir}/sysconfig/hardware/config
if test "x$LOAD_UNSUPPORTED_MODULES_AUTOMATICALLY" = "xno"; then
allow=0
fi
# obsolete
rm /etc/sysconfig/hardware/config
rm %{_sysconfdir}/sysconfig/hardware/config
fi
# don't change the setting during upgrade
if test "$1" != 1; then
allow=
return
fi
# on SLES, the default is not to allow unsupported modules
if grep -qs "Enterprise Server" /etc/SuSE-release; then
if grep -qs "Enterprise Server" %{_sysconfdir}/os-release; then
allow=0
else
return
@ -134,7 +137,7 @@ test_allow_on_install()
return
fi
# or if the installer already loaded some unsupported modules
# (see TAINT_NO_SUPPORT in /usr/src/linux/include/linux/kernel.h)
# (see TAINT_NO_SUPPORT in /etc/src/linux/include/linux/kernel.h)
tainted=$(cat /proc/sys/kernel/tainted 2>/dev/null || echo 0)
if test $((tainted & (1<<30))) != 0; then
allow=1
@ -142,34 +145,44 @@ test_allow_on_install()
fi
}
# upgrade from old locations
if test -e /etc/modprobe.d/unsupported-modules; then
mv -f /etc/modprobe.d/unsupported-modules \
/etc/modprobe.d/10-unsupported-modules.conf
fi
if test -e /etc/modprobe.conf.local; then
mv -f /etc/modprobe.conf.local \
/etc/modprobe.d/99-local.conf
if test -e %{_sysconfdir}/modprobe.d/unsupported-modules; then
mv -f %{_sysconfdir}/modprobe.d/unsupported-modules \
%{_sysconfdir}/modprobe.d/10-unsupported-modules.conf
fi
test_allow_on_install "$@"
if test "$allow" = "0"; then
sed -ri 's/^( *allow_unsupported_modules *) 1/\1 0/' \
/etc/modprobe.d/10-unsupported-modules.conf
if test -n "$allow" -a "$allow" != "$allowed"; then
sed -ri 's/^( *allow_unsupported_modules *) [01]/\1 '"$allow"'/' \
%{_sysconfdir}/modprobe.d/10-unsupported-modules.conf
fi
%endif
# upgrade from old locations
if test -e %{_sysconfdir}/modprobe.conf.local; then
mv -f %{_sysconfdir}/modprobe.conf.local \
%{_sysconfdir}/modprobe.d/99-local.conf
fi
%files
%defattr(-,root,root)
%dir /etc/modprobe.d
%config /etc/modprobe.d/00-system.conf
%config(noreplace) /etc/modprobe.d/10-unsupported-modules.conf
%config(noreplace) /etc/modprobe.d/99-local.conf
%dir /etc/depmod.d
%config /etc/depmod.d/00-system.conf
%config /etc/rpm/macros.initrd
%_docdir/module-init-tools
/usr/bin/modhash
/usr/bin/kmp-install
/usr/bin/modsign-verify
/usr/lib/module-init-tools
/usr/lib/systemd/system/systemd-sysctl.service.d
%if 0%{?sle_version:%{sle_version}}%{!?sle_version:150000} <= 120200
%dir %{_defaultlicensedir}
%endif
%license LICENSE
%doc README.SUSE
%dir %{_sysconfdir}/modprobe.d
%config %{_sysconfdir}/modprobe.d/00-system.conf
%config(noreplace) %{_sysconfdir}/modprobe.d/10-unsupported-modules.conf
%config(noreplace) %{_sysconfdir}/modprobe.d/99-local.conf
%dir %{_sysconfdir}/depmod.d
%config %{_sysconfdir}/depmod.d/00-system.conf
%config %{_sysconfdir}/rpm/macros.initrd
%{_bindir}/modhash
%{_bindir}/kmp-install
%{_bindir}/modsign-verify
%{_libexecdir}/module-init-tools
%{_libexecdir}/systemd/system/systemd-sysctl.service.d
%dir %{_sysconfdir}/modules-load.d
%config(noreplace) %{_sysconfdir}/modules-load.d/sg.conf
%changelog

View File

@ -1,325 +0,0 @@
#! /bin/bash
# This script is only needed to uninstall old KMPs when updating
# SLE10 to SLE11+. weak-modules2 is the script what should be used by new
# packages
unset LANG LC_ALL LC_COLLATE
NM=
if command -v nm >/dev/null; then
NM=nm
elif command -v eu-nm >/dev/null; then
NM=eu-nm
else
echo "ERROR: nm not found" >&2
exit 1
fi
# Check if MODULE is compatible with kernel release KREL.
module_is_compatible() {
declare module=$1 krel=$2 module_krel=$(krel_of_module "$module")
if [ ! -e $tmpdir/all-symvers-$krel-$module_krel ]; then
# Symbols exported by the "new" kernel
if [ ! -e $tmpdir/symvers-$krel ]; then
if [ -e /boot/symvers-$krel.gz ]; then
zcat /boot/symvers-$krel.gz \
| sed -r -ne 's:^0x0*([0-9a-f]+\t[0-9a-zA-Z_]+)\t.*:\1:p'
fi > $tmpdir/symvers-$krel
fi
# Symbols that other add-on modules of the "old" kernel export
# (and that this module may require)
if [ ! -e $tmpdir/extra-symvers-$module_krel ]; then
if [ -e /lib/modules/$module_krel/updates ]; then
find /lib/modules/$module_krel/updates -name '*.ko' \
| xargs $NM -B \
| sed -nre 's:^0*([0-9a-f]+) A __crc_(.*):\1 \2:p'
fi > $tmpdir/extra-symvers-$module_krel
fi
sort -u $tmpdir/symvers-$krel $tmpdir/extra-symvers-$module_krel \
> $tmpdir/all-symvers-$krel-$module_krel
fi
# If the module does not have modversions enabled, $tmpdir/modvers
# will be empty.
/sbin/modprobe --dump-modversions "$module" \
| sed -r -e 's:^0x0*([0-9a-f]+\t.*):\1:' \
| sort -u \
> $tmpdir/modvers
# Only include lines of the second file in the output that don't
# match lines in the first file. (The default separator is
# <space>, so we are matching the whole line.)
join -j 1 -v 2 $tmpdir/all-symvers-$krel-$module_krel \
$tmpdir/modvers > $tmpdir/join
if [ ! -s $tmpdir/modvers ]; then
echo "Warning: Module ${module##*/} from kernel $module_krel has no" \
"modversions, so it cannot be reused for kernel $krel" >&2
elif [ -s $tmpdir/join ]; then
[ -n "$verbose" ] &&
echo "Module ${module##*/} from kernel $module_krel is not compatible" \
"with kernel $krel in symbols:" $(sed -e 's:.* ::' $tmpdir/join)
elif [ "$krel" != "$module_krel" ]; then
[ -n "$verbose" ] &&
echo "Module ${module##*/} from kernel $module_krel is compatible" \
"with kernel $krel"
return 0
fi
return 1
}
# Compute the kernel release of a module.
krel_of_module() {
declare module=$1
set -- $(/sbin/modinfo -F vermagic "$module")
echo "$1"
}
# Read a list of modules from standard input, convert the filenames into
# absolute names, and compute the kernel release of each module.
read_modules_list() {
local saved_IFS=$IFS
IFS=$'\n'
modules=($(cat))
IFS=$saved_IFS
for ((n = 0; n < ${#modules[@]}; n++)); do
if [ ${modules[n]:0:1} != / ]; then
modules[n]=$PWD/${modules[n]}
fi
if [ -f "${modules[n]}" ]; then
module_krels[n]=$(krel_of_module "${modules[n]}")
else
# Try to extract the kernel release from the path
set -- "${modules[n]#/lib/modules/}"
module_krels[n]=${1%%/*}
fi
done
}
doit() {
[ -n "$verbose" ] && echo "$@"
[ -n "$dry_run" ] || "$@"
}
usage() {
cat <<'EOF'
Usage: ${0##*/} [options] {--add-modules|--remove-modules}
${0##*/} [options] {--add-kernel|--remove-kernel} {kernel-release}
--add-modules
Add a list of modules read from standard input. Create
symlinks in compatible kernel's weak-updates/ directory.
The list of modules is read from standard input.
--remove-modules
Remove compatibility symlinks from weak-updates/ directories
for a list of modules. The list of modules is read from
standard input.
--add-kernel
Add compatibility symlinks for all compatible modules to the
specified or running kernel.
--remove-kernel
Remove all compatibility symlinks for the specified or current
kernel.
--verbose
Print the commands executed.
-dry-run
Do not create/remove any files.
EOF
exit $1
}
[ -e /etc/sysconfig/kernel ] && source /etc/sysconfig/kernel
unset ${!changed_modules_*} ${!changed_initrd_*}
module_has_changed() {
declare module=$1 krel=$2
module=${module%.ko}
module=${module##*/}
eval "changed_modules_${krel//[^a-zA-Z0-9]/_}=$krel"
case " $INITRD_MODULES " in
*" $module "*)
eval "changed_initrd_${krel//[^a-zA-Z0-9]/_}=$krel"
;;
esac
}
options=`getopt -o h --long help,add-modules,remove-modules \
--long add-kernel,remove-kernel,dry-run,verbose -- "$@"`
[ $? -eq 0 ] || usage 1
eval set -- "$options"
while :; do
case "$1" in
--add-modules)
add_modules=1
;;
--remove-modules)
remove_modules=1
;;
--add-kernel)
add_kernel=1
;;
--remove-kernel)
remove_kernel=1
;;
--dry-run)
dry_run=1
;;
--verbose)
verbose=1
;;
-h|--help)
usage 0
;;
--)
shift
break
;;
esac
shift
done
if [ "$add_modules$remove_modules$add_kernel$remove_kernel" != 1 ]; then
usage 1
fi
if [ -n "$add_kernel" -o -n "$remove_kernel" ]; then
[ $# -gt 1 ] && usage 1
else
[ $# -ne 0 ] && usage 1
fi
tmpdir=$(mktemp -td ${0##*/}.XXXXXX)
trap "rm -rf $tmpdir" EXIT
if [ -n "$add_modules" ]; then
read_modules_list || exit 1
if [ ${#modules[@]} -gt 0 ]; then
for krel in $(ls /lib/modules/); do
[ -e /boot/symvers-$krel.gz ] || continue
for ((n = 0; n < ${#modules[@]}; n++)); do
module=${modules[n]}
module_krel=${module_krels[n]}
case "$module" in
/lib/modules/$krel/*)
continue ;;
esac
subpath=${module#/lib/modules/$module_krel/updates}
weak_module=/lib/modules/$krel/weak-updates/${subpath#/}
if [ -r "$weak_module" ]; then
weak_krel=$(krel_of_module "$weak_module")
if [ "$weak_krel" != "$module_krel" ] &&
[ "$(printf "%s\n" "$weak_krel" "$module_krel" \
| /usr/lib/rpm/rpmsort | head -n 1)" = \
"$module_krel" ]; then
# Keep modules from more recent kernels.
[ -n "$verbose" ] && echo \
"Keeping module ${module##*/} from kernel $weak_krel for kernel $krel"
continue
fi
fi
if module_is_compatible $module $krel; then
doit mkdir -p $(dirname $weak_module)
doit ln -sf $module $weak_module
module_has_changed $module $krel
fi
done
done
fi
elif [ -n "$remove_modules" ]; then
read_modules_list || exit 1
if [ ${#modules[@]} -gt 0 ]; then
krels=($(ls /lib/modules/ | /usr/lib/rpm/rpmsort -r))
for krel in "${krels[@]}"; do
[ -e /boot/symvers-$krel.gz ] || continue
for ((n = 0; n < ${#modules[@]}; n++)); do
module=${modules[n]}
[ -e "$module" ] && continue
module_krel=${module_krels[n]}
subpath=${module#/lib/modules/$module_krel/updates}
weak_module=/lib/modules/$krel/weak-updates/${subpath#/}
if [ "$(readlink "$weak_module")" = "$module" ]; then
[ -n "$verbose" ] && echo \
"Removing compatible module ${subpath#/} from kernel $krel"
doit rm -f "$weak_module"
for krel2 in "${krels[@]}"; do
[ -e /boot/symvers-$krel2.gz ] || continue
module=/lib/modules/$krel2/updates/${subpath#/}
[ -e "$module" ] || continue
if module_is_compatible "$module" "$krel2"; then
[ -n "$verbose" ] && echo \
"Adding compatible module ${module##*/} from kernel $krel2 instead"
doit ln -s "$module" "$weak_module"
break
fi
done
doit rmdir --parents --ignore-fail-on-non-empty \
"$(dirname "$weak_module")"
module_has_changed $module $krel
fi
done
done
fi
elif [ -n "$add_kernel" ]; then
add_krel=${1:-$(uname -r)}
if [ ! -e /boot/symvers-$add_krel.gz ]; then
echo "Symvers dump file /boot/symvers-$add_krel.gz" \
"not found" >&2
exit 1
fi
for krel in $(ls /lib/modules/ | /usr/lib/rpm/rpmsort -r); do
[ "$add_krel" = "$krel" ] && continue
[ -d /lib/modules/$krel/updates ] || continue
for module in $(find /lib/modules/$krel/updates -name '*.ko'); do
subpath=${module#/lib/modules/$krel/updates}
weak_module=/lib/modules/$add_krel/weak-updates/${subpath#/}
[ -e "$weak_module" ] && continue
if module_is_compatible $module $add_krel; then
doit mkdir -p $(dirname $weak_module)
doit ln -sf $module $weak_module
fi
done
done
elif [ -n "$remove_kernel" ]; then
remove_krel=${1:-$(uname -r)}
weak_modules=/lib/modules/$remove_krel/weak-updates
doit rm -rf "$weak_modules"
fi
for krel in ${!changed_modules_*}; do
krel=${!krel}
[ -e /boot/System.map-$krel ] || continue
/sbin/depmod -ae -F /boot/System.map-$krel $krel
done
for krel in ${!changed_initrd_*}; do
krel=${!krel}
[ -e /boot/System.map-$krel ] || continue
image=
for x in vmlinuz image vmlinux linux bzImage uImage Image; do
if [ -f /boot/$x-$krel ]; then
image=$x
break
fi
done
if [ -n "$image" ]; then
/sbin/mkinitrd -k /boot/$image-$krel -i /boot/initrd-$krel
fi
done
# vim:shiftwidth=4 softtabstop=4

View File

@ -1,703 +0,0 @@
#! /bin/bash
##############################################################################
# How it works:
# * Kernels install modules below /lib/modules/$krel/kernel/.
# * KMPs install modules below /lib/modules/$krel/updates/ or .../extra/.
# * Symbolic links to modules of compatible KMPs are created under
# /lib/modules/$krel/weak-updates/{updates,extra}/... (the original path
# below /lib/modules/$other_krel is used).
# * Depmod searches the directories in this order: updates/, extra/,
# weak-updates/, kernel/ (see /etd/depmod.conf or
# /etc/depmod.d/00-system.conf for details).
# * Compatibility of a kernel with a KMP is defined as: The KMP is built
# for the same flavor as the kernel and after adding the KMP modules to
# the kernel, depmod -e -E Module.symvers reports no errors about
# missing symbols or different symbol checksums. See the
# has_unresolved_symbols() function for details.
#
# * At KMP install time (function add_kmp()), we create symbolic links
# for all kernels that this KMP is compatible with. We skip kernels that
# already contain symbolic links to a newer KMP of the same name,
# contain the KMP itself or another version in updates/ or extra/ or
# have overlapping module names with other KMPs in the respective
# kernel (this should not happen).
# * At kernel install time (functions add_kernel()), we create symbolic
# links for each compatible KMP, unless the KMP or a different one with
# overlapping module names is present in updates/ or extra/ (KMP build
# against $krel can be installed before a kernel with that version).
# When multiple KMPs of the same name are compatbile, we chose the one
# with the highest version number. This is repeated when subsequent
# subpackages (main or -extra) of that kernel are installed.
# * At KMP removal time (function remove_kmp()), the modules and their
# symlinks are removed and, where possible, replaced by symlinks to the
# newest of the remaining compatible version of that KMP.
# * [NOT IMPLEMENTED] When a kernel subpackage is removed, symlinks to
# KMPs that become incompatible are removed as well. This is not
# implemented, because removing the main subpackage and only keeping
# the -base package AND having KMPs installed is not an expected
# scenario, and implementing this would only slow down kernel updates.
# * When the kernel is removed (function remove_kernel()), it's
# weak-updates directory is also removed.
#
# naming conventions used in this script:
# $kmp: name-version-release of a kmp, e.g kqemu-kmp-default-1.3.0pre11_2.6.25.16_0.1-7.1
# $kmpshort: name of a kmp, e.g kqemu-kmp-default
# $basename: portion of $kmp up to the "-kmp-" part, e.g kqemu
# $flavor: flavor of a kmp or kernel, e.g default
# $krel: kernel version, as in /lib/modules/$krel
# $module: full path to a module below updates/
# $symlink: full path to a module symlink below weak-updates/
#
# files in $tmpdir:
# krel-$kmp: kernel version for which $kmp was built
# modules-$kmp: list of modules in $kmp (full paths)
# basenames-$kmp: list of basenames of modules in $kmp
# kmps: list of kmps, newest first
#
log() {
[ -n "$opt_verbose" ] && echo "$@" >&2
}
doit() {
if [ -n "$doit" ]; then
# override
"$@"
return
fi
log "$@"
if [ -z "$opt_dry_run" ]; then
"$@"
else
:
fi
}
filter_basenames() {
sed -rn 's:.*\<lib/modules/.*/([^/]*\.ko)$:\1:p'
}
# Name of the symlink that makes a module available to a given kernel
symlink_to_module() {
local module=$1 krel=$2
echo /lib/modules/$krel/weak-updates/${module#/lib/modules/*/}
}
# Is a kmp already present in or linked to from this kernel?
kmp_is_present() {
local kmp=$1 krel=$2
if [ $krel = "$(cat $tmpdir/krel-$kmp)" ]; then
return 0
fi
local module symlink
while read module; do
symlink=$(symlink_to_module $module $krel)
[ $module -ef $symlink -o $module = "$(readlink $symlink)" ] || return 1
done < $tmpdir/modules-$kmp
return 0
}
# Add the modules of a kmp to /lib/modules/$krel
add_kmp_modules() {
local kmp=$1 krel=$2 basedir=$3
[ -n "$kmp" ] || return 0
local module symlink
while read module; do
symlink=$(symlink_to_module $module $krel)
doit mkdir -p ${opt_debug:+-v} $basedir${symlink%/*} || exit 1
doit ln -sf ${opt_debug:+-v} $module $basedir$symlink || exit 1
done < $tmpdir/modules-$kmp
}
# Remove the modules of a kmp from /lib/modules/$krel
remove_kmp_modules() {
local kmp=$1 krel=$2 basedir=$3
[ -n "$kmp" ] || return 0
local module symlink
while read module; do
symlink=$(symlink_to_module $module $krel)
doit rm -f ${opt_debug:+-v} $basedir$symlink
done < $tmpdir/modules-$kmp
}
# Create a temporary working copy of /lib/modules/$1
create_temporary_modules_dir() {
local modules_dir=/lib/modules/$1 basedir=$2
local opt_v=${opt_debug:+-v}
mkdir -p $opt_v $basedir$modules_dir/weak-updates
ln -s $opt_v $modules_dir/kernel $basedir$modules_dir/kernel
eval "$(find $modules_dir -path "$modules_dir/modules.*" -prune \
-o -path "$modules_dir/kernel" -prune \
-o -type d -printf "mkdir -p $opt_v $basedir%p\n" \
-o -printf "ln -s $opt_v %p $basedir%p\n"
)"
}
# Check for unresolved symbols
has_unresolved_symbols() {
local krel=$1 basedir=$2 output status args sym_errors
if [ ! -e $tmpdir/symvers-$krel -a -e /boot/symvers-$krel.gz ]; then
zcat /boot/symvers-$krel.gz > $tmpdir/symvers-$krel
fi
if [ -e $tmpdir/symvers-$krel ]; then
args=(-E $tmpdir/symvers-$krel)
else
echo "warning: $tmpdir/symvers-$krel not available" >&2
args=(-F /boot/System.map-$krel)
fi
output="$(/sbin/depmod -b "$basedir" -ae "${args[@]}" $krel 2>&1)"
status=$?
if [ $status -ne 0 ]; then
echo "$output" >&2
echo "depmod exited with error $status" >&2
return 0
fi
sym_errors=$(echo "$output" | \
grep -E ' (needs unknown|disagrees about version of) symbol ')
if [ -n "$sym_errors" ]; then
[ -z "$opt_debug" ] || echo "$sym_errors" >&2
return 0
fi
return 1
}
# KMPs can only be added if none of the module basenames overlap
basenames_are_unique() {
local kmp=$1 krel=$2 basedir=$3 dir
for dir in $basedir/lib/modules/$krel/{weak-updates,updates,extra}/; do
if [ ! -d "$dir" ]; then
continue
fi
if [ -n "$(comm -1 -2 $tmpdir/basenames-$kmp \
<(find "$dir" -not -type d -printf '%f\n' | sort -u))" ]; then
return 1
fi
done
return 0
}
# Can a kmp be replaced by a different version of the same kmp in a kernel?
# Set the old kmp to "" when no kmp is to be removed.
can_replace_kmp() {
local old_kmp=$1 new_kmp=$2 krel=$3
local basedir=$tmpdir/$krel
local weak_updates=/lib/modules/$krel/weak-updates/
[ -d "$basedir" ] || \
create_temporary_modules_dir "$krel" "$basedir"
# force doit() to execute the commands (in $tmpdir)
doit=1 remove_kmp_modules "$old_kmp" "$krel" "$basedir"
if ! basenames_are_unique "$new_kmp" "$krel" "$basedir"; then
doit=1 add_kmp_modules "$old_kmp" "$krel" "$basedir"
return 1
fi
doit=1 add_kmp_modules "$new_kmp" "$krel" "$basedir"
if has_unresolved_symbols "$krel" "$basedir"; then
doit=1 remove_kmp_modules "$new_kmp" "$krel" "$basedir"
doit=1 add_kmp_modules "$old_kmp" "$krel" "$basedir"
return 1
fi
return 0
}
# Figure out which modules a kmp contains
check_kmp() {
local kmp=$1
# Make sure all modules are for the same kernel
set -- $(sed -re 's:^/lib/modules/([^/]+)/.*:\1:' \
$tmpdir/modules-$kmp \
| sort -u)
if [ $# -ne 1 ]; then
echo "Error: package $kmp seems to contain modules for multiple" \
"kernel versions" >&2
return 1
fi
echo $1 > $tmpdir/krel-$kmp
# Make sure none of the modules are in kernel/ or weak-updates/
if grep -qE -e '^/lib/modules/[^/]+/(kernel|weak-updates)/' \
$tmpdir/modules-$kmp; then
echo "Error: package $kmp must not install modules into " \
"kernel/ or weak-updates/" >&2
return 1
fi
sed -e 's:.*/::' $tmpdir/modules-$kmp \
| sort -u > $tmpdir/basenames-$kmp
}
# Figure out which kmps there are, and which modules they contain
# set basename to '*' to find all kmps of a given flavor
find_kmps() {
local basename=$1 flavor=$2
local kmp
for kmp in $(rpm -qa --qf '%{n}-%{v}-%{r}\n' --nodigest --nosignature "$basename-kmp-$flavor"); do
if rpm -q --qf '[%{providename}\n]' --nodigest --nosignature "$kmp" | \
grep -q '^kmp_in_kernel$'; then
# KMP built directly from the kernel spec file (fate#319339)
continue
fi
rpm -ql --nodigest --nosignature "$kmp" \
| grep -Ee '^/lib/modules/[^/]+/.+\.ko$' \
> $tmpdir/modules-$kmp
if [ $? != 0 ]; then
echo "WARNING: $kmp does not contain any kernel modules" >&2
rm -f $tmpdir/modules-$kmp
continue
fi
check_kmp $kmp || return 1
done
printf "%s\n" $tmpdir/basenames-* \
| sed -re "s:$tmpdir/basenames-::" \
| /usr/lib/rpm/rpmsort -r \
> $tmpdir/kmps
}
previous_version_of_kmp() {
local new_kmp=$1 krel=$2
local module symlink old_kmp
while read module; do
symlink=$(symlink_to_module $module $krel)
[ -e "$symlink" ] || continue
[ -L "$symlink" ] || return
old_kmp=$(grep -l "$(readlink "$symlink")" $tmpdir/modules-* | sed 's:.*/modules-::' ) || return
# The package %NAME must be the same
[ "${old_kmp%-*-*}" == "${new_kmp%-*-*}" ] || return
# The other kmp must be older
while read kmp; do
[ "$kmp" == "$old_kmp" ] && return
[ "$kmp" == "$new_kmp" ] && break
done <$tmpdir/kmps
done < $tmpdir/modules-$new_kmp
echo "$old_kmp"
}
# write GZIP / XZ uncompressed file to stdout
uncomp() {
local file=$1
if gzip -cd "$file" 2>/dev/null; then
return
fi
xz -cd "$file"
}
# test if mkinitrd is needed for $krel.
# stdin - list of changed modules ("_kernel_" for the whole kernel)
needs_mkinitrd() {
local krel=$1
local changed_basenames=($(sort -u))
# Don't generate an initrd for kdump here. It's done automatically with mkdumprd when
# /etc/init.d/boot.kdump is called to load the kdump kernel. See mkdumprd(8) why
# it is done this way.
if [[ "$krel" == *kdump* ]] ; then
return 1
fi
if ! [ -f /etc/fstab -a ! -e /.buildenv -a -x /sbin/mkinitrd ] ; then
echo "Please run mkinitrd as soon as your system is complete." >&2
return 1
fi
# KMPs can force mkinitrd run with %kernel_module_package -b that sets
# this variable
if test -n "$KMP_NEEDS_MKINITRD" && \
! test "$KMP_NEEDS_MKINITRD" -eq 0 2>/dev/null; then
return 0
fi
if [ "$changed_basenames" = "_kernel_" ]; then
return 0
fi
if [ ! -e /boot/initrd-$krel ]; then
return 0
fi
local initrd_basenames=($( (lsinitrd /boot/initrd-$krel | filter_basenames; INITRD_MODULES=; . /etc/sysconfig/kernel &>/dev/null; printf '%s.ko\n' $INITRD_MODULES) | sort -u))
local i=($(join <(printf '%s\n' "${changed_basenames[@]}") \
<(printf '%s\n' "${initrd_basenames[@]}") ))
log "changed initrd modules for kernel $krel: ${i[@]-none}"
if [ ${#i[@]} -gt 0 ]; then
return 0
fi
return 1
}
# run depmod and mkinitrd for kernel version $krel
# stdin - list of changed modules ("_kernel_" for a whole kernel)
run_depmod_and_mkinitrd() {
local krel=$1
local status=0
if [ -d /lib/modules/$krel -a -f /boot/System.map-$krel ] ; then
doit /sbin/depmod -F /boot/System.map-$krel -ae $krel || return 1
fi
if needs_mkinitrd $krel; then
local image
for x in vmlinuz image vmlinux linux bzImage uImage Image zImage; do
if [ -f /boot/$x-$krel ]; then
image=$x
break
fi
done
if [ -n "$image" ]; then
if test -n "$INITRD_IN_POSTTRANS"; then
mkdir -p /run/regenerate-initrd
touch /run/regenerate-initrd/$image-$krel
else
doit /sbin/mkinitrd -k /boot/$image-$krel -i /boot/initrd-$krel
status=$?
# mkinitrd fails with status 10 if any required kernel modules
# missing. We expect those modules to be added later (by one of
# the other kernel-$flavor packages).
if [ $status -eq 10 ]; then
log "mkinitrd failed with status 10 (module missing), proceeding"
status=0
fi
fi
else
echo "WARNING: kernel image for $krel not found!" >&2
fi
fi
return $status
}
kernel_changed() {
local krel=$1 flavor=${1##*-}
if [ ! -f /boot/System.map-$krel ]; then
# this kernel does not exist anymore
return 0
fi
if [ ! -d /lib/modules/$krel ]; then
# a kernel without modules - run mkinitrd nevertheless (to mount the
# root fs, etc).
echo "_kernel_" | run_depmod_and_mkinitrd "$krel"
return
fi
find_kmps '*' $flavor || return 1
local kmps=( $(cat $tmpdir/kmps) )
while :; do
[ ${#kmps[@]} -gt 0 ] || break
local added='' skipped='' n kmp
for ((n=0; n<${#kmps[@]}; n++)); do
kmp=${kmps[n]}
[ -n "$kmp" ] || continue
if kmp_is_present $kmp $krel; then
log "Package $kmp does not need to be added to kernel $krel"
kmps[n]=''
continue
fi
local old_kmp=$(previous_version_of_kmp $kmp $krel)
if can_replace_kmp "$old_kmp" $kmp $krel; then
remove_kmp_modules "$old_kmp" "$krel"
add_kmp_modules "$kmp" "$krel"
if [ -z "$old_kmp" ]; then
log "Package $kmp added to kernel $krel"
else
log "Package $old_kmp replaced by package $kmp in kernel $krel"
fi
added=1
kmps[n]=''
continue
fi
skipped=1
done
[ -n "$added" -a -n "$skipped" ] || break
done
echo "_kernel_" | run_depmod_and_mkinitrd "$krel"
}
add_kernel() {
local krel=$1
kernel_changed $krel
}
remove_kernel() {
local krel=$1
local dir=/lib/modules/$krel
if [ -d $dir/weak-updates ]; then
rm -rf $dir/weak-updates
fi
# If there are no KMPs left, remove the empty directory
rmdir $dir 2>/dev/null
}
add_kernel_modules() {
local krel=$1
cat >/dev/null
kernel_changed $krel
}
remove_kernel_modules() {
local krel=$1
cat >/dev/null
# FIXME: remove KMP symlinks that no longer work
kernel_changed $krel
}
add_kmp() {
local kmp=$1 kmpshort=${1%-*-*}
local basename=${kmpshort%-kmp-*} flavor=${kmpshort##*-}
# Find the kmp to be added as well as any previous versions
find_kmps "$basename" "$flavor" || return 1
local dir krel status
for dir in /lib/modules/*; do
krel=${dir#/lib/modules/}
case "$krel" in
*-$flavor)
;;
*)
continue
esac
[ -d $dir -a -f /boot/System.map-$krel ] || continue
if opt_debug=1 has_unresolved_symbols "$krel" "/"; then
echo "Warning: /lib/modules/$krel is inconsistent" >&2
echo "Warning: weak-updates symlinks might not be created" >&2
fi
if kmp_is_present $kmp $krel; then
log "Package $kmp does not need to be added to kernel $krel"
run_depmod_and_mkinitrd "$krel" <$tmpdir/basenames-$kmp || \
status=1
continue
fi
local old_kmp=$(previous_version_of_kmp $kmp $krel)
if can_replace_kmp "$old_kmp" $kmp $krel; then
remove_kmp_modules "$old_kmp" "$krel"
add_kmp_modules "$kmp" "$krel"
if [ -z "$old_kmp" ]; then
log "Package $kmp added to kernel $krel"
run_depmod_and_mkinitrd "$krel" <$tmpdir/basenames-$kmp || \
status=1
else
log "Package $old_kmp replaced by package $kmp in kernel $krel"
cat $tmpdir/basenames-{$old_kmp,$kmp} \
| run_depmod_and_mkinitrd "$krel" || status=1
fi
fi
done
return $status
}
remove_kmp() {
local kmp=$1 kmpshort=${1%-*-*}
local basename=${kmpshort%-kmp-*} flavor=${kmpshort##*-}
# Find any previous versions of the same kmp
find_kmps "$basename" "$flavor" || return 1
# Read the list of module names from standard input
# (This kmp may already have been removed!)
cat > $tmpdir/modules-$kmp
check_kmp "$kmp" || return 1
local dir krel status
for dir in /lib/modules/*; do
krel=${dir#/lib/modules/}
case "$krel" in
*-$flavor)
;;
*)
continue
esac
[ -d $dir -a -f /boot/System.map-$krel ] || continue
if opt_debug=1 has_unresolved_symbols "$krel" "/"; then
echo "Warning: /lib/modules/$krel is inconsistent" >&2
echo "Warning: weak-updates symlinks might not be created" >&2
fi
if kmp_is_present $kmp $krel; then
if [ $krel != "$(cat $tmpdir/krel-$kmp)" ]; then
remove_kmp_modules "$kmp" "$krel"
fi
local other_kmp
while read other_kmp; do
[ "$kmp" != "$other_kmp" ] || continue
if can_replace_kmp "" "$other_kmp" "$krel"; then
add_kmp_modules "$other_kmp" "$krel"
break
fi
done < $tmpdir/kmps
if [ -n "$other_kmp" ]; then
log "Package $kmp replaced by package $other_kmp in kernel $krel"
cat $tmpdir/basenames-{$kmp,$other_kmp} \
| run_depmod_and_mkinitrd "$krel" || status=1
else
log "Package $kmp removed from kernel $krel"
run_depmod_and_mkinitrd "$krel" <$tmpdir/basenames-$kmp || \
status=1
fi
fi
done
return $status
}
help() {
cat <<EOF
${0##*/} --add-kmp kmp-name-version-release
To be called in %post of kernel module packages. Creates
symlinks in compatible kernel's weak-updates/ directory and runs
mkinitrd if needed.
${0##*/} --remove-kmp kmp-name < module-list
To be called in %postun of kernel module packages. Removes
weak-updates/ symlinks for this KMP. As the KMP doesn't exist in
the RPM database at this point, the list of modules has to be
passed on standard input. Runs mkinitrd if needed.
${0##*/} --add-kernel kernel-release
To be called in %post of the kernel base package. Adds
compatibility symlinks for all compatible KMPs and runs mkinitrd
if needed.
${0##*/} --remove-kernel kernel-release
To be called in %postun of the kernel base package. Removes all
compatibility symlinks.
${0##*/} --add-kernel-modules kernel-release < module-list
To be called in %post of kernel subpackages that only contain
modules (i.e. not kernel-*-base). Adds newly available
compatibity symlinks and runs mkinitrd if needed.
${0##*/} --remove-kernel-modules kernel-release < module-list
To be called in %postun of kernel subpackages that only contain
modules (i.e. not kernel-*-base). Removes no longer working
compatibity symlinks and runs mkinitrd if needed.
${0##*/} --verbose ...
Print commands as they are executed and other information.
${0##*/} --dry-run ...
Do not perform any changes to the system. Useful together with
--verbose for debugging.
EOF
}
usage() {
echo "Usage:"
help | sed -n 's/^[^[:blank:]]/ &/p'
}
##############################################################################
save_argv=("$@")
options=`getopt -o vh --long add-kernel,remove-kernel,add-kmp,remove-kmp \
--long add-kernel-modules,remove-kernel-modules \
--long usage,help,verbose,dry-run,debug -- "$@"`
if [ $? -ne 0 ]; then
usage >&2
exit 1
fi
eval set -- "$options"
mode=
while :; do
case "$1" in
--add-kernel | --remove-kernel | --add-kernel-modules | \
--remove-kernel-modules | --add-kmp | --remove-kmp )
mode="$1"
;;
-v | --verbose)
opt_verbose=1
;;
--dry-run)
opt_dry_run=1
;;
--debug)
opt_debug=1
;;
--usage)
usage
exit 0
;;
-h | --help)
help
exit 0
;;
--)
shift
break
;;
esac
shift
done
err=
case "$mode" in
"")
err="Please specify one of the --add-* or --remove-* options"
;;
--add-kernel | --remove-kernel)
if [ $# -gt 1 ]; then
err="Too many arguments to $mode"
fi
[ $# -eq 1 ] || set -- $(uname -r)
;;
*)
if [ $# -ne 1 ]; then
err="Option $mode requires exactly one argument"
fi
;;
esac
if [ -n "$err" ]; then
echo "ERROR: $err" >&2
usage >&2
exit 1
fi
#unset LANG LC_ALL LC_COLLATE
tmpdir=$(mktemp -d /var/tmp/${0##*/}.XXXXXX)
trap "rm -rf $tmpdir" EXIT
shopt -s nullglob
case $mode in
--add-kernel)
add_kernel "$1"
;;
--remove-kernel)
remove_kernel "$1"
;;
--add-kernel-modules)
add_kernel_modules "$1"
;;
--remove-kernel-modules)
remove_kernel_modules "$1"
;;
--add-kmp)
add_kmp "$1"
;;
--remove-kmp)
remove_kmp "$1"
esac
# vim:shiftwidth=4 softtabstop=4