I've changed pkg_add for updates and tied files a while back, which resulted
in creating a lot of temp files. The logic was complicated, and I didn't
want to make it more complex at the time until most of the issues were fixed.

Then we got tags, so that most packing-lists are innocuous these days.

Now is that time, the following patch may speed up some updates and additions
significantly, in case the packing-lists don't contain "random execs".

What this does:
- in case we extract a new file that's not on the filesystem, we can extract
in-place instead of going through a temporary item

- in case we are matching files with identical files during an update, and
the filename doesn't change, we acknowledge we don't need to do anything.

Caveat: this may bite. It is advised to run pkg_check afterwards and
report file system discrepancies.


Index: OpenBSD/Add.pm
===================================================================
RCS file: /cvs/src/usr.sbin/pkg_add/OpenBSD/Add.pm,v
retrieving revision 1.187
diff -u -p -r1.187 Add.pm
--- OpenBSD/Add.pm      9 Mar 2022 12:27:51 -0000       1.187
+++ OpenBSD/Add.pm      15 Mar 2022 10:08:07 -0000
@@ -466,6 +466,7 @@ sub find_safe_dir
        my $fullname = $self->fullname;
        my $filename = $state->{destdir}.$fullname;
        my $d = dirname($filename);
+       my $orig = $d;
 
        # we go back up until we find an existing directory.
        # hopefully this will be on the same file system.
@@ -483,6 +484,12 @@ sub find_safe_dir
        if (!-e _ && !$state->{not}) {
                $state->make_path($d, $fullname);
        }
+       if ($state->{current_set}{simple_update} && 
+           $d eq $orig && 
+           !-e $filename) {
+               $self->{avoid_temp} = $filename;
+       }
+
        return $d;
 }
 
@@ -503,6 +510,18 @@ sub create_temp
        return ($fh, $tempname);
 }
 
+sub may_create_temp
+{
+       my ($self, $d, $state) = @_;
+       if ($self->{avoid_temp}) {
+               if (open(my $fh, '>', $self->{avoid_temp})) {
+                       return ($fh, $self->{avoid_temp});
+               }
+       }
+       delete $self->{avoid_temp};
+       return $self->create_temp($d, $state);
+}
+
 sub tie
 {
        my ($self, $state) = @_;
@@ -513,14 +532,22 @@ sub tie
        $self->SUPER::extract($state);
 
        my $d = $self->find_safe_dir($state);
+       my $src = $self->{tieto}->realname($state);
+       my $dest = $self->realname($state);
+       if ($state->{current_set}{simple_update} && $src eq $dest) {
+               $state->say("No name change on tied file #1", $src)
+                   if $state->verbose >= 3;
+               $self->{tieto}{dont_delete} = 1;
+               $self->{avoid_temp} = 1;
+               return;
+       }
        if ($state->{not}) {
                $state->say("link #1 -> #2", 
                    $self->name, $d) if $state->verbose >= 3;
        } else {
-               my ($fh, $tempname) = $self->create_temp($d, $state);
+               my ($fh, $tempname) = $self->may_create_temp($d, $state);
 
                return if !defined $tempname;
-               my $src = $self->{tieto}->realname($state);
                unlink($tempname);
                $state->say("link #1 -> #2", $src, $tempname)
                    if $state->verbose >= 3;
@@ -528,6 +555,7 @@ sub tie
        }
 }
 
+
 sub extract
 {
        my ($self, $state, $file) = @_;
@@ -540,13 +568,13 @@ sub extract
                    $self->name, $d) if $state->verbose >= 3;
                $state->{archive}->skip;
        } else {
-               my ($fh, $tempname) = $self->create_temp($d, $state);
-               if (!defined $tempname) {
+               my ($fh, $filename) = $self->may_create_temp($d, $state);
+               if (!defined $filename) {
                        $state->{archive}->skip;
                        return;
                }
 
-               $state->say("extract #1 -> #2", $self->name, $tempname) 
+               $state->say("extract #1 -> #2", $self->name, $filename) 
                    if $state->verbose >= 3;
 
 
@@ -555,7 +583,7 @@ sub extract
                            $self->stringize);
                }
                $file->extract_to_fh($fh);
-               $self->may_check_digest($tempname, $state);
+               $self->may_check_digest($filename, $state);
        }
 }
 
@@ -576,17 +604,21 @@ sub install
        } elsif (defined $self->{symlink}) {
                symlink($self->{symlink}, $destdir.$fullname);
        } else {
-               if (!defined $self->{tempname}) {
-                       return if $state->allow_nonroot($fullname);
-                       $state->fatal("No tempname for #1", $fullname);
+               if (defined $self->{avoid_temp}) {
+                       delete $self->{avoid_temp};
+               } else {
+                       if (!defined $self->{tempname}) {
+                               return if $state->allow_nonroot($fullname);
+                               $state->fatal("No tempname for #1", $fullname);
+                       }
+                       rename($self->{tempname}, $destdir.$fullname) or
+                           $state->fatal("can't move #1 to #2: #3",
+                               $self->{tempname}, $fullname, $!);
+                       $state->say("moving #1 -> #2",
+                           $self->{tempname}, $destdir.$fullname)
+                               if $state->verbose >= 5;
+                       delete $self->{tempname};
                }
-               rename($self->{tempname}, $destdir.$fullname) or
-                   $state->fatal("can't move #1 to #2: #3",
-                       $self->{tempname}, $fullname, $!);
-               $state->say("moving #1 -> #2",
-                   $self->{tempname}, $destdir.$fullname)
-                       if $state->verbose >= 5;
-               delete $self->{tempname};
        }
        $self->set_modes($state, $destdir.$fullname);
 }
Index: OpenBSD/Delete.pm
===================================================================
RCS file: /cvs/src/usr.sbin/pkg_add/OpenBSD/Delete.pm,v
retrieving revision 1.160
diff -u -p -r1.160 Delete.pm
--- OpenBSD/Delete.pm   24 Jul 2019 18:05:26 -0000      1.160
+++ OpenBSD/Delete.pm   15 Mar 2022 10:08:07 -0000
@@ -448,6 +448,7 @@ sub is_intact
 sub delete
 {
        my ($self, $state) = @_;
+       return if $self->{dont_delete};
        my $realname = $self->realname($state);
 
        if (defined $self->{symlink}) {

Reply via email to