1# Create a log file on a file system that can be easily filled. 2# The client writes messages to Sys::Syslog native method. 3# While writing messages, the client fills the log file system. 4# After the file system has been filled, send sigterm to syslogd. 5# The syslogd writes it into a file and through a pipe and to tty. 6# The syslogd passes it via UDP to the loghost. 7# The server receives the message on its UDP socket. 8# Find the message in client, file, pipe, console, user, syslogd, server log. 9# Check that syslogd error 'No space left on device' error is logged to server. 10# Check that kernel error 'file system full' error is logged. 11# Check that the final 'dropped messages to file' is logged by server. 12 13use strict; 14use warnings; 15use Errno ':POSIX'; 16use File::Path qw(remove_tree); 17use Time::HiRes; 18 19my @errors = (ENOSPC); 20my $errors = "(". join("|", map { $! = $_ } @errors). ")"; 21 22my $fspath = "/mnt/regress-syslogd"; 23my $fslog = "$fspath/file.log"; 24my $fsbig = "$fspath/big"; 25 26remove_tree($fspath, { safe => 1, keep_root => 1 }); 27open(my $log, '>', $fslog) 28 or die "Create $fslog failed: $!"; 29 30our %args = ( 31 client => { 32 func => sub { write_between2logs(shift, sub { 33 my $self = shift; 34 open(my $big, '>', $fsbig) 35 or die ref($self), " create $fsbig failed: $!"; 36 ${$self->{syslogd}}->loggrep(get_firstlog(), 5) 37 or die ref($self), " first log not in syslogd log"; 38 undef $!; 39 for (my $i = 0; $i < 100000; $i++) { 40 syswrite($big, "regress syslogd file system full\n", 33) 41 or last; 42 } 43 $!{ENOSPC} 44 or die ref($self), " fill $fsbig failed: $!"; 45 # a single message still fits, write 4 KB logs to reach next block 46 write_lines($self, 100, 70); 47 ${$self->{syslogd}}->loggrep(qr/write to file .* $errors/, 10) 48 or die ref($self), " write to file error not in syslogd log"; 49 close($big); 50 # wait until syslogd has processed everything 51 write_message($self, get_secondlog()); 52 ${$self->{server}}->loggrep(get_secondlog(), 8) 53 or die ref($self), " second log not in server log"; 54 })}, 55 }, 56 syslogd => { 57 outfile => $fslog, 58 loggrep => { 59 get_charlog() => 100, 60 }, 61 }, 62 server => { 63 func => sub { 64 my $self = shift; 65 read_log($self); 66 ${$self->{syslogd}}->kill_syslogd('TERM'); 67 ${$self->{syslogd}}->loggrep("syslogd: exited", 5) 68 or die ref($self), " no 'syslogd: exited' in syslogd log"; 69 read_message($self, "exiting on signal 15"); 70 }, 71 loggrep => { 72 get_firstlog() => 1, 73 get_secondlog() => 1, 74 get_testgrep() => 1, 75 qr/syslogd\[\d+\]: start/ => 1, 76 qr/syslogd\[\d+\]: restart/ => 0, 77 qr/syslogd\[\d+\]: write to file "$fslog": /. 78 qr/No space left on device/ => '>=1', 79 qr/bsd: .* on $fspath: file system full/ => '>=1', 80 qr/syslogd\[\d+\]: dropped \d+ messages to file$/ => 1, 81 }, 82 }, 83 file => { 84 loggrep => { 85 get_firstlog() => 1, 86 get_testgrep() => 0, 87 qr/syslogd\[\d+\]: write to file "$fslog": /. 88 qr/No space left on device/ => 0, 89 qr/syslogd\[\d+\]: dropped \d+ messages to file$/ => 0, 90 }, 91 }, 92 pipe => { nocheck => 1 }, 93 tty => { nocheck => 1 }, 94); 95 961; 97