xref: /titanic_50/usr/src/cmd/vscan/vscand/vs_main.c (revision 8d7e41661dc4633488e93b13363137523ce59977)
1911106dfSjm199354 /*
2911106dfSjm199354  * CDDL HEADER START
3911106dfSjm199354  *
4911106dfSjm199354  * The contents of this file are subject to the terms of the
5911106dfSjm199354  * Common Development and Distribution License (the "License").
6911106dfSjm199354  * You may not use this file except in compliance with the License.
7911106dfSjm199354  *
8911106dfSjm199354  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9911106dfSjm199354  * or http://www.opensolaris.org/os/licensing.
10911106dfSjm199354  * See the License for the specific language governing permissions
11911106dfSjm199354  * and limitations under the License.
12911106dfSjm199354  *
13911106dfSjm199354  * When distributing Covered Code, include this CDDL HEADER in each
14911106dfSjm199354  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15911106dfSjm199354  * If applicable, add the following below this CDDL HEADER, with the
16911106dfSjm199354  * fields enclosed by brackets "[]" replaced with your own identifying
17911106dfSjm199354  * information: Portions Copyright [yyyy] [name of copyright owner]
18911106dfSjm199354  *
19911106dfSjm199354  * CDDL HEADER END
20911106dfSjm199354  */
21911106dfSjm199354 /*
22bfc848c6Sjm199354  * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
23911106dfSjm199354  * Use is subject to license terms.
24911106dfSjm199354  */
25911106dfSjm199354 
26911106dfSjm199354 /*
27911106dfSjm199354  * vscand Daemon Program
28911106dfSjm199354  */
29911106dfSjm199354 
30911106dfSjm199354 #include <stdio.h>
31911106dfSjm199354 #include <sys/stat.h>
32911106dfSjm199354 #include <sys/filio.h>
33911106dfSjm199354 #include <sys/types.h>
34911106dfSjm199354 #include <sys/socket.h>
35911106dfSjm199354 #include <sys/ioctl.h>
36911106dfSjm199354 #include <sys/param.h>
37911106dfSjm199354 #include <zone.h>
38911106dfSjm199354 #include <tsol/label.h>
39911106dfSjm199354 #include <string.h>
40911106dfSjm199354 #include <stdlib.h>
41911106dfSjm199354 #include <fcntl.h>
42911106dfSjm199354 #include <wait.h>
43911106dfSjm199354 #include <unistd.h>
44911106dfSjm199354 #include <getopt.h>
45911106dfSjm199354 #include <stdarg.h>
46911106dfSjm199354 #include <libscf.h>
47911106dfSjm199354 #include <signal.h>
48*8d7e4166Sjose borrego #include <atomic.h>
49911106dfSjm199354 #include <libintl.h>
50911106dfSjm199354 #include <netinet/in.h>
51911106dfSjm199354 #include <arpa/inet.h>
52911106dfSjm199354 #include <ctype.h>
53911106dfSjm199354 #include <pthread.h>
54911106dfSjm199354 #include <syslog.h>
55911106dfSjm199354 #include <locale.h>
56911106dfSjm199354 #include <pwd.h>
57911106dfSjm199354 #include <grp.h>
58911106dfSjm199354 #include <priv_utils.h>
59bfc848c6Sjm199354 #include <rctl.h>
60911106dfSjm199354 #include "vs_incl.h"
61911106dfSjm199354 
62bfc848c6Sjm199354 #define	VS_FILE_DESCRIPTORS	512
63bfc848c6Sjm199354 
64911106dfSjm199354 static int vscand_fg = 0; /* daemon by default */
65911106dfSjm199354 static vs_daemon_state_t vscand_state = VS_STATE_INIT;
66*8d7e4166Sjose borrego static volatile uint_t vscand_sigval = 0;
67*8d7e4166Sjose borrego static volatile uint_t vscand_n_refresh = 0;
68911106dfSjm199354 static int vscand_kdrv_fd = -1;
69911106dfSjm199354 static pthread_mutex_t vscand_cfg_mutex = PTHREAD_MUTEX_INITIALIZER;
70bfc848c6Sjm199354 static pthread_cond_t vscand_cfg_cv;
71bfc848c6Sjm199354 static pthread_t vscand_cfg_tid = 0;
72911106dfSjm199354 
73911106dfSjm199354 /* virus log path */
74911106dfSjm199354 static char vscand_vlog[MAXPATHLEN];
75911106dfSjm199354 
76911106dfSjm199354 /* user and group ids - default to 0 */
77911106dfSjm199354 static uid_t root_uid = 0, daemon_uid = 0;
78911106dfSjm199354 static gid_t sys_gid = 0;
79911106dfSjm199354 
80911106dfSjm199354 
81911106dfSjm199354 /* local function prototypes */
82911106dfSjm199354 static void vscand_sig_handler(int);
83911106dfSjm199354 static int vscand_parse_args(int, char **);
84911106dfSjm199354 static void vscand_get_uid_gid();
85911106dfSjm199354 static int vscand_init_file(char *, uid_t, gid_t, mode_t);
86911106dfSjm199354 static void vscand_usage(char *);
87911106dfSjm199354 static int vscand_daemonize_init(void);
88911106dfSjm199354 static void vscand_daemonize_fini(int, int);
89911106dfSjm199354 static int vscand_init(void);
90911106dfSjm199354 static void vscand_fini(void);
91bfc848c6Sjm199354 static int vscand_cfg_init(void);
92bfc848c6Sjm199354 static void vscand_cfg_fini(void);
93bfc848c6Sjm199354 static void *vscand_cfg_handler(void *);
94911106dfSjm199354 static int vscand_configure(void);
95bfc848c6Sjm199354 static void vscand_dtrace_cfg(vs_props_all_t *);
96911106dfSjm199354 static int vscand_kernel_bind(void);
97911106dfSjm199354 static void vscand_kernel_unbind(void);
98911106dfSjm199354 static int vscand_kernel_enable(int);
99911106dfSjm199354 static void vscand_kernel_disable(void);
100911106dfSjm199354 static int vscand_kernel_config(vs_config_t *);
101bfc848c6Sjm199354 static int vscand_kernel_max_req(uint32_t *);
102911106dfSjm199354 static void vscand_error(const char *);
103911106dfSjm199354 static int vscand_get_viruslog(void);
104bfc848c6Sjm199354 static int vscand_set_resource_limits(void);
105911106dfSjm199354 
106911106dfSjm199354 
107911106dfSjm199354 /*
108911106dfSjm199354  * Enable libumem debugging by default on DEBUG builds.
109911106dfSjm199354  */
110911106dfSjm199354 #ifdef DEBUG
111911106dfSjm199354 const char *
_umem_debug_init(void)112911106dfSjm199354 _umem_debug_init(void)
113911106dfSjm199354 {
114911106dfSjm199354 	return ("default,verbose"); /* $UMEM_DEBUG setting */
115911106dfSjm199354 }
116911106dfSjm199354 
117911106dfSjm199354 const char *
_umem_logging_init(void)118911106dfSjm199354 _umem_logging_init(void)
119911106dfSjm199354 {
120911106dfSjm199354 	return ("fail,contents"); /* $UMEM_LOGGING setting */
121911106dfSjm199354 }
122911106dfSjm199354 #endif
123911106dfSjm199354 
124911106dfSjm199354 
125911106dfSjm199354 /*
126*8d7e4166Sjose borrego  * vscand_sig_handler
127911106dfSjm199354  */
128911106dfSjm199354 static void
vscand_sig_handler(int sig)129911106dfSjm199354 vscand_sig_handler(int sig)
130911106dfSjm199354 {
131911106dfSjm199354 	if (vscand_sigval == 0)
132*8d7e4166Sjose borrego 		(void) atomic_swap_uint(&vscand_sigval, sig);
133*8d7e4166Sjose borrego 
134*8d7e4166Sjose borrego 	if (sig == SIGHUP)
135*8d7e4166Sjose borrego 		atomic_inc_uint(&vscand_n_refresh);
136911106dfSjm199354 }
137911106dfSjm199354 
138911106dfSjm199354 
139911106dfSjm199354 /*
140911106dfSjm199354  * main
141911106dfSjm199354  *
142911106dfSjm199354  * main must return SMF return code (see smf_method (5)) if vscand
143911106dfSjm199354  * is invoked directly by smf (see manifest: vscan.xml)
144911106dfSjm199354  * Exit codes: SMF_EXIT_ERR_CONFIG - error
145911106dfSjm199354  *             SMF_EXIT_ERR_FATAL - fatal error
146911106dfSjm199354  *             SMF_EXIT_OK - success
147911106dfSjm199354  */
148911106dfSjm199354 int
main(int argc,char ** argv)149911106dfSjm199354 main(int argc, char **argv)
150911106dfSjm199354 {
151911106dfSjm199354 	int err_stat = 0, pfd = -1;
152911106dfSjm199354 	sigset_t set;
153911106dfSjm199354 	struct sigaction act;
154bfc848c6Sjm199354 	int sigval;
155bfc848c6Sjm199354 
156911106dfSjm199354 	mode_t log_mode = S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP;
157911106dfSjm199354 	mode_t door_mode = S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH;
158911106dfSjm199354 
159911106dfSjm199354 	(void) setlocale(LC_ALL, "");
160911106dfSjm199354 	openlog("vscand", 0, LOG_DAEMON);
161911106dfSjm199354 
162911106dfSjm199354 	/* check if running in global zone; other zones not supported */
163911106dfSjm199354 	if (getzoneid() != GLOBAL_ZONEID) {
164911106dfSjm199354 		vscand_error(gettext("non-global zone not supported"));
165911106dfSjm199354 		exit(SMF_EXIT_ERR_FATAL);
166911106dfSjm199354 	}
167911106dfSjm199354 
168911106dfSjm199354 	/* check for a Trusted Solaris environment; not supported */
169911106dfSjm199354 	if (is_system_labeled()) {
170911106dfSjm199354 		vscand_error(gettext("Trusted Extensions not supported"));
171911106dfSjm199354 		exit(SMF_EXIT_ERR_FATAL);
172911106dfSjm199354 	}
173911106dfSjm199354 
174911106dfSjm199354 	/* Parse arguments */
175911106dfSjm199354 	if (vscand_parse_args(argc, argv) != 0)
176911106dfSjm199354 		exit(SMF_EXIT_ERR_CONFIG);
177911106dfSjm199354 
178911106dfSjm199354 	vscand_get_uid_gid();
179911106dfSjm199354 
180911106dfSjm199354 	/*
181911106dfSjm199354 	 * Initializetion of virus log and statistic door file
182911106dfSjm199354 	 * MUST be done BEFORE vscand_daemonize_init resets uid/gid.
183911106dfSjm199354 	 * Only root can create the files in /var/log and /var/run.
184911106dfSjm199354 	 */
185911106dfSjm199354 	if ((vscand_get_viruslog() != 0) ||
186911106dfSjm199354 	    (vscand_vlog[0] == '\0') ||
187911106dfSjm199354 	    (vscand_init_file(vscand_vlog, root_uid, sys_gid, log_mode) != 0)) {
188911106dfSjm199354 		*vscand_vlog = 0;
189911106dfSjm199354 	}
190911106dfSjm199354 
191911106dfSjm199354 	(void) vscand_init_file(VS_STATS_DOOR_NAME,
192911106dfSjm199354 	    daemon_uid, sys_gid, door_mode);
193911106dfSjm199354 
194911106dfSjm199354 	/*
195911106dfSjm199354 	 * Once we're done setting our global state up, set up signal handlers
196bfc848c6Sjm199354 	 * for ensuring orderly termination on SIGTERM.
197911106dfSjm199354 	 */
198911106dfSjm199354 	(void) sigfillset(&set);
199911106dfSjm199354 	(void) sigdelset(&set, SIGABRT); /* always unblocked for ASSERT() */
200911106dfSjm199354 
201911106dfSjm199354 	(void) sigfillset(&act.sa_mask);
202911106dfSjm199354 	act.sa_handler = vscand_sig_handler;
203911106dfSjm199354 	act.sa_flags = 0;
204911106dfSjm199354 
205911106dfSjm199354 	(void) sigaction(SIGTERM, &act, NULL);
206911106dfSjm199354 	(void) sigaction(SIGHUP, &act, NULL); /* Refresh config */
207911106dfSjm199354 	(void) sigaction(SIGINT, &act, NULL);
208bfc848c6Sjm199354 	(void) sigaction(SIGPIPE, &act, NULL);
209911106dfSjm199354 	(void) sigdelset(&set, SIGTERM);
210911106dfSjm199354 	(void) sigdelset(&set, SIGHUP);
211911106dfSjm199354 	(void) sigdelset(&set, SIGINT);
212bfc848c6Sjm199354 	(void) sigdelset(&set, SIGPIPE);
213911106dfSjm199354 
214911106dfSjm199354 	if (vscand_fg) {
215911106dfSjm199354 		(void) sigdelset(&set, SIGTSTP);
216911106dfSjm199354 		(void) sigdelset(&set, SIGTTIN);
217911106dfSjm199354 		(void) sigdelset(&set, SIGTTOU);
218911106dfSjm199354 
219911106dfSjm199354 		if (vscand_init() != 0) {
220911106dfSjm199354 			vscand_error(gettext("failed to initialize service"));
221911106dfSjm199354 			exit(SMF_EXIT_ERR_CONFIG);
222911106dfSjm199354 		}
223911106dfSjm199354 	} else {
224911106dfSjm199354 		/*
225911106dfSjm199354 		 * "pfd" is a pipe descriptor -- any fatal errors
226911106dfSjm199354 		 * during subsequent initialization of the child
227911106dfSjm199354 		 * process should be written to this pipe and the
228911106dfSjm199354 		 * parent will report this error as the exit status.
229911106dfSjm199354 		 */
230911106dfSjm199354 		pfd = vscand_daemonize_init();
231911106dfSjm199354 
232911106dfSjm199354 		if (vscand_init() != 0) {
233911106dfSjm199354 			vscand_error(gettext("failed to initialize service"));
234911106dfSjm199354 			exit(SMF_EXIT_ERR_CONFIG);
235911106dfSjm199354 		}
236911106dfSjm199354 
237911106dfSjm199354 		vscand_daemonize_fini(pfd, err_stat);
238911106dfSjm199354 	}
239911106dfSjm199354 
240911106dfSjm199354 	vscand_state = VS_STATE_RUNNING;
241911106dfSjm199354 
242911106dfSjm199354 	/* Wait here until shutdown */
243911106dfSjm199354 	while (vscand_state == VS_STATE_RUNNING) {
244*8d7e4166Sjose borrego 		if (vscand_sigval == 0 && vscand_n_refresh == 0)
245911106dfSjm199354 			(void) sigsuspend(&set);
246911106dfSjm199354 
247*8d7e4166Sjose borrego 		sigval = atomic_swap_uint(&vscand_sigval, 0);
248bfc848c6Sjm199354 
249bfc848c6Sjm199354 		switch (sigval) {
250911106dfSjm199354 		case 0:
251bfc848c6Sjm199354 		case SIGPIPE:
252911106dfSjm199354 		case SIGHUP:
253911106dfSjm199354 			break;
254911106dfSjm199354 		default:
255911106dfSjm199354 			vscand_state = VS_STATE_SHUTDOWN;
256911106dfSjm199354 			break;
257911106dfSjm199354 		}
258*8d7e4166Sjose borrego 
259*8d7e4166Sjose borrego 		if (atomic_swap_uint(&vscand_n_refresh, 0) != 0)
260*8d7e4166Sjose borrego 			(void) pthread_cond_signal(&vscand_cfg_cv);
261911106dfSjm199354 	}
262911106dfSjm199354 
263911106dfSjm199354 	vscand_fini();
264911106dfSjm199354 	return (SMF_EXIT_OK);
265911106dfSjm199354 }
266911106dfSjm199354 
267911106dfSjm199354 
268911106dfSjm199354 /*
269bfc848c6Sjm199354  * vscand_parse_args
270911106dfSjm199354  * Routine to parse the arguments to the daemon program
271911106dfSjm199354  * 'f' argument runs process in the foreground instead of as a daemon
272911106dfSjm199354  */
273911106dfSjm199354 int
vscand_parse_args(int argc,char ** argv)274911106dfSjm199354 vscand_parse_args(int argc, char **argv)
275911106dfSjm199354 {
276911106dfSjm199354 	int	optchar;
277911106dfSjm199354 
278911106dfSjm199354 	while ((optchar = getopt(argc, argv, "f?")) != EOF) {
279911106dfSjm199354 		switch (optchar) {
280911106dfSjm199354 		case 'f':
281911106dfSjm199354 			vscand_fg = 1;
282911106dfSjm199354 			break;
283911106dfSjm199354 		default:
284911106dfSjm199354 			vscand_usage(argv[0]);
285911106dfSjm199354 			return (-1);
286911106dfSjm199354 		}
287911106dfSjm199354 	}
288911106dfSjm199354 	return (0);
289911106dfSjm199354 }
290911106dfSjm199354 
291911106dfSjm199354 
292911106dfSjm199354 /*
293911106dfSjm199354  * vscand_usage
294911106dfSjm199354  */
295911106dfSjm199354 static void
vscand_usage(char * progname)296911106dfSjm199354 vscand_usage(char *progname)
297911106dfSjm199354 {
298911106dfSjm199354 	char buf[128];
299911106dfSjm199354 
300911106dfSjm199354 	(void) snprintf(buf, sizeof (buf), "%s %s [-f]",
301911106dfSjm199354 	    gettext("Usage"), progname);
302911106dfSjm199354 	vscand_error(buf);
303911106dfSjm199354 
304911106dfSjm199354 	(void) snprintf(buf, sizeof (buf), "\t-f %s\n",
305911106dfSjm199354 	    gettext("run program in foreground"));
306911106dfSjm199354 	vscand_error(buf);
307911106dfSjm199354 }
308911106dfSjm199354 
309911106dfSjm199354 
310911106dfSjm199354 /*
311911106dfSjm199354  * vscand_get_uid_gid
312911106dfSjm199354  *
313911106dfSjm199354  * failure to access a uid/gid results in the default (0) being used.
314911106dfSjm199354  */
315911106dfSjm199354 static void
vscand_get_uid_gid()316911106dfSjm199354 vscand_get_uid_gid()
317911106dfSjm199354 {
318911106dfSjm199354 	struct passwd *pwd;
319911106dfSjm199354 	struct group *grp;
320911106dfSjm199354 
321911106dfSjm199354 	if ((pwd = getpwnam("root")) != NULL)
322911106dfSjm199354 		root_uid = pwd->pw_uid;
323911106dfSjm199354 
324911106dfSjm199354 	if ((pwd = getpwnam("daemon")) != NULL)
325911106dfSjm199354 		daemon_uid = pwd->pw_uid;
326911106dfSjm199354 
327911106dfSjm199354 	if ((grp = getgrnam("sys")) != NULL)
328911106dfSjm199354 		sys_gid = grp->gr_gid;
329911106dfSjm199354 }
330911106dfSjm199354 
331911106dfSjm199354 
332911106dfSjm199354 /*
333911106dfSjm199354  * vscand_daemonize_init
334911106dfSjm199354  *
335911106dfSjm199354  * This function will fork off a child process, from which
336911106dfSjm199354  * only the child will return.
337911106dfSjm199354  */
338911106dfSjm199354 static int
vscand_daemonize_init(void)339911106dfSjm199354 vscand_daemonize_init(void)
340911106dfSjm199354 {
341911106dfSjm199354 	int status, pfds[2];
342911106dfSjm199354 	sigset_t set, oset;
343911106dfSjm199354 	pid_t pid;
344911106dfSjm199354 
345911106dfSjm199354 	/*
346911106dfSjm199354 	 * Reset process owner/group to daemon/sys. Root ownership is only
347911106dfSjm199354 	 * required to initialize virus log file in /var/log
348911106dfSjm199354 	 */
349911106dfSjm199354 	if (__init_daemon_priv(PU_RESETGROUPS | PU_LIMITPRIVS,
350911106dfSjm199354 	    daemon_uid, sys_gid,
351911106dfSjm199354 	    PRIV_PROC_AUDIT, PRIV_FILE_DAC_SEARCH, PRIV_FILE_DAC_READ,
352911106dfSjm199354 	    PRIV_FILE_FLAG_SET, NULL) != 0) {
353911106dfSjm199354 		vscand_error(gettext("failed to initialize privileges"));
354911106dfSjm199354 		_exit(SMF_EXIT_ERR_FATAL);
355911106dfSjm199354 	}
356911106dfSjm199354 
357911106dfSjm199354 	/*
358911106dfSjm199354 	 * Block all signals prior to the fork and leave them blocked in the
359911106dfSjm199354 	 * parent so we don't get in a situation where the parent gets SIGINT
360911106dfSjm199354 	 * and returns non-zero exit status and the child is actually running.
361911106dfSjm199354 	 * In the child, restore the signal mask once we've done our setsid().
362911106dfSjm199354 	 */
363911106dfSjm199354 	(void) sigfillset(&set);
364911106dfSjm199354 	(void) sigdelset(&set, SIGABRT);
365911106dfSjm199354 	(void) sigprocmask(SIG_BLOCK, &set, &oset);
366911106dfSjm199354 
367911106dfSjm199354 	if (pipe(pfds) == -1) {
368911106dfSjm199354 		vscand_error(gettext("failed to create pipe for daemonize"));
369911106dfSjm199354 		_exit(SMF_EXIT_ERR_FATAL);
370911106dfSjm199354 	}
371911106dfSjm199354 
372911106dfSjm199354 	if ((pid = fork()) == -1) {
373911106dfSjm199354 		vscand_error(gettext("failed to fork for daemonize"));
374911106dfSjm199354 		_exit(SMF_EXIT_ERR_FATAL);
375911106dfSjm199354 	}
376911106dfSjm199354 
377911106dfSjm199354 	/*
378911106dfSjm199354 	 * If we're the parent process, wait for either the child to send us
379911106dfSjm199354 	 * the appropriate exit status over the pipe or for the read to fail
380911106dfSjm199354 	 * (presumably with 0 for EOF if our child terminated abnormally).
381911106dfSjm199354 	 * If the read fails, exit with either the child's exit status if it
382911106dfSjm199354 	 * exited or with SMF_EXIT_ERR_FATAL if it died from a fatal signal.
383911106dfSjm199354 	 */
384911106dfSjm199354 	if (pid != 0) {
385911106dfSjm199354 		(void) close(pfds[1]);
386911106dfSjm199354 
387911106dfSjm199354 		if (read(pfds[0], &status, sizeof (status)) == sizeof (status))
388911106dfSjm199354 			_exit(status);
389911106dfSjm199354 
390911106dfSjm199354 		if (waitpid(pid, &status, 0) == pid && WIFEXITED(status))
391911106dfSjm199354 			_exit(WEXITSTATUS(status));
392911106dfSjm199354 
393911106dfSjm199354 		vscand_error(gettext("failed to daemonize"));
394911106dfSjm199354 		_exit(SMF_EXIT_ERR_FATAL);
395911106dfSjm199354 	}
396911106dfSjm199354 
397911106dfSjm199354 
398911106dfSjm199354 	(void) setsid();
399911106dfSjm199354 	(void) sigprocmask(SIG_SETMASK, &oset, NULL);
400911106dfSjm199354 	(void) chdir("/");
401911106dfSjm199354 	(void) umask(022);
402911106dfSjm199354 	(void) close(pfds[0]);
403911106dfSjm199354 
404911106dfSjm199354 	return (pfds[1]);
405911106dfSjm199354 }
406911106dfSjm199354 
407911106dfSjm199354 
408911106dfSjm199354 /*
409911106dfSjm199354  * vscand_daemonize_fini
410911106dfSjm199354  * Now that we're running, if a pipe fd was specified, write an exit
411911106dfSjm199354  * status to it to indicate that our parent process can safely detach.
412911106dfSjm199354  */
413911106dfSjm199354 static void
vscand_daemonize_fini(int fd,int err_status)414911106dfSjm199354 vscand_daemonize_fini(int fd, int err_status)
415911106dfSjm199354 {
416911106dfSjm199354 	if (fd >= 0)
417911106dfSjm199354 		(void) write(fd, &err_status, sizeof (err_status));
418911106dfSjm199354 
419911106dfSjm199354 	(void) close(fd);
420911106dfSjm199354 
421911106dfSjm199354 	/* Restore standard file descriptors */
422911106dfSjm199354 	if ((fd = open("/dev/null", O_RDWR)) >= 0) {
423911106dfSjm199354 		(void) fcntl(fd, F_DUP2FD, STDIN_FILENO);
424911106dfSjm199354 		(void) fcntl(fd, F_DUP2FD, STDOUT_FILENO);
425911106dfSjm199354 		(void) fcntl(fd, F_DUP2FD, STDERR_FILENO);
426911106dfSjm199354 		(void) close(fd);
427911106dfSjm199354 	}
428911106dfSjm199354 
429911106dfSjm199354 	/* clear basic privileges not required by vscand */
430911106dfSjm199354 	__fini_daemon_priv(PRIV_PROC_FORK, PRIV_PROC_EXEC, PRIV_PROC_SESSION,
431911106dfSjm199354 	    PRIV_FILE_LINK_ANY, PRIV_PROC_INFO, (char *)NULL);
432911106dfSjm199354 }
433911106dfSjm199354 
434911106dfSjm199354 
435911106dfSjm199354 /*
436911106dfSjm199354  * vscand_init_file
437911106dfSjm199354  *
438911106dfSjm199354  * create specified file and set its uid, gid and mode
439911106dfSjm199354  */
440911106dfSjm199354 static int
vscand_init_file(char * filepath,uid_t uid,gid_t gid,mode_t access_mode)441bfc848c6Sjm199354 vscand_init_file(char *filepath, uid_t uid, gid_t gid, mode_t access_mode)
442911106dfSjm199354 {
443911106dfSjm199354 	int fd, rc = 0;
444911106dfSjm199354 	struct stat stat_buf;
445911106dfSjm199354 	char buf[MAXPATHLEN];
446911106dfSjm199354 
447bfc848c6Sjm199354 	if ((fd = open(filepath, O_RDONLY | O_CREAT, access_mode)) == -1) {
448911106dfSjm199354 		rc = -1;
449bfc848c6Sjm199354 	} else {
450bfc848c6Sjm199354 		if (fstat(fd, &stat_buf) != 0) {
451911106dfSjm199354 			rc = -1;
452bfc848c6Sjm199354 		} else {
453bfc848c6Sjm199354 			if ((stat_buf.st_mode & S_IAMB) != access_mode) {
454bfc848c6Sjm199354 				if (fchmod(fd, access_mode) != 0)
455911106dfSjm199354 					rc = -1;
456911106dfSjm199354 			}
457911106dfSjm199354 
458911106dfSjm199354 			if ((stat_buf.st_uid != uid) ||
459911106dfSjm199354 			    (stat_buf.st_gid != gid)) {
460911106dfSjm199354 				if (fchown(fd, uid, gid) != 0)
461911106dfSjm199354 					rc = -1;
462911106dfSjm199354 			}
463911106dfSjm199354 		}
464911106dfSjm199354 
465911106dfSjm199354 		(void) close(fd);
466911106dfSjm199354 	}
467911106dfSjm199354 
468911106dfSjm199354 	if (rc == -1) {
469911106dfSjm199354 		(void) snprintf(buf, MAXPATHLEN, "%s %s",
470911106dfSjm199354 		    gettext("Failed to initialize"), filepath);
471911106dfSjm199354 		vscand_error(buf);
472911106dfSjm199354 	}
473911106dfSjm199354 
474911106dfSjm199354 	return (rc);
475911106dfSjm199354 }
476911106dfSjm199354 
477911106dfSjm199354 
478911106dfSjm199354 /*
479911106dfSjm199354  * vscand_init
480911106dfSjm199354  *
481911106dfSjm199354  * There are some requirements on the order in which the daemon
482911106dfSjm199354  * initialization functions are called.
483911106dfSjm199354  *
484911106dfSjm199354  * - vscand_kernel_bind - bind to kernel module
485911106dfSjm199354  * - vs_eng_init populates vs_icap data and thus vs_icap_init MUST be
486911106dfSjm199354  *   called before vs_eng_init
487911106dfSjm199354  * - vscand_configure - load the configuration
488911106dfSjm199354  * - vs_door_init - start vscan door server
489911106dfSjm199354  * - vscand_kernel_enable - enable scan requests from kernel
490911106dfSjm199354  */
491911106dfSjm199354 static int
vscand_init(void)492911106dfSjm199354 vscand_init(void)
493911106dfSjm199354 {
494911106dfSjm199354 	int door_fd = -1;
495bfc848c6Sjm199354 	uint32_t max_req;
496911106dfSjm199354 
497911106dfSjm199354 	if (vscand_kernel_bind() < 0)
498911106dfSjm199354 		return (-1);
499911106dfSjm199354 
500bfc848c6Sjm199354 	if (vscand_kernel_max_req(&max_req) == -1)
501bfc848c6Sjm199354 		return (-1);
502bfc848c6Sjm199354 
503bfc848c6Sjm199354 	if (vs_svc_init(max_req) != 0)
504bfc848c6Sjm199354 		return (-1);
505bfc848c6Sjm199354 
506911106dfSjm199354 	if (vs_stats_init() != 0)
507911106dfSjm199354 		vscand_error(
508911106dfSjm199354 		    gettext("failed to initialize statistics interface"));
509911106dfSjm199354 
510911106dfSjm199354 	vs_icap_init();
511911106dfSjm199354 	vs_eng_init();
512911106dfSjm199354 
513bfc848c6Sjm199354 	/* initialize configuration and handler thread */
514bfc848c6Sjm199354 	if (vscand_cfg_init() != 0) {
515911106dfSjm199354 		vscand_error(gettext("failed to initialize configuration"));
516bfc848c6Sjm199354 		vscand_fini();
517911106dfSjm199354 		return (-1);
518911106dfSjm199354 	}
519911106dfSjm199354 
520bfc848c6Sjm199354 	(void) vscand_set_resource_limits();
521bfc848c6Sjm199354 
522911106dfSjm199354 	if (((door_fd = vs_door_init()) < 0) ||
523911106dfSjm199354 	    (vscand_kernel_enable(door_fd) < 0)) {
524911106dfSjm199354 		vscand_fini();
525911106dfSjm199354 		return (-1);
526911106dfSjm199354 	}
527911106dfSjm199354 
528911106dfSjm199354 	return (0);
529911106dfSjm199354 }
530911106dfSjm199354 
531911106dfSjm199354 
532911106dfSjm199354 /*
533911106dfSjm199354  * vscand_fini
534911106dfSjm199354  *
535911106dfSjm199354  * vscand_kernel_disable - should be called first to ensure that no
536911106dfSjm199354  *	more scan requests are initiated from the kernel module
537bfc848c6Sjm199354  * vs_svc_terminate - terminate requests and wait for thread completion
538bfc848c6Sjm199354  * vs_xxx_fini - module cleanup routines
539911106dfSjm199354  * vscand_kernel_unbind - should be called last to tell the kernel module
540911106dfSjm199354  *	that vscand is shutdown.
541911106dfSjm199354  */
542911106dfSjm199354 static void
vscand_fini(void)543911106dfSjm199354 vscand_fini(void)
544911106dfSjm199354 {
545911106dfSjm199354 	vscand_kernel_disable();
546911106dfSjm199354 
547bfc848c6Sjm199354 	/* terminate reconfiguration handler thread */
548bfc848c6Sjm199354 	vscand_cfg_fini();
549bfc848c6Sjm199354 
550bfc848c6Sjm199354 	/* terminate requests and wait for completion */
551bfc848c6Sjm199354 	vs_svc_terminate();
552bfc848c6Sjm199354 
553bfc848c6Sjm199354 	/* clean up */
554911106dfSjm199354 	vs_svc_fini();
555911106dfSjm199354 	vs_eng_fini();
556911106dfSjm199354 	vs_icap_fini();
557911106dfSjm199354 	vs_door_fini();
558911106dfSjm199354 	vs_stats_fini();
559911106dfSjm199354 
560911106dfSjm199354 	vscand_kernel_unbind();
561911106dfSjm199354 }
562911106dfSjm199354 
563911106dfSjm199354 
564911106dfSjm199354 /*
565bfc848c6Sjm199354  * vscand_cfg_init
566bfc848c6Sjm199354  *
567bfc848c6Sjm199354  * initialize configuration and reconfiguration handler thread
568bfc848c6Sjm199354  */
569bfc848c6Sjm199354 static int
vscand_cfg_init(void)570bfc848c6Sjm199354 vscand_cfg_init(void)
571bfc848c6Sjm199354 {
572bfc848c6Sjm199354 	int rc;
573bfc848c6Sjm199354 
574bfc848c6Sjm199354 	(void) pthread_cond_init(&vscand_cfg_cv, NULL);
575bfc848c6Sjm199354 
576bfc848c6Sjm199354 	(void) pthread_mutex_lock(&vscand_cfg_mutex);
577bfc848c6Sjm199354 	rc = vscand_configure();
578bfc848c6Sjm199354 	(void) pthread_mutex_unlock(&vscand_cfg_mutex);
579bfc848c6Sjm199354 
580bfc848c6Sjm199354 	if (rc != 0)
581bfc848c6Sjm199354 		return (-1);
582bfc848c6Sjm199354 
583bfc848c6Sjm199354 	if (pthread_create(&vscand_cfg_tid, NULL, vscand_cfg_handler, 0) != 0) {
584bfc848c6Sjm199354 		vscand_cfg_tid = 0;
585bfc848c6Sjm199354 		return (-1);
586bfc848c6Sjm199354 	}
587bfc848c6Sjm199354 
588bfc848c6Sjm199354 	return (0);
589bfc848c6Sjm199354 }
590bfc848c6Sjm199354 
591bfc848c6Sjm199354 
592bfc848c6Sjm199354 /*
593bfc848c6Sjm199354  * vscand_cfg_fini
594bfc848c6Sjm199354  *
595bfc848c6Sjm199354  * terminate reconfiguration handler thread
596bfc848c6Sjm199354  */
597bfc848c6Sjm199354 static void
vscand_cfg_fini()598bfc848c6Sjm199354 vscand_cfg_fini()
599bfc848c6Sjm199354 {
600bfc848c6Sjm199354 	if (vscand_cfg_tid != 0) {
601bfc848c6Sjm199354 		(void) pthread_cond_signal(&vscand_cfg_cv);
602bfc848c6Sjm199354 		(void) pthread_join(vscand_cfg_tid, NULL);
603bfc848c6Sjm199354 		vscand_cfg_tid = 0;
604bfc848c6Sjm199354 	}
605bfc848c6Sjm199354 	(void) pthread_cond_destroy(&vscand_cfg_cv);
606bfc848c6Sjm199354 }
607bfc848c6Sjm199354 
608bfc848c6Sjm199354 
609bfc848c6Sjm199354 /*
610bfc848c6Sjm199354  * vscand_cfg_handler
611bfc848c6Sjm199354  * wait for reconfiguration event and reload configuration
612bfc848c6Sjm199354  * exit on VS_STATE_SHUTDOWN
613bfc848c6Sjm199354  */
614bfc848c6Sjm199354 /*ARGSUSED*/
615bfc848c6Sjm199354 static void *
vscand_cfg_handler(void * arg)616bfc848c6Sjm199354 vscand_cfg_handler(void *arg)
617bfc848c6Sjm199354 {
618bfc848c6Sjm199354 	(void) pthread_mutex_lock(&vscand_cfg_mutex);
619bfc848c6Sjm199354 
620bfc848c6Sjm199354 	while (pthread_cond_wait(&vscand_cfg_cv, &vscand_cfg_mutex) == 0) {
621bfc848c6Sjm199354 		if (vscand_state == VS_STATE_SHUTDOWN)
622bfc848c6Sjm199354 			break;
623bfc848c6Sjm199354 
624bfc848c6Sjm199354 		(void) vscand_configure();
625bfc848c6Sjm199354 	}
626bfc848c6Sjm199354 
627bfc848c6Sjm199354 	(void) pthread_mutex_unlock(&vscand_cfg_mutex);
628bfc848c6Sjm199354 
629bfc848c6Sjm199354 	return (NULL);
630bfc848c6Sjm199354 }
631bfc848c6Sjm199354 
632bfc848c6Sjm199354 
633bfc848c6Sjm199354 /*
634911106dfSjm199354  * vscand_configure
635911106dfSjm199354  */
636911106dfSjm199354 static int
vscand_configure(void)637911106dfSjm199354 vscand_configure(void)
638911106dfSjm199354 {
639911106dfSjm199354 	uint32_t len;
640911106dfSjm199354 	vs_config_t kconfig;
641911106dfSjm199354 	vs_props_all_t config;
642911106dfSjm199354 
643911106dfSjm199354 	(void) memset(&config, 0, sizeof (vs_props_all_t));
644911106dfSjm199354 	if (vs_props_get_all(&config) != VS_ERR_NONE) {
645911106dfSjm199354 		vscand_error(gettext("configuration data error"));
646911106dfSjm199354 		return (-1);
647911106dfSjm199354 	}
648911106dfSjm199354 
649911106dfSjm199354 	(void) memset(&kconfig, 0, sizeof (vs_config_t));
650911106dfSjm199354 	len = sizeof (kconfig.vsc_types);
651911106dfSjm199354 	if (vs_parse_types(config.va_props.vp_types,
652911106dfSjm199354 	    kconfig.vsc_types, &len) != 0) {
653911106dfSjm199354 		vscand_error(gettext("configuration data error - types"));
654911106dfSjm199354 		return (-1);
655911106dfSjm199354 	}
656911106dfSjm199354 	kconfig.vsc_types_len = len;
657911106dfSjm199354 
658911106dfSjm199354 	/* Convert the maxfsize string from the configuration into bytes */
659911106dfSjm199354 	if (vs_strtonum(config.va_props.vp_maxsize,
660911106dfSjm199354 	    &kconfig.vsc_max_size) != 0) {
661911106dfSjm199354 		vscand_error(gettext("configuration data error - max-size"));
662911106dfSjm199354 		return (-1);
663911106dfSjm199354 	}
664911106dfSjm199354 	kconfig.vsc_allow = config.va_props.vp_maxsize_action ? 1LL : 0LL;
665911106dfSjm199354 
666911106dfSjm199354 	/* Send configuration update to kernel */
667911106dfSjm199354 	if (vscand_kernel_config(&kconfig) != 0) {
668911106dfSjm199354 		return (-1);
669911106dfSjm199354 	}
670911106dfSjm199354 
671bfc848c6Sjm199354 	/* dtrace the configuration data */
672bfc848c6Sjm199354 	vscand_dtrace_cfg(&config);
673911106dfSjm199354 
674bfc848c6Sjm199354 	/* propagate configuration changes */
675bfc848c6Sjm199354 	vs_eng_config(&config);
676911106dfSjm199354 	vs_stats_config(&config);
677911106dfSjm199354 
678911106dfSjm199354 	return (0);
679911106dfSjm199354 }
680911106dfSjm199354 
681911106dfSjm199354 
682911106dfSjm199354 /*
683911106dfSjm199354  * vscand_get_state
684911106dfSjm199354  */
685911106dfSjm199354 vs_daemon_state_t
vscand_get_state(void)686911106dfSjm199354 vscand_get_state(void)
687911106dfSjm199354 {
688911106dfSjm199354 	return (vscand_state);
689911106dfSjm199354 }
690911106dfSjm199354 
691911106dfSjm199354 
692911106dfSjm199354 /*
693911106dfSjm199354  * vscand_get_viruslog
694911106dfSjm199354  */
695911106dfSjm199354 static int
vscand_get_viruslog()696911106dfSjm199354 vscand_get_viruslog()
697911106dfSjm199354 {
698911106dfSjm199354 	vs_props_t props;
699911106dfSjm199354 	uint64_t propids;
700911106dfSjm199354 	int rc;
701911106dfSjm199354 
702911106dfSjm199354 	propids = VS_PROPID_VLOG;
703911106dfSjm199354 	if ((rc = vs_props_get(&props, propids)) != VS_ERR_NONE) {
704911106dfSjm199354 		vscand_error(vs_strerror(rc));
705911106dfSjm199354 		return (-1);
706911106dfSjm199354 	}
707911106dfSjm199354 
708911106dfSjm199354 	(void) strlcpy(vscand_vlog, props.vp_vlog, sizeof (vscand_vlog));
709911106dfSjm199354 	return (0);
710911106dfSjm199354 }
711911106dfSjm199354 
712911106dfSjm199354 
713911106dfSjm199354 /*
714911106dfSjm199354  * vscand_viruslog
715911106dfSjm199354  */
716911106dfSjm199354 char *
vscand_viruslog(void)717911106dfSjm199354 vscand_viruslog(void)
718911106dfSjm199354 {
719911106dfSjm199354 	if (vscand_vlog[0] == '\0')
720911106dfSjm199354 		return (NULL);
721911106dfSjm199354 
722911106dfSjm199354 	return (vscand_vlog);
723911106dfSjm199354 }
724911106dfSjm199354 
725911106dfSjm199354 
726911106dfSjm199354 /*
727911106dfSjm199354  * vscand_kernel_bind
728911106dfSjm199354  */
729911106dfSjm199354 static int
vscand_kernel_bind(void)730911106dfSjm199354 vscand_kernel_bind(void)
731911106dfSjm199354 {
732911106dfSjm199354 	char devname[MAXPATHLEN];
733911106dfSjm199354 	int inst = 0;
734911106dfSjm199354 
735911106dfSjm199354 	(void) snprintf(devname, MAXPATHLEN, "%s%d", VS_DRV_PATH, inst);
736911106dfSjm199354 
737911106dfSjm199354 	if ((vscand_kdrv_fd = open(devname, O_RDONLY)) < 0) {
738911106dfSjm199354 		vscand_error(gettext("failed to bind to kernel"));
739911106dfSjm199354 		return (-1);
740911106dfSjm199354 	}
741911106dfSjm199354 
742911106dfSjm199354 	return (0);
743911106dfSjm199354 }
744911106dfSjm199354 
745911106dfSjm199354 
746911106dfSjm199354 /*
747911106dfSjm199354  * vscand_kernel_unbind
748911106dfSjm199354  */
749911106dfSjm199354 static void
vscand_kernel_unbind(void)750911106dfSjm199354 vscand_kernel_unbind(void)
751911106dfSjm199354 {
752911106dfSjm199354 	if (vscand_kdrv_fd >= 0)
753911106dfSjm199354 		(void) close(vscand_kdrv_fd);
754911106dfSjm199354 }
755911106dfSjm199354 
756911106dfSjm199354 
757911106dfSjm199354 /*
758911106dfSjm199354  * vscand_kernel_enable
759911106dfSjm199354  */
760911106dfSjm199354 static int
vscand_kernel_enable(int door_fd)761911106dfSjm199354 vscand_kernel_enable(int door_fd)
762911106dfSjm199354 {
763bfc848c6Sjm199354 	if (ioctl(vscand_kdrv_fd, VS_IOCTL_ENABLE, door_fd) < 0) {
764911106dfSjm199354 		vscand_error(gettext("failed to bind to kernel"));
765911106dfSjm199354 		(void) close(vscand_kdrv_fd);
766911106dfSjm199354 		vscand_kdrv_fd = -1;
767911106dfSjm199354 		return (-1);
768911106dfSjm199354 	}
769911106dfSjm199354 	return (0);
770911106dfSjm199354 }
771911106dfSjm199354 
772911106dfSjm199354 
773911106dfSjm199354 /*
774911106dfSjm199354  * vscand_kernel_disable
775911106dfSjm199354  */
776911106dfSjm199354 static void
vscand_kernel_disable()777911106dfSjm199354 vscand_kernel_disable()
778911106dfSjm199354 {
779911106dfSjm199354 	if (vscand_kdrv_fd >= 0)
780bfc848c6Sjm199354 		(void) ioctl(vscand_kdrv_fd, VS_IOCTL_DISABLE);
781911106dfSjm199354 }
782911106dfSjm199354 
783911106dfSjm199354 
784911106dfSjm199354 /*
785911106dfSjm199354  * vscand_kernel_config
786911106dfSjm199354  */
787911106dfSjm199354 int
vscand_kernel_config(vs_config_t * conf)788911106dfSjm199354 vscand_kernel_config(vs_config_t *conf)
789911106dfSjm199354 {
790bfc848c6Sjm199354 	if ((vscand_kdrv_fd < 0) ||
791bfc848c6Sjm199354 	    (ioctl(vscand_kdrv_fd, VS_IOCTL_CONFIG, conf) < 0)) {
792911106dfSjm199354 		vscand_error(gettext("failed to send config to kernel"));
793911106dfSjm199354 		return (-1);
794911106dfSjm199354 	}
795911106dfSjm199354 
796911106dfSjm199354 	return (0);
797911106dfSjm199354 }
798911106dfSjm199354 
799911106dfSjm199354 
800911106dfSjm199354 /*
801bfc848c6Sjm199354  * vscand_kernel_result
802bfc848c6Sjm199354  */
803bfc848c6Sjm199354 int
vscand_kernel_result(vs_scan_rsp_t * scan_rsp)804bfc848c6Sjm199354 vscand_kernel_result(vs_scan_rsp_t *scan_rsp)
805bfc848c6Sjm199354 {
806bfc848c6Sjm199354 	if ((vscand_kdrv_fd < 0) ||
807bfc848c6Sjm199354 	    (ioctl(vscand_kdrv_fd, VS_IOCTL_RESULT, scan_rsp) < 0)) {
808bfc848c6Sjm199354 		vscand_error(gettext("failed to send result to kernel"));
809bfc848c6Sjm199354 		return (-1);
810bfc848c6Sjm199354 	}
811bfc848c6Sjm199354 
812bfc848c6Sjm199354 	return (0);
813bfc848c6Sjm199354 }
814bfc848c6Sjm199354 
815bfc848c6Sjm199354 
816bfc848c6Sjm199354 /*
817bfc848c6Sjm199354  * vscand_kernel_max_req
818bfc848c6Sjm199354  */
819bfc848c6Sjm199354 int
vscand_kernel_max_req(uint32_t * max_req)820bfc848c6Sjm199354 vscand_kernel_max_req(uint32_t *max_req)
821bfc848c6Sjm199354 {
822bfc848c6Sjm199354 	if ((vscand_kdrv_fd < 0) ||
823bfc848c6Sjm199354 	    (ioctl(vscand_kdrv_fd, VS_IOCTL_MAX_REQ, max_req) < 0)) {
824bfc848c6Sjm199354 		vscand_error(gettext("failed to get config data from kernel"));
825bfc848c6Sjm199354 		return (-1);
826bfc848c6Sjm199354 	}
827bfc848c6Sjm199354 
828bfc848c6Sjm199354 	return (0);
829bfc848c6Sjm199354 }
830bfc848c6Sjm199354 
831bfc848c6Sjm199354 
832bfc848c6Sjm199354 /*
833bfc848c6Sjm199354  * vscand_set_resource_limits
834bfc848c6Sjm199354  *
835bfc848c6Sjm199354  * If the process's max file descriptor limit is less than
836bfc848c6Sjm199354  * VS_FILE_DESCRIPTORS, increae it to VS_FILE_DESCRIPTORS.
837bfc848c6Sjm199354  */
838bfc848c6Sjm199354 static int
vscand_set_resource_limits(void)839bfc848c6Sjm199354 vscand_set_resource_limits(void)
840bfc848c6Sjm199354 {
841bfc848c6Sjm199354 	int rc = -1;
842bfc848c6Sjm199354 	rctlblk_t *rblk;
843bfc848c6Sjm199354 	char *limit = "process.max-file-descriptor";
844bfc848c6Sjm199354 
845bfc848c6Sjm199354 	rblk = (rctlblk_t *)malloc(rctlblk_size());
846bfc848c6Sjm199354 
847bfc848c6Sjm199354 	if (rblk != NULL) {
848bfc848c6Sjm199354 		rc = getrctl(limit, NULL, rblk, 0);
849bfc848c6Sjm199354 		if ((rc == 0) &&
850bfc848c6Sjm199354 		    (rctlblk_get_value(rblk) < VS_FILE_DESCRIPTORS)) {
851bfc848c6Sjm199354 			rctlblk_set_value(rblk, VS_FILE_DESCRIPTORS);
852bfc848c6Sjm199354 			rc = setrctl(limit, NULL, rblk, 0);
853bfc848c6Sjm199354 		}
854bfc848c6Sjm199354 		(void) free(rblk);
855bfc848c6Sjm199354 	}
856bfc848c6Sjm199354 
857bfc848c6Sjm199354 	return (rc);
858bfc848c6Sjm199354 }
859bfc848c6Sjm199354 
860bfc848c6Sjm199354 
861bfc848c6Sjm199354 /*
862911106dfSjm199354  * vscand_error
863911106dfSjm199354  */
864911106dfSjm199354 static void
vscand_error(const char * errmsg)865911106dfSjm199354 vscand_error(const char *errmsg)
866911106dfSjm199354 {
867911106dfSjm199354 	(void) fprintf(stderr, "vscand: %s", errmsg);
868911106dfSjm199354 	syslog(LOG_ERR, "%s\n", errmsg);
869911106dfSjm199354 }
870bfc848c6Sjm199354 
871bfc848c6Sjm199354 
872bfc848c6Sjm199354 /*
873bfc848c6Sjm199354  * vscand_dtrace_cfg
874bfc848c6Sjm199354  * vscand_dtrace_gen
875bfc848c6Sjm199354  * vscand_dtrace_eng
876bfc848c6Sjm199354  *
877bfc848c6Sjm199354  * Support for dtracing vscand configuration when processing
878bfc848c6Sjm199354  * a reconfiguration event (SIGHUP)
879bfc848c6Sjm199354  */
880bfc848c6Sjm199354 /*ARGSUSED*/
881bfc848c6Sjm199354 static void
vscand_dtrace_eng(char * id,boolean_t enable,char * host,int port,int conn)882bfc848c6Sjm199354 vscand_dtrace_eng(char *id, boolean_t enable, char *host, int port, int conn)
883bfc848c6Sjm199354 {
884bfc848c6Sjm199354 }
885bfc848c6Sjm199354 /*ARGSUSED*/
886bfc848c6Sjm199354 static void
vscand_dtrace_gen(char * size,boolean_t action,char * types,char * log)887bfc848c6Sjm199354 vscand_dtrace_gen(char *size, boolean_t action, char *types, char *log)
888bfc848c6Sjm199354 {
889bfc848c6Sjm199354 }
890bfc848c6Sjm199354 static void
vscand_dtrace_cfg(vs_props_all_t * config)891bfc848c6Sjm199354 vscand_dtrace_cfg(vs_props_all_t *config)
892bfc848c6Sjm199354 {
893bfc848c6Sjm199354 	int i;
894bfc848c6Sjm199354 
895bfc848c6Sjm199354 	vscand_dtrace_gen(config->va_props.vp_maxsize,
896bfc848c6Sjm199354 	    config->va_props.vp_maxsize_action,
897bfc848c6Sjm199354 	    config->va_props.vp_types,
898bfc848c6Sjm199354 	    config->va_props.vp_vlog);
899bfc848c6Sjm199354 
900bfc848c6Sjm199354 	for (i = 0; i < VS_SE_MAX; i++) {
901bfc848c6Sjm199354 		if (config->va_se[i].vep_engid[0] != 0)
902bfc848c6Sjm199354 				vscand_dtrace_eng(config->va_se[i].vep_engid,
903bfc848c6Sjm199354 				    config->va_se[i].vep_enable,
904bfc848c6Sjm199354 				    config->va_se[i].vep_host,
905bfc848c6Sjm199354 				    config->va_se[i].vep_port,
906bfc848c6Sjm199354 				    config->va_se[i].vep_maxconn);
907bfc848c6Sjm199354 	}
908bfc848c6Sjm199354 }
909