diff --git a/checkin_notes b/checkin_notes index ef784e82b0..f8e065db7e 100755 --- a/checkin_notes +++ b/checkin_notes @@ -21671,3 +21671,27 @@ David 20 Dec 2004 sample_dummy_assimilator.C sched_util.C validate_util.C + +David 20 Dec 2004 + - modify scheduler to handle bad host IDs gracefully. + E.g.: it a project accidentally deletes its host table, + things will eventually return to normal without + users having to detach/reattach + + Old logic: + look up host based on request.hostid + look up user based on host.userid + if user.authenticator != request.authenticator + send error message and delay request + + New logic: + look up host based on request.hostid + If not found, create new host record and return its ID + look up user based on request.authenticator + if no such user + send error message and delay request + if host.userid != user.id + create new host record and return its ID + + sched/ + handle_request.C diff --git a/doc/assimilate.php b/doc/assimilate.php index cd99b1b999..d69e512687 100644 --- a/doc/assimilate.php +++ b/doc/assimilate.php @@ -34,7 +34,7 @@ If assimilate_handler() returns zero, the workunit record will be marked as assimilated. If assimilate_handler() returns nonzero, the assimilator will print an error message and exit. -Typically you should do this in any error situation. +Typically you should return any recoverable error.
You can use BOINC's back-end utility functions diff --git a/sched/handle_request.C b/sched/handle_request.C index c66fbcd99e..55e71fa5c5 100644 --- a/sched/handle_request.C +++ b/sched/handle_request.C @@ -80,23 +80,13 @@ int authenticate_user(SCHEDULER_REQUEST& sreq, SCHEDULER_REPLY& reply) { } reply.host = host; - retval = user.lookup_id(reply.host.userid); + strlcpy( + user.authenticator, sreq.authenticator, + sizeof(user.authenticator) + ); + sprintf(buf, "where authenticator='%s'", user.authenticator); + retval = user.lookup(buf); if (retval) { - // this should never happen - means inconsistent DB - // - strcpy(reply.message, "Can't find user record"); - strcpy(reply.message_priority, "low"); - reply.request_delay = 3600; - reply.nucleus_only = true; - log_messages.printf( - SCHED_MSG_LOG::NORMAL, - "[HOST#%d] [USER#%d?] can't find user record\n", - host.id, reply.host.userid - ); - return retval; - } - reply.user = user; - if (strcmp(sreq.authenticator, reply.user.authenticator)) { strcpy(reply.message, "Invalid or missing account key. " "Visit this project's web site to get an account key." @@ -111,6 +101,20 @@ int authenticate_user(SCHEDULER_REQUEST& sreq, SCHEDULER_REPLY& reply) { ); return ERR_AUTHENTICATOR; } + reply.user = user; + + if (host.userid != user.id) { + // If the request's host ID isn't consistent with the authenticator, + // create a new host record. + // + log_messages.printf( + SCHED_MSG_LOG::NORMAL, + "[HOST#%d] [USER#%d] inconsistent host ID; creating new host\n", + host.id, user.id + ); + goto make_new_host; + } + // If the seqno from the host is less than what we expect, // the user must have copied the state file to a different host. @@ -131,7 +135,7 @@ int authenticate_user(SCHEDULER_REQUEST& sreq, SCHEDULER_REPLY& reply) { // here no hostid was given; we'll have to create a new host record // lookup_user_and_make_new_host: - strncpy( + strlcpy( user.authenticator, sreq.authenticator, sizeof(user.authenticator) );