*** empty log message ***

svn path=/trunk/boinc/; revision=4809
This commit is contained in:
David Anderson 2004-12-10 19:17:32 +00:00
parent b4aeaca73d
commit 7a3f2d4939
9 changed files with 277 additions and 84 deletions

View File

@ -20987,3 +20987,15 @@ David 9 Dec 2004
boinc_api.C
client/
http.C,h
David 10 Dec 2004
- added a function get_file_dir() (in lib/filesys.C)
that searches the directories in the PATH env var,
looking for an executable file with a given name
(this is so boincmgr can find boinc on Unix)
client/
http.C
lib/
filesys.C,h
util.C,h

View File

@ -366,7 +366,7 @@ int HTTP_OP::init_get(const char* url, char* out, bool del_old_file, double off)
} else {
sprintf(proxy_buf, "/%s", filename);
}
if (!pi.use_http_auth){
if (!pi.use_http_auth) {
http_get_request_header(request_header, url_hostname, port, proxy_buf, (int)file_offset);
} else {
char id_passwd[512];
@ -376,8 +376,10 @@ int HTTP_OP::init_get(const char* url, char* out, bool del_old_file, double off)
strcat(id_passwd,":");
strcat(id_passwd,pi.http_user_passwd);
encstr = r_base64_encode(id_passwd,strlen(id_passwd));
http_get_request_header_proxy(request_header, url_hostname,
port, proxy_buf, (int)file_offset, (char*)encstr.c_str() );
http_get_request_header_proxy(
request_header, url_hostname,
port, proxy_buf, (int)file_offset, (char*)encstr.c_str()
);
}
return 0;
}
@ -408,7 +410,7 @@ int HTTP_OP::init_post(const char* url, char* in, char* out) {
sprintf(proxy_buf, "/%s", filename);
}
if (!pi.use_http_auth){
if (!pi.use_http_auth) {
http_post_request_header(
request_header, url_hostname, port, proxy_buf, content_length
);
@ -460,7 +462,7 @@ int HTTP_OP::init_post2(
} else {
sprintf(proxy_buf, "/%s", filename);
}
if (!pi.use_http_auth){
if (!pi.use_http_auth) {
http_post_request_header(
request_header, url_hostname, port, proxy_buf, content_length
);

View File

@ -73,6 +73,8 @@ before getting into the source code.
<li> <a href=python.php>Python framework</a>
<li> <a href=prefs_impl.php>Preferences</a>
<li> <a href=trickle_impl.php>Trickle messages</a>
<li> <a href=version_diff.txt>How to see what has changed
between two versions of an executable</a>.
</ul>
";

View File

@ -76,6 +76,8 @@ This tells the validator to write an error message and exit.
<p>
Neither function should delete files.
<p>
A more detailed description is <a href=validate_logic.txt>here</a>.
<p>
Two example validators are supplied
(each implements check_set() and check_pair()):
<ul>

135
doc/validate_logic.txt Normal file
View File

@ -0,0 +1,135 @@
int check_set(
vector<RESULT> results,
DB_WORKUNIT& wu,
int& canonicalid,
double& credit,
bool& retry
);
Define N := length of result vector, and let M := N.
check_set() will ALWAYS be called with N>=wu.min_quorum.
check_set() will ALWAYS be called with ALL results satisfying
result.outcome == RESULT_OUTCOME_SUCCESS
result.validate_state == VALIDATE_STATE_INIT
check_set() should NEVER modify wu [although it is not declared
const]
[1] Syntax pass (optional)
for (all N results) {
if (one or more of the output files can be read and one or
more of those files contains erroneous or invalid or
incorrect output, i.e. the file syntax is wrong)
{
set result.outcome=RESULT_OUTCOME_VALIDATE_ERROR;
set result.validate_state=VALIDATE_STATE_INVALID;
decrement counter: M = M-1;
} // erroneous or incorrect or invalid output files
else if (result has a potentially recoverable error,
i.e. NFS directory not mounted, server
is unreachable, upload server unreachable)
{
dont not modify result.validate_state;
dont not modify result.outcome;
decrement counter M = M-1;
set retry=true;
} // recoverable error
else if (every output file of the result is unreadable or
fails to exist)
{
set result.outcome=RESULT_OUTCOME_VALIDATE_ERROR;
set result.validate_state=VALIDATE_STATE_INIT;
decrement counter: M = M-1;
} // all result output files unreadable or nonexistent
} // end of syntax pass loop over all N results
Define REMAINING RESULTS to be those that do NOT fall into one of
the two categories above. There are M of these. If the syntax pass
has been skipped, then M == N.
if (M < wu.min_quorum)
{
dont modify canonicalid;
dont modify credit;
leave retry as set above;
leave result.outcome unchanged for M remaining results;
leave result.validate_state unchanged for M remaining results;
return 0;
} // fewer than min_quorum results remain
At any point in this process, if a major error occurs, check_set
should return nonzero. This will cause the validator to exit. If
this happens, it does not matter how you have set or modified
result.outcome, result.validate_state, retry, credit, or canonicalid.
// END OF OPTIONAL SYNTAX PASS
[2] Comparison pass (required). We have
M>=wu.min_quorum REMAINING RESULTS results with
result.outcome == RESULT_OUTCOME_SUCCESS
result.validate_state == VALIDATE_STATE_INIT
All the output files of all of these results are
readable. All of the output files for a given result
are, when taken "in isolation" apparently valid. If
these conditions are not met then you must do the
"syntax pass" above.
if (one of these results is determined to be THE correct
[canonical] result)
{
for correct result {
set result.validate_state=VALIDATE_STATE_VALID;
set canonicalid=result.id;
} // canonical result
for (the REMAINING M - 1 results)
{
// NOTE: what is below can be done by calling
// check_pair(result, canonical_result)
if (result is correct, matches canonical)
{
result.validate_state=VALIDATE_STATE_VALID;
}
else
{
result.validate_state=VALIDATE_STATE_INVALID;
}
} // loop over remaining M-1 results
set credit;
leave retry as set from the syntax pass above;
return 0;
} // found canonical result
else
{
// You are UNABLE to determine if one of the M REMAINING RESULTS
// is correct, so:
do not modify result.outcome for ANY of M remaining results;
do not modify result.validate_state for ANY of M remaining results;
do not set credit;
do not set canonicalid;
leave retry as set from the syntax pass;
return 0;
} // did not find canonical result
At any point in this process, if a major error occurs, check_set
should return nonzero. This will cause the validator to exit. If
this happens, it does not matter how you have set result.outcome,
result.validate_state, retry, credit, or canonicalid for ANY of the
results.
// end of Comparison pass

View File

@ -546,6 +546,33 @@ int get_filesystem_info(double &total_space, double &free_space) {
return 0;
}
#ifndef _WIN32
int get_file_dir(char* filename, char* dir) {
char buf[8192], *p, path[256];
struct stat sbuf;
int retval;
p = getenv("PATH");
if (!p) return ERR_NOT_FOUND;
strcpy(buf, p);
p = strtok(buf, ":");
while (p) {
sprintf(path, "%s/%s", p, filename);
retval = stat(path, &sbuf);
if (!retval && (sbuf.st_mode & 0111)) {
strcpy(dir, p);
return 0;
}
p = strtok(0, ":");
}
return ERR_NOT_FOUND;
}
#endif
#ifdef __GNUC__
static volatile const char __attribute__((unused)) *BOINCrcsid="$Id$";
#else

View File

@ -114,6 +114,15 @@ public:
bool scan(std::string& name); // return true if file returned
};
#ifndef _WIN32
// search PATH, find the directory that a program is in, if any
//
extern int get_file_dir(char* filename, char* dir);
#endif
#endif /* c++ */
#endif /* double-inclusion protection */

View File

@ -192,7 +192,8 @@ void nbytes_to_string(double nbytes, double total_bytes, char* str, int len) {
#define EPOCHFILETIME_SEC (11644473600.)
#define TEN_MILLION 10000000.
// return time of day as a double
// return time of day (seconds since 1970) as a double
//
double dtime() {
#ifdef _WIN32

View File

@ -56,8 +56,8 @@ extern void safe_strncpy(char*, const char*, int);
#define safe_strcpy(x, y) safe_strncpy(x, y, sizeof(x))
#define safe_strcat(x, y) if (strlen(x)+strlen(y)<sizeof(x)) strcat(x, y)
extern char* time_to_string(double);
std::string timediff_format(double);
int read_file_string(const char* pathname, std::string& result);
extern std::string timediff_format(double);
extern int read_file_string(const char* pathname, std::string& result);
inline bool ends_with(std::string const& s, std::string const& suffix) {
return
@ -89,16 +89,17 @@ static inline double drand() {
}
// return a random integer in the range [rmin,rmax)
static inline double rand_range(double rmin, double rmax)
{
if (rmin < rmax)
static inline double rand_range(double rmin, double rmax) {
if (rmin < rmax) {
return drand() * (rmax-rmin) + rmin;
else
} else {
return rmin;
}
}
// return a random integer in the range [MIN,min(e^n,MAX))
double calculate_exponential_backoff(
//
extern double calculate_exponential_backoff(
const char* debug_descr, int n, double MIN, double MAX,
double factor=1.0
);
@ -106,12 +107,14 @@ extern bool debug_fake_exponential_backoff;
#ifdef _WIN32
#include <windows.h>
char* windows_error_string(char* pszBuf, int iSize);
char* windows_format_error_string(
extern char* windows_error_string(char* pszBuf, int iSize);
extern char* windows_format_error_string(
unsigned long dwError, char* pszBuf, int iSize
);
int boinc_thread_cpu_time(HANDLE thread_handle, double& cpu);
extern int boinc_thread_cpu_time(HANDLE thread_handle, double& cpu);
#endif
extern void update_average(double, double, double, double&, double&);