11460 logadm docmd() can't handle too much on stderr

Review Request #2178 — Created July 13, 2019 and submitted — Latest diff uploaded

mgerdts
illumos-gate
general

When a process called by logadm generates more data on stderr than a pipe can hold, logadm becomes deadlocked waiting for its child to die while the child waits for logadm to free some space in the pipe. Since logadm holds a lock on the logadm config file during this time, it effectively draws all log rotation to a halt.

Reproduced with:

# rm -f /var/tmp/foo.log*

# echo stuff > /var/tmp/foo.log

# logadm -v -p now -b 'exec 1>&2; for i in {1..2500}; do echo $i blah blah blah; done' /var/tmp/foo.log

When the last command is run under truss you can see how it is hanging:

# logadm -v -p now -b 'exec 1>&2; for i in {1..2500}; do echo $i blah blah blah; done' /var/tmp/foo.log
...
16503:  write(1, " 8 6 8   b l a h   b l a".., 19)  = 19
16502:  waitid(P_PID, 16503, 0x0803EFE0, WEXITED|WTRAPPED) (sleeping...)
16503:  write(1, 0x0894D3E0, 19)    (sleeping...)

With the fix:

# rm -f /var/tmp/foo.log*

# echo stuff > /var/tmp/foo.log

# logadm -v -p now -b 'exec 1>&2; for i in {1..2500}; do echo $i blah blah blah; done' /var/tmp/foo.log
...
2499 blah blah blah
2500 blah blah blah
mkdir -p /var/tmp # verify directory exists
mv -f /var/tmp/foo.log /var/tmp/foo.log.0 # rotate log file
touch /var/tmp/foo.log
chown 0:0 /var/tmp/foo.log
chmod 644 /var/tmp/foo.log
#     recording rotation date Sat Jul 13 15:46:39 2019 for /var/tmp/foo.log
# writing changes to /var/logadm/timestampsIMaOsc
Loading...