BUG/MINOR: log: make sure writev() is not interrupted on a file output
Since 1.9 we support sending logs to various non-blocking outputs like stdou/stderr or flies, by using writev() which guarantees that it only returns after having written everything or nothing. However the syscall may be interrupted while doing so, and this is visible when writing to a tty during debug sessions, as some logs occasionally appear interleaved if an xterm or SSH connection is not very fast. Performance here is not a critical concern, log correctness is. Let's simply take the logger's lock around the writev() call to prevent multiple senders from stepping onto each other's toes. This may be backported to 2.0 and 1.9.
This commit is contained in:
parent
7859526fd6
commit
9fbcb7e2e9
|
@ -1672,8 +1672,15 @@ static inline void __do_send_log(struct logsrv *logsrv, int nblogger, char *pid_
|
||||||
iovec[7].iov_len = 1;
|
iovec[7].iov_len = 1;
|
||||||
|
|
||||||
if (logsrv->addr.ss_family == AF_UNSPEC) {
|
if (logsrv->addr.ss_family == AF_UNSPEC) {
|
||||||
/* the target is a direct file descriptor */
|
/* the target is a direct file descriptor. While writev() guarantees
|
||||||
|
* to write everything, it doesn't guarantee that it will not be
|
||||||
|
* interrupted while doing so. This occasionally results in interleaved
|
||||||
|
* messages when the output is a tty, hence the lock. There's no real
|
||||||
|
* performance concern here for such type of output.
|
||||||
|
*/
|
||||||
|
HA_SPIN_LOCK(LOGSRV_LOCK, &logsrv->lock);
|
||||||
sent = writev(*plogfd, iovec, 8);
|
sent = writev(*plogfd, iovec, 8);
|
||||||
|
HA_SPIN_UNLOCK(LOGSRV_LOCK, &logsrv->lock);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
msghdr.msg_name = (struct sockaddr *)&logsrv->addr;
|
msghdr.msg_name = (struct sockaddr *)&logsrv->addr;
|
||||||
|
|
Loading…
Reference in New Issue