mirror of https://github.com/BOINC/boinc.git
state file read logic
svn path=/trunk/boinc/; revision=9376
This commit is contained in:
parent
957f883c16
commit
8063219c41
|
@ -1252,3 +1252,26 @@ Bruce 31 Jan 2006
|
|||
inc/
|
||||
user.inc
|
||||
|
||||
David 31 Jan 2005
|
||||
- core client: finish logic for recovering from state file write failures.
|
||||
For some reason I'd done the write part but not the read part.
|
||||
write:
|
||||
1) write "next"
|
||||
2) rename "current" to "prev"
|
||||
3) rename "next" to "current"
|
||||
read:
|
||||
if "next" is valid, use it
|
||||
(in case failure between 1 and 2)
|
||||
In principle we should rename "next" to "current" here,
|
||||
but I didn't bother doing this.
|
||||
else if "current" is valid use it
|
||||
(normal case)
|
||||
else if "prev" is valid use it
|
||||
(in case 3) failed and file got deleted)
|
||||
|
||||
"is valid" means that the file has a <state_file> tag,
|
||||
followed later by a </state_file> tag
|
||||
|
||||
client/
|
||||
cs_statefile.C
|
||||
|
||||
|
|
|
@ -36,11 +36,30 @@ void CLIENT_STATE::set_client_state_dirty(const char* source) {
|
|||
client_state_dirty = true;
|
||||
}
|
||||
|
||||
static bool valid_state_file(char* fname) {
|
||||
char buf[256];
|
||||
FILE* f = boinc_fopen(fname, "r");
|
||||
if (!f) return false;
|
||||
fgets(buf, 256, f);
|
||||
if (!match_tag(buf, "<client_state>")) {
|
||||
fclose(f);
|
||||
return false;
|
||||
}
|
||||
while (fgets(buf, 256, f)) {
|
||||
if (match_tag(buf, "</client_state>")) {
|
||||
fclose(f);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
fclose(f);
|
||||
return false;
|
||||
}
|
||||
|
||||
// Parse the client_state.xml file
|
||||
//
|
||||
int CLIENT_STATE::parse_state_file() {
|
||||
char buf[256];
|
||||
PROJECT *project=NULL;
|
||||
char buf[256];
|
||||
int retval=0;
|
||||
int failnum;
|
||||
const char *fname;
|
||||
|
@ -50,10 +69,12 @@ int CLIENT_STATE::parse_state_file() {
|
|||
// Look for a valid state file:
|
||||
// First the regular one, then the "next" one.
|
||||
//
|
||||
if (boinc_file_exists(STATE_FILE_NAME)) {
|
||||
fname = STATE_FILE_NAME;
|
||||
} else if (boinc_file_exists(STATE_FILE_NEXT)) {
|
||||
if (valid_state_file(STATE_FILE_NEXT)) {
|
||||
fname = STATE_FILE_NEXT;
|
||||
} else if (valid_state_file(STATE_FILE_NAME)) {
|
||||
fname = STATE_FILE_NAME;
|
||||
} else if (boinc_file_exists(STATE_FILE_PREV)) {
|
||||
fname = STATE_FILE_PREV;
|
||||
} else {
|
||||
scope_messages.printf("CLIENT_STATE::parse_state_file(): No state file; will create one\n");
|
||||
|
||||
|
@ -68,25 +89,9 @@ int CLIENT_STATE::parse_state_file() {
|
|||
FILE* f = fopen(fname, "r");
|
||||
MIOFILE mf;
|
||||
mf.init_file(f);
|
||||
fgets(buf, 256, f);
|
||||
if (!match_tag(buf, "<client_state>")) {
|
||||
|
||||
// if file is invalid (probably empty), try the previous statefile
|
||||
//
|
||||
fclose(f);
|
||||
f = fopen(STATE_FILE_PREV, "r");
|
||||
mf.init_file(f);
|
||||
fgets(buf, 256, f);
|
||||
if (!match_tag(buf, "<client_state>")) {
|
||||
msg_printf(NULL, MSG_ERROR, "Missing open tag in state file.\n");
|
||||
retval = ERR_XML_PARSE;
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
while (fgets(buf, 256, f)) {
|
||||
if (match_tag(buf, "</client_state>")) {
|
||||
retval = 0;
|
||||
goto done;
|
||||
break;
|
||||
} else if (match_tag(buf, "<project>")) {
|
||||
PROJECT temp_project;
|
||||
retval = temp_project.parse_state(mf);
|
||||
|
@ -331,15 +336,8 @@ int CLIENT_STATE::parse_state_file() {
|
|||
} else if (parse_str(buf, "<newer_version>", newer_version)) {
|
||||
} else scope_messages.printf("CLIENT_STATE::parse_state_file: unrecognized: %s\n", buf);
|
||||
}
|
||||
|
||||
// if get here, we must have reached end of state file
|
||||
// without finding </client_state> tag.
|
||||
//
|
||||
retval = ERR_XML_PARSE;
|
||||
done:
|
||||
fclose(f);
|
||||
|
||||
return retval;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
|
Loading…
Reference in New Issue