1 0 stevel /* 2 0 stevel * CDDL HEADER START 3 0 stevel * 4 0 stevel * The contents of this file are subject to the terms of the 5 4197 paulson * Common Development and Distribution License (the "License"). 6 4197 paulson * You may not use this file except in compliance with the License. 7 0 stevel * 8 0 stevel * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9 0 stevel * or http://www.opensolaris.org/os/licensing. 10 0 stevel * See the License for the specific language governing permissions 11 0 stevel * and limitations under the License. 12 0 stevel * 13 0 stevel * When distributing Covered Code, include this CDDL HEADER in each 14 0 stevel * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15 0 stevel * If applicable, add the following below this CDDL HEADER, with the 16 0 stevel * fields enclosed by brackets "[]" replaced with your own identifying 17 0 stevel * information: Portions Copyright [yyyy] [name of copyright owner] 18 0 stevel * 19 0 stevel * CDDL HEADER END 20 0 stevel */ 21 0 stevel /* 22 10210 Paul * Copyright 2009 Sun Microsystems, Inc. All rights reserved. 23 0 stevel * Use is subject to license terms. 24 0 stevel */ 25 0 stevel 26 0 stevel 27 0 stevel #include <c2/audit.h> 28 0 stevel #include <c2/audit_kernel.h> 29 0 stevel #include <c2/audit_record.h> 30 0 stevel #include <sys/kmem.h> 31 0 stevel #include <sys/param.h> 32 0 stevel #include <sys/systm.h> 33 0 stevel #include <sys/taskq.h> 34 0 stevel #include <sys/t_lock.h> 35 0 stevel #include <sys/thread.h> 36 0 stevel #include <sys/types.h> 37 0 stevel #include <sys/zone.h> 38 0 stevel 39 0 stevel zone_key_t au_zone_key; 40 0 stevel 41 0 stevel /*ARGSUSED*/ 42 0 stevel static void * 43 0 stevel au_zone_init(zoneid_t zone) 44 0 stevel { 45 0 stevel au_kcontext_t *kctx = kmem_zalloc(sizeof (au_kcontext_t), KM_SLEEP); 46 0 stevel static au_kcontext_t *global_kctx = NULL; 47 0 stevel 48 0 stevel /* 49 0 stevel * INGLOBALZONE(curproc) is invalid at this point, so check for 50 0 stevel * zone 0 51 0 stevel */ 52 0 stevel 53 0 stevel if (zone == 0) { 54 0 stevel global_kctx = kctx; 55 4197 paulson global_zone->zone_audit_kctxt = kctx; 56 0 stevel } else { 57 0 stevel kctx->auk_policy = global_kctx->auk_policy; 58 4197 paulson curproc->p_zone->zone_audit_kctxt = kctx; 59 0 stevel } 60 0 stevel kctx->auk_valid = AUK_VALID; 61 0 stevel kctx->auk_zid = zone; 62 0 stevel 63 0 stevel kctx->auk_info.ai_termid.at_type = AU_IPv4; 64 0 stevel kctx->auk_info.ai_auid = AU_NOAUDITID; 65 0 stevel kctx->auk_auditstate = AUC_INIT_AUDIT; 66 0 stevel 67 0 stevel /* setup defaults for audit queue flow control */ 68 0 stevel kctx->auk_queue.hiwater = AQ_HIWATER; 69 0 stevel kctx->auk_queue.lowater = AQ_LOWATER; 70 0 stevel kctx->auk_queue.bufsz = AQ_BUFSZ; 71 0 stevel kctx->auk_queue.buflen = AQ_BUFSZ; 72 0 stevel kctx->auk_queue.delay = AQ_DELAY; 73 0 stevel 74 0 stevel /* statistics per zone */ 75 0 stevel kctx->auk_statistics.as_version = TOKEN_VERSION; 76 7753 Ton kctx->auk_statistics.as_numevent = MAX_KEVENTS; 77 0 stevel 78 0 stevel /* door IO buffer: */ 79 0 stevel kctx->auk_dbuffer = 80 0 stevel kmem_alloc(AU_DBUF_HEADER + kctx->auk_queue.bufsz, KM_SLEEP); 81 0 stevel 82 0 stevel /* locks and cv's */ 83 0 stevel 84 0 stevel mutex_init(&(kctx->auk_eagain_mutex), NULL, MUTEX_DEFAULT, NULL); 85 0 stevel cv_init(&(kctx->auk_eagain_cv), NULL, CV_DRIVER, NULL); 86 0 stevel 87 0 stevel mutex_init(&(kctx->auk_svc_lock), NULL, MUTEX_DEFAULT, NULL); 88 0 stevel 89 0 stevel mutex_init(&(kctx->auk_queue.lock), NULL, MUTEX_DEFAULT, NULL); 90 0 stevel cv_init(&(kctx->auk_queue.write_cv), NULL, CV_DRIVER, NULL); 91 0 stevel cv_init(&(kctx->auk_queue.read_cv), NULL, CV_DRIVER, NULL); 92 0 stevel 93 0 stevel return (kctx); 94 0 stevel } 95 0 stevel 96 0 stevel /*ARGSUSED*/ 97 0 stevel static void 98 0 stevel au_zone_shutdown(zoneid_t zone, void *arg) 99 0 stevel { 100 0 stevel au_kcontext_t *kctx = arg; 101 0 stevel 102 0 stevel if ((kctx->auk_zid == GLOBAL_ZONEID || 103 0 stevel (audit_policy | AUDIT_PERZONE)) && 104 0 stevel (kctx->auk_current_vp != NULL)) 105 0 stevel (void) au_doormsg(kctx, AU_DBUF_SHUTDOWN, NULL); 106 0 stevel 107 0 stevel kctx->auk_valid = AUK_INVALID; 108 0 stevel 109 0 stevel /* shutdown the output thread if it is still running */ 110 0 stevel kctx->auk_auditstate = AUC_NOAUDIT; 111 0 stevel 112 0 stevel if (kctx->auk_output_active) { 113 0 stevel mutex_enter(&(kctx->auk_queue.lock)); 114 0 stevel cv_broadcast(&(kctx->auk_queue.read_cv)); 115 0 stevel mutex_exit(&(kctx->auk_queue.lock)); 116 0 stevel 117 0 stevel taskq_destroy(kctx->auk_taskq); 118 0 stevel } 119 0 stevel } 120 0 stevel 121 0 stevel /*ARGSUSED*/ 122 0 stevel static void 123 0 stevel au_zone_destroy(zoneid_t zone, void *arg) 124 0 stevel { 125 0 stevel au_kcontext_t *kctx = arg; 126 0 stevel 127 0 stevel ASSERT(kctx->auk_auditstate == AUC_NOAUDIT); 128 0 stevel 129 0 stevel mutex_destroy(&(kctx->auk_eagain_mutex)); 130 0 stevel cv_destroy(&(kctx->auk_eagain_cv)); 131 0 stevel 132 0 stevel mutex_destroy(&(kctx->auk_svc_lock)); 133 0 stevel 134 0 stevel mutex_enter(&(kctx->auk_queue.lock)); 135 0 stevel if (kctx->auk_queue.head != NULL) { 136 0 stevel au_free_rec(kctx->auk_queue.head); 137 0 stevel } 138 0 stevel mutex_exit(&(kctx->auk_queue.lock)); 139 0 stevel 140 0 stevel mutex_destroy(&(kctx->auk_queue.lock)); 141 0 stevel 142 0 stevel cv_destroy(&(kctx->auk_queue.write_cv)); 143 0 stevel cv_destroy(&(kctx->auk_queue.read_cv)); 144 0 stevel 145 0 stevel kmem_free(kctx->auk_dbuffer, AU_DBUF_HEADER + kctx->auk_queue.bufsz); 146 0 stevel 147 0 stevel kmem_free(kctx, sizeof (au_kcontext_t)); 148 0 stevel } 149 0 stevel 150 0 stevel void 151 0 stevel au_zone_setup() 152 0 stevel { 153 0 stevel zone_key_create(&au_zone_key, au_zone_init, au_zone_shutdown, 154 0 stevel au_zone_destroy); 155 0 stevel 156 0 stevel } 157