Add counters to /proc/audit to instrument the wait_for_auditd condition. Signed-off-by: Richard Guy Briggs <r...@redhat.com> --- kernel/audit.c | 24 ++++++++++++++++++++++++ 1 files changed, 24 insertions(+), 0 deletions(-)
diff --git a/kernel/audit.c b/kernel/audit.c index 82df9fd..ffdec0c 100644 --- a/kernel/audit.c +++ b/kernel/audit.c @@ -125,6 +125,10 @@ u32 audit_sig_sid = 0; */ static atomic_t audit_lost = ATOMIC_INIT(0); static atomic_t audit_hold_lost = ATOMIC_INIT(0); +static atomic_t audit_overflows = ATOMIC_INIT(0); +static atomic_t audit_waiters = ATOMIC_INIT(0); +static atomic_t audit_recovers = ATOMIC_INIT(0); +static atomic_t audit_reserves = ATOMIC_INIT(0); /* The netlink socket. */ static struct sock *audit_sock; @@ -1204,6 +1208,10 @@ static int proc_auditstats_show(struct seq_file *m, void *v) seq_printf(m, "audit_skb_queue len_max\t\t%d\n", skb_queue_len_max(&audit_skb_queue)); seq_printf(m, "audit_skb_hold_queue len\t%d\n", skb_queue_len(&audit_skb_hold_queue)); seq_printf(m, "audit_skb_hold_queue len_max\t%d\n", skb_queue_len_max(&audit_skb_hold_queue)); + seq_printf(m, "audit_overflows\t\t\t%d\n", atomic_read(&audit_overflows)); + seq_printf(m, "audit_waiters\t\t\t%d\n", atomic_read(&audit_waiters)); + seq_printf(m, "audit_recovers\t\t\t%d\n", atomic_read(&audit_recovers)); + seq_printf(m, "audit_reserves\t\t\t%d\n", atomic_read(&audit_reserves)); return 0; } @@ -1422,6 +1430,8 @@ struct audit_buffer *audit_log_start(struct audit_context *ctx, gfp_t gfp_mask, /* reserve: Allow atomic callers to go over the normal backlog limit */ int reserve = audit_backlog_limit/16; unsigned long timeout_start = jiffies; + int waiter = 0; + int overflow_counted = 0; if (audit_initialized != AUDIT_INITIALIZED) return NULL; @@ -1434,7 +1444,10 @@ struct audit_buffer *audit_log_start(struct audit_context *ctx, gfp_t gfp_mask, if (ACCESS_ONCE(audit_cmd_mutex.owner) == current || current->tgid == 1 || (audit_pid && audit_pid == current->tgid)) + { gfp_mask &= ~__GFP_WAIT; + atomic_inc(&audit_reserves); + } else reserve = 0; rcu_read_unlock(); @@ -1449,14 +1462,25 @@ struct audit_buffer *audit_log_start(struct audit_context *ctx, gfp_t gfp_mask, while (audit_backlog_limit && skb_queue_len(&audit_skb_queue) > audit_backlog_limit + reserve) { + if (!overflow_counted) { + atomic_inc(&audit_overflows); + overflow_counted = 1; + } if (gfp_mask & __GFP_WAIT && audit_backlog_wait_time) { long sleep_time; + if (!waiter) { + atomic_inc(&audit_waiters); + waiter = 1; + } sleep_time = timeout_start + audit_backlog_wait_time - jiffies; if (sleep_time > 0) { sleep_time = wait_for_auditd(sleep_time); if (audit_pid && sleep_time > 0) + { + atomic_inc(&audit_recovers); continue; + } } } if (audit_rate_check() && printk_ratelimit()) -- 1.7.1 -- Linux-audit mailing list Linux-audit@redhat.com https://www.redhat.com/mailman/listinfo/linux-audit