From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on dcvr.yhbt.net X-Spam-Level: X-Spam-ASN: X-Spam-Status: No, score=-4.0 required=3.0 tests=ALL_TRUSTED,BAYES_00 shortcircuit=no autolearn=ham autolearn_force=no version=3.4.2 Received: from localhost (dcvr.yhbt.net [127.0.0.1]) by dcvr.yhbt.net (Postfix) with ESMTP id 0676A20670 for ; Thu, 23 May 2019 09:37:13 +0000 (UTC) From: Eric Wong To: meta@public-inbox.org Subject: [PATCH 21/26] xcpdb: remove temporary directories on aborts Date: Thu, 23 May 2019 09:36:59 +0000 Message-Id: <20190523093704.18367-22-e@80x24.org> In-Reply-To: <20190523093704.18367-1-e@80x24.org> References: <20190523093704.18367-1-e@80x24.org> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit List-Id: Cleanup temporary directories on common termination signals (INT, HUP, PIPE, TERM), but only if it's not in the process of being committed via rename() sequence. --- lib/PublicInbox/Xapcmd.pm | 39 +++++++++++++++++++++++++++++++++++++-- 1 file changed, 37 insertions(+), 2 deletions(-) diff --git a/lib/PublicInbox/Xapcmd.pm b/lib/PublicInbox/Xapcmd.pm index 0e44804..06389dd 100644 --- a/lib/PublicInbox/Xapcmd.pm +++ b/lib/PublicInbox/Xapcmd.pm @@ -31,13 +31,15 @@ sub commit_changes ($$$) { $over->connect->sqlite_backup_to_file($tmp_over); $over = undef; } + chmod($st[2] & 07777, $new) or die "chmod $old: $!\n"; + # Xtmpdir->DESTROY won't remove $new after this: rename($old, "$new/old") or die "rename $old => $new/old: $!\n"; - chmod($st[2] & 07777, $new) or die "chmod $old: $!\n"; rename($new, $old) or die "rename $new => $old: $!\n"; my $prev = "$old/old"; remove_tree($prev) or die "failed to remove $prev: $!\n"; } + $tmp->done; if ($reindex) { $opt->{-skip_lock} = 1; PublicInbox::Admin::index_inbox($ibx, $opt); @@ -126,7 +128,7 @@ sub run { my $old = $ibx->search->xdir(1); -d $old or die "$old does not exist\n"; - my $tmp = {}; # old partition => new (tmp) partition + my $tmp = PublicInbox::Xtmpdirs->new; my $v = $ibx->{version} ||= 1; my @cmds; @@ -286,4 +288,37 @@ sub cpdb { remove_tree($tmp) or die "failed to remove $tmp: $!\n"; } +# slightly easier-to-manage manage than END{} blocks +package PublicInbox::Xtmpdirs; +use strict; +use warnings; +use File::Path qw(remove_tree); +my %owner; + +sub new { + # http://www.tldp.org/LDP/abs/html/exitcodes.html + $SIG{INT} = sub { exit(130) }; + $SIG{HUP} = $SIG{PIPE} = $SIG{TERM} = sub { exit(1) }; + my $self = bless {}, $_[0]; # old partition => new (tmp) partition + $owner{"$self"} = $$; + $self; +} + +sub done { + my ($self) = @_; + delete $owner{"$self"}; + $SIG{INT} = $SIG{HUP} = $SIG{PIPE} = $SIG{TERM} = 'DEFAULT'; + %$self = (); +} + +sub DESTROY { + my ($self) = @_; + my $owner_pid = delete $owner{"$self"} or return; + return if $owner_pid != $$; + foreach my $new (values %$self) { + remove_tree($new) unless -d "$new/old"; + } + $SIG{INT} = $SIG{HUP} = $SIG{PIPE} = $SIG{TERM} = 'DEFAULT'; +} + 1; -- EW