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") 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 write_lines($self, 9, 1); 48 ${$self->{syslogd}}->loggrep(qr/write to file .* $errors/, 10) 49 or die ref($self), " write to file error not in syslogd log"; 50 close($big); 51 # wait until syslogd has processed everything 52 write_message($self, get_secondlog()); 53 ${$self->{server}}->loggrep(get_secondlog(), 8) 54 or die ref($self), " second log not in server log"; 55 })}, 56 }, 57 syslogd => { 58 outfile => $fslog, 59 loggrep => { 60 get_charlog() => 100, 61 }, 62 }, 63 server => { 64 func => sub { 65 my $self = shift; 66 read_log($self); 67 ${$self->{syslogd}}->kill_syslogd('TERM'); 68 ${$self->{syslogd}}->loggrep("syslogd: exited", 5) 69 or die ref($self), " no 'syslogd: exited' in syslogd log"; 70 read_message($self, "exiting on signal 15"); 71 }, 72 loggrep => { 73 get_firstlog() => 1, 74 get_secondlog() => 1, 75 get_testgrep() => 1, 76 qr/syslogd\[\d+\]: start/ => 1, 77 qr/syslogd\[\d+\]: restart/ => 0, 78 qr/syslogd\[\d+\]: write to file "$fslog": /. 79 qr/No space left on device/ => '>=1', 80 qr/bsd: .* on $fspath: file system full/ => '>=1', 81 qr/syslogd\[\d+\]: dropped \d+ messages to file$/ => 1, 82 }, 83 }, 84 file => { 85 loggrep => { 86 get_firstlog() => 1, 87 get_testgrep() => 0, 88 qr/syslogd\[\d+\]: write to file "$fslog": /. 89 qr/No space left on device/ => 0, 90 qr/syslogd\[\d+\]: dropped \d+ messages to file$/ => 0, 91 }, 92 }, 93 pipe => { nocheck => 1 }, 94 tty => { nocheck => 1 }, 95); 96 971; 98