From d5fd6240e782a3f114f3d3a90b500aa74f94da2f Mon Sep 17 00:00:00 2001 From: David Anderson Date: Fri, 6 Oct 2006 18:52:50 +0000 Subject: [PATCH] *** empty log message *** svn path=/trunk/boinc/; revision=11253 --- checkin_notes | 63 ++++++++++++++++++++++++----- doc/acct_mgt.php | 5 +++ doc/auto_start.php | 3 +- doc/boinc_news.inc | 9 +++++ lib/prefs.C | 18 +++++++-- lib/prefs.h | 1 + sched/handle_request.C | 92 +++++++++++++++++++++++++++--------------- sched/sched_send.C | 9 +++-- sched/server_types.C | 12 ++++++ sched/server_types.h | 5 ++- 10 files changed, 165 insertions(+), 52 deletions(-) diff --git a/checkin_notes b/checkin_notes index 0bc7175613..b2ca989892 100755 --- a/checkin_notes +++ b/checkin_notes @@ -10829,15 +10829,56 @@ Charlie & Rom 4 Oct 2006 clientgui/ sg_ViewTabPage.cpp -Kevin 29 Sept 2006 - - BSG - - Changed workunit area to use a static image rather then an animiated gif - - Center the image within the space and resize it dyanmically if necessary to fit - within the allocated space - - These changes should have been checked in with my changes on Sept 29 - - - clientgui/ - sg_ImageButton.cpp - sg_ViewTabPage.cpp/h +David 6 Oct 2006 + There's a problem with the current global prefs design: + A client has two different forms of global prefs: + - the "master prefs", which are stored on disk (in global_prefs.xml), + which have a mod time, and which can include elements. + - the "working prefs", which are formed by taking the + master prefs (using the venue variant for this host) + and then modifying it by the contents of the prefs override file. + The working prefs determine what the core client actually does, + i.e. how much memory/disk it uses. + When the client makes a scheduler RPC, the request message includes + global prefs, which are used for two purposes: + 1) so that the scheduler can take the prefs into account in making + scheduling decisions; + 2) to propagate preferences between projects, so that users + see consistent prefs, and can edit them on any project site. + The problem is: for 1), the scheduler needs the working prefs. + For 2), it needs the master prefs. + Currently the client sends the master prefs. + So in some cases, scheduling decisions are now based + on the wrong information. + Fix: include both master prefs and working prefs in request msg. + New server logic: + + if request message includes + P = + else + if req msg includes + if newer than DB + P = + else + P = DB prefs + + use P for sched decisions + + If request message includes , + and mod time is later than DB version, + and email hash is the same, + update DB + + Reply: if DB prefs have later mod time than P + send DB prefs in reply + + ----------------------- + - prefs: bandwidth limits default to zero (unenforced) rather than 1e12 + + lib/ + prefs.C,h + sched/ + handle_request.C + sched_send.C + server_types.C,h diff --git a/doc/acct_mgt.php b/doc/acct_mgt.php index 850d569a3e..0c6046e5aa 100644 --- a/doc/acct_mgt.php +++ b/doc/acct_mgt.php @@ -235,12 +235,15 @@ c8b3217e6cdff938ec0454330c70553fbe3d1f0d0184d8c628db2e093121ee98 [ ... ] [ MSG ] [ xxx ] + [ [ http://a.b.c ] [ http://a.b.c ] 1144105331 ... [ global preferences ] + ] + [ venue ] [ URL @@ -284,6 +287,8 @@ list_item("action", is included in the AM URL file (see above).
global_preferences
The current global preferences. +
venue +
The host venue In addition, a list of projects and their suspended flags is included.

diff --git a/doc/auto_start.php b/doc/auto_start.php index bc285b94be..de36c65d9b 100644 --- a/doc/auto_start.php +++ b/doc/auto_start.php @@ -39,7 +39,8 @@ To automatically run BOINC as a daemon or system service at boot time, or to pre automatically when selected users log in, see the Mac administrator tools.

