From 027c63c38d101d498328adec456b37cca07e4e5f6c1182ff05fea78954aaa256 Mon Sep 17 00:00:00 2001 From: "Dr. Werner Fink" Date: Mon, 31 Mar 2014 19:51:08 +0000 Subject: [PATCH] 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 --- kmp-install | 317 ++++++++++++++++++++++++++++++++++++++ modprobe.conf.tar.bz2 | 4 +- suse-module-tools.changes | 17 ++ suse-module-tools.spec | 3 + 4 files changed, 339 insertions(+), 2 deletions(-) create mode 100644 kmp-install diff --git a/kmp-install b/kmp-install new file mode 100644 index 0000000..7000206 --- /dev/null +++ b/kmp-install @@ -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] ... +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; diff --git a/modprobe.conf.tar.bz2 b/modprobe.conf.tar.bz2 index dbae041..efc4f28 100644 --- a/modprobe.conf.tar.bz2 +++ b/modprobe.conf.tar.bz2 @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:1ac5daaf81b8c4c6c0aa83b9ffc89aedada1d1e8ff864166ecb52034a628b375 -size 2783 +oid sha256:304a3d04717c996491fca55dcf320a4f19ada765d1a53e83419a404d74d6c60c +size 3000 diff --git a/suse-module-tools.changes b/suse-module-tools.changes index 0a72a9d..6abb896 100644 --- a/suse-module-tools.changes +++ b/suse-module-tools.changes @@ -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 diff --git a/suse-module-tools.spec b/suse-module-tools.spec index 9c4ec50..25b0403 100644 --- a/suse-module-tools.spec +++ b/suse-module-tools.spec @@ -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