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

Re: [PATCH] tmp-objdir: do not opendir() when handling a signal

From
Taylor Blau <me@ttaylorr.com>
Date
Sep 27, 2022, 00:18 UTC
Message-ID
<YzJBZ9QJWIv0hpXb@nand.local>
In-Reply-To
<pull.1348.git.git.1664236383785.gitgitgadget@gmail.com>
[+cc Peff as the author of tmp-objdir]
On Mon, Sep 26, 2022 at 11:53:03PM +0000, John Cai via GitGitGadget wrote:
> One place we call tmp_objdir_create() is in git-receive-pack, where
> we create a temporary quarantine directory "incoming". Incoming
> objects will be written to this directory before they get moved to
> the object directory.

Right, calling opendir() will allocate memory, so we'll get stuck in a deadlock if the signal arrives while libc's allocator lock is held. So we can't safely call opendir() there.

It does make me a little uneasy leaving the quarantine directory around via this path. So I wonder if we should be optimistically opening up the DIR handle? Calling unlink() in a signal is perfectly fine, so I'd think as long as we have an open DIR handle we could call readdir_r(), but I don't think we've discussed it before.

Show 7 quoted lines
> @@ -3261,7 +3261,10 @@ static int remove_dir_recurse(struct strbuf *path, int flag, int *kept_up)
>  	}
>
>  	flag &= ~REMOVE_DIR_KEEP_TOPLEVEL;
> -	dir = opendir(path->buf);
> +
> +	if ((flag & REMOVE_DIR_SIGNAL) == 0)
Comparing to the zero value is discouraged. Consider:
    if (!(flag & REMOVE_DIR_SIGNAL))
instead.
Show 7 quoted lines
> @@ -498,6 +498,9 @@ int get_sparse_checkout_patterns(struct pattern_list *pl);
>  /* Remove the_original_cwd too */
>  #define REMOVE_DIR_PURGE_ORIGINAL_CWD 0x08
>
> +/* Indicates a signal is being handled */
> +#define REMOVE_DIR_SIGNAL 0x16
> +
Perhaps REMOVE_DIR_IN_SIGNAL would be slightly more descriptive.
Show 8 quoted lines
> @@ -49,7 +50,11 @@ static int tmp_objdir_destroy_1(struct tmp_objdir *t, int on_signal)
>  	 * have pre-grown t->path sufficiently so that this
>  	 * doesn't happen in practice.
>  	 */
> -	err = remove_dir_recursively(&t->path, 0);
> +
> +	if (on_signal)
> +		flags = flags | REMOVE_DIR_SIGNAL;

I'm nitpicking, but you could just write "flags |= REMOVE_DIR_SIGNAL", or even:

    err = remove_dir_recursively(&t->path,
                                 on_signal ? REMOVE_DIR_SIGNAL : 0);

Thanks, Taylor

Previous: John Cai via GitGitGadgetNext: Jeff King
Message 2 of 18 in “tmp-objdir: do not opendir() when handling a signal”
  1. tmp-objdir: do not opendir() when handling a signalJohn Cai via GitGitGadget, Sep 26, 2022
  2. Taylor BlauSep 27, 2022
  3. Jeff KingSep 27, 2022
  4. Junio C HamanoSep 27, 2022
  5. Phillip WoodSep 27, 2022
  6. Jeff KingSep 27, 2022
  7. John CaiSep 27, 2022
  8. Jeff KingSep 27, 2022
  9. Junio C HamanoSep 27, 2022
  10. tmp-objdir: skip clean up when handling a signalJohn Cai via GitGitGadget, Sep 27, 2022
  11. Jeff KingSep 27, 2022
  12. Jeff KingSep 27, 2022
  13. tmp-objdir: skip clean up when handling a signalJohn Cai via GitGitGadget, Sep 28, 2022
  14. Ævar Arnfjörð BjarmasonSep 28, 2022
  15. tmp-objdir: skip clean up when handling a signalJohn Cai via GitGitGadget, Sep 30, 2022
  16. Jeff KingOct 3, 2022
  17. Another possible instance of async-signal-safe opendir path callstack? (Was: [PATCH] tmp-objdir: do not opendir() when handling a signal)Jan Pokorný, Oct 20, 2022
  18. Jeff KingOct 20, 2022

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.