forked from pool/suse-module-tools
Accepting request 228277 from home:michal-m:branches:Base:System
- Use softdep to order {u,o,e}hci-hcd drivers. - Drop ia64 modprobe config. - Add kmp-install tool for easier installation of SolidDriver KMPs (fate#314581). - load the uas driver simulsimultaneously with the usb_storage driver and vice versa (bnc#862397) OBS-URL: https://build.opensuse.org/request/show/228277 OBS-URL: https://build.opensuse.org/package/show/Base:System/suse-module-tools?expand=0&rev=11
This commit is contained in:
parent
afc042a2b6
commit
027c63c38d
317
kmp-install
Normal file
317
kmp-install
Normal file
@ -0,0 +1,317 @@
|
||||
#!/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;
|
@ -1,3 +1,3 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:1ac5daaf81b8c4c6c0aa83b9ffc89aedada1d1e8ff864166ecb52034a628b375
|
||||
size 2783
|
||||
oid sha256:304a3d04717c996491fca55dcf320a4f19ada765d1a53e83419a404d74d6c60c
|
||||
size 3000
|
||||
|
@ -1,3 +1,15 @@
|
||||
-------------------------------------------------------------------
|
||||
Mon Mar 31 09:11:16 UTC 2014 - mmarek@suse.cz
|
||||
|
||||
- Use softdep to order {u,o,e}hci-hcd drivers.
|
||||
- Drop ia64 modprobe config.
|
||||
|
||||
-------------------------------------------------------------------
|
||||
Fri Mar 28 14:25:25 UTC 2014 - mmarek@suse.cz
|
||||
|
||||
- Add kmp-install tool for easier installation of SolidDriver KMPs
|
||||
(fate#314581).
|
||||
|
||||
-------------------------------------------------------------------
|
||||
Tue Mar 11 12:57:36 UTC 2014 - mmarek@suse.cz
|
||||
|
||||
@ -18,6 +30,11 @@ Mon Mar 10 15:08:15 UTC 2014 - mmarek@suse.cz
|
||||
- Install 10-unsupported-modules.conf unconditionally, kmod has
|
||||
been patched.
|
||||
|
||||
-------------------------------------------------------------------
|
||||
Fri Feb 7 13:05:20 UTC 2014 - rsalevsky@suse.com
|
||||
|
||||
- load the uas driver simulsimultaneously with the usb_storage driver and vice versa (bnc#862397)
|
||||
|
||||
-------------------------------------------------------------------
|
||||
Wed May 29 12:44:00 UTC 2013 - schwab@suse.de
|
||||
|
||||
|
@ -38,6 +38,7 @@ Source6: weak-modules2
|
||||
Source7: driver-check.sh
|
||||
Source8: suse-module-tools.rpmlintrc
|
||||
Source9: modsign-verify
|
||||
Source10: kmp-install
|
||||
BuildRoot: %{_tmppath}/%{name}-%{version}-build
|
||||
|
||||
%description
|
||||
@ -80,6 +81,7 @@ install -pm 755 %_sourcedir/driver-check.sh "$b/usr/lib/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/"
|
||||
|
||||
%post
|
||||
test_allow_on_install()
|
||||
@ -144,6 +146,7 @@ fi
|
||||
%dir /etc/depmod.d
|
||||
%config /etc/depmod.d/00-system.conf
|
||||
%_docdir/module-init-tools
|
||||
/usr/bin/kmp-install
|
||||
/usr/bin/modsign-verify
|
||||
/usr/lib/module-init-tools
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user