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.
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.
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]
23 * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
24 * Use is subject to license terms.
27 #include <sys/types.h>
28 #include <sys/errno.h>
30 #include <sys/vnode.h>
31 #include <sys/pathname.h>
33 #include <sys/cmn_err.h>
34 #include <sys/sunddi.h> /* for string functions */
35 #include <sys/vscan.h>
37 #define VS_DOOR_RETRIES 3
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
;
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;
55 mutex_init(&vscan_door_mutex
, NULL
, MUTEX_DEFAULT
, NULL
);
56 cv_init(&vscan_door_cv
, NULL
, CV_DEFAULT
, NULL
);
67 mutex_destroy(&vscan_door_mutex
);
68 cv_destroy(&vscan_door_cv
);
76 vscan_door_open(int door_id
)
78 mutex_enter(&vscan_door_mutex
);
80 if (vscan_door_handle
== NULL
)
81 vscan_door_handle
= door_ki_lookup(door_id
);
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
);
90 mutex_exit(&vscan_door_mutex
);
99 vscan_door_close(void)
101 clock_t timeout
, time_left
;
103 mutex_enter(&vscan_door_mutex
);
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)) {
109 time_left
= cv_reltimedwait(&vscan_door_cv
, &vscan_door_mutex
,
110 timeout
, TR_CLOCK_TICK
);
114 cmn_err(CE_WARN
, "Timeout waiting for door calls to complete");
116 if (vscan_door_handle
) {
117 door_ki_rele(vscan_door_handle
);
118 vscan_door_handle
= NULL
;
121 mutex_exit(&vscan_door_mutex
);
126 * vscan_door_scan_file
128 * Returns: result returned in door response or VS_STATUS_ERROR
131 vscan_door_scan_file(vs_scan_req_t
*scan_req
)
138 if (!vscan_door_handle
)
139 return (VS_STATUS_ERROR
);
141 mutex_enter(&vscan_door_mutex
);
142 vscan_door_call_count
++;
143 mutex_exit(&vscan_door_mutex
);
145 arg
.data_ptr
= (char *)scan_req
;
146 arg
.data_size
= sizeof (vs_scan_req_t
);
149 arg
.rbuf
= (char *)&result
;
150 arg
.rsize
= sizeof (uint32_t);
152 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)
157 if (err
!= EAGAIN
&& err
!= EINTR
)
162 cmn_err(CE_WARN
, "Internal communication error (%d)"
163 "- failed to send scan request to vscand", err
);
164 result
= VS_STATUS_ERROR
;
167 mutex_enter(&vscan_door_mutex
);
168 vscan_door_call_count
--;
169 cv_signal(&vscan_door_cv
);
170 mutex_exit(&vscan_door_mutex
);