From aca1aead5f3fa531ad7a5ff4704f0a751cf936bd Mon Sep 17 00:00:00 2001 From: David Anderson Date: Tue, 17 Jun 2014 16:02:59 -0700 Subject: [PATCH] server: shuffle code so that the file upload handler doesn't need MySQL Also (client): remove notices about app_config.xml after problem is fixed --- Makefile.incl | 1 + client/cs_notice.cpp | 3 + client/cs_notice.h | 2 + client/cs_statefile.cpp | 5 +- client/log_flags.cpp | 6 +- html/user/top_hosts.php | 2 +- sched/Makefile.am | 5 +- sched/sched_util.cpp | 287 +--------------------------------- sched/sched_util.h | 58 +------ sched/sched_util_basic.cpp | 304 +++++++++++++++++++++++++++++++++++++ sched/sched_util_basic.h | 74 +++++++++ 11 files changed, 402 insertions(+), 345 deletions(-) create mode 100644 sched/sched_util_basic.cpp create mode 100644 sched/sched_util_basic.h diff --git a/Makefile.incl b/Makefile.incl index 6c4cca6f13..582e5b8de8 100644 --- a/Makefile.incl +++ b/Makefile.incl @@ -63,4 +63,5 @@ $(LIBAPI): SERVERLIBS = $(LIBSCHED) $(LIBBOINC_CRYPT) $(LIBBOINC) $(MYSQL_LIBS) $(PTHREAD_LIBS) $(RSA_LIBS) $(SSL_LIBS) SERVERLIBS_FCGI = $(LIBSCHED_FCGI) $(LIBBOINC_CRYPT) $(LIBBOINC_FCGI) -lfcgi $(MYSQL_LIBS) $(PTHREAD_LIBS) $(RSA_LIBS) $(SSL_LIBS) APPLIBS = $(LIBAPI) $(LIBBOINC) +FUHLIBS = $(LIBBOINC_CRYPT) $(LIBBOINC) $(RSA_LIBS) $(SSL_LIBS) diff --git a/client/cs_notice.cpp b/client/cs_notice.cpp index 226cc5aa01..ff1cb34b24 100644 --- a/client/cs_notice.cpp +++ b/client/cs_notice.cpp @@ -506,6 +506,9 @@ void NOTICES::remove_notices(PROJECT* p, int which) { case REMOVE_CONFIG_MSG: remove = (strstr(n.description.c_str(), "cc_config.xml") != NULL); break; + case REMOVE_APP_INFO_MSG: + remove = (strstr(n.description.c_str(), "app_info.xml") != NULL); + break; } if (remove) { i = notices.erase(i); diff --git a/client/cs_notice.h b/client/cs_notice.h index 01293e30b5..1ba59e8576 100644 --- a/client/cs_notice.h +++ b/client/cs_notice.h @@ -92,6 +92,8 @@ struct NOTICES { // msgs about no work due to settings #define REMOVE_CONFIG_MSG 3 // notices about cc_config.xml +#define REMOVE_APP_INFO_MSG 4 + // notices about project/app_info.xml extern NOTICES notices; diff --git a/client/cs_statefile.cpp b/client/cs_statefile.cpp index a353d194dd..34e3737f41 100644 --- a/client/cs_statefile.cpp +++ b/client/cs_statefile.cpp @@ -841,7 +841,10 @@ int CLIENT_STATE::parse_app_info(PROJECT* p, FILE* in) { while (!xp.get_tag()) { if (xp.match_tag("app_info")) continue; - if (xp.match_tag("/app_info")) return 0; + if (xp.match_tag("/app_info")) { + notices.remove_notices(p, REMOVE_APP_INFO_MSG); + return 0; + } if (xp.match_tag("file_info") || xp.match_tag("file")) { FILE_INFO* fip = new FILE_INFO; if (fip->parse(xp)) { diff --git a/client/log_flags.cpp b/client/log_flags.cpp index 321ed8a4dd..433c07d66d 100644 --- a/client/log_flags.cpp +++ b/client/log_flags.cpp @@ -564,7 +564,7 @@ void process_gpu_exclusions() { p = gstate.lookup_project(eg.url.c_str()); if (!p) { msg_printf(0, MSG_USER_ALERT, - "Bad URL in GPU exclusion: %s", eg.url.c_str() + "cc_config.xml: bad URL in GPU exclusion: %s", eg.url.c_str() ); continue; } @@ -572,7 +572,7 @@ void process_gpu_exclusions() { APP* app = gstate.lookup_app(p, eg.appname.c_str()); if (!app) { msg_printf(p, MSG_USER_ALERT, - "A GPU exclusion in your cc_config.xml file refers to an unknown application '%s'. Known applications: %s", + "cc_config.xml: a GPU exclusion refers to an unknown application '%s'. Known applications: %s", eg.appname.c_str(), app_list_string(p).c_str() ); @@ -593,7 +593,7 @@ void process_gpu_exclusions() { } if (!found) { msg_printf(p, MSG_USER_ALERT, - "Bad type '%s' in GPU exclusion; valid types:%s", + "cc_config.xml: bad type '%s' in GPU exclusion; valid types:%s", eg.type.c_str(), types.c_str() ); continue; diff --git a/html/user/top_hosts.php b/html/user/top_hosts.php index 5450f2b60b..aef32bcc68 100644 --- a/html/user/top_hosts.php +++ b/html/user/top_hosts.php @@ -84,7 +84,7 @@ top_host_table_start($sort_by); $i = 1 + $offset; $n = sizeof($data); foreach($data as $host) { - show_host_row($host, $i, false, true); + show_host_row($host, $i, false, true, false); $i++; } echo "\n

