git/list[1] front-page[2] threads[3] people[4] search[5] about
 

Re: RLIMIT_NOFILE fallback

From
Jeff King <peff@peff.net>
Date
Dec 19, 2013, 00:15 UTC
Message-ID
<20131219001519.GB17420@sigill.intra.peff.net>
In-Reply-To
<xmqqzjnxg3zz.fsf@gitster.dls.corp.google.com>
On Wed, Dec 18, 2013 at 02:59:12PM -0800, Junio C Hamano wrote:
Show 8 quoted lines
> Jeff King <peff@peff.net> writes:
>
> >> Yes, that is locally OK, but depending on how the caller behaves, we
> >> might need to have an extra saved_errno dance here, which I didn't
> >> want to get into...
> >
> > I think we are fine. The only caller is about to clobber errno by
> > closing packs anyway.

Also, I do not think we would be any worse off than the current code. getrlimit almost certainly just clobbered errno anyway. Either it is worth saving for the whole function, or not at all (and I think not at all).

Show 18 quoted lines
> diff --git a/sha1_file.c b/sha1_file.c
> index 760dd60..288badd 100644
> --- a/sha1_file.c
> +++ b/sha1_file.c
> @@ -807,15 +807,38 @@ void free_pack_by_name(const char *pack_name)
>  static unsigned int get_max_fd_limit(void)
>  {
>  #ifdef RLIMIT_NOFILE
> -	struct rlimit lim;
> +	{
> +		struct rlimit lim;
>  
> -	if (getrlimit(RLIMIT_NOFILE, &lim))
> -		die_errno("cannot get RLIMIT_NOFILE");
> +		if (!getrlimit(RLIMIT_NOFILE, &lim))
> +			return lim.rlim_cur;
> +	}
> +#endif

Yeah, I think pulling the variable into its own block makes this more readable.

Show 22 quoted lines
> +#ifdef _SC_OPEN_MAX
> +	{
> +		long open_max = sysconf(_SC_OPEN_MAX);
> +		if (0 < open_max)
> +			return open_max;
> +		/*
> +		 * Otherwise, we got -1 for one of the two
> +		 * reasons:
> +		 *
> +		 * (1) sysconf() did not understand _SC_OPEN_MAX
> +		 *     and signaled an error with -1; or
> +		 * (2) sysconf() said there is no limit.
> +		 *
> +		 * We _could_ clear errno before calling sysconf() to
> +		 * tell these two cases apart and return a huge number
> +		 * in the latter case to let the caller cap it to a
> +		 * value that is not so selfish, but letting the
> +		 * fallback OPEN_MAX codepath take care of these cases
> +		 * is a lot simpler.
> +		 */
> +	}
> +#endif

This is probably OK. I assume sane systems actually provide OPEN_MAX, and/or have a working getrlimit in the first place.

The fallback of "1" is actually quite low and can have an impact. Both for performance, but also for concurrent use. We used to run into a problem at GitHub where pack-objects serving a clone would have its packfile removed from under it (by a concurrent repack), and then would die. The normal code paths are able to just retry the object lookup and find the new pack, but the pack-objects code is a bit more intimate with the particular packfile and cannot (currently) do so. With a large enough mmap window and descriptor limit, we just keep the packfiles open. But if we have to close them for resource limits (like a too-low descriptor limit), then we can end up in the die() situation above.

-Peff
Previous: Junio C HamanoNext: Torsten Bögershausen
Message 11 of 16 in “RLIMIT_NOFILE fallback”
  1. Joey HessDec 18, 2013
  2. Junio C HamanoDec 18, 2013
  3. Joey HessDec 18, 2013
  4. Jeff KingDec 18, 2013
  5. Junio C HamanoDec 18, 2013
  6. Junio C HamanoDec 18, 2013
  7. Jeff KingDec 18, 2013
  8. Junio C HamanoDec 18, 2013
  9. Jeff KingDec 18, 2013
  10. Junio C HamanoDec 18, 2013
  11. Jeff KingDec 19, 2013
  12. Torsten BögershausenDec 19, 2013
  13. Junio C HamanoDec 19, 2013
  14. Jeff KingDec 20, 2013
  15. Torsten BögershausenDec 20, 2013
  16. Joey HessDec 18, 2013

Read the whole thread, see it on lore, or plain text.

$ cat FOOTERMessages come from the public archive at lore.kernel.org/git, fetched every hour. The front page is chosen and written each morning by an AI editor and can be wrong; the threads themselves are the record. About and API. For agents: an MCP server at https://gitlist.dev/mcp, and any thread, story or person page as Markdown by adding .md to its URL (or sending Accept: text/markdown). Details in /llms.txt.