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]
22 * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
23 * Use is subject to license terms.
26 #pragma ident "%Z%%M% %I% %E% SMI"
29 * Implementation of the vscan statistics interface
40 #include <auth_attr.h>
48 static vs_stats_t vscan_stats
;
49 static int vs_stats_door_cookie
;
50 static int vs_stats_door_fd
= -1;
51 static pthread_mutex_t vs_stats_mutex
= PTHREAD_MUTEX_INITIALIZER
;
54 /* function prototype */
55 static int vs_stats_check_auth(void);
56 static void vs_stats_reset(void);
57 static void vs_stats_door_call(void *, char *, size_t, door_desc_t
*, uint_t
);
63 * Invoked on daemon load and unload
68 (void) pthread_mutex_lock(&vs_stats_mutex
);
70 (void) memset(&vscan_stats
, 0, sizeof (vs_stats_t
));
72 /* door initialization */
73 if ((vs_stats_door_fd
= door_create(vs_stats_door_call
,
74 &vs_stats_door_cookie
, (DOOR_UNREF
| DOOR_REFUSE_DESC
))) < 0) {
75 vs_stats_door_fd
= -1;
77 (void) fdetach(VS_STATS_DOOR_NAME
);
78 if (fattach(vs_stats_door_fd
, VS_STATS_DOOR_NAME
) < 0) {
79 (void) door_revoke(vs_stats_door_fd
);
80 vs_stats_door_fd
= -1;
84 (void) pthread_mutex_unlock(&vs_stats_mutex
);
86 return ((vs_stats_door_fd
== -1) ? -1 : 0);
93 * Invoked on daemon unload
98 (void) pthread_mutex_lock(&vs_stats_mutex
);
100 /* door termination */
101 if (vs_stats_door_fd
!= -1)
102 (void) door_revoke(vs_stats_door_fd
);
103 vs_stats_door_fd
= -1;
105 (void) fdetach(VS_STATS_DOOR_NAME
);
106 (void) unlink(VS_STATS_DOOR_NAME
);
108 (void) pthread_mutex_unlock(&vs_stats_mutex
);
113 * vs_stats_check_auth
115 * Returns: 0 caller authorized to reset stats
116 * -1 caller not authorized to reset stats
119 vs_stats_check_auth()
125 if (door_ucred(&uc
) != 0)
128 if (((uid
= ucred_getsuid(uc
)) == (uid_t
)-1) ||
129 ((pw
= getpwuid(uid
)) == NULL
) ||
130 (chkauthattr(VS_VALUE_AUTH
, pw
->pw_name
) != 1)) {
145 vs_stats_door_call(void *cookie
, char *ptr
, size_t size
, door_desc_t
*dp
,
148 /* LINTED E_BAD_PTR_CAST_ALIGN */
149 vs_stats_req_t
*req
= (vs_stats_req_t
*)ptr
;
152 if ((cookie
!= &vs_stats_door_cookie
) ||
154 (size
!= sizeof (vs_stats_req_t
)) ||
155 (req
->vsr_magic
!= VS_STATS_DOOR_MAGIC
)) {
159 rsp
.vsr_magic
= VS_STATS_DOOR_MAGIC
;
161 switch (req
->vsr_id
) {
163 (void) pthread_mutex_lock(&vs_stats_mutex
);
164 rsp
.vsr_stats
= vscan_stats
;
165 (void) pthread_mutex_unlock(&vs_stats_mutex
);
166 (void) door_return((char *)&rsp
, sizeof (vs_stats_rsp_t
),
172 (void) door_return(NULL
, 0, NULL
, 0);
184 * Reset totals and per-engine statistics to 0
191 if (vs_stats_check_auth() != 0)
194 (void) pthread_mutex_lock(&vs_stats_mutex
);
196 vscan_stats
.vss_scanned
= 0;
197 vscan_stats
.vss_infected
= 0;
198 vscan_stats
.vss_cleaned
= 0;
199 vscan_stats
.vss_failed
= 0;
201 for (i
= 0; i
< VS_SE_MAX
; i
++)
202 vscan_stats
.vss_eng
[i
].vss_errors
= 0;
204 (void) pthread_mutex_unlock(&vs_stats_mutex
);
211 * Update scan request stats
214 vs_stats_set(int retval
)
216 (void) pthread_mutex_lock(&vs_stats_mutex
);
219 case VS_RESULT_CLEAN
:
220 vscan_stats
.vss_scanned
++;
222 case VS_RESULT_CLEANED
:
223 vscan_stats
.vss_scanned
++;
224 vscan_stats
.vss_infected
++;
225 vscan_stats
.vss_cleaned
++;
227 case VS_RESULT_FORBIDDEN
:
228 vscan_stats
.vss_scanned
++;
229 vscan_stats
.vss_infected
++;
231 case VS_RESULT_SE_ERROR
:
232 case VS_RESULT_ERROR
:
234 vscan_stats
.vss_failed
++;
238 (void) pthread_mutex_unlock(&vs_stats_mutex
);
245 * Increment the error count stat for eng
248 vs_stats_eng_err(char *engid
)
252 (void) pthread_mutex_lock(&vs_stats_mutex
);
254 for (i
= 0; i
< VS_SE_MAX
; i
++) {
255 if (*(vscan_stats
.vss_eng
[i
].vss_engid
) == 0)
258 if (strcmp(vscan_stats
.vss_eng
[i
].vss_engid
, engid
) == 0) {
259 ++(vscan_stats
.vss_eng
[i
].vss_errors
);
264 (void) pthread_mutex_unlock(&vs_stats_mutex
);
272 vs_stats_config(vs_props_all_t
*config
)
275 char *engid
, *previd
;
278 (void) pthread_mutex_lock(&vs_stats_mutex
);
280 (void) memcpy(&prev
, &vscan_stats
, sizeof (vs_stats_t
));
281 (void) memset(&vscan_stats
.vss_eng
, 0, sizeof (vscan_stats
.vss_eng
));
283 for (i
= 0; i
< VS_SE_MAX
; i
++) {
284 engid
= config
->va_se
[i
].vep_engid
;
288 (void) strlcpy(vscan_stats
.vss_eng
[i
].vss_engid
, engid
,
291 /* find previous error count for engid */
292 for (j
= 0; j
< VS_SE_MAX
; j
++) {
293 previd
= prev
.vss_eng
[j
].vss_engid
;
294 if (strcmp(previd
, engid
) == 0) {
295 vscan_stats
.vss_eng
[i
].vss_errors
=
296 prev
.vss_eng
[j
].vss_errors
;
302 (void) pthread_mutex_unlock(&vs_stats_mutex
);