]> git.sesse.net Git - freerainbowtables/blob - BOINC software/BOINC server apps/distrrtgen_workgenerator/distrrtgen_workgenerator.cpp
initial
[freerainbowtables] / BOINC software / BOINC server apps / distrrtgen_workgenerator / distrrtgen_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 "error_numbers.h"
37 #include "backend_lib.h"
38 #include "parse.h"
39 #include "util.h"
40
41 #include "sched_config.h"
42 #include "sched_util.h"
43 #include "sched_msgs.h"
44
45 #define CUSHION 100
46 #define int64 long long
47     // maintain at least this many unsent results
48 #define REPLICATION_FACTOR 2
49 // globals
50 //
51 char* wu_template;
52 DB_APP app;
53 DB_CONN *frt;
54 int start_time;
55 int seqno;
56
57 using namespace std;
58 // create one new job
59 //
60 int make_job() {
61     DB_WORKUNIT wu;
62     MYSQL_RES* resp;    
63     MYSQL_ROW row;
64     char name[256], path[256], query[1024];
65     const char* infiles[1];
66     int retval;
67     string charset;
68 //    retval = frt->do_query("CALL requestwork(1)");    
69     frt->do_query("SELECT TableID, ChainStartPosition FROM generator_tables WHERE ChainsDone < (NumTargetChains/* - (NumTargetChains / 20)*/) AND ChainStartPosition < Keyspace - PartSize AND IsCompleted = 0 LIMIT 1;");
70     if(retval)  return retval;
71     resp = mysql_store_result(frt->mysql);
72     if (!resp) return ERR_DB_NOT_FOUND;
73     row = mysql_fetch_row(resp);
74     mysql_free_result(resp);
75     if (!row) return ERR_DB_NOT_FOUND;
76     int tableid = atoi(row[0]);
77     int64 chainstart = atol(row[1]);
78     sprintf(query, "INSERT INTO generator_parts SET TableID = %s, ClientID = 1, AssignedTime = NOW(), Status = 1, ChainStart = %s\0", row[0], row[1]);
79     log_messages.printf(MSG_DEBUG, "%s\n", query);
80     retval = frt->do_query(query);
81     if(retval)  return retval;
82     int partid = frt->insert_id();
83
84     sprintf(query, "UPDATE generator_tables SET ChainStartPosition = ChainStartPosition + PartSize WHERE TableID = %i\0", tableid);
85     log_messages.printf(MSG_DEBUG, "%s\n", query);
86     retval = frt->do_query(query);
87     if(retval)  return retval;
88
89     
90     log_messages.printf(MSG_DEBUG, "SELECTING FROM DB\n");
91     sprintf(query, "SELECT %i AS PartID, HashRoutine, Charset, MinLetters, MaxLetters, `Index`, ChainLength, PartSize AS ChainCount, '%lld' AS ChainStart, CheckPoints, Salt  FROM generator_tables WHERE TableID = %i;\0", partid, chainstart, tableid);    
92     log_messages.printf(MSG_DEBUG, "%s\n", query);
93
94     retval = frt->do_query(query);
95     if(retval)  return retval;
96     resp = mysql_store_result(frt->mysql);
97     if (!resp) return ERR_DB_NOT_FOUND;
98     row = mysql_fetch_row(resp);
99     mysql_free_result(resp);
100     if (!row) return ERR_DB_NOT_FOUND;
101     char command_line[256];
102 //    char filename[256];
103     sprintf(command_line, "%s %s %s %s %s %s %s %s %s", row[1], row[2], row[3], row[4], row[5], row[6], row[7], row[8], row[9]);
104
105     // make a unique name (for the job and its input file)
106     //
107     sprintf(name, "%s %s_%s#%s-%s_%s_%sx%s - %s", row[0], row[1], row[2], row[3], row[4], row[5], row[6], row[7], row[8]);
108 //    sprintf(filename, "%s.txt", row[0]);
109     log_messages.printf(MSG_DEBUG, "%s\n", name);
110     
111     read_file_malloc("templates/input_template.xml", wu_template);
112   //  read_file_string("../download/charset.txt", charset);
113  /*   retval = config.download_path(filename, path);
114     if (retval) return retval;
115     FILE* f = fopen(path, "wb");
116     if (!f) return ERR_FOPEN;
117     fwrite(charset.c_str(), charset.length(), 1, f);
118     fclose(f);
119     infiles[0] = filename;*/
120     // Fill in the job parameters
121     //
122     wu.clear();
123     wu.appid = app.id;
124     strcpy(wu.name, name);
125     wu.rsc_fpops_est = 1e13;
126     wu.rsc_fpops_bound = 1e16;
127     wu.rsc_memory_bound = 1e8;
128     wu.rsc_disk_bound = 1e8;
129     wu.delay_bound = 4*86400;
130     wu.min_quorum = 1;
131     wu.target_nresults = 1;
132     wu.max_error_results = 8;
133     wu.max_total_results = 10;
134     wu.max_success_results = 2;
135     // Register the job with BOINC
136     //
137     return create_work(
138         wu,
139         wu_template,
140         "templates/output_template.xml",
141         "../templates/output_template.xml",
142         NULL,
143         0,
144         config,
145         command_line
146     );
147 }
148
149 void main_loop() {
150     int retval;
151
152     while (1) {
153         check_stop_daemons();
154         int n;
155         retval = count_unsent_results(n, 0);
156         if (n > CUSHION) {
157             sleep(60);
158         } else {
159             int njobs = (CUSHION-n)/REPLICATION_FACTOR;
160             log_messages.printf(MSG_DEBUG,
161                 "Making %d jobs\n", njobs
162             );
163             for (int i=0; i<njobs; i++) {
164                 retval = make_job();
165                 if (retval) {
166                     log_messages.printf(MSG_CRITICAL,
167                         "can't make job: %d\n", retval
168                     );
169                     exit(retval);
170                 }
171             }
172             // Now sleep for a few seconds to let the transitioner
173             // create instances for the jobs we just created.
174             // Otherwise we could end up creating an excess of jobs.
175             sleep(5);
176         }
177     }
178 }
179
180 int main(int argc, char** argv) {
181     int i, retval;
182     frt = new DB_CONN();
183
184     for (i=1; i<argc; i++) {
185         if (!strcmp(argv[i], "-d")) {
186             log_messages.set_debug_level(atoi(argv[++i]));
187         } else {
188             log_messages.printf(MSG_CRITICAL,
189                 "bad cmdline arg: %s", argv[i]
190             );
191         }
192     }
193
194     if (config.parse_file("..")) {
195         log_messages.printf(MSG_CRITICAL,
196             "can't read config file\n"
197         );
198         exit(1);
199     }
200     retval = frt->open("rainbowtables-distrrtgen", config.db_host, config.db_user, config.db_passwd);
201     if (retval) {
202         log_messages.printf(MSG_CRITICAL, "can't open db rainbowtables-distrrtgen\n");
203         exit(1);
204     }
205
206     retval = boinc_db.open(
207         config.db_name, config.db_host, config.db_user, config.db_passwd
208     );
209     if (retval) {
210         log_messages.printf(MSG_CRITICAL, "can't open db\n");
211         exit(1);
212     }
213     if (app.lookup("where name='distrrtgen'")) {
214         log_messages.printf(MSG_CRITICAL, "can't find app\n");
215         exit(1);
216     }
217     if (read_file_malloc("../templates/input_template.xml", wu_template)) {
218         log_messages.printf(MSG_CRITICAL, "can't read WU template\n");
219         exit(1);
220     }
221
222     start_time = time(0);
223     seqno = 0;
224
225     log_messages.printf(MSG_NORMAL, "Starting\n");
226
227     main_loop();
228 }