]> git.sesse.net Git - freerainbowtables/blob - BOINC software/BOINC server apps/chain_checker_workgenerator/chain_checker_workgenerator.cpp
initial
[freerainbowtables] / BOINC software / BOINC server apps / chain_checker_workgenerator / chain_checker_workgenerator.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 // sample_work_generator.C: an example BOINC work generator.
19 // This work generator has the following properties
20 // (you may need to change some or all of these):
21 //
22 // - Runs as a daemon, and creates an unbounded supply of work.
23 //   It attempts to maintain a "cushion" of 100 unsent job instances.
24 //   (your app may not work this way; e.g. you might create work in batches)
25 // - Creates work for the application "uppercase".
26 // - Creates a new input file for each job;
27 //   the file (and the workunit names) contain a timestamp
28 //   and sequence number, so that they're unique.
29
30 #include <unistd.h>
31 #include <cstdlib>
32 #include <string>
33 #include <cstring>
34
35 #include "boinc_db.h"
36 #include "filesys.h"
37 #include "error_numbers.h"
38 #include "backend_lib.h"
39 #include "parse.h"
40 #include "util.h"
41
42 #include "sched_config.h"
43 #include "sched_util.h"
44 #include "sched_msgs.h"
45
46 #define CUSHION 100
47 #define int64 long long
48     // maintain at least this many unsent results
49 #define REPLICATION_FACTOR 2
50 // globals
51 //
52 char* wu_template;
53 DB_APP app;
54 DB_CONN *frt;
55 int start_time;
56 int seqno;
57
58 using namespace std;
59 // create one new job
60 //
61 int make_job() { 
62     DB_WORKUNIT wu;
63     MYSQL_RES* resp;    
64     MYSQL_ROW row;
65     char name[256], path[256], query[1024];
66     const char* infiles[1];
67     int retval;
68     string charset;
69  
70     sprintf(query, "SELECT lookupid, hashroutine, charset, minletters, maxletters, `index`, hash FROM rainbowcrack_cracker_verificationqueue WHERE inuse = 0 LIMIT 1");
71     log_messages.printf(MSG_DEBUG, "%s\n", query);
72     retval = frt->do_query(query);
73     if(retval) {
74        log_messages.printf(MSG_DEBUG, "Query returned %i\n", retval);   
75         return retval;
76
77     }
78     resp = mysql_store_result(frt->mysql);
79     if (!resp) return ERR_DB_NOT_FOUND;
80     row = mysql_fetch_row(resp);
81     mysql_free_result(resp);
82     if (!row) return ERR_DB_NOT_FOUND;
83         
84     sprintf(query, "UPDATE rainbowcrack_cracker_verificationqueue SET inuse = 1 WHERE lookupid = %s", row[0]);
85     log_messages.printf(MSG_DEBUG, "%s\n", query);
86     retval = frt->do_query(query);
87     if(retval)  return retval;
88
89     char command_line[256];
90     char filename[256];
91     sprintf(command_line, "%s %s %s %s %s %s", row[1], row[2], row[3], row[4], row[5], row[6]);
92
93     // make a unique name (for the job and its input file)
94     //
95     sprintf(name, "%s_cc", row[0]);
96     retval = config.download_path(name, path);
97     if (retval) return retval;
98     log_messages.printf(MSG_DEBUG, "Path determined to be %s\n", path);
99     sprintf(filename, "/home/boincadm/chains/%s.chains", row[0]);
100     log_messages.printf(MSG_DEBUG, "Copying from %s to %s\n", filename, path);
101     retval = boinc_copy(filename, path);
102     if (retval) return retval;
103     log_messages.printf(MSG_DEBUG, "Removing old file %s\n", filename);
104     unlink(filename);
105
106     log_messages.printf(MSG_DEBUG, "%s\n", name); 
107     infiles[0] = name;
108     read_file_malloc("../templates/chain_checker_input_template.xml", wu_template);
109     // Fill in the job parameters
110     //
111     wu.clear();
112     wu.appid = app.id;
113     strcpy(wu.name, name);
114     wu.rsc_fpops_est = 1e12;
115     wu.rsc_fpops_bound = 1e14;
116     wu.rsc_memory_bound = 1e8;
117     wu.rsc_disk_bound = 1e8;
118     wu.delay_bound = 86400;
119     wu.min_quorum = 2;
120     wu.target_nresults = 2;
121     wu.max_error_results = 8;
122     wu.max_total_results = 10;
123     wu.max_success_results = 2;
124     // Register the job with BOINC
125     //
126     return create_work(
127         wu,
128         wu_template,
129         "templates/output_template.xml",
130         "../templates/output_template.xml",
131         infiles,
132         1,
133         config,
134         command_line
135     );
136 }
137
138 void main_loop() {
139     int retval;
140
141     while (1) {
142         check_stop_daemons();
143         int n;
144         retval = count_unsent_results(n, 0);
145         if (n > CUSHION) {
146             sleep(60);
147         } else {
148             int njobs = (CUSHION-n)/REPLICATION_FACTOR;
149             log_messages.printf(MSG_DEBUG,
150                 "Making %d jobs\n", njobs
151             );
152             for (int i=0; i<njobs; i++) {
153                 retval = make_job();
154                 if (retval) {
155                     log_messages.printf(MSG_CRITICAL,
156                         "can't make job: %d\n", retval
157                     );
158                     exit(retval);
159                 }
160             }
161             // Now sleep for a few seconds to let the transitioner
162             // create instances for the jobs we just created.
163             // Otherwise we could end up creating an excess of jobs.
164             sleep(5);
165         }
166     }
167 }
168
169 int main(int argc, char** argv) {
170     int i, retval;
171     frt = new DB_CONN();
172
173     for (i=1; i<argc; i++) {
174         if (!strcmp(argv[i], "-d")) {
175             log_messages.set_debug_level(atoi(argv[++i]));
176         } else {
177             log_messages.printf(MSG_CRITICAL,
178                 "bad cmdline arg: %s", argv[i]
179             );
180         }
181     }
182
183     if (config.parse_file("..")) {
184         log_messages.printf(MSG_CRITICAL,
185             "can't read config file\n"
186         );
187         exit(1);
188     }
189     retval = frt->open("rainbowtables-distrrtgen", config.db_host, config.db_user, config.db_passwd);
190     if (retval) {
191         log_messages.printf(MSG_CRITICAL, "can't open db rainbowtables-distrrtgen\n");
192         exit(1);
193     }
194
195     retval = boinc_db.open(
196         config.db_name, config.db_host, config.db_user, config.db_passwd
197     );
198     if (retval) {
199         log_messages.printf(MSG_CRITICAL, "can't open db\n");
200         exit(1);
201     }
202     if (app.lookup("where name='chain_checker'")) {
203         log_messages.printf(MSG_CRITICAL, "can't find app\n");
204         exit(1);
205     }
206     if (read_file_malloc("../templates/chain_checker_input_template.xml", wu_template)) {
207         log_messages.printf(MSG_CRITICAL, "can't read WU template\n");
208         exit(1);
209     }
210
211     start_time = time(0);
212     seqno = 0;
213
214     log_messages.printf(MSG_NORMAL, "Starting\n");
215
216     main_loop();
217 }
218