From a4d1d13ceb32c6d7aa3bef8bb2d22be2b4383a86 Mon Sep 17 00:00:00 2001 From: "Kyle J. McKay" Date: Wed, 20 Dec 2017 14:57:34 -0800 Subject: [PATCH] Project.pm: decline to set up cross device alternates If the objects directory to be included in the alternates file has a different device number than the project's own objects directory decline to set up any alternates for the project. Garbage collection would not work properly in such a case. Girocco itself would never cause this situation to occur, but an administrator could. Should this situation arise, a newly created fork whose objects live on a different device from its parent project will not get the "implicit clone" that a same-device fork does. Too bad. That's much safer from a gc perspective than writing out a cross-device alternates entry. Signed-off-by: Kyle J. McKay --- Girocco/Project.pm | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/Girocco/Project.pm b/Girocco/Project.pm index 762f9b0..ef11a45 100644 --- a/Girocco/Project.pm +++ b/Girocco/Project.pm @@ -400,13 +400,25 @@ sub _alternates_setup { mkdir $self->{path}.'/refs'; chmod 02775, $self->{path}.'/refs'; mkdir $self->{path}.'/objects'; chmod 02775, $self->{path}.'/objects'; mkdir $self->{path}.'/objects/info'; chmod 02775, $self->{path}.'/objects/info'; + mkdir $self->{path}.'/objects/pack'; chmod 02775, $self->{path}.'/objects/pack'; + + # If somehow either our objects/pack or the prospective alternate's pack + # directory does not exist decline to set up any alternates + my $altpath = "$forkee_path/objects"; + -d $self->{path}.'/objects/pack' && -d $altpath.'/pack' or return + + # If our objects/pack and the prospective alternate's pack directory + # do not share the same device then decline to set up any alternates + my ($selfdev) = stat($self->{path}.'/objects/pack'); + my ($altdev) = stat($altpath.'/pack'); + defined($selfdev) && defined($altdev) && $selfdev ne "" && $altdev ne "" && $selfdev == $altdev or return; # We set up both alternates and http_alternates since we cannot use # relative path in alternates - that doesn't work recursively. my $filename = $self->{path}.'/objects/info/alternates'; open my $x, '>', $filename or die "alternates failed: $!"; - print $x "$forkee_path/objects\n"; + print $x "$altpath\n"; close $x; chmod 0664, $filename or warn "cannot chmod $filename: $!"; -- 2.11.4.GIT