From 4ecd6bb9462f0fbaf4609f62d768847cc7e85f7e Mon Sep 17 00:00:00 2001 From: Rainer Gerhards Date: Mon, 22 Jul 2013 17:38:31 +0200 Subject: first shot at global variables (without proper sync so far) --- runtime/msg.c | 42 ++++++++++++++++++++++++++++++++++-------- 1 file changed, 34 insertions(+), 8 deletions(-) (limited to 'runtime/msg.c') diff --git a/runtime/msg.c b/runtime/msg.c index 73fa0367..87213bb7 100644 --- a/runtime/msg.c +++ b/runtime/msg.c @@ -66,6 +66,11 @@ #include "var.h" #include "rsconf.h" +/* TODO: move the global variable root to the config object - had no time to to it + * right now before vacation -- rgerhards, 2013-07-22 + */ +struct json_object *global_var_root = NULL; + /* static data */ DEFobjStaticHelpers DEFobjCurrIf(datetime) @@ -539,6 +544,8 @@ propNameStrToID(uchar *pName, propid_t *pPropID) *pPropID = PROP_CEE; } else if(!strncmp((char*) pName, "$.", 2)) { *pPropID = PROP_LOCAL_VAR; + } else if(!strncmp((char*) pName, "$/", 2)) { + *pPropID = PROP_GLOBAL_VAR; } else if(!strcmp((char*) pName, "$bom")) { *pPropID = PROP_SYS_BOM; } else if(!strcmp((char*) pName, "$uptime")) { @@ -639,6 +646,8 @@ uchar *propIDToName(propid_t propID) return UCHAR_CONSTANT("*CEE-based property*"); case PROP_LOCAL_VAR: return UCHAR_CONSTANT("*LOCAL_VARIABLE*"); + case PROP_GLOBAL_VAR: + return UCHAR_CONSTANT("*GLOBAL_VARIABLE*"); case PROP_CEE_ALL_JSON: return UCHAR_CONSTANT("$!all-json"); case PROP_SYS_BOM: @@ -2584,6 +2593,12 @@ getLocalVarPropVal(msg_t *pM, es_str_t *propName, uchar **pRes, rs_size_t *bufle return getJSONPropVal(pM->localvars, propName, pRes, buflen, pbMustBeFreed); } +rsRetVal +getGlobalVarPropVal( es_str_t *propName, uchar **pRes, rs_size_t *buflen, unsigned short *pbMustBeFreed) +{ + return getJSONPropVal(global_var_root, propName, pRes, buflen, pbMustBeFreed); +} + /* Get a JSON-based-variable as native json object */ rsRetVal @@ -2628,6 +2643,12 @@ msgGetLocalVarJSON(msg_t *pM, es_str_t *propName, struct json_object **pjson) return msgGetJSONPropJSON(pM->localvars, propName, pjson); } +rsRetVal +msgGetGlobalVarJSON(es_str_t *propName, struct json_object **pjson) +{ + return msgGetJSONPropJSON(global_var_root, propName, pjson); +} + /* Encode a JSON value and add it to provided string. Note that * the string object may be NULL. In this case, it is created * if and only if escaping is needed. @@ -3028,6 +3049,9 @@ uchar *MsgGetProp(msg_t *pMsg, struct templateEntry *pTpe, case PROP_LOCAL_VAR: getLocalVarPropVal(pMsg, propName, &pRes, &bufLen, pbMustBeFreed); break; + case PROP_GLOBAL_VAR: + getGlobalVarPropVal(propName, &pRes, &bufLen, pbMustBeFreed); + break; case PROP_SYS_BOM: if(*pbMustBeFreed == 1) free(pRes); @@ -3869,13 +3893,13 @@ jsonPathGetLeaf(uchar *name, int lenName) int i; for(i = lenName ; i >= 0 ; --i) if(i == 0) { - if(name[0] == '.' || name[0] == '!') + if(name[0] == '!' || name[0] == '.' || name[0] == '/') break; } else { if(name[i] == '!') break; } - if(name[i] == '!' || name[i] == '.') + if(name[i] == '!' || name[i] == '.' || name[i] == '/') ++i; return name + i; } @@ -3891,9 +3915,9 @@ jsonPathFindNext(struct json_object *root, uchar *namestart, uchar **name, uchar uchar *p = *name; DEFiRet; - if(*p == '!' || (*name == namestart && *p == '.')) + if(*p == '!' || (*name == namestart && (*p == '.' || *p == '/'))) ++p; - for(i = 0 ; *p && !(p == namestart && *p == '.') && *p != '!' && p != leaf && i < sizeof(namebuf)-1 ; ++i, ++p) + for(i = 0 ; *p && !(p == namestart && (*p == '.' || *p == '/')) && *p != '!' && p != leaf && i < sizeof(namebuf)-1 ; ++i, ++p) namebuf[i] = *p; if(i > 0) { namebuf[i] = '\0'; @@ -3988,7 +4012,7 @@ msgAddJSONObj(msg_t *pM, uchar *name, struct json_object *json, struct json_obje DEFiRet; MsgLock(pM); - if((name[0] == '!' || name[0] == '.') && name[1] == '\0') { + if((name[0] == '!' || name[0] == '.' || name[0] == '/') && name[1] == '\0') { if(*pjroot == NULL) *pjroot = json; else @@ -4049,7 +4073,7 @@ msgDelJSONVar(msg_t *pM, struct json_object **jroot, uchar *name) dbgprintf("AAAA: unset variable '%s'\n", name); MsgLock(pM); - if((name[0] == '!' || name[0] == '.') && name[1] == '\0') { + if((name[0] == '!' || name[0] == '.' || name[0] == '/') && name[1] == '\0') { /* strange, but I think we should permit this. After all, * we trust rsyslog.conf to be written by the admin. */ @@ -4157,10 +4181,12 @@ msgSetJSONFromVar(msg_t *pMsg, uchar *varname, struct var *v) ABORT_FINALIZE(RS_RET_ERR); } /* we always know strlen(varname) > 2 */ + if(varname[1] == '!') + msgAddJSONObj(pMsg, varname+1, json, &pMsg->json); if(varname[1] == '.') msgAddJSONObj(pMsg, varname+1, json, &pMsg->localvars); - else - msgAddJSONObj(pMsg, varname+1, json, &pMsg->json); + else /* global - '/' */ + msgAddJSONObj(pMsg, varname+1, json, &global_var_root); finalize_it: RETiRet; } -- cgit v1.2.3 From 57a7a34748014586eec0f99b68c52f43979218f8 Mon Sep 17 00:00:00 2001 From: Rainer Gerhards Date: Tue, 23 Jul 2013 11:34:53 +0200 Subject: fix: global&local variables could not be accessed via RainerScript also, global variable pool did receive extra variables that did not belong to global pool (problem in last milestone commit) --- runtime/msg.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) (limited to 'runtime/msg.c') diff --git a/runtime/msg.c b/runtime/msg.c index 87213bb7..5517dee8 100644 --- a/runtime/msg.c +++ b/runtime/msg.c @@ -551,6 +551,7 @@ propNameStrToID(uchar *pName, propid_t *pPropID) } else if(!strcmp((char*) pName, "$uptime")) { *pPropID = PROP_SYS_UPTIME; } else { + DBGPRINTF("PROP_INVALID for name '%s'\n", pName); *pPropID = PROP_INVALID; iRet = RS_RET_VAR_NOT_FOUND; } @@ -3774,13 +3775,16 @@ msgGetMsgVarNew(msg_t *pThis, uchar *name) propid_t propid; unsigned short bMustBeFreed = 0; es_str_t *estr; + es_str_t *propName; ISOBJ_TYPE_assert(pThis, msg); /* always call MsgGetProp() without a template specifier */ /* TODO: optimize propNameToID() call -- rgerhards, 2009-06-26 */ propNameStrToID(name, &propid); - pszProp = (uchar*) MsgGetProp(pThis, NULL, propid, NULL, &propLen, &bMustBeFreed, NULL); + propName = es_newStrFromCStr((char*)name+1, ustrlen(name)-1); // TODO: optimize! + pszProp = (uchar*) MsgGetProp(pThis, NULL, propid, propName, &propLen, &bMustBeFreed, NULL); + es_deleteStr(propName); estr = es_newStrFromCStr((char*)pszProp, propLen); if(bMustBeFreed) @@ -4183,7 +4187,7 @@ msgSetJSONFromVar(msg_t *pMsg, uchar *varname, struct var *v) /* we always know strlen(varname) > 2 */ if(varname[1] == '!') msgAddJSONObj(pMsg, varname+1, json, &pMsg->json); - if(varname[1] == '.') + else if(varname[1] == '.') msgAddJSONObj(pMsg, varname+1, json, &pMsg->localvars); else /* global - '/' */ msgAddJSONObj(pMsg, varname+1, json, &global_var_root); -- cgit v1.2.3 From a3c189b8b1a5e4c1326973224fd1e17bb15f2411 Mon Sep 17 00:00:00 2001 From: Rainer Gerhards Date: Tue, 23 Jul 2013 11:47:23 +0200 Subject: add proper sync to global variables --- runtime/msg.c | 20 +++++++++++++++++--- 1 file changed, 17 insertions(+), 3 deletions(-) (limited to 'runtime/msg.c') diff --git a/runtime/msg.c b/runtime/msg.c index 5517dee8..c7cd9406 100644 --- a/runtime/msg.c +++ b/runtime/msg.c @@ -69,6 +69,7 @@ /* TODO: move the global variable root to the config object - had no time to to it * right now before vacation -- rgerhards, 2013-07-22 */ +static pthread_rwlock_t glblVars_rwlock; struct json_object *global_var_root = NULL; /* static data */ @@ -2597,7 +2598,11 @@ getLocalVarPropVal(msg_t *pM, es_str_t *propName, uchar **pRes, rs_size_t *bufle rsRetVal getGlobalVarPropVal( es_str_t *propName, uchar **pRes, rs_size_t *buflen, unsigned short *pbMustBeFreed) { - return getJSONPropVal(global_var_root, propName, pRes, buflen, pbMustBeFreed); + DEFiRet; + pthread_rwlock_rdlock(&glblVars_rwlock); + iRet = getJSONPropVal(global_var_root, propName, pRes, buflen, pbMustBeFreed); + pthread_rwlock_unlock(&glblVars_rwlock); + RETiRet; } @@ -2647,7 +2652,11 @@ msgGetLocalVarJSON(msg_t *pM, es_str_t *propName, struct json_object **pjson) rsRetVal msgGetGlobalVarJSON(es_str_t *propName, struct json_object **pjson) { - return msgGetJSONPropJSON(global_var_root, propName, pjson); + DEFiRet; + pthread_rwlock_rdlock(&glblVars_rwlock); + iRet = msgGetJSONPropJSON(global_var_root, propName, pjson); + pthread_rwlock_unlock(&glblVars_rwlock); + RETiRet; } /* Encode a JSON value and add it to provided string. Note that @@ -4189,8 +4198,11 @@ msgSetJSONFromVar(msg_t *pMsg, uchar *varname, struct var *v) msgAddJSONObj(pMsg, varname+1, json, &pMsg->json); else if(varname[1] == '.') msgAddJSONObj(pMsg, varname+1, json, &pMsg->localvars); - else /* global - '/' */ + else { /* global - '/' */ + pthread_rwlock_wrlock(&glblVars_rwlock); msgAddJSONObj(pMsg, varname+1, json, &global_var_root); + pthread_rwlock_unlock(&glblVars_rwlock); + } finalize_it: RETiRet; } @@ -4203,6 +4215,8 @@ rsRetVal msgQueryInterface(void) { return RS_RET_NOT_IMPLEMENTED; } * rgerhards, 2008-01-04 */ BEGINObjClassInit(msg, 1, OBJ_IS_CORE_MODULE) + pthread_rwlock_init(&glblVars_rwlock, NULL); + /* request objects we use */ CHKiRet(objUse(datetime, CORE_COMPONENT)); CHKiRet(objUse(glbl, CORE_COMPONENT)); -- cgit v1.2.3