diff options
author | Marc Espie <espie@cvs.openbsd.org> | 2010-08-01 10:03:25 +0000 |
---|---|---|
committer | Marc Espie <espie@cvs.openbsd.org> | 2010-08-01 10:03:25 +0000 |
commit | 6a7f23bc725b38ae9f6b6182e75e269121cc111f (patch) | |
tree | db0185d57ba1c560557423e003daa347441a4d5d /usr.sbin | |
parent | dc12fd6878f03f275d62703cab18459c2d1d51fc (diff) |
fix the qt 4.5 -> 4.6 update issue.
since we usually deal with directories in a global way, replacing a
directory with something else didn't work.
the fix is to record removed directories in Vstat in a "lazy" way:
we only test these objects for existence if we add something else at
the same location. Since this happens rarely, we can afford to perform
the whole SharedItems dance twice...
Diffstat (limited to 'usr.sbin')
-rw-r--r-- | usr.sbin/pkg_add/OpenBSD/Delete.pm | 6 | ||||
-rw-r--r-- | usr.sbin/pkg_add/OpenBSD/PkgAdd.pm | 3 | ||||
-rw-r--r-- | usr.sbin/pkg_add/OpenBSD/SharedItems.pm | 54 | ||||
-rw-r--r-- | usr.sbin/pkg_add/OpenBSD/UpdateSet.pm | 16 | ||||
-rw-r--r-- | usr.sbin/pkg_add/OpenBSD/Vstat.pm | 36 |
5 files changed, 98 insertions, 17 deletions
diff --git a/usr.sbin/pkg_add/OpenBSD/Delete.pm b/usr.sbin/pkg_add/OpenBSD/Delete.pm index 32c40f8a5c0..77644983efb 100644 --- a/usr.sbin/pkg_add/OpenBSD/Delete.pm +++ b/usr.sbin/pkg_add/OpenBSD/Delete.pm @@ -1,5 +1,5 @@ # ex:ts=8 sw=4: -# $OpenBSD: Delete.pm,v 1.107 2010/07/25 05:20:34 espie Exp $ +# $OpenBSD: Delete.pm,v 1.108 2010/08/01 10:03:24 espie Exp $ # # Copyright (c) 2003-2007 Marc Espie <espie@openbsd.org> # @@ -311,9 +311,9 @@ sub prepare_for_deletion { my ($self, $state, $pkgname) = @_; my $fname = $state->{destdir}.$self->fullname; -# $state->vstat->remove_directory($fname); + $state->vstat->remove_directory($fname, $self); return unless $self->{noshadow}; - $state->{noshadow}->{$state->{destdir}.$self->fullname} = 1; + $state->{noshadow}{$fname} = 1; } sub delete diff --git a/usr.sbin/pkg_add/OpenBSD/PkgAdd.pm b/usr.sbin/pkg_add/OpenBSD/PkgAdd.pm index 97e762f9cd9..8fa5f2db23f 100644 --- a/usr.sbin/pkg_add/OpenBSD/PkgAdd.pm +++ b/usr.sbin/pkg_add/OpenBSD/PkgAdd.pm @@ -1,7 +1,7 @@ #! /usr/bin/perl # ex:ts=8 sw=4: -# $OpenBSD: PkgAdd.pm,v 1.10 2010/07/30 10:06:44 espie Exp $ +# $OpenBSD: PkgAdd.pm,v 1.11 2010/08/01 10:03:24 espie Exp $ # # Copyright (c) 2003-2010 Marc Espie <espie@openbsd.org> # @@ -656,6 +656,7 @@ sub delete_old_packages } OpenBSD::PkgCfl::unregister($o->plist, $state); }); + $set->cleanup_old_shared($state); # Here there should be code to handle old libs } diff --git a/usr.sbin/pkg_add/OpenBSD/SharedItems.pm b/usr.sbin/pkg_add/OpenBSD/SharedItems.pm index fd1df6afc24..fb0cf7e81d5 100644 --- a/usr.sbin/pkg_add/OpenBSD/SharedItems.pm +++ b/usr.sbin/pkg_add/OpenBSD/SharedItems.pm @@ -1,5 +1,5 @@ # ex:ts=8 sw=4: -# $OpenBSD: SharedItems.pm,v 1.26 2010/06/30 10:51:04 espie Exp $ +# $OpenBSD: SharedItems.pm,v 1.27 2010/08/01 10:03:24 espie Exp $ # # Copyright (c) 2004-2006 Marc Espie <espie@openbsd.org> # @@ -34,13 +34,53 @@ sub find_items_in_installed_packages sub { my $e = shift; my $plist = OpenBSD::PackingList->from_installation($e, - \&OpenBSD::PackingList::SharedItemsOnly) or next; + \&OpenBSD::PackingList::SharedItemsOnly) or return; return if !defined $plist; $plist->record_shared($db, $e); }); return $db; } +sub check_shared +{ + my ($set, $o) = @_; + if (!defined $set->{db}) { + $set->{db} = OpenBSD::SharedItemsRecorder->new; + for my $pkg (installed_packages()) { + next if $set->{older}{$pkg}; + my $plist = OpenBSD::PackingList->from_installation($pkg, + \&OpenBSD::PackingList::SharedItemsOnly) or next; + next if !defined $plist; + $plist->record_shared($set->{db}, $pkg); + } + } + if (defined $set->{db}{dirs}{$o->fullname}) { + return 1; + } else { + push(@{$set->{old_shared}{$o->fullname}}, $o); + return 0; + } +} + +sub wipe_directory +{ + my ($state, $h, $d) = @_; + + my $realname = $state->{destdir}.$d; + + for my $i (@{$h->{$d}}) { + $state->log->set_context($i->{pkgname}); + $i->cleanup($state); + } + if (!rmdir $realname) { + $state->log("Error deleting directory #1: #2", + $realname, $!) + unless $state->{dirs_okay}->{$d}; + return 0; + } + return 1; +} + sub cleanup { my ($recorder, $state) = @_; @@ -68,15 +108,7 @@ sub cleanup $i->reload($state); } } else { - for my $i (@{$h->{$d}}) { - $state->log->set_context($i->{pkgname}); - $i->cleanup($state); - } - if (!rmdir $realname) { - $state->log("Error deleting directory #1: #2", - $realname, $!) - unless $state->{dirs_okay}->{$d}; - } + wipe_directory($state, $h, $d); } $done++; } diff --git a/usr.sbin/pkg_add/OpenBSD/UpdateSet.pm b/usr.sbin/pkg_add/OpenBSD/UpdateSet.pm index 38ee050d89f..22eb42cd3dc 100644 --- a/usr.sbin/pkg_add/OpenBSD/UpdateSet.pm +++ b/usr.sbin/pkg_add/OpenBSD/UpdateSet.pm @@ -1,5 +1,5 @@ # ex:ts=8 sw=4: -# $OpenBSD: UpdateSet.pm,v 1.61 2010/07/11 07:27:25 espie Exp $ +# $OpenBSD: UpdateSet.pm,v 1.62 2010/08/01 10:03:24 espie Exp $ # # Copyright (c) 2007-2010 Marc Espie <espie@openbsd.org> # @@ -286,6 +286,8 @@ sub validate_plists $state->{problems} = 0; delete $state->{overflow}; + $state->{current_set} = $self; + for my $o ($self->older_to_do) { require OpenBSD::Delete; OpenBSD::Delete::validate_plist($o->{plist}, $state); @@ -321,6 +323,18 @@ sub validate_plists } } +sub cleanup_old_shared +{ + my ($set, $state) = @_; + my $h = $set->{old_shared}; + + for my $d (sort {$b cmp $a} keys %$h) { + OpenBSD::SharedItems::wipe_directory($state, $h, $d) || + $state->fatal("Can't continue"); + delete $state->{recorder}{dirs}{$d}; + } +} + sub create_new { my ($class, $pkgname) = @_; diff --git a/usr.sbin/pkg_add/OpenBSD/Vstat.pm b/usr.sbin/pkg_add/OpenBSD/Vstat.pm index b977317badf..a88b0801ec1 100644 --- a/usr.sbin/pkg_add/OpenBSD/Vstat.pm +++ b/usr.sbin/pkg_add/OpenBSD/Vstat.pm @@ -1,5 +1,5 @@ # ex:ts=8 sw=4: -# $OpenBSD: Vstat.pm,v 1.61 2010/06/30 10:51:04 espie Exp $ +# $OpenBSD: Vstat.pm,v 1.62 2010/08/01 10:03:24 espie Exp $ # # Copyright (c) 2003-2007 Marc Espie <espie@openbsd.org> # @@ -59,6 +59,7 @@ sub none } } + { package OpenBSD::Vstat::Object::None; our @ISA = qw(OpenBSD::Vstat::Object); @@ -77,6 +78,28 @@ sub new } } +{ +package OpenBSD::Vstat::Object::Directory; +our @ISA = qw(OpenBSD::Vstat::Object); + +sub new +{ + my ($class, $fname, $set, $o) = @_; + bless { name => $fname, set => $set, o => $o }, $class; +} + +# XXX directories don't do anything until you test for their presence. +# which only happens if you want to replace a directory with a file. +sub exists +{ + my $self = shift; + require OpenBSD::SharedItems; + + return OpenBSD::SharedItems::check_shared($self->{set}, $self->{o}); +} + +} + package OpenBSD::Vstat; use File::Basename; use OpenBSD::Paths; @@ -187,6 +210,17 @@ sub remove_first return defined($size) ? $self->account_for($name, -$size) : undef; } +# since directories may become files during updates, we may have to remove +# them early, so we need to record them: store exactly as much info as needed +# for SharedItems. +sub remove_directory +{ + my ($self, $name, $o) = @_; + $self->{v}[0]->{$name} = OpenBSD::Vstat::Object::Directory->new($name, + $self->{state}->{current_set}, $o); +} + + sub tally { my $self = shift; |