Client: Retry entire write_state_file routine from the beginning if there is an error, not just the step that failed

svn path=/trunk/boinc/; revision=14899
This commit is contained in:
Charlie Fenton 2008-03-12 09:39:17 +00:00
parent db1175f5c3
commit 156b5baa96
2 changed files with 52 additions and 47 deletions

View File

@ -2242,3 +2242,10 @@ David Mar 11 2008
user/
show_host_detail.php
hosts_user.php
Charlie Mar 11 2008
- Client: Retry entire write_state_file routine from the beginning if there is
an error writing or renaming the state file, not just the step that failed.
client/
cs_statefile.C

View File

@ -34,9 +34,6 @@
#include "file_names.h"
#include "client_msgs.h"
#include "client_state.h"
#ifdef __APPLE__
#include <cerrno>
#endif
#define MAX_STATE_FILE_WRITE_ATTEMPTS 2
@ -468,7 +465,7 @@ int CLIENT_STATE::parse_state_file() {
//
int CLIENT_STATE::write_state_file() {
MFILE mf;
int retval, ret1=0, ret2=0, attempt;
int retval, ret1, ret2, attempt;
#ifdef _WIN32
char win_error_msg[4096];
#endif
@ -500,72 +497,71 @@ int CLIENT_STATE::write_state_file() {
miof.init_mfile(&mf);
ret1 = write_state(miof);
ret2 = mf.close();
if ((!ret1) && (!ret2)) break;
if (ret1) {
if ((attempt == MAX_STATE_FILE_WRITE_ATTEMPTS) || log_flags.state_debug) {
msg_printf(NULL, MSG_INTERNAL_ERROR,
"Couldn't write state file: %s", boincerror(retval)
);
}
if (attempt < MAX_STATE_FILE_WRITE_ATTEMPTS) continue;
return ret1;
}
if (ret2) {
if (attempt < MAX_STATE_FILE_WRITE_ATTEMPTS) continue;
return ret2;
}
}
if (ret1) return ret1;
if (ret2) return ret2;
// only attempt to rename the current state file if it exists.
//
if (boinc_file_exists(STATE_FILE_NAME)) {
if (boinc_file_exists(STATE_FILE_PREV)) {
for (attempt=1; attempt<=MAX_STATE_FILE_WRITE_ATTEMPTS; attempt++) {
if (attempt > 1) boinc_sleep(1.0);
// only attempt to rename the current state file if it exists.
//
if (boinc_file_exists(STATE_FILE_NAME)) {
if (boinc_file_exists(STATE_FILE_PREV)) {
retval = boinc_delete_file(STATE_FILE_PREV);
if (!retval) break;
if (retval) {
if ((attempt == MAX_STATE_FILE_WRITE_ATTEMPTS) || log_flags.state_debug) {
#ifdef _WIN32
msg_printf(0, MSG_USER_ERROR,
"Can't delete previous state file; %s",
windows_error_string(win_error_msg, sizeof(win_error_msg))
);
#else
msg_printf(0, MSG_USER_ERROR,
"Can't delete previous state file; error %d: %s",
errno, strerror(errno)
);
#endif
}
if (attempt < MAX_STATE_FILE_WRITE_ATTEMPTS) continue;
}
}
retval = boinc_rename(STATE_FILE_NAME, STATE_FILE_PREV);
if (retval) {
if ((attempt == MAX_STATE_FILE_WRITE_ATTEMPTS) || log_flags.state_debug) {
#ifdef _WIN32
msg_printf(0, MSG_USER_ERROR,
"Can't delete previous state file; %s",
"Can't rename current state file to previous state file; %s",
windows_error_string(win_error_msg, sizeof(win_error_msg))
);
#else
msg_printf(0, MSG_USER_ERROR,
"Can't delete previous state file; error %d: %s",
msg_printf(0, MSG_USER_ERROR,
"rename current state file to previous state file returned error %d: %s",
errno, strerror(errno)
);
#endif
}
if (attempt < MAX_STATE_FILE_WRITE_ATTEMPTS) continue;
}
}
for (attempt=1; attempt<=MAX_STATE_FILE_WRITE_ATTEMPTS; attempt++) {
if (attempt > 1) boinc_sleep(1.0);
retval = boinc_rename(STATE_FILE_NAME, STATE_FILE_PREV);
if (!retval) break;
if ((attempt == MAX_STATE_FILE_WRITE_ATTEMPTS) || log_flags.state_debug) {
#ifdef _WIN32
msg_printf(0, MSG_USER_ERROR,
"Can't rename current state file to previous state file; %s",
windows_error_string(win_error_msg, sizeof(win_error_msg))
);
#else
msg_printf(0, MSG_USER_ERROR,
"rename current state file to previous state file returned error %d: %s",
errno, strerror(errno)
);
#endif
}
}
}
for (attempt=1; attempt<=MAX_STATE_FILE_WRITE_ATTEMPTS; attempt++) {
if (attempt > 1) boinc_sleep(1.0);
retval = boinc_rename(STATE_FILE_NEXT, STATE_FILE_NAME);
if (log_flags.state_debug) {
msg_printf(0, MSG_INFO,
"[status_debug] CLIENT_STATE::write_state_file(): Done writing state file"
);
}
if (!retval) return 0;
if ((attempt == MAX_STATE_FILE_WRITE_ATTEMPTS) || log_flags.state_debug) {
if (!retval) break; // Success!
if ((attempt == MAX_STATE_FILE_WRITE_ATTEMPTS) || log_flags.state_debug) {
#ifdef _WIN32
if (retval == ERROR_ACCESS_DENIED) {
msg_printf(0, MSG_USER_ERROR,
@ -587,14 +583,16 @@ int CLIENT_STATE::write_state_file() {
system("ls -al /Library/Application\\ Support/BOINC\\ Data/client*.*");
}
#else
msg_printf(0, MSG_USER_ERROR,
"Can't rename %s to %s; check file and directory permissions",
STATE_FILE_NEXT, STATE_FILE_NAME
);
msg_printf(0, MSG_USER_ERROR,
"Can't rename %s to %s; check file and directory permissions",
STATE_FILE_NEXT, STATE_FILE_NAME
);
#endif
}
if (attempt < MAX_STATE_FILE_WRITE_ATTEMPTS) continue;
return ERR_RENAME;
}
return ERR_RENAME;
return 0;
}
int CLIENT_STATE::write_state(MIOFILE& f) {