#1075871 /usr/bin/sbuild-createchroot: sbuild-createchroot takes toooooooo long with --include=gpg

Package:
sbuild
Source:
sbuild
Submitter:
Carlos Henrique Lima Melara
Date:
2025-04-16 06:30:02 UTC
Severity:
normal
Tags:
#1075871#5
Date:
2024-07-06 20:34:45 UTC
From:
To:
Dear Maintainer, hi!

I was creating some chroots this past month and noticed it was taking
too long in the last step which is the update step. After a pretty
intense debugging session with sergiodj, we were able to pin down the
problem to a interaction between 3 things. Including gpg in the chroot,
the bump in the max number of file descriptors and this update step only
doing a chroot without mounting /proc - and not using sbuild-update,
which does not show this bahaviour.

It basically boils down to gpg-agent trying to close all the possible
file descriptors when it's running. This happens because this is the
fallback behaviour when /proc is not mounted. When it is mounted, it
just closes what is showed in /proc/<pid>/fd/. This always happened, but
with the increase of the max number of fds [1], it's really taking a
loooong time to finish sbuild-createchroot.

I've been a bit lazy and didn't get all the urls to point you to. Let me
know if you rather have them all.

Cheers,
Charles

[1] https://lists.debian.org/debian-devel/2024/06/msg00041.html

#1075871#8
Date:
2024-07-06 21:30:04 UTC
From:
To:
Hi Charles (Carlos?),

Quoting Carlos Henrique Lima Melara (2024-07-06 22:34:45)

this sounds like a bug but how is it a bug in sbuild-createchroot? The tool is
just a very thin wrapper around debootstrap and the issue will also appear in
debootstrap, no?

Also, why are you using sbuild-createchroot? Are you trying to set up the
initial schroot configuration?

Why is this not a bug in gpg-agent?

Thanks!

cheers, josch

#1075871#13
Date:
2024-07-06 22:07:03 UTC
From:
To:
Hi,

I'm CC'ing 1075871, but if you you're the only maintainer I can add
-quiet. Just let me know.

Name is Carlos, nickname is Charles, usually everyone goes with the
nickname.

Yes, it's a thin wrapper (I think, don't speak perl, sorry). But the
problem is the last step where it chroot (plain chroot, nothing fancy)
to do an apt update. There it just invoke chroot but don't mount /proc
inside the chroor and then this triggers the fallback behaviour of
gpg-agent (exhaustively closing fds on a fork). It's the following
section of sbuild-createchroot that do the update [1]:

if (!$conf->get('SETUP_ONLY') || !$conf->get('MAKE_SBUILD_TARBALL')) {
    # FIXME: also update packages with the unshare backend
    if ($conf->get('ARCH') eq $conf->get('HOST_ARCH') && $conf->get('CHROOT_MODE') ne 'unshare') {
	my $session = Sbuild::ChrootPlain->new($conf, $target);
	my $host = Sbuild::ChrootRoot->new($conf);
	if (defined($session)) {
	    $session->set('Log Stream', \*STDOUT);

	    if (!$session->begin_session() || !$host->begin_session()) {
		print STDERR "E: Error creating chroot session: skipping apt update\n";
	    } else {
		my $resolver = Sbuild::AptResolver->new($conf, $session, $host);
		$resolver->setup();

In sbuild-update, it begins a new schroot source session with sbuild -
and here sbuild/schroot mounts /proc so gpg-agent use it to only close
the open fds. That's the main difference between sbuild-update and
sbuild-createchroot's update step.

Yes, to create a schroot to use with sbuild. Mainly as a convenience
script instead of using debootstrap.

Because it has the code to close file descriptors in a smart way (using
/proc/<pid>/fd) which is the preferred way.

Hopefully I could clarify things for you.

Cheers,
Charles

[1] https://salsa.debian.org/debian/sbuild/-/blob/main/bin/sbuild-createchroot#L676

#1075871#16
Date:
2024-07-07 07:45:51 UTC
From:
To:
Hi Charles,

Quoting Carlos Henrique Lima Melara (2024-07-07 00:07:03)

I think it's better to have all bug communication in public even though it's
unlikely that any of the other sbuild contributors replies here. I don't know
if people like Jochen or Christian are subscribed to the bug mails.

Ah, you are right. Even though I find it very odd that gpg chose to de-facto
require mounted /proc to operate, I think this code path would benefit from
having a bit more of a setup so that processes run inside the chroot can feel a
bit more like home.

Good. That's its intended use.

I am not using the schroot backend and when I did in the past, I used it
exclusively with tarballs. You seem to be creating directory-based chroots for
schroot. This is nothing that I am using in my daily sbuild usage, which
probably explains why I'm not running into bugs like these.

If you can supply a patch that does the right thing, that'd make me very happy.
As I'm not using schroot anymore, my motivation to fix this is low but it'll be
put on the TODO list.

For anybody having a go at fixing the issue, maybe it would be best to use the
ChrootUnshare backend for $session instead of ChrootPlain. The code is run as
the superuser anyways.

Thanks!

cheers, josch

#1075871#21
Date:
2024-07-07 18:17:51 UTC
From:
To:
Hi,

I'd love to provide a patch, but I don't speak perl :-( Maybe a simple
solution is to invoke sbuild-update instead of chrooting since it
already do the proper setup. Actually I was just Ctrl-C and running
sbuild-update afterwards.

I acknowledge is a low priority thing. Actually I stopped adding gpg
because I don't sign stuff in there. It was just documented in sbuild's
wike page and that was the reason I was adding --include=gpg.

Cheers,
Charles

#1075871#26
Date:
2024-12-01 14:02:52 UTC
From:
To:
So isn't this a bug in gpg then, which shouldn't manually close all
possible FDs? (Instead use the close range function/syscall?)

Chris

#1075871#31
Date:
2024-12-01 16:09:18 UTC
From:
To:
Hi!

It's been a long long time :-)

Actually, that might be a suitable solution on GPG's side, at least for
the simple case where one wants to close all FDs from 3 to max_fds. They
do have an usecase where one can pass an exception list of FDs that
shouldn't be closed and here close_range would require more logic to
work.

The original GPG code is from 2010 [1], using /proc/self/fd to speed up
things is from 2016 [2] and close_range was only introduced in Linux in
2019 [3], so it's understandable why they are not using it. I'll file an
issue on GPG and see how it goes.

Cheers,
Charles

[1] https://github.com/gpg/gnupg/commit/d1591a97f4ea9705f18185c95775afeb965af68f
[2] https://github.com/gpg/gnupg/commit/512c56af43027149e8beacf259746b8d7bf9b1a2
[3] https://lwn.net/Articles/789023/

#1075871#36
Date:
2025-04-15 18:11:37 UTC
From:
To:
Hi,

I just tried to reproduce this on a trixie machine by running

sbuild-createchroot --include=gnupg bookworm

and the final update step completed without any noticeable delay.

gnupg instead of gpg as gpg no longer contains gpg-agent.

Can someone still reproduce this?

#1075871#39
Date:
2025-04-15 18:11:37 UTC
From:
To:
Hi,

I just tried to reproduce this on a trixie machine by running

sbuild-createchroot --include=gnupg bookworm

and the final update step completed without any noticeable delay.

gnupg instead of gpg as gpg no longer contains gpg-agent.

Can someone still reproduce this?