summaryrefslogtreecommitdiffstats
path: root/misc-utils/logger.c
diff options
context:
space:
mode:
authorKarel Zak2017-10-10 13:56:30 +0200
committerKarel Zak2017-10-10 13:56:30 +0200
commitcaf6ac6e596b09615b5f4bffe588ec1268d8c596 (patch)
tree5ab43467a27165e8d59f4105580e8f575c81eb24 /misc-utils/logger.c
parentMerge branch 'mount-typo' of https://github.com/Liam-Ryan/util-linux (diff)
downloadkernel-qcow2-util-linux-caf6ac6e596b09615b5f4bffe588ec1268d8c596.tar.gz
kernel-qcow2-util-linux-caf6ac6e596b09615b5f4bffe588ec1268d8c596.tar.xz
kernel-qcow2-util-linux-caf6ac6e596b09615b5f4bffe588ec1268d8c596.zip
logger: reconnect on failed send()
The libc syslog() reconnects on failed send(). We need the same thing as logger(1) is expected as long time running tool. For example recommended Apache configuration is: ErrorLog "| /usr/bin/logger -t apache_error -p local6.debug" The issue is that connection endpoint (e.g. syslogd) maybe restarted. The simple way how to test is: for i in $(seq 0 3600); do echo "This is message number $i"; sleep 1; done | logger --tcp --server 127.0.0.1 --port 514 and restart your syslog. The current implementation gets SIGPIPE or write warning message, but it never reconnect. Addresses: https://github.com/karelzak/util-linux/issues/363 Signed-off-by: Karel Zak <kzak@redhat.com>
Diffstat (limited to 'misc-utils/logger.c')
-rw-r--r--misc-utils/logger.c47
1 files changed, 38 insertions, 9 deletions
diff --git a/misc-utils/logger.c b/misc-utils/logger.c
index 5e98d0144..f8dbb2cef 100644
--- a/misc-utils/logger.c
+++ b/misc-utils/logger.c
@@ -139,6 +139,8 @@ struct logger_ctl {
octet_count:1; /* use RFC6587 octet counting */
};
+static void logger_reopen(struct logger_ctl *ctl);
+
/*
* For tests we want to be able to control datetime outputs
*/
@@ -425,7 +427,7 @@ static char const *rfc3164_current_time(void)
* it is too much for the logger utility. If octet-counting is
* selected, we use that.
*/
-static void write_output(const struct logger_ctl *ctl, const char *const msg)
+static void write_output(struct logger_ctl *ctl, const char *const msg)
{
struct iovec iov[4];
int iovlen = 0;
@@ -482,9 +484,18 @@ static void write_output(const struct logger_ctl *ctl, const char *const msg)
cred->pid = ctl->pid;
}
#endif
+ /* Note that logger(1) maybe executed for long time (as pipe
+ * reader) and connection endpoint (syslogd) may be restarted.
+ *
+ * The libc syslog() function reconnects on failed send().
+ * Let's do the same to be robust. [kzak -- Oct 2017]
+ */
- if (sendmsg(ctl->fd, &message, 0) < 0)
- warn(_("send message failed"));
+ if (sendmsg(ctl->fd, &message, MSG_NOSIGNAL) < 0) {
+ logger_reopen(ctl);
+ if (sendmsg(ctl->fd, &message, MSG_NOSIGNAL) < 0)
+ warn(_("send message failed"));
+ }
}
if (ctl->stderr_printout) {
@@ -865,26 +876,44 @@ static void generate_syslog_header(struct logger_ctl *const ctl)
ctl->syslogfp(ctl);
}
-static void logger_open(struct logger_ctl *ctl)
+/* just open, nothing else */
+static void __logger_open(struct logger_ctl *ctl)
{
if (ctl->server) {
ctl->fd = inet_socket(ctl->server, ctl->port, &ctl->socket_type);
- if (!ctl->syslogfp)
- ctl->syslogfp = syslog_rfc5424_header;
} else {
if (!ctl->unix_socket)
ctl->unix_socket = _PATH_DEVLOG;
ctl->fd = unix_socket(ctl, ctl->unix_socket, &ctl->socket_type);
- if (!ctl->syslogfp)
- ctl->syslogfp = syslog_local_header;
}
+}
+
+/* open and initialize relevant @ctl tuff */
+static void logger_open(struct logger_ctl *ctl)
+{
+ __logger_open(ctl);
+
+ if (!ctl->syslogfp)
+ ctl->syslogfp = ctl->server ? syslog_rfc5424_header :
+ syslog_local_header;
if (!ctl->tag)
ctl->tag = xgetlogin();
+
generate_syslog_header(ctl);
}
-static void logger_command_line(const struct logger_ctl *ctl, char **argv)
+/* re-open; usually after failed connection */
+static void logger_reopen(struct logger_ctl *ctl)
+{
+ if (ctl->fd != -1)
+ close(ctl->fd);
+ ctl->fd = -1;
+
+ __logger_open(ctl);
+}
+
+static void logger_command_line(struct logger_ctl *ctl, char **argv)
{
/* note: we never re-generate the syslog header here, even if we
* generate multiple messages. If so, we think it is the right thing