From: Michael Haggerty <mhagger@alum.mit.edu>
To: Junio C Hamano <gitster@pobox.com>
Cc: git@vger.kernel.org, Anders Kaseorg <andersk@MIT.EDU>,
David Aguilar <davvid@gmail.com>,
Jiang Xin <worldhello.net@gmail.com>,
Lea Wiemann <lewiemann@gmail.com>,
David Reiss <dreiss@facebook.com>, Johannes Sixt <j6t@kdbg.org>,
"Lars R. Damerow" <lars@pixar.com>, Jeff King <peff@peff.net>,
Marc Jordan <marc.jordan@disneyanimation.com>
Subject: Re: [RFC] Provide a mechanism to turn off symlink resolution in ceiling paths
Date: Fri, 22 Feb 2013 08:23:08 +0100 [thread overview]
Message-ID: <51271CDC.4000001@alum.mit.edu> (raw)
In-Reply-To: <7vk3q1th1l.fsf@alter.siamese.dyndns.org>
On 02/21/2013 11:53 PM, Junio C Hamano wrote:
> Michael Haggerty <mhagger@alum.mit.edu> writes:
>
>> Unfortunately I am swamped with other work right now so I don't have
>> time to test the code and might not be able to respond promptly to
>> feedback.
>
> A note like the above is a good way to give a cue to others so that
> we can work together to pick up, tie the loose ends and move us
> closer to the goal, and is very much appreciated.
>
> I think the patch makes sense; I expanded on the part that has
> Anders's report in the log message and added a trivial test.
>
> Testing and eyeballing by others would help very much. We'd
> obviously need our sign-off as well ;-)
Thanks for following up on this. Your tests look OK by eyeball and they
run successfully here whether the testing --root is under a symlink or
not. I did notice some minor niggles in the text (including one in my
original submission); see below.
Signed-off-by: Michael Haggerty <mhagger@alum.mit.edu>
Michael
> -- >8 --
> From: Michael Haggerty <mhagger@alum.mit.edu>
> Date: Wed, 20 Feb 2013 10:09:24 +0100
> Subject: [PATCH] Provide a mechanism to turn off symlink resolution in ceiling paths
>
> Commit 1b77d83cab 'setup_git_directory_gently_1(): resolve symlinks
> in ceiling paths' changed the setup code to resolve symlinks in the
> entries in GIT_CEILING_DIRECTORIES. Because those entries are
> compared textually to the symlink-resolved current directory, an
> entry in GIT_CEILING_DIRECTORIES that contained a symlink would have
> no effect. It was known that this could cause performance problems
> if the symlink resolution *itself* touched slow filesystems, but it
> was thought that such use cases would be unlikely. The intention of
> the earlier change was to deal with a case when the user has this:
>
> GIT_CEILING_DIRECTORIES=/home/gitster
>
> but in reality, /home/gitster is a symbolic link to somewhere else,
> e.g. /net/machine/home4/gitster. A textual comparison between the
> specified value /home/gitster and the location getcwd(3) returns
> would not help us, but readlink("/home/gitster") would still be
> fast.
>
> After this change was released, Anders Kaseorg <andersk@mit.edu>
> reported:
>
>> [...] my computer has been acting so slow when I’m not connected to
>> the network. I put various network filesystem paths in
>> $GIT_CEILING_DIRECTORIES, such as
>> /afs/athena.mit.edu/user/a/n/andersk (to avoid hitting its parents
>> /afs/athena.mit.edu, /afs/athena.mit.edu/user/a, and
>> /afs/athena.mit.edu/user/a/n which all live in different AFS
>> volumes). Now when I’m not connected to the network, every
>> invocation of Git, including the __git_ps1 in my shell prompt, waits
>> for AFS to timeout.
>
> To allow users to work this around, give them a mechanism to turn
s/this around/around this problem/
> off symlink resolution in GIT_CEILING_DIRECTORIES entries. All the
> entries that follow an empty entry will not be checked for symbolic
> links and used literally in comparison. E.g. with these:
Make it clear that "not" doesn't apply to both sides of the "and", since
the operator precedence in English is undocumented:
s/and/but rather will be/
>
> GIT_CEILING_DIRECTORIES=:/foo/bar:/xyzzy or
> GIT_CEILING_DIRECTORIES=/foo/bar::/xyzzy
>
> we will not readlink("/xyzzy"), and with the former, we will not
> readlink("/foo/bar"), either.
> ---
> Documentation/git.txt | 19 +++++++++++++------
> setup.c | 32 ++++++++++++++++++++++----------
> t/t1504-ceiling-dirs.sh | 17 +++++++++++++++++
> 3 files changed, 52 insertions(+), 16 deletions(-)
>
> diff --git a/Documentation/git.txt b/Documentation/git.txt
> index 6710cb0..5c03616 100644
> --- a/Documentation/git.txt
> +++ b/Documentation/git.txt
> @@ -653,12 +653,19 @@ git so take care if using Cogito etc.
> The '--namespace' command-line option also sets this value.
>
> 'GIT_CEILING_DIRECTORIES'::
> - This should be a colon-separated list of absolute paths.
> - If set, it is a list of directories that git should not chdir
> - up into while looking for a repository directory.
> - It will not exclude the current working directory or
> - a GIT_DIR set on the command line or in the environment.
> - (Useful for excluding slow-loading network directories.)
> + This should be a colon-separated list of absolute paths. If
> + set, it is a list of directories that git should not chdir up
> + into while looking for a repository directory (useful for
> + excluding slow-loading network directories). It will not
> + exclude the current working directory or a GIT_DIR set on the
> + command line or in the environment. Normally, Git has to read
> + the entries in this list are read to resolve any symlinks that
"read" is duplicated:
s/are read to//
> + might be present in order to compare them with the current
> + directory. However, if even this access is slow, you
> + can add an empty entry to the list to tell Git that the
> + subsequent entries are not symlinks and needn't be resolved;
> + e.g.,
> + 'GIT_CEILING_DIRECTORIES=/maybe/symlink::/very/slow/non/symlink'.
>
> 'GIT_DISCOVERY_ACROSS_FILESYSTEM'::
> When run in a directory that does not have ".git" repository
> diff --git a/setup.c b/setup.c
> index f108c4b..1b12017 100644
> --- a/setup.c
> +++ b/setup.c
> @@ -624,22 +624,32 @@ static dev_t get_device_or_die(const char *path, const char *prefix, int prefix_
> /*
> * A "string_list_each_func_t" function that canonicalizes an entry
> * from GIT_CEILING_DIRECTORIES using real_path_if_valid(), or
> - * discards it if unusable.
> + * discards it if unusable. The presence of an empty entry in
> + * GIT_CEILING_DIRECTORIES turns off canonicalization for all
> + * subsequent entries.
> */
> static int canonicalize_ceiling_entry(struct string_list_item *item,
> - void *unused)
> + void *cb_data)
> {
> + int *empty_entry_found = cb_data;
> char *ceil = item->string;
> - const char *real_path;
>
> - if (!*ceil || !is_absolute_path(ceil))
> + if (!*ceil) {
> + *empty_entry_found = 1;
> return 0;
> - real_path = real_path_if_valid(ceil);
> - if (!real_path)
> + } else if (!is_absolute_path(ceil)) {
> return 0;
> - free(item->string);
> - item->string = xstrdup(real_path);
> - return 1;
> + } else if (*empty_entry_found) {
> + /* Keep entry but do not canonicalize it */
> + return 1;
> + } else {
> + const char *real_path = real_path_if_valid(ceil);
> + if (!real_path)
> + return 0;
> + free(item->string);
> + item->string = xstrdup(real_path);
> + return 1;
> + }
> }
>
> /*
> @@ -679,9 +689,11 @@ static const char *setup_git_directory_gently_1(int *nongit_ok)
> return setup_explicit_git_dir(gitdirenv, cwd, len, nongit_ok);
>
> if (env_ceiling_dirs) {
> + int empty_entry_found = 0;
> +
> string_list_split(&ceiling_dirs, env_ceiling_dirs, PATH_SEP, -1);
> filter_string_list(&ceiling_dirs, 0,
> - canonicalize_ceiling_entry, NULL);
> + canonicalize_ceiling_entry, &empty_entry_found);
> ceil_offset = longest_ancestor_length(cwd, &ceiling_dirs);
> string_list_clear(&ceiling_dirs, 0);
> }
> diff --git a/t/t1504-ceiling-dirs.sh b/t/t1504-ceiling-dirs.sh
> index cce87a5..3d51615 100755
> --- a/t/t1504-ceiling-dirs.sh
> +++ b/t/t1504-ceiling-dirs.sh
> @@ -44,6 +44,10 @@ test_prefix ceil_at_sub ""
> GIT_CEILING_DIRECTORIES="$TRASH_ROOT/sub/"
> test_prefix ceil_at_sub_slash ""
>
> +if test_have_prereq SYMLINKS
> +then
> + ln -s sub top
> +fi
>
> mkdir -p sub/dir || exit 1
> cd sub/dir || exit 1
> @@ -68,6 +72,19 @@ test_fail subdir_ceil_at_sub
> GIT_CEILING_DIRECTORIES="$TRASH_ROOT/sub/"
> test_fail subdir_ceil_at_sub_slash
>
> +if test_have_prereq SYMLINKS
> +then
> + GIT_CEILING_DIRECTORIES="$TRASH_ROOT/top"
> + test_fail subdir_ceil_at_top
> + GIT_CEILING_DIRECTORIES="$TRASH_ROOT/top/"
> + test_fail subdir_ceil_at_top_slash
> +
> + GIT_CEILING_DIRECTORIES=":$TRASH_ROOT/top"
> + test_prefix subdir_ceil_at_top_no_resolve "sub/dir/"
> + GIT_CEILING_DIRECTORIES=":$TRASH_ROOT/top/"
> + test_prefix subdir_ceil_at_top_slash_no_resolve "sub/dir/"
> +fi
> +
> GIT_CEILING_DIRECTORIES="$TRASH_ROOT/sub/dir"
> test_prefix subdir_ceil_at_subdir "sub/dir/"
>
>
--
Michael Haggerty
mhagger@alum.mit.edu
http://softwareswirl.blogspot.com/
next prev parent reply other threads:[~2013-02-22 7:23 UTC|newest]
Thread overview: 26+ messages / expand[flat|nested] mbox.gz Atom feed top
2012-10-21 5:57 [PATCH v3 0/8] Fix GIT_CEILING_DIRECTORIES that contain symlinks Michael Haggerty
2012-10-21 5:57 ` [PATCH v3 1/8] Introduce new static function real_path_internal() Michael Haggerty
2012-10-21 5:57 ` [PATCH v3 2/8] real_path_internal(): add comment explaining use of cwd Michael Haggerty
2012-10-21 5:57 ` [PATCH v3 3/8] Introduce new function real_path_if_valid() Michael Haggerty
2012-10-21 5:57 ` [PATCH v3 4/8] longest_ancestor_length(): use string_list_split() Michael Haggerty
2012-10-21 5:57 ` [PATCH v3 5/8] longest_ancestor_length(): take a string_list argument for prefixes Michael Haggerty
2012-10-21 5:57 ` [PATCH v3 6/8] longest_ancestor_length(): require prefix list entries to be normalized Michael Haggerty
2012-10-22 20:04 ` Johannes Sixt
2012-10-21 5:57 ` [PATCH v3 7/8] normalize_ceiling_entry(): resolve symlinks Michael Haggerty
2012-10-21 5:57 ` [PATCH v3 8/8] string_list_longest_prefix(): remove function Michael Haggerty
2012-10-21 6:51 ` [PATCH v3 0/8] Fix GIT_CEILING_DIRECTORIES that contain symlinks Junio C Hamano
2012-10-22 8:26 ` Michael Haggerty
2012-10-29 0:15 ` David Aguilar
2012-10-29 1:42 ` Junio C Hamano
2012-10-29 5:10 ` Michael Haggerty
2012-11-12 17:47 ` Junio C Hamano
2012-11-13 20:50 ` David Aguilar
2012-11-15 8:18 ` Michael Haggerty
2013-02-20 6:20 ` Anders Kaseorg
2013-02-20 6:55 ` Junio C Hamano
2013-02-20 9:09 ` [RFC] Provide a mechanism to turn off symlink resolution in ceiling paths Michael Haggerty
2013-02-20 17:41 ` Junio C Hamano
2013-02-21 22:53 ` Junio C Hamano
2013-02-22 7:23 ` Michael Haggerty [this message]
2013-02-20 9:39 ` [PATCH v3 0/8] Fix GIT_CEILING_DIRECTORIES that contain symlinks Anders Kaseorg
2012-10-29 5:34 ` Lars Damerow
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=51271CDC.4000001@alum.mit.edu \
--to=mhagger@alum.mit.edu \
--cc=andersk@MIT.EDU \
--cc=davvid@gmail.com \
--cc=dreiss@facebook.com \
--cc=git@vger.kernel.org \
--cc=gitster@pobox.com \
--cc=j6t@kdbg.org \
--cc=lars@pixar.com \
--cc=lewiemann@gmail.com \
--cc=marc.jordan@disneyanimation.com \
--cc=peff@peff.net \
--cc=worldhello.net@gmail.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).