summaryrefslogtreecommitdiff
path: root/regress/usr.sbin/syslogd/args-dropped-sigterm-filesystem.pl
blob: 77cf0387f5f01162c92c100b98aa7158518bcc86 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
# Create a log file on a file system that can be easily filled.
# The client writes messages to Sys::Syslog native method.
# While writing messages, the client fills the log file system.
# After the file system has been filled, send sigterm to syslogd.
# The syslogd writes it into a file and through a pipe and to tty.
# The syslogd passes it via UDP to the loghost.
# The server receives the message on its UDP socket.
# Find the message in client, file, pipe, console, user, syslogd, server log.
# Check that syslogd error 'No space left on device' error is logged to server.
# Check that kernel error 'file system full' error is logged.
# Check that the final 'dropped messages to file' is logged by server.

use strict;
use warnings;
use Errno ':POSIX';
use File::Path qw(remove_tree);
use Time::HiRes;

my @errors = (ENOSPC);
my $errors = "(". join("|", map { $! = $_ } @errors). ")";

my $fspath = "/mnt/regress-syslogd";
my $fslog = "$fspath/file.log";
my $fsbig = "$fspath/big";

remove_tree($fspath, { safe => 1, keep_root => 1 });
open(my $log, '>', $fslog)
    or die "Create $fslog failed: $!";

our %args = (
    client => {
	func => sub { write_between2logs(shift, sub {
	    my $self = shift;
	    open(my $big, '>', $fsbig)
		or die ref($self), " create $fsbig failed: $!";
	    ${$self->{syslogd}}->loggrep(get_firstlog(), 5)
		or die ref($self), " first log not in syslogd log";
	    undef $!;
	    for (my $i = 0; $i < 100000; $i++) {
		syswrite($big, "regress syslogd file system full\n")
		    or last;
	    }
	    $!{ENOSPC}
		or die ref($self), " fill $fsbig failed: $!";
	    # a single message still fits, write 4 KB logs to reach next block
	    write_lines($self, 100, 70);
	    write_lines($self, 9, 1);
	    ${$self->{syslogd}}->loggrep(qr/write to file .* $errors/, 10)
		or die ref($self), " write to file error not in syslogd log";
	    close($big);
	    # wait until syslogd has processed everything
	    write_message($self, get_secondlog());
	    ${$self->{server}}->loggrep(get_secondlog(), 8)
		or die ref($self), " second log not in server log";
	})},
    },
    syslogd => {
	outfile => $fslog,
	loggrep => {
	    get_charlog() => 100,
	},
    },
    server => {
	func => sub {
	    my $self = shift;
	    read_log($self);
	    ${$self->{syslogd}}->kill_syslogd('TERM');
	    ${$self->{syslogd}}->loggrep("syslogd: exited", 5)
		or die ref($self), " no 'syslogd: exited' in syslogd log";
	    read_message($self, "exiting on signal 15");
	},
	loggrep => {
	    get_firstlog() => 1,
	    get_secondlog() => 1,
	    get_testgrep() => 1,
	    qr/syslogd\[\d+\]: start/ => 1,
	    qr/syslogd\[\d+\]: restart/ => 0,
	    qr/syslogd\[\d+\]: write to file "$fslog": /.
		qr/No space left on device/ => '>=1',
	    qr/bsd: .* on $fspath: file system full/ => '>=1',
	    qr/syslogd\[\d+\]: dropped \d+ messages to file$/ => 1,
	},
    },
    file => {
	loggrep => {
	    get_firstlog() => 1,
	    get_testgrep() => 0,
	    qr/syslogd\[\d+\]: write to file "$fslog": /.
		qr/No space left on device/ => 0,
	    qr/syslogd\[\d+\]: dropped \d+ messages to file$/ => 0,
	},
    },
    pipe => { nocheck => 1 },
    tty => { nocheck => 1 },
);

1;