diff --git a/client/app.C b/client/app.C index 74733947e9..0920a7755d 100644 --- a/client/app.C +++ b/client/app.C @@ -422,11 +422,8 @@ bool ACTIVE_TASK_SET::poll() { } return found; -#endif +#else -#if HAVE_SYS_RESOURCE_H -#if HAVE_SYS_WAIT_H -#if HAVE_SYS_TIME_H struct rusage rs; int pid; int stat; @@ -455,8 +452,6 @@ bool ACTIVE_TASK_SET::poll() { atp->state = PROCESS_EXIT_UNKNOWN; atp->result->exit_status = -1; } -#endif -#endif #endif atp->read_stderr_file(); diff --git a/client/app.h b/client/app.h index 0942981f2b..921d6ffec2 100644 --- a/client/app.h +++ b/client/app.h @@ -20,15 +20,6 @@ #ifndef _TASK_ #define _TASK_ -// Possible states of a process in an ACTIVE_TASK -#define PROCESS_UNINITIALIZED 0 -#define PROCESS_RUNNING 1 -#define PROCESS_EXITED 2 -#define PROCESS_WAS_SIGNALED 3 -#define PROCESS_EXIT_UNKNOWN 4 - -typedef int PROCESS_ID; - #include "windows_cpp.h" #ifdef _WIN32 #include @@ -39,11 +30,21 @@ typedef int PROCESS_ID; #include "client_types.h" +// Possible states of a process in an ACTIVE_TASK +#define PROCESS_UNINITIALIZED 0 +#define PROCESS_RUNNING 1 +#define PROCESS_EXITED 2 +#define PROCESS_WAS_SIGNALED 3 +#define PROCESS_EXIT_UNKNOWN 4 +#define PROCESS_ABORTED 5 + // process exceeded time or disk limits + +typedef int PROCESS_ID; + class CLIENT_STATE; -// The following classes provide an interface for task execution - -// represents a task in progress +// ACTIVE_TASK represents a task in progress. +// Written to the client state file so that tasks can be restarted. // class ACTIVE_TASK { public: diff --git a/client/client_types.C b/client/client_types.C index 5237ae86ae..b362505b69 100644 --- a/client/client_types.C +++ b/client/client_types.C @@ -506,6 +506,8 @@ int WORKUNIT::parse(FILE* in) { app = NULL; project = NULL; seconds_to_complete = 0; + max_processing = DEFAULT_MAX_PROCESSING; + max_disk = DEFAULT_MAX_DISK; while (fgets(buf, 256, in)) { if (match_tag(buf, "")) return 0; else if (parse_str(buf, "", name, sizeof(name))) continue; @@ -514,6 +516,8 @@ int WORKUNIT::parse(FILE* in) { else if (parse_str(buf, "", command_line, sizeof(command_line))) continue; else if (parse_str(buf, "", env_vars, sizeof(env_vars))) continue; else if (parse_double(buf, "", seconds_to_complete)) continue; + else if (parse_double(buf, "", max_processing)) continue; + else if (parse_double(buf, "", max_disk)) continue; else if (match_tag(buf, "")) { file_ref.parse(in); input_files.push_back(file_ref); diff --git a/client/client_types.h b/client/client_types.h index ba37567f65..a15b64e416 100644 --- a/client/client_types.h +++ b/client/client_types.h @@ -35,6 +35,8 @@ #include "hostinfo.h" #define STDERR_MAX_LEN 4096 +#define DEFAULT_MAX_PROCESSING 1 +#define DEFAULT_MAX_DISK 1000000 class PERS_FILE_XFER; struct RESULT; @@ -181,7 +183,9 @@ struct WORKUNIT { APP* app; APP_VERSION* avp; int ref_cnt; - double seconds_to_complete; //needs to be initialized + double seconds_to_complete; // needs to be initialized + double max_processing; // abort if use this many cobblestones + double max_disk; // abort if use this much disk int parse(FILE*); int write(FILE*); @@ -193,7 +197,7 @@ struct WORKUNIT { #define RESULT_FILES_DOWNLOADED 1 // Files are downloaded, result can be computed #define RESULT_COMPUTE_DONE 2 - // Computation is done, files need to be uploaded + // Computation is done, if no error then files need to be uploaded #define RESULT_READY_TO_ACK 3 // Files are uploaded, notify scheduling server #define RESULT_SERVER_ACK 4 @@ -206,7 +210,7 @@ struct RESULT { vector output_files; bool is_active; // an app is currently running for this double final_cpu_time; - int state; // status of this result + int state; // status of this result int exit_status; // return value from the application char stderr_out[STDERR_MAX_LEN]; APP* app; diff --git a/db/schema.sql b/db/schema.sql index e41e776c01..069c8fd4a0 100644 --- a/db/schema.sql +++ b/db/schema.sql @@ -114,6 +114,12 @@ create table host ( primary key (id) ); +/* + * Only information needed by the server or other backend components + * is broken out into separate fields. + * Other info, i.e. that needed by the client (files, etc.) + * is stored in the XML doc + */ create table workunit ( id integer not null auto_increment, create_time integer not null, diff --git a/doc/work.html b/doc/work.html index 4776a48295..cc85171cc3 100644 --- a/doc/work.html +++ b/doc/work.html @@ -13,34 +13,55 @@ The attributes of a workunit include: (see below).
  • The estimated resource requirements of the work unit (computation, memory, disk space). -
  • A delay bound: upper bound on how long +
  • The maximum processing +(measured in Cobblestones) +and maximum disk space to be used for the computation. +An instance of the computation that exceeds either of these bounds +will be aborted. +This mechanism is used to prevent an infinite-loop bug from +indefinitely incapacitating a host. +
  • A delay bound: upper bound on how long (in real time) a result associated with this work unit should take to complete. This determines which hosts the workunit can be sent to, and it's used to assign result deadlines and times for retrying results.

    -The inputs to a workunit are described by an XML document of the form +Some parameters of a workunit are described by an XML document of the form

     [ <file_info>...</file_info> ]
     [ ... ]
     <workunit>
         [ <command_line>-flags xyz</command_line> ]
         [ <env_vars>name=val&name=val</env_vars> ]
    +    [ <max_processing>...</max_processing> ]
    +    [ <max_disk>...</max_disk> ]
         [ <file_ref>...</file_ref> ]
         [ ... ]
     </workunit>
     
    The components are: - +

    A workunit is associated with an application, not with a particular version or range of versions. diff --git a/test/sah_test.php b/test/sah_test.php index c20756c285..1e2026eecf 100755 --- a/test/sah_test.php +++ b/test/sah_test.php @@ -16,7 +16,7 @@ add_core_client(null); add_user(null); add_app("setiathome-3.06",null,null); - create_work("-appname setiathome-3.06 -wu_name sah_wu -wu_template sah_wu -result_template sah_result -nresults 1 work_unit.sah"); + create_work("-appname setiathome-3.06 -wu_name sah_wu -wu_template sah_wu -result_template sah_result -redundancy 1 work_unit.sah"); echo "starting feeder\n"; start_feeder(); echo "started feeder\n"; diff --git a/test/test.inc b/test/test.inc index 50d700460a..67dd1ed1e5 100644 --- a/test/test.inc +++ b/test/test.inc @@ -616,7 +616,7 @@ class Work { var $app; var $wu_template; var $result_template; - var $nresults; + var $redundancy; var $input_files; var $rsc_iops; var $rsc_fpops; @@ -630,6 +630,7 @@ class Work { $this->rcs_fpops = 100000000000; $this->rcs_disk = 1000000; $this->delay_bound = 1000; + $this->redundancy = 1; } function install($project) { @@ -674,9 +675,9 @@ if (false) { // doesn't belong here; needs comment } } fclose($f); -} + + $cmd = "create_work -db_name $project->db_name -download_dir $project->project_dir/download -upload_url $project->upload_url -download_url $project->download_url -keyfile $project->key_dir/upload_private -appname $app->name -rsc_iops $this->rcs_iops -rsc_fpops $this->rsc_fpops -rsc_disk $this->rsc_disk -wu_template $this->wu_template -result_template $this->result_template -redundancy $this->redundancy -wu_name $this->wu_template -delay_bound $this->delay_bound"; - $cmd = "create_work -db_name $project->db_name -download_dir $project->project_dir/download -upload_url $project->upload_url -download_url $project->download_url -keyfile $project->key_dir/upload_private -appname $app->name -rsc_iops $this->rcs_iops -rsc_fpops $this->rsc_fpops -rsc_disk $this->rsc_disk -wu_template $this->wu_template -result_template $this->result_template -nresults $this->nresults -wu_name $this->wu_template -delay_bound $this->delay_bound"; for ($i=0; $iinput_files); $i++) { $x = $this->input_files[$i]; $cmd = $cmd." ".$x; diff --git a/test/test_1sec.php b/test/test_1sec.php index 6baddc7159..57ac8a13e4 100644 --- a/test/test_1sec.php +++ b/test/test_1sec.php @@ -39,7 +39,7 @@ $work = new Work($app); $work->wu_template = "uc_wu"; $work->result_template = "uc_result"; - $work->nresults = 5; + $work->redundancy = 5; $work->delay_bound = 60; array_push($work->input_files, "input"); $work->install($project1); diff --git a/test/test_concat.php b/test/test_concat.php index b0c53d6063..2c5580ee35 100644 --- a/test/test_concat.php +++ b/test/test_concat.php @@ -23,7 +23,7 @@ $work = new Work($app); $work->wu_template = "concat_wu"; $work->result_template = "concat_result"; - $work->nresults = 2; + $work->redundancy = 2; array_push($work->input_files, "input"); array_push($work->input_files, "input"); $work->install($project); diff --git a/test/test_download_backoff.php b/test/test_download_backoff.php index de8efad84c..bbef36e889 100644 --- a/test/test_download_backoff.php +++ b/test/test_download_backoff.php @@ -32,7 +32,7 @@ $work = new Work($app); $work->wu_template = "uc_wu"; $work->result_template = "uc_result"; - $work->nresults = 2; + $work->redundancy = 2; $work->delay_bound = 10; array_push($work->input_files, "input"); $work->install($project); diff --git a/test/test_loop.php b/test/test_loop.php index 2444b1c57b..2eddc2dea1 100644 --- a/test/test_loop.php +++ b/test/test_loop.php @@ -25,7 +25,7 @@ $work = new Work($app); $work->wu_template = "uc_wu"; $work->result_template = "uc_result"; - $work->nresults = 2; + $work->redundancy = 2; array_push($work->input_files, "input"); $work->install($project); diff --git a/test/test_masterurl_failure.php b/test/test_masterurl_failure.php index 5a5c9198a1..9790a8d443 100644 --- a/test/test_masterurl_failure.php +++ b/test/test_masterurl_failure.php @@ -32,7 +32,7 @@ $work = new Work($app); $work->wu_template = "uc_wu"; $work->result_template = "uc_result"; - $work->nresults = 2; + $work->redundancy = 2; $work->delay_bound = 10; array_push($work->input_files, "input"); $work->install($project); diff --git a/test/test_mdownload_backoff.php b/test/test_mdownload_backoff.php index 9e9951881b..f1b3d2bf8a 100644 --- a/test/test_mdownload_backoff.php +++ b/test/test_mdownload_backoff.php @@ -32,7 +32,7 @@ $work = new Work($app); $work->wu_template = "uc_multiple_download_wu"; $work->result_template = "uc_result"; - $work->nresults = 2; + $work->redundancy = 2; $work->delay_bound = 10; array_push($work->input_files, "input"); $work->install($project); diff --git a/test/test_pers.php b/test/test_pers.php index 492a1c5aaf..1cb170751f 100644 --- a/test/test_pers.php +++ b/test/test_pers.php @@ -26,7 +26,7 @@ echo "adding work\n"; $work = new Work($app); $work->wu_template = "uc_wu"; $work->result_template = "uc_result"; -$work->nresults = 2; +$work->redundancy = 2; array_push($work->input_files, "input"); $work->install($project); $project->start_feeder(); diff --git a/test/test_prefs.php b/test/test_prefs.php index 91381b776c..1fcfa2bdc7 100644 --- a/test/test_prefs.php +++ b/test/test_prefs.php @@ -25,7 +25,6 @@ $work = new Work($app); $work->wu_template = "ucs_wu"; $work->result_template = "ucs_result"; - $work->nresults = 1; array_push($work->input_files, "small_input"); $work->install($project); diff --git a/test/test_rsc.php b/test/test_rsc.php index ac208354eb..9509fb52b2 100644 --- a/test/test_rsc.php +++ b/test/test_rsc.php @@ -25,7 +25,7 @@ $work = new Work($app); $work->wu_template = "uc_wu"; $work->result_template = "uc_result"; - $work->nresults = 1; + $work->redundancy = 1; $work->rsc_disk = 1000000000000; // 1 TB $work->rsc_fpops = 0; array_push($work->input_files, "input"); diff --git a/test/test_sched_failure.php b/test/test_sched_failure.php index 5cd9a12ea1..8f223d65e5 100644 --- a/test/test_sched_failure.php +++ b/test/test_sched_failure.php @@ -32,7 +32,7 @@ $work = new Work($app); $work->wu_template = "uc_wu"; $work->result_template = "uc_result"; - $work->nresults = 2; + $work->redundancy = 2; $work->delay_bound = 10; array_push($work->input_files, "input"); $work->install($project); diff --git a/test/test_sticky.php b/test/test_sticky.php index 649dfb70d4..46b6c2fed3 100644 --- a/test/test_sticky.php +++ b/test/test_sticky.php @@ -24,7 +24,7 @@ $work = new Work($app); $work->wu_template = "uc_wu_sticky"; $work->result_template = "uc_result_sticky"; - $work->nresults = 2; + $work->redundancy = 2; array_push($work->input_files, "input"); $work->install($project); diff --git a/test/test_time.php b/test/test_time.php index 942d430f69..b9c6ee55e9 100644 --- a/test/test_time.php +++ b/test/test_time.php @@ -24,7 +24,7 @@ $work = new Work($app); $work->wu_template = "uccpu_wu"; $work->result_template = "uccpu_result"; - $work->nresults = 1; + $work->redundancy = 1; array_push($work->input_files, "small_input"); $work->install($project); diff --git a/test/test_uc.php b/test/test_uc.php index 6482fcd7a0..442b12170b 100644 --- a/test/test_uc.php +++ b/test/test_uc.php @@ -33,7 +33,7 @@ $work = new Work($app); $work->wu_template = "uc_wu"; $work->result_template = "uc_result"; - $work->nresults = 2; + $work->redundancy = 2; $work->delay_bound = 10; array_push($work->input_files, "input"); $work->install($project); diff --git a/test/test_uc_slow.php b/test/test_uc_slow.php index 322063f53b..d1907e627f 100644 --- a/test/test_uc_slow.php +++ b/test/test_uc_slow.php @@ -25,7 +25,6 @@ $work = new Work($app); $work->wu_template = "ucs_wu"; $work->result_template = "ucs_result"; - $work->nresults = 1; array_push($work->input_files, "small_input"); $work->install($project); diff --git a/test/test_uc_win.php b/test/test_uc_win.php index d4638dbe28..f7a2ecce79 100644 --- a/test/test_uc_win.php +++ b/test/test_uc_win.php @@ -24,7 +24,7 @@ $work = new Work($app); $work->wu_template = "uc_wu"; $work->result_template = "uc_result"; - $work->nresults = 2; + $work->redundancy = 2; array_push($work->input_files, "input"); $work->install($project); diff --git a/test/test_upload_backoff.php b/test/test_upload_backoff.php index 8d9225aec1..43b0e26688 100644 --- a/test/test_upload_backoff.php +++ b/test/test_upload_backoff.php @@ -32,7 +32,7 @@ $work = new Work($app); $work->wu_template = "uc_wu"; $work->result_template = "uc_result"; - $work->nresults = 2; + $work->redundancy = 2; $work->delay_bound = 10; array_push($work->input_files, "input"); $work->install($project); diff --git a/todo b/todo index f2c8be5296..7c2941414b 100755 --- a/todo +++ b/todo @@ -1,3 +1,28 @@ +Windows hostinfo: CPU, #cpus, OS, memory, domain, IP address, + swap, disk, free +validate in crontab +email account ID +formatting of team, top user page +top hosts page is screwed up +make "external user view" page (no private info) +list hosts 1 per line, linked + +Windows client + "bring up graphics" button in core client + make mini-logo + test uninstall + fix "unable to calculate" + fix disk usage labels, limit size of pie + choose GB or MB correctly + get rid of xfers, results eventually + "free avail for boinc should be nonzero" + messages: prepend project name, have date/time + xfers: show file size, + done xfers: show elapsed time + done results: show used CPU time + notation for CPU time: HH:MM:SS +----------------------- + test feeder reread-DB mechanism use PHP session mechanism instead of our own cookies diff --git a/tools/backend_lib.C b/tools/backend_lib.C index cea226bbbf..3421c6dd56 100644 --- a/tools/backend_lib.C +++ b/tools/backend_lib.C @@ -82,12 +82,14 @@ static int process_wu_template( bool found; int i, retval; double nbytes; + assert(wu_name!=NULL); assert(tmplate!=NULL); assert(out!=NULL); assert(dirpath!=NULL); assert(infiles!=NULL); assert(n>=0); + strcpy(out, tmplate); while (1) { found = false; @@ -244,3 +246,42 @@ int create_work( } return 0; } + +int create_sequence( + WORKUNIT& wu, + char* wu_template, + char* result_template_filename, + int redundancy, + char* infile_dir, + char** infiles, + int ninfiles, + R_RSA_PRIVATE_KEY& key, + char* upload_url, char* download_url, + int nsteps +) { + int i, retval; + + retval = db_workseq_new(ws); + if (retval) return retval; + for (i=0; i