mirror of https://github.com/BOINC/boinc.git
*** empty log message ***
svn path=/trunk/boinc/; revision=5794
This commit is contained in:
parent
0fe68b46a2
commit
5fa6e0ec46
|
@ -26784,3 +26784,31 @@ David 6 April 2005
|
|||
|
||||
clientgui/
|
||||
*.cpp
|
||||
|
||||
David 6 April 2005
|
||||
- Attempt to fix the situation where:
|
||||
1) user merges hosts; hosts with lower IDs are folded
|
||||
into host with maximal ID, then deleted
|
||||
2) If host's client_state.xml file still has one of the
|
||||
lower IDs, then the next time it contacts the scheduler,
|
||||
the host lookup fails and a new host record is created,
|
||||
which defeats the purpose of the merge.
|
||||
|
||||
Solution:
|
||||
- When merge hosts, don't delete lower-ID records.
|
||||
Instead, change them to "zombie" state, in which:
|
||||
- userid is zero
|
||||
- rpc_seqno is ID of new host record
|
||||
- scheduler: if host is zombie, follow link to new host,
|
||||
send back its ID to client
|
||||
|
||||
db/
|
||||
boinc_db.h
|
||||
html/
|
||||
inc/
|
||||
util.inc
|
||||
user/
|
||||
host_edit_action.php
|
||||
host_edit_form.php
|
||||
sched/
|
||||
handle_request.C
|
||||
|
|
|
@ -1749,8 +1749,9 @@ wxInt32 CMainDocument::GetResourceProjectName(wxInt32 iIndex, wxString& strBuffe
|
|||
PROJECT* pStateProject = NULL;
|
||||
|
||||
try {
|
||||
if (!resource_status.projects.empty())
|
||||
if (!resource_status.projects.empty()) {
|
||||
pProject = resource_status.projects.at(iIndex);
|
||||
}
|
||||
}
|
||||
catch (std::out_of_range e) {
|
||||
pProject = NULL;
|
||||
|
@ -1760,17 +1761,17 @@ wxInt32 CMainDocument::GetResourceProjectName(wxInt32 iIndex, wxString& strBuffe
|
|||
pStateProject = state.lookup_project(pProject->master_url);
|
||||
if (NULL != pStateProject) {
|
||||
strBuffer = pStateProject->project_name.c_str();
|
||||
}
|
||||
else
|
||||
} else {
|
||||
ForceCacheUpdate();
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
wxInt32 CMainDocument::GetResourceDiskspace(wxInt32 iIndex, float& fBuffer)
|
||||
{ PROJECT* pProject = NULL;
|
||||
wxInt32 CMainDocument::GetResourceDiskspace(wxInt32 iIndex, float& fBuffer) {
|
||||
PROJECT* pProject = NULL;
|
||||
|
||||
try {
|
||||
if (!resource_status.projects.empty())
|
||||
|
|
|
@ -204,6 +204,9 @@ struct HOST {
|
|||
int id;
|
||||
int create_time;
|
||||
int userid; // ID of user running this host
|
||||
// If the host is "zombied" during merging of duplicate hosts,
|
||||
// this field is set to zero and rpc_seqno is used to
|
||||
// store the ID of the new host (kludge, but what the heck)
|
||||
int rpc_seqno; // last seqno received from client
|
||||
int rpc_time; // time of last scheduler RPC
|
||||
double total_credit;
|
||||
|
|
|
@ -220,13 +220,30 @@ function row3($x, $y, $z) {
|
|||
|
||||
function row4($xx, $xy, $yx, $yy) {
|
||||
echo "<tr><td width=25% valign=top>$xx</td><td width=25%>$xy</td>"
|
||||
. "<td width=25% >$yx</td><td width=%25>$yy</td></tr>\n";
|
||||
. "<td width=25% >$yx</td><td width=%25>$yy</td></tr>
|
||||
";
|
||||
}
|
||||
|
||||
function rowify($string) {
|
||||
echo "<tr><td>$string</td></tr>";
|
||||
}
|
||||
|
||||
function row($x) {
|
||||
echo "<tr>";
|
||||
foreach ($x as $h) {
|
||||
echo "<td>$h</th>";
|
||||
}
|
||||
echo "</tr>\n";
|
||||
}
|
||||
|
||||
function row_heading($x) {
|
||||
echo "<tr>";
|
||||
foreach ($x as $h) {
|
||||
echo "<th class=heading>$h</th>";
|
||||
}
|
||||
echo "</tr>\n";
|
||||
}
|
||||
|
||||
function random_string() {
|
||||
return md5(uniqid(rand(), true));
|
||||
}
|
||||
|
|
|
@ -18,34 +18,35 @@ function get_host($hostid, $user) {
|
|||
}
|
||||
|
||||
function merge_hosts($old_host, $new_host) {
|
||||
if ($old_host->id == $new_host->id) {
|
||||
fail("same host");
|
||||
}
|
||||
if (!hosts_compatible($old_host, $new_host)) {
|
||||
fail("Can't merge hosts - they're incompatible");
|
||||
}
|
||||
if ($old_host->id == $new_host->id) {
|
||||
fail("same host");
|
||||
}
|
||||
if (!hosts_compatible($old_host, $new_host)) {
|
||||
fail("Can't merge hosts - they're incompatible");
|
||||
}
|
||||
|
||||
echo "<br>Merging $old_host->id into $new_host->id\n";
|
||||
echo "<br>Merging host $old_host->id into host $new_host->id\n";
|
||||
|
||||
// update the database:
|
||||
// - add credit from old to new host
|
||||
// - change results to refer to new host
|
||||
// - delete old host
|
||||
//
|
||||
$total_credit = $old_host->total_credit + $new_host->total_credit;
|
||||
$recent_credit = $old_host->expavg_credit + $new_host->expavg_credit;
|
||||
$result = mysql_query("update host set total_credit=$total_credit, expavg_credit=$recent_credit where id=$new_host->id");
|
||||
if (!$result) {
|
||||
fail("Couldn't update credit of new host");
|
||||
}
|
||||
$result = mysql_query("update result set hostid=$new_host->id where hostid=$old_host->id");
|
||||
if (!$result) {
|
||||
fail("Couldn't update results");
|
||||
}
|
||||
$result = mysql_query("delete from host where id=$old_host->id");
|
||||
if (!$result) {
|
||||
fail("Couldn't delete record of computer");
|
||||
}
|
||||
// update the database:
|
||||
// - add credit from old to new host
|
||||
// - change results to refer to new host
|
||||
// - put old host in "zombie" state
|
||||
//
|
||||
$total_credit = $old_host->total_credit + $new_host->total_credit;
|
||||
$recent_credit = $old_host->expavg_credit + $new_host->expavg_credit;
|
||||
$result = mysql_query("update host set total_credit=$total_credit, expavg_credit=$recent_credit where id=$new_host->id");
|
||||
if (!$result) {
|
||||
fail("Couldn't update credit of new computer");
|
||||
}
|
||||
$result = mysql_query("update result set hostid=$new_host->id where hostid=$old_host->id");
|
||||
if (!$result) {
|
||||
fail("Couldn't update results");
|
||||
}
|
||||
$result = mysql_query("update host set total_credit=0, expavg_credit=0, userid=0, rpc_seqno=$new_host->id where id=$old_host->id");
|
||||
if (!$result) {
|
||||
fail("Couldn't update old computer");
|
||||
}
|
||||
echo "<br>Retired old computer $old_host->id\n";
|
||||
}
|
||||
|
||||
db_init();
|
||||
|
|
|
@ -22,12 +22,15 @@ echo "
|
|||
<form name=blah action=host_edit_action.php>
|
||||
<input type=hidden name=id_0 value=$hostid>
|
||||
<p>
|
||||
Check the computers that are the same as $host->domain_name (created $t):
|
||||
Check the computers that are the same as $host->domain_name
|
||||
(created $t, computer ID $host->id):
|
||||
<p>
|
||||
";
|
||||
|
||||
$result = mysql_query("select * from host where userid=$user->id");
|
||||
$nhosts = 1;
|
||||
start_table();
|
||||
row_heading(array("", "name", "created", "computer ID"));
|
||||
while ($host2 = mysql_fetch_object($result)) {
|
||||
if ($host->id == $host2->id) continue;
|
||||
//if ($host2->create_time > $host->create_time) continue;
|
||||
|
@ -37,10 +40,16 @@ while ($host2 = mysql_fetch_object($result)) {
|
|||
if ($x == "") {
|
||||
$x = "[no hostname]";
|
||||
}
|
||||
echo "<br><input type=checkbox name=id_$nhosts value=$host2->id> $x (created $t)\n";
|
||||
row(array(
|
||||
"<input type=checkbox name=id_$nhosts value=$host2->id>",
|
||||
$x,
|
||||
"$t",
|
||||
"$host2->id"
|
||||
));
|
||||
$nhosts++;
|
||||
if ($nhosts==500) break;
|
||||
}
|
||||
end_table();
|
||||
mysql_free_result($result);
|
||||
echo "
|
||||
<br>
|
||||
|
|
|
@ -87,6 +87,19 @@ int authenticate_user(SCHEDULER_REQUEST& sreq, SCHEDULER_REPLY& reply) {
|
|||
|
||||
if (sreq.hostid) {
|
||||
retval = host.lookup_id(sreq.hostid);
|
||||
if (!retval && host.userid==0) {
|
||||
// if host record is zombie, follow link to new host
|
||||
//
|
||||
retval = host.lookup_id(host.rpc_seqno);
|
||||
if (!retval) {
|
||||
reply.hostid = host.id;
|
||||
log_messages.printf(
|
||||
SCHED_MSG_LOG::NORMAL,
|
||||
"[HOST#%d] forwarding to new host ID %d\n",
|
||||
sreq.hostid, host.id
|
||||
);
|
||||
}
|
||||
}
|
||||
if (retval) {
|
||||
USER_MESSAGE um("Can't find host record", "low");
|
||||
reply.insert_message(um);
|
||||
|
@ -98,12 +111,13 @@ int authenticate_user(SCHEDULER_REQUEST& sreq, SCHEDULER_REPLY& reply) {
|
|||
sreq.hostid = 0;
|
||||
goto lookup_user_and_make_new_host;
|
||||
}
|
||||
|
||||
reply.host = host;
|
||||
log_messages.printf(
|
||||
SCHED_MSG_LOG::DEBUG,
|
||||
"Request [HOST#%d] Database [HOST#%d] Request [RPC#%d] Database [RPC#%d]\n",
|
||||
sreq.hostid, host.id, sreq.rpc_seqno, host.rpc_seqno
|
||||
);
|
||||
SCHED_MSG_LOG::DEBUG,
|
||||
"Request [HOST#%d] Database [HOST#%d] Request [RPC#%d] Database [RPC#%d]\n",
|
||||
sreq.hostid, host.id, sreq.rpc_seqno, host.rpc_seqno
|
||||
);
|
||||
|
||||
strlcpy(
|
||||
user.authenticator, sreq.authenticator,
|
||||
|
@ -443,10 +457,10 @@ int handle_results(
|
|||
// Comment -- In the sanity checks that follow, should we
|
||||
// verify that the results validate_state is consistent with
|
||||
// this being a newly arrived result?
|
||||
// What happens if a workunit was canceled after a result was sent?
|
||||
// When it gets back in, do we want to leave the validate state 'as is'?
|
||||
// Probably yes, which is as the code currently behaves.
|
||||
//
|
||||
// What happens if a workunit was canceled after a result was sent?
|
||||
// When it gets back in, do we want to leave the validate state 'as is'?
|
||||
// Probably yes, which is as the code currently behaves.
|
||||
//
|
||||
if (srip->server_state == RESULT_SERVER_STATE_UNSENT) {
|
||||
log_messages.printf(
|
||||
SCHED_MSG_LOG::CRITICAL,
|
||||
|
@ -1081,13 +1095,13 @@ int delete_file_from_host(SCHEDULER_REQUEST& sreq, SCHEDULER_REPLY& sreply) {
|
|||
}
|
||||
|
||||
// pick a data file to delete.
|
||||
// Do this deterministically so that we always tell host to delete the same file.
|
||||
// But to prevent all hosts from removing 'the same' file,
|
||||
// choose a file which depends upon the hostid.
|
||||
// Do this deterministically so that we always tell host to delete the same file.
|
||||
// But to prevent all hosts from removing 'the same' file,
|
||||
// choose a file which depends upon the hostid.
|
||||
//
|
||||
// Assumption is that if nothing has changed on the host,
|
||||
// the order in which it reports files is fixed.
|
||||
// If this is false, we need to sort files into order by name!
|
||||
// the order in which it reports files is fixed.
|
||||
// If this is false, we need to sort files into order by name!
|
||||
//
|
||||
int j = sreply.host.id % nfiles;
|
||||
FILE_INFO& fi = sreq.file_infos[j];
|
||||
|
@ -1098,7 +1112,7 @@ int delete_file_from_host(SCHEDULER_REQUEST& sreq, SCHEDULER_REPLY& sreply) {
|
|||
);
|
||||
|
||||
// give host 4 hours to nuke the file and come back.
|
||||
// This might in general be too soon, since host needs to complete any work
|
||||
// This might in general be too soon, since host needs to complete any work
|
||||
// that depends upon this file, before it will be removed by core client.
|
||||
//
|
||||
sprintf(buf, "Removing file %s to free up disk space", fi.name);
|
||||
|
@ -1203,10 +1217,10 @@ void handle_request(
|
|||
if (sreply.user.id==3) {
|
||||
USER_MESSAGE um("THIS IS A SHORT MESSAGE. \n AND ANOTHER", "high");
|
||||
// USER_MESSAGE um("THIS IS A VERY LONG TEST MESSAGE. THIS IS A VERY LONG TEST MESSAGE. \n"
|
||||
// "THIS IS A VERY LONG TEST MESSAGE. THIS IS A VERY LONG TEST MESSAGE.", "low");
|
||||
// "THIS IS A VERY LONG TEST MESSAGE. THIS IS A VERY LONG TEST MESSAGE.", "low");
|
||||
sreply.insert_message(um);
|
||||
// USER_MESSAGE um2("THIS IS A VERY LONG TEST MESSAGE2. THIS IS A VERY LONG TEST MESSAGE. \n"
|
||||
// "THIS IS A VERY LONG TEST MESSAGE. THIS IS A VERY LONG TEST MESSAGE.", "high");
|
||||
// "THIS IS A VERY LONG TEST MESSAGE. THIS IS A VERY LONG TEST MESSAGE.", "high");
|
||||
// sreply.insert_message(um2);
|
||||
}
|
||||
#endif
|
||||
|
@ -1239,7 +1253,7 @@ void handle_request(
|
|||
debug_sched(sreq, sreply, "../debug_sched");
|
||||
} else if (max_allowable_disk(sreq)<0 || (sreply.wreq.insufficient_disk || sreply.wreq.disk_available<0)) {
|
||||
debug_sched(sreq, sreply, "../debug_sched");
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
sreply.write(fout);
|
||||
|
|
Loading…
Reference in New Issue