1
// This file is part of BOINC.
2
// http://boinc.berkeley.edu
3
// Copyright (C) 2008 University of California
5
// BOINC is free software; you can redistribute it and/or modify it
6
// under the terms of the GNU Lesser General Public License
7
// as published by the Free Software Foundation,
8
// either version 3 of the License, or (at your option) any later version.
10
// BOINC is distributed in the hope that it will be useful,
11
// but WITHOUT ANY WARRANTY; without even the implied warranty of
12
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
13
// See the GNU Lesser General Public License for more details.
15
// You should have received a copy of the GNU Lesser General Public License
16
// along with BOINC. If not, see <http://www.gnu.org/licenses/>.
18
#ifndef _SERVER_TYPES_
19
#define _SERVER_TYPES_
25
#include "common_defs.h"
31
// for projects that support work filtering by app,
32
// this records an app for which the user will accept work
39
// represents a resource (disk etc.) that the client may not have enough of
43
double needed; // the min extra amount needed
45
inline void set_insufficient(double x) {
48
if (x < needed) needed = x;
55
// message intended for human eyes
60
USER_MESSAGE(const char* m, const char*p);
69
double projected_flops;
70
// the scheduler's best estimate of wu.rsc_fpops_est/elapsed_time.
71
// Taken from host_app_version elapsed time statistics if available,
72
// else on estimate provided by app_plan()
74
// stored in result.estimated_flops, and used for credit calculations
87
void sequential_app(double x) {
98
inline int resource_type() {
100
return ANON_PLATFORM_NVIDIA;
102
return ANON_PLATFORM_ATI;
104
return ANON_PLATFORM_CPU;
106
inline const char* resource_name() {
114
inline bool uses_gpu() {
115
if (ncudas) return true;
116
if (natis) return true;
121
// a description of a sticky file on host.
129
struct MSG_FROM_HOST_DESC {
131
std::string msg_text;
135
// an app version from an anonymous-platform client
136
// (starting with 6.11, ALL clients send these)
138
struct CLIENT_APP_VERSION {
142
char plan_class[256];
143
HOST_USAGE host_usage;
144
double rsc_fpops_scale;
145
// multiply wu.rsc_fpops_est and rsc_fpops_limit
146
// by this amount when send to client,
147
// to reflect the discrepancy between how fast the client
148
// thinks the app is versus how fast we think it is
150
// if NULL, this record is a place-holder,
151
// used to preserve array indices
156
// keep track of the best app_version for each app for this host
158
struct BEST_APP_VERSION {
161
// maintain this separately for jobs that need > 2GB RAM,
162
// in which case we can't use 32-bit apps
165
// false means there's no usable version for this app
167
CLIENT_APP_VERSION* cavp;
168
// populated if anonymous platform
171
// populated otherwise
173
HOST_USAGE host_usage;
174
// populated in either case
179
DB_HOST_APP_VERSION* host_app_version();
180
// get the HOST_APP_VERSION, if any
189
// subset of global prefs used by scheduler
191
struct GLOBAL_PREFS {
193
double disk_max_used_gb;
194
double disk_max_used_pct;
195
double disk_min_free_gb;
196
double work_buf_min_days;
197
double ram_max_used_busy_frac;
198
double ram_max_used_idle_frac;
199
double max_ncpus_pct;
201
void parse(const char* buf, const char* venue);
203
inline double work_buf_min() {return work_buf_min_days*86400;}
209
void get_gui_urls(USER& user, HOST& host, TEAM& team, char*);
212
struct PROJECT_FILES {
217
// Represents a result from this project that the client has.
218
// The request message has a list of these.
219
// The reply message may include a list of those to be aborted
220
// or aborted if not started
222
struct OTHER_RESULT {
224
int app_version; // index into CLIENT_APP_VERSION array
226
bool have_plan_class;
228
bool abort_if_not_started;
229
int reason; // see codes below
234
#define ABORT_REASON_NOT_FOUND 1
235
#define ABORT_REASON_WU_CANCELLED 2
236
#define ABORT_REASON_ASSIMILATED 3
237
#define ABORT_REASON_TIMED_OUT 4
239
struct CLIENT_PLATFORM {
244
struct PLATFORM_LIST {
245
std::vector<PLATFORM*> list;
248
struct SCHEDULER_REQUEST {
249
char authenticator[256];
250
CLIENT_PLATFORM platform;
251
std::vector<CLIENT_PLATFORM> alt_platforms;
252
PLATFORM_LIST platforms;
253
char cross_project_id[256];
254
int hostid; // zero if first RPC
255
int core_client_major_version;
256
int core_client_minor_version;
257
int core_client_release;
258
int core_client_version; // 10000*major + 100*minor + release
260
double work_req_seconds;
261
// in "normalized CPU seconds" (see work_req.php)
263
double cpu_req_instances;
264
double resource_share_fraction;
265
// this project's fraction of total resource share
267
// ... of runnable resource share
268
double prrs_fraction;
269
// ... of potentially runnable resource share
270
double cpu_estimated_delay;
271
// currently queued jobs saturate the CPU for this long;
272
// used for crude deadline check
273
double duration_correction_factor;
274
char global_prefs_xml[BLOB_SIZE];
275
char working_global_prefs_xml[BLOB_SIZE];
276
char code_sign_key[4096];
278
std::vector<CLIENT_APP_VERSION> client_app_versions;
279
GLOBAL_PREFS global_prefs;
280
char global_prefs_source_email_hash[MD5_LEN];
282
HOST host; // request message is parsed into here.
283
// does NOT contain the full host record.
285
std::vector<RESULT> results;
286
// completed results being reported
287
std::vector<MSG_FROM_HOST_DESC> msgs_from_host;
288
std::vector<FILE_INFO> file_infos;
289
// sticky files reported by host for locality scheduling
290
std::vector<FILE_INFO> file_delete_candidates;
291
// sticky files reported by host, deletion candidates
292
std::vector<FILE_INFO> files_not_needed;
293
// sticky files reported by host, no longer needed
294
std::vector<OTHER_RESULT> other_results;
295
// in-progress results from this project
296
std::vector<IP_RESULT> ip_results;
297
// in-progress results from all projects
298
bool have_other_results_list;
299
bool have_ip_results_list;
300
bool have_time_stats_log;
301
bool client_cap_plan_class;
303
// whether client uses account-based sandbox. -1 = don't know
304
int allow_multiple_clients;
305
// whether client allows multiple clients per host, -1 don't know
306
bool using_weak_auth;
307
// Request uses weak authenticator.
308
// Don't modify user prefs or CPID
309
int last_rpc_dayofyear;
310
int current_rpc_dayofyear;
313
~SCHEDULER_REQUEST();
314
const char* parse(FILE*);
315
int write(FILE*); // write request info to file: not complete
318
// keep track of bottleneck disk preference
326
// summary of a client's request for work, and our response to it
327
// Note: this is zeroed out in SCHEDULER_REPLY constructor
330
bool anonymous_platform;
332
// Flags used by old-style scheduling,
333
// while making multiple passes through the work array
334
bool infeasible_only;
339
bool resend_lost_results;
340
// this is set if the request is reporting a result
341
// that was previously reported.
342
// This is evidence that the earlier reply was not received
343
// by the client. It may have contained results,
344
// so check and resend just in case.
350
bool allow_non_preferred_apps;
351
bool allow_beta_work;
352
std::vector<APP_INFO> preferred_apps;
354
bool has_reliable_version;
355
// whether the host has a reliable app version
360
// 6.7+ clients send separate requests for different resource types:
362
double cpu_req_secs; // instance-seconds requested
363
double cpu_req_instances; // number of idle instances, use if possible
364
double cuda_req_secs;
365
double cuda_req_instances;
367
double ati_req_instances;
368
inline bool need_cpu() {
369
return (cpu_req_secs>0) || (cpu_req_instances>0);
371
inline bool need_cuda() {
372
return (cuda_req_secs>0) || (cuda_req_instances>0);
374
inline bool need_ati() {
375
return (ati_req_secs>0) || (ati_req_instances>0);
377
inline void clear_cpu_req() {
379
cpu_req_instances = 0;
381
inline void clear_gpu_req() {
383
cuda_req_instances = 0;
385
ati_req_instances = 0;
388
// older clients send send a single number, the requested duration of jobs
390
double seconds_to_fill;
392
// true if new-type request, which has resource-specific requests
394
bool rsc_spec_request;
396
double disk_available;
397
double ram, usable_ram;
401
// The following keep track of the "easiest" job that was rejected
402
// by EDF simulation.
403
// Any jobs harder than this can be rejected without doing the simulation.
405
double edf_reject_min_cpu;
406
int edf_reject_max_delay_bound;
407
bool have_edf_reject;
408
void edf_reject(double cpu, int delay_bound) {
409
if (have_edf_reject) {
410
if (cpu < edf_reject_min_cpu) edf_reject_min_cpu = cpu;
411
if (delay_bound> edf_reject_max_delay_bound) edf_reject_max_delay_bound = delay_bound;
413
edf_reject_min_cpu = cpu;
414
edf_reject_max_delay_bound = delay_bound;
415
have_edf_reject = true;
418
bool edf_reject_test(double cpu, int delay_bound) {
419
if (!have_edf_reject) return false;
420
if (cpu < edf_reject_min_cpu) return false;
421
if (delay_bound > edf_reject_max_delay_bound) return false;
430
std::vector<USER_MESSAGE> no_work_messages;
431
std::vector<BEST_APP_VERSION*> best_app_versions;
432
std::vector<BEST_APP_VERSION*> all_best_app_versions;
433
std::vector<DB_HOST_APP_VERSION> host_app_versions;
434
std::vector<DB_HOST_APP_VERSION> host_app_versions_orig;
436
// various reasons for not sending jobs (used to explain why)
438
bool no_allowed_apps_available;
441
bool outdated_client;
445
bool max_jobs_on_host_exceeded;
446
bool max_jobs_on_host_cpu_exceeded;
447
bool max_jobs_on_host_gpu_exceeded;
448
bool no_jobs_available; // project has no work right now
449
int max_jobs_per_rpc;
450
void update_for_result(double seconds_filled);
451
void add_no_work_message(const char*);
452
void get_job_limits();
455
for (unsigned int i=0; i<all_best_app_versions.size(); i++) {
456
delete all_best_app_versions[i];
461
// NOTE: if any field requires initialization,
462
// you must do it in the constructor. Nothing is zeroed by default.
464
struct SCHEDULER_REPLY {
466
DISK_LIMITS disk_limits;
467
double request_delay; // don't request again until this time elapses
468
std::vector<USER_MESSAGE> messages;
470
// nonzero only if a new host record was created.
471
// this tells client to reset rpc_seqno
472
int lockfile_fd; // file descriptor of lockfile, or -1 if no lock.
473
bool send_global_prefs;
474
bool nucleus_only; // send only message
476
char email_hash[MD5_LEN];
477
HOST host; // after validation, contains full host rec
479
std::vector<APP> apps;
480
std::vector<APP_VERSION> app_versions;
481
std::vector<WORKUNIT>wus;
482
std::vector<RESULT>results;
483
std::vector<std::string>result_acks;
484
std::vector<std::string>result_aborts;
485
std::vector<std::string>result_abort_if_not_starteds;
486
std::vector<MSG_TO_HOST>msgs_to_host;
487
std::vector<FILE_INFO>file_deletes;
488
char code_sign_key[4096];
489
char code_sign_key_signature[4096];
491
bool project_is_down;
495
int write(FILE*, SCHEDULER_REQUEST&);
496
void insert_app_unique(APP&);
497
void insert_app_version_unique(APP_VERSION&);
498
void insert_workunit_unique(WORKUNIT&);
499
void insert_result(RESULT&);
500
void insert_message(const char* msg, const char* prio);
501
void insert_message(USER_MESSAGE&);
502
void set_delay(double);
505
extern SCHEDULER_REQUEST* g_request;
506
extern SCHEDULER_REPLY* g_reply;
507
extern WORK_REQ* g_wreq;
509
static inline void add_no_work_message(const char* m) {
510
g_wreq->add_no_work_message(m);
513
extern void get_weak_auth(USER&, char*);
514
extern void get_rss_auth(USER&, char*);
515
extern void read_host_app_versions();
516
extern DB_HOST_APP_VERSION* get_host_app_version(int gavid);
517
extern void write_host_app_versions();
519
extern DB_HOST_APP_VERSION* gavid_to_havp(int gavid);
520
extern DB_HOST_APP_VERSION* quota_exceeded_version();