From 1959fbe160cdc31fed0e29ff2e28ad83bbe68173 Mon Sep 17 00:00:00 2001 From: David Anderson Date: Sun, 18 Dec 2005 02:00:15 +0000 Subject: [PATCH] don't leak fds to apps svn path=/trunk/boinc/; revision=9084 --- checkin_notes | 20 ++ doc/acct_mgt.php | 2 +- doc/api.php | 3 +- doc/auto_start.php | 5 + doc/boinc_news.inc | 4 + doc/download.php | 2 + doc/prefs.php | 14 +- html/languages/translations/en.po | 2 +- html/user/eah_server_status.php | 307 ++++++++++++++++++ .../sample_server_status.php} | 92 ++++-- html/user/sample_status.php | 104 ------ lib/filesys.C | 11 +- lib/network.C | 3 + py/Boinc/setup_project.py | 4 +- 14 files changed, 433 insertions(+), 140 deletions(-) create mode 100644 html/user/eah_server_status.php rename html/{ops/server_status.php => user/sample_server_status.php} (84%) delete mode 100644 html/user/sample_status.php diff --git a/checkin_notes b/checkin_notes index be584f628c..8badc43940 100755 --- a/checkin_notes +++ b/checkin_notes @@ -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 diff --git a/doc/acct_mgt.php b/doc/acct_mgt.php index 3283470c47..3cc878093e 100644 --- a/doc/acct_mgt.php +++ b/doc/acct_mgt.php @@ -184,9 +184,9 @@ list_item("action",
A time interval after which another RPC should be done.
signing_key +
The public key used to sign URLs, in an encoded notation. Use the BOINC crypt_prog program to generate this. -
For each account, the following items are returned:
diff --git a/doc/api.php b/doc/api.php index 8d26df6cc7..0655faacbb 100644 --- a/doc/api.php +++ b/doc/api.php @@ -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.

Checkpointing

diff --git a/doc/auto_start.php b/doc/auto_start.php index bc87e5de35..8530d1854a 100644 --- a/doc/auto_start.php +++ b/doc/auto_start.php @@ -1,5 +1,7 @@ Automatic startup on Mac OS X

+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.

  • Instructions from Paul Buck's diff --git a/doc/boinc_news.inc b/doc/boinc_news.inc index 9f2ea90674..c28ed05f74 100644 --- a/doc/boinc_news.inc +++ b/doc/boinc_news.inc @@ -1,6 +1,10 @@ story + about SETI@home's transition to BOINC appears in the Nature web site." +), array("December 12, 2005", "A new paper, The Computational and Storage Potential of Volunteer Computing, explores the limits of BOINC-based projects." diff --git a/doc/download.php b/doc/download.php index 29abc04f68..76b194e5d0 100755 --- a/doc/download.php +++ b/doc/download.php @@ -230,6 +230,8 @@ if ($xml) {
  • download executables from a third-party site (available for Solaris/Opteron, Linux/Opteron, Linux/PPC, HP-UX, and FreeBSD, and others).
+ Note: BOINC is not available for Mac OS 9 or earlier. + There are no plans to develop an OS 9 version. "; } echo " diff --git a/doc/prefs.php b/doc/prefs.php index e869acbf43..177e975242 100644 --- a/doc/prefs.php +++ b/doc/prefs.php @@ -3,14 +3,22 @@ require_once("docutil.php"); page_head("Preferences"); echo "

-You can specify preferences that determine and limit -how BOINC uses your computers. +You can specify preferences that limit +when and how BOINC uses your computers. Preferences are divided into two groups: General and Project.

Editing preferences

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'. +

+ +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'. + +
This shows you the preferences. If you want to change anything, click on 'Edit preferences'. diff --git a/html/languages/translations/en.po b/html/languages/translations/en.po index 85f18ccd95..f0ad493740 100644 --- a/html/languages/translations/en.po +++ b/html/languages/translations/en.po @@ -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" diff --git a/html/user/eah_server_status.php b/html/user/eah_server_status.php new file mode 100644 index 0000000000..b886f1806d --- /dev/null +++ b/html/user/eah_server_status.php @@ -0,0 +1,307 @@ +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 "$function$host"; + if ($running) { + echo "Running\n"; + } else { + echo "Not running\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 "
".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 "
The ".PROJECT. " main server has been continuously up for ". "$days"." days "."$hours"." hours "."$minutes"." minutes.\n

