summaryrefslogtreecommitdiff
path: root/usr.sbin
diff options
context:
space:
mode:
authorMarc Espie <espie@cvs.openbsd.org>2010-08-01 10:03:25 +0000
committerMarc Espie <espie@cvs.openbsd.org>2010-08-01 10:03:25 +0000
commit6a7f23bc725b38ae9f6b6182e75e269121cc111f (patch)
treedb0185d57ba1c560557423e003daa347441a4d5d /usr.sbin
parentdc12fd6878f03f275d62703cab18459c2d1d51fc (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.pm6
-rw-r--r--usr.sbin/pkg_add/OpenBSD/PkgAdd.pm3
-rw-r--r--usr.sbin/pkg_add/OpenBSD/SharedItems.pm54
-rw-r--r--usr.sbin/pkg_add/OpenBSD/UpdateSet.pm16
-rw-r--r--usr.sbin/pkg_add/OpenBSD/Vstat.pm36
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;