don't leak fds to apps

svn path=/trunk/boinc/; revision=9084
This commit is contained in:
David Anderson 2005-12-18 02:00:15 +00:00
parent 4ffb77322c
commit 1959fbe160
14 changed files with 433 additions and 140 deletions

View File

@ -14561,3 +14561,23 @@ Bruce 15 Dec 2005
makelog.sh
cleanlogs.sh
David 17 Dec 2005
- core client: set close-on-exec flag of sockets and files so that they
don't get 'leaked' to applications
- moved server status page from ops/ to user/
- make_project: copy sample_project_status.php to project_status.php
html/
languages/translations/
en.po
ops/
server_status.php (moved to user/sample_server_status.php)
user/
eah_server_status.php (new; Einstein@home status page)
sample_server_status.php (new; see above)
sample_status.php (removed)
lib/
filesys.C
network.C
py/Boinc/
setup_project.py

View File

@ -184,9 +184,9 @@ list_item("action",
<dd>
A time interval after which another RPC should be done.
<dt> signing_key
<dd>
The public key used to sign URLs, in an encoded notation.
Use the BOINC <a href=key_setup.php>crypt_prog</a> program to generate this.
<dd>
</dl>
For each account, the following items are returned:
<dl>

View File

@ -75,7 +75,8 @@ This deals with platform-specific problems.
On Windows, where security and indexing programs can briefly lock files,
boinc_fopen() does several retries at 1-second intervals.
On Unix, where signals can cause fopen() to fail with EINTR,
boinc_fopen checks for this and does a few retries.
boinc_fopen checks for this and does a few retries;
it also sets the 'close-on-exec' flag.
<h3>Checkpointing</h3>

View File

@ -1,5 +1,7 @@
<?php
require_once("docutil.php");
page_head("Starting BOINC automatically");
echo "
@ -29,6 +31,9 @@ startup of BOINC on various versions of Unix:
<h2> Automatic startup on Mac OS X</h2>
<p>
Note: the Mac Standard GUI installation arranges
for BOINC to run on system startup.
The following is relevant if you install the command-line client.
<ul>
<li>
Instructions from Paul Buck's

View File

@ -1,6 +1,10 @@
<?
$project_news = array(
array("December 15, 2005",
"A <a href=http://www.nature.com/news/2005/051212/full/051212-10.html>story
about SETI@home's transition to BOINC</a> appears in the Nature web site."
),
array("December 12, 2005",
"A new paper, <a href=http://boinc.berkeley.edu/boinc_papers/internet/paper.pdf>The Computational and Storage Potential of Volunteer Computing</a>,
explores the limits of BOINC-based projects."

View File

@ -230,6 +230,8 @@ if ($xml) {
<li> <a href=download_other.php>download executables from a third-party site</a>
(available for Solaris/Opteron, Linux/Opteron, Linux/PPC, HP-UX, and FreeBSD, and others).
</ul>
Note: BOINC is not available for Mac OS 9 or earlier.
There are no plans to develop an OS 9 version.
";
}
echo "

View File

@ -3,14 +3,22 @@ require_once("docutil.php");
page_head("Preferences");
echo "
<p>
You can specify <b>preferences</b> that determine and limit
how BOINC uses your computers.
You can specify <b>preferences</b> that limit
when and how BOINC uses your computers.
Preferences are divided into two groups: General and Project.
<h2>Editing preferences</h2>
<p>
You can view and edit your preferences via the project's web site.
Click on 'Your account', then 'View or edit preferences'.
Click on 'Your account', then 'View or edit general preferences'.
<blockquote>
<b>
Note: these links may be different on some projects.
For example, on Climateprediction.net you must click
'My CPDN', then 'BOINC CPDN', then 'Your account',
and 'View or edit general preferences'.
</b>
</blockquote>
This shows you the preferences.
If you want to change anything,
click on 'Edit preferences'.

View File

@ -196,7 +196,7 @@ msgid "CREATE_AC_PASSWORD"
msgstr "Password"
msgid "CREATE_AC_PASSWORD_DESC"
msgstr "Must be at least %s characters";
msgstr "Must be at least %s characters"
msgid "CREATE_AC_CONFIRM_PASSWORD"
msgstr "Confirm password"

View File

@ -0,0 +1,307 @@
<?php
require_once("../inc/cache.inc");
require_once("../inc/util.inc");
require_once("../inc/db.inc");
require_once("../project/project.inc");
################################################
# local functions
function numerical_query($query) {
// execute a database query which returns a single numerical result
$result = mysql_query("$query");
$x = mysql_fetch_object($result);
return $x->total;
}
function count_estimate($query) {
// this use of explain is way off at least for low counts -EAM 28Sep2004
//$result = mysql_query("explain $query");
$result = mysql_query("$query");
$x = mysql_fetch_object($result);
// return $x->rows-1;
return $x->total;
}
function find_oldest() {
$result=mysql_query("select name,create_time from result where server_state=2 order by create_time limit 1");
$x = mysql_fetch_object($result);
return $x->create_time;
}
function daemon_status($host, $pidname) {
$path = "../../pid_$host/$pidname.pid";
$running = false;
if (is_file($path)) {
$pid = file_get_contents($path);
if ($pid) {
// This needs to be set to work via ssh to other hosts
//$foo = exec("/usr/bin/ssh $host ps w $pid");
$foo = exec("ps w $pid");
if ($foo) {
if (strstr($foo, $pidname)) {
$running = true;
}
}
}
}
return $running;
}
function show_status($host, $function, $running) {
echo "<tr><td>$function</td><td>$host</td>";
if ($running) {
echo "<td bgcolor=00ff00>Running</td>\n";
} else {
echo "<td bgcolor=ff0000>Not running</td>\n";
}
}
function show_daemon_status($host, $progname, $pidname) {
$running = daemon_status($host, $pidname);
show_status($host, $progname, $running);
}
###############################################
# BEGIN:
start_cache(1800);
$Nmin = $cached_max_age/60;
$dbrc = db_init(1); // 1=soft, remember that DB might be down
page_head(PROJECT . " - Server Status");
// Date stamp
echo "<br ALIGN=RIGHT> ".PROJECT. " server status as of ".
date("g:i A T"). " on ". date("l, j F Y ") .
" (updated every $Nmin minutes).\n";
$proc_uptime=exec("cat /proc/uptime | cut -d\" \" -f-1");
$days = (int)($proc_uptime/86400);
$hours=(int)($proc_uptime/3600);
$hours=$hours % 24;
$minutes=(int)($proc_uptime/60);
$minutes=$minutes % 60;
echo "<br ALIGN=RIGHT>The ".PROJECT. " main server has been continuously up for ". "$days"." days "."$hours"." hours "."$minutes"." minutes.\n<P>";
// tables side by side
echo "<TABLE><TR><TD align=center> \n";
echo "
<h2>Server status</h2>
<table border=2 cellpadding=6>
<tr><th>Program</th><th>Host</th><th>Status</th></tr>
";
$web_running = !file_exists("../../stop_web");
show_status("einstein", "Web server", $web_running);
show_daemon_status("einstein", "Pulsar work generator (LHO)", "make_pulsar_WU_daemon_h");
show_daemon_status("einstein", "Pulsar work generator (LLO)", "make_pulsar_WU_daemon_l");
show_daemon_status("einstein", "BOINC database feeder", "feeder");
show_daemon_status("einstein", "BOINC transitioner", "transitioner");
$sched_running = !file_exists("../../stop_sched");
show_status("einstein", "BOINC scheduler", $sched_running);
show_daemon_status("einstein", "Einstein validator", "einstein_validator");
show_daemon_status("einstein", "Einstein assimilator", "einstein_assimilator");
show_daemon_status("einstein", "BOINC file deleter", "file_deleter");
show_daemon_status("einstein", "BOINC database purger", "db_purge");
echo "\n </table>
</TD><TD>&nbsp;</TD><TD VALIGN=TOP align=center>
\n";
echo "
<h2>Users and Computers</h2>
";
if ($dbrc) {
echo "The database server is not accessable";
} else {
$now=time(0);
$s_day=24*3600;
$d_ago=$now-$s_day;
$s_week=7*$s_day;
$w_ago=$now-$s_week;
echo "
<table border=2 cellpadding=6>
<tr><th>USERS</th><th>Approximate #</th></tr>
";
$n = count_estimate("select count(*) as total from user");
echo "
<tr><td>in database</td><td>".number_format($n)."</td></tr>
";
$n = count_estimate("select count(*) as total from user where total_credit>0");
echo "
<tr><td>with credit</td><td>".number_format($n)."</td></tr>
";
$n = count_estimate("select count(*) as total from user where create_time > $d_ago");
echo "
<tr><td>registered in past 24 hours</td><td>".number_format($n)."</td></tr>
";
echo "
<tr><th align=center>HOST COMPUTERS</th><th>Approximate #</th></tr>
";
$n = count_estimate("select count(*) as total from host");
echo "
<tr><td>in database</td><td>".number_format($n)."</td></tr>
";
$n = count_estimate("select count(*) as total from host where create_time > $d_ago");
echo "
<tr><td>registered in past 24 hours</td><td>".number_format($n)."</td></tr>
";
$n = count_estimate("select count(*) as total from host where total_credit>0");
echo "
<tr><td>with credit</td><td>".number_format($n)."</td></tr>
";
$n = count_estimate("select count(id) as total from host where rpc_time>$w_ago");
echo "
<tr><td>active in past 7 days</td><td>".number_format($n)."</td></tr>
";
$n = count_estimate("select sum(p_fpops) as total from host")/1000000000;
// echo "
// <tr><td>floating point speed</td><td>".number_format($n)." GFLOPS</td></tr>
//";
printf("<tr><td>floating point speed<sup>1)</sup></td><td>%.1f TFLOPS</td></tr>", $n/1000);
$n = count_estimate("select sum(p_fpops) as total from host where rpc_time>$w_ago")/1000000000;
// echo "
// <tr><td>GFLOPS in past 7 days</td><td>".number_format($n)." GFLOPS</td></tr>
//";
printf("<tr><td>floating point speed in past 7 days<sup>2)</sup></td><td>%.1f TFLOPS</td></tr>", $n/1000);
$n = numerical_query("SELECT SUM(cpu_time * p_fpops) / $s_week AS total FROM result,host where outcome = '1' AND (received_time > $w_ago) AND (result.hostid = host.id )")/1000000000;
printf("<tr><td>floating point speed from results<sup>3)</sup></td><td>%.1f TFLOPS</td></tr>", $n/1000);
echo "\n </table>
</TD><TD>&nbsp;</TD><TD VALIGN=TOP align=center>
<h2>Work and Results</h2>
\n";
echo "
<table border=2 cellpadding=6>
";
echo "
<tr><th>WORKUNITS</th><th>Approximate #</th></tr>
";
$n = count_estimate("select count(*) as total from workunit");
echo "
<tr><td>in database</td><td>".number_format($n)."</td></tr>
";
$n = count_estimate("select count(*) as total from workunit where canonical_resultid!=0");
echo "
<tr><td>with canonical result</td><td>".number_format($n)."</td></tr>
";
echo "
<tr><th>RESULTS</th><th>Approximate #</th></tr>
";
$n = count_estimate("select count(*) as total from result");
echo "
<tr><td>in database</td><td>".number_format($n)."</td></tr>
";
$n = count_estimate("select count(id) as total from result where server_state=2");
echo "
<tr><td>unsent</td><td>".number_format($n)."</td></tr>
";
$n = count_estimate("select count(id) as total from result where server_state=4");
echo "
<tr><td>in progress</td><td>".number_format($n)."</td></tr>
";
$n = count_estimate("select count(id) as total from result where server_state=5 and file_delete_state=2");
echo "
<tr><td>deleted</td><td>".number_format($n)."</td></tr>
";
$n = count_estimate("select count(id) as total from result where server_state=5 and outcome=1 and validate_state=1");
echo "
<tr><td>valid</td><td>".number_format($n)."</td></tr>
";
$n = numerical_query("SELECT COUNT(id) AS total FROM result WHERE server_state=5 AND outcome=1 AND validate_state=1 AND ( received_time > $w_ago )");
echo "
<tr><td>valid last week</td><td>".number_format($n)."</td></tr>
";
$n = count_estimate("select count(id) as total from result where server_state=5 and outcome=1 and validate_state=2");
echo "
<tr><td>invalid</td><td>".number_format($n)."</td></tr>
";
$n = time(0)-find_oldest();
$days = (int)($n/86400);
$hours=(int)($n/3600);
$hours=$hours % 24;
$minutes=(int)($n/60);
$minutes=$minutes % 60;
echo "
<tr><td>Oldest Unsent Result</td><td>".$days." d ".$hours." h ".$minutes." m</td></tr>
";
echo "
</table>
";
}
// Server restrictions
// Display cgi-bin restriction status
if ( file_exists("../../cgi-bin/.htaccess") ) {
echo "<P><font color=RED>
<b>The ".PROJECT." scheduler is currently restricted
to uwm.edu and a few other domains.
</b></font><P>
";
}
echo "</TD></TR>
</TABLE>
";
echo "<br> 1) the sum of the benchmarked FLops/s of all hosts in the database";
echo "<br> 2) the sum of the benchmarked FLops/s of all hosts that have contacted the Einstein@Home scheduler within the past week";
echo "<br> 3) the sum of the FLops of all valid results from last week divided by the number of seconds in a week";
page_tail();
end_cache(600);
?>

View File

@ -139,19 +139,33 @@ $config_xml = get_config();
$config_vars = parse_element($config_xml,"<config>");
$project_host = parse_element($config_vars,"<host>");
$www_host = parse_element($config_vars,"<www_host>");
if ($www_host == "") { $www_host = $project_host; }
if ($www_host == "") {
$www_host = $project_host;
}
$sched_pid = parse_element($config_vars,"<sched_pid>");
if ($sched_pid == "") { $sched_pid = "/etc/httpd/run/httpd.pid"; }
if ($sched_pid == "") {
$sched_pid = "/etc/httpd/run/httpd.pid";
}
$sched_host = parse_element($config_vars,"<sched_host>");
if ($sched_host == "") { $sched_host = $project_host; }
if ($sched_host == "") {
$sched_host = $project_host;
}
$uldl_pid = parse_element($config_vars,"<uldl_pid>");
if ($uldl_pid == "") { $uldl_pid = "/etc/httpd/run/httpd.pid"; }
if ($uldl_pid == "") {
$uldl_pid = "/etc/httpd/run/httpd.pid";
}
$uldl_host = parse_element($config_vars,"<uldl_host>");
if ($uldl_host == "") { $uldl_host = $project_host; }
if ($uldl_host == "") {
$uldl_host = $project_host;
}
$ssh_exe = parse_element($config_vars,"<ssh_exe>");
if ($ssh_exe == "") { $ssh_exe = "/usr/bin/ssh"; }
if ($ssh_exe == "") {
$ssh_exe = "/usr/bin/ssh";
}
$ps_exe = parse_element($config_vars,"<ps_exe>");
if ($ps_exe == "") { $ps_exe = "/bin/ps"; }
if ($ps_exe == "") {
$ps_exe = "/bin/ps";
}
$xmlstring = "<server_status>\n <update_time>" . time() . "</update_time>\n <daemon_status>\n";
@ -213,9 +227,12 @@ while ($thisxml = trim(parse_next_element($config_xml,"<daemon>",&$cursor))) {
}
$xmlstring = " </daemon_status>\n <database_file_states>\n";
if ($xml) { echo $xmlstring; }
else {
if ($xmlout) { fwrite($xmloutfile,$xmlstring); }
if ($xml) {
echo $xmlstring;
} else {
if ($xmlout) {
fwrite($xmloutfile,$xmlstring);
}
echo "
<tr><td align=right><b>Running:</b></td>
<td colspan=2>Program is operating normally</td></tr>
@ -250,28 +267,61 @@ if ($retval) {
// $n = `/bin/tail -1 $sendfile`;
// show_counts("Results ready to send","results_ready_to_send",$n);
show_counts("Results ready to send","results_ready_to_send",get_mysql_count("result where server_state = 2"));
show_counts("Results in progress","results_in_progress",get_mysql_count("result where server_state = 4"));
show_counts("Workunits waiting for validation","workunits_waiting_for_validation",get_mysql_count("workunit where need_validate=1"));
show_counts("Workunits waiting for assimilation","workunits_waiting_for_assimilation",get_mysql_count("workunit where assimilate_state=1"));
show_counts("Workunits waiting for deletion","workunits_waiting_for_deletion",get_mysql_count("workunit where file_delete_state=1"));
show_counts("Results waiting for deletion","results_waiting_for_deletion",get_mysql_count("result where file_delete_state=1"));
show_counts(
"Results ready to send",
"results_ready_to_send",
get_mysql_count("result where server_state = 2")
);
show_counts(
"Results in progress",
"results_in_progress",
get_mysql_count("result where server_state = 4")
);
show_counts(
"Workunits waiting for validation",
"workunits_waiting_for_validation",
get_mysql_count("workunit where need_validate=1")
);
show_counts(
"Workunits waiting for assimilation",
"workunits_waiting_for_assimilation",
get_mysql_count("workunit where assimilate_state=1")
);
show_counts(
"Workunits waiting for deletion",
"workunits_waiting_for_deletion",
get_mysql_count("workunit where file_delete_state=1")
);
show_counts(
"Results waiting for deletion",
"results_waiting_for_deletion",
get_mysql_count("result where file_delete_state=1")
);
$result = mysql_query("select MIN(transition_time) as min from workunit");
$min = mysql_fetch_object($result);
mysql_free_result($result);
$gap = (time() - $min->min)/3600;
if ($gap < 0) { $gap = 0; }
show_counts("Transitioner backlog (hours)","transitioner_backlog_hours",$gap);
if ($gap < 0) {
$gap = 0;
}
show_counts(
"Transitioner backlog (hours)",
"transitioner_backlog_hours",
$gap
);
if (!$xml) {
echo "</table>";
}
}
$xmlstring = " </database_file_states>\n</server_status>\n";
if ($xml) { echo $xmlstring; }
else {
if ($xmlout) { fwrite($xmloutfile,$xmlstring); }
if ($xml) {
echo $xmlstring;
} else {
if ($xmlout) {
fwrite($xmloutfile,$xmlstring);
}
echo "
</td>
<td>&nbsp;</td>

View File

@ -1,104 +0,0 @@
<?php
require_once("../inc/cache.inc");
require_once("../inc/util.inc");
start_cache(600);
require_once("../inc/db.inc");
function count_estimate($query) {
$result = mysql_query("explain $query");
$x = mysql_fetch_object($result);
return $x->rows;
}
function daemon_status($host, $pidname, $progname) {
$path = "../../pid_$host/$pidname.pid";
$running = false;
if (is_file($path)) {
$pid = file_get_contents($path);
if ($pid) {
$foo = exec("/opt/misc/bin/ssh $host ps w $pid");
if ($foo) {
if (strstr($foo, $progname)) {
$running = true;
}
}
}
}
return $running;
if ($running) {
echo "<br>$pidname is running on $host\n";
} else {
echo "<br>$pidname is not running on $host\n";
}
}
function show_status($host, $function, $running) {
echo "<tr><td>$function</td><td>$host</td>";
if ($running) {
echo "<td bgcolor=00ff00>Running</td>\n";
} else {
echo "<td bgcolor=ff0000>Not running</td>\n";
}
}
function show_daemon_status($host, $pidname, $progname) {
$running = daemon_status($host, $pidname, $progname);
show_status($host, $pidname, $running);
}
page_head("SETI@home status page");
echo "
<h2>Server status</h2>
<table border=2 cellpadding=6>
<tr><th>Program</th><th>Host</th><th>Status</th></tr>
";
$web_running = !file_exists("../../stop_web");
show_status("klaatu", "Data-driven web pages", $web_running);
$sched_running = !file_exists("../../stop_sched");
show_status("klaatu", "Scheduler", $sched_running);
show_daemon_status("kryten", "feeder", "feeder");
show_daemon_status("koloth", "file_deleter", "file_deleter");
show_daemon_status("klaatu", "transitioner1", "transitioner");
show_daemon_status("klaatu", "transitioner2", "transitioner");
show_daemon_status("kryten", "transitioner3", "transitioner");
show_daemon_status("kryten", "transitioner4", "transitioner");
show_daemon_status("klaatu", "sah_validate", "sah_validate");
show_daemon_status("galileo", "sah_assimilator", "sah_assimilator");
show_daemon_status("galileo", "sah_splitter", "sah_splitter");
show_daemon_status("milkyway", "sah_splitter2", "sah_splitter");
show_daemon_status("philmor", "sah_splitter3", "sah_splitter");
echo "
</table>
<h2>Database status</h2>
";
$retval = db_init_aux();
if ($retval) {
echo "The database server is not accessable";
} else {
echo "
<table border=2 cellpadding=6>
<tr><th>State</th><th>Approximate #results</th></tr>
";
$n = count_estimate("select count(*) from result where server_state=2");
echo "
<tr><td>Ready to send</td><td>".number_format($n)."</td></tr>
";
$n = count_estimate("select count(*) from result where server_state=4");
echo "
<tr><td>In progress</td><td>".number_format($n)."</td></tr>
</table>
";
}
page_tail(true);
end_cache(600);
?>

View File

@ -31,16 +31,10 @@
#include <ctime>
#include <cstring>
#include <cstdlib>
#ifdef HAVE_SYS_TIME_H
#include <sys/time.h>
#endif
#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif
#ifdef HAVE_DIRENT_H
#include <dirent.h>
#endif
#ifdef HAVE_SYS_RESOURCE_H
#include <sys/resource.h>
#endif
@ -372,6 +366,9 @@ FILE* boinc_fopen(const char* path, const char* mode) {
if (f) break;
}
}
if (f) {
fcntl(fileno(f), F_SETFD, FD_CLOEXEC);
}
#endif
return f;
}

View File

@ -114,6 +114,9 @@ int boinc_socket(int& fd) {
perror("socket");
return ERR_SOCKET;
}
#ifndef _WIN32
fcntl(fd, F_SETFD, FD_CLOEXEC);
#endif
return 0;
}

View File

@ -463,8 +463,8 @@ class Project:
self.dir('html/user/forum_index.php'))
install(srcdir('html/user', 'sample_rss_main.php'),
self.dir('html/user/rss_main.php'))
install(srcdir('html/user', 'sample_status.php'),
self.dir('html/user/status.php'))
install(srcdir('html/user', 'sample_server_status.php'),
self.dir('html/user/server_status.php'))
my_symlink(self.config.config.download_dir, self.dir('html', 'user', 'download'))