If you install the command-line client and want it to start automatically when each user logs in, see the -Instructions from Berki Yenigun, deadsmile at minitel.net +Instructions from Berki Yenigun, +stegozor@gmail.com. "; page_tail(); diff --git a/doc/boinc_news.inc b/doc/boinc_news.inc index 9f95e89fb1..a196c791e7 100644 --- a/doc/boinc_news.inc +++ b/doc/boinc_news.inc @@ -1,6 +1,15 @@ BOINC UK + or a mirror at Berkeley." +), array("September 26, 2006", "The 2nd Annual Pangalactic BOINC Workshop was held in Geneva on 20-21 September. diff --git a/lib/prefs.C b/lib/prefs.C index 3a6f09b8cd..b0c29ef6c5 100644 --- a/lib/prefs.C +++ b/lib/prefs.C @@ -64,7 +64,8 @@ void GLOBAL_PREFS::defaults() { max_bytes_sec_down = 0; cpu_usage_limit = 100; - // don't initialize source_project, source_scheduler here + // don't initialize source_project, source_scheduler, + // mod_time, host_specific here // since they are outside of elements, // and this is called when find the right venue. // Also, don't memset to 0 @@ -95,6 +96,9 @@ int GLOBAL_PREFS::parse( strcpy(source_project, ""); strcpy(source_scheduler, ""); + mod_time = 0; + host_specific = false; + return parse_override(xp, host_venue, found_venue); } @@ -205,16 +209,18 @@ int GLOBAL_PREFS::parse_override( } else if (xp.parse_double(tag, "idle_time_to_run", idle_time_to_run)) { continue; } else if (xp.parse_double(tag, "max_bytes_sec_up", max_bytes_sec_up)) { - if (max_bytes_sec_up <= 0) max_bytes_sec_up = 1e12; + if (max_bytes_sec_up < 0) max_bytes_sec_up = 0; continue; } else if (xp.parse_double(tag, "max_bytes_sec_down", max_bytes_sec_down)) { - if (max_bytes_sec_down <= 0) max_bytes_sec_down = 1e12; + if (max_bytes_sec_down < 0) max_bytes_sec_down = 0; continue; } else if (xp.parse_double(tag, "cpu_usage_limit", dtemp)) { if (dtemp > 0 && dtemp <= 100) { cpu_usage_limit = dtemp; } continue; + } else if (xp.parse_bool(tag, "host_specific", host_specific)) { + continue; } } return ERR_XML_PARSE; @@ -241,9 +247,13 @@ int GLOBAL_PREFS::parse_file( return retval; } -// this is used to write +// Write the global prefs that are actually in force +// (our particular venue, modified by overwrite file). +// This is used to write // 1) the app init data file // 2) GUI RPC get_state reply +// Not used for scheduler request; there, we just copy the +// global_prefs.xml file (which includes all venues). // int GLOBAL_PREFS::write(MIOFILE& f) { f.printf( diff --git a/lib/prefs.h b/lib/prefs.h index 3d23f09db1..135cc3c4a1 100644 --- a/lib/prefs.h +++ b/lib/prefs.h @@ -62,6 +62,7 @@ struct GLOBAL_PREFS { double cpu_usage_limit; char source_project[256]; char source_scheduler[256]; + bool host_specific; GLOBAL_PREFS(); void defaults(); diff --git a/sched/handle_request.C b/sched/handle_request.C index de1baf103a..33b56ccb4f 100644 --- a/sched/handle_request.C +++ b/sched/handle_request.C @@ -484,39 +484,69 @@ static int update_host_record(HOST& initial_host, HOST& xhost, USER& user) { return 0; } -// Decide which global prefs to use, -// (from request msg, or if absent then from user record) +// 1) Decide which global prefs to use for sched decisions: either +// - from request msg +// - from request message +// - prefs from user DB record // and parse them into the request message global_prefs field. -// Decide whether to send global prefs in reply msg +// 2) update prefs in user record if needed +// 2) send global prefs in reply msg if needed // int handle_global_prefs(SCHEDULER_REQUEST& sreq, SCHEDULER_REPLY& reply) { char buf[LARGE_BLOB_SIZE]; reply.send_global_prefs = false; + bool have_working_prefs = (strlen(sreq.working_global_prefs_xml)>0); + bool have_master_prefs = (strlen(sreq.global_prefs_xml)>0); + bool have_db_prefs = (strlen(reply.user.global_prefs)>0); + bool same_account = !strcmp( + sreq.global_prefs_source_email_hash, reply.email_hash + ); + unsigned master_mod_time=0, db_mod_time=0; + if (have_master_prefs) { + parse_int(sreq.global_prefs_xml, "", (int&)master_mod_time); + } + if (have_db_prefs) { + parse_int(reply.user.global_prefs, "", (int&)db_mod_time); + } - if (strlen(sreq.global_prefs_xml)) { - unsigned req_mod_time=0, db_mod_time=0; - bool same_account = !strcmp( - sreq.global_prefs_source_email_hash, reply.email_hash - ); - bool update_prefs = false; - - parse_int(sreq.global_prefs_xml, "", (int&)req_mod_time); - if (strlen(reply.user.global_prefs)) { - parse_int(reply.user.global_prefs, "", (int&)db_mod_time); - - // if user record has more recent prefs, - // use them and arrange to return in reply msg - // - if (req_mod_time < db_mod_time) { - strcpy(sreq.global_prefs_xml, reply.user.global_prefs); - reply.send_global_prefs = true; + // decide which prefs to use for sched decisions + // + if (have_working_prefs) { + sreq.global_prefs.parse(sreq.working_global_prefs_xml, ""); + log_messages.printf(SCHED_MSG_LOG::MSG_DEBUG, "using working prefs\n"); + } else { + if (have_master_prefs) { + if (have_db_prefs && db_mod_time > master_mod_time) { + sreq.global_prefs.parse(reply.user.global_prefs, reply.host.venue); + log_messages.printf(SCHED_MSG_LOG::MSG_DEBUG, "using db prefs - more recent\n"); } else { - if (same_account) update_prefs = true; + sreq.global_prefs.parse(sreq.global_prefs_xml, reply.host.venue); + log_messages.printf(SCHED_MSG_LOG::MSG_DEBUG, "using master prefs\n"); } } else { - if (same_account) update_prefs = true; + if (have_db_prefs) { + sreq.global_prefs.parse(reply.user.global_prefs, reply.host.venue); + log_messages.printf(SCHED_MSG_LOG::MSG_DEBUG, "using db prefs\n"); + } else { + sreq.global_prefs.defaults(); + log_messages.printf(SCHED_MSG_LOG::MSG_DEBUG, "using default prefs\n"); + } } - if (update_prefs) { + } + + // decide whether to update DB + // + if (have_master_prefs) { + bool update_user_record = false; + if (have_db_prefs) { + if (master_mod_time < db_mod_time && same_account) { + update_user_record = true; + } + } else { + if (same_account) update_user_record = true; + } + if (update_user_record) { + log_messages.printf(SCHED_MSG_LOG::MSG_DEBUG, "updating db prefs\n"); strcpy(reply.user.global_prefs, sreq.global_prefs_xml); DB_USER user; user.id = reply.user.id; @@ -530,16 +560,14 @@ int handle_global_prefs(SCHEDULER_REQUEST& sreq, SCHEDULER_REPLY& reply) { ); } } - } else { - // request message has no global prefs; - // copy from user record, and send them in reply - // - if (strlen(reply.user.global_prefs)) { - strcpy(sreq.global_prefs_xml, reply.user.global_prefs); - reply.send_global_prefs = true; - } } - sreq.global_prefs.parse(sreq.global_prefs_xml, reply.host.venue); + + // decide whether to send DB prefs in reply msg + // + if (have_db_prefs && db_mod_time > sreq.global_prefs.mod_time) { + log_messages.printf(SCHED_MSG_LOG::MSG_DEBUG, "sending db prefs in reply\n"); + reply.send_global_prefs = true; + } return 0; } diff --git a/sched/sched_send.C b/sched/sched_send.C index 8fc8085111..9df3f40864 100644 --- a/sched/sched_send.C +++ b/sched/sched_send.C @@ -126,13 +126,16 @@ double max_allowable_disk(SCHEDULER_REQUEST& req, SCHEDULER_REPLY& reply) { // -default_max_used_pct = 50 // -default_min_free_gb = .001 // - if (prefs.disk_max_used_gb == 0) + if (prefs.disk_max_used_gb == 0) { prefs.disk_max_used_gb = config.default_disk_max_used_gb; - if (prefs.disk_max_used_pct == 0) + } + if (prefs.disk_max_used_pct == 0) { prefs.disk_max_used_pct = config.default_disk_max_used_pct; + } // Always leave some disk space free - if (prefs.disk_min_free_gb < config.default_disk_min_free_gb) + if (prefs.disk_min_free_gb < config.default_disk_min_free_gb) { prefs.disk_min_free_gb = config.default_disk_min_free_gb; + } // no defaults for total/free disk space (host.d_total, d_free) // if they're zero, client will get no work. diff --git a/sched/server_types.C b/sched/server_types.C index fb388d7647..bd42ddd13a 100644 --- a/sched/server_types.C +++ b/sched/server_types.C @@ -127,6 +127,7 @@ int SCHEDULER_REQUEST::parse(FILE* fin) { prrs_fraction = 1.0; estimated_delay = 0; strcpy(global_prefs_xml, ""); + strcpy(working_global_prefs_xml, ""); strcpy(code_sign_key, ""); anonymous_platform = false; memset(&global_prefs, 0, sizeof(global_prefs)); @@ -175,6 +176,12 @@ int SCHEDULER_REQUEST::parse(FILE* fin) { } safe_strcat(global_prefs_xml, "\n"); } + else if (match_tag(buf, "")) { + while (fgets(buf, 256, fin)) { + if (strstr(buf, "")) break; + safe_strcat(working_global_prefs_xml, buf); + } + } else if (parse_str(buf, "", global_prefs_source_email_hash, sizeof(global_prefs_source_email_hash))) continue; else if (match_tag(buf, "")) { host.parse(fin); @@ -876,6 +883,11 @@ void GLOBAL_PREFS::parse(char* buf, char* venue) { if (parse_double(buf2, "", dtemp)) { ram_max_used_idle_frac = dtemp/100.; } + parse_int(buf2, "", mod_time); +} + +void GLOBAL_PREFS::defaults() { + memset(this, 0, sizeof(GLOBAL_PREFS)); } void GUI_URLS::init() { diff --git a/sched/server_types.h b/sched/server_types.h index 56485e53ce..2c7e2b0a0e 100644 --- a/sched/server_types.h +++ b/sched/server_types.h @@ -80,6 +80,7 @@ struct CLIENT_APP_VERSION { // subset of global prefs used by scheduler // struct GLOBAL_PREFS { + int mod_time; double disk_max_used_gb; double disk_max_used_pct; double disk_min_free_gb; @@ -88,6 +89,7 @@ struct GLOBAL_PREFS { double ram_max_used_idle_frac; void parse(char* buf, char* venue); + void defaults(); }; struct GUI_URLS { @@ -136,6 +138,7 @@ struct SCHEDULER_REQUEST { // host will begin any new work for this project double duration_correction_factor; char global_prefs_xml[LARGE_BLOB_SIZE]; + char working_global_prefs_xml[LARGE_BLOB_SIZE]; char code_sign_key[4096]; bool anonymous_platform; @@ -192,7 +195,7 @@ struct SCHEDULER_REPLY { // nonzero only if a new host record was created. // this tells client to reset rpc_seqno int lockfile_fd; // file descriptor of lockfile, or -1 if no lock. - bool send_global_prefs; // whether to send global preferences + bool send_global_prefs; bool nucleus_only; // send only message bool probable_user_browser; USER user;