[ARCHIVE DEBUG 04/13] audit_debug: add /proc counters for overflows, waiters, recovers, reserves

Richard Guy Briggs rgb at redhat.com
Thu Oct 22 18:58:50 UTC 2015


Add counters to /proc/audit to instrument the wait_for_auditd condition.

Signed-off-by: Richard Guy Briggs <rgb at 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




More information about the Linux-audit mailing list