Re: [systemd-devel] systemd-journald doesn't follow max datagram length when forwarding messages to syslog

2014-08-13 Thread Lennart Poettering
On Sun, 10.08.14 21:07, Umut Tezduyar Lindskog (u...@tezduyar.com) wrote:

 The problem is due to sending socket's SO_SNDBUF limit. My guess at
 this point is the amount of messages you can queue to syslog socket is
 determined by 3 factors. a) Sending socket's SO_SNDBUF b) Receiving
 socket's SO_RCVBUF c) Global variable
 /proc/sys/net/unix/max_dgram_qlen.
 
 My workaround is adding SendBuffer=8M to
 systemd-journald-dev-log.socket but I am not sure if the way we
 account things is intuitive. My propose is passing
 systemd-journald-dev-log.socket to systemd-journald so that
 systemd-journald can forward messages to rsyslog through it. Or not
 deal with this since newer rsyslog fetches logs.
 
 References
 https://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/tree/net/unix/af_unix.c#n1445
 http://vger.kernel.org/~davem/skb_sk.html

I have now changed git to also set SendBuffer=8M for the .socket unit.

I must agree though, it's a bit surprising that we use the same socket
here for recieving syslog and forwarding it. 

I was tempted to just add a second socket for the forwarding, that is
internal to journald, and never seen outside. While this appears
cleaner on one hand, it also would require us to either hardcode the
buffer size or come up with a new config setting for it. Neither of
these options are particularly attractive, in particular given that we
can currently just set SendBuffer=8M and be done with it. Hence that's
what I did.

Does that make sense?

Lennart

-- 
Lennart Poettering, Red Hat
___
systemd-devel mailing list
systemd-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/systemd-devel


Re: [systemd-devel] systemd-journald doesn't follow max datagram length when forwarding messages to syslog

2014-08-13 Thread Umut Tezduyar Lindskog
On Wed, Aug 13, 2014 at 6:59 PM, Lennart Poettering
lenn...@poettering.net wrote:
 On Sun, 10.08.14 21:07, Umut Tezduyar Lindskog (u...@tezduyar.com) wrote:

 The problem is due to sending socket's SO_SNDBUF limit. My guess at
 this point is the amount of messages you can queue to syslog socket is
 determined by 3 factors. a) Sending socket's SO_SNDBUF b) Receiving
 socket's SO_RCVBUF c) Global variable
 /proc/sys/net/unix/max_dgram_qlen.

 My workaround is adding SendBuffer=8M to
 systemd-journald-dev-log.socket but I am not sure if the way we
 account things is intuitive. My propose is passing
 systemd-journald-dev-log.socket to systemd-journald so that
 systemd-journald can forward messages to rsyslog through it. Or not
 deal with this since newer rsyslog fetches logs.

 References
 https://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/tree/net/unix/af_unix.c#n1445
 http://vger.kernel.org/~davem/skb_sk.html

 I have now changed git to also set SendBuffer=8M for the .socket unit.

 I must agree though, it's a bit surprising that we use the same socket
 here for recieving syslog and forwarding it.

 I was tempted to just add a second socket for the forwarding, that is
 internal to journald, and never seen outside. While this appears
 cleaner on one hand, it also would require us to either hardcode the
 buffer size or come up with a new config setting for it. Neither of
 these options are particularly attractive, in particular given that we
 can currently just set SendBuffer=8M and be done with it. Hence that's
 what I did.

 Does that make sense?

Thanks. I think it is good enough.


 Lennart

 --
 Lennart Poettering, Red Hat
___
systemd-devel mailing list
systemd-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/systemd-devel


Re: [systemd-devel] systemd-journald doesn't follow max datagram length when forwarding messages to syslog

2014-08-10 Thread Umut Tezduyar Lindskog
On Wed, Aug 6, 2014 at 9:08 PM, Umut Tezduyar Lindskog
u...@tezduyar.com wrote:
 Hi,

 journald fails to forward messages to syslog when it is using
 Server-syslog_fd even before the limit of
 /proc/sys/net/unix/max_dgram_qlen is reached.

 For this experiment,

 1) I have made sure /proc/sys/net/unix/max_dgram_qlen is set to 
 before syslog.socket is created.
 2) Replaced rsyslog.service's ExecStart with /bin/sleep
 3) Booted system and observed following messages:

 systemd-journal[434]: Forwarding to syslog missed 2 messages. (succeed
 274 messages) [*]
 systemd-journal[434]: Forwarding to syslog missed 183 messages.
 (succeed 274 messages)
 systemd-journal[434]: Forwarding to syslog missed 41 messages.
 (succeed 274 messages)

 This got me interested since we are loosing messages and after further
 debugging I have come up with attached patch [**]. After booting up
 the system and filling up the journal with systemd-cat echo hello,
 following correct behavior is observed.

 systemd-journal[449]: Forwarding to syslog missed 1 messages. (succeed
 1 messages)

 It is same hardware and clearly I have enough memory to store 1000
 messages. I can't explain why it would make a difference to use
 Server-syslog_fd vs a new socket fd but something is not right and
 hopefully someone can explain. Further, we can fix journal so we won't
 miss messages.

The problem is due to sending socket's SO_SNDBUF limit. My guess at
this point is the amount of messages you can queue to syslog socket is
determined by 3 factors. a) Sending socket's SO_SNDBUF b) Receiving
socket's SO_RCVBUF c) Global variable
/proc/sys/net/unix/max_dgram_qlen.

My workaround is adding SendBuffer=8M to
systemd-journald-dev-log.socket but I am not sure if the way we
account things is intuitive. My propose is passing
systemd-journald-dev-log.socket to systemd-journald so that
systemd-journald can forward messages to rsyslog through it. Or not
deal with this since newer rsyslog fetches logs.

