2008-08-06 18:36:30 +00:00
|
|
|
// This file is part of BOINC.
|
2005-01-20 23:22:22 +00:00
|
|
|
// http://boinc.berkeley.edu
|
2012-06-05 03:48:05 +00:00
|
|
|
// Copyright (C) 2012 University of California
|
2003-08-15 22:39:56 +00:00
|
|
|
//
|
2008-08-06 18:36:30 +00:00
|
|
|
// BOINC is free software; you can redistribute it and/or modify it
|
|
|
|
// under the terms of the GNU Lesser General Public License
|
|
|
|
// as published by the Free Software Foundation,
|
|
|
|
// either version 3 of the License, or (at your option) any later version.
|
2003-08-15 22:39:56 +00:00
|
|
|
//
|
2008-08-06 18:36:30 +00:00
|
|
|
// BOINC is distributed in the hope that it will be useful,
|
2005-01-20 23:22:22 +00:00
|
|
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
|
|
|
// See the GNU Lesser General Public License for more details.
|
2002-04-30 22:22:54 +00:00
|
|
|
//
|
2008-08-06 18:36:30 +00:00
|
|
|
// You should have received a copy of the GNU Lesser General Public License
|
|
|
|
// along with BOINC. If not, see <http://www.gnu.org/licenses/>.
|
2008-05-06 19:53:49 +00:00
|
|
|
|
2005-11-21 18:34:44 +00:00
|
|
|
#include "config.h"
|
2009-02-26 00:23:23 +00:00
|
|
|
#include <cstdlib>
|
2004-08-03 21:51:30 +00:00
|
|
|
#include <cassert>
|
2002-09-26 23:12:13 +00:00
|
|
|
#include <vector>
|
|
|
|
#include <string>
|
2008-02-27 23:26:38 +00:00
|
|
|
#include <cstring>
|
2002-09-26 23:12:13 +00:00
|
|
|
|
2002-04-30 22:22:54 +00:00
|
|
|
#include "parse.h"
|
2004-01-08 00:27:59 +00:00
|
|
|
#include "error_numbers.h"
|
2007-02-21 16:26:51 +00:00
|
|
|
#include "str_util.h"
|
2007-06-22 23:48:37 +00:00
|
|
|
#include "util.h"
|
- server: change the following from per-host to per-(host, app version):
- daily quota mechanism
- reliable mechanism (accelerated retries)
- "trusted" mechanism (adaptive replication)
- scheduler: enforce host scale probation only for apps with
host_scale_check set.
- validator: do scale probation on invalid results
(need this in addition to error and timeout cases)
- feeder: update app version scales every 10 min, not 10 sec
- back-end apps: support --foo as well as -foo for options
Notes:
- If you have, say, cuda, cuda23 and cuda_fermi plan classes,
a host will have separate quotas for each one.
That means it could error out on 100 jobs for cuda_fermi,
and when its quota goes to zero,
error out on 100 jobs for cuda23, etc.
This is intentional; there may be cases where one version
works but not the others.
- host.error_rate and host.max_results_day are deprecated
TODO:
- the values in the app table for limits on jobs in progress etc.
should override rather than config.xml.
Implementation notes:
scheduler:
process_request():
read all host_app_versions for host at start;
Compute "reliable" and "trusted" for each one.
write modified records at end
get_app_version():
add "reliable_only" arg; if set, use only reliable versions
skip over-quota versions
Multi-pass scheduling: if have at least one reliable version,
do a pass for jobs that need reliable,
and use only reliable versions.
Then clear best_app_versions cache.
Score-based scheduling: for need-reliable jobs,
it will pick the fastest version,
then give a score bonus if that version happens to be reliable.
When get back a successful result from client:
increase daily quota
When get back an error result from client:
impose scale probation
decrease daily quota if not aborted
Validator:
when handling a WU, create a vector of HOST_APP_VERSION
parallel to vector of RESULT.
Pass it to assign_credit_set().
Make copies of originals so we can update only modified ones
update HOST_APP_VERSION error rates
Transitioner:
decrease quota on timeout
svn path=/trunk/boinc/; revision=21181
2010-04-15 03:13:56 +00:00
|
|
|
#include "boinc_db.h"
|
2009-08-10 04:56:46 +00:00
|
|
|
|
2009-08-10 04:49:02 +00:00
|
|
|
#include "sched_main.h"
|
2003-06-11 23:36:40 +00:00
|
|
|
#include "sched_util.h"
|
2004-04-08 08:15:23 +00:00
|
|
|
#include "sched_msgs.h"
|
2009-08-26 18:21:36 +00:00
|
|
|
#include "sched_send.h"
|
2008-01-13 00:12:14 +00:00
|
|
|
#include "time_stats_log.h"
|
2009-08-10 04:56:46 +00:00
|
|
|
#include "sched_types.h"
|
2002-04-30 22:22:54 +00:00
|
|
|
|
2004-04-30 19:33:05 +00:00
|
|
|
#ifdef _USING_FCGI_
|
2008-09-09 19:10:42 +00:00
|
|
|
#include "boinc_fcgi.h"
|
2004-04-30 19:33:05 +00:00
|
|
|
#endif
|
|
|
|
|
2011-09-06 22:53:48 +00:00
|
|
|
using std::string;
|
|
|
|
|
2008-12-15 21:14:32 +00:00
|
|
|
SCHEDULER_REQUEST* g_request;
|
|
|
|
SCHEDULER_REPLY* g_reply;
|
2008-12-16 16:29:54 +00:00
|
|
|
WORK_REQ* g_wreq;
|
2008-12-15 21:14:32 +00:00
|
|
|
|
2005-10-26 06:29:35 +00:00
|
|
|
// remove (by truncating) any quotes from the given string.
|
|
|
|
// This is for things (e.g. authenticator) that will be used in
|
|
|
|
// a SQL query, to prevent SQL injection attacks
|
|
|
|
//
|
|
|
|
void remove_quotes(char* p) {
|
|
|
|
int i, n=strlen(p);
|
|
|
|
for (i=0; i<n; i++) {
|
|
|
|
if (p[i]=='\'' || p[i]=='"') {
|
|
|
|
p[i] = 0;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2011-08-10 17:11:08 +00:00
|
|
|
int CLIENT_APP_VERSION::parse(XML_PARSER& xp) {
|
2010-06-18 22:21:36 +00:00
|
|
|
double x;
|
2004-01-26 19:29:39 +00:00
|
|
|
|
2011-08-08 04:37:53 +00:00
|
|
|
memset(this, 0, sizeof(*this));
|
2010-06-18 22:21:36 +00:00
|
|
|
host_usage.avg_ncpus = 1;
|
2011-08-11 21:15:42 +00:00
|
|
|
while (!xp.get_tag()) {
|
|
|
|
if (xp.match_tag("/app_version")) {
|
2010-04-08 23:14:47 +00:00
|
|
|
app = ssp->lookup_app_name(app_name);
|
|
|
|
if (!app) return ERR_NOT_FOUND;
|
2010-06-18 22:21:36 +00:00
|
|
|
|
2011-07-01 02:12:11 +00:00
|
|
|
double pf = host_usage.avg_ncpus * g_reply->host.p_fpops;
|
2012-06-25 23:09:45 +00:00
|
|
|
if (host_usage.proc_type != PROC_TYPE_CPU) {
|
|
|
|
COPROC* cp = g_request->coprocs.type_to_coproc(host_usage.proc_type);
|
|
|
|
pf += host_usage.gpu_usage*cp->peak_flops;
|
2010-06-18 22:21:36 +00:00
|
|
|
}
|
2011-07-01 02:12:11 +00:00
|
|
|
host_usage.peak_flops = pf;
|
2010-04-08 23:14:47 +00:00
|
|
|
return 0;
|
|
|
|
}
|
2011-08-11 21:15:42 +00:00
|
|
|
if (xp.parse_str("app_name", app_name, 256)) continue;
|
|
|
|
if (xp.parse_str("platform", platform, 256)) continue;
|
|
|
|
if (xp.parse_str("plan_class", plan_class, 256)) continue;
|
|
|
|
if (xp.parse_int("version_num", version_num)) continue;
|
|
|
|
if (xp.parse_double("avg_ncpus", x)) {
|
2010-06-18 22:21:36 +00:00
|
|
|
if (x>0) host_usage.avg_ncpus = x;
|
2010-04-10 05:49:51 +00:00
|
|
|
continue;
|
|
|
|
}
|
2011-08-11 21:15:42 +00:00
|
|
|
if (xp.parse_double("flops", x)) {
|
2010-07-15 21:38:24 +00:00
|
|
|
if (x>0) host_usage.projected_flops = x;
|
2010-07-23 17:43:20 +00:00
|
|
|
continue;
|
2010-07-15 21:38:24 +00:00
|
|
|
}
|
2011-08-11 21:15:42 +00:00
|
|
|
if (xp.match_tag("coproc")) {
|
2010-01-18 19:22:03 +00:00
|
|
|
COPROC_REQ coproc_req;
|
2011-08-10 17:11:08 +00:00
|
|
|
int retval = coproc_req.parse(xp);
|
2012-06-22 07:35:54 +00:00
|
|
|
if (!retval) {
|
|
|
|
host_usage.gpu_usage = coproc_req.count;
|
|
|
|
if (!strcmp(coproc_req.type, "CUDA") || !strcmp(coproc_req.type, "NVIDIA")) {
|
2012-06-25 23:09:45 +00:00
|
|
|
host_usage.proc_type = PROC_TYPE_NVIDIA_GPU;
|
|
|
|
} else if (!strcmp(coproc_req.type, "ATI")) {
|
|
|
|
host_usage.proc_type = PROC_TYPE_AMD_GPU;
|
|
|
|
} else if (!strcmp(coproc_req.type, "INTEL_GPU")) {
|
|
|
|
host_usage.proc_type = PROC_TYPE_INTEL_GPU;
|
|
|
|
}
|
2009-08-17 17:07:38 +00:00
|
|
|
}
|
2010-07-23 17:43:20 +00:00
|
|
|
continue;
|
- scheduler: add support for anonymous-platform coproc apps.
Old: although the request message contained all info
about the app version (flops, coproc usage etc.)
the server ignored this info,
and assumed that all anonymous platform apps where CPU.
With 6.6 client, this could produce infinite work fetch:
- client uses anon platform, has coproc app
- client has idle CPU, requests CPU work
- scheduler sends it jobs, thinking they will be done by CPU app
- client asks for more work etc.
New: scheduler parses full info on anon platform app versions:
plan class, FLOPS, coprocs.
It uses this info to make scheduling decisions;
in particular, if the request is for CUDA work,
if will only send jobs that use a CUDA app version.
The <result> records it returns contain info
(plan_class) that tells the client which app_version to use.
This will work correctly even if the client has multiple app versions
for the same app (e.g., a CPU version and a GPU version)
svn path=/trunk/boinc/; revision=17506
2009-03-05 17:30:10 +00:00
|
|
|
}
|
2004-01-26 19:29:39 +00:00
|
|
|
}
|
|
|
|
return ERR_XML_PARSE;
|
|
|
|
}
|
|
|
|
|
2011-08-10 17:11:08 +00:00
|
|
|
int FILE_INFO::parse(XML_PARSER& xp) {
|
2011-08-08 04:37:53 +00:00
|
|
|
memset(this, 0, sizeof(*this));
|
2011-08-11 21:15:42 +00:00
|
|
|
while (!xp.get_tag()) {
|
|
|
|
if (xp.match_tag("/file_info")) {
|
2004-09-10 21:02:11 +00:00
|
|
|
if (!strlen(name)) return ERR_XML_PARSE;
|
|
|
|
return 0;
|
|
|
|
}
|
2011-08-11 21:15:42 +00:00
|
|
|
if (xp.parse_str("name", name, 256)) continue;
|
2004-09-10 21:02:11 +00:00
|
|
|
}
|
|
|
|
return ERR_XML_PARSE;
|
|
|
|
}
|
|
|
|
|
2011-08-10 17:11:08 +00:00
|
|
|
int OTHER_RESULT::parse(XML_PARSER& xp) {
|
2009-06-01 22:15:14 +00:00
|
|
|
strcpy(name, "");
|
|
|
|
have_plan_class = false;
|
2010-06-01 23:41:07 +00:00
|
|
|
app_version = -1;
|
2011-08-11 21:15:42 +00:00
|
|
|
while (!xp.get_tag()) {
|
|
|
|
if (xp.match_tag("/other_result")) {
|
2010-06-29 03:20:19 +00:00
|
|
|
if (!strcmp(name, "")) return ERR_XML_PARSE;
|
2005-07-28 09:00:19 +00:00
|
|
|
return 0;
|
|
|
|
}
|
2011-08-11 21:15:42 +00:00
|
|
|
if (xp.parse_str("name", name, sizeof(name))) continue;
|
|
|
|
if (xp.parse_int("app_version", app_version)) continue;
|
|
|
|
if (xp.parse_str("plan_class", plan_class, sizeof(plan_class))) {
|
2009-06-01 22:15:14 +00:00
|
|
|
have_plan_class = true;
|
|
|
|
continue;
|
|
|
|
}
|
2005-07-28 09:00:19 +00:00
|
|
|
}
|
|
|
|
return ERR_XML_PARSE;
|
|
|
|
}
|
|
|
|
|
2011-08-10 17:11:08 +00:00
|
|
|
int IP_RESULT::parse(XML_PARSER& xp) {
|
2005-07-28 09:00:19 +00:00
|
|
|
report_deadline = 0;
|
|
|
|
cpu_time_remaining = 0;
|
- scheduler: add <workload_sim> config option.
If set, the scheduler will use EDF simulation,
together with the in-progress workload reported by the client,
to avoid sending results that
1) will miss their deadline, or
2) will cause an in-progress result to miss its deadline, or
3) will make an in-progress result miss its deadline
by more than is already predicted.
If this option is not set, or if the client request doesn't
include a workload description (i.e. the client is old)
use the existing approach, which assumes there's no workload.
NOTE: this is experimental. Production projects should not use it.
- EDF sim: write debug stuff to stderr instead of stdout
- Account manager:
- if an account is detach_when_done, set dont_request_more_work
- check done_request_more_work even for first-time projects
- update_uotd: generate a file for use by Google gadget
- user_links(): use full URLs (so can use in Google gadget)
client/
acct_mgr.C
work_fetch.C
html/
inc/
uotd.inc
util.inc
user/
uotd_gadget.php (new)
sched/
Makefile.am
edf_sim.C
sched_config.C,h
sched_resend.C
sched_send.C,h
server_types.C,h
svn path=/trunk/boinc/; revision=12639
2007-05-10 21:50:52 +00:00
|
|
|
strcpy(name, "");
|
2011-08-11 21:15:42 +00:00
|
|
|
while (!xp.get_tag()) {
|
|
|
|
if (xp.match_tag("/ip_result")) return 0;
|
|
|
|
if (xp.parse_str("name", name, sizeof(name))) continue;
|
|
|
|
if (xp.parse_double("report_deadline", report_deadline)) continue;
|
|
|
|
if (xp.parse_double("cpu_time_remaining", cpu_time_remaining)) continue;
|
2005-07-28 09:00:19 +00:00
|
|
|
}
|
|
|
|
return ERR_XML_PARSE;
|
|
|
|
}
|
|
|
|
|
2011-08-10 17:11:08 +00:00
|
|
|
int CLIENT_PLATFORM::parse(XML_PARSER& xp) {
|
2007-04-19 22:45:57 +00:00
|
|
|
strcpy(name, "");
|
2011-08-11 21:15:42 +00:00
|
|
|
while (!xp.get_tag()) {
|
|
|
|
if (xp.match_tag("/alt_platform")) return 0;
|
|
|
|
if (xp.parse_str("name", name, sizeof(name))) continue;
|
2007-04-19 22:45:57 +00:00
|
|
|
}
|
|
|
|
return ERR_XML_PARSE;
|
|
|
|
}
|
|
|
|
|
2008-03-07 21:13:01 +00:00
|
|
|
|
2010-04-01 22:51:19 +00:00
|
|
|
void WORK_REQ::add_no_work_message(const char* message) {
|
- server code: at some point I made a global var "SCHED_CONFIG config",
mostly so that the parse function could assume
that everything was initially zero.
However, various back-end functions pass around SCHED_CONFIG&
as an argument (also named "config").
This creates a shadow, which is always bad.
Worse is the possibility that some projects have back-end programs
that have a SCHED_CONFIG variable that's automatic,
and therefore isn't zero initially,
and therefore isn't parsing correctly.
To fix this, I changed the 2 vectors in SCHED_CONFIG into pointers,
and have the parse routine zero the structure.
I was tempted to remove the SCHED_CONFIG& args to back-end functions,
but this would have broken some projects' code.
I did, however, change the name from config to config_loc
to avoid shadowing.
Also fixed various other compiler warnings.
svn path=/trunk/boinc/; revision=15541
2008-07-02 17:24:53 +00:00
|
|
|
for (unsigned int i=0; i<no_work_messages.size(); i++) {
|
2009-08-21 19:14:15 +00:00
|
|
|
if (!strcmp(message, no_work_messages.at(i).message.c_str())){
|
2008-11-26 21:49:36 +00:00
|
|
|
return;
|
2008-03-07 21:13:01 +00:00
|
|
|
}
|
|
|
|
}
|
2010-06-29 03:23:13 +00:00
|
|
|
no_work_messages.push_back(USER_MESSAGE(message, "notice"));
|
2008-03-07 21:13:01 +00:00
|
|
|
}
|
|
|
|
|
2008-10-01 22:07:35 +00:00
|
|
|
// return an error message or NULL
|
|
|
|
//
|
2011-08-10 17:11:08 +00:00
|
|
|
const char* SCHEDULER_REQUEST::parse(XML_PARSER& xp) {
|
2011-06-06 03:40:42 +00:00
|
|
|
SCHED_DB_RESULT result;
|
2004-01-08 00:27:59 +00:00
|
|
|
int retval;
|
|
|
|
|
2002-04-30 22:22:54 +00:00
|
|
|
strcpy(authenticator, "");
|
2007-04-19 22:45:57 +00:00
|
|
|
strcpy(platform.name, "");
|
2005-05-12 00:32:03 +00:00
|
|
|
strcpy(cross_project_id, "");
|
2002-04-30 22:22:54 +00:00
|
|
|
hostid = 0;
|
2005-05-12 00:32:03 +00:00
|
|
|
core_client_major_version = 0;
|
|
|
|
core_client_minor_version = 0;
|
2005-08-31 00:18:36 +00:00
|
|
|
core_client_release = 0;
|
2011-11-29 04:47:10 +00:00
|
|
|
core_client_version = 0;
|
2005-05-12 00:32:03 +00:00
|
|
|
rpc_seqno = 0;
|
2002-04-30 22:22:54 +00:00
|
|
|
work_req_seconds = 0;
|
2009-01-10 00:43:33 +00:00
|
|
|
cpu_req_secs = 0;
|
|
|
|
cpu_req_instances = 0;
|
2004-07-06 21:51:49 +00:00
|
|
|
resource_share_fraction = 1.0;
|
2005-10-04 21:44:58 +00:00
|
|
|
rrs_fraction = 1.0;
|
|
|
|
prrs_fraction = 1.0;
|
2009-01-30 21:25:24 +00:00
|
|
|
cpu_estimated_delay = 0;
|
2003-04-03 18:35:40 +00:00
|
|
|
strcpy(global_prefs_xml, "");
|
2006-10-06 18:52:50 +00:00
|
|
|
strcpy(working_global_prefs_xml, "");
|
2003-04-03 18:35:40 +00:00
|
|
|
strcpy(code_sign_key, "");
|
2005-05-12 00:32:03 +00:00
|
|
|
memset(&global_prefs, 0, sizeof(global_prefs));
|
|
|
|
memset(&host, 0, sizeof(host));
|
2005-07-28 10:13:30 +00:00
|
|
|
have_other_results_list = false;
|
|
|
|
have_ip_results_list = false;
|
2008-01-13 00:12:14 +00:00
|
|
|
have_time_stats_log = false;
|
2008-04-02 19:05:08 +00:00
|
|
|
client_cap_plan_class = false;
|
2008-10-01 19:48:52 +00:00
|
|
|
sandbox = -1;
|
- scheduler and client: fix the "allow multiple clients" feature.
This feature lets you run the BOINC client as a job on grid systems
that handle only 1-CPU jobs;
it disables various mechanisms that prevent multiple clients per host
(which is normally a bad thing).
Old:
- Run the client with a --allow_multiple_clients flag.
This tells it not to use a mutex that prevents
multiple clients per host.
- Run the project with the <multiple_clients_per_host> config flag.
This suppresses two mechanisms:
- (avoid duplicate host records)
on a scheduler request with no host ID,
looks for a host with same domain name, OS type,
and mem size, and assumes the request is from that host
- (job retry)
If we get a request that doesn't have a host ID
but does have a host CPID,
mark its in-progress results as over
NOTE: I CAN'T REMEMBER WHY WE SUPPRESS THIS;
MARK S, DO YOU REMEMBER?
Problem:
if the grid clients attach to a project that
doesn't use <multiple_clients_per_host>, bad things happen.
E.g., if there are several requests at about the same time,
most of them will fail with
"another RPC already in progress" errors.
If a project does include this flag,
it loses protection from duplicate host records.
New:
- If the client is run with --allow_multiple_clients flag,
it passes a <allow_multiple_clients> element
in scheduler requests.
- The scheduler skips the duplicate-host check on
requests that include this flag.
- There is no more <multiple_clients_per_host> scheduler option.
Note: if a project using the old mechanism upgrades to this change,
it will need to use new clients for its grid deployment.
svn path=/trunk/boinc/; revision=21839
2010-06-29 16:37:28 +00:00
|
|
|
allow_multiple_clients = -1;
|
2012-06-05 03:48:05 +00:00
|
|
|
results_truncated = false;
|
2002-04-30 22:22:54 +00:00
|
|
|
|
2011-08-11 21:15:42 +00:00
|
|
|
if (xp.get_tag()) {
|
|
|
|
return "xp.get_tag() failed";
|
2010-06-29 03:20:19 +00:00
|
|
|
}
|
2011-08-11 21:15:42 +00:00
|
|
|
if (xp.match_tag("?xml")) {
|
|
|
|
xp.get_tag();
|
2011-02-23 01:03:46 +00:00
|
|
|
}
|
2011-08-11 21:15:42 +00:00
|
|
|
if (!xp.match_tag("scheduler_request")) return "no start tag";
|
|
|
|
while (!xp.get_tag()) {
|
|
|
|
if (xp.match_tag("/scheduler_request")) {
|
2010-01-13 17:28:59 +00:00
|
|
|
core_client_version = 10000*core_client_major_version + 100*core_client_minor_version + core_client_release;
|
2008-10-01 22:07:35 +00:00
|
|
|
return NULL;
|
|
|
|
}
|
2011-08-11 21:15:42 +00:00
|
|
|
if (xp.parse_str("authenticator", authenticator, sizeof(authenticator))) {
|
2005-10-26 06:29:35 +00:00
|
|
|
remove_quotes(authenticator);
|
|
|
|
continue;
|
|
|
|
}
|
2011-08-11 21:15:42 +00:00
|
|
|
if (xp.parse_str("cross_project_id", cross_project_id, sizeof(cross_project_id))) continue;
|
|
|
|
if (xp.parse_int("hostid", hostid)) continue;
|
|
|
|
if (xp.parse_int("rpc_seqno", rpc_seqno)) continue;
|
|
|
|
if (xp.parse_str("platform_name", platform.name, sizeof(platform.name))) continue;
|
|
|
|
if (xp.match_tag("alt_platform")) {
|
2007-04-19 22:45:57 +00:00
|
|
|
CLIENT_PLATFORM cp;
|
2011-08-10 17:11:08 +00:00
|
|
|
retval = cp.parse(xp);
|
2007-04-19 22:45:57 +00:00
|
|
|
if (!retval) {
|
|
|
|
alt_platforms.push_back(cp);
|
|
|
|
}
|
2007-06-14 23:08:43 +00:00
|
|
|
continue;
|
2007-04-19 22:45:57 +00:00
|
|
|
}
|
2011-08-11 21:15:42 +00:00
|
|
|
if (xp.match_tag("app_versions")) {
|
|
|
|
while (!xp.get_tag()) {
|
|
|
|
if (xp.match_tag("/app_versions")) break;
|
|
|
|
if (xp.match_tag("app_version")) {
|
2004-01-26 19:29:39 +00:00
|
|
|
CLIENT_APP_VERSION cav;
|
2011-08-10 17:11:08 +00:00
|
|
|
retval = cav.parse(xp);
|
2010-04-08 23:14:47 +00:00
|
|
|
if (retval) {
|
2010-08-02 03:43:38 +00:00
|
|
|
if (!strcmp(platform.name, "anonymous")) {
|
2010-07-23 17:43:20 +00:00
|
|
|
if (retval == ERR_NOT_FOUND) {
|
|
|
|
g_reply->insert_message(
|
|
|
|
_("Unknown app name in app_info.xml"),
|
|
|
|
"notice"
|
|
|
|
);
|
|
|
|
} else {
|
|
|
|
g_reply->insert_message(
|
|
|
|
_("Syntax error in app_info.xml"),
|
|
|
|
"notice"
|
|
|
|
);
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
// this case happens if the app version
|
|
|
|
// refers to a deprecated app
|
|
|
|
}
|
|
|
|
cav.app = 0;
|
2010-04-08 23:14:47 +00:00
|
|
|
}
|
2010-07-23 17:43:20 +00:00
|
|
|
// store the CLIENT_APP_VERSION even if it didn't parse.
|
|
|
|
// This is necessary to maintain the correspondence
|
|
|
|
// with result.app_version
|
|
|
|
//
|
|
|
|
client_app_versions.push_back(cav);
|
2004-01-26 19:29:39 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
continue;
|
|
|
|
}
|
2011-08-11 21:15:42 +00:00
|
|
|
if (xp.parse_int("core_client_major_version", core_client_major_version)) continue;
|
|
|
|
if (xp.parse_int("core_client_minor_version", core_client_minor_version)) continue;
|
|
|
|
if (xp.parse_int("core_client_release", core_client_release)) continue;
|
|
|
|
if (xp.parse_double("work_req_seconds", work_req_seconds)) continue;
|
|
|
|
if (xp.parse_double("cpu_req_secs", cpu_req_secs)) continue;
|
|
|
|
if (xp.parse_double("cpu_req_instances", cpu_req_instances)) continue;
|
|
|
|
if (xp.parse_double("resource_share_fraction", resource_share_fraction)) continue;
|
|
|
|
if (xp.parse_double("rrs_fraction", rrs_fraction)) continue;
|
|
|
|
if (xp.parse_double("prrs_fraction", prrs_fraction)) continue;
|
|
|
|
if (xp.parse_double("estimated_delay", cpu_estimated_delay)) continue;
|
|
|
|
if (xp.parse_double("duration_correction_factor", host.duration_correction_factor)) continue;
|
|
|
|
if (xp.match_tag("global_preferences")) {
|
2003-04-03 18:35:40 +00:00
|
|
|
strcpy(global_prefs_xml, "<global_preferences>\n");
|
2011-11-15 00:11:12 +00:00
|
|
|
char buf[BLOB_SIZE];
|
2011-08-11 21:15:42 +00:00
|
|
|
retval = xp.element_contents(
|
|
|
|
"</global_preferences>", buf, sizeof(buf)
|
|
|
|
);
|
|
|
|
if (retval) return "error copying global prefs";
|
|
|
|
safe_strcat(global_prefs_xml, buf);
|
2003-04-03 18:35:40 +00:00
|
|
|
safe_strcat(global_prefs_xml, "</global_preferences>\n");
|
2007-06-14 23:08:43 +00:00
|
|
|
continue;
|
2002-06-01 20:26:21 +00:00
|
|
|
}
|
2011-08-11 21:15:42 +00:00
|
|
|
if (xp.match_tag("working_global_preferences")) {
|
|
|
|
retval = xp.element_contents(
|
|
|
|
"</working_global_preferences>",
|
|
|
|
working_global_prefs_xml,
|
|
|
|
sizeof(working_global_prefs_xml)
|
|
|
|
);
|
|
|
|
if (retval) return "error copying working global prefs";
|
2007-06-14 23:08:43 +00:00
|
|
|
continue;
|
2006-10-06 18:52:50 +00:00
|
|
|
}
|
2011-08-11 21:15:42 +00:00
|
|
|
if (xp.parse_str("global_prefs_source_email_hash", global_prefs_source_email_hash, sizeof(global_prefs_source_email_hash))) continue;
|
|
|
|
if (xp.match_tag("host_info")) {
|
2011-08-10 17:11:08 +00:00
|
|
|
host.parse(xp);
|
2002-04-30 22:22:54 +00:00
|
|
|
continue;
|
|
|
|
}
|
2011-08-11 21:15:42 +00:00
|
|
|
if (xp.match_tag("time_stats")) {
|
2011-08-10 17:11:08 +00:00
|
|
|
host.parse_time_stats(xp);
|
2002-04-30 22:22:54 +00:00
|
|
|
continue;
|
|
|
|
}
|
2011-08-11 21:15:42 +00:00
|
|
|
if (xp.match_tag("time_stats_log")) {
|
2011-08-10 17:11:08 +00:00
|
|
|
handle_time_stats_log(xp.f->f);
|
2008-01-13 00:12:14 +00:00
|
|
|
have_time_stats_log = true;
|
|
|
|
continue;
|
|
|
|
}
|
2011-08-11 21:15:42 +00:00
|
|
|
if (xp.match_tag("net_stats")) {
|
2011-08-10 17:11:08 +00:00
|
|
|
host.parse_net_stats(xp);
|
2002-04-30 22:22:54 +00:00
|
|
|
continue;
|
|
|
|
}
|
2011-08-11 21:15:42 +00:00
|
|
|
if (xp.match_tag("disk_usage")) {
|
2011-08-10 17:11:08 +00:00
|
|
|
host.parse_disk_usage(xp);
|
2005-10-04 21:44:58 +00:00
|
|
|
continue;
|
|
|
|
}
|
2011-08-11 21:15:42 +00:00
|
|
|
if (xp.match_tag("result")) {
|
2011-08-10 17:11:08 +00:00
|
|
|
retval = result.parse_from_client(xp);
|
2011-07-19 20:52:41 +00:00
|
|
|
if (retval) continue;
|
|
|
|
if (strstr(result.name, "download") || strstr(result.name, "upload")) {
|
|
|
|
file_xfer_results.push_back(result);
|
|
|
|
continue;
|
|
|
|
}
|
2012-06-07 18:34:53 +00:00
|
|
|
if (config.max_results_accepted && (int)(results.size()) >= config.max_results_accepted) {
|
2012-06-05 03:48:05 +00:00
|
|
|
results_truncated = true;
|
2010-09-30 21:40:44 +00:00
|
|
|
continue;
|
|
|
|
}
|
|
|
|
// check if client is sending the same result twice.
|
|
|
|
// Shouldn't happen, but if it does bad things will happen
|
|
|
|
//
|
|
|
|
bool found = false;
|
|
|
|
for (unsigned int i=0; i<results.size(); i++) {
|
|
|
|
if (!strcmp(results[i].name, result.name)) {
|
|
|
|
found = true;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (!found) {
|
|
|
|
results.push_back(result);
|
|
|
|
}
|
2002-04-30 22:22:54 +00:00
|
|
|
continue;
|
|
|
|
}
|
2011-08-11 21:15:42 +00:00
|
|
|
if (xp.match_tag("code_sign_key")) {
|
|
|
|
copy_element_contents(xp.f->f, "</code_sign_key>", code_sign_key, sizeof(code_sign_key));
|
|
|
|
strip_whitespace(code_sign_key);
|
2007-06-14 23:08:43 +00:00
|
|
|
continue;
|
2002-07-07 20:39:24 +00:00
|
|
|
}
|
2011-08-11 21:15:42 +00:00
|
|
|
if (xp.match_tag("msg_from_host")) {
|
2004-06-24 21:00:13 +00:00
|
|
|
MSG_FROM_HOST_DESC md;
|
2011-08-10 17:11:08 +00:00
|
|
|
retval = md.parse(xp);
|
2004-01-08 00:27:59 +00:00
|
|
|
if (!retval) {
|
2004-06-24 21:00:13 +00:00
|
|
|
msgs_from_host.push_back(md);
|
2004-01-08 00:27:59 +00:00
|
|
|
}
|
2007-06-14 23:08:43 +00:00
|
|
|
continue;
|
2004-09-10 21:02:11 +00:00
|
|
|
}
|
2011-08-11 21:15:42 +00:00
|
|
|
if (xp.match_tag("file_info")) {
|
2004-09-10 21:02:11 +00:00
|
|
|
FILE_INFO fi;
|
2011-08-10 17:11:08 +00:00
|
|
|
retval = fi.parse(xp);
|
2004-09-10 21:02:11 +00:00
|
|
|
if (!retval) {
|
|
|
|
file_infos.push_back(fi);
|
|
|
|
}
|
2005-06-25 17:48:17 +00:00
|
|
|
continue;
|
2007-06-14 23:08:43 +00:00
|
|
|
}
|
2011-08-11 21:15:42 +00:00
|
|
|
if (xp.match_tag("host_venue")) {
|
2007-06-14 23:08:43 +00:00
|
|
|
continue;
|
|
|
|
}
|
2011-08-11 21:15:42 +00:00
|
|
|
if (xp.match_tag("other_results")) {
|
2005-07-28 10:13:30 +00:00
|
|
|
have_other_results_list = true;
|
2011-08-11 21:15:42 +00:00
|
|
|
while (!xp.get_tag()) {
|
|
|
|
if (xp.match_tag("/other_results")) break;
|
|
|
|
if (xp.match_tag("other_result")) {
|
2005-07-28 09:00:19 +00:00
|
|
|
OTHER_RESULT o_r;
|
2011-08-10 17:11:08 +00:00
|
|
|
retval = o_r.parse(xp);
|
2005-07-28 09:00:19 +00:00
|
|
|
if (!retval) {
|
|
|
|
other_results.push_back(o_r);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2005-06-25 17:48:17 +00:00
|
|
|
continue;
|
2007-06-14 23:08:43 +00:00
|
|
|
}
|
2011-08-11 21:15:42 +00:00
|
|
|
if (xp.match_tag("in_progress_results")) {
|
2005-07-28 10:13:30 +00:00
|
|
|
have_ip_results_list = true;
|
- scheduler: add <workload_sim> config option.
If set, the scheduler will use EDF simulation,
together with the in-progress workload reported by the client,
to avoid sending results that
1) will miss their deadline, or
2) will cause an in-progress result to miss its deadline, or
3) will make an in-progress result miss its deadline
by more than is already predicted.
If this option is not set, or if the client request doesn't
include a workload description (i.e. the client is old)
use the existing approach, which assumes there's no workload.
NOTE: this is experimental. Production projects should not use it.
- EDF sim: write debug stuff to stderr instead of stdout
- Account manager:
- if an account is detach_when_done, set dont_request_more_work
- check done_request_more_work even for first-time projects
- update_uotd: generate a file for use by Google gadget
- user_links(): use full URLs (so can use in Google gadget)
client/
acct_mgr.C
work_fetch.C
html/
inc/
uotd.inc
util.inc
user/
uotd_gadget.php (new)
sched/
Makefile.am
edf_sim.C
sched_config.C,h
sched_resend.C
sched_send.C,h
server_types.C,h
svn path=/trunk/boinc/; revision=12639
2007-05-10 21:50:52 +00:00
|
|
|
int i = 0;
|
|
|
|
double now = time(0);
|
2011-08-11 21:15:42 +00:00
|
|
|
while (!xp.get_tag()) {
|
|
|
|
if (xp.match_tag("/in_progress_results")) break;
|
|
|
|
if (xp.match_tag("ip_result")) {
|
2005-07-28 09:00:19 +00:00
|
|
|
IP_RESULT ir;
|
2011-08-10 17:11:08 +00:00
|
|
|
retval = ir.parse(xp);
|
2005-07-28 09:00:19 +00:00
|
|
|
if (!retval) {
|
- scheduler: add <workload_sim> config option.
If set, the scheduler will use EDF simulation,
together with the in-progress workload reported by the client,
to avoid sending results that
1) will miss their deadline, or
2) will cause an in-progress result to miss its deadline, or
3) will make an in-progress result miss its deadline
by more than is already predicted.
If this option is not set, or if the client request doesn't
include a workload description (i.e. the client is old)
use the existing approach, which assumes there's no workload.
NOTE: this is experimental. Production projects should not use it.
- EDF sim: write debug stuff to stderr instead of stdout
- Account manager:
- if an account is detach_when_done, set dont_request_more_work
- check done_request_more_work even for first-time projects
- update_uotd: generate a file for use by Google gadget
- user_links(): use full URLs (so can use in Google gadget)
client/
acct_mgr.C
work_fetch.C
html/
inc/
uotd.inc
util.inc
user/
uotd_gadget.php (new)
sched/
Makefile.am
edf_sim.C
sched_config.C,h
sched_resend.C
sched_send.C,h
server_types.C,h
svn path=/trunk/boinc/; revision=12639
2007-05-10 21:50:52 +00:00
|
|
|
if (!strlen(ir.name)) {
|
|
|
|
sprintf(ir.name, "ip%d", i++);
|
|
|
|
}
|
|
|
|
ir.report_deadline -= now;
|
2005-07-28 09:00:19 +00:00
|
|
|
ip_results.push_back(ir);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2005-06-25 17:48:17 +00:00
|
|
|
continue;
|
2003-01-07 01:02:08 +00:00
|
|
|
}
|
2011-08-11 21:15:42 +00:00
|
|
|
if (xp.match_tag("coprocs")) {
|
2011-08-10 17:11:08 +00:00
|
|
|
coprocs.parse(xp);
|
2008-03-10 21:59:27 +00:00
|
|
|
continue;
|
|
|
|
}
|
2011-08-11 21:15:42 +00:00
|
|
|
if (xp.parse_bool("client_cap_plan_class", client_cap_plan_class)) continue;
|
|
|
|
if (xp.parse_int("sandbox", sandbox)) continue;
|
|
|
|
if (xp.parse_int("allow_multiple_clients", allow_multiple_clients)) continue;
|
2011-11-14 06:27:36 +00:00
|
|
|
if (xp.parse_string("client_opaque", client_opaque)) continue;
|
2007-09-23 21:38:47 +00:00
|
|
|
|
2011-08-11 21:15:42 +00:00
|
|
|
if (xp.match_tag("active_task_set")) continue;
|
|
|
|
if (xp.match_tag("app")) continue;
|
|
|
|
if (xp.match_tag("app_version")) continue;
|
|
|
|
if (xp.match_tag("duration_variability")) continue;
|
|
|
|
if (xp.match_tag("new_version_check_time")) continue;
|
|
|
|
if (xp.match_tag("newer_version")) continue;
|
|
|
|
if (xp.match_tag("project")) continue;
|
|
|
|
if (xp.match_tag("project_files")) continue;
|
|
|
|
if (xp.match_tag("proxy_info")) continue;
|
|
|
|
if (xp.match_tag("user_network_request")) continue;
|
|
|
|
if (xp.match_tag("user_run_request")) continue;
|
|
|
|
if (xp.match_tag("master_url")) continue;
|
|
|
|
if (xp.match_tag("project_name")) continue;
|
|
|
|
if (xp.match_tag("user_name")) continue;
|
|
|
|
if (xp.match_tag("team_name")) continue;
|
|
|
|
if (xp.match_tag("email_hash")) continue;
|
|
|
|
if (xp.match_tag("user_total_credit")) continue;
|
|
|
|
if (xp.match_tag("user_expavg_credit")) continue;
|
|
|
|
if (xp.match_tag("user_create_time")) continue;
|
|
|
|
if (xp.match_tag("host_total_credit")) continue;
|
|
|
|
if (xp.match_tag("host_expavg_credit")) continue;
|
|
|
|
if (xp.match_tag("host_create_time")) continue;
|
|
|
|
if (xp.match_tag("nrpc_failures")) continue;
|
|
|
|
if (xp.match_tag("master_fetch_failures")) continue;
|
|
|
|
if (xp.match_tag("min_rpc_time")) continue;
|
|
|
|
if (xp.match_tag("short_term_debt")) continue;
|
|
|
|
if (xp.match_tag("long_term_debt")) continue;
|
|
|
|
if (xp.match_tag("resource_share")) continue;
|
|
|
|
if (xp.match_tag("scheduler_url")) continue;
|
|
|
|
if (xp.match_tag("/project")) continue;
|
|
|
|
if (xp.match_tag("?xml")) continue;
|
2007-09-23 21:38:47 +00:00
|
|
|
|
2008-02-21 21:00:58 +00:00
|
|
|
log_messages.printf(MSG_NORMAL,
|
2011-08-11 21:15:42 +00:00
|
|
|
"SCHEDULER_REQUEST::parse(): unexpected: %s\n", xp.parsed_tag
|
2007-06-14 23:08:43 +00:00
|
|
|
);
|
2011-08-11 21:15:42 +00:00
|
|
|
xp.skip_unexpected();
|
2002-04-30 22:22:54 +00:00
|
|
|
}
|
2008-07-01 16:34:51 +00:00
|
|
|
return "no end tag";
|
2002-04-30 22:22:54 +00:00
|
|
|
}
|
|
|
|
|
2010-05-14 03:08:23 +00:00
|
|
|
// I'm not real sure why this is here.
|
|
|
|
// Why not copy the request message directly?
|
|
|
|
//
|
2005-01-31 16:10:49 +00:00
|
|
|
int SCHEDULER_REQUEST::write(FILE* fout) {
|
2005-04-18 17:54:03 +00:00
|
|
|
unsigned int i;
|
2005-01-31 16:10:49 +00:00
|
|
|
|
2005-04-18 17:54:03 +00:00
|
|
|
fprintf(fout,
|
|
|
|
"<scheduler_request>\n"
|
|
|
|
" <authenticator>%s</authentiicator>\n"
|
|
|
|
" <platform_name>%s</platform_name>\n"
|
|
|
|
" <cross_project_id>%s</cross_project_id>\n"
|
|
|
|
" <hostid>%d</hostid>\n"
|
|
|
|
" <core_client_major_version>%d</core_client_major_version>\n"
|
|
|
|
" <core_client_minor_version>%d</core_client_minor_version>\n"
|
2005-08-31 00:18:36 +00:00
|
|
|
" <core_client_release>%d</core_client_release>\n"
|
2005-04-18 17:54:03 +00:00
|
|
|
" <rpc_seqno>%d</rpc_seqno>\n"
|
|
|
|
" <work_req_seconds>%.15f</work_req_seconds>\n"
|
|
|
|
" <resource_share_fraction>%.15f</resource_share_fraction>\n"
|
2005-10-04 21:44:58 +00:00
|
|
|
" <rrs_fraction>%.15f</rrs_fraction>\n"
|
|
|
|
" <prrs_fraction>%.15f</prrs_fraction>\n"
|
2005-04-18 17:54:03 +00:00
|
|
|
" <estimated_delay>%.15f</estimated_delay>\n"
|
|
|
|
" <code_sign_key>%s</code_sign_key>\n"
|
|
|
|
" <anonymous_platform>%s</anonymous_platform>\n",
|
|
|
|
authenticator,
|
2007-04-19 22:45:57 +00:00
|
|
|
platform.name,
|
2005-04-18 17:54:03 +00:00
|
|
|
cross_project_id,
|
|
|
|
hostid,
|
|
|
|
core_client_major_version,
|
|
|
|
core_client_minor_version,
|
2005-08-31 00:18:36 +00:00
|
|
|
core_client_release,
|
2005-04-18 17:54:03 +00:00
|
|
|
rpc_seqno,
|
|
|
|
work_req_seconds,
|
|
|
|
resource_share_fraction,
|
2005-10-04 21:44:58 +00:00
|
|
|
rrs_fraction,
|
|
|
|
prrs_fraction,
|
2009-01-30 21:25:24 +00:00
|
|
|
cpu_estimated_delay,
|
2005-04-18 17:54:03 +00:00
|
|
|
code_sign_key,
|
2010-07-23 17:43:20 +00:00
|
|
|
is_anonymous(platforms.list[0])?"true":"false"
|
2005-04-18 17:54:03 +00:00
|
|
|
);
|
2005-01-31 16:10:49 +00:00
|
|
|
|
2005-04-18 17:54:03 +00:00
|
|
|
for (i=0; i<client_app_versions.size(); i++) {
|
|
|
|
fprintf(fout,
|
2005-01-31 16:10:49 +00:00
|
|
|
" <app_version>\n"
|
|
|
|
" <app_name>%s</app_name>\n"
|
|
|
|
" <version_num>%d</version_num>\n"
|
|
|
|
" </app_version>\n",
|
|
|
|
client_app_versions[i].app_name,
|
|
|
|
client_app_versions[i].version_num
|
2005-04-18 17:54:03 +00:00
|
|
|
);
|
|
|
|
}
|
2005-01-31 16:10:49 +00:00
|
|
|
|
2005-04-18 17:54:03 +00:00
|
|
|
fprintf(fout,
|
|
|
|
" <global_prefs_xml>\n"
|
|
|
|
" %s"
|
|
|
|
" </globals_prefs_xml>\n",
|
|
|
|
global_prefs_xml
|
|
|
|
);
|
2005-01-31 16:10:49 +00:00
|
|
|
|
2005-04-18 17:54:03 +00:00
|
|
|
fprintf(fout,
|
|
|
|
" <global_prefs_source_email_hash>%s</global_prefs_source_email_hash>\n",
|
|
|
|
global_prefs_source_email_hash
|
|
|
|
);
|
2005-01-31 16:10:49 +00:00
|
|
|
|
|
|
|
fprintf(fout,
|
2005-04-18 17:54:03 +00:00
|
|
|
" <host>\n"
|
|
|
|
" <id>%d</id>\n"
|
|
|
|
" <rpc_time>%d</rpc_time>\n"
|
|
|
|
" <timezone>%d</timezone>\n"
|
|
|
|
" <d_total>%.15f</d_total>\n"
|
|
|
|
" <d_free>%.15f</d_free>\n"
|
|
|
|
" <d_boinc_used_total>%.15f</d_boinc_used_total>\n"
|
|
|
|
" <d_boinc_used_project>%.15f</d_boinc_used_project>\n"
|
|
|
|
" <d_boinc_max>%.15f</d_boinc_max>\n",
|
|
|
|
host.id,
|
|
|
|
host.rpc_time,
|
|
|
|
host.timezone,
|
|
|
|
host.d_total,
|
|
|
|
host.d_free,
|
|
|
|
host.d_boinc_used_total,
|
|
|
|
host.d_boinc_used_project,
|
|
|
|
host.d_boinc_max
|
|
|
|
);
|
|
|
|
|
|
|
|
for (i=0; i<results.size(); i++) {
|
|
|
|
fprintf(fout,
|
2005-01-31 16:10:49 +00:00
|
|
|
" <result>\n"
|
|
|
|
" <name>%s</name>\n"
|
|
|
|
" <client_state>%d</client_state>\n"
|
|
|
|
" <cpu_time>%.15f</cpu_time>\n"
|
|
|
|
" <exit_status>%d</exit_status>\n"
|
|
|
|
" <app_version_num>%d</app_version_num>\n"
|
|
|
|
" </result>\n",
|
|
|
|
results[i].name,
|
|
|
|
results[i].client_state,
|
|
|
|
results[i].cpu_time,
|
|
|
|
results[i].exit_status,
|
|
|
|
results[i].app_version_num
|
2005-04-18 17:54:03 +00:00
|
|
|
);
|
|
|
|
}
|
2005-01-31 16:10:49 +00:00
|
|
|
|
2005-04-18 17:54:03 +00:00
|
|
|
for (i=0; i<msgs_from_host.size(); i++) {
|
|
|
|
fprintf(fout,
|
|
|
|
" <msg_from_host>\n"
|
|
|
|
" <variety>%s</variety>\n"
|
|
|
|
" <msg_text>%s</msg_text>\n"
|
|
|
|
" </msg_from_host>\n",
|
|
|
|
msgs_from_host[i].variety,
|
|
|
|
msgs_from_host[i].msg_text.c_str()
|
|
|
|
);
|
|
|
|
}
|
2005-01-31 16:10:49 +00:00
|
|
|
|
2005-04-18 17:54:03 +00:00
|
|
|
for (i=0; i<file_infos.size(); i++) {
|
|
|
|
fprintf(fout,
|
|
|
|
" <file_info>\n"
|
|
|
|
" <name>%s</name>\n"
|
|
|
|
" </file_info>\n",
|
|
|
|
file_infos[i].name
|
|
|
|
);
|
|
|
|
fprintf(fout, "</scheduler_request>\n");
|
|
|
|
}
|
|
|
|
return 0;
|
2005-01-31 16:10:49 +00:00
|
|
|
}
|
|
|
|
|
2011-08-10 17:11:08 +00:00
|
|
|
int MSG_FROM_HOST_DESC::parse(XML_PARSER& xp) {
|
2004-01-08 00:27:59 +00:00
|
|
|
char buf[256];
|
|
|
|
|
2004-06-24 21:00:13 +00:00
|
|
|
msg_text = "";
|
2011-08-10 17:11:08 +00:00
|
|
|
MIOFILE& in = *(xp.f);
|
|
|
|
while (in.fgets(buf, sizeof(buf))) {
|
2004-06-24 21:00:13 +00:00
|
|
|
if (match_tag(buf, "</msg_from_host>")) return 0;
|
2004-07-06 04:10:51 +00:00
|
|
|
if (parse_str(buf, "<variety>", variety, sizeof(variety))) continue;
|
|
|
|
msg_text += buf;
|
2004-01-08 00:27:59 +00:00
|
|
|
}
|
|
|
|
return ERR_XML_PARSE;
|
|
|
|
}
|
2002-04-30 22:22:54 +00:00
|
|
|
|
|
|
|
SCHEDULER_REPLY::SCHEDULER_REPLY() {
|
2005-01-31 23:20:49 +00:00
|
|
|
memset(&wreq, 0, sizeof(wreq));
|
2005-04-18 17:54:03 +00:00
|
|
|
memset(&disk_limits, 0, sizeof(disk_limits));
|
2002-04-30 22:22:54 +00:00
|
|
|
request_delay = 0;
|
|
|
|
hostid = 0;
|
2002-09-27 20:36:03 +00:00
|
|
|
send_global_prefs = false;
|
2003-04-03 18:35:40 +00:00
|
|
|
strcpy(code_sign_key, "");
|
|
|
|
strcpy(code_sign_key_signature, "");
|
2002-09-22 23:27:14 +00:00
|
|
|
memset(&user, 0, sizeof(user));
|
|
|
|
memset(&host, 0, sizeof(host));
|
2003-02-24 21:31:36 +00:00
|
|
|
memset(&team, 0, sizeof(team));
|
2002-12-02 04:29:40 +00:00
|
|
|
nucleus_only = false;
|
2008-03-13 23:35:13 +00:00
|
|
|
project_is_down = false;
|
2004-06-24 21:00:13 +00:00
|
|
|
send_msg_ack = false;
|
2004-05-03 02:18:35 +00:00
|
|
|
strcpy(email_hash, "");
|
2002-04-30 22:22:54 +00:00
|
|
|
}
|
|
|
|
|
2008-10-01 22:07:35 +00:00
|
|
|
int SCHEDULER_REPLY::write(FILE* fout, SCHEDULER_REQUEST& sreq) {
|
2007-06-20 22:34:06 +00:00
|
|
|
unsigned int i;
|
2008-03-31 16:19:45 +00:00
|
|
|
char buf[BLOB_SIZE];
|
2002-12-02 04:29:40 +00:00
|
|
|
|
2007-02-23 17:29:19 +00:00
|
|
|
// Note: at one point we had
|
|
|
|
// "<?xml version=\"1.0\" encoding=\"ISO-8859-1\" ?>\n"
|
|
|
|
// after the Content-type (to make it legit XML),
|
|
|
|
// but this broke 4.19 clients
|
|
|
|
//
|
2002-04-30 22:22:54 +00:00
|
|
|
fprintf(fout,
|
2006-12-04 19:00:37 +00:00
|
|
|
"Content-type: text/xml\n\n"
|
2002-04-30 22:22:54 +00:00
|
|
|
"<scheduler_reply>\n"
|
2012-06-14 17:14:52 +00:00
|
|
|
"<scheduler_version>%d</scheduler_version>\n",
|
2005-01-27 23:09:19 +00:00
|
|
|
BOINC_MAJOR_VERSION*100+BOINC_MINOR_VERSION
|
2002-12-02 04:29:40 +00:00
|
|
|
);
|
2012-06-14 17:14:52 +00:00
|
|
|
if (sreq.core_client_version >= 70028) {
|
|
|
|
fprintf(fout, "<dont_use_dcf/>\n");
|
|
|
|
}
|
2006-03-07 21:46:49 +00:00
|
|
|
if (strlen(config.master_url)) {
|
|
|
|
fprintf(fout,
|
|
|
|
"<master_url>%s</master_url>\n",
|
|
|
|
config.master_url
|
|
|
|
);
|
|
|
|
}
|
2007-05-24 16:07:21 +00:00
|
|
|
if (config.ended) {
|
|
|
|
fprintf(fout, " <ended>1</ended>\n");
|
|
|
|
}
|
2002-12-02 04:29:40 +00:00
|
|
|
|
2005-09-13 13:25:01 +00:00
|
|
|
// if the scheduler has requested a delay OR the sysadmin has configured
|
|
|
|
// the scheduler with a minimum time between RPCs, send a delay request.
|
|
|
|
// Make it 1% larger than the min required to take care of time skew.
|
2005-09-13 13:36:11 +00:00
|
|
|
// If this is less than one second bigger, bump up by one sec.
|
2005-09-13 13:25:01 +00:00
|
|
|
//
|
|
|
|
if (request_delay || config.min_sendwork_interval) {
|
2005-10-12 18:40:53 +00:00
|
|
|
double min_delay_needed = 1.01*config.min_sendwork_interval;
|
|
|
|
if (min_delay_needed < config.min_sendwork_interval+1) {
|
|
|
|
min_delay_needed = config.min_sendwork_interval+1;
|
|
|
|
}
|
|
|
|
if (request_delay<min_delay_needed) {
|
2009-06-01 22:15:14 +00:00
|
|
|
request_delay = min_delay_needed;
|
2005-10-12 18:40:53 +00:00
|
|
|
}
|
2005-02-16 23:17:43 +00:00
|
|
|
fprintf(fout, "<request_delay>%f</request_delay>\n", request_delay);
|
2002-12-02 04:29:40 +00:00
|
|
|
}
|
2008-05-02 17:48:29 +00:00
|
|
|
log_messages.printf(MSG_NORMAL,
|
- scheduler: add support for anonymous-platform coproc apps.
Old: although the request message contained all info
about the app version (flops, coproc usage etc.)
the server ignored this info,
and assumed that all anonymous platform apps where CPU.
With 6.6 client, this could produce infinite work fetch:
- client uses anon platform, has coproc app
- client has idle CPU, requests CPU work
- scheduler sends it jobs, thinking they will be done by CPU app
- client asks for more work etc.
New: scheduler parses full info on anon platform app versions:
plan class, FLOPS, coprocs.
It uses this info to make scheduling decisions;
in particular, if the request is for CUDA work,
if will only send jobs that use a CUDA app version.
The <result> records it returns contain info
(plan_class) that tells the client which app_version to use.
This will work correctly even if the client has multiple app versions
for the same app (e.g., a CPU version and a GPU version)
svn path=/trunk/boinc/; revision=17506
2009-03-05 17:30:10 +00:00
|
|
|
"Sending reply to [HOST#%d]: %d results, delay req %.2f\n",
|
2009-06-01 22:15:14 +00:00
|
|
|
host.id, wreq.njobs_sent, request_delay
|
2008-05-02 17:48:29 +00:00
|
|
|
);
|
|
|
|
|
2010-01-13 17:28:59 +00:00
|
|
|
if (sreq.core_client_version <= 41900) {
|
2011-09-06 22:53:48 +00:00
|
|
|
string msg;
|
|
|
|
string pri = "low";
|
2005-02-01 20:30:33 +00:00
|
|
|
for (i=0; i<messages.size(); i++) {
|
|
|
|
USER_MESSAGE& um = messages[i];
|
2011-09-06 22:53:48 +00:00
|
|
|
msg += um.message + string(" ");
|
2010-06-29 03:23:13 +00:00
|
|
|
if (um.priority == "notice") {
|
|
|
|
pri = "notice";
|
2005-02-01 20:30:33 +00:00
|
|
|
}
|
|
|
|
}
|
2005-02-02 15:16:59 +00:00
|
|
|
if (messages.size()>0) {
|
2005-02-28 21:58:27 +00:00
|
|
|
// any newlines will break message printing under 4.19 and under!
|
|
|
|
// replace them with spaces.
|
2005-03-10 22:05:42 +00:00
|
|
|
//
|
|
|
|
while (1) {
|
2011-09-06 22:53:48 +00:00
|
|
|
string::size_type pos = msg.find("\n", 0);
|
|
|
|
if (pos == string::npos) break;
|
2005-03-10 22:05:42 +00:00
|
|
|
msg.replace(pos, 1, " ");
|
2005-02-28 21:58:27 +00:00
|
|
|
}
|
2005-02-02 15:16:59 +00:00
|
|
|
fprintf(fout,
|
|
|
|
"<message priority=\"%s\">%s</message>\n",
|
|
|
|
pri.c_str(), msg.c_str()
|
|
|
|
);
|
|
|
|
}
|
2010-07-13 02:49:35 +00:00
|
|
|
} else if (sreq.core_client_version <= 61100) {
|
|
|
|
char prio[256];
|
|
|
|
for (i=0; i<messages.size(); i++) {
|
|
|
|
USER_MESSAGE& um = messages[i];
|
|
|
|
strcpy(prio, um.priority.c_str());
|
|
|
|
if (!strcmp(prio, "notice")) {
|
|
|
|
strcpy(prio, "high");
|
|
|
|
}
|
|
|
|
fprintf(fout,
|
|
|
|
"<message priority=\"%s\">%s</message>\n",
|
|
|
|
prio,
|
|
|
|
um.message.c_str()
|
|
|
|
);
|
|
|
|
}
|
2005-02-01 20:30:33 +00:00
|
|
|
} else {
|
|
|
|
for (i=0; i<messages.size(); i++) {
|
|
|
|
USER_MESSAGE& um = messages[i];
|
|
|
|
fprintf(fout,
|
|
|
|
"<message priority=\"%s\">%s</message>\n",
|
|
|
|
um.priority.c_str(),
|
|
|
|
um.message.c_str()
|
|
|
|
);
|
|
|
|
}
|
2002-12-02 04:29:40 +00:00
|
|
|
}
|
|
|
|
fprintf(fout,
|
2003-02-14 22:35:35 +00:00
|
|
|
"<project_name>%s</project_name>\n",
|
2004-05-02 15:55:17 +00:00
|
|
|
config.long_name
|
2002-04-30 22:22:54 +00:00
|
|
|
);
|
|
|
|
|
2008-01-13 00:12:14 +00:00
|
|
|
if (config.request_time_stats_log) {
|
2008-12-19 18:14:02 +00:00
|
|
|
if (!have_time_stats_log()) {
|
2008-01-13 00:12:14 +00:00
|
|
|
fprintf(fout, "<send_time_stats_log>1</send_time_stats_log>\n");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2008-05-16 00:14:48 +00:00
|
|
|
if (project_is_down) {
|
|
|
|
fprintf(fout,"<project_is_down/>\n");
|
|
|
|
goto end;
|
|
|
|
}
|
2010-05-14 03:08:23 +00:00
|
|
|
if (config.workload_sim) {
|
2010-07-21 16:19:37 +00:00
|
|
|
fprintf(fout, "<send_full_workload/>\n");
|
2010-05-14 03:08:23 +00:00
|
|
|
}
|
2008-05-16 00:14:48 +00:00
|
|
|
|
|
|
|
if (nucleus_only) goto end;
|
|
|
|
|
2006-05-22 09:54:31 +00:00
|
|
|
if (strlen(config.symstore)) {
|
|
|
|
fprintf(fout, "<symstore>%s</symstore>\n", config.symstore);
|
|
|
|
}
|
2006-05-25 18:51:57 +00:00
|
|
|
if (config.next_rpc_delay) {
|
|
|
|
fprintf(fout, "<next_rpc_delay>%f</next_rpc_delay>\n", config.next_rpc_delay);
|
|
|
|
}
|
2004-08-12 13:36:05 +00:00
|
|
|
if (user.id) {
|
2008-08-13 17:27:13 +00:00
|
|
|
xml_escape(user.name, buf, sizeof(buf));
|
2004-05-13 04:48:19 +00:00
|
|
|
fprintf(fout,
|
2011-01-13 22:40:48 +00:00
|
|
|
"<userid>%d</userid>\n"
|
2004-08-12 13:36:05 +00:00
|
|
|
"<user_name>%s</user_name>\n"
|
|
|
|
"<user_total_credit>%f</user_total_credit>\n"
|
|
|
|
"<user_expavg_credit>%f</user_expavg_credit>\n"
|
|
|
|
"<user_create_time>%d</user_create_time>\n",
|
2011-01-13 22:40:48 +00:00
|
|
|
user.id,
|
2006-04-17 22:41:29 +00:00
|
|
|
buf,
|
2004-08-12 13:36:05 +00:00
|
|
|
user.total_credit,
|
|
|
|
user.expavg_credit,
|
|
|
|
user.create_time
|
2004-05-13 04:48:19 +00:00
|
|
|
);
|
2004-08-12 13:36:05 +00:00
|
|
|
// be paranoid about the following to avoid sending null
|
|
|
|
//
|
|
|
|
if (strlen(email_hash)) {
|
|
|
|
fprintf(fout,
|
|
|
|
"<email_hash>%s</email_hash>\n",
|
|
|
|
email_hash
|
|
|
|
);
|
|
|
|
}
|
|
|
|
if (strlen(user.cross_project_id)) {
|
|
|
|
fprintf(fout,
|
|
|
|
"<cross_project_id>%s</cross_project_id>\n",
|
|
|
|
user.cross_project_id
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (send_global_prefs) {
|
|
|
|
fputs(user.global_prefs, fout);
|
2006-04-19 18:49:54 +00:00
|
|
|
fputs("\n", fout);
|
2004-08-12 13:36:05 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// always send project prefs
|
|
|
|
//
|
|
|
|
fputs(user.project_prefs, fout);
|
2006-04-19 18:49:54 +00:00
|
|
|
fputs("\n", fout);
|
2004-08-12 13:36:05 +00:00
|
|
|
|
2004-05-13 04:48:19 +00:00
|
|
|
}
|
2004-08-12 13:36:05 +00:00
|
|
|
if (hostid) {
|
2004-05-13 04:48:19 +00:00
|
|
|
fprintf(fout,
|
2004-10-01 07:49:01 +00:00
|
|
|
"<hostid>%d</hostid>\n",
|
|
|
|
hostid
|
2004-05-13 04:48:19 +00:00
|
|
|
);
|
2004-08-13 11:21:12 +00:00
|
|
|
}
|
2004-10-01 07:49:01 +00:00
|
|
|
fprintf(fout,
|
|
|
|
"<host_total_credit>%f</host_total_credit>\n"
|
|
|
|
"<host_expavg_credit>%f</host_expavg_credit>\n"
|
|
|
|
"<host_venue>%s</host_venue>\n"
|
|
|
|
"<host_create_time>%d</host_create_time>\n",
|
|
|
|
host.total_credit,
|
|
|
|
host.expavg_credit,
|
|
|
|
host.venue,
|
|
|
|
host.create_time
|
|
|
|
);
|
2004-05-13 04:48:19 +00:00
|
|
|
|
2003-02-24 21:31:36 +00:00
|
|
|
// might want to send team credit too.
|
|
|
|
//
|
|
|
|
if (team.id) {
|
2008-08-13 17:27:13 +00:00
|
|
|
xml_escape(team.name, buf, sizeof(buf));
|
2003-02-24 21:31:36 +00:00
|
|
|
fprintf(fout,
|
2011-01-13 22:40:48 +00:00
|
|
|
"<teamid>%d</teamid>\n"
|
2003-02-24 21:31:36 +00:00
|
|
|
"<team_name>%s</team_name>\n",
|
2011-01-13 22:40:48 +00:00
|
|
|
team.id,
|
2006-04-17 22:41:29 +00:00
|
|
|
buf
|
2003-02-24 21:31:36 +00:00
|
|
|
);
|
2005-10-09 05:53:35 +00:00
|
|
|
} else {
|
|
|
|
fprintf(fout,
|
|
|
|
"<team_name></team_name>\n"
|
|
|
|
);
|
2003-02-24 21:31:36 +00:00
|
|
|
}
|
|
|
|
|
2002-04-30 22:22:54 +00:00
|
|
|
// acknowledge results
|
|
|
|
//
|
|
|
|
for (i=0; i<result_acks.size(); i++) {
|
|
|
|
fprintf(fout,
|
|
|
|
"<result_ack>\n"
|
|
|
|
" <name>%s</name>\n"
|
|
|
|
"</result_ack>\n",
|
2005-06-22 06:02:59 +00:00
|
|
|
result_acks[i].c_str()
|
2002-04-30 22:22:54 +00:00
|
|
|
);
|
|
|
|
}
|
|
|
|
|
2007-04-05 17:02:01 +00:00
|
|
|
// abort results
|
|
|
|
//
|
|
|
|
for (i=0; i<result_aborts.size(); i++) {
|
|
|
|
fprintf(fout,
|
|
|
|
"<result_abort>\n"
|
|
|
|
" <name>%s</name>\n"
|
|
|
|
"</result_abort>\n",
|
|
|
|
result_aborts[i].c_str()
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
// abort results not started
|
|
|
|
//
|
|
|
|
for (i=0; i<result_abort_if_not_starteds.size(); i++) {
|
|
|
|
fprintf(fout,
|
|
|
|
"<result_abort_if_not_started>\n"
|
|
|
|
" <name>%s</name>\n"
|
|
|
|
"</result_abort_if_not_started>\n",
|
|
|
|
result_abort_if_not_starteds[i].c_str()
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
2002-04-30 22:22:54 +00:00
|
|
|
for (i=0; i<apps.size(); i++) {
|
|
|
|
apps[i].write(fout);
|
|
|
|
}
|
2003-05-20 00:03:39 +00:00
|
|
|
|
2002-04-30 22:22:54 +00:00
|
|
|
for (i=0; i<app_versions.size(); i++) {
|
2007-05-02 23:14:00 +00:00
|
|
|
app_versions[i].write(fout);
|
2002-04-30 22:22:54 +00:00
|
|
|
}
|
2003-05-20 00:03:39 +00:00
|
|
|
|
2002-04-30 22:22:54 +00:00
|
|
|
for (i=0; i<wus.size(); i++) {
|
|
|
|
fputs(wus[i].xml_doc, fout);
|
2011-08-31 18:52:57 +00:00
|
|
|
fputs("\n", fout); // for old clients
|
2002-04-30 22:22:54 +00:00
|
|
|
}
|
2003-05-20 00:03:39 +00:00
|
|
|
|
2002-04-30 22:22:54 +00:00
|
|
|
for (i=0; i<results.size(); i++) {
|
2007-05-02 23:14:00 +00:00
|
|
|
results[i].write_to_client(fout);
|
2002-04-30 22:22:54 +00:00
|
|
|
}
|
2003-05-20 00:03:39 +00:00
|
|
|
|
2003-04-03 18:35:40 +00:00
|
|
|
if (strlen(code_sign_key)) {
|
2002-07-07 20:39:24 +00:00
|
|
|
fputs("<code_sign_key>\n", fout);
|
|
|
|
fputs(code_sign_key, fout);
|
2011-08-19 16:19:52 +00:00
|
|
|
fputs("\n</code_sign_key>\n", fout);
|
2002-07-07 20:39:24 +00:00
|
|
|
}
|
2003-05-20 00:03:39 +00:00
|
|
|
|
2003-04-03 18:35:40 +00:00
|
|
|
if (strlen(code_sign_key_signature)) {
|
2002-07-07 20:39:24 +00:00
|
|
|
fputs("<code_sign_key_signature>\n", fout);
|
|
|
|
fputs(code_sign_key_signature, fout);
|
|
|
|
fputs("</code_sign_key_signature>\n", fout);
|
|
|
|
}
|
2006-06-20 17:36:28 +00:00
|
|
|
|
2004-06-24 21:00:13 +00:00
|
|
|
if (send_msg_ack) {
|
|
|
|
fputs("<message_ack/>\n", fout);
|
2004-03-17 01:26:44 +00:00
|
|
|
}
|
2004-07-10 00:11:20 +00:00
|
|
|
|
2004-06-22 22:56:50 +00:00
|
|
|
for (i=0; i<msgs_to_host.size(); i++) {
|
2004-06-24 21:00:13 +00:00
|
|
|
MSG_TO_HOST& md = msgs_to_host[i];
|
|
|
|
fprintf(fout, "%s\n", md.xml);
|
2004-01-08 00:27:59 +00:00
|
|
|
}
|
2004-07-13 13:54:09 +00:00
|
|
|
|
2004-04-14 23:32:17 +00:00
|
|
|
if (config.non_cpu_intensive) {
|
|
|
|
fprintf(fout, "<non_cpu_intensive/>\n");
|
|
|
|
}
|
2004-09-10 21:02:11 +00:00
|
|
|
|
2006-06-20 17:36:28 +00:00
|
|
|
if (config.verify_files_on_app_start) {
|
|
|
|
fprintf(fout, "<verify_files_on_app_start/>\n");
|
|
|
|
}
|
|
|
|
|
2004-09-10 21:02:11 +00:00
|
|
|
for (i=0; i<file_deletes.size(); i++) {
|
|
|
|
fprintf(fout,
|
|
|
|
"<delete_file_info>%s</delete_file_info>\n",
|
|
|
|
file_deletes[i].name
|
|
|
|
);
|
|
|
|
}
|
2012-02-29 01:11:28 +00:00
|
|
|
for (i=0; i<file_transfer_requests.size(); i++) {
|
|
|
|
fprintf(fout, "%s", file_transfer_requests[i].c_str());
|
|
|
|
}
|
2004-09-13 18:05:54 +00:00
|
|
|
|
2010-11-09 19:04:24 +00:00
|
|
|
fprintf(fout,
|
2010-11-09 19:41:53 +00:00
|
|
|
"<no_cpu_apps>%d</no_cpu_apps>\n"
|
|
|
|
"<no_cuda_apps>%d</no_cuda_apps>\n"
|
2012-06-22 07:35:54 +00:00
|
|
|
"<no_ati_apps>%d</no_ati_apps>\n"
|
|
|
|
"<no_intel_apps>%d</no_intel_apps>\n",
|
|
|
|
ssp->have_apps_for_proc_type[PROC_TYPE_CPU]?0:1,
|
2012-06-25 23:09:45 +00:00
|
|
|
ssp->have_apps_for_proc_type[PROC_TYPE_NVIDIA_GPU]?0:1,
|
|
|
|
ssp->have_apps_for_proc_type[PROC_TYPE_AMD_GPU]?0:1,
|
|
|
|
ssp->have_apps_for_proc_type[PROC_TYPE_INTEL_GPU]?0:1
|
2010-11-09 19:04:24 +00:00
|
|
|
);
|
2004-09-27 19:44:40 +00:00
|
|
|
gui_urls.get_gui_urls(user, host, team, buf);
|
2004-09-13 18:05:54 +00:00
|
|
|
fputs(buf, fout);
|
2006-06-26 22:58:24 +00:00
|
|
|
if (project_files.text) {
|
|
|
|
fputs(project_files.text, fout);
|
2008-10-02 19:16:09 +00:00
|
|
|
fprintf(fout, "\n");
|
2006-06-26 22:58:24 +00:00
|
|
|
}
|
2004-09-13 18:05:54 +00:00
|
|
|
|
2002-12-02 04:29:40 +00:00
|
|
|
end:
|
2002-04-30 22:22:54 +00:00
|
|
|
fprintf(fout,
|
|
|
|
"</scheduler_reply>\n"
|
2004-01-08 00:27:59 +00:00
|
|
|
);
|
2002-04-30 22:22:54 +00:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2005-02-16 23:17:43 +00:00
|
|
|
// set delay to the MAX of the existing value or the requested value
|
|
|
|
// never send a delay request longer than two days.
|
|
|
|
//
|
|
|
|
void SCHEDULER_REPLY::set_delay(double delay) {
|
2005-02-16 01:26:43 +00:00
|
|
|
if (request_delay < delay) {
|
2005-02-16 01:14:12 +00:00
|
|
|
request_delay = delay;
|
2005-02-16 01:26:43 +00:00
|
|
|
}
|
2008-02-28 21:22:50 +00:00
|
|
|
if (request_delay > DELAY_MAX) {
|
|
|
|
request_delay = DELAY_MAX;
|
2005-02-16 01:26:43 +00:00
|
|
|
}
|
2005-02-16 01:14:12 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2002-04-30 22:22:54 +00:00
|
|
|
void SCHEDULER_REPLY::insert_app_unique(APP& app) {
|
|
|
|
unsigned int i;
|
|
|
|
for (i=0; i<apps.size(); i++) {
|
|
|
|
if (app.id == apps[i].id) return;
|
|
|
|
}
|
|
|
|
apps.push_back(app);
|
|
|
|
}
|
|
|
|
|
|
|
|
void SCHEDULER_REPLY::insert_app_version_unique(APP_VERSION& av) {
|
|
|
|
unsigned int i;
|
|
|
|
for (i=0; i<app_versions.size(); i++) {
|
|
|
|
if (av.id == app_versions[i].id) return;
|
|
|
|
}
|
|
|
|
app_versions.push_back(av);
|
|
|
|
}
|
|
|
|
|
|
|
|
void SCHEDULER_REPLY::insert_workunit_unique(WORKUNIT& wu) {
|
|
|
|
unsigned int i;
|
|
|
|
for (i=0; i<wus.size(); i++) {
|
|
|
|
if (wu.id == wus[i].id) return;
|
|
|
|
}
|
|
|
|
wus.push_back(wu);
|
|
|
|
}
|
|
|
|
|
2011-06-06 03:40:42 +00:00
|
|
|
void SCHEDULER_REPLY::insert_result(SCHED_DB_RESULT& result) {
|
2002-04-30 22:22:54 +00:00
|
|
|
results.push_back(result);
|
|
|
|
}
|
|
|
|
|
2009-08-21 19:14:15 +00:00
|
|
|
void SCHEDULER_REPLY::insert_message(const char* msg, const char* prio) {
|
2011-04-19 17:57:54 +00:00
|
|
|
messages.push_back(USER_MESSAGE(msg, prio));
|
2009-08-21 19:14:15 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void SCHEDULER_REPLY::insert_message(USER_MESSAGE& um) {
|
2005-01-31 22:19:03 +00:00
|
|
|
messages.push_back(um);
|
|
|
|
}
|
|
|
|
|
2005-02-16 23:17:43 +00:00
|
|
|
USER_MESSAGE::USER_MESSAGE(const char* m, const char* p) {
|
2011-04-19 17:57:54 +00:00
|
|
|
if (g_request->core_client_version < 61200) {
|
|
|
|
char buf[1024];
|
|
|
|
strcpy(buf, m);
|
|
|
|
strip_translation(buf);
|
|
|
|
message = buf;
|
|
|
|
} else {
|
|
|
|
message = m;
|
|
|
|
}
|
2005-01-31 22:19:03 +00:00
|
|
|
priority = p;
|
|
|
|
}
|
|
|
|
|
2002-04-30 22:22:54 +00:00
|
|
|
int APP::write(FILE* fout) {
|
|
|
|
fprintf(fout,
|
|
|
|
"<app>\n"
|
|
|
|
" <name>%s</name>\n"
|
2006-06-26 19:08:00 +00:00
|
|
|
" <user_friendly_name>%s</user_friendly_name>\n"
|
2002-04-30 22:22:54 +00:00
|
|
|
"</app>\n",
|
2006-06-26 19:08:00 +00:00
|
|
|
name, user_friendly_name
|
2002-04-30 22:22:54 +00:00
|
|
|
);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2005-02-16 23:17:43 +00:00
|
|
|
int APP_VERSION::write(FILE* fout) {
|
2008-04-02 19:57:41 +00:00
|
|
|
char buf[APP_VERSION_XML_BLOB_SIZE];
|
2008-03-28 18:00:27 +00:00
|
|
|
|
2007-05-02 23:14:00 +00:00
|
|
|
strcpy(buf, xml_doc);
|
|
|
|
char* p = strstr(buf, "</app_version>");
|
|
|
|
if (!p) {
|
|
|
|
fprintf(stderr, "ERROR: app version %d XML has no end tag!\n", id);
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
*p = 0;
|
|
|
|
fputs(buf, fout);
|
|
|
|
PLATFORM* pp = ssp->lookup_platform_id(platformid);
|
2008-03-27 18:25:29 +00:00
|
|
|
fprintf(fout, " <platform>%s</platform>\n", pp->name);
|
|
|
|
if (strlen(plan_class)) {
|
|
|
|
fprintf(fout, " <plan_class>%s</plan_class>\n", plan_class);
|
|
|
|
}
|
2008-03-28 18:00:27 +00:00
|
|
|
fprintf(fout,
|
|
|
|
" <avg_ncpus>%f</avg_ncpus>\n"
|
|
|
|
" <max_ncpus>%f</max_ncpus>\n"
|
|
|
|
" <flops>%f</flops>\n",
|
|
|
|
bavp->host_usage.avg_ncpus,
|
|
|
|
bavp->host_usage.max_ncpus,
|
2010-04-10 05:49:51 +00:00
|
|
|
bavp->host_usage.projected_flops
|
2008-03-28 18:00:27 +00:00
|
|
|
);
|
|
|
|
if (strlen(bavp->host_usage.cmdline)) {
|
|
|
|
fprintf(fout,
|
|
|
|
" <cmdline>%s</cmdline>\n",
|
|
|
|
bavp->host_usage.cmdline
|
|
|
|
);
|
|
|
|
}
|
2012-06-22 07:35:54 +00:00
|
|
|
int pt = bavp->host_usage.proc_type;
|
|
|
|
if (pt != PROC_TYPE_CPU) {
|
2009-08-17 17:07:38 +00:00
|
|
|
fprintf(fout,
|
|
|
|
" <coproc>\n"
|
2012-06-22 07:35:54 +00:00
|
|
|
" <type>%s</type>\n"
|
2009-08-19 18:41:47 +00:00
|
|
|
" <count>%f</count>\n"
|
2009-08-17 17:07:38 +00:00
|
|
|
" </coproc>\n",
|
2012-06-25 23:09:45 +00:00
|
|
|
proc_type_name_xml(pt),
|
2012-06-22 07:35:54 +00:00
|
|
|
bavp->host_usage.gpu_usage
|
2009-08-17 17:07:38 +00:00
|
|
|
);
|
|
|
|
}
|
2009-12-11 22:45:59 +00:00
|
|
|
if (bavp->host_usage.gpu_ram) {
|
|
|
|
fprintf(fout,
|
|
|
|
" <gpu_ram>%f</gpu_ram>\n",
|
|
|
|
bavp->host_usage.gpu_ram
|
|
|
|
);
|
|
|
|
}
|
2007-05-02 23:14:00 +00:00
|
|
|
fputs("</app_version>\n", fout);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2011-06-06 03:40:42 +00:00
|
|
|
int SCHED_DB_RESULT::write_to_client(FILE* fout) {
|
2008-03-31 16:19:45 +00:00
|
|
|
char buf[BLOB_SIZE];
|
2008-03-27 18:25:29 +00:00
|
|
|
|
2007-05-02 23:14:00 +00:00
|
|
|
strcpy(buf, xml_doc_in);
|
|
|
|
char* p = strstr(buf, "</result>");
|
|
|
|
if (!p) {
|
|
|
|
fprintf(stderr, "ERROR: result %d XML has no end tag!\n", id);
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
*p = 0;
|
|
|
|
fputs(buf, fout);
|
2011-08-31 18:52:57 +00:00
|
|
|
fputs("\n", fout); // for old clients
|
2007-05-21 14:49:00 +00:00
|
|
|
|
2011-06-06 03:40:42 +00:00
|
|
|
APP_VERSION* avp = bav.avp;
|
|
|
|
CLIENT_APP_VERSION* cavp = bav.cavp;
|
2008-03-27 18:25:29 +00:00
|
|
|
if (avp) {
|
|
|
|
PLATFORM* pp = ssp->lookup_platform_id(avp->platformid);
|
|
|
|
fprintf(fout,
|
2007-05-21 14:49:00 +00:00
|
|
|
" <platform>%s</platform>\n"
|
2008-03-28 18:00:27 +00:00
|
|
|
" <version_num>%d</version_num>\n"
|
|
|
|
" <plan_class>%s</plan_class>\n",
|
|
|
|
pp->name, avp->version_num, avp->plan_class
|
2007-05-21 14:49:00 +00:00
|
|
|
);
|
- scheduler: add support for anonymous-platform coproc apps.
Old: although the request message contained all info
about the app version (flops, coproc usage etc.)
the server ignored this info,
and assumed that all anonymous platform apps where CPU.
With 6.6 client, this could produce infinite work fetch:
- client uses anon platform, has coproc app
- client has idle CPU, requests CPU work
- scheduler sends it jobs, thinking they will be done by CPU app
- client asks for more work etc.
New: scheduler parses full info on anon platform app versions:
plan class, FLOPS, coprocs.
It uses this info to make scheduling decisions;
in particular, if the request is for CUDA work,
if will only send jobs that use a CUDA app version.
The <result> records it returns contain info
(plan_class) that tells the client which app_version to use.
This will work correctly even if the client has multiple app versions
for the same app (e.g., a CPU version and a GPU version)
svn path=/trunk/boinc/; revision=17506
2009-03-05 17:30:10 +00:00
|
|
|
} else if (cavp) {
|
|
|
|
fprintf(fout,
|
2009-03-05 17:54:39 +00:00
|
|
|
" <platform>%s</platform>\n"
|
- scheduler: add support for anonymous-platform coproc apps.
Old: although the request message contained all info
about the app version (flops, coproc usage etc.)
the server ignored this info,
and assumed that all anonymous platform apps where CPU.
With 6.6 client, this could produce infinite work fetch:
- client uses anon platform, has coproc app
- client has idle CPU, requests CPU work
- scheduler sends it jobs, thinking they will be done by CPU app
- client asks for more work etc.
New: scheduler parses full info on anon platform app versions:
plan class, FLOPS, coprocs.
It uses this info to make scheduling decisions;
in particular, if the request is for CUDA work,
if will only send jobs that use a CUDA app version.
The <result> records it returns contain info
(plan_class) that tells the client which app_version to use.
This will work correctly even if the client has multiple app versions
for the same app (e.g., a CPU version and a GPU version)
svn path=/trunk/boinc/; revision=17506
2009-03-05 17:30:10 +00:00
|
|
|
" <version_num>%d</version_num>\n"
|
|
|
|
" <plan_class>%s</plan_class>\n",
|
2009-03-05 17:54:39 +00:00
|
|
|
cavp->platform, cavp->version_num, cavp->plan_class
|
- scheduler: add support for anonymous-platform coproc apps.
Old: although the request message contained all info
about the app version (flops, coproc usage etc.)
the server ignored this info,
and assumed that all anonymous platform apps where CPU.
With 6.6 client, this could produce infinite work fetch:
- client uses anon platform, has coproc app
- client has idle CPU, requests CPU work
- scheduler sends it jobs, thinking they will be done by CPU app
- client asks for more work etc.
New: scheduler parses full info on anon platform app versions:
plan class, FLOPS, coprocs.
It uses this info to make scheduling decisions;
in particular, if the request is for CUDA work,
if will only send jobs that use a CUDA app version.
The <result> records it returns contain info
(plan_class) that tells the client which app_version to use.
This will work correctly even if the client has multiple app versions
for the same app (e.g., a CPU version and a GPU version)
svn path=/trunk/boinc/; revision=17506
2009-03-05 17:30:10 +00:00
|
|
|
);
|
2007-05-21 14:49:00 +00:00
|
|
|
}
|
- scheduler: add support for anonymous-platform coproc apps.
Old: although the request message contained all info
about the app version (flops, coproc usage etc.)
the server ignored this info,
and assumed that all anonymous platform apps where CPU.
With 6.6 client, this could produce infinite work fetch:
- client uses anon platform, has coproc app
- client has idle CPU, requests CPU work
- scheduler sends it jobs, thinking they will be done by CPU app
- client asks for more work etc.
New: scheduler parses full info on anon platform app versions:
plan class, FLOPS, coprocs.
It uses this info to make scheduling decisions;
in particular, if the request is for CUDA work,
if will only send jobs that use a CUDA app version.
The <result> records it returns contain info
(plan_class) that tells the client which app_version to use.
This will work correctly even if the client has multiple app versions
for the same app (e.g., a CPU version and a GPU version)
svn path=/trunk/boinc/; revision=17506
2009-03-05 17:30:10 +00:00
|
|
|
|
2007-05-02 23:14:00 +00:00
|
|
|
fputs("</result>\n", fout);
|
2002-04-30 22:22:54 +00:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2011-08-10 17:11:08 +00:00
|
|
|
int SCHED_DB_RESULT::parse_from_client(XML_PARSER& xp) {
|
2011-09-05 17:29:53 +00:00
|
|
|
double dtemp;
|
2011-09-06 22:53:48 +00:00
|
|
|
bool btemp;
|
|
|
|
string stemp;
|
|
|
|
int itemp;
|
2003-01-07 01:02:08 +00:00
|
|
|
|
2004-03-20 07:57:22 +00:00
|
|
|
// should be non-zero if exit_status is not found
|
2004-06-24 21:00:13 +00:00
|
|
|
exit_status = ERR_NO_EXIT_STATUS;
|
2011-08-08 04:37:53 +00:00
|
|
|
memset(this, 0, sizeof(*this));
|
2011-09-06 22:53:48 +00:00
|
|
|
while (!xp.get_tag()) {
|
|
|
|
if (xp.match_tag("/result")) {
|
2009-03-18 21:14:44 +00:00
|
|
|
return 0;
|
|
|
|
}
|
2011-09-06 22:53:48 +00:00
|
|
|
if (xp.parse_str("name", name, sizeof(name))) continue;
|
|
|
|
if (xp.parse_int("state", client_state)) continue;
|
|
|
|
if (xp.parse_double("final_cpu_time", cpu_time)) continue;
|
|
|
|
if (xp.parse_double("final_elapsed_time", elapsed_time)) continue;
|
|
|
|
if (xp.parse_int("exit_status", exit_status)) continue;
|
|
|
|
if (xp.parse_int("app_version_num", app_version_num)) continue;
|
|
|
|
if (xp.match_tag("file_info")) {
|
|
|
|
string s;
|
|
|
|
xp.copy_element(s);
|
|
|
|
safe_strcat(xml_doc_out, s.c_str());
|
2002-04-30 22:22:54 +00:00
|
|
|
continue;
|
2007-06-14 23:08:43 +00:00
|
|
|
}
|
2011-09-06 22:53:48 +00:00
|
|
|
if (xp.match_tag("stderr_out" )) {
|
|
|
|
copy_element_contents(xp.f->f, "</stderr_out>", stderr_out, sizeof(stderr_out));
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
if (xp.parse_string("platform", stemp)) continue;
|
|
|
|
if (xp.parse_int("version_num", itemp)) continue;
|
|
|
|
if (xp.parse_string("plan_class", stemp)) continue;
|
|
|
|
if (xp.parse_double("completed_time", dtemp)) continue;
|
|
|
|
if (xp.parse_string("file_name", stemp)) continue;
|
|
|
|
if (xp.match_tag("file_ref")) {
|
|
|
|
xp.copy_element(stemp);
|
2002-04-30 22:22:54 +00:00
|
|
|
continue;
|
2003-01-07 01:02:08 +00:00
|
|
|
}
|
2011-09-06 22:53:48 +00:00
|
|
|
if (xp.parse_string("open_name", stemp)) continue;
|
|
|
|
if (xp.parse_bool("ready_to_report", btemp)) continue;
|
|
|
|
if (xp.parse_double("report_deadline", dtemp)) continue;
|
|
|
|
if (xp.parse_string("wu_name", stemp)) continue;
|
2007-09-23 21:38:47 +00:00
|
|
|
|
2011-09-05 17:29:53 +00:00
|
|
|
// deprecated stuff
|
2011-09-06 22:53:48 +00:00
|
|
|
if (xp.parse_double("fpops_per_cpu_sec", dtemp)) continue;
|
|
|
|
if (xp.parse_double("fpops_cumulative", dtemp)) continue;
|
|
|
|
if (xp.parse_double("intops_per_cpu_sec", dtemp)) continue;
|
|
|
|
if (xp.parse_double("intops_cumulative", dtemp)) continue;
|
2011-09-05 17:29:53 +00:00
|
|
|
|
2008-02-21 21:00:58 +00:00
|
|
|
log_messages.printf(MSG_NORMAL,
|
2007-06-14 23:08:43 +00:00
|
|
|
"RESULT::parse_from_client(): unrecognized: %s\n",
|
2011-09-06 22:53:48 +00:00
|
|
|
xp.parsed_tag
|
2007-06-14 23:08:43 +00:00
|
|
|
);
|
2002-04-30 22:22:54 +00:00
|
|
|
}
|
2004-01-08 00:27:59 +00:00
|
|
|
return ERR_XML_PARSE;
|
2002-04-30 22:22:54 +00:00
|
|
|
}
|
|
|
|
|
2011-08-10 17:11:08 +00:00
|
|
|
int HOST::parse(XML_PARSER& xp) {
|
2005-02-14 04:39:07 +00:00
|
|
|
p_ncpus = 1;
|
2011-09-06 22:53:48 +00:00
|
|
|
double dtemp;
|
|
|
|
string stemp;
|
|
|
|
while (!xp.get_tag()) {
|
|
|
|
if (xp.match_tag("/host_info")) return 0;
|
|
|
|
if (xp.parse_int("timezone", timezone)) continue;
|
|
|
|
if (xp.parse_str("domain_name", domain_name, sizeof(domain_name))) continue;
|
|
|
|
if (xp.parse_str("ip_addr", last_ip_addr, sizeof(last_ip_addr))) continue;
|
|
|
|
if (xp.parse_str("host_cpid", host_cpid, sizeof(host_cpid))) continue;
|
|
|
|
if (xp.parse_int("p_ncpus", p_ncpus)) continue;
|
|
|
|
if (xp.parse_str("p_vendor", p_vendor, sizeof(p_vendor))) continue;
|
|
|
|
if (xp.parse_str("p_model", p_model, sizeof(p_model))) continue;
|
|
|
|
if (xp.parse_double("p_fpops", p_fpops)) continue;
|
|
|
|
if (xp.parse_double("p_iops", p_iops)) continue;
|
|
|
|
if (xp.parse_double("p_membw", p_membw)) continue;
|
|
|
|
if (xp.parse_str("os_name", os_name, sizeof(os_name))) continue;
|
|
|
|
if (xp.parse_str("os_version", os_version, sizeof(os_version))) continue;
|
|
|
|
if (xp.parse_double("m_nbytes", m_nbytes)) continue;
|
|
|
|
if (xp.parse_double("m_cache", m_cache)) continue;
|
|
|
|
if (xp.parse_double("m_swap", m_swap)) continue;
|
|
|
|
if (xp.parse_double("d_total", d_total)) continue;
|
|
|
|
if (xp.parse_double("d_free", d_free)) continue;
|
|
|
|
if (xp.parse_double("n_bwup", n_bwup)) continue;
|
|
|
|
if (xp.parse_double("n_bwdown", n_bwdown)) continue;
|
|
|
|
if (xp.parse_str("p_features", p_features, sizeof(p_features))) continue;
|
|
|
|
if (xp.parse_str("virtualbox_version", virtualbox_version, sizeof(virtualbox_version))) continue;
|
2011-12-30 09:43:58 +00:00
|
|
|
if (xp.parse_bool("p_vm_extensions_disabled", p_vm_extensions_disabled)) continue;
|
2005-10-04 21:44:58 +00:00
|
|
|
|
|
|
|
// parse deprecated fields to avoid error messages
|
2005-10-23 07:19:03 +00:00
|
|
|
//
|
2011-09-06 22:53:48 +00:00
|
|
|
if (xp.parse_double("p_calculated", dtemp)) continue;
|
|
|
|
if (xp.match_tag("p_fpop_err")) continue;
|
|
|
|
if (xp.match_tag("p_iop_err")) continue;
|
|
|
|
if (xp.match_tag("p_membw_err")) continue;
|
2005-10-04 21:44:58 +00:00
|
|
|
|
2006-06-22 19:40:30 +00:00
|
|
|
// fields reported by 5.5+ clients, not currently used
|
2006-05-24 09:40:35 +00:00
|
|
|
//
|
2011-09-06 22:53:48 +00:00
|
|
|
if (xp.parse_string("p_capabilities", stemp)) continue;
|
|
|
|
if (xp.parse_string("accelerators", stemp)) continue;
|
2006-05-24 09:40:35 +00:00
|
|
|
|
2007-09-23 21:38:47 +00:00
|
|
|
#if 1
|
2008-12-19 20:55:49 +00:00
|
|
|
// not sure where these fields belong in the above categories
|
2007-09-23 21:38:47 +00:00
|
|
|
//
|
2011-09-06 22:53:48 +00:00
|
|
|
if (xp.parse_string("cpu_caps", stemp)) continue;
|
|
|
|
if (xp.parse_string("cache_l1", stemp)) continue;
|
|
|
|
if (xp.parse_string("cache_l2", stemp)) continue;
|
|
|
|
if (xp.parse_string("cache_l3", stemp)) continue;
|
2007-09-23 21:38:47 +00:00
|
|
|
#endif
|
|
|
|
|
2008-02-21 21:00:58 +00:00
|
|
|
log_messages.printf(MSG_NORMAL,
|
2011-09-06 22:53:48 +00:00
|
|
|
"HOST::parse(): unrecognized: %s\n", xp.parsed_tag
|
2007-06-14 23:08:43 +00:00
|
|
|
);
|
2002-04-30 22:22:54 +00:00
|
|
|
}
|
2004-01-08 00:27:59 +00:00
|
|
|
return ERR_XML_PARSE;
|
2002-04-30 22:22:54 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2011-08-10 17:11:08 +00:00
|
|
|
int HOST::parse_time_stats(XML_PARSER& xp) {
|
2011-09-06 22:53:48 +00:00
|
|
|
while (!xp.get_tag()) {
|
|
|
|
if (xp.match_tag("/time_stats")) return 0;
|
|
|
|
if (xp.parse_double("on_frac", on_frac)) continue;
|
|
|
|
if (xp.parse_double("connected_frac", connected_frac)) continue;
|
|
|
|
if (xp.parse_double("active_frac", active_frac)) continue;
|
2008-12-17 20:53:46 +00:00
|
|
|
#if 0
|
2011-09-06 22:53:48 +00:00
|
|
|
if (xp.match_tag("outages")) continue;
|
|
|
|
if (xp.match_tag("outage")) continue;
|
|
|
|
if (xp.match_tag("start")) continue;
|
|
|
|
if (xp.match_tag("end")) continue;
|
2008-02-21 21:00:58 +00:00
|
|
|
log_messages.printf(MSG_NORMAL,
|
2007-06-14 23:08:43 +00:00
|
|
|
"HOST::parse_time_stats(): unrecognized: %s\n",
|
2011-09-06 22:53:48 +00:00
|
|
|
xp.parsed_tag
|
2007-06-14 23:08:43 +00:00
|
|
|
);
|
2008-12-17 20:53:46 +00:00
|
|
|
#endif
|
2002-04-30 22:22:54 +00:00
|
|
|
}
|
2004-01-08 00:27:59 +00:00
|
|
|
return ERR_XML_PARSE;
|
2002-04-30 22:22:54 +00:00
|
|
|
}
|
|
|
|
|
2011-08-10 17:11:08 +00:00
|
|
|
int HOST::parse_net_stats(XML_PARSER& xp) {
|
2011-09-06 22:53:48 +00:00
|
|
|
double dtemp;
|
|
|
|
while (!xp.get_tag()) {
|
|
|
|
if (xp.match_tag("/net_stats")) return 0;
|
|
|
|
if (xp.parse_double("bwup", n_bwup)) continue;
|
|
|
|
if (xp.parse_double("bwdown", n_bwdown)) continue;
|
2007-09-21 18:10:54 +00:00
|
|
|
|
|
|
|
// items reported by 5.10+ clients, not currently used
|
|
|
|
//
|
2011-09-06 22:53:48 +00:00
|
|
|
if (xp.parse_double("avg_time_up", dtemp)) continue;
|
|
|
|
if (xp.parse_double("avg_up", dtemp)) continue;
|
|
|
|
if (xp.parse_double("avg_time_down", dtemp)) continue;
|
|
|
|
if (xp.parse_double("avg_down", dtemp)) continue;
|
2007-09-23 21:38:47 +00:00
|
|
|
|
2008-02-21 21:00:58 +00:00
|
|
|
log_messages.printf(MSG_NORMAL,
|
2007-06-14 23:08:43 +00:00
|
|
|
"HOST::parse_net_stats(): unrecognized: %s\n",
|
2011-09-06 22:53:48 +00:00
|
|
|
xp.parsed_tag
|
2007-06-14 23:08:43 +00:00
|
|
|
);
|
2002-04-30 22:22:54 +00:00
|
|
|
}
|
2004-01-08 00:27:59 +00:00
|
|
|
return ERR_XML_PARSE;
|
2002-04-30 22:22:54 +00:00
|
|
|
}
|
2003-11-04 22:22:06 +00:00
|
|
|
|
2011-08-10 17:11:08 +00:00
|
|
|
int HOST::parse_disk_usage(XML_PARSER& xp) {
|
2011-09-06 22:53:48 +00:00
|
|
|
while (!xp.get_tag()) {
|
|
|
|
if (xp.match_tag("/disk_usage")) return 0;
|
|
|
|
if (xp.parse_double("d_boinc_used_total", d_boinc_used_total)) continue;
|
|
|
|
if (xp.parse_double("d_boinc_used_project", d_boinc_used_project)) continue;
|
2012-02-01 03:30:14 +00:00
|
|
|
if (xp.parse_double("d_project_share", d_project_share)) continue;
|
2008-02-21 21:00:58 +00:00
|
|
|
log_messages.printf(MSG_NORMAL,
|
2007-06-14 23:08:43 +00:00
|
|
|
"HOST::parse_disk_usage(): unrecognized: %s\n",
|
2011-09-06 22:53:48 +00:00
|
|
|
xp.parsed_tag
|
2007-06-14 23:08:43 +00:00
|
|
|
);
|
2005-10-04 21:44:58 +00:00
|
|
|
}
|
|
|
|
return ERR_XML_PARSE;
|
|
|
|
}
|
|
|
|
|
2006-11-07 17:40:55 +00:00
|
|
|
void GLOBAL_PREFS::parse(const char* buf, const char* venue) {
|
2008-03-31 16:19:45 +00:00
|
|
|
char buf2[BLOB_SIZE];
|
2006-10-04 17:01:36 +00:00
|
|
|
double dtemp;
|
2005-04-18 18:42:29 +00:00
|
|
|
|
2006-10-31 17:14:03 +00:00
|
|
|
defaults();
|
2003-11-04 22:22:06 +00:00
|
|
|
|
2008-02-03 21:46:30 +00:00
|
|
|
if (parse_double(buf, "<mod_time>", mod_time)) {
|
|
|
|
// mod_time is outside of venue
|
|
|
|
if (mod_time > dtime()) mod_time = dtime();
|
|
|
|
}
|
2004-03-31 06:07:17 +00:00
|
|
|
extract_venue(buf, venue, buf2);
|
|
|
|
parse_double(buf2, "<disk_max_used_gb>", disk_max_used_gb);
|
|
|
|
parse_double(buf2, "<disk_max_used_pct>", disk_max_used_pct);
|
|
|
|
parse_double(buf2, "<disk_min_free_gb>", disk_min_free_gb);
|
2005-04-18 18:42:29 +00:00
|
|
|
parse_double(buf2, "<work_buf_min_days>", work_buf_min_days);
|
2006-10-04 17:01:36 +00:00
|
|
|
if (parse_double(buf2, "<ram_max_used_busy_pct>", dtemp)) {
|
|
|
|
ram_max_used_busy_frac = dtemp/100.;
|
|
|
|
}
|
|
|
|
if (parse_double(buf2, "<ram_max_used_idle_pct>", dtemp)) {
|
|
|
|
ram_max_used_idle_frac = dtemp/100.;
|
|
|
|
}
|
2008-03-27 18:25:29 +00:00
|
|
|
parse_double(buf2, "<max_ncpus_pct>", max_ncpus_pct);
|
2006-10-06 18:52:50 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void GLOBAL_PREFS::defaults() {
|
|
|
|
memset(this, 0, sizeof(GLOBAL_PREFS));
|
2003-11-04 22:22:06 +00:00
|
|
|
}
|
2004-09-13 18:05:54 +00:00
|
|
|
|
|
|
|
void GUI_URLS::init() {
|
|
|
|
text = 0;
|
2009-05-07 13:54:51 +00:00
|
|
|
read_file_malloc(config.project_path("gui_urls.xml"), text);
|
2004-09-13 18:05:54 +00:00
|
|
|
}
|
|
|
|
|
2004-09-27 19:44:40 +00:00
|
|
|
void GUI_URLS::get_gui_urls(USER& user, HOST& host, TEAM& team, char* buf) {
|
2004-09-13 18:05:54 +00:00
|
|
|
bool found;
|
2010-01-12 21:53:40 +00:00
|
|
|
char userid[256], teamid[256], hostid[256], weak_auth[256], rss_auth[256];
|
2004-09-13 18:05:54 +00:00
|
|
|
strcpy(buf, "");
|
|
|
|
if (!text) return;
|
|
|
|
strcpy(buf, text);
|
|
|
|
|
|
|
|
sprintf(userid, "%d", user.id);
|
|
|
|
sprintf(hostid, "%d", host.id);
|
2004-09-27 19:44:40 +00:00
|
|
|
if (user.teamid) {
|
|
|
|
sprintf(teamid, "%d", team.id);
|
|
|
|
} else {
|
|
|
|
strcpy(teamid, "0");
|
2004-09-27 20:09:49 +00:00
|
|
|
while (remove_element(buf, "<ifteam>", "</ifteam>")) {
|
2004-09-27 19:44:40 +00:00
|
|
|
continue;
|
|
|
|
}
|
|
|
|
}
|
2010-01-12 21:53:40 +00:00
|
|
|
|
|
|
|
get_weak_auth(user, weak_auth);
|
|
|
|
get_rss_auth(user, rss_auth);
|
2004-09-13 18:05:54 +00:00
|
|
|
while (1) {
|
|
|
|
found = false;
|
|
|
|
found |= str_replace(buf, "<userid/>", userid);
|
2004-09-27 19:44:40 +00:00
|
|
|
found |= str_replace(buf, "<user_name/>", user.name);
|
2004-09-13 18:05:54 +00:00
|
|
|
found |= str_replace(buf, "<hostid/>", hostid);
|
|
|
|
found |= str_replace(buf, "<teamid/>", teamid);
|
2004-09-27 19:44:40 +00:00
|
|
|
found |= str_replace(buf, "<team_name/>", team.name);
|
2004-09-13 18:05:54 +00:00
|
|
|
found |= str_replace(buf, "<authenticator/>", user.authenticator);
|
2010-01-12 21:53:40 +00:00
|
|
|
found |= str_replace(buf, "<weak_auth/>", weak_auth);
|
|
|
|
found |= str_replace(buf, "<rss_auth/>", rss_auth);
|
2004-09-13 18:05:54 +00:00
|
|
|
if (!found) break;
|
|
|
|
}
|
|
|
|
}
|
2004-12-08 00:40:19 +00:00
|
|
|
|
2006-06-26 22:58:24 +00:00
|
|
|
void PROJECT_FILES::init() {
|
|
|
|
text = 0;
|
2009-05-07 13:54:51 +00:00
|
|
|
read_file_malloc(config.project_path("project_files.xml"), text);
|
2006-06-26 22:58:24 +00:00
|
|
|
}
|
|
|
|
|
2010-01-12 21:53:40 +00:00
|
|
|
void get_weak_auth(USER& user, char* buf) {
|
|
|
|
char buf2[256], out[256];
|
|
|
|
sprintf(buf2, "%s%s", user.authenticator, user.passwd_hash);
|
|
|
|
md5_block((unsigned char*)buf2, strlen(buf2), out);
|
|
|
|
sprintf(buf, "%d_%s", user.id, out);
|
|
|
|
}
|
|
|
|
|
|
|
|
void get_rss_auth(USER& user, char* buf) {
|
|
|
|
char buf2[256], out[256];
|
|
|
|
sprintf(buf2, "%s%s%s", user.authenticator, user.passwd_hash, "notify_rss");
|
|
|
|
md5_block((unsigned char*)buf2, strlen(buf2), out);
|
|
|
|
sprintf(buf, "%d_%s", user.id, out);
|
|
|
|
}
|
|
|
|
|
- server: change the following from per-host to per-(host, app version):
- daily quota mechanism
- reliable mechanism (accelerated retries)
- "trusted" mechanism (adaptive replication)
- scheduler: enforce host scale probation only for apps with
host_scale_check set.
- validator: do scale probation on invalid results
(need this in addition to error and timeout cases)
- feeder: update app version scales every 10 min, not 10 sec
- back-end apps: support --foo as well as -foo for options
Notes:
- If you have, say, cuda, cuda23 and cuda_fermi plan classes,
a host will have separate quotas for each one.
That means it could error out on 100 jobs for cuda_fermi,
and when its quota goes to zero,
error out on 100 jobs for cuda23, etc.
This is intentional; there may be cases where one version
works but not the others.
- host.error_rate and host.max_results_day are deprecated
TODO:
- the values in the app table for limits on jobs in progress etc.
should override rather than config.xml.
Implementation notes:
scheduler:
process_request():
read all host_app_versions for host at start;
Compute "reliable" and "trusted" for each one.
write modified records at end
get_app_version():
add "reliable_only" arg; if set, use only reliable versions
skip over-quota versions
Multi-pass scheduling: if have at least one reliable version,
do a pass for jobs that need reliable,
and use only reliable versions.
Then clear best_app_versions cache.
Score-based scheduling: for need-reliable jobs,
it will pick the fastest version,
then give a score bonus if that version happens to be reliable.
When get back a successful result from client:
increase daily quota
When get back an error result from client:
impose scale probation
decrease daily quota if not aborted
Validator:
when handling a WU, create a vector of HOST_APP_VERSION
parallel to vector of RESULT.
Pass it to assign_credit_set().
Make copies of originals so we can update only modified ones
update HOST_APP_VERSION error rates
Transitioner:
decrease quota on timeout
svn path=/trunk/boinc/; revision=21181
2010-04-15 03:13:56 +00:00
|
|
|
void read_host_app_versions() {
|
|
|
|
DB_HOST_APP_VERSION hav;
|
|
|
|
char clause[256];
|
|
|
|
|
|
|
|
sprintf(clause, "where host_id=%d", g_reply->host.id);
|
|
|
|
while (!hav.enumerate(clause)) {
|
|
|
|
g_wreq->host_app_versions.push_back(hav);
|
|
|
|
}
|
|
|
|
g_wreq->host_app_versions_orig = g_wreq->host_app_versions;
|
|
|
|
}
|
|
|
|
|
|
|
|
DB_HOST_APP_VERSION* gavid_to_havp(int gavid) {
|
|
|
|
for (unsigned int i=0; i<g_wreq->host_app_versions.size(); i++) {
|
|
|
|
DB_HOST_APP_VERSION& hav = g_wreq->host_app_versions[i];
|
|
|
|
if (hav.app_version_id == gavid) return &hav;
|
|
|
|
}
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
void write_host_app_versions() {
|
|
|
|
for (unsigned int i=0; i<g_wreq->host_app_versions.size(); i++) {
|
|
|
|
DB_HOST_APP_VERSION& hav = g_wreq->host_app_versions[i];
|
|
|
|
DB_HOST_APP_VERSION& hav_orig = g_wreq->host_app_versions_orig[i];
|
|
|
|
|
|
|
|
int retval = hav.update_scheduler(hav_orig);
|
|
|
|
if (retval) {
|
|
|
|
log_messages.printf(MSG_CRITICAL,
|
2010-11-08 17:51:57 +00:00
|
|
|
"CRITICAL: hav.update_sched() error: %s\n", boincerror(retval)
|
- server: change the following from per-host to per-(host, app version):
- daily quota mechanism
- reliable mechanism (accelerated retries)
- "trusted" mechanism (adaptive replication)
- scheduler: enforce host scale probation only for apps with
host_scale_check set.
- validator: do scale probation on invalid results
(need this in addition to error and timeout cases)
- feeder: update app version scales every 10 min, not 10 sec
- back-end apps: support --foo as well as -foo for options
Notes:
- If you have, say, cuda, cuda23 and cuda_fermi plan classes,
a host will have separate quotas for each one.
That means it could error out on 100 jobs for cuda_fermi,
and when its quota goes to zero,
error out on 100 jobs for cuda23, etc.
This is intentional; there may be cases where one version
works but not the others.
- host.error_rate and host.max_results_day are deprecated
TODO:
- the values in the app table for limits on jobs in progress etc.
should override rather than config.xml.
Implementation notes:
scheduler:
process_request():
read all host_app_versions for host at start;
Compute "reliable" and "trusted" for each one.
write modified records at end
get_app_version():
add "reliable_only" arg; if set, use only reliable versions
skip over-quota versions
Multi-pass scheduling: if have at least one reliable version,
do a pass for jobs that need reliable,
and use only reliable versions.
Then clear best_app_versions cache.
Score-based scheduling: for need-reliable jobs,
it will pick the fastest version,
then give a score bonus if that version happens to be reliable.
When get back a successful result from client:
increase daily quota
When get back an error result from client:
impose scale probation
decrease daily quota if not aborted
Validator:
when handling a WU, create a vector of HOST_APP_VERSION
parallel to vector of RESULT.
Pass it to assign_credit_set().
Make copies of originals so we can update only modified ones
update HOST_APP_VERSION error rates
Transitioner:
decrease quota on timeout
svn path=/trunk/boinc/; revision=21181
2010-04-15 03:13:56 +00:00
|
|
|
);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
DB_HOST_APP_VERSION* BEST_APP_VERSION::host_app_version() {
|
|
|
|
if (cavp) {
|
|
|
|
return gavid_to_havp(
|
|
|
|
generalized_app_version_id(host_usage.resource_type(), appid)
|
|
|
|
);
|
|
|
|
} else {
|
|
|
|
return gavid_to_havp(avp->id);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// return some HAV for which quota was exceeded
|
|
|
|
//
|
|
|
|
DB_HOST_APP_VERSION* quota_exceeded_version() {
|
|
|
|
for (unsigned int i=0; i<g_wreq->host_app_versions.size(); i++) {
|
|
|
|
DB_HOST_APP_VERSION& hav = g_wreq->host_app_versions[i];
|
|
|
|
if (hav.daily_quota_exceeded) return &hav;
|
|
|
|
}
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
2012-01-09 17:35:48 +00:00
|
|
|
double capped_host_fpops() {
|
|
|
|
double x = g_request->host.p_fpops;
|
2012-06-06 03:47:13 +00:00
|
|
|
if (!ssp) return x;
|
2012-01-09 17:35:48 +00:00
|
|
|
if (x <= 0) {
|
|
|
|
return ssp->perf_info.host_fpops_50_percentile;
|
|
|
|
}
|
|
|
|
if (x > ssp->perf_info.host_fpops_95_percentile*1.1) {
|
|
|
|
return ssp->perf_info.host_fpops_95_percentile*1.1;
|
|
|
|
}
|
|
|
|
return x;
|
|
|
|
}
|
|
|
|
|
2005-01-02 18:29:53 +00:00
|
|
|
const char *BOINC_RCSID_ea659117b3 = "$Id$";
|