on premature exit, try to kill our existing children by sending them
the proper signal and waiting for a bit. Some scaffolding left (verbose) to allow more precise debugging
This commit is contained in:
parent
8afb9c2bda
commit
73534e9b6e
@ -1,7 +1,7 @@
|
||||
#! /usr/bin/perl
|
||||
|
||||
# ex:ts=8 sw=4:
|
||||
# $OpenBSD: dpb,v 1.127 2019/05/08 09:10:54 espie Exp $
|
||||
# $OpenBSD: dpb,v 1.128 2019/05/12 10:37:04 espie Exp $
|
||||
#
|
||||
# Copyright (c) 2010-2013 Marc Espie <espie@openbsd.org>
|
||||
#
|
||||
@ -29,7 +29,6 @@ use lib ("$ports1/infrastructure/lib", "$FindBin::Bin/../lib");
|
||||
|
||||
package main;
|
||||
|
||||
|
||||
use DPB::State;
|
||||
use DPB::PkgPath;
|
||||
use DPB::Core;
|
||||
@ -97,6 +96,24 @@ sub affinityclass
|
||||
}
|
||||
|
||||
my $subdirlist = {};
|
||||
|
||||
my $master_pid = $$;
|
||||
for my $S (qw(INT HUP TERM QUIT)) {
|
||||
$SIG{$S} = sub {
|
||||
if ($$ == $master_pid) {
|
||||
$> = 0;
|
||||
DPB::Core->cleanup($S, 0);
|
||||
# my $g = getpgrp();
|
||||
# kill $S => -$g; # or ask Core.pm ?
|
||||
} else {
|
||||
# print STDERR "Entering $S handler from $$ ($master_pid)\n";
|
||||
# print STDERR join("\n", DPB::Trace::trace_message()), "\n";
|
||||
}
|
||||
$SIG{$S} = 'DEFAULT';
|
||||
kill $S => $$;
|
||||
};
|
||||
}
|
||||
|
||||
DPB::Trace->setup(\%SIG);
|
||||
|
||||
my $state = DPB::State->new;
|
||||
|
@ -1,5 +1,5 @@
|
||||
# ex:ts=8 sw=4:
|
||||
# $OpenBSD: Core.pm,v 1.93 2019/05/11 15:31:12 espie Exp $
|
||||
# $OpenBSD: Core.pm,v 1.94 2019/05/12 10:37:04 espie Exp $
|
||||
#
|
||||
# Copyright (c) 2010-2013 Marc Espie <espie@openbsd.org>
|
||||
#
|
||||
@ -232,15 +232,74 @@ sub reap_wait
|
||||
return $class->reap_kid(waitpid(-1, 0));
|
||||
}
|
||||
|
||||
sub dump
|
||||
{
|
||||
my $c = shift;
|
||||
return join(' ', ref($c), ref($c->job), $c->job->name);
|
||||
}
|
||||
|
||||
sub send_signal
|
||||
{
|
||||
my ($class, $sig, $h, $verbose) = @_;
|
||||
while (my ($pid, $core) = each %$h) {
|
||||
print STDERR "Sending $sig to ".$core->dump, "\n"
|
||||
if $verbose;
|
||||
kill $sig => $pid;
|
||||
}
|
||||
}
|
||||
|
||||
sub wait_for_kill
|
||||
{
|
||||
my ($class, $h, $verbose) = @_;
|
||||
for (my $i = 0; $i < 4;) {
|
||||
my $kid = waitpid(-1, WNOHANG);
|
||||
if ($kid > 0) {
|
||||
my $info = "";
|
||||
if (exists $h->{$kid}) {
|
||||
$info = $h->{$kid}->dump;
|
||||
delete $h->{$kid};
|
||||
}
|
||||
print STDERR "Killed $kid $? $info\n" if $verbose;
|
||||
} elsif ($kid == -1) {
|
||||
return 1;
|
||||
} else {
|
||||
print STDERR "Waiting for children to quit\n";
|
||||
sleep 5;
|
||||
$i++;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
sub cleanup
|
||||
{
|
||||
my $class = shift;
|
||||
my ($class, $sig, $verbose) = @_;
|
||||
$sig //= 'INT';
|
||||
local $> = 0;
|
||||
|
||||
# collate repos together
|
||||
my $h = {};
|
||||
for my $repo ($class->repositories) {
|
||||
for my $pid (keys %$repo) {
|
||||
kill INT => $pid;
|
||||
while (my ($k, $v) = each %$repo) {
|
||||
$h->{$k} = $v;
|
||||
}
|
||||
}
|
||||
$class->send_signal($sig, $h, $verbose);
|
||||
|
||||
return if $class->wait_for_kill($h, $verbose);
|
||||
return if keys %$h == 0;
|
||||
if ($verbose) {
|
||||
for my $pid (keys %$h) {
|
||||
system {'ps'} ('ps', '-p', $pid, '-o',
|
||||
'pid,ppid,uid,gid,pgid,command');
|
||||
}
|
||||
}
|
||||
print STDERR "Sending KILL to remaining children\n";
|
||||
$class->send_signal('KILL', $h, $verbose);
|
||||
$class->wait_for_kill($h, $verbose);
|
||||
if (keys %$h > 0) {
|
||||
print STDERR "Some children still alive, giving up\n";
|
||||
}
|
||||
}
|
||||
|
||||
sub debug_dump
|
||||
|
Loading…
Reference in New Issue
Block a user