diff options
Diffstat (limited to 'urpm')
-rw-r--r-- | urpm/main_loop.pm | 7 | ||||
-rw-r--r-- | urpm/select.pm | 43 | ||||
-rw-r--r-- | urpm/sys.pm | 18 |
3 files changed, 68 insertions, 0 deletions
diff --git a/urpm/main_loop.pm b/urpm/main_loop.pm index 9cf8ab99..d7fbb504 100644 --- a/urpm/main_loop.pm +++ b/urpm/main_loop.pm @@ -82,6 +82,9 @@ my ($ok, $nok) = (0, 0); my @errors; my $exit_code = 0; +my $migrate_back_rpmdb_db_version = + $urpm->{root} && urpm::select::should_we_migrate_back_rpmdb_db_version($urpm, $state); + foreach my $set (@{$state->{transaction} || []}) { #- put a blank line to separate with previous transaction or user question. @@ -275,6 +278,10 @@ foreach my $set (@{$state->{transaction} || []}) { } } +if ($migrate_back_rpmdb_db_version) { + urpm::sys::migrate_back_rpmdb_db_version($urpm, $urpm->{root}); +} + $callbacks->{completed} and $callbacks->{completed}->(); if ($nok) { diff --git a/urpm/select.pm b/urpm/select.pm index 6ae72bcb..3183eac8 100644 --- a/urpm/select.pm +++ b/urpm/select.pm @@ -10,6 +10,8 @@ use URPM; my $default_priority_list = 'rpm,perl-URPM,perl-MDV-Distribconf,urpmi,meta-task,glibc'; my @priority_list = split(',', $default_priority_list); +my $evr_re = qr/[^\-]*-[^\-]*\.[^\.\-]*$/; + sub add_packages_to_priority_upgrade_list { @priority_list = uniq(@priority_list, @_); } @@ -573,6 +575,21 @@ sub translate_why_unselected_one { $fullname . ($s ? " ($s)" : ''); } +sub selected_packages_providing { + my ($urpm, $state, $name) = @_; + map { $urpm->{depslist}[$_] } grep { $state->{selected}{$_} } keys %{$urpm->{provides}{$name} || {}}; +} + +sub was_pkg_name_installed { + my ($rejected, $name) = @_; + + foreach (keys %$rejected) { + /^\Q$name\E-$evr_re/ or next; + $rejected->{$_}{obsoleted} and return 1; + } + 0; +} + sub removed_packages { my (undef, $state) = @_; grep { @@ -623,4 +640,30 @@ sub translate_why_removed_one { $fullname . ($s ? "\n ($s)" : ''); } +sub _libdb_version { $_[0] =~ /libdb-(\S+)\.so/ ? eval "v$1" : () } + +sub should_we_migrate_back_rpmdb_db_version { + my ($urpm, $state) = @_; + + my ($pkg) = urpm::select::selected_packages_providing($urpm, $state, 'rpm') or return; + urpm::select::was_pkg_name_installed($state->{rejected}, 'rpm') and return; + my ($rooted_librpm_version) = map { _libdb_version($_) } $pkg->requires; + + my $urpmi_librpm_version = _libdb_version(scalar `ldd /bin/rpm`); + + if ($urpmi_librpm_version ge v4.6) { + if ($rooted_librpm_version && $rooted_librpm_version ge v4.6) { + $urpm->{debug} and $urpm->{debug}("chrooted db version used by librpm is at least as good as non-rooted one"); + } else { + foreach my $bin ('db_dump', 'db42_load') { + urpm::sys::whereis_binary($bin) + or $urpm->{error}("can not migrate rpm db from Hash version 9 to Hash version 8 without $bin"), + return; + } + return 1; + } + } + 0; +} + 1; diff --git a/urpm/sys.pm b/urpm/sys.pm index 2e36a273..088a3150 100644 --- a/urpm/sys.pm +++ b/urpm/sys.pm @@ -221,6 +221,24 @@ sub print_need_restart() { print "$_\n" foreach values %$h; } +sub migrate_back_rpmdb_db_version { + my ($urpm, $root) = @_; + + $urpm->{info}("migrating back the created rpm db from Hash version 9 to Hash version 8"); + + foreach my $db_file (glob("$root/var/lib/rpm/[A-Z]*")) { + rename $db_file, "$db_file."; + system("db_dump $db_file. | db42_load $db_file"); + if (-e $db_file) { + unlink "$db_file."; + } else { + rename "$db_file.", $db_file; + $urpm->{error}("rpm db migration failed on $db_file. You will not be able to run rpm chrooted"); + return; + } + } + clean_rpmdb_shared_regions($root); +} #- create a plain rpm from an installed rpm and a delta rpm (in the current directory) #- returns the new rpm filename in case of success |