From afdb81839a9397b63858b8e27c3aa9dfe33aa750 Mon Sep 17 00:00:00 2001 From: espie Date: Mon, 25 Apr 2011 11:58:46 +0000 Subject: [PATCH] finish refactoring options. Deprecate: -t and -T use -DCONNECTION_TIMEOUT=... -DDISPLAY_TIMEOUT=... instead New feature: -DSTUCK_TIMEOUT= kill tasks when they don't show any progress for that long. --- infrastructure/bin/dpb | 294 ++++++++++++++------------ infrastructure/lib/DPB/Core.pm | 38 ++-- infrastructure/lib/DPB/Engine.pm | 2 +- infrastructure/lib/DPB/Grabber.pm | 13 +- infrastructure/lib/DPB/Job/Port.pm | 27 ++- infrastructure/lib/DPB/PortBuilder.pm | 24 ++- infrastructure/man/man1/dpb.1 | 36 +++- 7 files changed, 249 insertions(+), 185 deletions(-) diff --git a/infrastructure/bin/dpb b/infrastructure/bin/dpb index cbd65d25be9..fa91d49dd14 100755 --- a/infrastructure/bin/dpb +++ b/infrastructure/bin/dpb @@ -1,7 +1,7 @@ #! /usr/bin/perl # ex:ts=8 sw=4: -# $OpenBSD: dpb,v 1.17 2011/04/24 09:14:45 espie Exp $ +# $OpenBSD: dpb,v 1.18 2011/04/25 11:58:46 espie Exp $ # # Copyright (c) 2010 Marc Espie # @@ -31,15 +31,17 @@ package DPB::State; our @ISA = qw(OpenBSD::State); use OpenBSD::State; -use DPB::Heuristics; use OpenBSD::Paths; +use DPB::Heuristics; +use DPB::PkgPath; +use DPB::Logger; sub init { my $self = shift; $self->SUPER::init; - $self->{export_level}++; + $self->{no_exports} = 1; $self->{heuristics} = DPB::Heuristics->new; $self->{make} = $ENV{MAKE} || OpenBSD::Paths->make; ($self->{ports}, $self->{repo}, $self->{localarch}, $self->{distdir}) = @@ -53,26 +55,89 @@ sub init sub handle_options { my $state = shift; - $state->{opt}{A} = sub { - $state->{arch} = shift; - }; - $state->{opt}{L} = sub { - $state->{logdir} = shift; - }; - $state->{opt}{r} = sub { - $state->heuristics->random; - }; - $state->{opt}{m} = sub { - $state->heuristics->set_threshold(shift); + $state->{opt} = { + a => sub { + $state->{all} = 1; + }, + A => sub { + $state->{arch} = shift; + }, + L => sub { + $state->{logdir} = shift; + }, + r => sub { + $state->heuristics->random; + }, + m => sub { + $state->heuristics->set_threshold(shift) + }, + P => sub { + my $file = shift; + open my $fh, '<', $file or die "Can't open $file\n"; + my $_; + while (<$fh>) { + chomp; + next if m/^\#/; + unshift @main::ARGV, $_; + } + }, + b => sub { + push(@{$state->{build_files}}, shift); + }, + S => sub { + $state->parse_size_file(shift, $state->heuristics); + }, }; - $state->SUPER::handle_options('aceqrRsuUh:xA:f:j:m:P:b:d:L:S:t:T:', + $state->SUPER::handle_options('aceqrRsuUh:xA:f:j:m:P:b:L:S:t:T:', "[-acerRsuUx] [-A arch] [-j N] [-P plist] [-h hosts] [-L logdir]", - "[-b log] [-t ctimeout] [-T dtimeout] [-m threshold] [path ...]"); + "[-b log] [-t ctimeout] [-m threshold] [path ...]"); $state->{fullrepo} = join("/", $state->{repo}, $state->arch, "all"); $state->{logdir} //= $ENV{LOGDIR} // join("/", $state->ports, "logs", $state->arch); + if (defined $state->opt('j')) { + if ($state->localarch ne $state->arch) { + $state->usage( + "Can't use -j if -A arch is not local architecture"); + } + if ($state->opt('j') !~ m/^\d+$/) { + $state->usage("-j takes a numerical argument"); + } + } + $state->{logger} = DPB::Logger->new($state->logdir, $state->opt('c')); + $state->heuristics->set_logger($state->logger); + $state->{display_timeout} = + $state->{subst}->value('DISPLAY_TIMEOUT') // $state->opt('T') // 10; + $state->{connection_timeout} = + $state->{subst}->value('CONNECTION_TIMEOUT') // $state->opt('t'); + $state->{stuck_timeout} = $state->{subst}->value('STUCK_TIMEOUT'); +} +sub start_cores +{ + my $state = shift; + + if ($state->opt('h')) { + DPB::Core->parse_hosts_file($state->opt('h'), $state); + } + + my $prop = {}; + if ($state->opt('j')) { + $prop->{jobs} = $state->opt('j'); + } + if ($state->{stuck_timeout}) { + $prop->{stuck} = $state->{stuck_timeout}; + } + + if ($state->opt('j') || !$state->opt('h')) { + DPB::Core::Factory->new('localhost', $prop); + } + DPB::Core::Factory->init_cores($state); +} + +sub logger +{ + return shift->{logger}; } sub heuristics @@ -115,31 +180,52 @@ sub logdir return shift->{logdir}; } -package main; +sub parse_build_line +{ + return split(/\s+/, shift); +} +sub parse_build_file +{ + my ($state, $fname, @consumers) = @_; + if (!-f $fname) { + my $arch = $state->arch; + if (-f "$fname/$arch/build.log") { + $fname = "$fname/$arch/build.log"; + } elsif (-f "$fname/build.log") { + $fname = "$fname/build.log"; + } + } + open my $fh, '<', $fname or + $state->fatal("Couldn't open build file #1: #2", $fname, $!); + my $_; + while (<$fh>) { + chomp; + my ($pkgpath, $host, $time, $sz, @rest) = parse_build_line($_); + next if (!defined $sz) || $sz =~ m/!$/; + my $o = DPB::PkgPath->new_hidden($pkgpath); + for my $c (@consumers) { + $c->add_build_info($o, $host, $time, $sz); + } + } +} -use DPB::PkgPath; -use DPB::Core; -use DPB::Vars; -use DPB::PortInfo; -use DPB::Engine; -use DPB::PortBuilder; -use DPB::Reporter; -use OpenBSD::Error; -use DPB::Locks; -use DPB::Logger; -use DPB::Job; -use DPB::Grabber; - -our ($opt_t, $opt_d, $opt_e, $opt_T, $opt_c, $opt_h, $opt_j, $opt_a, - $opt_q, $opt_R, $opt_s, $opt_u, $opt_U, - $opt_f, $opt_x); -my @subdirlist; +sub handle_build_files +{ + my $state = shift; + return unless defined $state->{build_files}; + for my $file (@{$state->{build_files}}) { + $state->parse_build_file($file, $state->heuristics, + "DPB::Job::Port"); + } + $state->heuristics->finished_parsing; +} sub parse_size_file { - my ($fname, @consumers) = @_; - open my $fh, '<', $fname or die "Couldn't open build file $fname\n"; + my ($state, $fname, @consumers) = @_; + open my $fh, '<', $fname or + $state->fatal("Couldn't open build file #1: #2", $fname, $!); my $_; while (<$fh>) { chomp; @@ -154,60 +240,31 @@ sub parse_size_file } } -sub parse_build_line -{ - return split(/\s+/, shift); -} +package main; -sub parse_build_file -{ - my ($fname, $arch, @consumers) = @_; - if (!-f $fname) { - if (-f "$fname/$arch/build.log") { - $fname = "$fname/$arch/build.log"; - } elsif (-f "$fname/build.log") { - $fname = "$fname/build.log"; - } - } - open my $fh, '<', $fname or die "Couldn't open build file $fname\n"; - my $_; - while (<$fh>) { - chomp; - my ($pkgpath, $host, $time, $sz, @rest) = parse_build_line($_); - next if (!defined $sz) || $sz =~ m/!$/; - my $o = DPB::PkgPath->new_hidden($pkgpath); - for my $c (@consumers) { - $c->add_build_info($o, $host, $time, $sz); - } - } -} -my @build_files = (); +use DPB::PkgPath; +use DPB::Core; +use DPB::Vars; +use DPB::PortInfo; +use DPB::Engine; +use DPB::PortBuilder; +use DPB::Reporter; +use OpenBSD::Error; +use DPB::Locks; +use DPB::Job; +use DPB::Grabber; + +my @subdirlist; + my $state = DPB::State->new('dpb'); -$state->{opt} = { - P => sub { - my $file = shift; - open my $fh, '<', $file or die "Can't open $file\n"; - my $_; - while (<$fh>) { - chomp; - next if m/^\#/; - unshift @ARGV, $_; - } - }, - b => sub { - push(@build_files, shift); - }, - S => sub { - parse_size_file(shift, $state->heuristics); - } - }; $state->handle_options; +$state->start_cores; -my $dpb = $opt_f ? "fetch" : "normal"; +$state->handle_build_files; if (@ARGV == 0) { - $opt_a = 1; + $state->{all} = 1; } for my $arg (@ARGV) { $arg =~ s/\/+$//; @@ -223,56 +280,22 @@ for my $arg (@ARGV) { $pkgpath->add_to_subdirlist(\@subdirlist); } -my $logger = DPB::Logger->new($state->logdir, $opt_c); -$state->heuristics->set_logger($logger); - -if (defined $opt_j && $state->localarch ne $state->arch) { - $state->usage("Can't use -j if -A arch is not local architecture"); -} - -if (defined $opt_j && $opt_j !~ m/^\d+$/) { - $state->usage("-j takes a numerical argument"); -} - -if ($opt_h) { - DPB::Core->parse_hosts_file($opt_h, $state->arch, $opt_t, $logger, $state->heuristics); -} - -my $prop = {}; -if ($opt_j) { - $prop->{jobs} = $opt_j; -} - -if ($opt_j || !$opt_h) { - DPB::Core::Factory->new('localhost', $prop); -} - -if (@build_files > 0) { - for my $file (@build_files) { - parse_build_file($file, $state->arch, $state->heuristics, "DPB::Job::Port"); - } - $state->heuristics->finished_parsing; -} - -DPB::Core::Factory->init_cores($logger); - -my $builder = DPB::PortBuilder->new( - $opt_c, $opt_s, $opt_u, $opt_U, $opt_R, $state->fullrepo, $logger, - $state->ports, $state->make, $state->heuristics); +my $builder = DPB::PortBuilder->new($state); my $locker = DPB::Locks->new(join("/", $state->logdir, "locks")); -my $engine = DPB::Engine->new($builder, $state->heuristics, $logger, $locker); -my $reporter = DPB::Reporter->new($opt_x, $state->heuristics, "DPB::Core", $engine); +my $engine = DPB::Engine->new($builder, $state->heuristics, $state->logger, + $locker); +my $reporter = DPB::Reporter->new($state->opt('x'), + $state->heuristics, "DPB::Core", $engine); while (!DPB::Core->avail) { DPB::Core->reap; sleep 1; } my $core = DPB::Core->get; -#my $dump = DPB::Util->make_hot($logger->open('dump')); +#my $dump = DPB::Util->make_hot($state->logger->open('dump')); my $keep_going = 1; -$opt_T //= 10; -my $last_time = time() - $opt_T; +my $last_time = time() - $state->{display_timeout}; sub handle_non_waiting_jobs { @@ -290,7 +313,8 @@ sub handle_non_waiting_jobs } if ($need_clock) { my $current = time(); - if ($current >= $last_time + $opt_T || $reaped) { + if ($current >= $last_time + $state->{display_timeout} || + $reaped) { $reporter->report; $last_time = $current; } @@ -300,13 +324,13 @@ sub handle_non_waiting_jobs return $keep_going; } -my $grabber = DPB::Grabber->new($state->ports, $state->make, $logger, $engine, - $dpb, sub { handle_non_waiting_jobs(1) }); +my $grabber = DPB::Grabber->new($state, $engine, + sub { handle_non_waiting_jobs(1) }); -if ($opt_a) { +if ($state->{all}) { # when restarting interrupted dpb, # find the most important paths first - my $list = $engine->find_best($logger->logfile("dependencies"), 10); + my $list = $engine->find_best($state->logger->logfile("dependencies"), 10); # if we have them, list them before the full ports tree walk. if (@$list > 0) { $grabber->grab_subdirs($core, $list); @@ -319,7 +343,7 @@ if (@subdirlist > 0) { $grabber->complete_subdirs($core); -if ($opt_a) { +if ($state->{all}) { $grabber->grab_subdirs($core); } @@ -327,19 +351,19 @@ if ($opt_a) { $grabber->complete_subdirs($core); # give back "our" core to the pool. -if (!$opt_e) { +if (!$state->opt('e')) { $core->mark_ready; } # and let's wait for all jobs now. -if ($opt_a) { +if ($state->{all}) { $engine->dump_dependencies; } #$engine->dump($dump); $engine->check_buildable; #$engine->dump($dump); -DPB::Core->start_clock($opt_T); +DPB::Core->start_clock($state->{display_timeout}); while (1) { while (1) { handle_non_waiting_jobs(0); @@ -354,7 +378,7 @@ while (1) { DPB::Core->reap_wait; } } - if (!$opt_q || !$engine->recheck_errors) { + if (!$state->opt('q') || !$engine->recheck_errors) { last; } } @@ -362,5 +386,5 @@ while (1) { $reporter->reset; DPB::Core->cleanup; print $engine->report; -$engine->dump_category('tobuild', $logger->open('dump')); +$engine->dump_category('tobuild', $state->logger->open('dump')); diff --git a/infrastructure/lib/DPB/Core.pm b/infrastructure/lib/DPB/Core.pm index 8f0e4d3d04a..d819b8ef8ea 100644 --- a/infrastructure/lib/DPB/Core.pm +++ b/infrastructure/lib/DPB/Core.pm @@ -1,5 +1,5 @@ # ex:ts=8 sw=4: -# $OpenBSD: Core.pm,v 1.6 2011/03/22 19:49:56 espie Exp $ +# $OpenBSD: Core.pm,v 1.7 2011/04/25 11:58:46 espie Exp $ # # Copyright (c) 2010 Marc Espie # @@ -127,6 +127,12 @@ sub sf return $self->prop->{sf}; } +sub stuck_timeout +{ + my $self = shift; + return $self->prop->{stuck}; +} + sub memory { my $self = shift; @@ -397,13 +403,13 @@ sub new } } -my $inited = 0; sub init_cores { - my ($self, $logger, $startup) = @_; - return if $inited; + my ($self, $state) = @_; + my $logger = $state->logger; + my $startup = $state->{startup_script}; DPB::Core->set_logdir($logger->{logdir}); for my $core (values %$init) { my $job = DPB::Job::Init->new($logger); @@ -426,7 +432,6 @@ sub init_cores } $core->start_job($job); } - $inited = 1; } package DPB::Core; @@ -466,7 +471,7 @@ sub one_core my $hostname = $core->hostname; return $core->job->name." [$core->{pid}]". (DPB::Host->name_is_localhost($hostname) ? "" : " on ".$hostname). - $core->job->watched($time); + $core->job->watched($time, $core); } sub report @@ -583,18 +588,18 @@ sub has_sf sub parse_hosts_file { - my ($class, $filename, $arch, $timeout, $logger, $heuristics) = @_; - open my $fh, '<', $filename or die "Can't read host files $filename\n"; + my ($class, $filename, $state) = @_; + open my $fh, '<', $filename or + $state->fatal("Can't read host files #1: #2", $filename, $!); my $_; my $sf; my $cores = {}; - my $startup_script; while (<$fh>) { chomp; s/\s*\#.*$//; next if m/^$/; if (m/^STARTUP=\s*(.*)\s*$/) { - $startup_script = $1; + $state->{startup_script} = $1; next; } my $prop = {}; @@ -604,7 +609,7 @@ sub parse_hosts_file $prop->{$1} = $2; } } - if (defined $prop->{arch} && $prop->{arch} ne $arch) { + if (defined $prop->{arch} && $prop->{arch} ne $state->arch) { next; } if (defined $prop->{mem}) { @@ -614,12 +619,15 @@ sub parse_hosts_file if (defined $prop->{sf} && $prop->{sf} != $sf) { $has_sf = 1; } - if (defined $timeout) { - $prop->{timeout} //= $timeout; + if (defined $state->{connection_timeout}) { + $prop->{timeout} //= $state->{connection_timeout}; } - $heuristics->calibrate(DPB::Core::Factory->new($host, $prop)); + if (defined $state->{stuck_timeout}) { + $prop->{stuck} //= $state->{stuck_timeout}; + } + $state->heuristics->calibrate(DPB::Core::Factory->new($host, + $prop)); } - DPB::Core::Factory->init_cores($logger, $startup_script); } sub start_pipe diff --git a/infrastructure/lib/DPB/Engine.pm b/infrastructure/lib/DPB/Engine.pm index 31c83b857db..a1e818f58f4 100644 --- a/infrastructure/lib/DPB/Engine.pm +++ b/infrastructure/lib/DPB/Engine.pm @@ -1,5 +1,5 @@ # ex:ts=8 sw=4: -# $OpenBSD: Engine.pm,v 1.15 2010/12/07 10:56:26 espie Exp $ +# $OpenBSD: Engine.pm,v 1.16 2011/04/25 11:58:46 espie Exp $ # # Copyright (c) 2010 Marc Espie # diff --git a/infrastructure/lib/DPB/Grabber.pm b/infrastructure/lib/DPB/Grabber.pm index bbea91a0219..c9aee80ba3c 100644 --- a/infrastructure/lib/DPB/Grabber.pm +++ b/infrastructure/lib/DPB/Grabber.pm @@ -1,5 +1,5 @@ # ex:ts=8 sw=4: -# $OpenBSD: Grabber.pm,v 1.10 2010/12/05 10:06:12 espie Exp $ +# $OpenBSD: Grabber.pm,v 1.11 2011/04/25 11:58:46 espie Exp $ # # Copyright (c) 2010 Marc Espie # @@ -24,12 +24,13 @@ use DPB::Util; package DPB::Grabber; sub new { - my ($class, $ports, $make, $logger, $engine, $dpb, $endcode) = @_; - my $o = bless { ports => $ports, make => $make, - loglist => DPB::Util->make_hot($logger->open("vars")), - logger => $logger, + my ($class, $state, $engine, $endcode) = @_; + + my $o = bless { ports => $state->ports, make => $state->make, + loglist => DPB::Util->make_hot($state->logger->open("vars")), + logger => $state->logger, engine => $engine, - dpb => $dpb, + dpb => $state->opt('f') ? "fetch" : "normal", keep_going => 1, endcode => $endcode }, $class; diff --git a/infrastructure/lib/DPB/Job/Port.pm b/infrastructure/lib/DPB/Job/Port.pm index 07aefc03b73..6496cabdc35 100644 --- a/infrastructure/lib/DPB/Job/Port.pm +++ b/infrastructure/lib/DPB/Job/Port.pm @@ -1,5 +1,5 @@ # ex:ts=8 sw=4: -# $OpenBSD: Port.pm,v 1.6 2010/11/01 10:55:26 espie Exp $ +# $OpenBSD: Port.pm,v 1.7 2011/04/25 11:58:46 espie Exp $ # # Copyright (c) 2010 Marc Espie # @@ -388,6 +388,10 @@ sub finished_task sub finalize { my $self = shift; + if ($self->{stuck}) { + open my $fh, ">>", $self->{log}; + print $fh $self->{stuck}, "\n"; + } $self->SUPER::finalize(@_); } @@ -443,7 +447,7 @@ sub watch sub watched { - my ($self, $current) = @_; + my ($self, $current, $core) = @_; return "" unless defined $self->{watched}; $self->watch; my $progress = ''; @@ -458,15 +462,26 @@ sub watched } my $diff = $current - $self->{time}; + my $unchanged = " unchanged for "; if ($diff > 7200) { - return "$progress unchanged for ".int($diff/3600)." hours"; + $unchanged .= int($diff/3600)." hours"; } elsif ($diff > 300) { - return "$progress unchanged for ".int($diff/60)." minutes"; + $unchanged .= int($diff/60)." minutes"; } elsif ($diff > 10) { - return "$progress unchanged for ".int($diff)." seconds"; + $unchanged .= int($diff)." seconds"; } else { - return $progress; + $unchanged = ""; } + my $stuck = $core->stuck_timeout; + if (defined $stuck) { + if ($diff / $core->sf > $stuck) { + $self->{stuck} = + "KILLED: $self->{current} stuck at $progress,$unchanged"; + kill 9, $core->{pid}; + return $self->{stuck}; + } + } + return $progress.$unchanged; } sub really_watch diff --git a/infrastructure/lib/DPB/PortBuilder.pm b/infrastructure/lib/DPB/PortBuilder.pm index 99581c2341a..567073b9148 100644 --- a/infrastructure/lib/DPB/PortBuilder.pm +++ b/infrastructure/lib/DPB/PortBuilder.pm @@ -1,5 +1,5 @@ # ex:ts=8 sw=4: -# $OpenBSD: PortBuilder.pm,v 1.6 2010/11/02 20:32:59 espie Exp $ +# $OpenBSD: PortBuilder.pm,v 1.7 2011/04/25 11:58:46 espie Exp $ # # Copyright (c) 2010 Marc Espie # @@ -27,18 +27,20 @@ use DPB::Job::Port; sub new { - my $class = shift; - my ($opt_c, $opt_s, $opt_u, $opt_U, $opt_R, $fullrepo, $logger, $ports, $make, - $h) = @_; - my $self = bless {clean => $opt_c, size => $opt_s, - rebuild => $opt_R, - fullrepo => $fullrepo, - logger => $logger, ports => $ports, make => $make, - heuristics => $h}, $class; - if ($opt_u || $opt_U) { + my ($class, $state) = @_; + my $self = bless { + clean => $state->opt('c'), + size => $state->opt('s'), + rebuild => $state->opt('R'), + fullrepo => $state->fullrepo, + logger => $state->logger, + ports => $state->ports, + make => $state->make, + heuristics => $state->heuristics}, $class; + if ($state->opt('u') || $state->opt('U')) { $self->{update} = 1; } - if ($opt_U) { + if ($state->opt('U')) { $self->{forceupdate} = 1; } $self->init; diff --git a/infrastructure/man/man1/dpb.1 b/infrastructure/man/man1/dpb.1 index 1b1ade7596f..1cf6d1d142c 100644 --- a/infrastructure/man/man1/dpb.1 +++ b/infrastructure/man/man1/dpb.1 @@ -1,4 +1,4 @@ -.\" $OpenBSD: dpb.1,v 1.10 2010/11/02 11:34:29 espie Exp $ +.\" $OpenBSD: dpb.1,v 1.11 2011/04/25 11:58:46 espie Exp $ .\" .\" Copyright (c) 2010 Marc Espie .\" @@ -14,7 +14,7 @@ .\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF .\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. .\" -.Dd $Mdocdate: November 2 2010 $ +.Dd $Mdocdate: April 25 2011 $ .Dt DPB 1 .Os .Sh NAME @@ -26,14 +26,13 @@ .Op Fl aceqrRsuUx .Op Fl A Ar arch .Op Fl b Ar logfile +.Op Fl D Ar PARAM Ns = Ns Ar value .Op Fl h Ar hosts .Op Fl j Ar n .Op Fl L Ar logdir .Op Fl m Ar threshold .Op Fl P Ar subdirlist .Op Fl S Ar sizefile -.Op Fl t Ar ctimeout -.Op Fl T Ar dtimeout .Op Ar pkgpath ... .Ek .Sh DESCRIPTION @@ -60,6 +59,25 @@ Prime the heuristics module with a previous build log, so that packages that take a long time to build will happen earlier. .It Fl c Clean port working directory and log before each build. +.It Fl D Ar PARAM Ns = Ns Ar value +Set defined parameter to value. +Known parameters are as follows: +.Bl -tag -width DISPLAY +.It Ar CONNECTION_TIMEOUT +Connection timeout for ssh. +Defaults to 60 seconds. +.It Ar DISPLAY_TIMEOUT +Display timeout (in seconds) while waiting for jobs to finish, so that the +display is updated even if jobs didn't finish. +Defaults to 10 seconds. +.It Ar STUCK_TIMEOUT +Timeout (in seconds * speed factor) after which tasks that don't show +any progress will be killed. +This can be set on a per-core basis as the +.Sq stuck +property. +Note that this will always be divided by the core's speed factor. +.El .It Fl e The listing job is extra and won't be given back to the pool when it's finished. @@ -93,6 +111,9 @@ The machine (or machines) with the highest speed factor will get access to all jobs, whereas other machines will be clamped to stuff which does not take too long. Requires previous build information to be effective. +.It stuck=s +Stuck timeout (in seconds * sf) after which tasks which show no progress +will get killed. .It timeout=s Defines a specific connection timeout for ssh to that host. .El @@ -135,13 +156,6 @@ Compute workdir sizes before cleaning up, and stash them in log file .Pa ${LOGDIR}/size.log . .It Fl S Ar sizefile Read a size log file and use it for choosing to put WRKDIR in memory. -.It Fl t Ar ctimeout -Connection timeout for ssh. -Defaults to 60 seconds. -.It Fl T Ar dtimeout -Display timeout (in seconds) while waiting for jobs to finish, so that the -display is updated even if jobs didn't finish. -Defaults to 10 seconds. .It Fl u Update existing packages during dependency solving. Can be used to run a bulk-build on a machine with installed packages,