1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License (the "License"). 6 * You may not use this file except in compliance with the License. 7 * 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9 * or http://www.opensolaris.org/os/licensing. 10 * See the License for the specific language governing permissions 11 * and limitations under the License. 12 * 13 * When distributing Covered Code, include this CDDL HEADER in each 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15 * If applicable, add the following below this CDDL HEADER, with the 16 * fields enclosed by brackets "[]" replaced with your own identifying 17 * information: Portions Copyright [yyyy] [name of copyright owner] 18 * 19 * CDDL HEADER END 20 */ 21 /* 22 * Copyright 2010 Sun Microsystems, Inc. All rights reserved. 23 * Use is subject to license terms. 24 */ 25 26 #include <pthread.h> 27 #include <memory.h> 28 #include "queue.h" 29 #include <stdio.h> 30 #include <assert.h> 31 #include "plugin.h" 32 33 #define DEBUG 0 34 35 #if DEBUG 36 extern FILE *dbfp; 37 extern FILE *__auditd_debug_file_open(); 38 #define DPRINT(x) { (void) fprintf x; } 39 #else 40 #define DPRINT(x) 41 #endif 42 43 void 44 audit_queue_init(au_queue_t *q) 45 { 46 q->auq_head = NULL; 47 q->auq_tail = NULL; 48 (void) pthread_mutex_init(&q->auq_lock, NULL); 49 q->auq_count = 0; 50 #if DEBUG 51 if (dbfp == NULL) { 52 dbfp = __auditd_debug_file_open(); 53 } 54 #endif 55 } 56 57 /* 58 * enqueue() caller creates queue entry 59 */ 60 61 void 62 audit_enqueue(au_queue_t *q, void *p) 63 { 64 (void) pthread_mutex_lock(&q->auq_lock); 65 66 DPRINT((dbfp, "enqueue0(%p): p=%p, head=%p, tail=%p, count=%d\n", 67 (void *)q, (void *)p, (void *)q->auq_head, (void *)q->auq_tail, 68 q->auq_count)); 69 70 if (q->auq_head == NULL) 71 q->auq_head = p; 72 else { 73 DPRINT((dbfp, "\tindirect tail=%p\n", 74 (void *)&(((audit_link_t *)(q->auq_tail))->aln_next))); 75 76 ((audit_link_t *)(q->auq_tail))->aln_next = p; 77 } 78 q->auq_tail = p; 79 ((audit_link_t *)p)->aln_next = NULL; 80 q->auq_count++; 81 82 DPRINT((dbfp, "enqueue1(%p): p=%p, head=%p, tail=%p, " 83 "count=%d, pnext=%p\n", (void *)q, (void *)p, (void *)q->auq_head, 84 (void *)q->auq_tail, q->auq_count, 85 (void *)((audit_link_t *)p)->aln_next)); 86 87 (void) pthread_mutex_unlock(&q->auq_lock); 88 } 89 90 /* 91 * audit_dequeue() returns entry; caller is responsible for free 92 */ 93 94 int 95 audit_dequeue(au_queue_t *q, void **p) 96 { 97 (void) pthread_mutex_lock(&q->auq_lock); 98 99 if ((*p = q->auq_head) == NULL) { 100 DPRINT((dbfp, "dequeue1(%p): p=%p, head=%p, " 101 "tail=%p, count=%d\n", (void *)q, (void *)*p, 102 (void *)q->auq_head, (void *)q->auq_tail, q->auq_count)); 103 104 (void) pthread_mutex_unlock(&q->auq_lock); 105 return (1); 106 } 107 q->auq_count--; 108 109 /* if *p is the last, next is NULL */ 110 q->auq_head = ((audit_link_t *)*p)->aln_next; 111 112 DPRINT((dbfp, "dequeue0(%p): p=%p, head=%p, tail=%p, " 113 "count=%d, pnext=%p\n", (void *)q, (void *)*p, (void *)q->auq_head, 114 (void *)q->auq_tail, q->auq_count, 115 (void *)((audit_link_t *)*p)->aln_next)); 116 117 (void) pthread_mutex_unlock(&q->auq_lock); 118 return (0); 119 } 120 121 /* 122 * increment ref count 123 */ 124 void 125 audit_incr_ref(pthread_mutex_t *l, audit_rec_t *p) 126 { 127 (void) pthread_mutex_lock(l); 128 p->abq_ref_count++; 129 DPRINT((dbfp, "incr_ref: p=%p, count=%d\n", 130 (void *)p, p->abq_ref_count)); 131 (void) pthread_mutex_unlock(l); 132 } 133 /* 134 * decrement reference count; if it reaches zero, 135 * return a pointer to it. Otherwise, return NULL. 136 */ 137 audit_rec_t * 138 audit_release(pthread_mutex_t *l, audit_rec_t *p) 139 { 140 assert(p != NULL); 141 142 (void) pthread_mutex_lock(l); 143 144 DPRINT((dbfp, "release: p=%p , count=%d\n", 145 (void *)p, p->abq_ref_count)); 146 147 if (--(p->abq_ref_count) > 0) { 148 (void) pthread_mutex_unlock(l); 149 return (NULL); 150 } 151 (void) pthread_mutex_unlock(l); 152 153 return (p); 154 } 155 156 int 157 audit_queue_size(au_queue_t *q) 158 { 159 int size; 160 161 (void) pthread_mutex_lock(&q->auq_lock); 162 size = q->auq_count; 163 (void) pthread_mutex_unlock(&q->auq_lock); 164 165 return (size); 166 } 167 168 169 void 170 audit_queue_destroy(au_queue_t *q) 171 { 172 (void) pthread_mutex_destroy(&q->auq_lock); 173 } 174