15440Sjm199354 /*
25440Sjm199354 * CDDL HEADER START
35440Sjm199354 *
45440Sjm199354 * The contents of this file are subject to the terms of the
55440Sjm199354 * Common Development and Distribution License (the "License").
65440Sjm199354 * You may not use this file except in compliance with the License.
75440Sjm199354 *
85440Sjm199354 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
95440Sjm199354 * or http://www.opensolaris.org/os/licensing.
105440Sjm199354 * See the License for the specific language governing permissions
115440Sjm199354 * and limitations under the License.
125440Sjm199354 *
135440Sjm199354 * When distributing Covered Code, include this CDDL HEADER in each
145440Sjm199354 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
155440Sjm199354 * If applicable, add the following below this CDDL HEADER, with the
165440Sjm199354 * fields enclosed by brackets "[]" replaced with your own identifying
175440Sjm199354 * information: Portions Copyright [yyyy] [name of copyright owner]
185440Sjm199354 *
195440Sjm199354 * CDDL HEADER END
205440Sjm199354 */
215440Sjm199354
225440Sjm199354 /*
23*11066Srafael.vanoni@sun.com * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
245440Sjm199354 * Use is subject to license terms.
255440Sjm199354 */
265440Sjm199354
275440Sjm199354 #include <sys/types.h>
287943Samw@Sun.COM #include <sys/errno.h>
295440Sjm199354 #include <sys/kmem.h>
305440Sjm199354 #include <sys/vnode.h>
315440Sjm199354 #include <sys/pathname.h>
325440Sjm199354 #include <sys/door.h>
335440Sjm199354 #include <sys/cmn_err.h>
345440Sjm199354 #include <sys/sunddi.h> /* for string functions */
355440Sjm199354 #include <sys/vscan.h>
365440Sjm199354
377943Samw@Sun.COM #define VS_DOOR_RETRIES 3
385440Sjm199354
396407Sjm199354 /* max time (secs) to wait for door calls to complete during door_close */
406407Sjm199354 #define VS_DOOR_CLOSE_TIMEOUT_DEFAULT 30
416407Sjm199354 uint32_t vs_door_close_timeout = VS_DOOR_CLOSE_TIMEOUT_DEFAULT;
426407Sjm199354
435440Sjm199354 static door_handle_t vscan_door_handle = NULL;
445440Sjm199354 static kmutex_t vscan_door_mutex;
455440Sjm199354 static kcondvar_t vscan_door_cv;
465440Sjm199354 static int vscan_door_call_count = 0;
475440Sjm199354
485440Sjm199354
495440Sjm199354 /*
505440Sjm199354 * vscan_door_init
515440Sjm199354 */
525440Sjm199354 int
vscan_door_init(void)535440Sjm199354 vscan_door_init(void)
545440Sjm199354 {
555440Sjm199354 mutex_init(&vscan_door_mutex, NULL, MUTEX_DEFAULT, NULL);
565440Sjm199354 cv_init(&vscan_door_cv, NULL, CV_DEFAULT, NULL);
575440Sjm199354 return (0);
585440Sjm199354 }
595440Sjm199354
605440Sjm199354
615440Sjm199354 /*
625440Sjm199354 * vscan_door_fini
635440Sjm199354 */
645440Sjm199354 void
vscan_door_fini(void)655440Sjm199354 vscan_door_fini(void)
665440Sjm199354 {
675440Sjm199354 mutex_destroy(&vscan_door_mutex);
685440Sjm199354 cv_destroy(&vscan_door_cv);
695440Sjm199354 }
705440Sjm199354
715440Sjm199354
725440Sjm199354 /*
735440Sjm199354 * vscan_door_open
745440Sjm199354 */
755440Sjm199354 int
vscan_door_open(int door_id)765440Sjm199354 vscan_door_open(int door_id)
775440Sjm199354 {
785440Sjm199354 mutex_enter(&vscan_door_mutex);
795440Sjm199354
806407Sjm199354 if (vscan_door_handle == NULL)
815440Sjm199354 vscan_door_handle = door_ki_lookup(door_id);
825440Sjm199354
835440Sjm199354 if (vscan_door_handle == NULL) {
845440Sjm199354 cmn_err(CE_WARN, "Internal communication error "
855440Sjm199354 "- failed to access vscan service daemon.");
866407Sjm199354 mutex_exit(&vscan_door_mutex);
875440Sjm199354 return (-1);
885440Sjm199354 }
895440Sjm199354
906407Sjm199354 mutex_exit(&vscan_door_mutex);
915440Sjm199354 return (0);
925440Sjm199354 }
935440Sjm199354
945440Sjm199354
955440Sjm199354 /*
965440Sjm199354 * vscan_door_close
975440Sjm199354 */
985440Sjm199354 void
vscan_door_close(void)995440Sjm199354 vscan_door_close(void)
1005440Sjm199354 {
1016407Sjm199354 clock_t timeout, time_left;
1026407Sjm199354
1035440Sjm199354 mutex_enter(&vscan_door_mutex);
1045440Sjm199354
1055440Sjm199354 /* wait for any in-progress requests to complete */
1066407Sjm199354 time_left = SEC_TO_TICK(vs_door_close_timeout);
1076407Sjm199354 while ((vscan_door_call_count > 0) && (time_left > 0)) {
108*11066Srafael.vanoni@sun.com timeout = time_left;
109*11066Srafael.vanoni@sun.com time_left = cv_reltimedwait(&vscan_door_cv, &vscan_door_mutex,
110*11066Srafael.vanoni@sun.com timeout, TR_CLOCK_TICK);
1115440Sjm199354 }
1125440Sjm199354
1136407Sjm199354 if (time_left == -1)
1146407Sjm199354 cmn_err(CE_WARN, "Timeout waiting for door calls to complete");
1156407Sjm199354
1165440Sjm199354 if (vscan_door_handle) {
1175440Sjm199354 door_ki_rele(vscan_door_handle);
1185440Sjm199354 vscan_door_handle = NULL;
1195440Sjm199354 }
1205440Sjm199354
1215440Sjm199354 mutex_exit(&vscan_door_mutex);
1225440Sjm199354 }
1235440Sjm199354
1245440Sjm199354
1255440Sjm199354 /*
1265440Sjm199354 * vscan_door_scan_file
1276407Sjm199354 *
1286407Sjm199354 * Returns: result returned in door response or VS_STATUS_ERROR
1295440Sjm199354 */
1305440Sjm199354 int
vscan_door_scan_file(vs_scan_req_t * scan_req)1315440Sjm199354 vscan_door_scan_file(vs_scan_req_t *scan_req)
1325440Sjm199354 {
1336407Sjm199354 int err;
1347943Samw@Sun.COM int i;
1355440Sjm199354 door_arg_t arg;
1366407Sjm199354 uint32_t result = 0;
1375440Sjm199354
1386407Sjm199354 if (!vscan_door_handle)
1396407Sjm199354 return (VS_STATUS_ERROR);
1405440Sjm199354
1415440Sjm199354 mutex_enter(&vscan_door_mutex);
1425440Sjm199354 vscan_door_call_count++;
1435440Sjm199354 mutex_exit(&vscan_door_mutex);
1445440Sjm199354
1455440Sjm199354 arg.data_ptr = (char *)scan_req;
1465440Sjm199354 arg.data_size = sizeof (vs_scan_req_t);
1475440Sjm199354 arg.desc_ptr = NULL;
1485440Sjm199354 arg.desc_num = 0;
1496407Sjm199354 arg.rbuf = (char *)&result;
1506407Sjm199354 arg.rsize = sizeof (uint32_t);
1515440Sjm199354
1527943Samw@Sun.COM for (i = 0; i < VS_DOOR_RETRIES; ++i) {
1537943Samw@Sun.COM if ((err = door_ki_upcall_limited(vscan_door_handle, &arg,
1547943Samw@Sun.COM NULL, SIZE_MAX, 0)) == 0)
1557943Samw@Sun.COM break;
1567943Samw@Sun.COM
1577943Samw@Sun.COM if (err != EAGAIN && err != EINTR)
1587943Samw@Sun.COM break;
1597943Samw@Sun.COM }
1607943Samw@Sun.COM
1617943Samw@Sun.COM if (err != 0) {
1625440Sjm199354 cmn_err(CE_WARN, "Internal communication error (%d)"
1635440Sjm199354 "- failed to send scan request to vscand", err);
1646407Sjm199354 result = VS_STATUS_ERROR;
1655440Sjm199354 }
1665440Sjm199354
1675440Sjm199354 mutex_enter(&vscan_door_mutex);
1685440Sjm199354 vscan_door_call_count--;
1695440Sjm199354 cv_signal(&vscan_door_cv);
1705440Sjm199354 mutex_exit(&vscan_door_mutex);
1715440Sjm199354
1726407Sjm199354 return (result);
1735440Sjm199354 }
174