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

Re: [PATCH v1 1/2] sha1_file: open window into packfiles with CLOEXEC

From
Lars Schneider <larsxschneider@gmail.com>
Date
Sep 7, 2016, 13:20 UTC
Message-ID
<F8E7B7CE-1177-4CBD-999E-21C593A8ACD2@gmail.com>
In-Reply-To
<alpine.DEB.2.20.1609061333030.129229@virtualbox>
Show 26 quoted lines
> On 06 Sep 2016, at 13:38, Johannes Schindelin <johannes.schindelin@gmx.de> wrote:
> 
> Hi Eric & Lars,
> 
> On Mon, 5 Sep 2016, Eric Wong wrote:
> 
>> larsxschneider@gmail.com wrote:
>>> All processes that the Git main process spawns inherit the open file
>>> descriptors of the main process. These leaked file descriptors can
>>> cause problems.
>> 
>> 
>>> -int git_open_noatime(const char *name)
>>> +int git_open_noatime_cloexec(const char *name)
>>> {
>>> -	static int sha1_file_open_flag = O_NOATIME;
>>> +	static int sha1_file_open_flag = O_NOATIME | O_CLOEXEC;
>>> 
>>> 	for (;;) {
>>> 		int fd;
> 
>> I question the need for the "_cloexec" suffixing in the
>> function name since the old function is going away entirely.
> 
> Me, too. While it is correct, it makes things harder to read, so it may
> even cause more harm than it does good.

What name would you suggest? Leaving the name as-is seems misleading to me. Maybe just "git_open()" ?

Show 14 quoted lines
>> I prefer all FD-creating functions set cloexec by default
>> for FD > 2 to avoid inadvertantly leaking FDs.  So we
>> ought to use pipe2, accept4, socket(..., SOCK_CLOEXEC), etc...
>> and fallback to the racy+slower F_SETFD when not available.
> 
> In the original Pull Request where the change was contributed to Git for
> Windows, this was tested (actually, the code did not see whether fd > 2,
> but simply assumed that all newly opened file descriptors would be > 2
> anyway), and it failed:
> 
> https://github.com/git-for-windows/git/pull/755#issuecomment-220247972
> 
> So it appears that we would have to exclude at least the code path to `git
> upload-pack` from that magic.

I just realized that Dscho improved his original patch in GfW with a fallback if CLOEXEC is not present.

I applied the same mechanism here. Would that be OK?

Thanks, Lars

-       static int sha1_file_open_flag = O_NOATIME;
+       static int sha1_file_open_flag = O_NOATIME | O_CLOEXEC;
        for (;;) {
                int fd;
@@ -1471,12 +1471,17 @@ int git_open_noatime(const char *name)
                if (fd >= 0)
                        return fd;

-               /* Might the failure be due to O_NOATIME? */
-               if (errno != ENOENT && sha1_file_open_flag) {
-                       sha1_file_open_flag = 0;
+               /* Try again w/o O_CLOEXEC: the kernel might not support it */
+               if (O_CLOEXEC && errno == EINVAL && (sha1_file_open_flag & O_CLOEXEC)) {
+                       sha1_file_open_flag &= ~O_CLOEXEC;
                        continue;
                }

+               /* Might the failure be due to O_NOATIME? */
+               if (errno != ENOENT && (sha1_file_open_flag & O_NOATIME)) {
+                       sha1_file_open_flag &= ~O_NOATIME;
+                       continue;
+               }
Previous: Johannes SchindelinNext: Eric Wong
Message 6 of 15 in “Use CLOEXEC to avoid fd leaks”
  1. 0/2 Use CLOEXEC to avoid fd leakslarsxschneider@gmail.com, Sep 5, 2016
  2. 1/2 sha1_file: open window into packfiles with CLOEXEClarsxschneider@gmail.com, Sep 5, 2016
  3. Eric WongSep 5, 2016
  4. Jakub NarębskiSep 6, 2016
  5. Johannes SchindelinSep 6, 2016
  6. Lars SchneiderSep 7, 2016
  7. Eric WongSep 7, 2016
  8. 2/2 read-cache: make sure file handles are not inherited by child processeslarsxschneider@gmail.com, Sep 5, 2016
  9. Johannes SchindelinSep 6, 2016
  10. Eric WongSep 6, 2016
  11. Lars SchneiderSep 7, 2016
  12. Eric WongSep 7, 2016
  13. Junio C HamanoSep 7, 2016
  14. Lars SchneiderSep 8, 2016
  15. Junio C HamanoSep 8, 2016

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.