Hello community,
here is the log from the commit of package icecream
checked in at Mon Sep 4 17:53:00 CEST 2006.
--------
--- icecream/icecream.changes 2006-09-03 20:53:28.000000000 +0200
+++ icecream/icecream.changes 2006-09-04 17:52:01.000000000 +0200
@@ -1,0 +2,23 @@
+Mon Sep 4 17:52:01 CEST 2006 - mls@suse.de
+
+- converted neededforbuild to BuildRequires
+
+-------------------------------------------------------------------
+Mon Sep 4 16:22:40 CEST 2006 - coolo@suse.de
+
+- 0.7.10:
+ - handle errors in installing environments correctly
+ - block daemons that have full discs
+ - add -pipe to the command line to reduce disk usage
+ - fix cancelling of jobs awaiting a remote job (were hanging
+ in scheduler forever)
+ - if ICECC=no is set, don't try to be clever
+ - adding two more flags for local compilation (profile
+ feedback related)
+ - flush debug files before every fork to avoid dups in
+ log output
+ - be stricter in what messages are required to keep the
+ daemon<->scheduler communication intact (network drops
+ again)
+
+-------------------------------------------------------------------
Old:
----
icecc-0.7.9.tar.bz2
New:
----
icecc-0.7.10.tar.bz2
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Other differences:
------------------
++++++ icecream.spec ++++++
--- /var/tmp/diff_new_pack.OiPJFf/_old 2006-09-04 17:52:22.000000000 +0200
+++ /var/tmp/diff_new_pack.OiPJFf/_new 2006-09-04 17:52:22.000000000 +0200
@@ -1,5 +1,5 @@
#
-# spec file for package icecream (Version 0.7.9)
+# spec file for package icecream (Version 0.7.10)
#
# Copyright (c) 2006 SUSE LINUX Products GmbH, Nuernberg, Germany.
# This file and all modifications and additions to the pristine
@@ -22,7 +22,7 @@
%endif
Prereq: /usr/sbin/useradd /usr/sbin/groupadd
Requires: gcc-c++
-Version: 0.7.9
+Version: 0.7.10
Release: 1
Source0: ftp://ftp.suse.com/pub/projects/icecream/icecc-%{version}.tar.bz2
Source1: %name-manpages.tar.bz2
@@ -139,6 +139,23 @@
%_libdir/pkgconfig/icecc.pc
%changelog -n icecream
+* Mon Sep 04 2006 - mls@suse.de
+- converted neededforbuild to BuildRequires
+* Mon Sep 04 2006 - coolo@suse.de
+- 0.7.10:
+- handle errors in installing environments correctly
+- block daemons that have full discs
+- add -pipe to the command line to reduce disk usage
+- fix cancelling of jobs awaiting a remote job (were hanging
+ in scheduler forever)
+- if ICECC=no is set, don't try to be clever
+- adding two more flags for local compilation (profile
+ feedback related)
+- flush debug files before every fork to avoid dups in
+ log output
+- be stricter in what messages are required to keep the
+ daemon<->scheduler communication intact (network drops
+ again)
* Sun Sep 03 2006 - coolo@suse.de
- 0.7.9:
- scheduler will ping the daemon periodically,
++++++ icecc-0.7.9.tar.bz2 -> icecc-0.7.10.tar.bz2 ++++++
diff -urN --exclude=CVS --exclude=.cvsignore --exclude=.svn --exclude=.svnignore old/icecream/BENCH new/icecream/BENCH
--- old/icecream/BENCH 2006-06-19 15:18:26.000000000 +0200
+++ new/icecream/BENCH 2006-09-04 13:51:58.000000000 +0200
@@ -97,3 +97,64 @@
make -j10/sched: 389s
As we can see, the scheduler improves performance by 38%.
+
+
+======================================================================
+
+New performance experiments.
+
+New baseline:
+
+make-it-cool, both with -m 1, make -j5
+
+make -j5 : 382s
+make -j5 : 354s
+make -j5 : 336s
+make -j5 : 355s
+
+remote with -m 2
+
+make -j5 : 333s
+make -j5 : 299s
+make -j5 : 307s
+
+remote with -m 2, preload scheduler:
+
+make -j5 : 303s
+make -j5 : 287s
+make -j5 : 291s
+
+remote with -m 1, preload scheduler:
+
+make -j5 : 287s
+make -j5 : 288s
+make -j5 : 289s
+
+remote with -m 1, preload scheduler, optimized return:
+make -j5 : 288s
+make -j5 : 289s
+make -j5 : 288s
+
+remote with -m 2, preload scheduler, optimized return:
+make -j5 : 279s
+make -j5 : 281s
+make -j5 : 278s
+
+As we can see, over-booking the remote slave improves performance by 13%.
+As the CPU hardly gets faster, it means that we're reducing idle wait time
+this way.
+
+One experiment was to pre-load jobs on the remote slave. This means even
+though all compile slots are filled, it gets one (exactly one) job assigned.
+The daemon itself will start compilation as soon as it gets a free slot,
+reducing both client<->CS and CS<->scheduler roundtrip. Overall, it gave an
+impressive 4% speedup.
+
+A lot of time is however spent on writing back the compiled object file
+to the client, and this is dominated by network saturation and latency
+and not by CPU usage. The obvious solution is to notify the scheduler
+about a free slot as soon as compilation (but not write-back) has
+finished. With remote over-booking this resulted in another 3% speedup,
+while no improvments could be measured in the -m 1 case. Given that
+it significantly reduced code complexity in the daemon, it should still be
+an improvement (reduced code size by almost 8%!).
diff -urN --exclude=CVS --exclude=.cvsignore --exclude=.svn --exclude=.svnignore old/icecream/NEWS new/icecream/NEWS
--- old/icecream/NEWS 2006-09-03 13:43:13.000000000 +0200
+++ new/icecream/NEWS 2006-09-04 16:20:28.000000000 +0200
@@ -1,4 +1,19 @@
-0.7.9 (r580380):
+0.7.10 (r580794):
+ - handle errors in installing environments correctly
+ - block daemons that have full discs
+ - add -pipe to the command line to reduce disk usage
+ - fix cancelling of jobs awaiting a remote job (were hanging
+ in scheduler forever)
+ - if ICECC=no is set, don't try to be clever
+ - adding two more flags for local compilation (profile
+ feedback related)
+ - flush debug files before every fork to avoid dups in
+ log output
+ - be stricter in what messages are required to keep the
+ daemon<->scheduler communication intact (network drops
+ again)
+
+0.7.9 (r580498):
- scheduler will ping the daemon periodically,
daemon will disconnect if not pinged from time
to time (to avoid network drops being unnoticed)
diff -urN --exclude=CVS --exclude=.cvsignore --exclude=.svn --exclude=.svnignore old/icecream/client/arg.cpp new/icecream/client/arg.cpp
--- old/icecream/client/arg.cpp 2006-03-17 15:24:29.000000000 +0100
+++ new/icecream/client/arg.cpp 2006-09-04 13:21:54.000000000 +0200
@@ -141,6 +141,8 @@
} else if (!strcmp(a, "-fprofile-arcs")
|| !strcmp(a, "-ftest-coverage")
|| !strcmp( a, "-frepo" )
+ || !strcmp( a, "-fprofile-generate" )
+ || !strcmp( a, "-fprofile-use" )
|| !strcmp( a, "-fbranch-probabilities") ) {
#if CLIENT_DEBUG
log_info() << "compiler will emit profile info; must be local" << endl;
diff -urN --exclude=CVS --exclude=.cvsignore --exclude=.svn --exclude=.svnignore old/icecream/client/cpp.cpp new/icecream/client/cpp.cpp
--- old/icecream/client/cpp.cpp 2006-06-19 11:50:09.000000000 +0200
+++ new/icecream/client/cpp.cpp 2006-09-04 13:58:53.000000000 +0200
@@ -63,6 +63,7 @@
**/
pid_t call_cpp(CompileJob &job, int fdwrite, int fdread)
{
+ flush_debug();
pid_t pid = fork();
if (pid == -1) {
log_perror("failed to fork:");
diff -urN --exclude=CVS --exclude=.cvsignore --exclude=.svn --exclude=.svnignore old/icecream/client/local.cpp new/icecream/client/local.cpp
--- old/icecream/client/local.cpp 2006-09-02 19:12:13.000000000 +0200
+++ new/icecream/client/local.cpp 2006-09-04 13:58:53.000000000 +0200
@@ -193,8 +193,10 @@
if (color_output && pipe(pf))
color_output = false;
- if ( used || color_output )
+ if ( used || color_output ) {
+ flush_debug();
child_pid = fork();
+ }
if ( child_pid ) {
if (color_output)
diff -urN --exclude=CVS --exclude=.cvsignore --exclude=.svn --exclude=.svnignore old/icecream/client/main.cpp new/icecream/client/main.cpp
--- old/icecream/client/main.cpp 2006-09-03 15:35:11.000000000 +0200
+++ new/icecream/client/main.cpp 2006-09-04 10:41:51.000000000 +0200
@@ -215,17 +215,18 @@
CompileJob job;
+ local |= analyse_argv( argv, job );
+
/* if ICECC is set to no, then run job locally */
if ( getenv( "ICECC" ) ) {
string icecc;
icecc = getenv( "ICECC" );
- if ( icecc == "no" ) {
- local = true;
- }
+ /* if the environment variable is set, the user wants to debug if a compile
+ failure is to blame to icecream, so make sure we do the least we can. */
+ if ( icecc == "no" )
+ return build_local( job, 0 );
}
- local |= analyse_argv( argv, job );
-
MsgChannel *local_daemon = Service::createChannel( "127.0.0.1", 10245, 0/*timeout*/);
if ( ! local_daemon ) {
log_warning() << "no local daemon found\n";
diff -urN --exclude=CVS --exclude=.cvsignore --exclude=.svn --exclude=.svnignore old/icecream/client/remote.cpp new/icecream/client/remote.cpp
--- old/icecream/client/remote.cpp 2006-09-02 22:20:58.000000000 +0200
+++ new/icecream/client/remote.cpp 2006-09-04 13:58:53.000000000 +0200
@@ -638,6 +638,7 @@
remote_daemon = umsgs[i]->hostname;
trace() << "got_server_for_job " << umsgs[i]->hostname << endl;
+ flush_debug();
pid_t pid = fork();
if ( !pid ) {
int ret = 42;
diff -urN --exclude=CVS --exclude=.cvsignore --exclude=.svn --exclude=.svnignore old/icecream/configure.in new/icecream/configure.in
--- old/icecream/configure.in 2006-09-03 11:29:48.000000000 +0200
+++ new/icecream/configure.in 2006-09-04 16:20:28.000000000 +0200
@@ -4,7 +4,7 @@
AC_INIT(client/main.cpp)
-AM_INIT_AUTOMAKE(icecc, "0.7.9")
+AM_INIT_AUTOMAKE(icecc, "0.7.10")
AM_CONFIG_HEADER(config.h)
AC_CANONICAL_HOST
@@ -33,8 +33,8 @@
# Some of these are needed by popt (or other libraries included in the future).
-AC_CHECK_HEADERS([unistd.h stdint.h sys/types.h sys/sendfile.h sys/signal.h ifaddrs.h])
-AC_CHECK_HEADERS([ctype.h sys/resource.h sys/socket.h sys/select.h])
+AC_CHECK_HEADERS([unistd.h stdint.h sys/types.h sys/signal.h ifaddrs.h])
+AC_CHECK_HEADERS([ctype.h sys/resource.h sys/socket.h sys/select.h sys/vfs.h])
AC_CHECK_HEADERS([netinet/in.h], [], [],
[#if HAVE_SYS_TYPES_H
# include
@@ -120,7 +120,7 @@
AC_CHECK_LIB(resolv, hstrerror, , , [-lnsl -lsocket])
AC_CHECK_LIB(resolv, inet_aton, , , [-lnsl -lsocket])
-AC_CHECK_FUNCS([sendfile setsid flock lockf hstrerror strerror setuid setreuid])
+AC_CHECK_FUNCS([setsid flock lockf hstrerror strerror setuid setreuid])
AC_CHECK_FUNCS([getuid geteuid mcheck wait4 wait3 waitpid setgroups getcwd])
AC_CHECK_FUNCS([snprintf vsnprintf vasprintf asprintf getcwd getwd])
AC_CHECK_FUNCS([getrusage strsignal gettimeofday])
diff -urN --exclude=CVS --exclude=.cvsignore --exclude=.svn --exclude=.svnignore old/icecream/daemon/environment.cpp new/icecream/daemon/environment.cpp
--- old/icecream/daemon/environment.cpp 2006-07-06 20:16:45.000000000 +0200
+++ new/icecream/daemon/environment.cpp 2006-09-04 13:58:53.000000000 +0200
@@ -143,6 +143,7 @@
bool cleanup_cache( const string &basedir )
{
+ flush_debug();
pid_t pid = fork();
if ( pid )
{
@@ -214,6 +215,7 @@
return 0;
}
+ flush_debug();
pid_t pid = fork();
if ( pid ) {
int status = 1;
@@ -227,8 +229,10 @@
status = 1;
}
trace() << "native_environment " << native_environment << endl;
- if ( status )
+ if ( status ) {
+ rmdir( nativedir.c_str() );
return 0;
+ }
else {
return sumup_dir( nativedir );
}
@@ -245,20 +249,14 @@
if ( chdir( nativedir.c_str() ) ) {
log_perror( "chdir" );
- rmdir( nativedir.c_str() );
- goto error;
+ _exit(1);
}
if ( system( BINDIR "/icecc --build-native" ) ) {
log_error() << BINDIR "/icecc --build-native failed\n";
- goto error;
- } else {
- _exit( 0 );
+ _exit(1);
}
-
-error:
- rmdir( nativedir.c_str() );
- _exit( 1 );
+ _exit( 0 );
}
size_t install_environment( const std::string &basename, const std::string &target,
@@ -317,6 +315,7 @@
if ( pipe( fds ) )
return 0;
+ flush_debug();
pid_t pid = fork();
if ( pid )
{
@@ -357,25 +356,22 @@
fclose( fpipe );
close( fds[1] );
- int status = 0;
+ int status = 1;
+ while ( waitpid( pid, &status, 0) < 0 && errno == EINTR)
+ ;
+
+ error |= WEXITSTATUS(status);
+
if ( error ) {
kill( pid, SIGTERM );
char buffer[PATH_MAX];
snprintf( buffer, PATH_MAX, "rm -rf '/%s'", dirname.c_str() );
system( buffer );
+ return 0;
} else {
mkdir( ( dirname + "/tmp" ).c_str(), 01775 );
chown( ( dirname + "/tmp" ).c_str(), 0, nobody_gid );
chmod( ( dirname + "/tmp" ).c_str(), 01775 );
- }
-
- status = 1;
- while ( waitpid( pid, &status, 0) < 0 && errno == EINTR)
- ;
-
- if ( WEXITSTATUS(status) ) {
- return 0;
- } else {
return sumup_dir( dirname );
}
}
@@ -406,7 +402,7 @@
argv[3] = strdup( "-xf" );
argv[4] = strdup( "-" );
argv[5] = 0;
- _exit(execv( argv[0], argv ));
+ _exit( execv( argv[0], argv ) );
}
size_t remove_environment( const string &basename, const string &env )
@@ -421,6 +417,7 @@
size_t res = sumup_dir( dirname );
+ flush_debug();
pid_t pid = fork();
if ( pid )
{
diff -urN --exclude=CVS --exclude=.cvsignore --exclude=.svn --exclude=.svnignore old/icecream/daemon/main.cpp new/icecream/daemon/main.cpp
--- old/icecream/daemon/main.cpp 2006-09-03 18:45:03.000000000 +0200
+++ new/icecream/daemon/main.cpp 2006-09-04 14:24:30.000000000 +0200
@@ -52,6 +52,10 @@
# include
#endif
+#ifdef HAVE_SYS_VFS_H
+#include
+#endif
+
#include
#ifdef HAVE_RESOLV_H
@@ -266,6 +270,10 @@
}
};
+static void empty_func( int )
+{
+}
+
static int set_new_pgrp(void)
{
/* If we're a session group leader, then we are not able to call
@@ -542,6 +550,11 @@
if ( idle_average < 100 )
msg.load = 1000;
+ struct statfs buf;
+ int ret = statfs(envbasedir.c_str(), &buf);
+ if (!ret && buf.f_bavail < (max_kids + 1 - current_kids) * 4 * 1024 * 1024 / buf.f_bsize)
+ msg.load = 1000;
+
// Matz got in the urine that not all CPUs are always feed
mem_limit = std::max( msg.freeMem / std::min( std::max( max_kids, 1U ), 4U ), 100U );
@@ -627,9 +640,13 @@
string target = emsg->target;
if ( target.empty() )
target = machine_name;
- size_t installed_size = install_environment( envbasedir, emsg->target,
- emsg->name, c, nobody_uid,
- nobody_gid );
+
+ size_t installed_size = 0;
+ /* HACKALERT: install_environment can block for a while, make sure
+ the scheduler doesn't kick us */
+ if ( maybe_stats(true) )
+ installed_size = install_environment( envbasedir, emsg->target,
+ emsg->name, c, nobody_uid, nobody_gid );
if (!installed_size) {
trace() << "install environment failed" << endl;
c->send_msg(EndMsg()); // shut up, we had an error
@@ -679,6 +696,8 @@
reannounce_environments(envbasedir, nodename); // do that before the file compiles
}
+ // we do that here so we're not given out in case of full discs
+ maybe_stats(true);
return true;
}
@@ -875,6 +894,10 @@
int job_id = client->job_id;
if ( client->status == Client::TOCOMPILE )
job_id = client->job->jobID();
+ if ( client->status == Client::WAITFORCS ) {
+ job_id = client->client_id; // it's all we have
+ exitcode = CLIENT_WAS_WAITING_FOR_CS; // this is the message
+ }
if ( job_id > 0 ) {
JobDoneMsg::from_type flag = JobDoneMsg::FROM_SUBMITTER;
@@ -885,7 +908,6 @@
case Client::UNKNOWN:
case Client::GOTNATIVE:
case Client::JOBDONE:
- case Client::WAITFORCS:
case Client::WAITFORCHILD:
case Client::LINKJOB:
assert( false ); // should not have a job_id
@@ -893,6 +915,7 @@
case Client::WAITCOMPILE:
case Client::PENDING_USE_CS:
case Client::CLIENTWORK:
+ case Client::WAITFORCS:
flag = JobDoneMsg::FROM_SUBMITTER;
break;
}
@@ -1015,6 +1038,11 @@
#endif
+ /* reap zombis */
+ int status;
+ while (waitpid(-1, &status, WNOHANG) < 0 && errno == EINTR)
+ ;
+
handle_old_request();
/* collect the stats after the children exited icecream_load */
@@ -1102,7 +1130,6 @@
log_error() << "unknown scheduler type " << ( char )msg->type << endl;
}
}
- last_scheduler = time(0);
delete msg;
return ret;
}
@@ -1415,10 +1442,11 @@
exit( EXIT_DISTCC_FAILED );
}
- if (signal(SIGCHLD, SIG_IGN) == SIG_ERR) {
- log_warning() << "signal(SIGCHLD, ignore) failed: " << strerror(errno) << endl;
+ if (signal(SIGCHLD, empty_func) == SIG_ERR) {
+ log_warning() << "signal(SIGCHLD) failed: " << strerror(errno) << endl;
exit( EXIT_DISTCC_FAILED );
}
+
/* This is called in the master daemon, whether that is detached or
* not. */
dcc_master_pid = getpid();
diff -urN --exclude=CVS --exclude=.cvsignore --exclude=.svn --exclude=.svnignore old/icecream/daemon/serve.cpp new/icecream/daemon/serve.cpp
--- old/icecream/daemon/serve.cpp 2006-09-02 19:56:15.000000000 +0200
+++ new/icecream/daemon/serve.cpp 2006-09-04 13:58:53.000000000 +0200
@@ -86,6 +86,7 @@
if ( pipe( socket ) == -1)
return -1;
+ flush_debug();
pid_t pid = fork();
assert(pid >= 0);
if ( pid > 0) { // parent
diff -urN --exclude=CVS --exclude=.cvsignore --exclude=.svn --exclude=.svnignore old/icecream/daemon/workit.cpp new/icecream/daemon/workit.cpp
--- old/icecream/daemon/workit.cpp 2006-09-03 18:45:03.000000000 +0200
+++ new/icecream/daemon/workit.cpp 2006-09-04 13:58:53.000000000 +0200
@@ -180,6 +180,7 @@
sigprocmask( SIG_UNBLOCK, &act.sa_mask, 0 );
char buffer[4096];
+ flush_debug();
pid_t pid = fork();
if ( pid == -1 ) {
close( sock_err[0] );
@@ -228,6 +229,7 @@
argc++; // the program
argc += 6; // -x c - -o file.o -fpreprocessed
argc += 4; // gpc parameters
+ argc += 1; // -pipe
char **argv = new char*[argc + 1];
int i = 0;
if (j.language() == CompileJob::Lang_C)
@@ -237,13 +239,16 @@
else
assert(0);
- //TODOlist.push_back( "-Busr/lib/gcc-lib/i586-suse-linux/3.3.1/" );
-
+ bool hasPipe = false;
for ( std::list<string>::const_iterator it = list.begin();
it != list.end(); ++it) {
+ if(*it == "-pipe")
+ hasPipe = true;
argv[i++] = strdup( it->c_str() );
}
argv[i++] = strdup("-fpreprocessed");
+ if(!hasPipe)
+ argv[i++] = strdup("-pipe");
argv[i++] = strdup("-x");
argv[i++] = strdup((j.language() == CompileJob::Lang_CXX) ? "c++" : "c");
argv[i++] = strdup( "-" );
@@ -257,14 +262,8 @@
argv[i++] = strdup( buffer );
// before you add new args, check above for argc
argv[i] = 0;
- if (i > argc)
- printf ("Ohh bummer. You can't count.\n");
-#if 0
- printf( "forking " );
- for ( int index = 0; argv[index]; index++ )
- printf( "%s ", argv[index] );
- printf( "\n" );
-#endif
+ assert(i <= argc);
+
close_debug();
dup2 (sock_out[1], STDOUT_FILENO );
close(sock_out[1]);
@@ -292,11 +291,11 @@
struct timeval starttv;
gettimeofday(&starttv, 0 );
-
+
for (;;) {
Msg* msg = client->get_msg(60);
- if ( !msg || (msg->type != M_FILE_CHUNK && msg->type != M_END) )
+ if ( !msg || (msg->type != M_FILE_CHUNK && msg->type != M_END) )
{
log_error() << "protocol error while reading preprocessed file\n";
delete msg;
@@ -356,7 +355,6 @@
error_client( client, "compiler failed." );
delete msg;
msg = 0;
- kill( pid, SIGTERM ); // make sure it's dead
while ( waitpid(pid, 0, 0) < 0 && errno == EINTR)
;
throw myexception (EXIT_COMPILER_CRASHED);
@@ -444,7 +442,6 @@
if ( FD_ISSET( client_fd, &rfds ) ) {
rmsg.err.append( "client cancelled\n" );
close( client_fd );
- kill( pid, SIGTERM );
while ( waitpid(pid, 0, 0) < 0 && errno == EINTR)
;
return EXIT_CLIENT_KILLED;
@@ -453,12 +450,11 @@
case -1:
if ( ret < 0 && errno != EINTR ) { // this usually means the logic broke
error_client( client, string( "select returned " ) + strerror( errno ) );
- kill( pid, SIGTERM ); // make sure it's dead
while ( waitpid(pid, 0, 0) < 0 && errno == EINTR)
;
return EXIT_DISTCC_FAILED;
}
- // fall through; should happen if tvp->tv_sec < 0
+ // fall through
case 0:
struct rusage ru;
int status;
diff -urN --exclude=CVS --exclude=.cvsignore --exclude=.svn --exclude=.svnignore old/icecream/services/comm.cpp new/icecream/services/comm.cpp
--- old/icecream/services/comm.cpp 2006-09-02 22:20:58.000000000 +0200
+++ new/icecream/services/comm.cpp 2006-09-04 14:07:28.000000000 +0200
@@ -817,7 +817,6 @@
case M_UNKNOWN: return 0;
case M_PING: m = new PingMsg; break;
case M_END: m = new EndMsg; break;
- case M_TIMEOUT: m = new TimeoutMsg; break;
case M_GET_CS: m = new GetCSMsg; break;
case M_USE_CS: m = new UseCSMsg; break;
case M_COMPILE_FILE: m = new CompileFileMsg (new CompileJob, true); break;
@@ -842,6 +841,7 @@
case M_GET_INTERNALS: m = new GetInternalStatus; break;
case M_STATUS_TEXT: m = new StatusTextMsg; break;
case M_CS_CONF: m = new ConfCSMsg; break;
+ case M_TIMEOUT: break;
}
if (!m)
return 0;
diff -urN --exclude=CVS --exclude=.cvsignore --exclude=.svn --exclude=.svnignore old/icecream/services/comm.h new/icecream/services/comm.h
--- old/icecream/services/comm.h 2006-09-02 20:31:52.000000000 +0200
+++ new/icecream/services/comm.h 2006-09-04 14:07:28.000000000 +0200
@@ -56,8 +56,7 @@
/* Either the end of file chunks or connection (A<->A) */
M_END,
- // Fake message used in message reading loops (A<->A)
- M_TIMEOUT,
+ M_TIMEOUT, // unused
// C --> CS
M_GET_NATIVE_ENV,
@@ -236,11 +235,6 @@
EndMsg () : Msg(M_END) {}
};
-class TimeoutMsg : public Msg {
-public:
- TimeoutMsg () : Msg(M_TIMEOUT) {}
-};
-
class GetCSMsg : public Msg {
public:
Environments versions;
@@ -345,6 +339,10 @@
virtual void send_to_channel (MsgChannel * c) const;
};
+enum SpecialExits {
+ CLIENT_WAS_WAITING_FOR_CS = 200
+};
+
class JobDoneMsg : public Msg {
public:
uint32_t real_msec; /* real time it used */
diff -urN --exclude=CVS --exclude=.cvsignore --exclude=.svn --exclude=.svnignore old/icecream/services/logging.cpp new/icecream/services/logging.cpp
--- old/icecream/services/logging.cpp 2006-09-02 22:20:58.000000000 +0200
+++ new/icecream/services/logging.cpp 2006-09-04 13:58:53.000000000 +0200
@@ -93,6 +93,16 @@
logfile_trace = logfile_info = logfile_warning = logfile_error = 0;
}
+/* Flushes all ostreams used for debug messages. You need to call
+ this before forking. */
+void flush_debug()
+{
+ if (logfile_null.is_open())
+ logfile_null.flush();
+ if (logfile_file.is_open())
+ logfile_file.flush();
+}
+
#ifdef HAVE_BACKTRACE
#include
#endif
diff -urN --exclude=CVS --exclude=.cvsignore --exclude=.svn --exclude=.svnignore old/icecream/services/logging.h new/icecream/services/logging.h
--- old/icecream/services/logging.h 2006-09-02 22:20:58.000000000 +0200
+++ new/icecream/services/logging.h 2006-09-04 13:58:53.000000000 +0200
@@ -38,6 +38,7 @@
void setup_debug(int level, const std::string &logfile = "", const std::string& prefix="");
void reset_debug(int);
void close_debug();
+void flush_debug();
static inline std::ostream & output_date( std::ostream &os )
{
diff -urN --exclude=CVS --exclude=.cvsignore --exclude=.svn --exclude=.svnignore old/icecream/services/scheduler.cpp new/icecream/services/scheduler.cpp
--- old/icecream/services/scheduler.cpp 2006-09-02 21:42:52.000000000 +0200
+++ new/icecream/services/scheduler.cpp 2006-09-04 14:07:28.000000000 +0200
@@ -1163,65 +1163,114 @@
if ( !m )
return false;
- if (jobs.find(m->job_id) == jobs.end())
+ Job *j = 0;
+
+ if (m->exitcode == CLIENT_WAS_WAITING_FOR_CS)
+ {
+ // the daemon saw a cancel of what he believes is waiting in the scheduler
+ map::iterator mit;
+ for (mit = jobs.begin(); mit != jobs.end(); mit++)
+ {
+ Job *job = mit->second;
+ trace() << "looking for waitcs " << job->server << " " << job->submitter << " " << c << " "
+ << job->state << " " << job->local_client_id << " " << m->job_id << endl;
+ if (job->server == 0 && job->submitter == c && job->state == Job::PENDING
+ && job->local_client_id == m->job_id )
+ {
+ trace() << "STOP (WAITFORCS) FOR " << mit->first << endl;
+ j = job;
+ m->job_id = j->id; // that's faked
+
+ /* Unfortunately the toanswer queues are also tagged based on the daemon,
+ so we need to clean them up also. */
+ list::iterator it;
+ for (it = toanswer.begin(); it != toanswer.end(); ++it)
+ if ((*it)->server == c)
+ {
+ UnansweredList *l = *it;
+ list::iterator jit;
+ for (jit = l->l.begin(); jit != l->l.end(); ++jit)
+ {
+ if (*jit == j)
+ {
+ l->l.erase(jit);
+ break;
+ }
+ }
+ if (l->l.empty())
+ {
+ it = toanswer.erase (it);
+ break;
+ }
+ }
+ }
+ }
+ }
+ else
+ if (jobs.find(m->job_id) != jobs.end())
+ j = jobs[m->job_id];
+
+ if (!j)
{
trace() << "job ID not present " << m->job_id << endl;
return false;
}
- Job *j = jobs[m->job_id];
-
if ( m->exitcode == 0 )
{
std::ostream &dbg = trace();
dbg << "END " << m->job_id
- << " status=" << m->exitcode;
+ << " status=" << m->exitcode;
if ( m->in_uncompressed )
- dbg << " in=" << m->in_uncompressed
- << "(" << int( m->in_compressed * 100 / m->in_uncompressed ) << "%)";
+ dbg << " in=" << m->in_uncompressed
+ << "(" << int( m->in_compressed * 100 / m->in_uncompressed ) << "%)";
else
- dbg << " in=0(0%)";
+ dbg << " in=0(0%)";
if ( m->out_uncompressed )
- dbg << " out=" << m->out_uncompressed
- << "(" << int( m->out_compressed * 100 / m->out_uncompressed ) << "%)";
+ dbg << " out=" << m->out_uncompressed
+ << "(" << int( m->out_compressed * 100 / m->out_uncompressed ) << "%)";
else
- dbg << " out=0(0%)";
+ dbg << " out=0(0%)";
dbg << " real=" << m->real_msec
- << " user=" << m->user_msec
- << " sys=" << m->sys_msec
- << " pfaults=" << m->pfaults
- << " server=" << j->server->nodename
- << endl;
+ << " user=" << m->user_msec
+ << " sys=" << m->sys_msec
+ << " pfaults=" << m->pfaults
+ << " server=" << j->server->nodename
+ << endl;
}
else
trace() << "END " << m->job_id
- << " status=" << m->exitcode << endl;
+ << " status=" << m->exitcode << endl;
- if (m->is_from_server() && jobs[m->job_id]->server != c)
+ if (m->is_from_server() && j->server != c)
{
log_info() << "the server isn't the same for job " << m->job_id << endl;
- log_info() << "server: " << jobs[m->job_id]->server->nodename << endl;
+ log_info() << "server: " << j->server->nodename << endl;
log_info() << "msg came from: " << ((CS*)c)->nodename << endl;
// the daemon is not following matz's rules: kick him
handle_end(c, 0);
return false;
}
- if (!m->is_from_server() && jobs[m->job_id]->submitter != c)
+ if (!m->is_from_server() && j->submitter != c)
{
log_info() << "the submitter isn't the same for job " << m->job_id << endl;
- log_info() << "submitter: " << jobs[m->job_id]->submitter->nodename << endl;
+ log_info() << "submitter: " << j->submitter->nodename << endl;
log_info() << "msg came from: " << ((CS*)c)->nodename << endl;
// the daemon is not following matz's rules: kick him
handle_end(c, 0);
return false;
}
- j->server->joblist.remove (j);
+
+ if (j->server)
+ {
+ j->server->joblist.remove (j);
+ j->server->busy_installing = 0;
+ }
add_job_stats (j, m);
notify_monitors (MonJobDoneMsg (*m));
- j->server->busy_installing = 0;
jobs.erase (m->job_id);
done_jobs.erase (m->job_id);
delete j;
@@ -1246,7 +1295,6 @@
if (!m)
return false;
- c->last_talk = time( 0 );
CS *cs = dynamic_cast( c );
if ( cs && cs->max_jobs < 0 )
cs->max_jobs *= -1;
@@ -1263,9 +1311,8 @@
}
static bool
-handle_timeout (MsgChannel * c, Msg * /*_m*/)
+handle_timeout (MsgChannel * /*c*/, Msg * /*_m*/)
{
- c->last_talk = time( 0 );
return false;
}
++++++ icecream-manpages.tar.bz2 ++++++
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Remember to have fun...
---------------------------------------------------------------------
To unsubscribe, e-mail: opensuse-commit+unsubscribe@opensuse.org
For additional commands, e-mail: opensuse-commit+help@opensuse.org