summaryrefslogtreecommitdiffstats
path: root/urpm
diff options
context:
space:
mode:
Diffstat (limited to 'urpm')
-rw-r--r--urpm/main_loop.pm7
-rw-r--r--urpm/select.pm43
-rw-r--r--urpm/sys.pm18
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