From 156b5baa96970f98cb655b070df69c634054750c Mon Sep 17 00:00:00 2001 From: Charlie Fenton Date: Wed, 12 Mar 2008 09:39:17 +0000 Subject: [PATCH] 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 --- checkin_notes | 7 ++++ client/cs_statefile.C | 92 +++++++++++++++++++++---------------------- 2 files changed, 52 insertions(+), 47 deletions(-) diff --git a/checkin_notes b/checkin_notes index 4cc21a2fba..b3baf172e4 100644 --- a/checkin_notes +++ b/checkin_notes @@ -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 diff --git a/client/cs_statefile.C b/client/cs_statefile.C index 03cc281e24..f5ceccad02 100644 --- a/client/cs_statefile.C +++ b/client/cs_statefile.C @@ -34,9 +34,6 @@ #include "file_names.h" #include "client_msgs.h" #include "client_state.h" -#ifdef __APPLE__ -#include -#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) {