diff --git a/checkin_notes b/checkin_notes index d16edf7589..48f3c67faf 100755 --- a/checkin_notes +++ b/checkin_notes @@ -4877,3 +4877,28 @@ Karl 2003/06/19 sched/ make_work.C + +Karl 2003/06/19 + - scheduler daemons: write pid to a pidfile. trap SIGINTs and exit on + the next check_stop_trigger() (the 'stop_server' file still works) + - wrote a kill_server program that kills specified daemons by sending + SIGINT to processes + - use kill_server in test scripts + + sched/ + kill_server (added) + Makefile.am + assimilator.C + feeder.C + file_deleter.C + make_work.C + sched_util.C + sched_util.h + timeout_check.C + update_stats.C + validate.C + test/ + .cvsignore + Makefile.am + boinc.py + version.py.in diff --git a/sched/assimilator.C b/sched/assimilator.C index 403ec8c169..41f28e0b60 100644 --- a/sched/assimilator.C +++ b/sched/assimilator.C @@ -1,19 +1,19 @@ // The contents of this file are subject to the Mozilla Public License // Version 1.0 (the "License"); you may not use this file except in // compliance with the License. You may obtain a copy of the License at -// http://www.mozilla.org/MPL/ -// +// http://www.mozilla.org/MPL/ +// // Software distributed under the License is distributed on an "AS IS" // basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the // License for the specific language governing rights and limitations -// under the License. -// -// The Original Code is the Berkeley Open Infrastructure for Network Computing. -// +// under the License. +// +// The Original Code is the Berkeley Open Infrastructure for Network Computing. +// // The Initial Developer of the Original Code is the SETI@home project. -// Portions created by the SETI@home project are Copyright (C) 2002 -// University of California at Berkeley. All Rights Reserved. -// +// Portions created by the SETI@home project are Copyright (C) 2002, 2003 +// University of California at Berkeley. All Rights Reserved. +// // Contributor(s): // @@ -30,7 +30,8 @@ #include "sched_util.h" #include "assimilate_handler.h" -#define ASSIMILATOR_LOCKFILE "assimilator.out" +#define LOCKFILE "assimilator.out" +#define PIDFILE "assimilator.pid" CONFIG config; @@ -148,10 +149,11 @@ int main(int argc, char** argv) { } // Call lock_file after fork(), because file locks are not always inherited - if (lock_file(ASSIMILATOR_LOCKFILE)) { + if (lock_file(LOCKFILE)) { write_log("Another copy of assimilator is already running\n", MSG_NORMAL); exit(1); } + write_pid_file(PIDFILE); retval = boinc_db_open(config.db_name, config.db_passwd); if (retval) { @@ -164,6 +166,7 @@ int main(int argc, char** argv) { write_log("Can't find app\n", MSG_CRITICAL); exit(1); } + install_sigint_handler(); if (one_pass) { do_pass(app); } else { diff --git a/sched/feeder.C b/sched/feeder.C index 15c1f96d6f..c0c2d7e2f9 100644 --- a/sched/feeder.C +++ b/sched/feeder.C @@ -1,19 +1,19 @@ // The contents of this file are subject to the Mozilla Public License // Version 1.0 (the "License"); you may not use this file except in // compliance with the License. You may obtain a copy of the License at -// http://www.mozilla.org/MPL/ -// +// http://www.mozilla.org/MPL/ +// // Software distributed under the License is distributed on an "AS IS" // basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the // License for the specific language governing rights and limitations -// under the License. -// -// The Original Code is the Berkeley Open Infrastructure for Network Computing. -// +// under the License. +// +// The Original Code is the Berkeley Open Infrastructure for Network Computing. +// // The Initial Developer of the Original Code is the SETI@home project. -// Portions created by the SETI@home project are Copyright (C) 2002 -// University of California at Berkeley. All Rights Reserved. -// +// Portions created by the SETI@home project are Copyright (C) 2002, 2003 +// University of California at Berkeley. All Rights Reserved. +// // Contributor(s): // @@ -62,19 +62,20 @@ #define RESULTS_PER_ENUM 100 #define REREAD_DB_FILENAME "reread_db" #define LOCKFILE "feeder.out" +#define PIDFILE "feeder.pid" CONFIG config; -int check_triggers(SCHED_SHMEM* ssp) { - FILE* f; +SCHED_SHMEM* ssp; - f = fopen(STOP_TRIGGER_FILENAME, "r"); - if (f) { - fclose(f); - detach_shmem((void*)ssp); - destroy_shmem(config.shmem_key); - exit(0); - } +void cleanup_shmem() +{ + detach_shmem((void*)ssp); + destroy_shmem(config.shmem_key); +} + +int check_reread_trigger() { + FILE* f; f = fopen(REREAD_DB_FILENAME, "r"); if (f) { fclose(f); @@ -102,7 +103,7 @@ int check_triggers(SCHED_SHMEM* ssp) { // Crude approach: if a "collision" (as above) occurred on // a pass through the array, wait a long time (5 sec) // -void feeder_loop(SCHED_SHMEM* ssp) { +void feeder_loop() { int i, j, nadditions, ncollisions, retval; DB_RESULT result; DB_WORKUNIT wu; @@ -202,12 +203,12 @@ try_again: sleep(5); } fflush(stdout); - check_triggers(ssp); + check_stop_trigger(); + check_reread_trigger(); } } int main(int argc, char** argv) { - SCHED_SHMEM* ssp; int i, retval; bool asynch = false; void* p; @@ -240,6 +241,7 @@ int main(int argc, char** argv) { write_log("Another copy of feeder is already running\n", MSG_NORMAL); exit(1); } + write_pid_file(PIDFILE); retval = destroy_shmem(config.shmem_key); if (retval) { @@ -253,6 +255,10 @@ int main(int argc, char** argv) { } ssp = (SCHED_SHMEM*)p; ssp->init(); + + atexit(cleanup_shmem); + install_sigint_handler(); + retval = boinc_db_open(config.db_name, config.db_passwd); if (retval) { sprintf(buf, "boinc_db_open: %d\n", retval); @@ -271,5 +277,5 @@ int main(int argc, char** argv) { ssp->napp_versions ); - feeder_loop(ssp); + feeder_loop(); } diff --git a/sched/file_deleter.C b/sched/file_deleter.C index 540cf374a7..fdbc2f49a0 100644 --- a/sched/file_deleter.C +++ b/sched/file_deleter.C @@ -1,19 +1,19 @@ // The contents of this file are subject to the Mozilla Public License // Version 1.0 (the "License"); you may not use this file except in // compliance with the License. You may obtain a copy of the License at -// http://www.mozilla.org/MPL/ -// +// http://www.mozilla.org/MPL/ +// // Software distributed under the License is distributed on an "AS IS" // basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the // License for the specific language governing rights and limitations -// under the License. -// -// The Original Code is the Berkeley Open Infrastructure for Network Computing. -// +// under the License. +// +// The Original Code is the Berkeley Open Infrastructure for Network Computing. +// // The Initial Developer of the Original Code is the SETI@home project. -// Portions created by the SETI@home project are Copyright (C) 2002 -// University of California at Berkeley. All Rights Reserved. -// +// Portions created by the SETI@home project are Copyright (C) 2002, 2003 +// University of California at Berkeley. All Rights Reserved. +// // Contributor(s): // @@ -32,6 +32,7 @@ #include "sched_util.h" #define LOCKFILE "file_deleter.out" +#define PIDFILE "file_deleter.pid" CONFIG config; @@ -156,12 +157,14 @@ int main(int argc, char** argv) { write_log("Another copy of file deleter is running\n", MSG_NORMAL); exit(1); } + write_pid_file(PIDFILE); retval = boinc_db_open(config.db_name, config.db_passwd); if (retval) { write_log("can't open DB\n", MSG_CRITICAL); exit(1); } + install_sigint_handler(); if (one_pass) { do_pass(); } else { diff --git a/sched/make_work.C b/sched/make_work.C index 3d91b155cc..91973d1236 100644 --- a/sched/make_work.C +++ b/sched/make_work.C @@ -43,6 +43,7 @@ #include "sched_util.h" #define LOCKFILE "make_work.out" +#define PIDFILE "make_work.pid" int cushion = 10; int redundancy = 10; @@ -130,6 +131,8 @@ void make_work() { } nresults_left = 0; while (1) { + check_stop_trigger(); + sprintf(buf, "where server_state=%d", RESULT_SERVER_STATE_UNSENT); retval = result.count(n, buf); if (retval) { @@ -137,7 +140,6 @@ void make_work() { exit(1); } if (n > cushion) { - check_stop_trigger(); sleep(1); continue; } @@ -193,7 +195,6 @@ void make_work() { sprintf(buf, "added result: %s_%s\n", wu.name, suffix); write_log(buf, MSG_DEBUG); nresults_left--; - check_stop_trigger(); } } @@ -238,6 +239,8 @@ int main(int argc, char** argv) { write_log("Another copy of make_work is already running\n", MSG_NORMAL); exit(1); } + write_pid_file(PIDFILE); + install_sigint_handler(); srand48(getpid() + time(0)); make_work(); diff --git a/sched/sched_util.C b/sched/sched_util.C index be6fa434df..74def21c7e 100644 --- a/sched/sched_util.C +++ b/sched/sched_util.C @@ -1,25 +1,26 @@ // The contents of this file are subject to the Mozilla Public License // Version 1.0 (the "License"); you may not use this file except in // compliance with the License. You may obtain a copy of the License at -// http://www.mozilla.org/MPL/ -// +// http://www.mozilla.org/MPL/ +// // Software distributed under the License is distributed on an "AS IS" // basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the // License for the specific language governing rights and limitations -// under the License. -// -// The Original Code is the Berkeley Open Infrastructure for Network Computing. -// +// under the License. +// +// The Original Code is the Berkeley Open Infrastructure for Network Computing. +// // The Initial Developer of the Original Code is the SETI@home project. -// Portions created by the SETI@home project are Copyright (C) 2002 -// University of California at Berkeley. All Rights Reserved. -// +// Portions created by the SETI@home project are Copyright (C) 2002, 2003 +// University of California at Berkeley. All Rights Reserved. +// // Contributor(s): // using namespace std; #include +#include #include "parse.h" #include "util.h" @@ -34,16 +35,48 @@ void write_log(char* p, int msg_level) { fprintf(stderr, "%s: %s", timestamp(), p); } +void write_pid_file(const char* filename) +{ + FILE* fpid = fopen(filename, "w"); + if (!fpid) { + write_log("Couldn't write pid\n", MSG_NORMAL); + return; + } + fprintf(fpid, "%d\n", getpid()); + fclose(fpid); +} + void set_debug_level(int new_level) { debug_level = new_level; } -void check_stop_trigger() { - FILE* f = fopen(STOP_TRIGGER_FILENAME, "r"); - if (!f) return; - exit(0); +// sig_int will be set to true if SIGINT is caught. +bool sig_int = false; +static void sigint_handler(int) +{ + fprintf(stderr, "SIGINT\n"); + sig_int = true; } +void install_sigint_handler() +{ + signal(SIGINT, sigint_handler); + // SIGINT is now default again so hitting ^C again will kill the program. +} + +void check_stop_trigger() { + if (sig_int) { + write_log("Quitting due to SIGINT\n", MSG_CRITICAL); + exit(0); + } + FILE* f = fopen(STOP_TRIGGER_FILENAME, "r"); + if (f) { + write_log("Quitting due to stop trigger\n", MSG_NORMAL); + exit(0); + } +} + + // update an exponential average of credit per second. // void update_average(double credit_assigned_time, double credit, double& avg, double& avg_time) { diff --git a/sched/sched_util.h b/sched/sched_util.h index 7a05e43b40..89e0954554 100644 --- a/sched/sched_util.h +++ b/sched/sched_util.h @@ -1,19 +1,19 @@ // The contents of this file are subject to the Mozilla Public License // Version 1.0 (the "License"); you may not use this file except in // compliance with the License. You may obtain a copy of the License at -// http://www.mozilla.org/MPL/ -// +// http://www.mozilla.org/MPL/ +// // Software distributed under the License is distributed on an "AS IS" // basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the // License for the specific language governing rights and limitations -// under the License. -// -// The Original Code is the Berkeley Open Infrastructure for Network Computing. -// +// under the License. +// +// The Original Code is the Berkeley Open Infrastructure for Network Computing. +// // The Initial Developer of the Original Code is the SETI@home project. -// Portions created by the SETI@home project are Copyright (C) 2002 -// University of California at Berkeley. All Rights Reserved. -// +// Portions created by the SETI@home project are Copyright (C) 2002, 2003 +// University of California at Berkeley. All Rights Reserved. +// // Contributor(s): // @@ -44,9 +44,12 @@ #define MSG_DEBUG 2 extern void write_log(char*, int); +extern void write_pid_file(const char* filename); extern void set_debug_level(int); extern void check_stop_trigger(); extern void update_average(double, double, double&, double&); +extern void install_sigint_handler(); +extern bool sig_int; #endif diff --git a/sched/update_stats.C b/sched/update_stats.C index 185b8757e6..c8126d6dfb 100644 --- a/sched/update_stats.C +++ b/sched/update_stats.C @@ -1,19 +1,19 @@ // The contents of this file are subject to the Mozilla Public License // Version 1.0 (the "License"); you may not use this file except in // compliance with the License. You may obtain a copy of the License at -// http://www.mozilla.org/MPL/ -// +// http://www.mozilla.org/MPL/ +// // Software distributed under the License is distributed on an "AS IS" // basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the // License for the specific language governing rights and limitations -// under the License. -// -// The Original Code is the Berkeley Open Infrastructure for Network Computing. -// +// under the License. +// +// The Original Code is the Berkeley Open Infrastructure for Network Computing. +// // The Initial Developer of the Original Code is the SETI@home project. -// Portions created by the SETI@home project are Copyright (C) 2002 -// University of California at Berkeley. All Rights Reserved. -// +// Portions created by the SETI@home project are Copyright (C) 2002, 2003 +// University of California at Berkeley. All Rights Reserved. +// // Contributor(s): // @@ -33,6 +33,7 @@ #include "sched_util.h" #define LOCKFILE "update_stats.out" +#define PIDFILE "update_stats.pid" int update_users() { DB_USER user; @@ -143,6 +144,7 @@ int main(int argc, char** argv) { write_log("Another copy of update_stats is already running\n", MSG_NORMAL); exit(1); } + write_pid_file(PIDFILE); retval = config.parse_file(); if (retval) { diff --git a/sched/validate.C b/sched/validate.C index ff435cdcb0..adea9f4a43 100644 --- a/sched/validate.C +++ b/sched/validate.C @@ -1,19 +1,19 @@ // The contents of this file are subject to the Mozilla Public License // Version 1.0 (the "License"); you may not use this file except in // compliance with the License. You may obtain a copy of the License at -// http://www.mozilla.org/MPL/ -// +// http://www.mozilla.org/MPL/ +// // Software distributed under the License is distributed on an "AS IS" // basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the // License for the specific language governing rights and limitations -// under the License. -// -// The Original Code is the Berkeley Open Infrastructure for Network Computing. -// +// under the License. +// +// The Original Code is the Berkeley Open Infrastructure for Network Computing. +// // The Initial Developer of the Original Code is the SETI@home project. -// Portions created by the SETI@home project are Copyright (C) 2002 -// University of California at Berkeley. All Rights Reserved. -// +// Portions created by the SETI@home project are Copyright (C) 2002, 2003 +// University of California at Berkeley. All Rights Reserved. +// // Contributor(s): @@ -51,6 +51,7 @@ using namespace std; #include "sched_util.h" #define LOCKFILE "validate.out" +#define PIDFILE "validate.pid" extern int check_set(vector&, int& canonical, double& credit); extern int check_pair(RESULT&, RESULT&, bool&); @@ -113,7 +114,7 @@ void handle_wu(DB_WORKUNIT& wu) { // sprintf(buf, "where workunitid=%d", wu.id); while (!result.enumerate(buf)) { - if (result.validate_state == VALIDATE_STATE_INIT + if (result.validate_state == VALIDATE_STATE_INIT && result.server_state == RESULT_SERVER_STATE_OVER && result.outcome == RESULT_OUTCOME_SUCCESS ) { @@ -329,6 +330,8 @@ int main(int argc, char** argv) { fprintf(stderr, "Another copy of validate is already running\n"); exit(1); } + write_pid_file(PIDFILE); + install_sigint_handler(); main_loop(one_pass); } diff --git a/test/Makefile.am b/test/Makefile.am index 78fa985bb8..1e6816df4c 100644 --- a/test/Makefile.am +++ b/test/Makefile.am @@ -2,19 +2,28 @@ include $(top_srcdir)/Makefile.incl -TESTS = test_sanity.php \ - test_uc.php \ - test_concat.php \ - test_1sec.php \ - test_rsc.php \ - test_backend.php +# TESTS = test_sanity.php \ +# test_uc.php \ +# test_concat.php \ +# test_1sec.php \ +# test_rsc.php \ +# test_backend.php -# test_sticky.php +TESTS = test_sanity.py \ + test_uc.py \ + test_concat.py \ + test_1sec.py \ + test_backend.py EXTRA_DIST = \ - *.xml *.php *wu *result *output \ - *input *.inc *.py *.in \ - db_def_to_php db_def_to_py + *.xml *.php *wu *result *output *input + +# TODO: phase out php stuff +noinst_SCRIPTS = \ + db_def_to_php db_def_to_py \ + *.php version.inc.in boinc.py test_*.py version.py.in + +BUILT_SOURCES = boinc_db.inc boinc_db.py boinc_db.inc: ../db/boinc_db.h ./db_def_to_php < ../db/boinc_db.h > boinc_db.inc diff --git a/test/Makefile.in b/test/Makefile.in index b1adaae119..845bbaef97 100644 --- a/test/Makefile.in +++ b/test/Makefile.in @@ -170,30 +170,43 @@ AM_CPPFLAGS = \ # programs linking to it: LIBRSA = $(top_builddir)/RSAEuro/source/librsaeuro.a -TESTS = test_sanity.php \ - test_uc.php \ - test_concat.php \ - test_1sec.php \ - test_rsc.php \ - test_backend.php + +# TESTS = test_sanity.php \ +# test_uc.php \ +# test_concat.php \ +# test_1sec.php \ +# test_rsc.php \ +# test_backend.php +TESTS = test_sanity.py \ + test_uc.py \ + test_concat.py \ + test_1sec.py \ + test_backend.py - -# test_sticky.php EXTRA_DIST = \ - *.xml *.php *wu *result *output \ - *input *.inc *.py *.in \ - db_def_to_php db_def_to_py + *.xml *.php *wu *result *output *input + +# TODO: phase out php stuff +noinst_SCRIPTS = \ + db_def_to_php db_def_to_py \ + *.php version.inc.in boinc.py test_*.py version.py.in + + +BUILT_SOURCES = boinc_db.inc boinc_db.py subdir = test ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs CONFIG_HEADER = $(top_builddir)/config.h CONFIG_CLEAN_FILES = version.inc version.py +SCRIPTS = $(noinst_SCRIPTS) + DIST_SOURCES = DIST_COMMON = $(top_srcdir)/Makefile.incl Makefile.am Makefile.in \ version.inc.in version.py.in -all: all-am +all: $(BUILT_SOURCES) + $(MAKE) $(AM_MAKEFLAGS) all-am .SUFFIXES: $(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ Makefile.am $(top_srcdir)/Makefile.incl $(top_srcdir)/configure.ac $(ACLOCAL_M4) @@ -320,11 +333,13 @@ distdir: $(DISTFILES) done check-am: all-am $(MAKE) $(AM_MAKEFLAGS) check-TESTS -check: check-am -all-am: Makefile +check: $(BUILT_SOURCES) + $(MAKE) $(AM_MAKEFLAGS) check-am +all-am: Makefile $(SCRIPTS) installdirs: -install: install-am +install: $(BUILT_SOURCES) + $(MAKE) $(AM_MAKEFLAGS) install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am @@ -348,6 +363,7 @@ distclean-generic: maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." + -test -z "$(BUILT_SOURCES)" || rm -f $(BUILT_SOURCES) clean: clean-am clean-am: clean-generic mostlyclean-am diff --git a/test/boinc.py b/test/boinc.py index 71cdc29b63..3555efe9c1 100644 --- a/test/boinc.py +++ b/test/boinc.py @@ -368,7 +368,7 @@ class Project: map(lambda (s): self.copy(os.path.join('sched', s), 'cgi/'), [ 'cgi', 'file_upload_handler', 'make_work', 'feeder', 'timeout_check', 'validate_test', - 'file_deleter', 'assimilator', 'start_servers' ]) + 'file_deleter', 'assimilator', 'start_servers', 'kill_server' ]) verbose_echo(1, "Setting up database") map(self.run_db_script, [ 'drop.sql', 'schema.sql', 'constraints.sql' ]) @@ -582,15 +582,16 @@ class Project: self._run_cgi_prog('looper' , '"dir_size ../download" 1' , 'download_size') self._run_cgi_prog('looper' , '"dir_size ../upload" 1' , 'upload_size') - def stop(self, sleep=7): - '''Stop the feeder and other daemons''' - ## TODO: have the daemons write pid to a file so we can kill them that way. + def stop(self, daemons=['ALL']): + '''Stop running scheduler daemons.''' + ## the following shouldn't be necessary anymore: f = open(self.dir('cgi', 'stop_server'), 'w') print >>f, "" f.close() - # need to sleep because the feeder sleeps (up to 5+5+1) seconds to - # check triggers. - verbose_sleep("Stopping server(s) for project '%s'" % self.short_name, sleep) + + daemons = ' '.join(daemons) + verbose_echo(1,"Stopping server(s) for project '%s': "%self.short_name) + shell_call("cd %s ; ./kill_server -v %s" % (self.dir('cgi'), daemons)) def restart(self): '''remove the stop_server trigger''' diff --git a/test/boinc_db.py b/test/boinc_db.py index 71e4b2c955..46a45312a8 100644 --- a/test/boinc_db.py +++ b/test/boinc_db.py @@ -1,4 +1,4 @@ -# Generated by db_def_to_py on Tue Jun 17 20:03:34 PDT 2003 +# Generated by db_def_to_py on Wed Jun 18 19:09:35 PDT 2003 MAX_BLOB_SIZE = 4096 TEAM_TYPE_CLUB = 1 TEAM_TYPE_COMPANY = 2 diff --git a/test/version.py.in b/test/version.py.in index 2a02e525ec..7227f99b23 100644 --- a/test/version.py.in +++ b/test/version.py.in @@ -1,8 +1,6 @@ ## $Id$ -# version.inc.in - -# defines version numbers using autoconf +# define version numbers using autoconf MAJOR_VERSION = @MAJOR_VERSION@ MINOR_VERSION = @MINOR_VERSION@ CLIENT_BIN_FILENAME = "@CLIENT_BIN_FILENAME@"