mirror of https://github.com/BOINC/boinc.git
*** empty log message ***
svn path=/trunk/boinc/; revision=11253
This commit is contained in:
parent
a499d5a90e
commit
d5fd6240e7
|
@ -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
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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.
|
||||
|
|
18
lib/prefs.C
18
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 <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(
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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() {
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Reference in New Issue