mirror of https://github.com/BOINC/boinc.git
- client code: my next-to-last checkin was flawed
svn path=/trunk/boinc/; revision=14725
This commit is contained in:
parent
e038442f82
commit
35dab13859
|
@ -1321,3 +1321,17 @@ David Feb 12 2008
|
|||
|
||||
client/
|
||||
work_fetch.C
|
||||
|
||||
David Feb 12 2008
|
||||
- client code: my next-to-last checkin was flawed
|
||||
|
||||
client/
|
||||
app_start.C
|
||||
client_state.C,h
|
||||
sandbox.C
|
||||
clientgui/
|
||||
BOINCClientManager.cpp
|
||||
MainDocument.cpp
|
||||
lib/
|
||||
common_defs.h
|
||||
util.C,h
|
||||
|
|
|
@ -496,23 +496,11 @@ int ACTIVE_TASK::start(bool first_time) {
|
|||
cmd_line = exec_path + std::string(" ") + wup->command_line;
|
||||
relative_to_absolute(slot_dir, slotdirpath);
|
||||
bool success = false;
|
||||
get_sandbox_account_token();
|
||||
for (i=0; i<5; i++) {
|
||||
if (strlen(gstate.sandbox_account_name)) {
|
||||
HANDLE hToken;
|
||||
std::string username = gstate.sandbox_account_name;
|
||||
std::string password = r_base64_decode(gstate.sandbox_account_password);
|
||||
if (!LogonUser( username.c_str(), NULL, password.c_str(),
|
||||
LOGON32_LOGON_SERVICE, LOGON32_PROVIDER_DEFAULT,
|
||||
&hToken)
|
||||
) {
|
||||
windows_error_string(error_msg, sizeof(error_msg));
|
||||
msg_printf(wup->project, MSG_INTERNAL_ERROR,
|
||||
"LogonUser failed: %s", error_msg
|
||||
);
|
||||
}
|
||||
|
||||
if (sandbox_account_token != NULL) {
|
||||
if (CreateProcessAsUser(
|
||||
hToken,
|
||||
sandbox_account_token,
|
||||
exec_path,
|
||||
(LPSTR)cmd_line.c_str(),
|
||||
NULL,
|
||||
|
|
|
@ -211,7 +211,6 @@ int CLIENT_STATE::init() {
|
|||
"BOINC is running as a service and as a non-system user."
|
||||
);
|
||||
}
|
||||
read_client_auth_file();
|
||||
#endif
|
||||
|
||||
#ifdef __APPLE__
|
||||
|
|
|
@ -111,11 +111,7 @@ public:
|
|||
char attach_project_auth[256];
|
||||
bool exit_before_upload;
|
||||
// exit when about to upload a file
|
||||
#ifdef _WIN32
|
||||
char sandbox_account_name[256];
|
||||
char sandbox_account_password[256];
|
||||
void read_client_auth_file();
|
||||
#else
|
||||
#ifndef _WIN32
|
||||
gid_t boinc_project_gid;
|
||||
#endif
|
||||
|
||||
|
|
|
@ -38,22 +38,7 @@
|
|||
|
||||
bool g_use_sandbox = false;
|
||||
|
||||
#ifdef _WIN32
|
||||
|
||||
void CLIENT_STATE::read_client_auth_file() {
|
||||
FILE* f;
|
||||
char buf[256];
|
||||
|
||||
f = fopen(CLIENT_AUTH_FILENAME, "r");
|
||||
if (!f) return;
|
||||
while (fgets(buf, 256, f)) {
|
||||
if (parse_str(buf, "<username>", sandbox_account_name, sizeof(sandbox_account_name))) continue;
|
||||
if (parse_str(buf, "<password>", sandbox_account_password, sizeof(sandbox_account_name))) continue;
|
||||
}
|
||||
fclose(f);
|
||||
}
|
||||
|
||||
#else
|
||||
#ifndef _WIN32
|
||||
#ifndef _DEBUG
|
||||
static int lookup_group(char* name, gid_t& gid) {
|
||||
struct group* gp = getgrnam(name);
|
||||
|
|
|
@ -239,11 +239,15 @@ bool CBOINCClientManager::StartupBOINCCore() {
|
|||
argv[4] = NULL;
|
||||
}
|
||||
#endif
|
||||
// Under wxMac-2.8.0, wxExecute starts a separate thread to wait for child's termination.
|
||||
// That wxProcessTerminationThread uses a huge amount of processor time (about 11% of one
|
||||
// CPU on 2GHz Intel Dual-Core Mac).
|
||||
// Under wxMac-2.8.0, wxExecute starts a separate thread
|
||||
// to wait for child's termination.
|
||||
// That wxProcessTerminationThread uses a huge amount of processor
|
||||
// time (about 11% of one CPU on 2GHz Intel Dual-Core Mac).
|
||||
// m_lBOINCCoreProcessId = ::wxExecute(argv);
|
||||
run_program("/Library/Application Support/BOINC Data", buf, argv[3] ? 4 : 3, argv, 0.0, m_lBOINCCoreProcessId);
|
||||
run_program(
|
||||
"/Library/Application Support/BOINC Data",
|
||||
buf, argv[3] ? 4 : 3, argv, 0.0, m_lBOINCCoreProcessId
|
||||
);
|
||||
#endif
|
||||
} else {
|
||||
buf[0] = '\0';
|
||||
|
|
|
@ -1181,7 +1181,9 @@ int CMainDocument::WorkShowGraphics(RESULT* result)
|
|||
char* argv[5];
|
||||
|
||||
if (previous_gfx_app) {
|
||||
// If this graphics app is already running, just bring it to the front
|
||||
// If this graphics app is already running,
|
||||
// just bring it to the front
|
||||
//
|
||||
if (! GetProcessForPID(previous_gfx_app->pid, &gfx_app_psn)) {
|
||||
SetFrontProcess(&gfx_app_psn);
|
||||
}
|
||||
|
@ -1190,6 +1192,7 @@ int CMainDocument::WorkShowGraphics(RESULT* result)
|
|||
// For unknown reasons, the graphics application exits with
|
||||
// "RegisterProcess failed (error = -50)" unless we pass its
|
||||
// full path twice in the argument list to execv.
|
||||
//
|
||||
argv[0] = "switcher";
|
||||
argv[1] = (char *)result->graphics_exec_path.c_str();
|
||||
argv[2] = (char *)result->graphics_exec_path.c_str();
|
||||
|
@ -1219,6 +1222,7 @@ int CMainDocument::WorkShowGraphics(RESULT* result)
|
|||
char* argv[2];
|
||||
|
||||
// If graphics app is already running, don't launch a second instance
|
||||
//
|
||||
if (previous_gfx_app) return 0;
|
||||
argv[0] = "--graphics";
|
||||
argv[1] = 0;
|
||||
|
|
|
@ -1,9 +1,10 @@
|
|||
alter table bossa_app
|
||||
add unique(name);
|
||||
add unique(name),
|
||||
add unique(short_name);
|
||||
|
||||
alter table bossa_job
|
||||
add unique(name),
|
||||
add index bj_more_needed(app_id, more_needed);
|
||||
add index bj_conf_needed(app_id, conf_needed);
|
||||
|
||||
alter table bossa_job_inst
|
||||
add index bji_job(job_id),
|
||||
|
|
|
@ -2,6 +2,7 @@ create table bossa_app (
|
|||
id integer not null auto_increment,
|
||||
create_time integer not null,
|
||||
name varchar(255) not null,
|
||||
short_name varchar(255) not null,
|
||||
description varchar(255) not null,
|
||||
long_jobs tinyint not null,
|
||||
display_script varchar(255) not null,
|
||||
|
@ -25,7 +26,8 @@ create table bossa_job (
|
|||
time_estimate integer not null,
|
||||
time_limit integer not null,
|
||||
transition_time double not null,
|
||||
nneeded integer not null,
|
||||
conf_needed double not null,
|
||||
canonical_inst_id integer not null,
|
||||
primary key(id)
|
||||
) engine=InnoDB;
|
||||
|
||||
|
@ -35,12 +37,15 @@ create table bossa_job_inst (
|
|||
job_id integer not null,
|
||||
user_id integer not null,
|
||||
finish_time integer not null,
|
||||
validate_state integer not null,
|
||||
-- 0 init, 1 valid, 2 invalid
|
||||
info text,
|
||||
primary key(id)
|
||||
) engine=InnoDB;
|
||||
|
||||
create table bossa_app_user (
|
||||
app_id integer not null,
|
||||
create table bossa_user (
|
||||
user_id integer not null,
|
||||
info text
|
||||
-- Info about skill.
|
||||
-- May depend on app; may be scalar or something else
|
||||
);
|
||||
|
|
|
@ -1,6 +1,10 @@
|
|||
<?
|
||||
|
||||
$project_news = array(
|
||||
array("Feb 12, 2008",
|
||||
"Where is BOINC headed? Marcin Cieslak's vision:
|
||||
<a href=http://boinc.berkeley.edu/cieslak.pdf>BOINC on JXTA</a>."
|
||||
),
|
||||
array("Feb 11, 2008",
|
||||
"Bulgarian BOINC users:
|
||||
find forums and information in your language at
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
// two results are compatible if neither found an ellipse,
|
||||
// or they both did and centers are within 20 pixels
|
||||
//
|
||||
function compare($r1, $r2) {
|
||||
function ellipse_compare($r1, $r2) {
|
||||
if ($r1->have_ellipse) {
|
||||
if ($r2->have_ellipse) {
|
||||
$dx = ($r1->cx - $r2->cx);
|
||||
|
@ -18,7 +18,7 @@ function compare($r1, $r2) {
|
|||
|
||||
// handle a completed job with the given consensus set
|
||||
//
|
||||
function handle_consensus($bj, $c) {
|
||||
function ellipse_handle($bj, $c) {
|
||||
$res = $c[0];
|
||||
if ($res->have_ellipse) {
|
||||
$res->cx = 0;
|
||||
|
|
|
@ -5,9 +5,11 @@ require_once("../inc/util_ops.inc");
|
|||
|
||||
function show_bapp($app) {
|
||||
echo "<tr>
|
||||
<td>Name: $app->name<br>Description: $app->description<br>Created: ".date_str($app->create_time)."</td>
|
||||
<td>$app->display_script</td>
|
||||
<td>$app->backend_script</td>
|
||||
<td>Name: $app->name<br>
|
||||
Short name: $app->short_name<br>
|
||||
Description: $app->description<br>
|
||||
Created: ".date_str($app->create_time)."
|
||||
</td>
|
||||
<td>
|
||||
";
|
||||
if ($app->hidden) {
|
||||
|
@ -35,12 +37,11 @@ function add_app_form() {
|
|||
start_table();
|
||||
row1("Add app");
|
||||
row2("Name<span class=note><br>Visible to users</span>", "<input name=app_name>");
|
||||
row2("Short name<span class=note><br>Used in file and function names - no spaces or special characters</span>", "<input name=short_name>");
|
||||
row2("Description<span class=note><br>Visible to users</span>", "<textarea name=description cols=60></textarea>");
|
||||
row2("Display script filename", "<input name=display_script>");
|
||||
row2("Backend script filename", "<input name=backend_script>");
|
||||
row2("Min confidence sum for consensus", "<input name=min_conf_sum>");
|
||||
row2("Min confidence fraction for consensus", "<input name=min_conf_frac>");
|
||||
row2("Max instances", "<input name=max_instances>");
|
||||
row2("Min confidence sum for consensus", "<input name=min_conf_sum value=2>");
|
||||
row2("Min confidence fraction for consensus", "<input name=min_conf_frac value=\"0.5\">");
|
||||
row2("Max job instances", "<input name=max_instances value=5>");
|
||||
row2("", "<input type=submit name=submit value=\"Create app\">");
|
||||
end_table();
|
||||
echo "</form>";
|
||||
|
|
|
@ -12,6 +12,61 @@ function lookup_app($id) {
|
|||
return null;
|
||||
}
|
||||
|
||||
// return the confidence of the instances that agree with the given one
|
||||
//
|
||||
function agree_conf($instances, $inst) {
|
||||
$sum = $inst->conf;
|
||||
foreach ($instances as $i) {
|
||||
if ($i->id == $inst->id) continue;
|
||||
if (compatible($i, $inst)) {
|
||||
$sum += $i->conf;
|
||||
}
|
||||
}
|
||||
return $sum;
|
||||
}
|
||||
|
||||
// return the total confidence
|
||||
//
|
||||
function total_confidence($instances) {
|
||||
$sum = 0;
|
||||
foreach ($instances as $i) {
|
||||
if (!$i->finished_time) continue;
|
||||
$sum += $i->conf;
|
||||
}
|
||||
}
|
||||
|
||||
// See if there's a canonical instance.
|
||||
// If there's not, return the confidence of the largest compatible set
|
||||
//
|
||||
function find_canonical($instances, $total_conf, &$max_conf) {
|
||||
$best = null;
|
||||
$best_conf = 0;
|
||||
foreach ($instances as $inst) {
|
||||
$ac = agree_conf($instances, $inst);
|
||||
if ($ac > $best_conf) {
|
||||
$best_conf = $ac;
|
||||
$best = $inst;
|
||||
}
|
||||
}
|
||||
if (!$best) return;
|
||||
$max_conf = $best_conf;
|
||||
if ($best_conf < $app->min_conf_sum) return;
|
||||
if ($best_conf/$total_conf < $app->min_conf_frac) return;
|
||||
return $best;
|
||||
}
|
||||
|
||||
function get_confidence(&$instances) {
|
||||
foreach ($instances as $inst) {
|
||||
$user = BoincUser::lookup_id($inst->user_id);
|
||||
BossaUser::lookup($user);
|
||||
$inst->conf = 1;
|
||||
}
|
||||
}
|
||||
|
||||
// this gets invoked when
|
||||
// 1) an instance has been completed
|
||||
// 2) an instance has timed out
|
||||
//
|
||||
function handle_job($job) {
|
||||
$app = lookup_app($job->app_id);
|
||||
if (!$app) {
|
||||
|
@ -19,6 +74,32 @@ function handle_job($job) {
|
|||
return;
|
||||
}
|
||||
$instances = BossaJobInst::enum("job_id=$job->id");
|
||||
if ($job->canonical_inst_id) {
|
||||
// Already have a canonical instance.
|
||||
// Are there new instances to validate?
|
||||
//
|
||||
$canonical_inst = find_canonical($job, $instances);
|
||||
foreach ($instances as $inst) {
|
||||
switch ($inst->validate_state) {
|
||||
case VALIDATE_STATE_INIT:
|
||||
if (compatible($inst, $canonical_inst)) {
|
||||
$inst->validate_state = VALIDATE_STATE_VALID;
|
||||
} else {
|
||||
$inst->validate_state = VALIDATE_STATE_INVALID;
|
||||
}
|
||||
$inst->update("validate_state=$inst->validate_state");
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// No canonical instance yet.
|
||||
// If we have enough total confidence, check for consensus
|
||||
//
|
||||
get_confidences($instances);
|
||||
$total_conf = total_confidence(instances);
|
||||
if ($total_conf >= $app->min_conf_sum) {
|
||||
$inst = find_canonical($instances, $total_conf, $max_conf);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function do_pass() {
|
||||
|
@ -32,6 +113,10 @@ function do_pass() {
|
|||
function main() {
|
||||
global $apps;
|
||||
$apps = BossaApp::enum();
|
||||
foreach ($apps as $app) {
|
||||
$bs = "../lib/".$app->short_name."_backend.inc";
|
||||
require_once($bs);
|
||||
}
|
||||
while (1) {
|
||||
do_pass();
|
||||
}
|
||||
|
|
|
@ -187,6 +187,7 @@ struct VERSION_INFO {
|
|||
#define REG_BLANK_NAME "Blank"
|
||||
#define REG_BLANK_TIME "Blank Time"
|
||||
#define REG_STARTUP_NAME "BOINC"
|
||||
#define CLIENT_AUTH_FILENAME "client_auth.xml"
|
||||
#else
|
||||
#define LOCK_FILE_NAME "lockfile"
|
||||
#endif
|
||||
|
|
71
lib/util.C
71
lib/util.C
|
@ -279,13 +279,41 @@ void update_average(
|
|||
avg_time = now;
|
||||
}
|
||||
|
||||
#ifdef _WIN32
|
||||
void get_sandbox_account_token() {
|
||||
FILE* f;
|
||||
char buf[256], username[256], password[256];
|
||||
static bool first=true;
|
||||
|
||||
if (!first) return;
|
||||
first = true;
|
||||
f = fopen(CLIENT_AUTH_FILENAME, "r");
|
||||
if (!f) return;
|
||||
while (fgets(buf, 256, f)) {
|
||||
if (parse_str(buf, "<username>", username, sizeof(username))) continue;
|
||||
if (parse_str(buf, "<password>", password, sizeof(password))) continue;
|
||||
}
|
||||
fclose(f);
|
||||
std::string password_str = r_base64_decode(ca.boinc_project.password);
|
||||
retval = LogonUser(
|
||||
username,
|
||||
NULL,
|
||||
password_str.c_str(),
|
||||
LOGON32_LOGON_SERVICE,
|
||||
LOGON32_PROVIDER_DEFAULT,
|
||||
&sandbox_account_token
|
||||
);
|
||||
if (!retval) sandbox_account_token = NULL;
|
||||
}
|
||||
#endif
|
||||
|
||||
// chdir into the given directory, and run a program there.
|
||||
// If nsecs is nonzero, make sure it's still running after that many seconds.
|
||||
//
|
||||
// argv is set up Unix-style, i.e. argv[0] is the program name
|
||||
//
|
||||
#ifdef _WIN32
|
||||
|
||||
#ifdef _WIN32
|
||||
int run_program(
|
||||
const char* dir, const char* file, int argc, char *const argv[], double nsecs, HANDLE& id
|
||||
) {
|
||||
|
@ -307,18 +335,35 @@ int run_program(
|
|||
}
|
||||
}
|
||||
|
||||
retval = CreateProcess(
|
||||
file,
|
||||
cmdline,
|
||||
NULL,
|
||||
NULL,
|
||||
FALSE,
|
||||
0,
|
||||
NULL,
|
||||
dir,
|
||||
&startup_info,
|
||||
&process_info
|
||||
);
|
||||
get_sandbox_account_token();
|
||||
if (sandbox_account_token != NULL) {
|
||||
retval = CreateProcessAsUser(
|
||||
sandbox_account_token,
|
||||
file,
|
||||
cmdline,
|
||||
NULL,
|
||||
NULL,
|
||||
FALSE,
|
||||
0,
|
||||
NULL,
|
||||
dir,
|
||||
&startup_info,
|
||||
&process_info
|
||||
);
|
||||
} else {
|
||||
retval = CreateProcess(
|
||||
file,
|
||||
cmdline,
|
||||
NULL,
|
||||
NULL,
|
||||
FALSE,
|
||||
0,
|
||||
NULL,
|
||||
dir,
|
||||
&startup_info,
|
||||
&process_info
|
||||
);
|
||||
}
|
||||
|
||||
if (!retval) {
|
||||
return -1; // CreateProcess returns 1 if successful, false if it failed.
|
||||
|
|
|
@ -72,6 +72,7 @@ extern int boinc_calling_thread_cpu_time(double&);
|
|||
extern void mysql_timestamp(double, char*);
|
||||
|
||||
#ifdef _WIN32
|
||||
extern HANDLE sandbox_account_token = NULL;
|
||||
extern int run_program(
|
||||
const char* path, const char* cdir, int argc, char *const argv[], double, HANDLE&
|
||||
);
|
||||
|
|
Loading…
Reference in New Issue