| Summary: | Flood of syslog() calls temporarily blocks process | ||
|---|---|---|---|
| Product: | uClibc | Reporter: | Martin Lottermoser <mjl-s> |
| Component: | Other | Assignee: | unassigned |
| Status: | NEW --- | ||
| Severity: | normal | CC: | uclibc-cvs |
| Priority: | P5 | ||
| Version: | 0.9.33.2 | ||
| Target Milestone: | --- | ||
| Hardware: | All | ||
| OS: | Linux | ||
| Host: | Target: | ||
| Build: | |||
On an AMD-Elan-based system with Linux 2.6.32 and uClibc 0.9.33.2, a flood of syslog() calls in a real-time process led to the process freezing up for about two seconds. This was caused by the following code in libc/misc/syslog/sylog.c, vsyslog(): write_err: /* * Output the message to the console; don't worry about blocking, * if console blocks everything will. Make sure the error reported * is the one from the syslogd failure. */ /* should mode be O_WRONLY | O_NOCTTY? -- Uli */ /* yes, but in Linux "/dev/console" never becomes ctty anyway -- vda */ if ((LogStat & LOG_CONS) && (fd = open(_PATH_CONSOLE, O_WRONLY | O_NOCTTY)) >= 0) { p = strchr(tbuf, '>') + 1; last_chr[0] = '\r'; last_chr[1] = '\n'; (void)write(fd, p, last_chr - p + 2); (void)close(fd); } The system in question had a serial console, configured for 19.2 kb/s with 8N1. The kernel's internal buffer for that console has a size of UART_XMIT_SIZE, i.e., 4096 bytes. Transmitting 4096 bytes at 19.2 kb/s with 8N1 requires 2.1 seconds. Adding O_NONBLOCK to the open() call above fixed the problem, i.e., the comment a few lines above that call seems unnecessarily optimistic.