Git development
 help / color / mirror / Atom feed
From: Patrick Steinhardt <ps@pks.im>
To: Junio C Hamano <gitster@pobox.com>
Cc: git@vger.kernel.org,
	Jean-Christophe Manciot <actionmystique@gmail.com>,
	Mikael Magnusson <mikachu@gmail.com>, Jeff King <peff@peff.net>,
	Taylor Blau <me@ttaylorr.com>, Derrick Stolee <stolee@gmail.com>
Subject: Re: [PATCH 1/2] builtin/maintenance: fix locking with "--detach"
Date: Tue, 12 May 2026 07:59:18 +0200	[thread overview]
Message-ID: <agLBtvKtvWFn64-Y@pks.im> (raw)
In-Reply-To: <xmqq4ikdqvad.fsf@gitster.g>

On Tue, May 12, 2026 at 10:19:22AM +0900, Junio C Hamano wrote:
> Patrick Steinhardt <ps@pks.im> writes:
> 
> > diff --git a/builtin/gc.c b/builtin/gc.c
> > index 3a71e314c9..09cb92ac97 100644
> > --- a/builtin/gc.c
> > +++ b/builtin/gc.c
> > @@ -1810,10 +1810,32 @@ 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 assign ownership
> > +			 * of the lockfile to the child and then exit immediately.
> > +			 */
> > +			lock_file_reassign_owner(&lk, child_pid);
> > +			exit(0);
> 
> The point of reassigning the owner to somebody else is so that we
> won't clean them when we exit as the tempfile.c::remove_tempfile()
> function checks the "owner" is "me" and refrains from unlinking
> those that do not belong to us, so there is nothing wrong in this
> code, but this somehow felt awkward.  In a sense, child_pid here
> does not have to be what fork() returned but anything that is not
> our own pid.  Perhaps "we assign ... to the child" -> "we relinquish
> ... to prevent us removing upon exiting" would convey the intention
> better?  I dunno.

Fair. This is what I got now:

	/*
	 * We're in the parent process, so we drop ownership of
	 * the lockfile to prevent us from removing it upon
	 * exit.
	 */

> > -int daemonize(void)
> > +pid_t daemonize_without_exit(void)
> >  {
> >  #ifdef NO_POSIX_GOODIES
> >  	errno = ENOSYS;
> >  	return -1;
> >  #else
> > -	switch (fork()) {
> > -		case 0:
> > -			break;
> > -		case -1:
> > -			die_errno(_("fork failed"));
> > -		default:
> > -			exit(0);
> > -	}
> > +	pid_t pid = fork();
> > +	if (pid < 0)
> > +		return -1;
> > +	if (pid > 0)
> > +		return pid;
> > +
> >  	if (setsid() == -1)
> >  		die_errno(_("setsid failed"));
> >  	close(0);
> > @@ -2180,6 +2178,21 @@ int daemonize(void)
> >  #endif
> >  }
> >  
> > +int daemonize(void)
> > +{
> > +#ifdef NO_POSIX_GOODIES
> > +	errno = ENOSYS;
> > +	return -1;
> > +#else
> > +	pid_t pid = daemonize_without_exit();
> > +	if (pid < 0)
> > +		die_errno(_("fork failed"));
> > +	if (pid > 0)
> > +		exit(0);
> > +	return 0;
> > +#endif
> > +}
> 
> I was hoping that we can do without the #ifdef in this caller as
> daemonize_without_exit() already has exactly the same condtional
> compilation.  If the NO_POSIX_GOODIES side can just return silently
> wit ENOSYS, shouldn't the callers be also fine if we return failure
> instead of calling die_errno(_("fork failed")), I have to wonder.
> 
> But because (1) as long as we have to call die_errno() here, we must
> keep the conditional compilation in daemonize() as well as
> daemonize_without_exit(), and (2) changing what the callers get when
> fork failed here is totally outside of this topic, I would say that
> the code around here is good as-is.

Yeah, I was also pondering whether I can drop the additional ifdef. But
I eventually decided to aim for the most minimal fix that has the least
potential for additional regressions. So I aimed to keep `daemonize()`
semantically the same as before, and I aimed to only fix the issue with
the lockfile we know about.

I agree though that this is something we should probably clean up in a
subsequent series. We don't have that many callers of `daemonize()`
after all, so it shouldn't be that involved, either.

Thanks!

Patrick

  reply	other threads:[~2026-05-12  5:59 UTC|newest]

Thread overview: 17+ 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 [this message]
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
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-13  7:31   ` [PATCH v3 2/2] run-command: honor "gc.auto" for auto-maintenance 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=agLBtvKtvWFn64-Y@pks.im \
    --to=ps@pks.im \
    --cc=actionmystique@gmail.com \
    --cc=git@vger.kernel.org \
    --cc=gitster@pobox.com \
    --cc=me@ttaylorr.com \
    --cc=mikachu@gmail.com \
    --cc=peff@peff.net \
    --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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox