diff options
author | Rainer Gerhards <rgerhards@adiscon.com> | 2010-04-20 16:03:51 +0200 |
---|---|---|
committer | Rainer Gerhards <rgerhards@adiscon.com> | 2010-04-20 16:03:51 +0200 |
commit | 534e07d738fc5c7f5464ab94a010cc7113dfad2c (patch) | |
tree | 389432aabff3f72aee014452f7b449f41e829315 /plugins | |
parent | 527edddb4646c24fa9a587601cd90d7a57a1fcf0 (diff) | |
parent | 74000ea71eb47c19653e0cd7bbffb83d913c3923 (diff) | |
download | rsyslog-534e07d738fc5c7f5464ab94a010cc7113dfad2c.tar.gz rsyslog-534e07d738fc5c7f5464ab94a010cc7113dfad2c.tar.xz rsyslog-534e07d738fc5c7f5464ab94a010cc7113dfad2c.zip |
Merge branch 'v4-devel' into master
Conflicts:
plugins/imsolaris/imsolaris.c
tests/Makefile.am
Diffstat (limited to 'plugins')
-rw-r--r-- | plugins/imsolaris/imsolaris.c | 236 |
1 files changed, 126 insertions, 110 deletions
diff --git a/plugins/imsolaris/imsolaris.c b/plugins/imsolaris/imsolaris.c index c51a08a3..6b07ba2b 100644 --- a/plugins/imsolaris/imsolaris.c +++ b/plugins/imsolaris/imsolaris.c @@ -102,79 +102,16 @@ static prop_t *pInputName = NULL; /* our inputName currently is always "imuxsock static char *LogName = NULL; /* the log socket name TODO: make configurable! */ - -/* This function receives data from a socket indicated to be ready - * to receive and submits the message received for processing. - * rgerhards, 2007-12-20 - * Interface changed so that this function is passed the array index - * of the socket which is to be processed. This eases access to the - * growing number of properties. -- rgerhards, 2008-08-01 +/* a function to replace the sun logerror() function. + * It generates an error message from the supplied string. The main + * reason for not calling logError directly is that sun_cddl.c does not + * know or has acces to rsyslog objects (namely errmsg) -- and we do not + * want to do this effort. -- rgerhards, 2010-04-19 */ -rsRetVal -solaris_readLog(int fd) +void +imsolaris_logerror(int err, char *errStr) { - DEFiRet; - int iRcvd; - int iMaxLine; - struct strbuf data; - struct strbuf ctl; - struct log_ctl hdr; - int flags; - msg_t *pMsg; - int ret; - uchar bufRcv[4096+1]; - uchar *pRcv = NULL; /* receive buffer */ - char errStr[1024]; - - iMaxLine = glbl.GetMaxLine(); - - /* we optimize performance: if iMaxLine is below 4K (which it is in almost all - * cases, we use a fixed buffer on the stack. Only if it is higher, heap memory - * is used. We could use alloca() to achive a similar aspect, but there are so - * many issues with alloca() that I do not want to take that route. - * rgerhards, 2008-09-02 - */ - if((size_t) iMaxLine < sizeof(bufRcv) - 1) { - pRcv = bufRcv; - } else { - CHKmalloc(pRcv = (uchar*) malloc(sizeof(uchar) * (iMaxLine + 1))); - } - - data.buf = (char*)pRcv; - data.maxlen = iMaxLine; - ctl.maxlen = sizeof (struct log_ctl); - ctl.buf = (caddr_t)&hdr; - flags = 0; - ret = getmsg(fd, &ctl, &data, &flags); - if(ret < 0) { - rs_strerror_r(errno, errStr, sizeof(errStr)); - DBGPRINTF("imsolaris: getmsg() error on fd %d: %s.\n", fd, errStr); - } - DBGPRINTF("imsolaris: getmsg() returns %d\n", ret); - DBGPRINTF("imsolaris: message from log socket: #%d: %s\n", fd, pRcv); - if (1) {//iRcvd > 0) { - CHKiRet(msgConstruct(&pMsg)); - //MsgSetFlowControlType(pMsg, eFLOWCTL_FULL_DELAY); - MsgSetInputName(pMsg, pInputName); - MsgSetRawMsg(pMsg, (char*)pRcv, strlen((char*)pRcv)); - MsgSetHOSTNAME(pMsg, glbl.GetLocalHostName(), ustrlen(glbl.GetLocalHostName())); - pMsg->iFacility = LOG_FAC(hdr.pri); - pMsg->iSeverity = LOG_PRI(hdr.pri); - //pMsg->bParseHOSTNAME = 0; - pMsg->msgFlags = NEEDS_PARSING | NO_PRI_IN_RAW; - CHKiRet(submitMsg(pMsg)); - } else if (iRcvd < 0 && errno != EINTR) { - int en = errno; - rs_strerror_r(en, errStr, sizeof(errStr)); - DBGPRINTF("imsolaris: stream error: %d = %s.\n", errno, errStr); - errmsg.LogError(en, NO_ERRCODE, "imsolaris: stream input error: %s", errStr); - } - -finalize_it: - if(pRcv != NULL && (size_t) iMaxLine >= sizeof(bufRcv) - 1) - free(pRcv); - - RETiRet; + errmsg.LogError(err, RS_RET_ERR_DOOR, "%s", errStr); } @@ -185,10 +122,10 @@ finalize_it: * iteration. * rgerhards, 2010-04-19 */ -static inline void +static void tryRecover(void) { - int tryNum = 0; + int tryNum = 1; int waitsecs; int waitusecs; rsRetVal iRet; @@ -199,17 +136,20 @@ tryRecover(void) while(1) { /* loop broken inside */ iRet = sun_openklog((LogName == NULL) ? PATH_LOG : LogName); if(iRet == RS_RET_OK) { - if(tryNum > 0) { + if(tryNum > 1) { errmsg.LogError(0, iRet, "failure on system log socket recovered."); } break; } /* failure, so sleep a bit. We wait try*10 ms, with a max of 15 seconds */ - if(tryNum == 0) { + if(tryNum == 1) { errmsg.LogError(0, iRet, "failure on system log socket, trying to recover..."); + } waitusecs = tryNum * 10000; waitsecs = waitusecs / 1000000; - if(waitsecs != 15) { + DBGPRINTF("imsolaris: try %d to recover system log socket in %d.%d seconds\n", + tryNum, waitsecs, waitusecs); + if(waitsecs > 15) { waitsecs = 15; waitusecs = 0; } else { @@ -217,21 +157,61 @@ tryRecover(void) } srSleep(waitsecs, waitusecs); ++tryNum; - } } } -/* a function to replace the sun logerror() function. - * It generates an error message from the supplied string. The main - * reason for not calling logError directly is that sun_cddl.c does not - * know or has acces to rsyslog objects (namely errmsg) -- and we do not - * want to do this effort. -- rgerhards, 2010-04-19 +/* This function receives data from a socket indicated to be ready + * to receive and submits the message received for processing. + * rgerhards, 2007-12-20 + * Interface changed so that this function is passed the array index + * of the socket which is to be processed. This eases access to the + * growing number of properties. -- rgerhards, 2008-08-01 */ -void -imsolaris_logerror(int err, char *errStr) +static rsRetVal +readLog(int fd, uchar *pRcv, int iMaxLine) { - errmsg.LogError(err, RS_RET_ERR_DOOR, "%s", errStr); + DEFiRet; + struct strbuf data; + struct strbuf ctl; + struct log_ctl hdr; + int flags; + msg_t *pMsg; + int ret; + char errStr[1024]; + + data.buf = (char*)pRcv; + data.maxlen = iMaxLine; + ctl.maxlen = sizeof (struct log_ctl); + ctl.buf = (caddr_t)&hdr; + flags = 0; + ret = getmsg(fd, &ctl, &data, &flags); + if(ret < 0) { + if(errno == EINTR) { + FINALIZE; + } else { + int en = errno; + rs_strerror_r(errno, errStr, sizeof(errStr)); + DBGPRINTF("imsolaris: stream input error on fd %d: %s.\n", fd, errStr); + errmsg.LogError(en, NO_ERRCODE, "imsolaris: stream input error: %s", errStr); + tryRecover(); + } + } else { + DBGPRINTF("imsolaris: message from log stream %d: %s\n", fd, pRcv); + pRcv[data.len] = '\0'; /* make sure it is a valid C-String */ + CHKiRet(msgConstruct(&pMsg)); + MsgSetInputName(pMsg, pInputName); + MsgSetRawMsg(pMsg, (char*)pRcv, strlen((char*)pRcv)); + MsgSetHOSTNAME(pMsg, glbl.GetLocalHostName(), ustrlen(glbl.GetLocalHostName())); + pMsg->iFacility = LOG_FAC(hdr.pri); + pMsg->iSeverity = LOG_PRI(hdr.pri); + pMsg->bParseHOSTNAME = 0; + pMsg->msgFlags = NEEDS_PARSING | NO_PRI_IN_RAW; + CHKiRet(submitMsg(pMsg)); + } + +finalize_it: + RETiRet; } @@ -248,43 +228,76 @@ getMsgs(int timeout) { DEFiRet; int nfds; + int iMaxLine; + uchar *pRcv = NULL; /* receive buffer */ + uchar bufRcv[4096+1]; char errStr[1024]; - do { - DBGPRINTF("imsolaris: waiting for next message (timeout %d)...\n", timeout); - nfds = poll(&sun_Pfd, 1, timeout); /* wait without timeout */ + iMaxLine = glbl.GetMaxLine(); - /* v5-TODO: here we must check if we should terminante! */ + /* we optimize performance: if iMaxLine is below 4K (which it is in almost all + * cases, we use a fixed buffer on the stack. Only if it is higher, heap memory + * is used. We could use alloca() to achive a similar aspect, but there are so + * many issues with alloca() that I do not want to take that route. + * rgerhards, 2008-09-02 + */ + if((size_t) iMaxLine < sizeof(bufRcv) - 1) { + pRcv = bufRcv; + } else { + CHKmalloc(pRcv = (uchar*) malloc(sizeof(uchar) * (iMaxLine + 1))); + } - if(nfds == 0) { - if(timeout == 0) { - DBGPRINTF("imsolaris: no more messages, getMsgs() terminates\n"); - FINALIZE; - } else { + do { + DBGPRINTF("imsolaris: waiting for next message (timeout %d)...\n", timeout); + if(timeout == 0) { + nfds = poll(&sun_Pfd, 1, timeout); /* wait without timeout */ + + /* v5-TODO: here we must check if we should terminante! */ + + if(nfds == 0) { + if(timeout == 0) { + DBGPRINTF("imsolaris: no more messages, getMsgs() terminates\n"); + FINALIZE; + } else { + continue; + } + } + + if(nfds < 0) { + if(errno != EINTR) { + int en = errno; + rs_strerror_r(en, errStr, sizeof(errStr)); + DBGPRINTF("imsolaris: poll error: %d = %s.\n", errno, errStr); + errmsg.LogError(en, NO_ERRCODE, "imsolaris: poll error: %s", + errStr); + } continue; - } - } - - if(nfds < 0) { - if(errno != EINTR) { - int en = errno; - rs_strerror_r(en, errStr, sizeof(errStr)); - DBGPRINTF("imsolaris: poll error: %d = %s.\n", errno, errStr); - errmsg.LogError(en, NO_ERRCODE, "imsolaris: poll error: %s", errStr); } - continue; - } - if(sun_Pfd.revents & POLLIN) { - solaris_readLog(sun_Pfd.fd); - } else if(sun_Pfd.revents & (POLLNVAL|POLLHUP|POLLERR)) { - tryRecover(); + if(sun_Pfd.revents & POLLIN) { + readLog(sun_Pfd.fd, pRcv, iMaxLine); + } else if(sun_Pfd.revents & (POLLNVAL|POLLHUP|POLLERR)) { + tryRecover(); + } + } else { + /* if we have an infinite wait, we do not use poll at all + * I'd consider this a waste of time. However, I do not totally + * remove the code, as it may be useful if we decide at some + * point to provide a capability to support multiple input streams + * at once (this may be useful for a jail). In that case, the poll() + * loop would be needed, and so it doesn't make much sense to change + * the code to not support it. -- rgerhards, 2010-04-20 + */ + readLog(sun_Pfd.fd, pRcv, iMaxLine); } - } while(1); + } while(1); /* TODO: in v5, we must check the termination predicate */ /* Note: in v4, this code is never reached (our thread will be cancelled) */ finalize_it: + if(pRcv != NULL && (size_t) iMaxLine >= sizeof(bufRcv) - 1) + free(pRcv); + RETiRet; } @@ -333,6 +346,7 @@ CODESTARTafterRun /* do cleanup here */ if(pInputName != NULL) prop.Destruct(&pInputName); + free(LogName); ENDafterRun @@ -370,6 +384,8 @@ CODEmodInit_QueryRegCFSLineHdlr /* register config file handlers */ CHKiRet(omsdRegCFSLineHdlr((uchar *)"resetconfigvariables", 1, eCmdHdlrCustomHandler, resetConfigVariables, NULL, STD_LOADABLE_MODULE_ID)); + CHKiRet(omsdRegCFSLineHdlr((uchar *)"imsolarislogsocketname", 0, eCmdHdlrGetWord, + NULL, &LogName, STD_LOADABLE_MODULE_ID)); ENDmodInit /* vim:set ai: */ |