"; diff --git a/sched/Makefile.am b/sched/Makefile.am index 0142a326cb..c023eb226f 100644 --- a/sched/Makefile.am +++ b/sched/Makefile.am @@ -12,6 +12,7 @@ libsched_sources = \ credit.cpp \ sched_shmem.cpp \ sched_util.cpp \ + sched_util_basic.cpp \ sched_config.cpp \ sched_limit.cpp \ sched_msgs.cpp \ @@ -266,8 +267,8 @@ trickle_echo_LDADD = $(SERVERLIBS) update_stats_SOURCES = update_stats.cpp update_stats_LDADD = $(SERVERLIBS) -file_upload_handler_SOURCES = file_upload_handler.cpp -file_upload_handler_LDADD = $(SERVERLIBS) +file_upload_handler_SOURCES = file_upload_handler.cpp sched_msgs.cpp sched_config.cpp sched_util_basic.cpp sched_limit.cpp +file_upload_handler_LDADD = $(FUHLIBS) make_work_SOURCES = make_work.cpp make_work_LDADD = $(SERVERLIBS) diff --git a/sched/sched_util.cpp b/sched/sched_util.cpp index 309b21b224..38dc8e06a2 100644 --- a/sched/sched_util.cpp +++ b/sched/sched_util.cpp @@ -1,6 +1,6 @@ // This file is part of BOINC. // http://boinc.berkeley.edu -// Copyright (C) 2008 University of California +// Copyright (C) 2014 University of California // // BOINC is free software; you can redistribute it and/or modify it // under the terms of the GNU Lesser General Public License @@ -15,205 +15,11 @@ // You should have received a copy of the GNU Lesser General Public License // along with BOINC. If not, see . -// Utility functions for server software (not just scheduler) - #include "config.h" -#include -#include -#include -#include -#include -#include -#include -#include "error_numbers.h" -#include "filesys.h" -#include "md5_file.h" -#include "util.h" - -#include "sched_config.h" -#include "sched_msgs.h" +#include "boinc_db.h" #include "sched_util.h" -#ifdef _USING_FCGI_ -#include "boinc_fcgi.h" -#endif - -const char* STOP_DAEMONS_FILENAME = "stop_daemons"; - // NOTE: this must be same as in the "start" script -const char* STOP_SCHED_FILENAME = "stop_sched"; - // NOTE: this must be same as in the "start" script -const int STOP_SIGNAL = SIGHUP; - // NOTE: this must be same as in the "start" script - -void write_pid_file(const char* filename) { -#ifndef _USING_FCGI_ - FILE* fpid = fopen(filename, "w"); -#else - FCGI_FILE* fpid = FCGI::fopen(filename,"w"); -#endif - - if (!fpid) { - log_messages.printf(MSG_CRITICAL, "Couldn't write pid file\n"); - return; - } - fprintf(fpid, "%d\n", (int)getpid()); - fclose(fpid); -} - -// caught_sig_int will be set to true if STOP_SIGNAL (normally SIGHUP) -// is caught. -bool caught_stop_signal = false; -static void stop_signal_handler(int) { - fprintf(stderr, "GOT STOP SIGNAL\n"); - caught_stop_signal = true; -} - -void install_stop_signal_handler() { - signal(STOP_SIGNAL, stop_signal_handler); - // handler is now default again so hitting ^C again will kill the program. -} - -void check_stop_daemons() { - if (caught_stop_signal) { - log_messages.printf(MSG_NORMAL, "Quitting due to SIGHUP\n"); - exit(0); - } - const char *stop_file = config.project_path(STOP_DAEMONS_FILENAME); - if (boinc_file_exists(stop_file)) { - log_messages.printf(MSG_NORMAL, - "Quitting because trigger file '%s' is present\n", - stop_file - ); - exit(0); - } -} - -// sleep for n seconds, but check every second for trigger file -// -void daemon_sleep(int nsecs) { - for (int i=0; i0) if another process has lock -// -1 if error -// -int mylockf(int fd) { - struct flock fl; - fl.l_type=F_WRLCK; - fl.l_whence=SEEK_SET; - fl.l_start=0; - fl.l_len=0; - if (-1 != fcntl(fd, F_SETLK, &fl)) return 0; - - // if lock failed, find out why - errno=0; - fcntl(fd, F_GETLK, &fl); - if (fl.l_pid>0) return fl.l_pid; - return -1; -} - int count_results(char* query, int& n) { DB_RESULT result; return result.count(n, query); @@ -287,35 +73,6 @@ int count_unsent_results(int& n, int appid, int size_class) { return count_results(query, n); } -bool is_arg(const char* x, const char* y) { - char buf[256]; - strcpy(buf, "--"); - strcat(buf, y); - if (!strcmp(buf, x)) return true; - if (!strcmp(buf+1, x)) return true; - return false; -} - -// the following is used, among other things, -// to enforce limits on in-progress jobs -// for GPUs and CPUs (see handle_request.cpp) -// -int plan_class_to_proc_type(const char* plan_class) { - if (strstr(plan_class, "cuda")) { - return PROC_TYPE_NVIDIA_GPU; - } - if (strstr(plan_class, "nvidia")) { - return PROC_TYPE_NVIDIA_GPU; - } - if (strstr(plan_class, "ati")) { - return PROC_TYPE_AMD_GPU; - } - if (strstr(plan_class, "intel_gpu")) { - return PROC_TYPE_INTEL_GPU; - } - return PROC_TYPE_CPU; -} - // Arrange that further results for this workunit // will be sent only to hosts with the given user ID. // This could be used, for example, so that late workunits @@ -367,43 +124,3 @@ int restrict_wu_to_user(WORKUNIT& _wu, int userid) { int min_transition_time(double& x) { return boinc_db.get_double("select min(transition_time) from workunit", x); } - -#ifdef GCL_SIMULATOR - -void simulator_signal_handler(int signum) { - FILE *fsim; - char currenttime[64]; - fsim = fopen(config.project_path("simulator/sim_time.txt"),"r"); - if(fsim){ - fscanf(fsim,"%s", currenttime); - simtime = atof(currenttime); - fclose(fsim); - } - log_messages.printf(MSG_NORMAL, - "Invoked by the simulator at time %.0f... \n", simtime - ); -} - -int itime() { - return (int) simtime; -} - -void continue_simulation(const char *daemonname){ - char daemonfilelok[64]; - char daemonfile[64]; - sprintf(daemonfile, strcat((char*)config.project_path("simulator/"),"sim_%s.txt"),daemonname); - sprintf(daemonfilelok, strcat((char*)config.project_path("simulator/"),"sim_%s.lok"),daemonname); - FILE *fsimlok = fopen(daemonfilelok, "w"); - if (fsimlok){ - fclose(fsimlok); - FILE *fsim = fopen(daemonfile, "w"); - if (fsim) { - fclose(fsim); - } - } - remove(daemonfilelok); -} - -#endif - -const char *BOINC_RCSID_affa6ef1e4 = "$Id$"; diff --git a/sched/sched_util.h b/sched/sched_util.h index 28b4f0dfae..e47f9341f9 100644 --- a/sched/sched_util.h +++ b/sched/sched_util.h @@ -1,6 +1,6 @@ // This file is part of BOINC. // http://boinc.berkeley.edu -// Copyright (C) 2008 University of California +// Copyright (C) 2014 University of California // // BOINC is free software; you can redistribute it and/or modify it // under the terms of the GNU Lesser General Public License @@ -15,7 +15,7 @@ // You should have received a copy of the GNU Lesser General Public License // along with BOINC. If not, see . -// general back-end utility functions (not scheduler-specific) +// server utility functions that refer to the DB #ifndef SCHED_UTIL_H #define SCHED_UTIL_H @@ -23,36 +23,7 @@ #include "boinc_db_types.h" #include "util.h" -// "average credit" uses an exponential decay so that recent -// activity is weighted more heavily. -// CREDIT_HALF_LIFE is the "half-life" period: -// the average decreases by 1/2 if idle for this period. -// -#define SECONDS_IN_DAY (3600*24) -#define CREDIT_HALF_LIFE (SECONDS_IN_DAY*7) - -extern void write_pid_file(const char* filename); -extern void set_debug_level(int); -extern void check_stop_daemons(); -extern void daemon_sleep(int); -extern bool check_stop_sched(); -extern void install_stop_signal_handler(); -extern int try_fopen(const char* path, FILE*& f, const char* mode); -extern void get_log_path(char*, const char*); - -// convert filename to path in a hierarchical directory system -// -extern int dir_hier_path( - const char* filename, const char* root, int fanout, - char* result, bool create=false -); - -// convert filename to URL in a hierarchical directory system -// -extern int dir_hier_url( - const char* filename, const char* root, int fanout, - char* result -); +#include "sched_util_basic.h" extern void compute_avg_turnaround(HOST& host, double turnaround); @@ -65,15 +36,6 @@ struct PERF_INFO { int get_from_db(); }; -// returns zero if we get lock on file with file descriptor fd. -// returns < 0 if error -// returns PID > 0 if another process has lock -// -extern int mylockf(int fd); - -extern int count_workunits(int&, const char* query); -extern int count_unsent_results(int&, int appid, int size_class=-1); - // Return a value for host_app_version.app_version_id. // if the app version is anonymous platform, // make a "pseudo ID" that combines the app ID and the resource type @@ -86,19 +48,9 @@ inline int generalized_app_version_id(int avid, int appid) { return avid; } -// return true if x is -y or --y (for argv processing) -// -extern bool is_arg(const char*, const char*); - -extern int plan_class_to_proc_type(const char* plan_class); - +extern int count_workunits(int&, const char* query); +extern int count_unsent_results(int&, int appid, int size_class=-1); extern int restrict_wu_to_user(WORKUNIT& wu, int userid); - extern int min_transition_time(double&); -#ifdef GCL_SIMULATOR -extern void simulator_signal_handler(int signum); -extern void continue_simulation(const char *daemonname); -#endif - #endif diff --git a/sched/sched_util_basic.cpp b/sched/sched_util_basic.cpp new file mode 100644 index 0000000000..9b20b57022 --- /dev/null +++ b/sched/sched_util_basic.cpp @@ -0,0 +1,304 @@ +// This file is part of BOINC. +// http://boinc.berkeley.edu +// Copyright (C) 2008 University of California +// +// BOINC is free software; you can redistribute it and/or modify it +// under the terms of the GNU Lesser General Public License +// as published by the Free Software Foundation, +// either version 3 of the License, or (at your option) any later version. +// +// BOINC is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +// See the GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with BOINC. If not, see . + +// Utility functions for server software (not just scheduler) + +#include "config.h" +#include +#include +#include +#include +#include +#include +#include + +#include "error_numbers.h" +#include "filesys.h" +#include "md5_file.h" +#include "util.h" + +#include "sched_config.h" +#include "sched_msgs.h" +#include "sched_util.h" + +#ifdef _USING_FCGI_ +#include "boinc_fcgi.h" +#endif + +const char* STOP_DAEMONS_FILENAME = "stop_daemons"; + // NOTE: this must be same as in the "start" script +const char* STOP_SCHED_FILENAME = "stop_sched"; + // NOTE: this must be same as in the "start" script +const int STOP_SIGNAL = SIGHUP; + // NOTE: this must be same as in the "start" script + +void write_pid_file(const char* filename) { +#ifndef _USING_FCGI_ + FILE* fpid = fopen(filename, "w"); +#else + FCGI_FILE* fpid = FCGI::fopen(filename,"w"); +#endif + + if (!fpid) { + log_messages.printf(MSG_CRITICAL, "Couldn't write pid file\n"); + return; + } + fprintf(fpid, "%d\n", (int)getpid()); + fclose(fpid); +} + +// caught_sig_int will be set to true if STOP_SIGNAL (normally SIGHUP) +// is caught. +bool caught_stop_signal = false; +static void stop_signal_handler(int) { + fprintf(stderr, "GOT STOP SIGNAL\n"); + caught_stop_signal = true; +} + +void install_stop_signal_handler() { + signal(STOP_SIGNAL, stop_signal_handler); + // handler is now default again so hitting ^C again will kill the program. +} + +void check_stop_daemons() { + if (caught_stop_signal) { + log_messages.printf(MSG_NORMAL, "Quitting due to SIGHUP\n"); + exit(0); + } + const char *stop_file = config.project_path(STOP_DAEMONS_FILENAME); + if (boinc_file_exists(stop_file)) { + log_messages.printf(MSG_NORMAL, + "Quitting because trigger file '%s' is present\n", + stop_file + ); + exit(0); + } +} + +// sleep for n seconds, but check every second for trigger file +// +void daemon_sleep(int nsecs) { + for (int i=0; i0) if another process has lock +// -1 if error +// +int mylockf(int fd) { + struct flock fl; + fl.l_type=F_WRLCK; + fl.l_whence=SEEK_SET; + fl.l_start=0; + fl.l_len=0; + if (-1 != fcntl(fd, F_SETLK, &fl)) return 0; + + // if lock failed, find out why + errno=0; + fcntl(fd, F_GETLK, &fl); + if (fl.l_pid>0) return fl.l_pid; + return -1; +} + +bool is_arg(const char* x, const char* y) { + char buf[256]; + strcpy(buf, "--"); + strcat(buf, y); + if (!strcmp(buf, x)) return true; + if (!strcmp(buf+1, x)) return true; + return false; +} + +// the following is used, among other things, +// to enforce limits on in-progress jobs +// for GPUs and CPUs (see handle_request.cpp) +// +int plan_class_to_proc_type(const char* plan_class) { + if (strstr(plan_class, "cuda")) { + return PROC_TYPE_NVIDIA_GPU; + } + if (strstr(plan_class, "nvidia")) { + return PROC_TYPE_NVIDIA_GPU; + } + if (strstr(plan_class, "ati")) { + return PROC_TYPE_AMD_GPU; + } + if (strstr(plan_class, "intel_gpu")) { + return PROC_TYPE_INTEL_GPU; + } + return PROC_TYPE_CPU; +} + +#ifdef GCL_SIMULATOR + +void simulator_signal_handler(int signum) { + FILE *fsim; + char currenttime[64]; + fsim = fopen(config.project_path("simulator/sim_time.txt"),"r"); + if(fsim){ + fscanf(fsim,"%s", currenttime); + simtime = atof(currenttime); + fclose(fsim); + } + log_messages.printf(MSG_NORMAL, + "Invoked by the simulator at time %.0f... \n", simtime + ); +} + +int itime() { + return (int) simtime; +} + +void continue_simulation(const char *daemonname){ + char daemonfilelok[64]; + char daemonfile[64]; + sprintf(daemonfile, strcat((char*)config.project_path("simulator/"),"sim_%s.txt"),daemonname); + sprintf(daemonfilelok, strcat((char*)config.project_path("simulator/"),"sim_%s.lok"),daemonname); + FILE *fsimlok = fopen(daemonfilelok, "w"); + if (fsimlok){ + fclose(fsimlok); + FILE *fsim = fopen(daemonfile, "w"); + if (fsim) { + fclose(fsim); + } + } + remove(daemonfilelok); +} + +#endif + +const char *BOINC_RCSID_affa6ef1e4 = "$Id$"; diff --git a/sched/sched_util_basic.h b/sched/sched_util_basic.h new file mode 100644 index 0000000000..d71f27dbb3 --- /dev/null +++ b/sched/sched_util_basic.h @@ -0,0 +1,74 @@ +// This file is part of BOINC. +// http://boinc.berkeley.edu +// Copyright (C) 2014 University of California +// +// BOINC is free software; you can redistribute it and/or modify it +// under the terms of the GNU Lesser General Public License +// as published by the Free Software Foundation, +// either version 3 of the License, or (at your option) any later version. +// +// BOINC is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +// See the GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with BOINC. If not, see . + +// general back-end utility functions (not scheduler-specific) +// No database-related stuff here; put that in sched_util.h + +#ifndef SCHED_UTIL_BASIC_H +#define SCHED_UTIL_BASIC_H + +#include "util.h" + +// "average credit" uses an exponential decay so that recent +// activity is weighted more heavily. +// CREDIT_HALF_LIFE is the "half-life" period: +// the average decreases by 1/2 if idle for this period. +// +#define SECONDS_IN_DAY (3600*24) +#define CREDIT_HALF_LIFE (SECONDS_IN_DAY*7) + +extern void write_pid_file(const char* filename); +extern void set_debug_level(int); +extern void check_stop_daemons(); +extern void daemon_sleep(int); +extern bool check_stop_sched(); +extern void install_stop_signal_handler(); +extern int try_fopen(const char* path, FILE*& f, const char* mode); +extern void get_log_path(char*, const char*); + +// convert filename to path in a hierarchical directory system +// +extern int dir_hier_path( + const char* filename, const char* root, int fanout, + char* result, bool create=false +); + +// convert filename to URL in a hierarchical directory system +// +extern int dir_hier_url( + const char* filename, const char* root, int fanout, + char* result +); + +// returns zero if we get lock on file with file descriptor fd. +// returns < 0 if error +// returns PID > 0 if another process has lock +// +extern int mylockf(int fd); + +// return true if x is -y or --y (for argv processing) +// +extern bool is_arg(const char*, const char*); + +extern int plan_class_to_proc_type(const char* plan_class); + +#ifdef GCL_SIMULATOR +extern void simulator_signal_handler(int signum); +extern void continue_simulation(const char *daemonname); +#endif + +#endif