"; + +// tables side by side +echo " +
\n"; + + +echo " +

Server status

+ + +"; + + + +$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
ProgramHostStatus
+
  + \n"; + + +echo " + +

Users and Computers

+"; + + +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 " + + + "; + $n = count_estimate("select count(*) as total from user"); + echo " + + "; + + $n = count_estimate("select count(*) as total from user where total_credit>0"); + echo " + + "; + + $n = count_estimate("select count(*) as total from user where create_time > $d_ago"); + echo " + + "; + + echo " + + "; + + $n = count_estimate("select count(*) as total from host"); + echo " + + "; + $n = count_estimate("select count(*) as total from host where create_time > $d_ago"); + echo " + + "; + + $n = count_estimate("select count(*) as total from host where total_credit>0"); + echo " + + "; + $n = count_estimate("select count(id) as total from host where rpc_time>$w_ago"); + echo " + + "; + $n = count_estimate("select sum(p_fpops) as total from host")/1000000000; + // echo " + // + //"; + printf("", $n/1000); + + $n = count_estimate("select sum(p_fpops) as total from host where rpc_time>$w_ago")/1000000000; + // echo " + // + //"; + printf("", $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("", $n/1000); + + echo "\n
USERSApproximate #
in database".number_format($n)."
with credit".number_format($n)."
registered in past 24 hours".number_format($n)."
HOST COMPUTERSApproximate #
in database".number_format($n)."
registered in past 24 hours".number_format($n)."
with credit".number_format($n)."
active in past 7 days".number_format($n)."
floating point speed".number_format($n)." GFLOPS
floating point speed1)%.1f TFLOPS
GFLOPS in past 7 days".number_format($n)." GFLOPS
floating point speed in past 7 days2)%.1f TFLOPS
floating point speed from results3)%.1f TFLOPS
+
  +

Work and Results

+ \n"; + + + + echo " + + "; + + echo " + + "; + + $n = count_estimate("select count(*) as total from workunit"); + echo " + + "; + + $n = count_estimate("select count(*) as total from workunit where canonical_resultid!=0"); + echo " + + "; + + echo " + + "; + + $n = count_estimate("select count(*) as total from result"); + echo " + + "; + + $n = count_estimate("select count(id) as total from result where server_state=2"); + echo " + + "; + $n = count_estimate("select count(id) as total from result where server_state=4"); + echo " + + "; + + $n = count_estimate("select count(id) as total from result where server_state=5 and file_delete_state=2"); + echo " + + "; + + $n = count_estimate("select count(id) as total from result where server_state=5 and outcome=1 and validate_state=1"); + echo " + + "; + + $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 " + + "; + + $n = count_estimate("select count(id) as total from result where server_state=5 and outcome=1 and validate_state=2"); + echo " + + "; + + $n = time(0)-find_oldest(); + $days = (int)($n/86400); + $hours=(int)($n/3600); + $hours=$hours % 24; + $minutes=(int)($n/60); + $minutes=$minutes % 60; + echo " + + "; + + + + echo " +
WORKUNITSApproximate #
in database".number_format($n)."
with canonical result".number_format($n)."
RESULTSApproximate #
in database".number_format($n)."
unsent".number_format($n)."
in progress".number_format($n)."
deleted".number_format($n)."
valid".number_format($n)."
valid last week".number_format($n)."
invalid".number_format($n)."
Oldest Unsent Result".$days." d ".$hours." h ".$minutes." m
+ "; +} + +// Server restrictions + +// Display cgi-bin restriction status + +if ( file_exists("../../cgi-bin/.htaccess") ) { + echo "

+ The ".PROJECT." scheduler is currently restricted + to uwm.edu and a few other domains. + +

+ "; +} + + +echo "

