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 835201F5AE for ; Thu, 29 Apr 2021 19:49:57 +0000 (UTC) From: Eric Wong To: meta@public-inbox.org Subject: [PATCH] lei_store: fix locking w.r.t epoch creation Date: Thu, 29 Apr 2021 19:49:57 +0000 Message-Id: <20210429194957.19303-1-e@80x24.org> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit List-Id: Prior to this change, it was possible for oneshot lei processes to race on epoch creation/rollover. lei-daemon normally prevents the problem by funnelling all writes to a single socket, but oneshot lei has no such protection. --- lib/PublicInbox/ExtSearchIdx.pm | 2 +- lib/PublicInbox/LeiStore.pm | 9 ++++++--- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/lib/PublicInbox/ExtSearchIdx.pm b/lib/PublicInbox/ExtSearchIdx.pm index 9d6b3b9d..08f2295a 100644 --- a/lib/PublicInbox/ExtSearchIdx.pm +++ b/lib/PublicInbox/ExtSearchIdx.pm @@ -926,7 +926,7 @@ sub update_last_commit { # overrides V2Writable sub _idx_init { # with_umask callback my ($self, $opt) = @_; - PublicInbox::V2Writable::_idx_init($self, $opt); + PublicInbox::V2Writable::_idx_init($self, $opt); # acquires ei.lock $self->{midx} = PublicInbox::MiscIdx->new($self); } diff --git a/lib/PublicInbox/LeiStore.pm b/lib/PublicInbox/LeiStore.pm index fcc9224d..8af740fd 100644 --- a/lib/PublicInbox/LeiStore.pm +++ b/lib/PublicInbox/LeiStore.pm @@ -88,6 +88,7 @@ sub importer { $self->checkpoint; $max = $self->git_epoch_max + 1; } + my (undef, $tl) = eidx_init($self); # acquire lock my $pfx = $self->git_pfx; $max //= $self->git_epoch_max; while (1) { @@ -97,7 +98,9 @@ sub importer { my $git = PublicInbox::Git->new($latest); if (!$old) { $git->qx(qw(config core.sharedRepository 0600)); - $self->done; # force eidx_init on next round + $self->done; # unlock + # re-acquire lock, update alternates for new epoch + (undef, $tl) = eidx_init($self); } my $packed_bytes = $git->packed_bytes; my $unpacked_bytes = $packed_bytes / $self->packing_factor; @@ -130,7 +133,7 @@ sub eidx_init { my $tl = wantarray && $self->{-err_wr} ? PublicInbox::OnDestroy->new($$, \&_tail_err, $self) : undef; - $eidx->idx_init({-private => 1}); + $eidx->idx_init({-private => 1}); # acquires lock wantarray ? ($eidx, $tl) : $eidx; } @@ -204,7 +207,7 @@ sub set_sync_info ($$$) { sub add_eml { my ($self, $eml, $vmd, $xoids) = @_; my $im = $self->importer; # may create new epoch - my ($eidx, $tl) = eidx_init($self); # updates/writes alternates file + my ($eidx, $tl) = eidx_init($self); my $oidx = $eidx->{oidx}; # PublicInbox::Import::add checks this my $smsg = bless { -oidx => $oidx }, 'PublicInbox::Smsg'; my $im_mark = $im->add($eml, undef, $smsg);