All of lore.kernel.org
 help / color / mirror / Atom feed
From: Taylor Blau <me@ttaylorr.com>
To: Patrick Steinhardt <ps@pks.im>
Cc: git@vger.kernel.org,
	Jean-Christophe Manciot <actionmystique@gmail.com>,
	Mikael Magnusson <mikachu@gmail.com>, Jeff King <peff@peff.net>,
	Derrick Stolee <stolee@gmail.com>,
	Junio C Hamano <gitster@pobox.com>
Subject: Re: [PATCH v2 1/2] builtin/maintenance: fix locking with "--detach"
Date: Tue, 12 May 2026 17:14:22 -0400	[thread overview]
Message-ID: <agOYLsJF4rHESk9k@nand.local> (raw)
In-Reply-To: <20260512-pks-maintenance-fix-lock-with-detach-v2-1-dc6f2d284b6d@pks.im>

On Tue, May 12, 2026 at 10:30:30AM +0200, Patrick Steinhardt wrote:
> diff --git a/builtin/gc.c b/builtin/gc.c
> index 3a71e314c9..d866c19b92 100644
> --- a/builtin/gc.c
> +++ b/builtin/gc.c
> @@ -1810,10 +1810,33 @@ static int maintenance_run_tasks(struct maintenance_run_opts *opts,
>  				   TASK_PHASE_FOREGROUND))
>  			result = 1;
>
> -	/* Failure to daemonize is ok, we'll continue in foreground. */
>  	if (opts->detach > 0) {
> +		pid_t child_pid;
> +
>  		trace2_region_enter("maintenance", "detach", the_repository);
> -		daemonize();
> +
> +		child_pid = daemonize_without_exit();
> +		if (!child_pid) {
> +			/*
> +			 * We're in the child process, so we take ownership of
> +			 * the lockfile.
> +			 */
> +			lock_file_reassign_owner(&lk, getpid());
> +		} else if (child_pid > 0) {
> +			/*
> +			 * We're in the parent process, so we drop ownership of
> +			 * the lockfile to prevent us from removing it upon
> +			 * exit.
> +			 */
> +			lock_file_reassign_owner(&lk, child_pid);
> +			exit(0);
> +		} else {
> +			/*
> +			 * Failure to daemonize is ok, we'll continue in
> +			 * foreground.
> +			 */
> +		}
> +

This works almost identically as the original implementation I shared[1]
original thread discussing this issue, but it takes a slightly different
approach.

Instead of doing this automatically as a part of daemonize(), this patch
only adjusts this singular call-site, and forces us to introduce a new
function daemonize_without_exit() in order to facilitate it.

I personally prefer the other approach, for many of the reasons that
Peff wrote about in [2, 3]. There are two questions in my mind that I
would be curious of your thoughts on:

 * Should we transfer ownership of all tempfiles, or a subset of them?

 * Should we perform that transfer automatically via daemonize(), or
   manually via its callers?

Judging from the other parts of the original thread, I think the answer
to the first question is an unambiguous "yes". The second question I
think there is less of a consensus on, but I'd like to advocate for
doing this automatically via daemonize().

To summarize some of my thoughts after reading [2], I think that because
daemonize() is about letting a process continue on in the background
rather than fork()-ing children and then continuing on ourselves, *not*
automatically handing those off feels like an accident waiting to
happen.

I can't think of a situation where someone would want to daemonize() but
not have the new process assume ownership of its locks and tempfiles. I
think an alternative approach here would be to document the behavior I'm
proposing above clearly in daemonize(). Should a caller arise in the
future that *doesn't* want to this behavior, then we could introduce a
function similar to your daemonize_without_exit() (maybe in this case it
would be daemonize_without_transfer(), since not exiting in a function
that is supposed to daemonize feels awkward).

I guess what I'm saying is that I feel that future daemonize() callers
are much more likely to want this behavior than not, and putting this in
daemonize() feels like the safer option between the two.

FWIW, I feel fairly strongly about ^ this, but I'm of course happy to
discuss more if you feel differently.

(If you do end up taking that approach, that makes the C changes
identical to the ones I shared in [1], so you are free to forge my
Co-authored-by and Signed-off-by lines if you want to take that approach
instead.)

> diff --git a/t/t7900-maintenance.sh b/t/t7900-maintenance.sh
> index 4700beacc1..df0bbc1669 100755
> --- a/t/t7900-maintenance.sh
> +++ b/t/t7900-maintenance.sh
> @@ -1438,6 +1438,64 @@ test_expect_success '--no-detach causes maintenance to not run in background' '
>  	)
>  '
>
> +test_expect_success PIPE '--detach holds maintenance lock until daemonized child exits' '
> +	test_when_finished "rm -rf repo" &&
> +	git init repo &&
> +	(
> +		cd repo &&
> +
> +		git config maintenance.auto false &&
> +		git config core.lockfilepid true &&
> +
> +		git remote add origin /does/not/exist &&
> +		git config set remote.origin.uploadpack "cat fifo-uploadpack" &&
> +
> +		mkfifo fifo-uploadpack fifo-maint &&
> +
> +		# Open the maintenance FIFO, as otherwise spawning
> +		# git-maintenance(1) would block. Note that we need to open it
> +		# as read-write, as otherwise we would block here already.
> +		exec 9<>fifo-maint &&

Very nice. The fifo-maint idea is much more robust than what I was able
to come up with in my original sketch, and it is a nice compliment to
fifo-uploadpack.

The rest of the test is nearly identical to mine and looks good to me.

Thanks,
Taylor

[1]: https://lore.kernel.org/git/af+snTGFeoUUyfPU@nand.local/
[2]: https://lore.kernel.org/git/20260511200112.GA22912@coredump.intra.peff.net/
[3]: https://lore.kernel.org/git/20260511202258.GD22912@coredump.intra.peff.net/

  reply	other threads:[~2026-05-12 21:14 UTC|newest]

Thread overview: 23+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-05-11 12:29 [PATCH 0/2] builtin/maintenance: fix locking and respect "gc.auto" Patrick Steinhardt
2026-05-11 12:29 ` [PATCH 1/2] builtin/maintenance: fix locking with "--detach" Patrick Steinhardt
2026-05-12  1:19   ` Junio C Hamano
2026-05-12  5:59     ` Patrick Steinhardt
2026-05-11 12:29 ` [PATCH 2/2] run-command: honor "gc.auto" for auto-maintenance Patrick Steinhardt
2026-05-11 20:18   ` Jeff King
2026-05-12  1:21     ` Junio C Hamano
2026-05-12  5:59       ` Patrick Steinhardt
2026-05-12  8:30 ` [PATCH v2 0/2] builtin/maintenance: fix locking and respect "gc.auto" Patrick Steinhardt
2026-05-12  8:30   ` [PATCH v2 1/2] builtin/maintenance: fix locking with "--detach" Patrick Steinhardt
2026-05-12 21:14     ` Taylor Blau [this message]
2026-05-13  6:23       ` Patrick Steinhardt
2026-05-12  8:30   ` [PATCH v2 2/2] run-command: honor "gc.auto" for auto-maintenance Patrick Steinhardt
2026-05-13  7:31 ` [PATCH v3 0/2] builtin/maintenance: fix locking and respect "gc.auto" Patrick Steinhardt
2026-05-13  7:31   ` [PATCH v3 1/2] builtin/maintenance: fix locking with "--detach" Patrick Steinhardt
2026-05-13 10:06     ` Junio C Hamano
2026-05-20  0:10       ` Taylor Blau
2026-05-20  5:47         ` Jeff King
2026-05-20  5:52           ` Patrick Steinhardt
2026-05-13  7:31   ` [PATCH v3 2/2] run-command: honor "gc.auto" for auto-maintenance Patrick Steinhardt
2026-05-21  5:39 ` [PATCH 0/2] builtin/maintenance: fix locking and respect "gc.auto" Patrick Steinhardt
2026-05-21  5:55   ` Junio C Hamano
2026-05-21  7:45     ` Patrick Steinhardt

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=agOYLsJF4rHESk9k@nand.local \
    --to=me@ttaylorr.com \
    --cc=actionmystique@gmail.com \
    --cc=git@vger.kernel.org \
    --cc=gitster@pobox.com \
    --cc=mikachu@gmail.com \
    --cc=peff@peff.net \
    --cc=ps@pks.im \
    --cc=stolee@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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.