- user web: added new feature to merge hosts by name.

This is handy if you have a lot of hosts,
    and every now and then they get a new host ID
    (e.g. because you delete and reinstall BOINC).
    You can now merge all of them with a single click.
    
html/
    inc/
        host.inc
    user/
        host_edit_action.php
        merge_by_name.php (new)
        hosts_user.php

svn path=/trunk/boinc/; revision=12785
This commit is contained in:
David Anderson 2007-05-30 20:30:28 +00:00
parent 88860ed316
commit f2fd5da3ff
5 changed files with 163 additions and 55 deletions

View File

@ -5587,3 +5587,18 @@ David 30 May 2007
sched/
sched_array.C
sched_send.C,h
David 30 May 2007
- user web: added new feature to merge hosts by name.
This is handy if you have a lot of hosts,
and every now and then they get a new host ID
(e.g. because you delete and reinstall BOINC).
You can now merge all of them with a single click.
html/
inc/
host.inc
user/
host_edit_action.php
merge_by_name.php (new)
hosts_user.php

View File

@ -257,14 +257,11 @@ function ghz($x) {
}
}
// return true if it's possible that the two host records
// correspond to the same host
//
function hosts_compatible($host1, $host2) {
function cpus_compatible($host1, $host2) {
// we screwed around with Intel processor names,
// so count them as compatible if both contain "Intel" and "Pentium",
// and don't have conflicting clock rate info
//
$p1 = "$host1->p_vendor $host1->p_model";
$p2 = "$host2->p_vendor $host2->p_model";
if (strstr($p1, "Pentium") && strstr($p1, "Intel")
@ -279,26 +276,46 @@ function hosts_compatible($host1, $host2) {
}
} else {
if ($host2->p_vendor != $host1->p_vendor) return false;
// they're compatible if models are the same,
// or contents of [family/model/stepping] are the same
//
$pos = strpos($host1->p_model, '[');
$host1pm = $host1->p_model;
if($pos !== FALSE) {
if($pos) {
$host1pm = trim(substr($host1->p_model, 0, $pos));
}
$pos = strpos($host2->p_model, '[');
$host2pm = $host2->p_model;
if($pos !== FALSE) {
if($pos) {
$host2pm = trim(substr($host2->p_model, 0, $pos));
}
if($host2pm != $host1pm) return false;
if ($host1pm != $host2pm) return false;
}
if ($host2->os_name != $host1->os_name) return false;
return true;
}
// one host must strictly precede the other
// does one host strictly precede the other?
//
function times_disjoint($host1, $host2) {
if ($host1->rpc_time < $host2->create_time) return true;
if ($host2->rpc_time < $host1->create_time) return true;
return false;
}
// Return true if it's possible that the two host records
// correspond to the same host
// NOTE: the cheat-proofing comes from checking
// that their time intervals are disjoint.
// So the CPU/OS checks don't have to be very strict.
//
function hosts_compatible($host1, $host2) {
if (!times_disjoint($host1, $host2)) return false;
if ($host2->os_name != $host1->os_name) return false;
if (!cpus_compatible($host1, $host2)) return false;
return true;
}
// recompute host's average credit by scanning results.
// Could be expensive if lots of results!
//
@ -353,4 +370,47 @@ function host_inactive_ndays($host, $ndays) {
return false;
}
// invariant: old_host.create_time < new_host.create_time
//
function merge_hosts($old_host, $new_host) {
if ($old_host->id == $new_host->id) {
return "same host";
}
if (!hosts_compatible($old_host, $new_host)) {
return "Can't merge host $old_host->id into $new_host->id - they're incompatible";
}
echo "<br>Merging host $old_host->id into host $new_host->id\n";
// decay the average credit of both hosts
//
$now = time();
update_average($now, 0, 0, $old_host->expavg_credit, $old_host->expavg_time);
update_average($now, 0, 0, $new_host->expavg_credit, $new_host->expavg_time);
// update the database:
// - add credit from old to new host
// - change results to refer to new host
// - put old host in "zombie" state
// - update rpc_seqno if needed
//
$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, expavg_time=$now where id=$new_host->id");
if (!$result) {
return "Couldn't update credit of new computer";
}
$result = mysql_query("update result set hostid=$new_host->id where hostid=$old_host->id");
if (!$result) {
return "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) {
return "Couldn't retire old computer";
}
echo "<br>Retired old computer $old_host->id\n";
return 0;
}
?>

View File

@ -17,48 +17,6 @@ function get_host($hostid, $user) {
return $host;
}
// invariant: old_host.create_time < new_host.create_time
//
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("<br>Can't merge host $old_host->id into $new_host->id - they're incompatible");
}
echo "<br>Merging host $old_host->id into host $new_host->id\n";
// decay the average credit of both hosts
//
$now = time();
update_average($now, 0, 0, $old_host->expavg_credit, $old_host->expavg_time);
update_average($now, 0, 0, $new_host->expavg_credit, $new_host->expavg_time);
// update the database:
// - add credit from old to new host
// - change results to refer to new host
// - put old host in "zombie" state: userid 0, rpc_seqno = new host ID
// (this lets scheduler handle requests from old host ID)
//
$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, expavg_time=$now 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 retire old computer");
}
echo "<br>Retired old computer $old_host->id\n";
}
db_init();
$user = get_logged_in_user();
@ -73,7 +31,10 @@ for ($i=1; $i<$nhosts; $i++) {
if (!$hostid) continue;
$host = get_host($hostid, $user);
if ($host->create_time > $latest_host->create_time) {
merge_hosts($latest_host, $host);
$error = merge_hosts($latest_host, $host);
if ($error) {
fail($error);
}
$latest_host = $host;
} else {
merge_hosts($host, $latest_host);

View File

@ -9,9 +9,9 @@ require_once("../inc/cache.inc");
function more_or_less($show_all) {
if ($show_all) {
echo "<p>Show: All hosts | ".link_with_GET_variables("Only hosts active in past 30 days<br>", "hosts_user.php", 'show_all', '0');
echo "<p>Show: All hosts | ".link_with_GET_variables("Only hosts active in past 30 days<p>", "hosts_user.php", 'show_all', '0');
} else {
echo "<p>Show: ".link_with_GET_variables("All hosts", "hosts_user.php", 'show_all', '1')." | Only hosts active in past 30 days<br>";;
echo "<p>Show: ".link_with_GET_variables("All hosts", "hosts_user.php", 'show_all', '1')." | Only hosts active in past 30 days<p>";;
}
}
@ -130,6 +130,10 @@ echo "</table>\n";
if ($old_hosts>0) more_or_less($show_all);
echo "
<a href=merge_by_name.php>Merge hosts by name</a>
";
if ($caching) {
page_tail(true);
end_cache(USER_PAGE_TTL, $cache_args);

View File

@ -0,0 +1,68 @@
<?php
require_once("../inc/db.inc");
require_once("../inc/host.inc");
db_init();
function merge_name($list) {
// find the newest one
//
$newest_host = $list[0];
echo "<br><br>Processing $newest_host->domain_name\n";
foreach ($list as $host) {
if ($host->create_time > $newest_host->create_time) {
$newest_host = $host;
}
}
foreach ($list as $host) {
if ($host->id == $newest_host->id) {
continue;
}
$error = merge_hosts($host, $newest_host);
if (!$error) {
echo "<b>merged $host->id into $newest_host->id\n";
} else {
echo "<br>$error\n";
}
}
}
function merge_by_name($userid) {
$hosts = array();
$result = mysql_query("select * from host where userid=$userid");
while ($host = mysql_fetch_object($result)) {
$hosts[$host->domain_name][] = $host;
}
foreach($hosts as $hlist) {
merge_name($hlist);
}
}
$user = get_logged_in_user();
page_head("Merge computers by name");
if ($_GET['confirmed']) {
merge_by_name($user->id);
echo "
<p><a href=hosts_user.php>
Return to the list of your computers</a>.
";
} else {
echo "
This operation will merge all of your computers
that have the same domain name.
<p>
For each name, it will merge all older computers
having that name with the newest computer having that name.
Incompatible computers will not be merged.
<p>
Click <a href=merge_by_name.php?confirmed=1>here</a>
if you're sure you want to do this.
<p>Click <a href=hosts_user.php>here</a>
to return to the list of your computers.
";
}
page_tail();
?>