+ "; + + echo "
1) the sum of the benchmarked FLops/s of all hosts in the database"; + echo "
2) the sum of the benchmarked FLops/s of all hosts that have contacted the Einstein@Home scheduler within the past week"; + echo "
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); +?> diff --git a/html/ops/server_status.php b/html/user/sample_server_status.php similarity index 84% rename from html/ops/server_status.php rename to html/user/sample_server_status.php index 2b581c55b5..c35b71ae75 100644 --- a/html/ops/server_status.php +++ b/html/user/sample_server_status.php @@ -139,19 +139,33 @@ $config_xml = get_config(); $config_vars = parse_element($config_xml,""); $project_host = parse_element($config_vars,""); $www_host = parse_element($config_vars,""); -if ($www_host == "") { $www_host = $project_host; } +if ($www_host == "") { + $www_host = $project_host; +} $sched_pid = parse_element($config_vars,""); -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,""); -if ($sched_host == "") { $sched_host = $project_host; } +if ($sched_host == "") { + $sched_host = $project_host; +} $uldl_pid = parse_element($config_vars,""); -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,""); -if ($uldl_host == "") { $uldl_host = $project_host; } +if ($uldl_host == "") { + $uldl_host = $project_host; +} $ssh_exe = parse_element($config_vars,""); -if ($ssh_exe == "") { $ssh_exe = "/usr/bin/ssh"; } +if ($ssh_exe == "") { + $ssh_exe = "/usr/bin/ssh"; +} $ps_exe = parse_element($config_vars,""); -if ($ps_exe == "") { $ps_exe = "/bin/ps"; } +if ($ps_exe == "") { + $ps_exe = "/bin/ps"; +} $xmlstring = "\n " . time() . "\n \n"; @@ -213,9 +227,12 @@ while ($thisxml = trim(parse_next_element($config_xml,"",&$cursor))) { } $xmlstring = " \n \n"; -if ($xml) { echo $xmlstring; } -else { - if ($xmlout) { fwrite($xmloutfile,$xmlstring); } +if ($xml) { + echo $xmlstring; +} else { + if ($xmlout) { + fwrite($xmloutfile,$xmlstring); + } echo " Running: Program is operating normally @@ -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 ""; } } $xmlstring = " \n\n"; -if ($xml) { echo $xmlstring; } -else { - if ($xmlout) { fwrite($xmloutfile,$xmlstring); } +if ($xml) { + echo $xmlstring; +} else { + if ($xmlout) { + fwrite($xmloutfile,$xmlstring); + } echo "   diff --git a/html/user/sample_status.php b/html/user/sample_status.php deleted file mode 100644 index 2984f6e1db..0000000000 --- a/html/user/sample_status.php +++ /dev/null @@ -1,104 +0,0 @@ -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 "
$pidname is running on $host\n"; - } else { - echo "
$pidname is not running on $host\n"; - } -} - -function show_status($host, $function, $running) { - echo "$function$host"; - if ($running) { - echo "Running\n"; - } else { - echo "Not running\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 " -

Server status

- - -"; - -$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 " -
ProgramHostStatus
- -

Database status

-"; - -$retval = db_init_aux(); -if ($retval) { - echo "The database server is not accessable"; -} else { - echo " - - - "; - $n = count_estimate("select count(*) from result where server_state=2"); - echo " - - "; - $n = count_estimate("select count(*) from result where server_state=4"); - echo " - -
StateApproximate #results
Ready to send".number_format($n)."
In progress".number_format($n)."
- "; -} - -page_tail(true); -end_cache(600); - -?> diff --git a/lib/filesys.C b/lib/filesys.C index 44f4db0fa5..ec2f2cf077 100755 --- a/lib/filesys.C +++ b/lib/filesys.C @@ -31,16 +31,10 @@ #include #include #include - -#ifdef HAVE_SYS_TIME_H #include -#endif -#ifdef HAVE_UNISTD_H #include -#endif -#ifdef HAVE_DIRENT_H #include -#endif + #ifdef HAVE_SYS_RESOURCE_H #include #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; } diff --git a/lib/network.C b/lib/network.C index a42a605057..44f4da2306 100644 --- a/lib/network.C +++ b/lib/network.C @@ -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; } diff --git a/py/Boinc/setup_project.py b/py/Boinc/setup_project.py index 4481c65a23..f54e8a24d5 100644 --- a/py/Boinc/setup_project.py +++ b/py/Boinc/setup_project.py @@ -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'))