References
https://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/tree/net/unix/af_unix.c#n1445
http://vger.kernel.org/~davem/skb_sk.html

Umut



 Thank you
 Umut


 [*] The number 274 fluctuates a bit between boots and I patched
 journald to display how many messages have been sent to syslog.
 [**] Patch is only to show proof of concept and not optimized.
___
systemd-devel mailing list
systemd-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/systemd-devel


[systemd-devel] systemd-journald doesn't follow max datagram length when forwarding messages to syslog

2014-08-06 Thread Umut Tezduyar Lindskog
Hi,

journald fails to forward messages to syslog when it is using
Server-syslog_fd even before the limit of
/proc/sys/net/unix/max_dgram_qlen is reached.

For this experiment,

1) I have made sure /proc/sys/net/unix/max_dgram_qlen is set to 
before syslog.socket is created.
2) Replaced rsyslog.service's ExecStart with /bin/sleep
3) Booted system and observed following messages:

systemd-journal[434]: Forwarding to syslog missed 2 messages. (succeed
274 messages) [*]
systemd-journal[434]: Forwarding to syslog missed 183 messages.
(succeed 274 messages)
systemd-journal[434]: Forwarding to syslog missed 41 messages.
(succeed 274 messages)

This got me interested since we are loosing messages and after further
debugging I have come up with attached patch [**]. After booting up
the system and filling up the journal with systemd-cat echo hello,
following correct behavior is observed.

systemd-journal[449]: Forwarding to syslog missed 1 messages. (succeed
1 messages)

It is same hardware and clearly I have enough memory to store 1000
messages. I can't explain why it would make a difference to use
Server-syslog_fd vs a new socket fd but something is not right and
hopefully someone can explain. Further, we can fix journal so we won't
miss messages.

Thank you
Umut


[*] The number 274 fluctuates a bit between boots and I patched
journald to display how many messages have been sent to syslog.
[**] Patch is only to show proof of concept and not optimized.
diff --git a/systemd/src/journal/journald-server.h 
b/systemd/src/journal/journald-server.h
index 42a2235..b4117f7 100644
--- a/systemd/src/journal/journald-server.h
+++ b/systemd/src/journal/journald-server.h
@@ -100,6 +100,7 @@ typedef struct Server {
 bool forward_to_wall;
 
 unsigned n_forward_syslog_missed;
+unsigned n_forward_syslog_success;
 usec_t last_warn_forward_syslog_missed;
 
 uint64_t cached_available_space;
diff --git a/systemd/src/journal/journald-syslog.c 
b/systemd/src/journal/journald-syslog.c
index b826e23..537386f 100644
--- a/systemd/src/journal/journald-syslog.c
+++ b/systemd/src/journal/journald-syslog.c
@@ -37,6 +37,7 @@
 
 static void forward_syslog_iovec(Server *s, const struct iovec *iovec, 
unsigned n_iovec, struct ucred *ucred, struct timeval *tv) {
 
+int fd = -1;
 union sockaddr_union sa = {
 .un.sun_family = AF_UNIX,
 .un.sun_path = /run/systemd/journal/syslog,
@@ -71,12 +72,22 @@ static void forward_syslog_iovec(Server *s, const struct 
iovec *iovec, unsigned
 msghdr.msg_controllen = cmsg-cmsg_len;
 }
 
+fd = socket(AF_UNIX, SOCK_DGRAM|SOCK_CLOEXEC|SOCK_NONBLOCK, 0);
+if (fd  0) {
+log_debug(Failed to create a socket);
+return;
+}
+
+
 /* Forward the syslog message we received via /dev/log to
  * /run/systemd/syslog. Unfortunately we currently can't set
  * the SO_TIMESTAMP auxiliary data, and hence we don't. */
 
-if (sendmsg(s-syslog_fd, msghdr, MSG_NOSIGNAL) = 0)
+if (sendmsg(fd, msghdr, MSG_NOSIGNAL) = 0) {
+s-n_forward_syslog_success++;
+close(fd);
 return;
+   }
 
 /* The socket is full? I guess the syslog implementation is
  * too slow, and we shouldn't wait for that... */
@@ -96,17 +107,22 @@ static void forward_syslog_iovec(Server *s, const struct 
iovec *iovec, unsigned
 u.pid = getpid();
 memcpy(CMSG_DATA(cmsg), u, sizeof(struct ucred));
 
-if (sendmsg(s-syslog_fd, msghdr, MSG_NOSIGNAL) = 0)
+if (sendmsg(fd, msghdr, MSG_NOSIGNAL) = 0) {
+s-n_forward_syslog_success++;
+close(fd);
 return;
+   }
 
 if (errno == EAGAIN) {
 s-n_forward_syslog_missed++;
+close(fd);
 return;
 }
 }
 
 if (errno != ENOENT)
 log_debug(Failed to forward syslog message: %m);
+close(fd);
 }
 
 static void forward_syslog_raw(Server *s, int priority, const char *buffer, 
struct ucred *ucred, struct timeval *tv) {
@@ -492,7 +508,8 @@ void server_maybe_warn_forward_syslog_missed(Server *s) {
 if (s-last_warn_forward_syslog_missed + 
WARN_FORWARD_SYSLOG_MISSED_USEC  n)
 return;
 
-server_driver_message(s, SD_MESSAGE_FORWARD_SYSLOG_MISSED, Forwarding 
to syslog missed %u messages., s-n_forward_syslog_missed);
+server_driver_message(s, SD_MESSAGE_FORWARD_SYSLOG_MISSED, Forwarding 
to syslog missed %u messages. (succeed %u messages), 
s-n_forward_syslog_missed,
+   
  
s-n_forward_syslog_success);