2
0
mirror of https://github.com/xcat2/xcat-dep.git synced 2026-09-12 12:36:23 +00:00

fix(xcat-dep): reach the per-package builder when a build is cancelled

The worker spawned the builder with system(), so the builder, its schroot
session and qemu were in the worker's process group but owned by nobody: a
cancelled worker died and left them running, holding the chroot and writing
into staging. Only the build inside the builder was protected, and nothing
signalled the builder.

The builder now runs through run_bounded, which gives it its own process group
and forwards the signal, so one cancellation unwinds the whole chain. The
wall-clock bound stays with the builder, which derives it from the chroot arch.
A forked worker also drops the parent's forwarder, whose copy names siblings the
parent already signals.
This commit is contained in:
Vinícius Ferrão
2026-09-06 01:57:19 -03:00
parent 3c6ec97417
commit 4395cb9536
+17 -2
View File
@@ -594,7 +594,17 @@ sub build_one_codename {
'>', sh_quote($log), '2>&1',
);
print " [$cn] -> $pkg ($dir/sbuild.pl)\n";
my $ec = run($cmd, nofail => 1);
# run_bounded, not run(): it puts the builder in its own process group and forwards a
# signal to it. system() would leave the builder, its schroot session and qemu running
# after this worker died, holding the chroot and writing into staging. The wall-clock
# bound belongs to the builder itself, so this call only carries the cancellation.
print "+ $cmd\n";
my $ec = 0;
unless ($dry_run) {
require XCAT::BuildUtils;
$ec = XCAT::BuildUtils::run_bounded(cmd => $cmd, timeout => 0,
label => "[$cn] $pkg", out => \*STDOUT)->{ec};
}
if ($ec != 0) { warn "FATAL: [$cn] $pkg build failed (rc=$ec) -- see $log\n"; return 1; }
}
print "== [$cn] done ==\n";
@@ -633,7 +643,12 @@ sub build_deps {
my $cn = shift @queue;
my $pid = fork();
die "FATAL: fork failed: $!\n" unless defined $pid;
if ($pid == 0) { exit(build_one_codename($cn)); } # child
# The child must not inherit the parent's forwarder: its copy names sibling workers,
# which the parent already signals.
if ($pid == 0) {
$SIG{$_} = 'DEFAULT' for qw(INT TERM HUP);
exit(build_one_codename($cn));
}
$pid2cn{$pid} = $cn; $running++;
}
my $pid = wait();