1 // This file is part of BOINC.
2 // http://boinc.berkeley.edu
3 // Copyright (C) 2014 University of California
4 //
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.
9 //
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.
14 //
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/>.
17 
18 #ifndef BOINC_PROJECT_H
19 #define BOINC_PROJECT_H
20 
21 #include "app_config.h"
22 #include "client_types.h"
23 
24 // describes a project to which this client is attached
25 //
26 struct PROJECT : PROJ_AM {
27     char _project_dir[MAXPATHLEN];
28     char _project_dir_absolute[MAXPATHLEN];
29 
30     std::string sci_keywords;
31     std::string loc_keywords;
32 
33     // the following items come from the account file
34     // They are a function of the user and the project (not host)
35     //
36     char authenticator[256];
37         // user's authenticator on this project
38     std::string project_prefs;
39         // without the enclosing <project_preferences> tags.
40         // May include <venue> elements
41         // This field is used only briefly: between handling a
42         // scheduler RPC reply and writing the account file
43     std::string project_specific_prefs;
44         // without enclosing <project_specific> tags
45         // Does not include <venue> elements
46     std::string gui_urls;
47         // GUI URLs, with enclosing <gui_urls> tags
48     double resource_share;
49         // project's resource share relative to other projects.
50     double resource_share_frac;
51         // temp; fraction of RS of non-suspended, compute-intensive projects
52     double disk_resource_share;
53         // temp in get_disk_shares()
54     double desired_disk_usage;
55         // reported by project
56     double ddu;
57         // temp in get_disk_shares()
58     double disk_quota;
59         // temp in get_disk_shares()
60 
61     // the following are from the user's project prefs
62     //
63     bool no_rsc_pref[MAX_RSC];
64 
65     // derived from GPU exclusions in cc_config.xml;
66     // disable work fetch if all instances excluded
67     //
68     bool no_rsc_config[MAX_RSC];
69 
70     // the following are from the project itself
71     // (or derived from app version list if anonymous platform)
72     //
73     bool no_rsc_apps[MAX_RSC];
74 
75     // the following are from the account manager, if any
76     //
77     bool no_rsc_ams[MAX_RSC];
78 
79     char host_venue[256];
80         // logically, this belongs in the client state file
81         // rather than the account file.
82         // But we need it in the latter in order to parse prefs.
83     bool using_venue_specific_prefs;
84 
85     ///////  START OF ITEMS STORED IN client_state.xml
86     //
87     // They may depend on the host as well as user and project
88     // NOTE: if you add anything, add it to copy_state_fields() also!!!
89     //
90     std::vector<std::string> scheduler_urls;
91         // where to find scheduling servers
92     char symstore[256];
93         // URL of symbol server (Windows)
94     char user_name[256];
95     char team_name[256];
96     char email_hash[MD5_LEN];
97     char cross_project_id[MD5_LEN];
98         // the "internal" user CPID
99     char external_cpid[MD5_LEN];
100         // the "external" user CPID (as exported to stats sites)
101     double cpid_time;
102     double user_total_credit;
103     double user_expavg_credit;
104     double user_create_time;
105     int userid;
106     int teamid;
107     int hostid;
108     double host_total_credit;
109     double host_expavg_credit;
110     double host_create_time;
111     double ams_resource_share;
112         // resource share according to AMS; overrides project
113         // -1 means not specified by AMS, or not using an AMS
114     double last_rpc_time;
115         // when last RPC finished; used by Manager
116     double duration_correction_factor;
117         // Multiply by this when estimating the CPU time of a result
118         // (based on FLOPs estimated and benchmarks).
119         // This is dynamically updated in a way that maintains an upper bound.
120         // it goes down slowly but if a new estimate X is larger,
121         // the factor is set to X.
122         //
123         // Deprecated - current server logic handles this,
124         // and this should go to 1.
125         // But we need to keep it around for older projects
126 
127     // accounting info; estimated credit and time for CPU and GPU
128     //
129     double cpu_ec;
130     double cpu_time;
131     double gpu_ec;
132     double gpu_time;
133 
134     // stuff related to scheduler RPCs and master fetch
135     //
136     int rpc_seqno;
137     int nrpc_failures;
138         // # of consecutive times we've failed to contact all scheduling servers
139     int master_fetch_failures;
140     double min_rpc_time;
141         // earliest time to contact any server of this project (or zero)
142     double next_rpc_time;
143         // if nonzero, specifies a time when another scheduler RPC
144         // should be done (as requested by server).
145         // An RPC could be done sooner than this.
146     bool waiting_until_min_rpc_time();
147         // returns true if min_rpc_time > now
148     bool master_url_fetch_pending;
149         // need to fetch and parse the master URL
150     int sched_rpc_pending;
151         // we need to do a scheduler RPC, for various possible reasons:
152         // user request, propagate host CPID, time-based, etc.
153         // Reasons are enumerated in lib/common_defs.h
154     bool trickle_up_pending;
155         // have trickle up to send
156     double disk_usage;
157         // computed by get_disk_usages()
158     double disk_share;
159         // computed by get_disk_shares();
160 
161     ///////  END OF ITEMS STORED IN client_state.xml
162 
163     // Other stuff
164     //
165     bool possibly_backed_off;
166         // we need to call request_work_fetch() when a project
167         // transitions from being backed off to not.
168         // This (slightly misnamed) keeps track of whether this
169         // may still need to be done for given project
170     bool anonymous_platform;
171         // app_versions.xml file found in project dir;
172         // use those apps rather then getting from server
173     bool non_cpu_intensive;
174         // All this project's apps are non-CPU-intensive.
175         // Apps can also be individually marked as NCI
176     bool verify_files_on_app_start;
177         // Check app version and input files on app startup,
178         // to make sure they haven't been tampered with.
179         // This provides only the illusion of security.
180     bool use_symlinks;
181     bool report_results_immediately;
182 
183     // items sent in scheduler replies,
184     // requesting that various things be sent subsequent requests
185     //
186     int send_time_stats_log;
187         // if nonzero, send time stats log from that point on
188     int send_job_log;
189         // if nonzero, send this project's job log from that point on
190     bool send_full_workload;
191 
192     bool dont_use_dcf;
193 
194     bool suspended_via_gui;
195     bool dont_request_more_work;
196         // Return work, but don't request more
197         // Used for a clean exit to a project,
198         // or if a user wants to pause doing work for the project
199     bool attached_via_acct_mgr;
200     bool detach_when_done;
201         // when no results for this project, detach it.
202         // if using AM, do AM RPC before detaching
203     bool ended;
204         // project has ended; advise user to detach
205     char code_sign_key[MAX_KEY_LEN];
206     std::vector<FILE_REF> user_files;
207     std::vector<FILE_REF> project_files;
208         // files not specific to apps or work - e.g. icons
209 
210     ///////////////// member functions /////////////////
211 
212     void set_min_rpc_time(double future_time, const char* reason);
213     int parse_preferences_for_user_files();
214     void write_project_files(MIOFILE&);
215     void link_project_files();
216     void create_project_file_symlinks();
217     void delete_project_file_symlinks();
218     int write_symlink_for_project_file(FILE_INFO*);
219     double project_files_downloaded_time;
220         // when last project file download finished
221     void update_project_files_downloaded_time();
222         // called when a project file download finishes.
223         // If it's the last one, set project_files_downloaded_time to now
224 
225     void update_duration_correction_factor(ACTIVE_TASK*);
226 
227     // fields used by CPU scheduler and work fetch
228     // everything from here on applies only to CPU intensive projects
229 
230     bool can_request_work();
231         // not suspended and not deferred and not no more work
232     bool runnable(int rsc_type);
233         // has a runnable result using the given resource type
234     bool downloading();
235         // has a result in downloading state
236     bool potentially_runnable();
237         // runnable or contactable or downloading
238     bool nearly_runnable();
239         // runnable or downloading
240     bool overworked();
241         // the project has used too much CPU time recently
242     bool some_download_stalled();
243         // a download is backed off
244     bool some_result_suspended();
245     bool uploading();
246     bool has_results();
247     int n_concurrent;
248         // used to enforce APP_CONFIGS::max_concurrent
249 
250     struct RESULT *next_runnable_result;
251         // the next result to run for this project
252     int nuploading_results;
253         // number of results in UPLOADING state
254         // Don't start new results if these exceeds 2*ncpus.
255     bool too_many_uploading_results;
256 
257     // scheduling (work fetch and job scheduling)
258     //
259     double sched_priority;
260     void compute_sched_priority();
261 
262     // stuff for RR sim
263     //
264     double rr_sim_cpu_share;
265     bool rr_sim_active;
266     bool operator<(const PROJECT& p) {
267         return sched_priority > p.sched_priority;
268     }
269 
270     // stuff related to work fetch
271     //
272     RSC_PROJECT_WORK_FETCH rsc_pwf[MAX_RSC];
273     PROJECT_WORK_FETCH pwf;
resetPROJECT274     inline void reset() {
275         for (int i=0; i<coprocs.n_rsc; i++) {
276             rsc_pwf[i].reset();
277         }
278     }
deadlines_missedPROJECT279     inline int deadlines_missed(int rsc_type) {
280         return rsc_pwf[rsc_type].deadlines_missed;
281     }
282     void get_task_durs(double& not_started_dur, double& in_progress_dur);
283     void check_no_rsc_apps();
284         // if flags are set for all resource types,
285         // something's wrong; clear them.
286     void check_no_apps();
287         // set no_X_apps for anonymous platform projects
288 
289     int nresults_returned;
290         // # of results being returned in current scheduler op
291     const char* get_scheduler_url(int index, double r);
292         // get scheduler URL with random offset r
293     bool checked;
294         // temporary used when scanning projects
295     bool dont_contact;
296         // temp in find_project_with_overdue_results()
297     int n_ready;
298         // temp in find_project_with_overdue_results()
299 
300     FILE_XFER_BACKOFF download_backoff;
301     FILE_XFER_BACKOFF upload_backoff;
file_xfer_backoffPROJECT302     inline FILE_XFER_BACKOFF& file_xfer_backoff(bool is_upload) {
303         return is_upload?upload_backoff:download_backoff;
304     }
305 
306     // support for replicated trickle-ups
307     //
308     std::vector<TRICKLE_UP_OP*> trickle_up_ops;
309 
310     // app config stuff
311     //
312     APP_CONFIGS app_configs;
313 
314     // job counting
315     //
316     int njobs_success;
317     int njobs_error;
318 
319     // total elapsed time of this project's jobs (for export to GUI)
320     //
321     double elapsed_time;
322 
323     PROJECT();
~PROJECTPROJECT324     ~PROJECT(){}
325     void init();
326     void copy_state_fields(PROJECT&);
327     int write_account_file();
328     int parse_account(FILE*);
329     int parse_account_file_venue();
330     int parse_account_file();
331     int parse_state(XML_PARSER&);
332     int write_state(MIOFILE&, bool gui_rpc=false);
333     const char* project_dir();
334     const char* project_dir_absolute();
335     void show_no_work_notice();
336 
337     // statistic of the last x days
338     std::vector<DAILY_STATS> statistics;
339     int parse_statistics(MIOFILE&);
340     int parse_statistics(FILE*);
341     int write_statistics(MIOFILE&);
342     int write_statistics_file();
343     void trim_statistics();
344 
345     void suspend();
346     void resume();
347     void abort_not_started();
348         // abort unstarted jobs
349 
350     // clear AMS-related fields
detach_amsPROJECT351     inline void detach_ams() {
352         attached_via_acct_mgr = false;
353         for (int i=0; i<MAX_RSC; i++) {
354             no_rsc_ams[i] = false;
355         }
356 
357         ams_resource_share = -1;
358 
359         // parse the account file to get right resource share
360         // in case AMS had set it
361         //
362         parse_account_file();
363     }
364 
365 #ifdef SIM
366     RANDOM_PROCESS available;
367     int index;
368     int result_index;
369     double idle_time;
370     double idle_time_sumsq;
371     bool idle;
372     int max_infeasible_count;
373     bool no_apps;
374     bool ignore;
375     // for DCF variants:
376     int completed_task_count;
377     double completions_ratio_mean;
378     double completions_ratio_s;
379     double completions_ratio_stdev;
380     double completions_required_stdevs;
381     PROJECT_RESULTS project_results;
382     void print_results(FILE*, SIM_RESULTS&);
383     void backoff();
384     void update_dcf_stats(RESULT*);
385 #endif
386 };
387 
388 #endif
389