On Thu, Oct 03, 2002 at 04:09:27PM -0700, Brian Thomas wrote:
On Thu, Oct 03, 2002 at 12:54:41PM +0200, Balazs Scheidler wrote:
Hi,
Thanks for the information you provided.
The problem is that the programs do not send \n at the end of line while syslog-ng expects one for STREAM oriented sources. (such as unix-stream),
This seems like a bug in the packages like cron, I would think. If using a stream source I'd think the daemon would be expected to provide \n's?
libc should do that. there's nothing saying that syslog() calls should be made with a string terminated with NLs.
Earlier versions of syslog-ng took a message as a full message in the following cases: 1) either NL or NUL was found in the incoming stream 2) after a single read and the source is datagram oriented (UDP or unix-dgram) 3) after the incoming buffer is full (specified via log_msg_size())
For stream oriented sources either 1) or 3) must be true. The strace you sent me indicates that some programs do not terminate their messages by '\n'.
Checking out the libc sources shows that libc automatically terminates messages by NL if LOG_PERROR is set, and also adds a \0 at the end of the line if STREAM sockets are used. So both syslog-ng and libc behaviour seems to be correct. Something must be wrong anyway as the strace didn't show terminating NUL characters.
I assumed that you are using unix-stream sources, but this assumption should be true as syslog-ng issues read() instead of recvfrom().
I should have provided my syslog-ng.conf. Here's the sources line:
source src { unix-dgram("/dev/log"); internal(); file("/proc/kmsg" log_prefix("kernel: ")); udp(); };
So no, I'm not using streams, I'm using sockets. And this is interesting, because this was the default .conf that was installed, and from looking at the man page I'd think that should be unix-socket("/dev/log"), right?
hmm... unix-dgram sources should call recvfrom and not read. I verified this and they do indeed use recvfrom. (I've just found a bug in the kernel, it returns bogus sockaddrs from recvfrom on SOCK_DGRAM sockets) I workaround in libol is now available at the end of this message. I've also attached the kernel patch that should fix the problem.
As syslog-ng reads no terminating NUL characters, I think this should be a libc issue. stream sockets should always have line terminations, as it is not guaranteed by the kernel that a single write will be read by single read calls.
I don't know where to submit this bug, to the libc people, or to the cron people?
Assuming that my confusion about unix-dgram vs. unix-stream is just me being confused, and that I'm using streams even when I specify unix-dgram, than I would think this is a cron issue. It seems like they're being sloppy in their logging.
can you check lsof -p <syslogng pid> just to see what fd 3 is ? If it is really a unix-dgram socket, it should not be read by read() syslog-ng should have used recvfrom() instead. On my testbox it correctly used recvfrom. PS: please Cc syslog-ng@lists.balabit.hu in followups. Kernel patch, which fixes the unix domain socket issue (against 2.4.18): --- af_unix.c~ Mon Feb 25 20:38:16 2002 +++ af_unix.c Fri Oct 4 09:46:26 2002 @@ -1392,6 +1392,9 @@ sk->protinfo.af_unix.addr->name, sk->protinfo.af_unix.addr->len); } + else { + ((struct sockaddr *) msg->msg_name)->sa_family = AF_UNIX; + } } static int unix_dgram_recvmsg(struct socket *sock, struct msghdr *msg, int size, Libol patch, which works around the problem above: diff -u -r1.28 io.c --- io.c 16 Sep 2002 08:23:22 -0000 1.28 +++ io.c 4 Oct 2002 08:53:41 -0000 @@ -368,7 +368,16 @@ } for (;;) { - int res = recvfrom(closure->fd, buffer, length, 0, (struct sockaddr *) addr, (socklen_t *) addrlen); + int res; + + res = recvfrom(closure->fd, buffer, length, 0, (struct sockaddr *) addr, (socklen_t *) addrlen); + + if (*addrlen == 2) { + /* HACK: this is a workaround of a Linux 2.2 & 2.4 bug, + * it doesn't return anything sensible in sockaddr buf + */ + ((struct sockaddr *) addr)->sa_family = AF_UNIX; + } if (res == 0) { /* on SOCK_DGRAM protocols 0 returned bytes doesn't mean anything */ -- Bazsi PGP info: KeyID 9AF8D0A9 Fingerprint CD27 CFB0 802C 0944 9CFD 804E C82C 8EB1
participants (1)
-
Balazs Scheidler