diff --git a/api/boinc_api.C b/api/boinc_api.C index d3ae9ed59e..937942371d 100644 --- a/api/boinc_api.C +++ b/api/boinc_api.C @@ -188,8 +188,8 @@ double boinc_cpu_time() { static DWORD last_count = 0; if (first) { - last_count = GetTickCount(); - first = true; + last_count = GetTickCount(); + first = true; } DWORD cur = GetTickCount(); double x = (cur - last_count)/1000.; @@ -355,46 +355,20 @@ int write_fd_init_file(FILE* f, char *file_name, int fdesc, int input_file ) { // int parse_fd_init_file(FILE* f) { char buf[256],filename[256]; - int filedesc,fd,retval; + int filedesc; while (fgets(buf, 256, f)) { if (parse_str(buf, "", filename)) { if (fgets(buf, 256, f)) { if (parse_int(buf, "", filedesc)) { -#if 1 - freopen(filename, "r", stdin); -#else - fd = open(filename, O_RDONLY); - if (fd < 0) return ERR_OPEN; - if (fd != filedesc) { - retval = dup2(fd, filedesc); - if (retval < 0) { - fprintf(stderr, "dup2 %d %d returned %d\n", fd, filedesc, retval); - return ERR_DUP2; - } - close(fd); - } -#endif - fprintf(stderr, "opened input file %s\n", filename); + freopen(filename, "r", stdin); + fprintf(stderr, "opened input file %s\n", filename); } } } else if (parse_str(buf, "", filename)) { if (fgets(buf, 256, f)) { if (parse_int(buf, "", filedesc)) { -#if 1 - freopen(filename, "w", stdout); -#else - fd = open(filename, O_WRONLY|O_CREAT, 0660); - if (fd < 0) return ERR_OPEN; - if (fd != filedesc) { - retval = dup2(fd, filedesc); - if (retval < 0) { - fprintf(stderr, "dup2 %d %d returned %d\n", fd, filedesc, retval); - return ERR_DUP2; - } - close(fd); - } -#endif - fprintf(stderr, "opened output file %s\n", filename); + freopen(filename, "w", stdout); + fprintf(stderr, "opened output file %s\n", filename); } } } else fprintf(stderr, "parse_fd_init_file: unrecognized %s", buf); diff --git a/checkin_notes b/checkin_notes index 467b24e3f7..d9b4d16c7d 100755 --- a/checkin_notes +++ b/checkin_notes @@ -1758,3 +1758,50 @@ David August 26, 2002 init.inc master.html test_uc.php + +David August 28, 2002 + - added DB fields to keep track of credit for hosts and result + - added utility program "grant_credit" to grant credit for a result + - removed some extraneous printfs + - file upload handler error messages have user name + - added a "poll_debug" flag; turn this on in case of infinite + poll loop, to see what's causing the problem + - added a "libboinc.a" target to lib/ Makefile. + We might want to consider using a random library + instead of referring to explicit .o files everywhere + + api/ + boinc_api.h + client/ + Makefile.in + app.C + client_state.C + cs_apps.C + cs_files.C + cs_scheduler.C + file_xfer.C + log_flags.C,h + net_xfer.C + pers_file_xfer.C + db/ + db.h + db_mysql.C + schema.sql + html_ops/ + db.inc + db.php + html_user/ + index.html + lib/ + Makefile.in + sched/ + feeder.C + file_upload_handler.C + handle_request.C + test/ + master.html + test_uc.php + tools/ + Makefile.in + backend_lib.C,h + grant_credit.C (new) diff --git a/client/Makefile.in b/client/Makefile.in index 5883c20847..2c1bce8a9c 100644 --- a/client/Makefile.in +++ b/client/Makefile.in @@ -35,7 +35,6 @@ OBJS = \ cs_scheduler.o \ file_names.o \ file_xfer.o \ - filesys.o \ hostinfo.o \ hostinfo_unix.o \ http.o \ @@ -47,21 +46,22 @@ OBJS = \ scheduler_op.o \ speed_stats.o \ time_stats.o \ - util.o \ + ../lib/filesys.o \ ../lib/parse.o \ ../lib/md5_file.o \ ../lib/md5.o \ ../lib/crypt.o \ + ../lib/util.o \ ../RSAEuro/source/rsaeuro.a \ ../api/boinc_api.o TEST_NET_XFER_OBJS = \ - filesys.o \ http.o \ log_flags.o \ - ../lib/parse.o \ net_xfer.o \ - util.o + ../lib/filesys.o \ + ../lib/parse.o \ + ../lib/util.o TEST_HTTP_OBJS = $(TEST_NET_XFER_OBJS) diff --git a/client/app.C b/client/app.C index 2ac8e6d1f6..25b6aa2b84 100644 --- a/client/app.C +++ b/client/app.C @@ -421,7 +421,6 @@ bool ACTIVE_TASK_SET::poll() { } } - if (log_flags.task_debug && found) printf("ACTIVE_TASK_SET::poll\n"); return found; #endif @@ -472,7 +471,6 @@ bool ACTIVE_TASK_SET::poll() { clean_out_dir(atp->slot_dir); - if (log_flags.task_debug) printf("ACTIVE_TASK_SET::poll\n"); return true; } @@ -613,9 +611,9 @@ bool ACTIVE_TASK::check_app_status_files() { retval = file_delete(path); if (retval) { fprintf(stderr, - "ACTIVE_TASK.check_app_status_files: could not delete %s: %d\n", - path, retval - ); + "ACTIVE_TASK.check_app_status_files: could not delete %s: %d\n", + path, retval + ); } } @@ -630,9 +628,9 @@ bool ACTIVE_TASK::check_app_status_files() { retval = file_delete(path); if (retval) { fprintf(stderr, - "ACTIVE_TASK.check_app_status_files: could not delete %s: %d\n", - path, retval - ); + "ACTIVE_TASK.check_app_status_files: could not delete %s: %d\n", + path, retval + ); } } return found; @@ -650,7 +648,6 @@ bool ACTIVE_TASK_SET::poll_time() { updated |= atp->check_app_status_files(); } - if (log_flags.task_debug && updated) printf("ACTIVE_TASK_SET::poll_time\n"); return updated; } diff --git a/client/client_state.C b/client/client_state.C index 7d064c44e0..62e08770a1 100644 --- a/client/client_state.C +++ b/client/client_state.C @@ -183,6 +183,12 @@ int CLIENT_STATE::check_suspend_activities() { return 0; } +static void print_log(char* p) { + if (log_flags.poll_debug) { + printf(p); + } +} + // do_something is where all the action happens. This is part of the // finite state machine abstraction of the client. Each of the key // elements of the client is given a chance to perform work here. @@ -195,32 +201,45 @@ bool CLIENT_STATE::do_something() { check_suspend_activities(); if (!activities_suspended) { - // Call these functions in bottom to top order in - // respect to the FSMs hierarchy + // Call these functions in bottom to top order with + // respect to the FSM hierarchy + net_xfers->poll(999999, nbytes); - if (nbytes) { printf("net_xfers\n"); action = true; } + if (nbytes) { action=true; print_log("net_xfers\n"); } + x = http_ops->poll(); - if (x) {action=true; printf("http_ops::poll\n"); } + if (x) {action=true; print_log("http_ops::poll\n"); } + x = file_xfers->poll(); - if (x) {action=true; printf("file_xfers::poll\n"); } + if (x) {action=true; print_log("file_xfers::poll\n"); } + x = active_tasks.poll(); - if (x) {action=true; printf("active_tasks::poll\n"); } + if (x) {action=true; print_log("active_tasks::poll\n"); } + x = active_tasks.poll_time(); - if (x) {action=true; printf("active_tasks::poll_time\n"); } + if (x) {action=true; print_log("active_tasks::poll_time\n"); } + x = scheduler_rpc_poll(); - if (x) {action=true; printf("scheduler_rpc_poll\n"); } + if (x) {action=true; print_log("scheduler_rpc_poll\n"); } + x = start_apps(); - if (x) {action=true; printf("start_apps\n"); } + if (x) {action=true; print_log("start_apps\n"); } + x = pers_xfers->poll(); - if (x) {action=true; printf("pers_xfers->poll\n"); } + if (x) {action=true; print_log("pers_xfers->poll\n"); } + x = handle_running_apps(); - if (x) {action=true; printf("handle_running_apps\n"); } + if (x) {action=true; print_log("handle_running_apps\n"); } + x = handle_pers_file_xfers(); - if (x) {action=true; printf("handle_pers_file_xfers\n"); } + if (x) {action=true; print_log("handle_pers_file_xfers\n"); } + x = garbage_collect(); - if (x) {action=true; printf("garbage_collect\n"); } + if (x) {action=true; print_log("garbage_collect\n"); } + x = update_results(); - if (x) {action=true; printf("update_results\n"); } + if (x) {action=true; print_log("update_results\n"); } + write_state_file_if_needed(); } if (!action) time_stats.update(true, !activities_suspended); diff --git a/client/cs_apps.C b/client/cs_apps.C index 29799e034a..414030da36 100644 --- a/client/cs_apps.C +++ b/client/cs_apps.C @@ -119,7 +119,6 @@ bool CLIENT_STATE::handle_running_apps() { action = true; } } - if (log_flags.task_debug && action) printf("CS::handle_running_apps\n"); return action; } @@ -154,10 +153,10 @@ bool CLIENT_STATE::start_apps() { int open_slot; for (i=0; istate == RESULT_FILES_DOWNLOADED && !rp->is_active ) { if (log_flags.task_debug) { printf("starting application for result %s\n", rp->name); @@ -180,10 +181,9 @@ bool CLIENT_STATE::start_apps() { active_tasks.insert(atp); action = true; set_client_state_dirty("start_apps"); - app_started = time(0); + app_started = time(0); } } - if (log_flags.task_debug && action) printf("CS::start_apps\n"); return action; } diff --git a/client/cs_files.C b/client/cs_files.C index 2fb4057bae..77e4c82e05 100644 --- a/client/cs_files.C +++ b/client/cs_files.C @@ -94,21 +94,21 @@ bool CLIENT_STATE::handle_pers_file_xfers() { for (i=0; ipers_file_xfer; - if (pfx) continue; + if (pfx) continue; if (!fip->generated_locally && fip->status == FILE_NOT_PRESENT) { // Set up the persistent file transfer object. - // This will start the download when there is available bandwidth + // This will start the download when there is available bandwidth // pfx = new PERS_FILE_XFER; pfx->init(fip, false); fip->pers_file_xfer = pfx; - pers_xfers->insert( fip->pers_file_xfer ); + pers_xfers->insert( fip->pers_file_xfer ); action = true; } else if (fip->upload_when_present && fip->status == FILE_PRESENT && !fip->uploaded) { // Set up the persistent file transfer object. - // This will start the upload when there is available bandwidth + // This will start the upload when there is available bandwidth // pfx = new PERS_FILE_XFER; pfx->init(fip, true); @@ -123,7 +123,7 @@ bool CLIENT_STATE::handle_pers_file_xfers() { // If the transfer finished, remove the PERS_FILE_XFER object // from the set and delete it - // + // if (pfx->xfer_done) { pfx->fip->pers_file_xfer = NULL; pers_xfers->remove(pfx); @@ -132,6 +132,5 @@ bool CLIENT_STATE::handle_pers_file_xfers() { } } - if (log_flags.file_xfer_debug && action) printf("CS::handle_pers_file_xfers\n"); return action; } diff --git a/client/cs_scheduler.C b/client/cs_scheduler.C index 5cc0a9a95d..8cf708ec60 100644 --- a/client/cs_scheduler.C +++ b/client/cs_scheduler.C @@ -125,9 +125,10 @@ PROJECT* CLIENT_STATE::next_project(PROJECT* old) { return pbest; } -// Compute the "resource debt" of each project. This is used -// to determine what project we will focus on next, based on -// the user specified resource share +// Compute the "resource debt" of each project. +// This is used to determine what project we will focus on next, +// based on the user-specified resource share. +// TODO: this counts only CPU time. Should reflect disk/network usage too. // void CLIENT_STATE::compute_resource_debts() { unsigned int i, j; @@ -278,7 +279,6 @@ bool CLIENT_STATE::scheduler_rpc_poll() { } break; } - if (log_flags.sched_op_debug && action) printf("CS::scheduler_rpc_poll\n"); return action; } @@ -322,6 +322,11 @@ void CLIENT_STATE::handle_scheduler_reply( if (strlen(sr.project_name)) { strcpy(project->project_name, sr.project_name); } + if (strlen(sr.user_name)) { + strcpy(project->user_name, sr.user_name); + } + project->total_credit = sr.total_credit; + project->expavg_credit = sr.expavg_credit; if (strlen(sr.message)) { show_message(sr.message, sr.message_priority); } diff --git a/client/file_xfer.C b/client/file_xfer.C index 377eebabd3..13c56bcab9 100644 --- a/client/file_xfer.C +++ b/client/file_xfer.C @@ -221,8 +221,5 @@ bool FILE_XFER_SET::poll() { } } } - if (log_flags.file_xfer_debug) { - if (action) printf("FILE_XFER_SET poll true\n"); - } return action; } diff --git a/client/log_flags.C b/client/log_flags.C index 026ceae378..892b99ea17 100644 --- a/client/log_flags.C +++ b/client/log_flags.C @@ -83,6 +83,10 @@ int LOG_FLAGS::parse(FILE* in) { net_xfer_debug = true; continue; } + else if (match_tag(buf, "")) { + poll_debug = true; + continue; + } else fprintf(stderr, "LOG_FLAGS::parse: unrecognized: %s\n", buf); } return ERR_XML_PARSE; diff --git a/client/log_flags.h b/client/log_flags.h index b7d5121bb0..1f8bee17bf 100644 --- a/client/log_flags.h +++ b/client/log_flags.h @@ -42,6 +42,7 @@ public: bool http_debug; bool time_debug; // print message on sleep bool net_xfer_debug; + bool poll_debug; // show what polls are responding LOG_FLAGS(); int parse(FILE*); diff --git a/client/net_xfer.C b/client/net_xfer.C index c375b047cf..9f9afe1cf2 100644 --- a/client/net_xfer.C +++ b/client/net_xfer.C @@ -189,9 +189,6 @@ int NET_XFER_SET::poll(int max_bytes, int& bytes_transferred) { bytes_transferred += n; if (max_bytes < 0) break; } - if (log_flags.net_xfer_debug && bytes_transferred) { - printf("NET_XFER_SET::poll bytes_transferred %d\n", bytes_transferred); - } return 0; } diff --git a/client/pers_file_xfer.C b/client/pers_file_xfer.C index 36453913e0..0fe48cd225 100644 --- a/client/pers_file_xfer.C +++ b/client/pers_file_xfer.C @@ -120,8 +120,10 @@ bool PERS_FILE_XFER::poll(unsigned int now) { if (fxp->file_xfer_done) { if (log_flags.file_xfer) { - printf( "file transfer done for %s; retval %d\n", - fip->get_url(), fxp->file_xfer_retval ); + printf( + "file transfer done for %s; retval %d\n", + fip->get_url(), fxp->file_xfer_retval + ); } if (fxp->file_xfer_retval == 0) { // The transfer finished with no errors. @@ -260,7 +262,6 @@ bool PERS_FILE_XFER_SET::poll() { if (action) gstate.set_client_state_dirty("pers_file_xfer_set poll"); - if (log_flags.file_xfer_debug && action) printf("PERS_FILE_XFER_SET::poll\n"); return action; } diff --git a/client/scheduler_op.C b/client/scheduler_op.C index 7bad50c6c8..41e9778bb3 100644 --- a/client/scheduler_op.C +++ b/client/scheduler_op.C @@ -335,7 +335,6 @@ bool SCHEDULER_OP::poll() { default: break; } - if (log_flags.sched_op_debug && action) printf("SCHEDULER_OP::poll\n"); return action; } @@ -378,6 +377,12 @@ int SCHEDULER_REPLY::parse(FILE* in) { return 0; } else if (parse_str(buf, "", project_name)) { continue; + } else if (parse_str(buf, "", user_name)) { + continue; + } else if (parse_double(buf, "", total_credit)) { + continue; + } else if (parse_double(buf, "", expavg_credit)) { + continue; } else if (parse_int(buf, "", hostid)) { continue; } else if (parse_int(buf, "", request_delay)) { diff --git a/db/db.h b/db/db.h index d8d43727da..e117c8fb8f 100644 --- a/db/db.h +++ b/db/db.h @@ -148,6 +148,9 @@ struct HOST { int userid; // ID of user running this host int rpc_seqno; // last seqno received from client unsigned int rpc_time; // time of last scheduler RPC + double total_credit; + double expavg_credit; + double expavg_time; // all remaining items are assigned by the client int timezone; @@ -236,6 +239,7 @@ struct RESULT { int batch; int project_state; bool validated; + double granted_credit; // the following not used in the DB char wu_name[256]; @@ -290,6 +294,7 @@ extern int db_workunit_lookup_name(WORKUNIT&); extern int db_workunit_enum_dynamic_to_send(WORKUNIT&, int); extern int db_result_new(RESULT& p); +extern int db_result(int id, RESULT&); extern int db_result_update(RESULT& p); extern int db_result_lookup_name(RESULT& p); extern int db_result_enum_to_send(RESULT&, int); diff --git a/db/db_mysql.C b/db/db_mysql.C index 1fd5fb9a2a..0d4858b8e2 100644 --- a/db/db_mysql.C +++ b/db/db_mysql.C @@ -162,6 +162,7 @@ void struct_to_str(void* vp, char* q, int type) { sprintf(q, "id=%d, create_time=%d, userid=%d, " "rpc_seqno=%d, rpc_time=%d, " + "total_credit=%f, expavg_credit=%f, expavg_time=%f, " "timezone=%d, domain_name='%s', serialnum='%s', " "last_ip_addr='%s', nsame_ip_addr=%d, " "on_frac=%f, connected_frac=%f, active_frac=%f, " @@ -173,6 +174,7 @@ void struct_to_str(void* vp, char* q, int type) { "n_bwup=%f, n_bwdown=%f", hp->id, hp->create_time, hp->userid, hp->rpc_seqno, hp->rpc_time, + hp->total_credit, hp->expavg_credit, hp->expavg_time, hp->timezone, hp->domain_name, hp->serialnum, hp->last_ip_addr, hp->nsame_ip_addr, hp->on_frac, hp->connected_frac, hp->active_frac, @@ -208,12 +210,12 @@ void struct_to_str(void* vp, char* q, int type) { "hostid=%d, report_deadline=%d, sent_time=%d, received_time=%d, " "name='%s', exit_status=%d, cpu_time=%f, " "xml_doc_in='%s', xml_doc_out='%s', stderr_out='%s', " - "batch=%d, project_state=%d, validated=%d", + "batch=%d, project_state=%d, validated=%d, granted_credit=%f", rp->id, rp->create_time, rp->workunitid, rp->state, rp->hostid, rp->report_deadline, rp->sent_time, rp->received_time, rp->name, rp->exit_status, rp->cpu_time, rp->xml_doc_in, rp->xml_doc_out, rp->stderr_out, - rp->batch, rp->project_state, rp->validated + rp->batch, rp->project_state, rp->validated, rp->granted_credit ); break; } @@ -307,6 +309,9 @@ void row_to_struct(MYSQL_ROW& r, void* vp, int type) { hp->userid = atoi(r[i++]); hp->rpc_seqno = atoi(r[i++]); hp->rpc_time = atoi(r[i++]); + hp->total_credit = atof(r[i++]); + hp->expavg_credit = atof(r[i++]); + hp->expavg_time = atof(r[i++]); hp->timezone = atoi(r[i++]); strcpy(hp->domain_name, r[i++]); strcpy(hp->serialnum, r[i++]); @@ -373,6 +378,7 @@ void row_to_struct(MYSQL_ROW& r, void* vp, int type) { rp->batch = atoi(r[i++]); rp->project_state = atoi(r[i++]); rp->validated = atoi(r[i++]); + rp->granted_credit = atof(r[i++]); break; } } @@ -570,6 +576,10 @@ int db_result_new(RESULT& p) { return db_new(&p, TYPE_RESULT); } +int db_result(int i, RESULT& p) { + return db_lookup_id(i, &p, TYPE_RESULT); +} + int db_result_update(RESULT& p) { return db_update(&p, TYPE_RESULT); } diff --git a/db/schema.sql b/db/schema.sql index bef5713059..d65357865a 100644 --- a/db/schema.sql +++ b/db/schema.sql @@ -74,6 +74,9 @@ create table host ( userid integer not null, rpc_seqno integer not null, rpc_time integer not null, + total_credit float not null, + expavg_credit float not null, + expavg_time float not null, timezone integer not null, domain_name varchar(254), @@ -148,5 +151,6 @@ create table result ( batch integer not null, project_state integer not null, validated smallint not null, + granted_credit float not null, primary key (id) ); diff --git a/html/ops/db.inc b/html/ops/db.inc index eb7709a3ed..a964c001a3 100644 --- a/html/ops/db.inc +++ b/html/ops/db.inc @@ -74,42 +74,41 @@ function show_app_version($app_version,$show_xml_docs) { } function show_host($host) { + start_table(); - echo TABLE2."\n"; - echo ""; - echo "

"; - echo "".TD2.LG_FONT."Host Information:\n"; - row("IP address: ", "$host->last_ip_addr
(same the last $host->nsame_ip_addr times)"); - row("Domain name: ", $host->domain_name); + row("Created", time_str($host->create_time)); + row("Total credit", $host->total_credit); + row("Average credit", $host->expavg_credit); + row("Average update time", time_str($host->expavg_time)); + row("IP address", "$host->last_ip_addr
(same the last $host->nsame_ip_addr times)"); + row("Domain name", $host->domain_name); $x = $host->timezone/3600; - row("Time zone: ", "UTC - $x hours"); - row("Created: ", time_str($host->create_time)); - row("CPU: ", "$host->p_vendor $host->p_model"); - row("Number of CPUs: ", $host->p_ncpus); - row("Operating System: ", "$host->os_name $host->os_version"); + row("Time zone", "UTC - $x hours"); + row("CPU", "$host->p_vendor $host->p_model"); + row("Number of CPUs", $host->p_ncpus); + row("Operating System", "$host->os_name $host->os_version"); $x = $host->m_nbytes/(1024*1024); $y = round($x, 2); - row("Memory: ", "$y MB"); + row("Memory", "$y MB"); $x = $host->m_cache/1024; $y = round($x, 2); - row("Cache: ", "$y KB"); + row("Cache", "$y KB"); $x = $host->m_swap/(1024*1024); $y = round($x, 2); - row("Swap Space: ", "$y MB"); + row("Swap Space", "$y MB"); $x = $host->d_total/(1024*1024*1024); $y = round($x, 2); - row("Total Disk Space: ", "$y GB"); + row("Total Disk Space", "$y GB"); $x = $host->d_free/(1024*1024*1024); $y = round($x, 2); - row("Free Disk Space: ", "$y GB"); - row("Avg network bandwidth:
(upstream)
", "$host->n_bwup bytes/sec"); - row("Avg network bandwidth:
(downstream)
", "$host->n_bwdown bytes/sec"); - row("Number of times client has contacted server: ", $host->rpc_seqno); - row("Last time contacted server: ", time_str($host->rpc_time)); - row("% of time client on: ", 100*$host->on_frac." %"); - row("% of time host connected: ", 100*$host->connected_frac." %"); - row("% of time user active: ", 100*$host->active_frac." %"); - row("","id>Results Assigned to Host"); + row("Free Disk Space", "$y GB"); + row("Avg network bandwidth (upstream)", "$host->n_bwup bytes/sec"); + row("Avg network bandwidth (downstream)", "$host->n_bwdown bytes/sec"); + row("Number of RPCs", $host->rpc_seqno); + row("Last RPC", time_str($host->rpc_time)); + row("% of time client on", 100*$host->on_frac." %"); + row("% of time host connected", 100*$host->connected_frac." %"); + row("% of time user active", 100*$host->active_frac." %"); end_table(); } @@ -171,15 +170,16 @@ function show_result($result,$show_xml_docs,$show_stderr,$show_times) { function show_user($user) { start_table(); - row("Created", time_str($user->create_time)); - row("Total Credit", $user->total_credit); - row("Recent Averaged Credit:", $user->expavg_credit); - row("Name", $user->name); - row("Email Address", $user->email_addr); - row("Country", $user->country); - row("Postal Code", $user->postal_code); - row("Team", ($user->teamid == 0 ? "None" : "teamid>" . team_name_by_id($user->teamid) . "" )); - row("", "id>User Hosts"); + row("created", time_str($user->create_time)); + row("total credit", $user->total_credit); + row("recent averaged credit:", $user->expavg_credit); + row("name", $user->name); + row("email address", $user->email_addr); + row("country", $user->country); + row("postal code", $user->postal_code); + row("total credit", $user->total_credit); + row("average credit", $user->expavg_credit); + row("last average time", time_str($user->expavg_time)); end_table(); } diff --git a/html/ops/db.php b/html/ops/db.php index 7dca125574..2ad2be9734 100644 --- a/html/ops/db.php +++ b/html/ops/db.php @@ -4,40 +4,84 @@ db_init(); - echo "


Platforms"; - $result = mysql_query("select * from platform"); - while ($platform = mysql_fetch_object($result)) { - show_platform($platform); + function show_platform_table() { + echo "
Platforms"; + $result = mysql_query("select * from platform"); + while ($platform = mysql_fetch_object($result)) { + show_platform($platform); + } } - echo "
Apps"; - $result = mysql_query("select * from app"); - while ($app = mysql_fetch_object($result)) { - show_app($app); + function show_app_table() { + echo "
Apps"; + $result = mysql_query("select * from app"); + while ($app = mysql_fetch_object($result)) { + show_app($app); + } } - echo "
App versions"; - $result = mysql_query("select * from app_version"); - while ($app_version = mysql_fetch_object($result)) { - show_app_version($app_version); + + function show_app_version_table() { + echo "
App versions"; + $result = mysql_query("select * from app_version"); + while ($app_version = mysql_fetch_object($result)) { + show_app_version($app_version); + } } - echo "
Hosts"; - $result = mysql_query("select * from host"); - while ($host = mysql_fetch_object($result)) { - show_host($host); + + function show_host_table() { + echo "
Hosts"; + $result = mysql_query("select * from host"); + while ($host = mysql_fetch_object($result)) { + show_host($host); + } } - echo "
Workunits"; - $result = mysql_query("select * from workunit"); - while ($workunit = mysql_fetch_object($result)) { - show_workunit($workunit); + + function show_workunit_table() { + echo "
Workunits"; + $result = mysql_query("select * from workunit"); + while ($workunit = mysql_fetch_object($result)) { + show_workunit($workunit); + } } - echo "
Results"; - $result = mysql_query("select * from result"); - while ($res = mysql_fetch_object($result)) { - show_result($res); + + function show_result_table() { + echo "
Results"; + $result = mysql_query("select * from result"); + while ($res = mysql_fetch_object($result)) { + show_result($res); + } } - echo "
Users"; - $result = mysql_query("select * from user"); - while ($user = mysql_fetch_object($result)) { - show_user($user); + + function show_user_table() { + echo "
Users"; + $result = mysql_query("select * from user"); + while ($user = mysql_fetch_object($result)) { + show_user($user); + } + } + + parse_str(getenv("QUERY_STRING")); + if ($show=="platform") { + show_platform_table(); + } else if ($show=="app") { + show_app_table(); + } else if ($show=="app_version") { + show_app_version_table(); + } else if ($show=="host") { + show_host_table(); + } else if ($show=="workunit") { + show_workunit_table(); + } else if ($show=="result") { + show_result_table(); + } else if ($show=="user") { + show_user_table(); + } else { + echo "
Platform"; + echo "
App"; + echo "
App Version"; + echo "
Host"; + echo "
Workunit"; + echo "
Result"; + echo "
User"; } ?> diff --git a/html/user/index.html b/html/user/index.html index 254f3f85c2..c241140af9 100644 --- a/html/user/index.html +++ b/html/user/index.html @@ -1,28 +1,14 @@ - -BOINC - Berkeley Open Infrastructure for Network Computing - - -

BOINC - Berkeley Open Infrastructure for Network Computing

+BOINC Test Project +

BOINC Test Project

-BOINC is a software platform for public-participation -distributed computing projects. -Users are allowed to simultaneously participate in multiple projects -and to choose how to allocate their resources -for each project. +This is a placeholder for the main page of the project's web site.

-First download the core client by clicking on the below link. -Then create a BOINC account, -setting your preferences to specify how much your computer should -be working on each project. -You may view your user page to see how much credit -you have accumulated as your participation proceeds. -In addition, you may modify your preferences through your user page -at anytime to reallocate your resources -among the different projects you may be involved in. +To participate in this project, +create an account, then download the BOINC client.

diff --git a/lib/Makefile.in b/lib/Makefile.in index 807c343d7e..8efe4ae43e 100644 --- a/lib/Makefile.in +++ b/lib/Makefile.in @@ -38,6 +38,9 @@ all: $(PROGS) $(OBJS) $(MD5_OBJS) $(CRYPT_OBJS) .c.o: $(CC) -c -o $*.o $< +libboinc.a: $(OBJS) $(MD5_OBJS) + ar cr libboinc.a $(OBJS) $(MD5_OBJS); ranlib libboinc.a + md5_test: md5_test.o $(MD5_OBJS) $(CC) md5_test.o $(MD5_OBJS) -o md5_test diff --git a/sched/feeder.C b/sched/feeder.C index 4291554f83..5d7ec216b0 100644 --- a/sched/feeder.C +++ b/sched/feeder.C @@ -73,6 +73,7 @@ int check_trigger(SCHED_SHMEM* ssp) { ssp->scan_tables(); } else { fprintf(stderr, "feeder: unknown command in trigger file: %s\n", buf); + exit(0); } unlink(TRIGGER_FILENAME); return 0; diff --git a/sched/file_upload_handler.C b/sched/file_upload_handler.C index a17e4a0349..e1466ba530 100644 --- a/sched/file_upload_handler.C +++ b/sched/file_upload_handler.C @@ -78,11 +78,13 @@ int FILE_INFO::parse(FILE* in) { int print_status(int status, char* message) { printf("Content-type: text/plain\n\n%d\n", status); - if (message) printf("%s\n", message); - fprintf(stderr, - "file_upload_handler (%s): status %d: %s>\n", - BOINC_USER, status, message - ); + if (message) { + printf("%s\n", message); + fprintf(stderr, + "file_upload_handler (%s): status %d: %s>\n", + BOINC_USER, status, message + ); + } return 0; } @@ -145,12 +147,12 @@ int handle_request(FILE* in, R_RSA_PUBLIC_KEY& key) { if (match_tag(buf, "")) { retval = file_info.parse(in); if (retval) { - fprintf(stderr, - "file_upload_handler (%s): FILE_INFO.parse\n", - BOINC_USER - ); - return retval; - } + fprintf(stderr, + "file_upload_handler (%s): FILE_INFO.parse\n", + BOINC_USER + ); + return retval; + } retval = verify_string( file_info.signed_xml, file_info.xml_signature, key, is_valid ); @@ -163,14 +165,23 @@ int handle_request(FILE* in, R_RSA_PUBLIC_KEY& key) { // Handle a file size request else if (parse_str(buf, "", file_name)) { struct stat sbuf; - // TODO: put checking here to ensure path doesn't point somewhere bad + // TODO: check to ensure path doesn't point somewhere bad + // sprintf( path, "%s/%s", BOINC_UPLOAD_DIR, file_name ); retval = stat( path, &sbuf ); - if (retval && errno != ENOENT) print_status( -1, "cannot open file" ); - else if (retval) printf("Content-type: text/plain\n\n0\n" - "0\n"); - else printf("Content-type: text/plain\n\n%d\n" - "0\n", (int)sbuf.st_size); + if (retval && errno != ENOENT) { + print_status( -1, "cannot open file" ); + } else if (retval) { + printf( + "Content-type: text/plain\n\n0\n" + "0\n" + ); + } else { + printf( + "Content-type: text/plain\n\n%d\n" + "0\n", (int)sbuf.st_size + ); + } exit(0); } else if (parse_double(buf, "", offset)) continue; @@ -193,12 +204,12 @@ int handle_request(FILE* in, R_RSA_PUBLIC_KEY& key) { sprintf(path, "%s/%s", BOINC_UPLOAD_DIR, file_info.name); retval = copy_socket_to_file(in, path, offset, nbytes); - if (retval) { - fprintf(stderr, - "file_upload_handler (%s): copy_socket_to_file %d %s\n", - BOINC_USER, retval, path - ); - } + if (retval) { + fprintf(stderr, + "file_upload_handler (%s): copy_socket_to_file %d %s\n", + BOINC_USER, retval, path + ); + } break; } } @@ -233,7 +244,6 @@ int main() { if (retval) { fprintf(stderr, "file_upload_handler: handle_request: %d\n", retval); } else { - //fprintf(stderr, "file_upload_handler: handle_request: %d\n", retval); print_status(0, 0); } return 0; diff --git a/sched/handle_request.C b/sched/handle_request.C index e8fa357814..965b26e7cf 100644 --- a/sched/handle_request.C +++ b/sched/handle_request.C @@ -52,10 +52,10 @@ int insert_time_tag(WORKUNIT& wu, double seconds) { location = strstr(wu.xml_doc, ""); if ((location - wu.xml_doc) > (MAX_BLOB_SIZE - 64)) { - return -1; //not enough space to include time info + return -1; //not enough space to include time info } sprintf(location, - " %lf\n" + " %f\n" "\n", seconds ); @@ -140,8 +140,8 @@ int authenticate_user(SCHEDULER_REQUEST& sreq, SCHEDULER_REPLY& reply) { return -1; } new_host: - // reply.user is filled in and valid at this point - // + // reply.user is filled in and valid at this point + // reply.host = sreq.host; reply.host.id = 0; reply.host.create_time = time(0); @@ -156,8 +156,8 @@ new_host: return -1; } reply.host.id = db_insert_id(); - reply.hostid = reply.host.id; - // this tells client to updates its host ID + reply.hostid = reply.host.id; + // this tells client to updates its host ID } return 0; } @@ -300,18 +300,18 @@ int send_work( if (!ss.wu_results[i].present || !wu_is_feasible(ss.wu_results[i].workunit, reply.host) ) { - continue; - } + continue; + } wu = ss.wu_results[i].workunit; result = ss.wu_results[i].result; ss.wu_results[i].present = false; retval = add_wu_to_reply(wu, reply, platform, ss, - estimate_duration(wu, reply.host) + estimate_duration(wu, reply.host) ); if (retval) continue; reply.insert_result(result); - seconds_to_fill -= (int)estimate_duration(wu, reply.host); + seconds_to_fill -= (int)estimate_duration(wu, reply.host); nresults++; result.state = RESULT_STATE_IN_PROGRESS; diff --git a/test/master.html b/test/master.html index 254f3f85c2..c241140af9 100644 --- a/test/master.html +++ b/test/master.html @@ -1,28 +1,14 @@ - -BOINC - Berkeley Open Infrastructure for Network Computing - - -

BOINC - Berkeley Open Infrastructure for Network Computing

+BOINC Test Project +

BOINC Test Project

-BOINC is a software platform for public-participation -distributed computing projects. -Users are allowed to simultaneously participate in multiple projects -and to choose how to allocate their resources -for each project. +This is a placeholder for the main page of the project's web site.

-First download the core client by clicking on the below link. -Then create a BOINC account, -setting your preferences to specify how much your computer should -be working on each project. -You may view your user page to see how much credit -you have accumulated as your participation proceeds. -In addition, you may modify your preferences through your user page -at anytime to reallocate your resources -among the different projects you may be involved in. +To participate in this project, +create an account, then download the BOINC client.

diff --git a/test/test_uc.php b/test/test_uc.php index 9bd5528719..244fe137db 100644 --- a/test/test_uc.php +++ b/test/test_uc.php @@ -9,10 +9,10 @@ check_env_vars(); clear_db(); if (true) { - clear_server_dirs(false); + clear_server_dirs(false); } else { - clear_server_dirs(true); - create_keys(); + clear_server_dirs(true); + create_keys(); } clear_client_dirs(); init_client_dirs("prefs1.xml"); @@ -21,10 +21,11 @@ add_platform(null); add_user("prefs.xml"); add_app("upper_case", null, null); + add_core_client(null); create_work("-appname upper_case -rsc_iops 180000000000.0 -rsc_fpops 0.0 -wu_name uc_wu -wu_template uc_wu -result_template uc_result -nresults 2 input input input input input"); start_feeder(); - run_client("-exit_after 10"); - //run_client("-exit_when_idle"); + //run_client("-exit_after 10"); + run_client("-exit_when_idle"); stop_feeder(); check_results_done(); compare_file("uc_wu_0_0", "uc_correct_output"); diff --git a/tools/Makefile.in b/tools/Makefile.in index 7ba3340784..4c30e2c13c 100644 --- a/tools/Makefile.in +++ b/tools/Makefile.in @@ -15,7 +15,8 @@ CFLAGS = -g -Wall @DEFS@ \ -I @top_srcdir@/lib \ -I @top_srcdir@/RSAEuro/source \ -I @top_srcdir@/db \ - -I $(MYSQL_INC) + -I $(MYSQL_INC) \ + -L../lib CC = @CC@ $(CFLAGS) @@ -27,7 +28,7 @@ OBJS = \ backend_lib.o \ process_result_template.o -PROGS = create_work add country_select +PROGS = create_work add country_select grant_credit all: $(PROGS) $(OBJS) MYSQL_DIR = /usr/local/mysql/lib @@ -56,6 +57,9 @@ create_work: create_work.o $(CLIBS) $(LIBS) $(CRYPTO_LIBS) add: add.o $(CLIBS) $(LIBS) $(CRYPTO_LIBS) $(CC) add.o $(CLIBS) $(LIBS) $(CRYPTO_LIBS) $(MYSQL_LIBS) -o add +grant_credit: grant_credit.o + $(CC) grant_credit.o $(LIBS) $(CRYPTO_LIBS) $(MYSQL_LIBS) $(CLIBS) -o grant_credit; + country_select: country_select.o ../lib/countries.o $(CC) country_select.o ../lib/countries.o -o country_select diff --git a/tools/backend_lib.C b/tools/backend_lib.C index 7d5b57bf87..9e87c71d3f 100644 --- a/tools/backend_lib.C +++ b/tools/backend_lib.C @@ -202,3 +202,16 @@ int create_work( } return 0; } + +// not finished! +int grant_credit(int resultid, double credit) { + RESULT result; + int retval; + + retval = db_result(resultid, result); + if (retval) return retval; + result.granted_credit = credit; + result.validated = true; + retval = db_result_update(result); + return retval; +} diff --git a/tools/backend_lib.h b/tools/backend_lib.h index 0ca2469e4b..22a7fda179 100644 --- a/tools/backend_lib.h +++ b/tools/backend_lib.h @@ -38,3 +38,5 @@ extern int create_work( int ninfiles, R_RSA_PRIVATE_KEY& ); + +extern int grant_credit(int resultid, double cobblestones); diff --git a/tools/grant_credit.C b/tools/grant_credit.C new file mode 100644 index 0000000000..18fe46dcd0 --- /dev/null +++ b/tools/grant_credit.C @@ -0,0 +1,78 @@ +// grant_credit result_name +// +// grant credit for the given result, based on its reported CPU time +// +// TODO: redundancy checking + +#include +#include +#include + +#include "db.h" + +#define EXP_DECAY_RATE (1./(3600*24*7)) + +int main(int argc, char** argv) { + RESULT result; + HOST host; + USER user; + int retval; + double host_speed, credit, deltat; + time_t now; + + retval = db_open(getenv("BOINC_DB_NAME"), getenv("BOINC_DB_PASSWD")); + if (retval) exit(1); + strcpy(result.name, argv[1]); + retval = db_result_lookup_name(result); + if (retval) { + printf("can't find result\n"); + exit(1); + } + if (result.state != RESULT_STATE_DONE) { + printf("result is not done\n"); + exit(1); + } + retval = db_host(result.hostid, host); + if (retval) { + printf("can't find host\n"); + exit(1); + } + retval = db_user(host.userid, user); + if (retval) { + printf("can't find user\n"); + exit(1); + } + + host_speed = host.p_fpops + host.p_iops + host.p_membw/10; + credit = result.cpu_time*host_speed; + + result.granted_credit = credit; + retval = db_result_update(result); + if (retval) { + printf("can't update result\n"); + } + + now = time(0); + if (user.expavg_time) { + deltat = now - user.expavg_time; + user.expavg_credit *= exp(deltat*EXP_DECAY_RATE); + } + user.expavg_credit += credit; + user.expavg_time = now; + retval = db_user_update(user); + if (retval) { + printf("can't update user\n"); + } + + if (host.expavg_time) { + deltat = now - host.expavg_time; + host.expavg_credit *= exp(deltat*EXP_DECAY_RATE); + } + host.expavg_credit += credit; + host.expavg_time = now; + retval = db_host_update(host); + if (retval) { + printf("can't update host\n"); + } + +}