blob: efd5ca083dda8e669fcf2660e0af814fae24fd1d [file] [log] [blame]
jm199354911106d2007-11-08 16:09:20 -08001/*
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/*
Rafael Vanonid3d50732009-11-13 01:32:32 -080023 * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
jm199354911106d2007-11-08 16:09:20 -080024 * Use is subject to license terms.
25 */
26
jm199354911106d2007-11-08 16:09:20 -080027#include <sys/types.h>
Alan Wright1843d052008-10-25 14:44:56 -070028#include <sys/errno.h>
jm199354911106d2007-11-08 16:09:20 -080029#include <sys/kmem.h>
30#include <sys/vnode.h>
31#include <sys/pathname.h>
32#include <sys/door.h>
33#include <sys/cmn_err.h>
34#include <sys/sunddi.h> /* for string functions */
35#include <sys/vscan.h>
36
Alan Wright1843d052008-10-25 14:44:56 -070037#define VS_DOOR_RETRIES 3
jm199354911106d2007-11-08 16:09:20 -080038
jm199354bfc848c2008-04-10 17:45:54 -070039/* max time (secs) to wait for door calls to complete during door_close */
40#define VS_DOOR_CLOSE_TIMEOUT_DEFAULT 30
41uint32_t vs_door_close_timeout = VS_DOOR_CLOSE_TIMEOUT_DEFAULT;
42
jm199354911106d2007-11-08 16:09:20 -080043static door_handle_t vscan_door_handle = NULL;
44static kmutex_t vscan_door_mutex;
45static kcondvar_t vscan_door_cv;
46static int vscan_door_call_count = 0;
47
48
49/*
50 * vscan_door_init
51 */
52int
53vscan_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 */
64void
65vscan_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 */
75int
76vscan_door_open(int door_id)
77{
78 mutex_enter(&vscan_door_mutex);
79
jm199354bfc848c2008-04-10 17:45:54 -070080 if (vscan_door_handle == NULL)
jm199354911106d2007-11-08 16:09:20 -080081 vscan_door_handle = door_ki_lookup(door_id);
jm199354911106d2007-11-08 16:09:20 -080082
83 if (vscan_door_handle == NULL) {
84 cmn_err(CE_WARN, "Internal communication error "
85 "- failed to access vscan service daemon.");
jm199354bfc848c2008-04-10 17:45:54 -070086 mutex_exit(&vscan_door_mutex);
jm199354911106d2007-11-08 16:09:20 -080087 return (-1);
88 }
89
jm199354bfc848c2008-04-10 17:45:54 -070090 mutex_exit(&vscan_door_mutex);
jm199354911106d2007-11-08 16:09:20 -080091 return (0);
92}
93
94
95/*
96 * vscan_door_close
97 */
98void
99vscan_door_close(void)
100{
jm199354bfc848c2008-04-10 17:45:54 -0700101 clock_t timeout, time_left;
102
jm199354911106d2007-11-08 16:09:20 -0800103 mutex_enter(&vscan_door_mutex);
104
105 /* wait for any in-progress requests to complete */
jm199354bfc848c2008-04-10 17:45:54 -0700106 time_left = SEC_TO_TICK(vs_door_close_timeout);
107 while ((vscan_door_call_count > 0) && (time_left > 0)) {
Rafael Vanonid3d50732009-11-13 01:32:32 -0800108 timeout = time_left;
109 time_left = cv_reltimedwait(&vscan_door_cv, &vscan_door_mutex,
110 timeout, TR_CLOCK_TICK);
jm199354911106d2007-11-08 16:09:20 -0800111 }
112
jm199354bfc848c2008-04-10 17:45:54 -0700113 if (time_left == -1)
114 cmn_err(CE_WARN, "Timeout waiting for door calls to complete");
115
jm199354911106d2007-11-08 16:09:20 -0800116 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
jm199354bfc848c2008-04-10 17:45:54 -0700127 *
128 * Returns: result returned in door response or VS_STATUS_ERROR
jm199354911106d2007-11-08 16:09:20 -0800129 */
130int
131vscan_door_scan_file(vs_scan_req_t *scan_req)
132{
jm199354bfc848c2008-04-10 17:45:54 -0700133 int err;
Alan Wright1843d052008-10-25 14:44:56 -0700134 int i;
jm199354911106d2007-11-08 16:09:20 -0800135 door_arg_t arg;
jm199354bfc848c2008-04-10 17:45:54 -0700136 uint32_t result = 0;
jm199354911106d2007-11-08 16:09:20 -0800137
jm199354bfc848c2008-04-10 17:45:54 -0700138 if (!vscan_door_handle)
139 return (VS_STATUS_ERROR);
jm199354911106d2007-11-08 16:09:20 -0800140
141 mutex_enter(&vscan_door_mutex);
142 vscan_door_call_count++;
143 mutex_exit(&vscan_door_mutex);
144
145 arg.data_ptr = (char *)scan_req;
146 arg.data_size = sizeof (vs_scan_req_t);
147 arg.desc_ptr = NULL;
148 arg.desc_num = 0;
jm199354bfc848c2008-04-10 17:45:54 -0700149 arg.rbuf = (char *)&result;
150 arg.rsize = sizeof (uint32_t);
jm199354911106d2007-11-08 16:09:20 -0800151
Alan Wright1843d052008-10-25 14:44:56 -0700152 for (i = 0; i < VS_DOOR_RETRIES; ++i) {
153 if ((err = door_ki_upcall_limited(vscan_door_handle, &arg,
154 NULL, SIZE_MAX, 0)) == 0)
155 break;
156
157 if (err != EAGAIN && err != EINTR)
158 break;
159 }
160
161 if (err != 0) {
jm199354911106d2007-11-08 16:09:20 -0800162 cmn_err(CE_WARN, "Internal communication error (%d)"
163 "- failed to send scan request to vscand", err);
jm199354bfc848c2008-04-10 17:45:54 -0700164 result = VS_STATUS_ERROR;
jm199354911106d2007-11-08 16:09:20 -0800165 }
166
167 mutex_enter(&vscan_door_mutex);
168 vscan_door_call_count--;
169 cv_signal(&vscan_door_cv);
170 mutex_exit(&vscan_door_mutex);
171
jm199354bfc848c2008-04-10 17:45:54 -0700172 return (result);
jm199354911106d2007-11-08 16:09:20 -0800173}