From: Jeff King <peff@peff.net>
To: git@vger.kernel.org
Subject: [PATCH 13/20] tempfile: robustify cleanup handler
Date: Tue, 5 Sep 2017 08:14:53 -0400 [thread overview]
Message-ID: <20170905121452.eycytdbsabkbrlvx@sigill.intra.peff.net> (raw)
In-Reply-To: <20170905121353.62zg3mtextmq5zrs@sigill.intra.peff.net>
We may call remove_tempfiles() from an atexit handler, or
from a signal handler. In the latter case we must take care
to avoid functions which may deadlock if the process is in
an unknown state, including looking at any stdio handles
(which may be in the middle of doing I/O and locked) or
calling malloc() or free().
The current implementation calls delete_tempfile(). We unset
the tempfile's stdio handle (if any) to avoid deadlocking
there. But delete_tempfile() still calls unlink_or_warn(),
which can deadlock writing to stderr if the unlink fails.
Since delete_tempfile() isn't very long, let's just
open-code our own simple conservative version of the same
thing. Notably:
1. The "skip_fclose" flag is now called "in_signal_handler",
because it should inform more decisions than just the
fclose handling.
2. We can replace close_tempfile() with just close(fd).
That skips the fclose() question altogether. This is
fine for the atexit() case, too; there's no point
flushing data to a file which we're about to delete
anyway.
3. We can choose between unlink/unlink_or_warn based on
whether it's safe to use stderr.
4. We can replace the deactivate_tempfile() call with a
simple setting of the active flag. There's no need to
do any further cleanup since we know the program is
exiting. And even though the current deactivation code
is safe in a signal handler, this frees us up in future
patches to make non-signal deactivation more
complicated (e.g., by freeing resources).
5. There's no need to remove items from the tempfile_list.
The "active" flag is the ultimate answer to whether an
entry has been handled or not. Manipulating the list
just introduces more chance of recursive signals
stomping on each other, and the whole list will go away
when the program exits anyway. Less is more.
Signed-off-by: Jeff King <peff@peff.net>
---
tempfile.c | 24 +++++++++++++++---------
1 file changed, 15 insertions(+), 9 deletions(-)
diff --git a/tempfile.c b/tempfile.c
index 9d7f0a2f2b..3348ad59dd 100644
--- a/tempfile.c
+++ b/tempfile.c
@@ -57,18 +57,24 @@
static struct tempfile *volatile tempfile_list;
-static void remove_tempfiles(int skip_fclose)
+static void remove_tempfiles(int in_signal_handler)
{
pid_t me = getpid();
+ struct tempfile *volatile p;
- while (tempfile_list) {
- if (tempfile_list->owner == me) {
- /* fclose() is not safe to call in a signal handler */
- if (skip_fclose)
- tempfile_list->fp = NULL;
- delete_tempfile(tempfile_list);
- }
- tempfile_list = tempfile_list->next;
+ for (p = tempfile_list; p; p = p->next) {
+ if (!is_tempfile_active(p) || p->owner != me)
+ continue;
+
+ if (p->fd >= 0)
+ close(p->fd);
+
+ if (in_signal_handler)
+ unlink(p->filename.buf);
+ else
+ unlink_or_warn(p->filename.buf);
+
+ p->active = 0;
}
}
--
2.14.1.721.gc5bc1565f1
next prev parent reply other threads:[~2017-09-05 12:14 UTC|newest]
Thread overview: 21+ messages / expand[flat|nested] mbox.gz Atom feed top
2017-09-05 12:13 [PATCH 0/20] allowing struct lock_file to be deleted Jeff King
2017-09-05 12:14 ` [PATCH 01/20] write_index_as_tree: cleanup tempfile on error Jeff King
2017-09-05 12:14 ` [PATCH 02/20] setup_temporary_shallow: avoid using inactive tempfile Jeff King
2017-09-05 12:14 ` [PATCH 03/20] setup_temporary_shallow: move tempfile struct into function Jeff King
2017-09-05 12:14 ` [PATCH 04/20] verify_signed_buffer: prefer close_tempfile() to close() Jeff King
2017-09-05 12:14 ` [PATCH 05/20] always check return value of close_tempfile Jeff King
2017-09-05 12:14 ` [PATCH 06/20] tempfile: do not delete tempfile on failed close Jeff King
2017-09-05 12:14 ` [PATCH 07/20] lockfile: do not rollback lock " Jeff King
2017-09-05 12:14 ` [PATCH 08/20] tempfile: prefer is_tempfile_active to bare access Jeff King
2017-09-05 12:14 ` [PATCH 09/20] tempfile: handle NULL tempfile pointers gracefully Jeff King
2017-09-05 12:14 ` [PATCH 10/20] tempfile: replace die("BUG") with BUG() Jeff King
2017-09-05 12:14 ` [PATCH 11/20] tempfile: factor out activation Jeff King
2017-09-05 12:14 ` [PATCH 12/20] tempfile: factor out deactivation Jeff King
2017-09-05 12:14 ` Jeff King [this message]
2017-09-05 12:14 ` [PATCH 14/20] tempfile: release deactivated strbufs instead of resetting Jeff King
2017-09-05 12:15 ` [PATCH 15/20] tempfile: use list.h for linked list Jeff King
2017-09-05 12:15 ` [PATCH 16/20] tempfile: remove deactivated list entries Jeff King
2017-09-05 12:15 ` [PATCH 17/20] tempfile: auto-allocate tempfiles on heap Jeff King
2017-09-05 12:15 ` [PATCH 18/20] lockfile: update lifetime requirements in documentation Jeff King
2017-09-05 12:15 ` [PATCH 19/20] ref_lock: stop leaking lock_files Jeff King
2017-09-05 12:15 ` [PATCH 20/20] stop leaking lock structs in some simple cases Jeff King
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=20170905121452.eycytdbsabkbrlvx@sigill.intra.peff.net \
--to=peff@peff.net \
--cc=git@vger.kernel.org \
/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).