Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 9 Aug 2006 00:55:18 GMT
From:      Robert Watson <rwatson@FreeBSD.org>
To:        Perforce Change Reviews <perforce@freebsd.org>
Subject:   PERFORCE change 103480 for review
Message-ID:  <200608090055.k790tI8T077821@repoman.freebsd.org>

next in thread | raw e-mail | index | archive | help
http://perforce.freebsd.org/chv.cgi?CH=103480

Change 103480 by rwatson@rwatson_zoo on 2006/08/09 00:54:57

	Prototype kqueue support for audit pipes.  Untested.

Affected files ...

.. //depot/projects/trustedbsd/audit3/sys/security/audit/audit_pipe.c#26 edit

Differences ...

==== //depot/projects/trustedbsd/audit3/sys/security/audit/audit_pipe.c#26 (text+ko) ====

@@ -172,6 +172,7 @@
 static d_read_t		audit_pipe_read;
 static d_ioctl_t	audit_pipe_ioctl;
 static d_poll_t		audit_pipe_poll;
+static d_kqfilter_t	audit_pipe_kqfilter;
 
 static struct cdevsw	audit_pipe_cdevsw = {
 	.d_version =	D_VERSION,
@@ -181,9 +182,20 @@
 	.d_read =	audit_pipe_read,
 	.d_ioctl =	audit_pipe_ioctl,
 	.d_poll =	audit_pipe_poll,
+	.d_kqfilter =	audit_pipe_kqfilter,
 	.d_name =	AUDIT_PIPE_NAME,
 };
 
+static int	audit_pipe_kqread(struct knote *note, long hint);
+static void	audit_pipe_kqdetach(struct knote *note);
+
+static struct filterops audit_pipe_read_filterops = {
+	.f_isfd =	1,
+	.f_attach =	NULL,
+	.f_detach =	audit_pipe_kqdetach,
+	.f_event =	audit_pipe_kqread,
+};
+
 /*
  * Some global statistics on audit pipes.
  */
@@ -425,6 +437,7 @@
 	ap->ap_inserts++;
 	ap->ap_qlen++;
 	selwakeuppri(&ap->ap_selinfo, PSOCK);
+	KNOTE_LOCKED(&ap->ap_selinfo.si_note, 0);
 	if (ap->ap_flags & AUDIT_PIPE_ASYNC)
 		pgsigio(&ap->ap_sigio, SIGIO, 0);
 }
@@ -520,6 +533,8 @@
 		return (NULL);
 	ap->ap_qlimit = AUDIT_PIPE_QLIMIT_DEFAULT;
 	TAILQ_INIT(&ap->ap_queue);
+	knlist_init(&ap->ap_selinfo.si_note, &audit_pipe_mtx, NULL, NULL,
+	    NULL);
 
 	/*
 	 * Default flags, naflags, and auid-specific preselection settings to
@@ -533,6 +548,9 @@
 	TAILQ_INIT(&ap->ap_preselect_list);
 	ap->ap_preselect_mode = AUDITPIPE_PRESELECT_MODE_TRAIL;
 
+	/*
+	 * Add to global list and update global statistics.
+	 */
 	TAILQ_INSERT_HEAD(&audit_pipe_list, ap, ap_list);
 	audit_pipe_count++;
 	audit_pipe_ever++;
@@ -572,6 +590,7 @@
 
 	audit_pipe_preselect_flush_locked(ap);
 	audit_pipe_flush(ap);
+	knlist_destroy(&ap->ap_selinfo.si_note);
 	TAILQ_REMOVE(&audit_pipe_list, ap, ap_list);
 	free(ap, M_AUDIT_PIPE);
 	audit_pipe_count--;
@@ -946,6 +965,71 @@
 }
 
 /*
+ * Audit pipe kqfilter.
+ */
+static int
+audit_pipe_kqfilter(struct cdev *dev, struct knote *kn)
+{
+	struct audit_pipe *ap;
+
+	ap = dev->si_drv1;
+	KASSERT(ap != NULL, ("audit_pipe_kqfilter: ap == NULL"));
+
+	if (kn->kn_filter != EVFILT_READ)
+		return (EINVAL);
+
+	kn->kn_fop = &audit_pipe_read_filterops;
+	kn->kn_hook = ap;
+
+	mtx_lock(&audit_pipe_mtx);
+	knlist_add(&ap->ap_selinfo.si_note, kn, 1);
+	mtx_unlock(&audit_pipe_mtx);
+	return (0);
+}
+
+/*
+ * Return true if there are records available for reading on the pipe.
+ */
+static int
+audit_pipe_kqread(struct knote *kn, long hint)
+{
+	struct audit_pipe_entry *ape;
+	struct audit_pipe *ap;
+
+	mtx_assert(&audit_pipe_mtx, MA_OWNED);
+
+	ap = (struct audit_pipe *)kn->kn_hook;
+	KASSERT(ap != NULL, ("audit_pipe_kqread: ap == NULL"));
+
+	if (ap->ap_qlen != 0) {
+		ape = TAILQ_FIRST(&ap->ap_queue);
+		KASSERT(ape != NULL, ("audit_pipe_kqread: ape == NULL"));
+
+		kn->kn_data = ape->ape_record_len;
+		return (1);
+	} else {
+		kn->kn_data = 0;
+		return (0);
+	}
+}
+
+/*
+ * Detach kqueue state from audit pipe.
+ */
+static void
+audit_pipe_kqdetach(struct knote *kn)
+{
+	struct audit_pipe *ap;
+
+	ap = (struct audit_pipe *)kn->kn_hook;
+	KASSERT(ap != NULL, ("audit_pipe_kqdetach: ap == NULL"));
+
+	mtx_lock(&audit_pipe_mtx);
+	knlist_remove(&ap->ap_selinfo.si_note, kn, 1);
+	mtx_unlock(&audit_pipe_mtx);
+}
+
+/*
  * Initialize the audit pipe system.
  */
 static void



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200608090055.k790tI8T077821>