diff options
author | Rainer Gerhards <rgerhards@adiscon.com> | 2010-03-25 08:26:18 +0100 |
---|---|---|
committer | Rainer Gerhards <rgerhards@adiscon.com> | 2010-03-25 08:26:18 +0100 |
commit | 648e84cad86a94d2f21ceed37e020fbed6a27b9d (patch) | |
tree | 93f9dcff68b5aadd41f9b4ff8e919a0faa37979e /runtime | |
parent | 2f8b5cafd0dcc5f09b7b64f5015a2aebd1c7b31c (diff) | |
parent | 841f841ce12e49659966db006f3f244e1f23b70e (diff) | |
download | rsyslog-648e84cad86a94d2f21ceed37e020fbed6a27b9d.tar.gz rsyslog-648e84cad86a94d2f21ceed37e020fbed6a27b9d.tar.xz rsyslog-648e84cad86a94d2f21ceed37e020fbed6a27b9d.zip |
Merge branch 'v4-stable' into v4-stable-solaris
Conflicts:
ChangeLog
Diffstat (limited to 'runtime')
-rw-r--r-- | runtime/msg.c | 6 | ||||
-rw-r--r-- | runtime/srutils.c | 32 | ||||
-rw-r--r-- | runtime/stream.c | 2 |
3 files changed, 33 insertions, 7 deletions
diff --git a/runtime/msg.c b/runtime/msg.c index 3a2331f4..2ce7843a 100644 --- a/runtime/msg.c +++ b/runtime/msg.c @@ -2319,6 +2319,12 @@ uchar *MsgGetProp(msg_t *pMsg, struct templateEntry *pTpe, *pPropLen = sizeof("**INVALID PROPERTY NAME**") - 1; return UCHAR_CONSTANT("**INVALID PROPERTY NAME**"); } + /* the following line fixes the symptom, but not the root cause -- at least MSG sometimes + * returns a size of one too less. To prevent all troubles, we recalculate the sizes based + * on what we actually got. TODO: remove once root cause is found. + * rgerhards, 2010-03-23 + */ + bufLen = ustrlen(pRes); /* If we did not receive a template pointer, we are already done... */ diff --git a/runtime/srutils.c b/runtime/srutils.c index c403b312..1452c9b7 100644 --- a/runtime/srutils.c +++ b/runtime/srutils.c @@ -166,10 +166,22 @@ uchar *srUtilStrDup(uchar *pOld, size_t len) /* creates a path recursively - * Return 0 on success, -1 otherwise. On failure, errno - * hold the last OS error. - * Param "mode" holds the mode that all non-existing directories - * are to be created with. + * Return 0 on success, -1 otherwise. On failure, errno * hold the last OS error. + * Param "mode" holds the mode that all non-existing directories are to be + * created with. + * Note that we have a potential race inside that code, a race that even exists + * outside of the rsyslog process (if multiple instances run, or other programs + * generate directories): If the directory does not exist, a context switch happens, + * at that moment another process creates it, then our creation on the context + * switch back fails. This actually happened in practice, and depending on the + * configuration it is even likely to happen. We can not solve this situation + * with a mutex, as that works only within out process space. So the solution + * is that we take the optimistic approach, try the creation, and if it fails + * with "already exists" we go back and do one retry of the check/create + * sequence. That should then succeed. If the directory is still not found but + * the creation fails in the similar way, we return an error on that second + * try because otherwise we would potentially run into an endless loop. + * loop. -- rgerhards, 2010-03-25 */ int makeFileParentDirs(uchar *szFile, size_t lenFile, mode_t mode, uid_t uid, gid_t gid, int bFailOnChownFail) @@ -177,6 +189,8 @@ int makeFileParentDirs(uchar *szFile, size_t lenFile, mode_t mode, uchar *p; uchar *pszWork; size_t len; + int err; + int iTry = 0; int bErr = 0; assert(szFile != NULL); @@ -190,8 +204,9 @@ int makeFileParentDirs(uchar *szFile, size_t lenFile, mode_t mode, if(*p == '/') { /* temporarily terminate string, create dir and go on */ *p = '\0'; +again: if(access((char*)pszWork, F_OK)) { - if(mkdir((char*)pszWork, mode) == 0) { + if((err = mkdir((char*)pszWork, mode)) == 0) { if(uid != (uid_t) -1 || gid != (gid_t) -1) { /* we need to set owner/group */ if(chown((char*)pszWork, uid, gid) != 0) @@ -201,8 +216,13 @@ int makeFileParentDirs(uchar *szFile, size_t lenFile, mode_t mode, * to do so. */ } - } else + } else { + if(err == EEXIST && iTry == 0) { + iTry = 1; + goto again; + } bErr = 1; + } if(bErr) { int eSave = errno; free(pszWork); diff --git a/runtime/stream.c b/runtime/stream.c index bfeecee5..e8805a40 100644 --- a/runtime/stream.c +++ b/runtime/stream.c @@ -722,7 +722,7 @@ CODESTARTobjDestruct(strm) free(pThis->pZipBuf); free(pThis->pszCurrFName); free(pThis->pszFName); - + pThis->bStopWriter = 2; /* RG: use as flag for destruction */ ENDobjDestruct(strm) |