tests: disable fsync everywhere
The "GIT_TEST_FSYNC" environment variable now exists for disabling fsync() even on packfiles and other "critical" data. Running "make test -j8 NO_SVN_TESTS=1" on a noisy 8-core system on an HDD, test runtime drops from ~4 minutes down to ~3 minutes. Using "GIT_TEST_FSYNC=1" re-enables fsync() for comparison purposes. SVN interopability tests are minimally affected since SVN will still use fsync in various places. This will also be useful for 3rd-party tools which create throwaway git repositories of temporary data, but remains undocumented for end users. Signed-off-by: Eric Wong <e@80x24.org> Signed-off-by: Junio C Hamano <gitster@pobox.com>
Eric Wong committed
Oct 29, 2021 at 00:15 UTC
412e4caee387d825903bf1252aefbd5cf995a599
6 files changed
+48
-2
cache.h
+1
@@ -985,6 +985,7 @@ extern int read_replace_refs;
985
extern char *git_replace_ref_base;
986
987
extern int fsync_object_files;
988
+extern int use_fsync;
989
extern int core_preload_index;
990
extern int precomposed_unicode;
991
extern int protect_hfs;
environment.c
+1
@@ -43,6 +43,7 @@ const char *git_hooks_path;
43
int zlib_compression_level = Z_BEST_SPEED;
44
int pack_compression_level = Z_DEFAULT_COMPRESSION;
45
int fsync_object_files;
46
+int use_fsync = -1;
47
size_t packed_git_window_size = DEFAULT_PACKED_GIT_WINDOW_SIZE;
48
size_t packed_git_limit = DEFAULT_PACKED_GIT_LIMIT;
49
size_t delta_base_cache_limit = 96 * 1024 * 1024;
git-cvsserver.perl
+19
@@ -3607,6 +3607,22 @@ package GITCVS::updater;
3607
use strict;
3608
use warnings;
3609
use DBI;
3610
+our $_use_fsync;
3611
+
3612
+# n.b. consider using Git.pm
3613
+sub use_fsync {
3614
+ if (!defined($_use_fsync)) {
3615
+ my $x = $ENV{GIT_TEST_FSYNC};
3616
+ if (defined $x) {
3617
+ local $ENV{GIT_CONFIG};
3618
+ delete $ENV{GIT_CONFIG};
3619
+ my $v = ::safe_pipe_capture('git', '-c', "test.fsync=$x",
3620
+ qw(config --type=bool test.fsync));
3621
+ $_use_fsync = defined($v) ? ($v eq "true\n") : 1;
3622
+ }
3623
+ }
3624
+ $_use_fsync;
3625
+}
3626
3627
=head1 METHODS
3628
@@ -3676,6 +3692,9 @@ sub new
3692
$self->{dbuser},
3693
$self->{dbpass});
3694
die "Error connecting to database\n" unless defined $self->{dbh};
3695
+ if ($self->{dbdriver} eq 'SQLite' && !use_fsync()) {
3696
+ $self->{dbh}->do('PRAGMA synchronous = OFF');
3697
+ }
3698
3699
$self->{tables} = {};
3700
foreach my $table ( keys %{$self->{dbh}->table_info(undef,undef,undef,'TABLE')->fetchall_hashref('TABLE_NAME')} )
perl/Git/SVN.pm
+15
-2
@@ -6,7 +6,7 @@ use constant rev_map_fmt => 'NH*';
6
use vars qw/$_no_metadata
7
$_repack $_repack_flags $_use_svm_props $_head
8
$_use_svnsync_props $no_reuse_existing
9
- $_use_log_author $_add_author_from $_localtime/;
9
+ $_use_log_author $_add_author_from $_localtime $_use_fsync/;
10
use Carp qw/croak/;
11
use File::Path qw/mkpath/;
12
use IPC::Open3;
@@ -2269,6 +2269,19 @@ sub mkfile {
2269
}
2270
}
2271
2272
+# TODO: move this to Git.pm?
2273
+sub use_fsync {
2274
+ if (!defined($_use_fsync)) {
2275
+ my $x = $ENV{GIT_TEST_FSYNC};
2276
+ if (defined $x) {
2277
+ my $v = command_oneline('-c', "test.fsync=$x",
2278
+ qw(config --type=bool test.fsync));
2279
+ $_use_fsync = defined($v) ? ($v eq "true\n") : 1;
2280
+ }
2281
+ }
2282
+ $_use_fsync;
2283
+}
2284
+
2285
sub rev_map_set {
2286
my ($self, $rev, $commit, $update_ref, $uuid) = @_;
2287
defined $commit or die "missing arg3\n";
@@ -2290,7 +2303,7 @@ sub rev_map_set {
2303
my $sync;
2304
# both of these options make our .rev_db file very, very important
2305
# and we can't afford to lose it because rebuild() won't work
2293
- if ($self->use_svm_props || $self->no_metadata) {
2306
+ if (($self->use_svm_props || $self->no_metadata) && use_fsync()) {
2307
require File::Copy;
2308
$sync = 1;
2309
File::Copy::copy($db, $db_lock) or die "rev_map_set(@_): ",
t/test-lib.sh
+7
@@ -489,6 +489,13 @@ then
489
export GIT_PERL_FATAL_WARNINGS
490
fi
491
492
+case $GIT_TEST_FSYNC in
493
+'')
494
+ GIT_TEST_FSYNC=0
495
+ export GIT_TEST_FSYNC
496
+ ;;
497
+esac
498
+
499
# Add libc MALLOC and MALLOC_PERTURB test
500
# only if we are not executing the test with valgrind
501
if test -n "$valgrind" ||
write-or-die.c
+5
@@ -1,4 +1,5 @@
1
#include "cache.h"
2
+#include "config.h"
3
#include "run-command.h"
4
5
/*
@@ -57,6 +58,10 @@ void fprintf_or_die(FILE *f, const char *fmt, ...)
58
59
void fsync_or_die(int fd, const char *msg)
60
{
61
+ if (use_fsync < 0)
62
+ use_fsync = git_env_bool("GIT_TEST_FSYNC", 1);
63
+ if (!use_fsync)
64
+ return;
65
while (fsync(fd) < 0) {
66
if (errno != EINTR)
67
die_errno("fsync error on '%s'", msg);