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 2007 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 static int vscan_door_id = -1; 40 static door_handle_t vscan_door_handle = NULL; 41 static kmutex_t vscan_door_mutex; 42 static kcondvar_t vscan_door_cv; 43 static int vscan_door_call_count = 0; 44 45 46 /* 47 * vscan_door_init 48 */ 49 int 50 vscan_door_init(void) 51 { 52 mutex_init(&vscan_door_mutex, NULL, MUTEX_DEFAULT, NULL); 53 cv_init(&vscan_door_cv, NULL, CV_DEFAULT, NULL); 54 return (0); 55 } 56 57 58 /* 59 * vscan_door_fini 60 */ 61 void 62 vscan_door_fini(void) 63 { 64 mutex_destroy(&vscan_door_mutex); 65 cv_destroy(&vscan_door_cv); 66 } 67 68 69 /* 70 * vscan_door_open 71 */ 72 int 73 vscan_door_open(int door_id) 74 { 75 mutex_enter(&vscan_door_mutex); 76 77 if (vscan_door_handle == NULL) { 78 vscan_door_id = door_id; 79 vscan_door_handle = door_ki_lookup(door_id); 80 } 81 82 mutex_exit(&vscan_door_mutex); 83 84 if (vscan_door_handle == NULL) { 85 cmn_err(CE_WARN, "Internal communication error " 86 "- failed to access vscan service daemon."); 87 return (-1); 88 } 89 90 return (0); 91 } 92 93 94 /* 95 * vscan_door_close 96 */ 97 void 98 vscan_door_close(void) 99 { 100 mutex_enter(&vscan_door_mutex); 101 102 /* wait for any in-progress requests to complete */ 103 while (vscan_door_call_count > 0) { 104 cv_wait(&vscan_door_cv, &vscan_door_mutex); 105 } 106 107 if (vscan_door_handle) { 108 door_ki_rele(vscan_door_handle); 109 vscan_door_handle = NULL; 110 } 111 112 mutex_exit(&vscan_door_mutex); 113 } 114 115 116 /* 117 * vscan_door_scan_file 118 */ 119 int 120 vscan_door_scan_file(vs_scan_req_t *scan_req) 121 { 122 int err, rc = 0; 123 door_arg_t arg; 124 125 if (!vscan_door_handle && 126 vscan_door_open(vscan_door_id) != 0) 127 return (-1); 128 129 mutex_enter(&vscan_door_mutex); 130 vscan_door_call_count++; 131 mutex_exit(&vscan_door_mutex); 132 133 arg.data_ptr = (char *)scan_req; 134 arg.data_size = sizeof (vs_scan_req_t); 135 arg.desc_ptr = NULL; 136 arg.desc_num = 0; 137 arg.rbuf = (char *)scan_req; 138 arg.rsize = sizeof (vs_scan_req_t); 139 140 if ((err = door_ki_upcall(vscan_door_handle, &arg)) != 0) { 141 cmn_err(CE_WARN, "Internal communication error (%d)" 142 "- failed to send scan request to vscand", err); 143 vscan_door_close(); 144 rc = -1; 145 } 146 147 mutex_enter(&vscan_door_mutex); 148 vscan_door_call_count--; 149 cv_signal(&vscan_door_cv); 150 mutex_exit(&vscan_door_mutex); 151 152 return (rc); 153 } 154