From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) 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.0 Received: from localhost (dcvr.yhbt.net [127.0.0.1]) by dcvr.yhbt.net (Postfix) with ESMTP id E7EA92095B for ; Tue, 21 Mar 2017 21:15:29 +0000 (UTC) From: Eric Wong To: meta@public-inbox.org Subject: [PATCH ssoma] extractor: backup state file when updating and fsync Date: Tue, 21 Mar 2017 21:15:29 +0000 Message-Id: <20170321211529.6957-1-e@80x24.org> List-Id: The state file is important, so try not to lose it by creating a backup before git writes it, and fsync the result ASAP since git does not consider the config file important enough. --- lib/Ssoma/Extractor.pm | 26 +++++++++++++++++++++++++- 1 file changed, 25 insertions(+), 1 deletion(-) diff --git a/lib/Ssoma/Extractor.pm b/lib/Ssoma/Extractor.pm index afc9afd..7e2b5d1 100644 --- a/lib/Ssoma/Extractor.pm +++ b/lib/Ssoma/Extractor.pm @@ -7,6 +7,7 @@ use strict; use warnings; use Ssoma::Git; use Email::LocalDelivery; +use IO::File; sub new { my ($class, $git) = @_; @@ -106,9 +107,32 @@ sub _extract { # update the last-imported var { + # This state file is important, and git does not fsync it. + if (open my $st, '<', $state) { + # clobber existing backup + my $bak = "$state.bak"; + open my $bk, '>', $bak or die + "failed to open backup ($bak): $!"; + my $size = -s $st; + my $r = read($st, my $buf, $size); + $st->close or die "close $state failed for copy: $!"; + defined $r or die "failed read $size from $state: $!"; + $r == $size or die "read ($r != $size) from $state"; + $bk->write($buf) or die "failed to write $bak: $!"; + defined($bk->flush) or die "flush $bak failed: $!"; + defined($bk->sync) or die "fsync $bak failed: $!"; + $bk->close or die "close $bak failed: $!"; + } + local $ENV{GIT_CONFIG} = $state; my $rv = system(qw/git config/, $lkey, $tip); - $rv == 0 or die "git config $lkey $tip failed: $? ($rv)\n"; + $rv == 0 or die "git config $lkey $tip failed: $? ($rv)"; + + # git-config(1) does not fsync state files by default + open my $st, '+<', $state or + die "failed to open state ($state): $!"; + defined($st->sync) or die "fsync $state failed: $!"; + $st->close or die "close $state failed for fsync: $!"; } } -- EW