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 /* 23 * Copyright 2008 Sun Microsystems, Inc. All rights reserved. 24 * Use is subject to license terms. 25 */ 26 27 #pragma ident "%Z%%M% %I% %E% SMI" 28 29 #include <sys/types.h> 30 #include <sys/kmem.h> 31 #include <sys/vnode.h> 32 #include <sys/pathname.h> 33 #include <sys/door.h> 34 #include <sys/cmn_err.h> 35 #include <sys/sunddi.h> /* for string functions */ 36 #include <sys/vscan.h> 37 38 39 /* max time (secs) to wait for door calls to complete during door_close */ 40 #define VS_DOOR_CLOSE_TIMEOUT_DEFAULT 30 41 uint32_t vs_door_close_timeout = VS_DOOR_CLOSE_TIMEOUT_DEFAULT; 42 43 static door_handle_t vscan_door_handle = NULL; 44 static kmutex_t vscan_door_mutex; 45 static kcondvar_t vscan_door_cv; 46 static int vscan_door_call_count = 0; 47 48 49 /* 50 * vscan_door_init 51 */ 52 int 53 vscan_door_init(void) 54 { 55 mutex_init(&vscan_door_mutex, NULL, MUTEX_DEFAULT, NULL); 56 cv_init(&vscan_door_cv, NULL, CV_DEFAULT, NULL); 57 return (0); 58 } 59 60 61 /* 62 * vscan_door_fini 63 */ 64 void 65 vscan_door_fini(void) 66 { 67 mutex_destroy(&vscan_door_mutex); 68 cv_destroy(&vscan_door_cv); 69 } 70 71 72 /* 73 * vscan_door_open 74 */ 75 int 76 vscan_door_open(int door_id) 77 { 78 mutex_enter(&vscan_door_mutex); 79 80 if (vscan_door_handle == NULL) 81 vscan_door_handle = door_ki_lookup(door_id); 82 83 if (vscan_door_handle == NULL) { 84 cmn_err(CE_WARN, "Internal communication error " 85 "- failed to access vscan service daemon."); 86 mutex_exit(&vscan_door_mutex); 87 return (-1); 88 } 89 90 mutex_exit(&vscan_door_mutex); 91 return (0); 92 } 93 94 95 /* 96 * vscan_door_close 97 */ 98 void 99 vscan_door_close(void) 100 { 101 clock_t timeout, time_left; 102 103 mutex_enter(&vscan_door_mutex); 104 105 /* wait for any in-progress requests to complete */ 106 time_left = SEC_TO_TICK(vs_door_close_timeout); 107 while ((vscan_door_call_count > 0) && (time_left > 0)) { 108 timeout = lbolt + time_left; 109 time_left = cv_timedwait(&vscan_door_cv, 110 &vscan_door_mutex, timeout); 111 } 112 113 if (time_left == -1) 114 cmn_err(CE_WARN, "Timeout waiting for door calls to complete"); 115 116 if (vscan_door_handle) { 117 door_ki_rele(vscan_door_handle); 118 vscan_door_handle = NULL; 119 } 120 121 mutex_exit(&vscan_door_mutex); 122 } 123 124 125 /* 126 * vscan_door_scan_file 127 * 128 * Returns: result returned in door response or VS_STATUS_ERROR 129 */ 130 int 131 vscan_door_scan_file(vs_scan_req_t *scan_req) 132 { 133 int err; 134 door_arg_t arg; 135 uint32_t result = 0; 136 137 if (!vscan_door_handle) 138 return (VS_STATUS_ERROR); 139 140 mutex_enter(&vscan_door_mutex); 141 vscan_door_call_count++; 142 mutex_exit(&vscan_door_mutex); 143 144 arg.data_ptr = (char *)scan_req; 145 arg.data_size = sizeof (vs_scan_req_t); 146 arg.desc_ptr = NULL; 147 arg.desc_num = 0; 148 arg.rbuf = (char *)&result; 149 arg.rsize = sizeof (uint32_t); 150 151 if ((err = door_ki_upcall_limited(vscan_door_handle, &arg, NULL, 152 SIZE_MAX, 0)) != 0) { 153 cmn_err(CE_WARN, "Internal communication error (%d)" 154 "- failed to send scan request to vscand", err); 155 result = VS_STATUS_ERROR; 156 } 157 158 mutex_enter(&vscan_door_mutex); 159 vscan_door_call_count--; 160 cv_signal(&vscan_door_cv); 161 mutex_exit(&vscan_door_mutex); 162 163 return (result); 164 } 165