*** empty log message ***

svn path=/trunk/boinc/; revision=11253
This commit is contained in:
David Anderson 2006-10-06 18:52:50 +00:00
parent a499d5a90e
commit d5fd6240e7
10 changed files with 165 additions and 52 deletions

View File

@ -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 <venue> 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 <working_global_preferences>
P = <working_global_prefs>
else
if req msg includes <global_preferences>
if newer than DB
P = <global_prefs>
else
P = DB prefs
use P for sched decisions
If request message includes <global_preferences>,
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

View File

@ -235,12 +235,15 @@ c8b3217e6cdff938ec0454330c70553fbe3d1f0d0184d8c628db2e093121ee98
[ ... ]
[ <error>MSG</error> ]
[ <repeat_sec>xxx</repeat_sec> ]
[
<global_preferences>
[ <source_project>http://a.b.c</source_project> ]
[ <source_scheduler>http://a.b.c</source_scheduler> ]
<mod_time>1144105331</mod_time>
... [ global preferences ]
</global_preferences>
]
[ <host_venue>venue</host_venue> ]
[
<account>
<url>URL</url>
@ -284,6 +287,8 @@ list_item("action",
is included in the AM URL file (see above).
<dt> global_preferences
<dd> The current global preferences.
<dt> venue
<dd> The host venue
</dl>
In addition, a list of projects and their suspended flags is included.
<p>

View File

@ -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 <a href=mac_admin_tools.php>Mac administrator tools</a>.
<p>
If you install the command-line client and want it to start automatically when each user logs in, see the
<a href=mac_yenigun.php>Instructions from Berki Yenigun</a>, deadsmile at minitel.net
<a href=mac_yenigun.php>Instructions from Berki Yenigun</a>,
<a mailto=stegozor@gmail.com?Subject=Boinc_automatic_startup>stegozor@gmail.com</a>.
";
page_tail();

View File

@ -1,6 +1,15 @@
<?
$project_news = array(
array("October 4, 2006",
"Eric Korpela and David Anderson were interviewed today
by Mike O'Connell of BOINC UK.
Many topics were covered, including the question of
credit and optimized clients.
Download an recording of the conversation (MP3, 13.5 MB) from
<a href=http://www.boincuk.com/david_anderson.mp3>BOINC UK</a>
or <a href=mp3/boincuk_4_oct_2006.mp3>a mirror at Berkeley</a>."
),
array("September 26, 2006",
"The 2nd Annual Pangalactic BOINC Workshop was held
in Geneva on 20-21 September.

View File

@ -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 <venue> 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(

View File

@ -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();

View File

@ -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
// - <working_global_prefs> from request msg
// - <global_prefs> 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, "<mod_time>", (int&)master_mod_time);
}
if (have_db_prefs) {
parse_int(reply.user.global_prefs, "<mod_time>", (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, "<mod_time>", (int&)req_mod_time);
if (strlen(reply.user.global_prefs)) {
parse_int(reply.user.global_prefs, "<mod_time>", (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;
}

View File

@ -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.

View File

@ -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, "</global_preferences>\n");
}
else if (match_tag(buf, "<working_global_preferences>")) {
while (fgets(buf, 256, fin)) {
if (strstr(buf, "</working_global_preferences>")) break;
safe_strcat(working_global_prefs_xml, buf);
}
}
else if (parse_str(buf, "<global_prefs_source_email_hash>", global_prefs_source_email_hash, sizeof(global_prefs_source_email_hash))) continue;
else if (match_tag(buf, "<host_info>")) {
host.parse(fin);
@ -876,6 +883,11 @@ void GLOBAL_PREFS::parse(char* buf, char* venue) {
if (parse_double(buf2, "<ram_max_used_idle_pct>", dtemp)) {
ram_max_used_idle_frac = dtemp/100.;
}
parse_int(buf2, "<mod_time>", mod_time);
}
void GLOBAL_PREFS::defaults() {
memset(this, 0, sizeof(GLOBAL_PREFS));
}
void GUI_URLS::init() {

View File

@ -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;