]> git.sesse.net Git - freerainbowtables/blob - BOINC software/BOINC client apps/distrrtgen/Release/sched_util.cpp
cleanup
[freerainbowtables] / BOINC software / BOINC client apps / distrrtgen / Release / sched_util.cpp
1 // This file is part of BOINC.
2 // http://boinc.berkeley.edu
3 // Copyright (C) 2008 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 using namespace std;
19
20 #include "config.h"
21 #include <cstdlib>
22 #include <csignal>
23 #include <cerrno>
24 #include <unistd.h>
25 #include <sys/stat.h>
26 #include <sys/types.h>
27 #include <fcntl.h>
28
29 #include "filesys.h"
30 #include "md5_file.h"
31 #include "error_numbers.h"
32
33 #include "sched_msgs.h"
34 #include "sched_util.h"
35 #include "util.h"
36
37 #ifdef _USING_FCGI_
38 #include "boinc_fcgi.h"
39 #endif
40
41 const char* STOP_DAEMONS_FILENAME = "../stop_daemons";
42     // NOTE: this must be same as in the "start" script
43 const char* STOP_SCHED_FILENAME = "../stop_sched";
44     // NOTE: this must be same as in the "start" script
45 const int STOP_SIGNAL = SIGHUP;
46     // NOTE: this must be same as in the "start" script
47
48 void write_pid_file(const char* filename) {
49 #ifndef _USING_FCGI_
50     FILE* fpid = fopen(filename, "w");
51 #else
52     FCGI_FILE* fpid = FCGI::fopen(filename,"w");
53 #endif
54
55     if (!fpid) {
56         log_messages.printf(MSG_CRITICAL, "Couldn't write pid file\n");
57         return;
58     }
59     fprintf(fpid, "%d\n", (int)getpid());
60     fclose(fpid);
61 }
62
63 // caught_sig_int will be set to true if STOP_SIGNAL (normally SIGHUP)
64 //  is caught.
65 bool caught_stop_signal = false;
66 static void stop_signal_handler(int) {
67     fprintf(stderr, "GOT STOP SIGNAL\n");
68     caught_stop_signal = true;
69 }
70
71 void install_stop_signal_handler() {
72     signal(STOP_SIGNAL, stop_signal_handler);
73     // handler is now default again so hitting ^C again will kill the program.
74 }
75
76 void check_stop_daemons() {
77     if (caught_stop_signal) {
78         log_messages.printf(MSG_NORMAL, "Quitting due to SIGHUP\n");
79         exit(0);
80     }
81     if (boinc_file_exists(STOP_DAEMONS_FILENAME)) {
82         log_messages.printf(MSG_NORMAL,
83             "Quitting because trigger file '%s' is present\n",
84             STOP_DAEMONS_FILENAME
85         );
86         exit(0);
87     }
88 }
89
90 bool check_stop_sched() {
91     return boinc_file_exists(STOP_SCHED_FILENAME);
92 }
93
94 // try to open a file.
95 // On failure:
96 //   return ERR_FOPEN if the dir is there but not file
97 //     (this is generally a nonrecoverable failure)
98 //   return ERR_OPENDIR if dir is not there.
99 //     (this is generally a recoverable error,
100 //     like NFS mount failure, that may go away later)
101 //
102 #ifndef _USING_FCGI_
103 int try_fopen(const char* path, FILE*& f, const char* mode) {
104 #else
105 int try_fopen(const char* path, FCGI_FILE*& f, const char *mode) {
106 #endif
107     char* p;
108     DIR* d;
109     char dirpath[256];
110
111 #ifndef _USING_FCGI_
112     f = fopen(path, mode);
113 #else
114     f = FCGI::fopen(path, mode);
115 #endif
116
117     if (!f) {
118         memset(dirpath, '\0', sizeof(dirpath));
119         p = strrchr(path, '/');
120         if (p) {
121             strncpy(dirpath, path, (int)(p-path));
122         } else {
123             strcpy(dirpath, ".");
124         }
125         if ((d = opendir(dirpath)) == NULL) {
126             return ERR_OPENDIR;
127         } else {
128             closedir(d);
129             return ERR_FOPEN;
130         }
131     }
132     return 0;
133 }
134
135 void get_log_path(char* p, const char* filename) {
136     char host[256];
137     char dir[256];
138     gethostname(host, 256);
139     char* q = strchr(host, '.');
140     if (q) *q=0;
141     sprintf(dir, "../log_%s", host);
142     sprintf(p, "%s/%s", dir, filename);
143     mode_t old_mask = umask(0);
144     mkdir(dir, 01770);
145         // make log_x directory sticky and group-rwx
146         // so that whatever apache puts there will be owned by us
147     umask(old_mask);
148 }
149
150 static void filename_hash(const char* filename, int fanout, char* dir) {
151         std::string s = md5_string((const unsigned char*)filename, strlen(filename));
152         int x = strtol(s.substr(1, 7).c_str(), 0, 16);
153     sprintf(dir, "%x", x % fanout);
154 }
155
156 // given a filename, compute its path in a directory hierarchy
157 // If create is true, create the directory if needed
158 //
159 int dir_hier_path(
160     const char* filename, const char* root, int fanout,
161         char* path, bool create
162 ) {
163     char dir[256], dirpath[256];
164     int retval;
165
166     if (fanout==0) {
167         sprintf(path, "%s/%s", root, filename);
168         return 0;
169     }
170
171     filename_hash(filename, fanout, dir);
172
173     sprintf(dirpath, "%s/%s", root, dir);
174     if (create) {
175         retval = boinc_mkdir(dirpath);
176         if (retval && (errno != EEXIST)) {
177             fprintf(stderr, "boinc_mkdir(%s): retval %d errno %d\n", dirpath, retval, errno);
178             return ERR_MKDIR;
179         }
180     }
181     sprintf(path, "%s/%s", dirpath, filename);
182     return 0;
183 }
184
185 // same, but the output is a URL (used by tools/backend_lib.C)
186 //
187 int dir_hier_url(
188     const char* filename, const char* root, int fanout,
189         char* result
190 ) {
191     char dir[256];
192
193     if (fanout==0) {
194         sprintf(result, "%s/%s", root, filename);
195         return 0;
196     }
197
198     filename_hash(filename, fanout, dir);
199     sprintf(result, "%s/%s/%s", root, dir, filename);
200     return 0;
201 }
202
203 // Locality scheduling: get filename from result name
204 //
205
206 int extract_filename(char* in, char* out) {
207     strcpy(out, in);
208     char* p = strstr(out, "__");
209     if (!p) return -1;
210     *p = 0;
211     return 0;
212 }
213
214 void compute_avg_turnaround(HOST& host, double turnaround) {
215     double new_avg;
216     if (host.avg_turnaround == 0) {
217         new_avg = turnaround;
218     } else {
219         new_avg = .7*host.avg_turnaround + .3*turnaround;
220     }
221     host.avg_turnaround = new_avg;
222 }
223
224 double elapsed_wallclock_time() {
225     static double wallclock_execution_time=0.0;
226
227     if (wallclock_execution_time == 0.0) {
228         wallclock_execution_time=dtime();
229         return 0.0;
230     }
231
232     return dtime()-wallclock_execution_time;
233 }
234
235 // Request lock on the given file with given fd.  Returns:
236 // 0 if we get lock
237 // PID (>0) if another process has lock
238 // -1 if error
239 //
240 int mylockf(int fd) {
241     struct flock fl;
242     fl.l_type=F_WRLCK;
243     fl.l_whence=SEEK_SET;
244     fl.l_start=0;
245     fl.l_len=0;
246     if (-1 != fcntl(fd, F_SETLK, &fl)) return 0;
247
248     // if lock failed, find out why
249     errno=0;
250     fcntl(fd, F_GETLK, &fl);
251     if (fl.l_pid>0) return fl.l_pid;
252     return -1;
253 }
254
255 double fpops_to_credit(double fpops, double intops) {
256     // TODO: use fp_weight if specified in config file
257     double fpc = (fpops/1e9)*COBBLESTONE_FACTOR/SECONDS_PER_DAY;
258     double intc = (intops/1e9)*COBBLESTONE_FACTOR/SECONDS_PER_DAY;
259     return std::max(fpc, intc);
260 }
261
262 double credit_multiplier(int appid, time_t create_time) {
263     DB_CREDIT_MULTIPLIER mult;
264     mult.get_nearest(appid,create_time);
265     return mult.multiplier;
266 }
267
268 int count_results(char* query, int& n) {
269     DB_RESULT result;
270     int retval = result.count(n, query);
271     if (retval) return retval;
272     return 0;
273 }
274
275 int count_workunits(int& n, const char* query) {
276     DB_WORKUNIT workunit;
277     int retval = workunit.count(n, query);
278     if (retval) return retval;
279     return 0;
280 }
281
282 int count_unsent_results(int& n, int appid) {
283     char buf[256];
284     if (appid) {
285         sprintf(buf, "where server_state=%d and appid=%d ",
286             RESULT_SERVER_STATE_UNSENT, appid
287         );
288     } else {
289         sprintf(buf, "where server_state=%d", RESULT_SERVER_STATE_UNSENT);
290     }
291     return count_results(buf, n);
292
293 }
294
295 #ifdef GCL_SIMULATOR
296
297 void simulator_signal_handler(int signum){    
298     FILE *fsim;
299     char currenttime[64];
300     fsim = fopen("../simulator/sim_time.txt","r");
301     if(fsim){
302         fscanf(fsim,"%s", currenttime);
303         simtime = atof(currenttime); 
304         fclose(fsim);
305     }
306     log_messages.printf(SCHED_MSG_LOG::MSG_NORMAL,
307         "Invoked by the simulator at time %.0f... \n", simtime
308     );
309 }
310
311 int itime() {
312     return (int) simtime;
313 }
314
315 void continue_simulation(const char *daemonname){
316     char daemonfilelok[64];
317     char daemonfile[64];
318     sprintf(daemonfile, "../simulator/sim_%s.txt",daemonname);
319     sprintf(daemonfilelok, "../simulator/sim_%s.lok",daemonname);
320     FILE *fsimlok = fopen(daemonfilelok, "w");
321     if (fsimlok){
322         fclose(fsimlok);
323         FILE *fsim = fopen(daemonfile, "w");
324         if (fsim) {
325             fclose(fsim);
326         }
327     }
328     remove(daemonfilelok);
329 }
330
331 #endif
332
333 const char *BOINC_RCSID_affa6ef1e4 = "$Id: sched_util.cpp 16097 2008-09-30 18:21:41Z davea $";