From cc50b6824e21d9ebb3491bbd4c6d7d8f09be9657 Mon Sep 17 00:00:00 2001 From: Luis Fernando Munoz Mejias Date: Thu, 12 Nov 2009 14:34:55 +0100 Subject: If the server disconnects the handle is no longer valid and we need to call tryResume(), so we have to return RS_RET_SUSPENDED. Otherwise, we may keep losing messages until rsyslog is restarted. --- plugins/omoracle/omoracle.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'plugins/omoracle/omoracle.c') diff --git a/plugins/omoracle/omoracle.c b/plugins/omoracle/omoracle.c index 331b7dd4..ee0c226a 100644 --- a/plugins/omoracle/omoracle.c +++ b/plugins/omoracle/omoracle.c @@ -180,6 +180,9 @@ static int oci_errors(void* handle, ub4 htype, sword status) break; case OCI_INVALID_HANDLE: errmsg.LogError(0, NO_ERRCODE, "OCI INVALID HANDLE\n"); + /* In this case we may have to trigger a call to + * tryResume(). */ + return RS_RET_SUSPENDED; break; case OCI_STILL_EXECUTING: errmsg.LogError(0, NO_ERRCODE, "Still executing...\n"); -- cgit v1.2.3 From d06b63272d9d5eb568201026bfd42be2be845b18 Mon Sep 17 00:00:00 2001 From: Luis Fernando Munoz Mejias Date: Thu, 12 Nov 2009 14:37:14 +0100 Subject: doc --- plugins/omoracle/omoracle.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'plugins/omoracle/omoracle.c') diff --git a/plugins/omoracle/omoracle.c b/plugins/omoracle/omoracle.c index ee0c226a..ccb1593f 100644 --- a/plugins/omoracle/omoracle.c +++ b/plugins/omoracle/omoracle.c @@ -47,9 +47,9 @@ $OmoracleStatement \ insert into foo(hostname,message)values(:host,:message) - Also note that identifiers to placeholders are arbitrarry. You - need to define the properties on the template in the correct order - you want them passed to the statement! + Also note that identifiers to placeholders are arbitrary. You need + to define the properties on the template in the correct order you + want them passed to the statement! This file is licensed under the terms of the GPL version 3 or, at your choice, any later version. Exceptionally (perhaps), you are -- cgit v1.2.3 From 4ed50bb87466ecaba05e6fc53892926997120c18 Mon Sep 17 00:00:00 2001 From: Luis Fernando Munoz Mejias Date: Thu, 12 Nov 2009 14:40:30 +0100 Subject: Improve the handling of OCI_SUCCESS_WITH_INFO. Stop considering it as an error, and make it display the information from the Oracle server. --- plugins/omoracle/omoracle.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) (limited to 'plugins/omoracle/omoracle.c') diff --git a/plugins/omoracle/omoracle.c b/plugins/omoracle/omoracle.c index ccb1593f..35478ef4 100644 --- a/plugins/omoracle/omoracle.c +++ b/plugins/omoracle/omoracle.c @@ -87,7 +87,8 @@ MODULE_TYPE_OUTPUT DEF_OMOD_STATIC_DATA DEFobjCurrIf(errmsg) -/** */ +/** Structure defining a batch of items to be sent to the database in + * the same statement execution. */ struct oracle_batch { /* Batch size */ @@ -162,8 +163,10 @@ static int oci_errors(void* handle, ub4 htype, sword status) return OCI_SUCCESS; break; case OCI_SUCCESS_WITH_INFO: - errmsg.LogError(0, NO_ERRCODE, "OCI SUCCESS - With info\n"); - break; + OCIErrorGet(handle, 1, NULL, &errcode, buf, sizeof buf, htype); + errmsg.LogError(0, NO_ERRCODE, "OCI SUCCESS - With info: %s", + buf); + return OCI_SUCCESS; case OCI_NEED_DATA: errmsg.LogError(0, NO_ERRCODE, "OCI NEEDS MORE DATA\n"); break; -- cgit v1.2.3 From 54672aa273f3fa19435e1c300f258ec6059745d8 Mon Sep 17 00:00:00 2001 From: Luis Fernando Munoz Mejias Date: Thu, 12 Nov 2009 14:43:44 +0100 Subject: Report errors when OCI_SUCCESS_WITH_INFO happens --- plugins/omoracle/omoracle.c | 30 +++++++++++++++++++++++++++++- 1 file changed, 29 insertions(+), 1 deletion(-) (limited to 'plugins/omoracle/omoracle.c') diff --git a/plugins/omoracle/omoracle.c b/plugins/omoracle/omoracle.c index 35478ef4..67b0cff0 100644 --- a/plugins/omoracle/omoracle.c +++ b/plugins/omoracle/omoracle.c @@ -166,7 +166,7 @@ static int oci_errors(void* handle, ub4 htype, sword status) OCIErrorGet(handle, 1, NULL, &errcode, buf, sizeof buf, htype); errmsg.LogError(0, NO_ERRCODE, "OCI SUCCESS - With info: %s", buf); - return OCI_SUCCESS; + return OCI_SUCCESS_WITH_INFO; case OCI_NEED_DATA: errmsg.LogError(0, NO_ERRCODE, "OCI NEEDS MORE DATA\n"); break; @@ -338,6 +338,30 @@ CODESTARTcreateInstance finalize_it: ENDcreateInstance +static void log_detailed_err(instanceData* pData) +{ + int errs, i, row, code; + OCIError *er, *er2; + unsigned char buf[MAX_BUFSIZE]; + + OCIAttrGet(pData->statement, OCI_HTYPE_STMT, &errs, 0, + OCI_ATTR_NUM_DML_ERRORS, pData->error); + + for (i = 0; i < errs; i++) { + OCIHandleAlloc(pData->environment, &er2, OCI_HTYPE_ERROR, + 0, NULL); + OCIParamGet(pData->error, OCI_HTYPE_ERROR, + er2, &er, i); + OCIAttrGet(er, OCI_HTYPE_ERROR, &row, 0, + OCI_ATTR_DML_ROW_OFFSET, er2); + OCIErrorGet(er, row, NULL, &code, buf, sizeof buf, + OCI_HTYPE_ERROR); + errmsg.LogError(0, NO_ERRCODE, "FAILURE DETAILS: %s", buf); + OCIHandleFree(er2, OCI_HTYPE_ERROR); + } +} + + /* Inserts all stored statements into the database, releasing any * allocated memory. */ static int insert_to_db(instanceData* pData) @@ -352,6 +376,10 @@ static int insert_to_db(instanceData* pData) OCI_BATCH_ERRORS)); finalize_it: + if (iRet == OCI_SUCCESS_WITH_INFO) { + log_detailed_err(pData); + iRet = RS_RET_OK; + } pData->batch.n = 0; OCITransCommit(pData->service, pData->error, 0); dbgprintf ("omoracle insertion to DB %s\n", iRet == RS_RET_OK ? -- cgit v1.2.3 From 4be35fbc60c94ee504f5a0428270b59d8438c9f4 Mon Sep 17 00:00:00 2001 From: Luis Fernando Munoz Mejias Date: Thu, 12 Nov 2009 14:44:30 +0100 Subject: Debug output to find out a crash --- plugins/omoracle/omoracle.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'plugins/omoracle/omoracle.c') diff --git a/plugins/omoracle/omoracle.c b/plugins/omoracle/omoracle.c index 67b0cff0..c3acfb38 100644 --- a/plugins/omoracle/omoracle.c +++ b/plugins/omoracle/omoracle.c @@ -346,14 +346,18 @@ static void log_detailed_err(instanceData* pData) OCIAttrGet(pData->statement, OCI_HTYPE_STMT, &errs, 0, OCI_ATTR_NUM_DML_ERRORS, pData->error); - + dbgprintf("There were %d errors\n", errs); for (i = 0; i < errs; i++) { + dbgprintf("Allocating stuff %d\n", i); OCIHandleAlloc(pData->environment, &er2, OCI_HTYPE_ERROR, 0, NULL); + dbgprintf("ParamGet %d\n", i); OCIParamGet(pData->error, OCI_HTYPE_ERROR, er2, &er, i); + dbgprintf("AttrGet %d\n", i); OCIAttrGet(er, OCI_HTYPE_ERROR, &row, 0, OCI_ATTR_DML_ROW_OFFSET, er2); + dbgprintf("ErrorGet %d\n", i); OCIErrorGet(er, row, NULL, &code, buf, sizeof buf, OCI_HTYPE_ERROR); errmsg.LogError(0, NO_ERRCODE, "FAILURE DETAILS: %s", buf); -- cgit v1.2.3 From 774fdc6c799e9671c8e0eac5271a83a3f8fb4646 Mon Sep 17 00:00:00 2001 From: Luis Fernando Munoz Mejias Date: Thu, 12 Nov 2009 14:45:05 +0100 Subject: Improve the debug messages Improve traceability while testing. --- plugins/omoracle/omoracle.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) (limited to 'plugins/omoracle/omoracle.c') diff --git a/plugins/omoracle/omoracle.c b/plugins/omoracle/omoracle.c index c3acfb38..31e498f7 100644 --- a/plugins/omoracle/omoracle.c +++ b/plugins/omoracle/omoracle.c @@ -346,23 +346,23 @@ static void log_detailed_err(instanceData* pData) OCIAttrGet(pData->statement, OCI_HTYPE_STMT, &errs, 0, OCI_ATTR_NUM_DML_ERRORS, pData->error); - dbgprintf("There were %d errors\n", errs); + errmsg.LogError(0, NO_ERRCODE, "%d errors in statement execution\n", + errs); + OCIHandleAlloc(pData->environment, &er, OCI_HTYPE_ERROR, + 0, NULL); + OCIHandleAlloc(pData->environment, &er2, OCI_HTYPE_ERROR, + 0, NULL); for (i = 0; i < errs; i++) { - dbgprintf("Allocating stuff %d\n", i); - OCIHandleAlloc(pData->environment, &er2, OCI_HTYPE_ERROR, - 0, NULL); - dbgprintf("ParamGet %d\n", i); OCIParamGet(pData->error, OCI_HTYPE_ERROR, er2, &er, i); - dbgprintf("AttrGet %d\n", i); OCIAttrGet(er, OCI_HTYPE_ERROR, &row, 0, OCI_ATTR_DML_ROW_OFFSET, er2); - dbgprintf("ErrorGet %d\n", i); OCIErrorGet(er, row, NULL, &code, buf, sizeof buf, OCI_HTYPE_ERROR); errmsg.LogError(0, NO_ERRCODE, "FAILURE DETAILS: %s", buf); - OCIHandleFree(er2, OCI_HTYPE_ERROR); } + OCIHandleFree(er, OCI_HTYPE_ERROR); + OCIHandleFree(er2, OCI_HTYPE_ERROR); } -- cgit v1.2.3 From f5676115b54cb9620cc5092a898d83531f22b502 Mon Sep 17 00:00:00 2001 From: Luis Fernando Munoz Mejias Date: Thu, 12 Nov 2009 14:46:09 +0100 Subject: Give even better output Tell which statement is failing, which element in the batch, and give its details. --- plugins/omoracle/omoracle.c | 32 +++++++++++++++++++++++--------- 1 file changed, 23 insertions(+), 9 deletions(-) (limited to 'plugins/omoracle/omoracle.c') diff --git a/plugins/omoracle/omoracle.c b/plugins/omoracle/omoracle.c index 31e498f7..48ee1fa4 100644 --- a/plugins/omoracle/omoracle.c +++ b/plugins/omoracle/omoracle.c @@ -338,29 +338,43 @@ CODESTARTcreateInstance finalize_it: ENDcreateInstance +/* Analyses the errors during a batch statement execution, and logs + * all the corresponding ORA-MESSAGES, together with some useful + * information. */ static void log_detailed_err(instanceData* pData) { - int errs, i, row, code; - OCIError *er, *er2; + DEFiRet; + int errs, i, row, code, j; + OCIError *er = NULL, *er2 = NULL; unsigned char buf[MAX_BUFSIZE]; OCIAttrGet(pData->statement, OCI_HTYPE_STMT, &errs, 0, OCI_ATTR_NUM_DML_ERRORS, pData->error); - errmsg.LogError(0, NO_ERRCODE, "%d errors in statement execution\n", - errs); - OCIHandleAlloc(pData->environment, &er, OCI_HTYPE_ERROR, - 0, NULL); - OCIHandleAlloc(pData->environment, &er2, OCI_HTYPE_ERROR, - 0, NULL); + errmsg.LogError(0, NO_ERRCODE, "OCI: %d errors in execution of " + "statement: %s", errs, pData->txt_statement); + + CHECKENV(pData->environment, + OCIHandleAlloc(pData->environment, &er, OCI_HTYPE_ERROR, + 0, NULL)); + CHECKENV(pData->environment, + OCIHandleAlloc(pData->environment, &er2, OCI_HTYPE_ERROR, + 0, NULL)); + for (i = 0; i < errs; i++) { OCIParamGet(pData->error, OCI_HTYPE_ERROR, er2, &er, i); OCIAttrGet(er, OCI_HTYPE_ERROR, &row, 0, OCI_ATTR_DML_ROW_OFFSET, er2); - OCIErrorGet(er, row, NULL, &code, buf, sizeof buf, + errmsg.LogError(0, NO_ERRCODE, "OCI failure in row %d:", row); + for (j = 0; j < pData->batch.arguments; j++) + errmsg.LogError(0, NO_ERRCODE, "%s", + pData->batch.parameters[j][row]); + OCIErrorGet(er, 1, NULL, &code, buf, sizeof buf, OCI_HTYPE_ERROR); errmsg.LogError(0, NO_ERRCODE, "FAILURE DETAILS: %s", buf); } + +finalize_it: OCIHandleFree(er, OCI_HTYPE_ERROR); OCIHandleFree(er2, OCI_HTYPE_ERROR); } -- cgit v1.2.3 From 0b18c17b2850152203ce9db648ce06212ab67157 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Luis=20Fernando=20Mu=C3=B1oz=20Mej=C3=ADas?= Date: Tue, 30 Nov 2010 13:04:58 +0100 Subject: Fix a potential missing '\0' on too long strings. By implementing a trivial strlcpy it's much easier to detect string truncations and react to them. This also gives a noticeable speedup in buffer handling (can be HUGE), since strlcpy() doesn't clear all the buffer entry before writing data. Converted all uses of strncpy() into strlcpy(). Also, we don't need to check for some null pointers, as there are no malloc-like operations in the doAction loop. --- plugins/omoracle/omoracle.c | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) (limited to 'plugins/omoracle/omoracle.c') diff --git a/plugins/omoracle/omoracle.c b/plugins/omoracle/omoracle.c index 48ee1fa4..30b5834b 100644 --- a/plugins/omoracle/omoracle.c +++ b/plugins/omoracle/omoracle.c @@ -127,6 +127,13 @@ typedef struct _instanceData { struct oracle_batch batch; } instanceData; +/* To be honest, strlcpy is faster than strncpy and makes very easy to + * detect if a message has been truncated. */ +#ifndef strlcpy +#define strlcpy(dst,src,sz) snprintf((dst), (sz), "%s", (src)) +#endif + + /** Database name, to be filled by the $OmoracleDB directive */ static char* db_name; /** Database user name, to be filled by the $OmoracleDBUser @@ -529,7 +536,7 @@ CODE_STD_FINALIZERparseSelectorAct ENDparseSelectorAct BEGINdoAction - int i; + int i, sz; char **params = (char**) ppString[0]; CODESTARTdoAction @@ -540,9 +547,13 @@ CODESTARTdoAction for (i = 0; i < pData->batch.arguments && params[i]; i++) { dbgprintf("batch[%d][%d]=%s\n", i, pData->batch.n, params[i]); - strncpy(pData->batch.parameters[i][pData->batch.n], params[i], - pData->batch.param_size); - CHKmalloc(pData->batch.parameters[i][pData->batch.n]); + sz = strlcpy(pData->batch.parameters[i][pData->batch.n], + params[i], pData->batch.param_size); + if (sz >= pData->batch.param_size) + errmsg.LogError(0, NO_ERRCODE, + "Possibly truncated %d column of '%s' " + "statement: %s", i, + pData->txt_statement, params[i]); } pData->batch.n++; -- cgit v1.2.3