osaf/tools/saflog/saflogger/saf_logger.c | 82 +++++++++++++++++++++++++------ 1 files changed, 66 insertions(+), 16 deletions(-)
Currently the saflogger tool does not honours the SA_AIS_ERR_TRY_AGAIN for the saLogInitialize(), saLogStreamOpen_2(), saLogStreamClose(), saLogFinalize() APIs. This can create problems in the context of the overload protection scheme in the LOG Server and the upcoming #793 that provides for a flow control mechanism. The absence of a try again mechanism can lead to discarded writes(ofcourse depends on how the enduser has integrated the saflogger tool) and other problems for eg:- It has been observed that if a TRY_AGAIN(after sometime) is not attmepted on streamOpen, can lead to other serious problems. This patch does the following: - Enables the saflogger tool to TRY_AGAIN for all the LOG APIs. - Waits for 10 ms before trying again, until a worstcase of 10 seconds. - Removes an undesired error mesasge when try_again is hit. - Avoids an indefinite loop for log Writes() and instead makes it re-attempt till a worstcase of 10 seconds. diff --git a/osaf/tools/saflog/saflogger/saf_logger.c b/osaf/tools/saflog/saflogger/saf_logger.c --- a/osaf/tools/saflog/saflogger/saf_logger.c +++ b/osaf/tools/saflog/saflogger/saf_logger.c @@ -48,6 +48,11 @@ #define DEFAULT_APP_LOG_FILE_SIZE 1024 #define VENDOR_ID 193 #define DEFAULT_MAX_FILES_ROTATED 4 +/* Try for 10 seconds before giving up on an API */ +#define TEN_SECONDS 10*1000*1000 +/* Sleep for 100 ms before retrying an API */ +#define HUNDRED_MS 100*1000 +/* To the reviewer: Should we increase either of the above two timeperiod? */ static void logWriteLogCallbackT(SaInvocationT invocation, SaAisErrorT error); @@ -121,9 +126,9 @@ static SaAisErrorT write_log_record(SaLo SaAisErrorT errorCode; SaInvocationT invocation; int i = 0; - int try_agains = 0; struct pollfd fds[1]; int ret; + unsigned int wait_time = 0; i++; @@ -131,13 +136,15 @@ static SaAisErrorT write_log_record(SaLo retry: errorCode = saLogWriteLogAsync(logStreamHandle, invocation, SA_LOG_RECORD_WRITE_ACK, logRecord); - if (errorCode == SA_AIS_ERR_TRY_AGAIN) { - usleep(100000); /* 100 ms */ - try_agains++; + if (errorCode == SA_AIS_ERR_TRY_AGAIN && wait_time < TEN_SECONDS) { + usleep(HUNDRED_MS); + wait_time += HUNDRED_MS; goto retry; } if (errorCode != SA_AIS_OK) { + if (wait_time) + fprintf(stderr, "Waited for %u seconds.\n", wait_time/1000000); fprintf(stderr, "saLogWriteLogAsync FAILED: %s\n", saf_error(errorCode)); return errorCode; } @@ -172,28 +179,25 @@ poll_retry: return errorCode; } - if (cb_error == SA_AIS_ERR_TRY_AGAIN) { - usleep(100000); /* 100 ms */ - try_agains++; + if (cb_error == SA_AIS_ERR_TRY_AGAIN && wait_time < TEN_SECONDS) { + usleep(HUNDRED_MS); + wait_time += HUNDRED_MS; goto retry; } if (cb_error == SA_AIS_ERR_TIMEOUT) { - usleep(100000); /* 100 ms */ + usleep(HUNDRED_MS); fprintf(stderr, "got SA_AIS_ERR_TIMEOUT, retry\n"); goto retry; } if (cb_error != SA_AIS_OK) { + if (wait_time) + fprintf(stderr, "Waited for %u seconds.\n", wait_time/1000000); fprintf(stderr, "logWriteLogCallbackT FAILED: %s\n", saf_error(cb_error)); return errorCode; } - if (try_agains > 0) { - fprintf(stderr, "got %u SA_AIS_ERR_TRY_AGAIN, waited %u secs\n", try_agains, try_agains / 10); - try_agains = 0; - } - return errorCode; } @@ -249,6 +253,7 @@ int main(int argc, char *argv[]) SaLogHandleT logHandle; SaLogStreamHandleT logStreamHandle; SaSelectionObjectT selectionObject; + unsigned int wait_time; srandom(getpid()); @@ -338,8 +343,17 @@ int main(int argc, char *argv[]) logRecord.logBuffer = &logBuffer; } + wait_time = 0; error = saLogInitialize(&logHandle, &logCallbacks, &logVersion); + while (error == SA_AIS_ERR_TRY_AGAIN && wait_time < TEN_SECONDS) { + usleep(HUNDRED_MS); + wait_time += HUNDRED_MS; + error = saLogInitialize(&logHandle, &logCallbacks, &logVersion); + } + if (error != SA_AIS_OK) { + if (wait_time) + fprintf(stderr, "Waited for %u seconds.\n", wait_time/1000000); fprintf(stderr, "saLogInitialize FAILED: %s\n", saf_error(error)); exit(EXIT_FAILURE); } @@ -353,33 +367,69 @@ int main(int argc, char *argv[]) /* Try open the stream before creating it. It might be a configured app * stream with other attributes than we have causing open with default * attributes to fail */ + wait_time = 0; error = saLogStreamOpen_2(logHandle, &logStreamName, NULL, 0, SA_TIME_ONE_SECOND, &logStreamHandle); + while (error == SA_AIS_ERR_TRY_AGAIN && wait_time < TEN_SECONDS) { + usleep(HUNDRED_MS); + wait_time += HUNDRED_MS; + error = saLogStreamOpen_2(logHandle, &logStreamName, NULL, 0, + SA_TIME_ONE_SECOND, &logStreamHandle); + } if (error == SA_AIS_ERR_NOT_EXIST) { + wait_time = 0; error = saLogStreamOpen_2(logHandle, &logStreamName, logFileCreateAttributes, logStreamOpenFlags, SA_TIME_ONE_SECOND, &logStreamHandle); - if (error != SA_AIS_OK) { - fprintf(stderr, "saLogStreamOpen_2 FAILED: %s\n", saf_error(error)); - exit(EXIT_FAILURE); + while (error == SA_AIS_ERR_TRY_AGAIN && wait_time < TEN_SECONDS) { + usleep(HUNDRED_MS); + wait_time += HUNDRED_MS; + error = saLogStreamOpen_2(logHandle, &logStreamName, logFileCreateAttributes, + logStreamOpenFlags, SA_TIME_ONE_SECOND, &logStreamHandle); } } + if (error != SA_AIS_OK) { + if (wait_time) + fprintf(stderr, "Waited for %u seconds.\n", wait_time/1000000); + fprintf(stderr, "saLogStreamOpen_2 FAILED: %s\n", saf_error(error)); + exit(EXIT_FAILURE); + } + if (write_log_record(logHandle, logStreamHandle, selectionObject, &logRecord) != SA_AIS_OK) { exit(EXIT_FAILURE); } + wait_time = 0; error = saLogStreamClose(logStreamHandle); + while (error == SA_AIS_ERR_TRY_AGAIN && wait_time < TEN_SECONDS) { + usleep(HUNDRED_MS); + wait_time += HUNDRED_MS; + error = saLogStreamClose(logStreamHandle); + } + if (SA_AIS_OK != error) { + if (wait_time) + fprintf(stderr, "Waited for %u seconds.\n", wait_time/1000000); fprintf(stderr, "saLogStreamClose FAILED: %s\n", saf_error(error)); exit(EXIT_FAILURE); } + wait_time = 0; error = saLogFinalize(logHandle); + while (error == SA_AIS_ERR_TRY_AGAIN && wait_time < TEN_SECONDS) { + usleep(HUNDRED_MS); + wait_time += HUNDRED_MS; + error = saLogFinalize(logHandle); + } + if (SA_AIS_OK != error) { + if (wait_time) + fprintf(stderr, "Waited for %u seconds.\n", wait_time/1000000); fprintf(stderr, "saLogFinalize FAILED: %s\n", saf_error(error)); exit(EXIT_FAILURE); } exit(EXIT_SUCCESS); } + ------------------------------------------------------------------------------ Learn Graph Databases - Download FREE O'Reilly Book "Graph Databases" is the definitive new guide to graph databases and their applications. Written by three acclaimed leaders in the field, this first edition is now available. Download your free book today! http://p.sf.net/sfu/NeoTech _______________________________________________ Opensaf-devel mailing list Opensaf-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/opensaf-devel