fix the qt 4.5 -> 4.6 update issue.
authorespie <espie@openbsd.org>
Sun, 1 Aug 2010 10:03:24 +0000 (10:03 +0000)
committerespie <espie@openbsd.org>
Sun, 1 Aug 2010 10:03:24 +0000 (10:03 +0000)
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...

usr.sbin/pkg_add/OpenBSD/Delete.pm
usr.sbin/pkg_add/OpenBSD/PkgAdd.pm
usr.sbin/pkg_add/OpenBSD/SharedItems.pm
usr.sbin/pkg_add/OpenBSD/UpdateSet.pm
usr.sbin/pkg_add/OpenBSD/Vstat.pm

index 32c40f8..7764498 100644 (file)
@@ -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
index 97e762f..8fa5f2d 100644 (file)
@@ -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
 }
 
index fd1df6a..fb0cf7e 100644 (file)
@@ -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++;
        }
index 38ee050..22eb42c 100644 (file)
@@ -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) = @_;
index b977317..a88b080 100644 (file)
@@ -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;