forked from BOINC/boinc
-
Notifications
You must be signed in to change notification settings - Fork 0
/
target_batch.cpp
212 lines (149 loc) · 5.45 KB
/
target_batch.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
// NOTE: this is from Derrick Kondo (INRIA). Needs to be cleaned up a bit.
/* Assigns uncompleted (and unassigned) workunits of a batch to hosts
registered under a DEDICATED_USER_ID. The constant DEDICATED_USER_ID
should be defined accordingly below.
The constant MAX_TO_ASSIGN should be defined according to the size of
the feeder's shmem array.
The project dir must be defined in the projects config.xml file.
Input parameter of the form 'batch=[id]' can be passed via url or commmand line.
Example usage from command line:
./target_batch batch=1
Example usage from URL:
http://abenaki.imag.fr/clouds_ops/target_batch?batch=1
----------------
To enable targeted jobs in general in BOINC, add
<enable_assignment>1</enable_assignment>
to the config.xml file.
*/
/* TESTS
PLAIN OLD SCHEDULING OF A BATCH
Works as long as boinc client is up-to-date.
-----------------------
SCHEDULING OF BATCH TARGETTED TO DEDICATED HOST
Create a batch of low-priority tasks:
./create_test_work.pl -appname example_app -numwu 10 -batch 0 -label "lowpri" -db clouds -password "" -wu "templates/example_app_in.xml" -result "templates/example_app_out.xml"
Target batch to dedicated workers:
/bin/target_batch batch=0
Start dedicated work with USER_ID corresonding to DEDICATED_USER_ID.
Check that these tasks are only assigned to dedicated workers.
* Assignment table appears correct
* Cloud worker downloads and processes targetted results. Results in ops
* php page have status "Didn't need"
* Non-cloud workers do not download targetted results
-----------------------
OOO What cleans up the assignment table?
*/
#include "config.h"
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <errno.h>
#include <unistd.h>
#include <ctime>
#include <vector>
#include <string>
using std::vector;
using std::string;
#include "boinc_db.h"
#include "crypt.h"
#include "util.h"
#include "backend_lib.h"
#include "sched_config.h"
#include "parse.h"
#include "sched_util.h"
#include "sched_msgs.h"
#include "str_util.h"
#include "svn_version.h"
#define DEDICATED_USER_ID 1
#define MAX_TO_ASSIGN 100
int main(int argc, char *argv[])
{
//must have two lines after content header. Else you will get "Internal
//Server Error" when executing script
printf ("Content-type: text/plain\n\n");
printf ("Targeting batch\n\n");
int retval = config.parse_file();
if (retval) {
log_messages.printf(MSG_CRITICAL,
"Can't parse config.xml: %s\n", boincerror(retval)
);
exit(1);
}
retval = boinc_db.open(config.db_name, config.db_host, config.db_user, config.db_passwd);
if (retval) {
log_messages.printf(MSG_CRITICAL, "can't open DB\n");
exit(1);
}
char buf[256];
////////////////////////////////////////////////////////////////////////////
// Get targetted batch id
char * query_str = getenv("QUERY_STRING");
if (query_str == NULL){
printf ("Batch id not provided in url. Checking for command line argument...\n");
if (argc==2 && argv[1] != NULL){
printf ("\tUsing batch id from command line\n\n");
query_str = argv[1];
} else {
printf ("Error: batch id not provided, argc: %d\n", argc);
exit(1);
}
}
int batch;
if (sscanf(query_str, "batch=%d", &batch) == 1){
printf ("Targetting batch id: %d\n\n", batch);
} else {
printf ("Bad argument format. Should be \"batch=[id]\"\n");
exit(1);
}
////////////////////////////////////////////////////////////////////////////
// Left join to get workunits not already in the
// assignment table
// TESTED: DOESN'T RESELECT ASSIGNED WUS
sprintf(buf,
"SELECT workunit.* \
FROM workunit \
LEFT JOIN assignment \
ON workunit.id = assignment.workunitid \
WHERE assignment.workunitid IS NULL \
AND canonical_resultid = 0 AND batch = %d \
LIMIT %d",
batch, MAX_TO_ASSIGN);
// Tried moving "AND canonical_resultid = 0 AND batch = %d \" in line
// where join appears, but the results of the query were wrong
retval = boinc_db.do_query(buf);
if (retval) {
printf ("Problem with db\n");
boinc_db.close();
exit(1);
}
MYSQL_RES* rp;
rp = mysql_store_result(boinc_db.mysql);
if (!rp) {
printf ("Problem with db\n");
boinc_db.close();
exit(1);
}
MYSQL_ROW row;
DB_WORKUNIT workunit;
int num_assigned=0;
while ((row = mysql_fetch_row(rp))){
workunit.db_parse(row);
printf ("Assigning WU %d to user \n", workunit.id, DEDICATED_USER_ID);
restrict_wu_to_user (workunit, DEDICATED_USER_ID);
num_assigned++;
printf ("End of this WU assignment\n\n");
}
mysql_free_result(rp);
///////////////////////////////////////////////////////////////////////////
// reset the feeder
char cmd_buf[256];
if (num_assigned>0){
sprintf (cmd_buf, "touch %s/reread_db", config.project_dir);
printf ("Running cmd: %s", cmd_buf);
int ret_val = system (cmd_buf);
if (ret_val > 0){
printf ("Houston: we have a reread_db problem\n");
}
}
printf ("\nDONE.\n");
}