xref: /titanic_52/usr/src/cmd/picl/picld/picld.c (revision 0ec5755428223b8105e488e8fddc19de4db26521)
17c478bd9Sstevel@tonic-gate /*
27c478bd9Sstevel@tonic-gate  * CDDL HEADER START
37c478bd9Sstevel@tonic-gate  *
47c478bd9Sstevel@tonic-gate  * The contents of this file are subject to the terms of the
57c478bd9Sstevel@tonic-gate  * Common Development and Distribution License, Version 1.0 only
67c478bd9Sstevel@tonic-gate  * (the "License").  You may not use this file except in compliance
77c478bd9Sstevel@tonic-gate  * with the License.
87c478bd9Sstevel@tonic-gate  *
97c478bd9Sstevel@tonic-gate  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
107c478bd9Sstevel@tonic-gate  * or http://www.opensolaris.org/os/licensing.
117c478bd9Sstevel@tonic-gate  * See the License for the specific language governing permissions
127c478bd9Sstevel@tonic-gate  * and limitations under the License.
137c478bd9Sstevel@tonic-gate  *
147c478bd9Sstevel@tonic-gate  * When distributing Covered Code, include this CDDL HEADER in each
157c478bd9Sstevel@tonic-gate  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
167c478bd9Sstevel@tonic-gate  * If applicable, add the following below this CDDL HEADER, with the
177c478bd9Sstevel@tonic-gate  * fields enclosed by brackets "[]" replaced with your own identifying
187c478bd9Sstevel@tonic-gate  * information: Portions Copyright [yyyy] [name of copyright owner]
197c478bd9Sstevel@tonic-gate  *
207c478bd9Sstevel@tonic-gate  * CDDL HEADER END
217c478bd9Sstevel@tonic-gate  */
22*0ec57554Sraf 
237c478bd9Sstevel@tonic-gate /*
247c478bd9Sstevel@tonic-gate  * Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
257c478bd9Sstevel@tonic-gate  * Use is subject to license terms.
267c478bd9Sstevel@tonic-gate  */
277c478bd9Sstevel@tonic-gate 
287c478bd9Sstevel@tonic-gate #pragma ident	"%Z%%M%	%I%	%E% SMI"
297c478bd9Sstevel@tonic-gate 
307c478bd9Sstevel@tonic-gate /*
317c478bd9Sstevel@tonic-gate  * PICL daemon
327c478bd9Sstevel@tonic-gate  */
337c478bd9Sstevel@tonic-gate 
347c478bd9Sstevel@tonic-gate #include <stdio.h>
357c478bd9Sstevel@tonic-gate #include <stdlib.h>
367c478bd9Sstevel@tonic-gate #include <stdarg.h>
377c478bd9Sstevel@tonic-gate #include <string.h>
387c478bd9Sstevel@tonic-gate #include <libintl.h>
397c478bd9Sstevel@tonic-gate #include <locale.h>
407c478bd9Sstevel@tonic-gate #include <alloca.h>
417c478bd9Sstevel@tonic-gate #include <errno.h>
427c478bd9Sstevel@tonic-gate #include <assert.h>
437c478bd9Sstevel@tonic-gate #include <stropts.h>
447c478bd9Sstevel@tonic-gate #include <unistd.h>
457c478bd9Sstevel@tonic-gate #include <signal.h>
467c478bd9Sstevel@tonic-gate #include <pthread.h>
477c478bd9Sstevel@tonic-gate #include <synch.h>
487c478bd9Sstevel@tonic-gate #include <door.h>
497c478bd9Sstevel@tonic-gate #include <sys/door.h>
507c478bd9Sstevel@tonic-gate #include <fcntl.h>
517c478bd9Sstevel@tonic-gate #include <dlfcn.h>
527c478bd9Sstevel@tonic-gate #include <time.h>
537c478bd9Sstevel@tonic-gate #include <sys/utsname.h>
547c478bd9Sstevel@tonic-gate #include <sys/systeminfo.h>
557c478bd9Sstevel@tonic-gate #include <sys/stat.h>
567c478bd9Sstevel@tonic-gate #include <sys/wait.h>
577c478bd9Sstevel@tonic-gate #include <dirent.h>
587c478bd9Sstevel@tonic-gate #include <syslog.h>
597c478bd9Sstevel@tonic-gate #include <poll.h>
607c478bd9Sstevel@tonic-gate #include <limits.h>
617c478bd9Sstevel@tonic-gate #include <picl.h>
627c478bd9Sstevel@tonic-gate #include "picl2door.h"
637c478bd9Sstevel@tonic-gate #include <picltree.h>
647c478bd9Sstevel@tonic-gate #include "ptree_impl.h"
657c478bd9Sstevel@tonic-gate 
667c478bd9Sstevel@tonic-gate /*
677c478bd9Sstevel@tonic-gate  * Log text messages
687c478bd9Sstevel@tonic-gate  */
697c478bd9Sstevel@tonic-gate #define	MUST_BE_ROOT	gettext("this program must be run as root\n")
707c478bd9Sstevel@tonic-gate #define	CD_ROOT_FAILED	gettext("chdir to root failed\n")
717c478bd9Sstevel@tonic-gate #define	INIT_FAILED	gettext("ptree initialization failed\n")
727c478bd9Sstevel@tonic-gate #define	DAEMON_RUNNING	gettext("PICL daemon already running\n")
737c478bd9Sstevel@tonic-gate #define	DOOR_FAILED	gettext("Failed creating picld door\n")
747c478bd9Sstevel@tonic-gate #define	SIGACT_FAILED	\
757c478bd9Sstevel@tonic-gate 		gettext("Failed to install signal handler for %s: %s\n")
767c478bd9Sstevel@tonic-gate 
777c478bd9Sstevel@tonic-gate /*
787c478bd9Sstevel@tonic-gate  * Constants
797c478bd9Sstevel@tonic-gate  */
807c478bd9Sstevel@tonic-gate #define	PICLD				"picld"
817c478bd9Sstevel@tonic-gate #define	DOS_PICL_REQUESTS_LIMIT		10000
827c478bd9Sstevel@tonic-gate #define	SLIDING_INTERVAL_MILLISECONDS	1000
837c478bd9Sstevel@tonic-gate #define	PICLD_MAJOR_REV			0x1
847c478bd9Sstevel@tonic-gate #define	PICLD_MINOR_REV			0x0
857c478bd9Sstevel@tonic-gate #define	DOS_SLEEPTIME_MS		1000
867c478bd9Sstevel@tonic-gate 
877c478bd9Sstevel@tonic-gate /*
887c478bd9Sstevel@tonic-gate  * Macros
897c478bd9Sstevel@tonic-gate  */
907c478bd9Sstevel@tonic-gate #define	PICLD_VERSION(x, y)	((x << 8) | y)
917c478bd9Sstevel@tonic-gate #define	PICL_CLIENT_REV(x)	(x & 0xff)
927c478bd9Sstevel@tonic-gate #define	MILLI_TO_NANO(x)	(x * 1000000)
937c478bd9Sstevel@tonic-gate 
947c478bd9Sstevel@tonic-gate extern	char	**environ;
957c478bd9Sstevel@tonic-gate 
967c478bd9Sstevel@tonic-gate /*
977c478bd9Sstevel@tonic-gate  * Module Variables
987c478bd9Sstevel@tonic-gate  */
997c478bd9Sstevel@tonic-gate static	int		logflag = 1;
1007c478bd9Sstevel@tonic-gate static	int		doreinit = 0;
1017c478bd9Sstevel@tonic-gate static	int		door_id = -1;
1027c478bd9Sstevel@tonic-gate static  int 		service_requests = 0;
1037c478bd9Sstevel@tonic-gate static	hrtime_t	orig_time;
1047c478bd9Sstevel@tonic-gate static	hrtime_t	sliding_interval_ms;
1057c478bd9Sstevel@tonic-gate static	uint32_t	dos_req_limit;
1067c478bd9Sstevel@tonic-gate static	uint32_t	dos_ms;
1077c478bd9Sstevel@tonic-gate static	pthread_mutex_t	dos_mutex = PTHREAD_MUTEX_INITIALIZER;
1087c478bd9Sstevel@tonic-gate static	rwlock_t	init_lk;
1097c478bd9Sstevel@tonic-gate 
1107c478bd9Sstevel@tonic-gate /*
1117c478bd9Sstevel@tonic-gate  * This returns an error message to libpicl
1127c478bd9Sstevel@tonic-gate  */
1137c478bd9Sstevel@tonic-gate static void
1147c478bd9Sstevel@tonic-gate picld_return_error(picl_callnumber_t cnum, picl_errno_t err)
1157c478bd9Sstevel@tonic-gate {
1167c478bd9Sstevel@tonic-gate 	picl_reterror_t	ret_error;
1177c478bd9Sstevel@tonic-gate 
1187c478bd9Sstevel@tonic-gate 	ret_error.cnum = PICL_CNUM_ERROR;
1197c478bd9Sstevel@tonic-gate 	ret_error.in_cnum = cnum;
1207c478bd9Sstevel@tonic-gate 	ret_error.errnum = err;
1217c478bd9Sstevel@tonic-gate 	(void) rw_unlock(&init_lk);
1227c478bd9Sstevel@tonic-gate 	(void) door_return((char *)&ret_error, sizeof (picl_reterror_t), NULL,
1237c478bd9Sstevel@tonic-gate 	    0);
1247c478bd9Sstevel@tonic-gate }
1257c478bd9Sstevel@tonic-gate 
1267c478bd9Sstevel@tonic-gate /*
1277c478bd9Sstevel@tonic-gate  * picld_init is called when a picl_initialize request is received
1287c478bd9Sstevel@tonic-gate  */
1297c478bd9Sstevel@tonic-gate static void
1307c478bd9Sstevel@tonic-gate picld_init(picl_service_t *req)
1317c478bd9Sstevel@tonic-gate {
1327c478bd9Sstevel@tonic-gate 	picl_retinit_t	ret_init;
1337c478bd9Sstevel@tonic-gate 	int	clmajrev;
1347c478bd9Sstevel@tonic-gate 
1357c478bd9Sstevel@tonic-gate 	clmajrev = PICL_CLIENT_REV(req->req_init.clrev);
1367c478bd9Sstevel@tonic-gate 
1377c478bd9Sstevel@tonic-gate 	if (clmajrev < PICL_VERSION_1)
1387c478bd9Sstevel@tonic-gate 		picld_return_error(req->req_init.cnum, PICL_NOTSUPPORTED);
1397c478bd9Sstevel@tonic-gate 
1407c478bd9Sstevel@tonic-gate 	ret_init.cnum = req->req_init.cnum;
1417c478bd9Sstevel@tonic-gate 	ret_init.rev = PICLD_VERSION(PICLD_MAJOR_REV, PICLD_MINOR_REV);
1427c478bd9Sstevel@tonic-gate 
1437c478bd9Sstevel@tonic-gate 	(void) rw_unlock(&init_lk);
1447c478bd9Sstevel@tonic-gate 	(void) door_return((char *)&ret_init, sizeof (picl_retinit_t), NULL, 0);
1457c478bd9Sstevel@tonic-gate }
1467c478bd9Sstevel@tonic-gate 
1477c478bd9Sstevel@tonic-gate /*
1487c478bd9Sstevel@tonic-gate  * picld_fini is called when a picl_shutdown request is received
1497c478bd9Sstevel@tonic-gate  */
1507c478bd9Sstevel@tonic-gate static void
1517c478bd9Sstevel@tonic-gate picld_fini(picl_service_t *in)
1527c478bd9Sstevel@tonic-gate {
1537c478bd9Sstevel@tonic-gate 	picl_retfini_t	ret;
1547c478bd9Sstevel@tonic-gate 
1557c478bd9Sstevel@tonic-gate 	ret.cnum = in->req_fini.cnum;
1567c478bd9Sstevel@tonic-gate 
1577c478bd9Sstevel@tonic-gate 	(void) rw_unlock(&init_lk);
1587c478bd9Sstevel@tonic-gate 	(void) door_return((char *)&ret, sizeof (picl_retfini_t), NULL, 0);
1597c478bd9Sstevel@tonic-gate }
1607c478bd9Sstevel@tonic-gate 
1617c478bd9Sstevel@tonic-gate static void
1627c478bd9Sstevel@tonic-gate picld_ping(picl_service_t *in)
1637c478bd9Sstevel@tonic-gate {
1647c478bd9Sstevel@tonic-gate 	picl_retping_t	ret;
1657c478bd9Sstevel@tonic-gate 
1667c478bd9Sstevel@tonic-gate 	ret.cnum = in->req_ping.cnum;
1677c478bd9Sstevel@tonic-gate 
1687c478bd9Sstevel@tonic-gate 	(void) rw_unlock(&init_lk);
1697c478bd9Sstevel@tonic-gate 	(void) door_return((char *)&ret, sizeof (picl_retping_t), NULL, 0);
1707c478bd9Sstevel@tonic-gate }
1717c478bd9Sstevel@tonic-gate 
1727c478bd9Sstevel@tonic-gate /*
1737c478bd9Sstevel@tonic-gate  * picld_wait is called when a picl_wait request is received
1747c478bd9Sstevel@tonic-gate  */
1757c478bd9Sstevel@tonic-gate static void
1767c478bd9Sstevel@tonic-gate picld_wait(picl_service_t *in)
1777c478bd9Sstevel@tonic-gate {
1787c478bd9Sstevel@tonic-gate 	picl_retwait_t	ret;
1797c478bd9Sstevel@tonic-gate 	int		err;
1807c478bd9Sstevel@tonic-gate 
1817c478bd9Sstevel@tonic-gate 	ret.cnum = in->req_wait.cnum;
1827c478bd9Sstevel@tonic-gate 
1837c478bd9Sstevel@tonic-gate 	err = xptree_refresh_notify(in->req_wait.secs);
1847c478bd9Sstevel@tonic-gate 	ret.retcode = err;
1857c478bd9Sstevel@tonic-gate 
1867c478bd9Sstevel@tonic-gate 	(void) rw_unlock(&init_lk);
1877c478bd9Sstevel@tonic-gate 	(void) door_return((char *)&ret, sizeof (picl_retwait_t), NULL, 0);
1887c478bd9Sstevel@tonic-gate }
1897c478bd9Sstevel@tonic-gate 
1907c478bd9Sstevel@tonic-gate /*
1917c478bd9Sstevel@tonic-gate  * This function returns the handle of the root node of the PICL tree
1927c478bd9Sstevel@tonic-gate  */
1937c478bd9Sstevel@tonic-gate static void
1947c478bd9Sstevel@tonic-gate picld_getroot(picl_service_t *in)
1957c478bd9Sstevel@tonic-gate {
1967c478bd9Sstevel@tonic-gate 	picl_retroot_t	ret;
1977c478bd9Sstevel@tonic-gate 	int		err;
1987c478bd9Sstevel@tonic-gate 
1997c478bd9Sstevel@tonic-gate 	ret.cnum = PICL_CNUM_GETROOT;
2007c478bd9Sstevel@tonic-gate 	err = ptree_get_root(&ret.rnode);
2017c478bd9Sstevel@tonic-gate 	if (err != PICL_SUCCESS)
2027c478bd9Sstevel@tonic-gate 		picld_return_error(in->in.cnum, err);
2037c478bd9Sstevel@tonic-gate 	cvt_ptree2picl(&ret.rnode);
2047c478bd9Sstevel@tonic-gate 	(void) rw_unlock(&init_lk);
2057c478bd9Sstevel@tonic-gate 	(void) door_return((char *)&ret, sizeof (picl_retroot_t), NULL, 0);
2067c478bd9Sstevel@tonic-gate }
2077c478bd9Sstevel@tonic-gate 
2087c478bd9Sstevel@tonic-gate /*
2097c478bd9Sstevel@tonic-gate  * This function returns the value of the PICL property
2107c478bd9Sstevel@tonic-gate  */
2117c478bd9Sstevel@tonic-gate static void
2127c478bd9Sstevel@tonic-gate picld_get_attrval(picl_service_t *in)
2137c478bd9Sstevel@tonic-gate {
2147c478bd9Sstevel@tonic-gate 	picl_retattrval_t	*ret;
2157c478bd9Sstevel@tonic-gate 	int			err;
2167c478bd9Sstevel@tonic-gate 	size_t			vbufsize;
2177c478bd9Sstevel@tonic-gate 	size_t			len;
2187c478bd9Sstevel@tonic-gate 	door_cred_t		cred;
2197c478bd9Sstevel@tonic-gate 	picl_prophdl_t		ptreeh;
2207c478bd9Sstevel@tonic-gate 	ptree_propinfo_t	pinfo;
2217c478bd9Sstevel@tonic-gate 
2227c478bd9Sstevel@tonic-gate 	if (door_cred(&cred) < 0)
2237c478bd9Sstevel@tonic-gate 		picld_return_error(in->in.cnum, PICL_FAILURE);
2247c478bd9Sstevel@tonic-gate 
2257c478bd9Sstevel@tonic-gate 	err = cvt_picl2ptree(in->req_attrval.attr, &ptreeh);
2267c478bd9Sstevel@tonic-gate 	if (err != PICL_SUCCESS)
2277c478bd9Sstevel@tonic-gate 		picld_return_error(in->in.cnum, err);
2287c478bd9Sstevel@tonic-gate 
2297c478bd9Sstevel@tonic-gate 	err = ptree_get_propinfo(ptreeh, &pinfo);
2307c478bd9Sstevel@tonic-gate 	if (err != PICL_SUCCESS)
2317c478bd9Sstevel@tonic-gate 		picld_return_error(in->in.cnum, err);
2327c478bd9Sstevel@tonic-gate 
2337c478bd9Sstevel@tonic-gate 	if (!(pinfo.piclinfo.accessmode & PICL_READ))
2347c478bd9Sstevel@tonic-gate 		picld_return_error(in->in.cnum, PICL_NOTREADABLE);
2357c478bd9Sstevel@tonic-gate 
2367c478bd9Sstevel@tonic-gate 	vbufsize = pinfo.piclinfo.size;
2377c478bd9Sstevel@tonic-gate 	vbufsize = MIN((size_t)in->req_attrval.bufsize, vbufsize);
2387c478bd9Sstevel@tonic-gate 
2397c478bd9Sstevel@tonic-gate 	len = sizeof (picl_retattrval_t) + vbufsize;
2407c478bd9Sstevel@tonic-gate 	ret = alloca(len);
2417c478bd9Sstevel@tonic-gate 	if (ret == NULL)
2427c478bd9Sstevel@tonic-gate 		picld_return_error(in->in.cnum, PICL_FAILURE);
2437c478bd9Sstevel@tonic-gate 	ret->cnum = PICL_CNUM_GETATTRVAL;
2447c478bd9Sstevel@tonic-gate 	ret->attr = in->req_attrval.attr;
2457c478bd9Sstevel@tonic-gate 	ret->nbytes = (uint32_t)vbufsize;
2467c478bd9Sstevel@tonic-gate 	err = xptree_get_propval_with_cred(ptreeh, ret->ret_buf, vbufsize,
2477c478bd9Sstevel@tonic-gate 	    cred);
2487c478bd9Sstevel@tonic-gate 	if (err != PICL_SUCCESS)
2497c478bd9Sstevel@tonic-gate 		picld_return_error(in->in.cnum, err);
2507c478bd9Sstevel@tonic-gate 
2517c478bd9Sstevel@tonic-gate 	/*
2527c478bd9Sstevel@tonic-gate 	 * adjust returned bytes for charstrings
2537c478bd9Sstevel@tonic-gate 	 */
2547c478bd9Sstevel@tonic-gate 	if (pinfo.piclinfo.type == PICL_PTYPE_CHARSTRING)
2557c478bd9Sstevel@tonic-gate 		ret->nbytes = (uint32_t)strlen(ret->ret_buf) + 1;
2567c478bd9Sstevel@tonic-gate 
2577c478bd9Sstevel@tonic-gate 	/*
2587c478bd9Sstevel@tonic-gate 	 * convert handle values to picl handles
2597c478bd9Sstevel@tonic-gate 	 */
2607c478bd9Sstevel@tonic-gate 	if ((pinfo.piclinfo.type == PICL_PTYPE_TABLE) ||
2617c478bd9Sstevel@tonic-gate 	    (pinfo.piclinfo.type == PICL_PTYPE_REFERENCE))
2627c478bd9Sstevel@tonic-gate 		cvt_ptree2picl(&ret->ret_nodeh);
2637c478bd9Sstevel@tonic-gate 	(void) rw_unlock(&init_lk);
2647c478bd9Sstevel@tonic-gate 	(void) door_return((char *)ret, sizeof (picl_retattrval_t) +
2657c478bd9Sstevel@tonic-gate 	    (size_t)ret->nbytes, NULL, 0);
2667c478bd9Sstevel@tonic-gate }
2677c478bd9Sstevel@tonic-gate 
2687c478bd9Sstevel@tonic-gate /*
2697c478bd9Sstevel@tonic-gate  * This function returns the value of the PICL property specified by
2707c478bd9Sstevel@tonic-gate  * its name.
2717c478bd9Sstevel@tonic-gate  */
2727c478bd9Sstevel@tonic-gate static void
2737c478bd9Sstevel@tonic-gate picld_get_attrval_by_name(picl_service_t *in)
2747c478bd9Sstevel@tonic-gate {
2757c478bd9Sstevel@tonic-gate 	picl_retattrvalbyname_t	*ret;
2767c478bd9Sstevel@tonic-gate 	int			err;
2777c478bd9Sstevel@tonic-gate 	size_t			vbufsize;
2787c478bd9Sstevel@tonic-gate 	size_t			len;
2797c478bd9Sstevel@tonic-gate 	door_cred_t		cred;
2807c478bd9Sstevel@tonic-gate 	picl_nodehdl_t		ptreeh;
2817c478bd9Sstevel@tonic-gate 	ptree_propinfo_t	pinfo;
2827c478bd9Sstevel@tonic-gate 
2837c478bd9Sstevel@tonic-gate 	if (door_cred(&cred) < 0)
2847c478bd9Sstevel@tonic-gate 		picld_return_error(in->in.cnum, PICL_FAILURE);
2857c478bd9Sstevel@tonic-gate 
2867c478bd9Sstevel@tonic-gate 	err = cvt_picl2ptree(in->req_attrvalbyname.nodeh, &ptreeh);
2877c478bd9Sstevel@tonic-gate 	if (err != PICL_SUCCESS)
2887c478bd9Sstevel@tonic-gate 		picld_return_error(in->in.cnum, err);
2897c478bd9Sstevel@tonic-gate 
2907c478bd9Sstevel@tonic-gate 	err = xptree_get_propinfo_by_name(ptreeh,
2917c478bd9Sstevel@tonic-gate 	    in->req_attrvalbyname.propname, &pinfo);
2927c478bd9Sstevel@tonic-gate 	if (err != PICL_SUCCESS)
2937c478bd9Sstevel@tonic-gate 		picld_return_error(in->in.cnum, err);
2947c478bd9Sstevel@tonic-gate 
2957c478bd9Sstevel@tonic-gate 	if (!(pinfo.piclinfo.accessmode & PICL_READ))
2967c478bd9Sstevel@tonic-gate 		picld_return_error(in->in.cnum, PICL_NOTREADABLE);
2977c478bd9Sstevel@tonic-gate 
2987c478bd9Sstevel@tonic-gate 	/*
2997c478bd9Sstevel@tonic-gate 	 * allocate the minimum of piclinfo.size and input bufsize
3007c478bd9Sstevel@tonic-gate 	 */
3017c478bd9Sstevel@tonic-gate 	vbufsize = pinfo.piclinfo.size;
3027c478bd9Sstevel@tonic-gate 	vbufsize = MIN((size_t)in->req_attrvalbyname.bufsize, vbufsize);
3037c478bd9Sstevel@tonic-gate 	len = sizeof (picl_retattrvalbyname_t) + vbufsize;
3047c478bd9Sstevel@tonic-gate 	ret = alloca(len);
3057c478bd9Sstevel@tonic-gate 	if (ret == NULL)
3067c478bd9Sstevel@tonic-gate 		picld_return_error(in->in.cnum, PICL_FAILURE);
3077c478bd9Sstevel@tonic-gate 	ret->cnum = PICL_CNUM_GETATTRVALBYNAME;
3087c478bd9Sstevel@tonic-gate 	ret->nodeh = in->req_attrvalbyname.nodeh;
3097c478bd9Sstevel@tonic-gate 	(void) strcpy(ret->propname, in->req_attrvalbyname.propname);
3107c478bd9Sstevel@tonic-gate 	ret->nbytes = (uint32_t)vbufsize;
3117c478bd9Sstevel@tonic-gate 
3127c478bd9Sstevel@tonic-gate 	err = xptree_get_propval_by_name_with_cred(ptreeh,
3137c478bd9Sstevel@tonic-gate 	    in->req_attrvalbyname.propname, ret->ret_buf, vbufsize,
3147c478bd9Sstevel@tonic-gate 	    cred);
3157c478bd9Sstevel@tonic-gate 	if (err != PICL_SUCCESS)
3167c478bd9Sstevel@tonic-gate 		picld_return_error(in->in.cnum, err);
3177c478bd9Sstevel@tonic-gate 	/*
3187c478bd9Sstevel@tonic-gate 	 * adjust returned value size for charstrings
3197c478bd9Sstevel@tonic-gate 	 */
3207c478bd9Sstevel@tonic-gate 	if (pinfo.piclinfo.type == PICL_PTYPE_CHARSTRING)
3217c478bd9Sstevel@tonic-gate 		ret->nbytes = (uint32_t)strlen(ret->ret_buf) + 1;
3227c478bd9Sstevel@tonic-gate 
3237c478bd9Sstevel@tonic-gate 	if ((pinfo.piclinfo.type == PICL_PTYPE_TABLE) ||
3247c478bd9Sstevel@tonic-gate 	    (pinfo.piclinfo.type == PICL_PTYPE_REFERENCE))
3257c478bd9Sstevel@tonic-gate 		cvt_ptree2picl(&ret->ret_nodeh);
3267c478bd9Sstevel@tonic-gate 
3277c478bd9Sstevel@tonic-gate 	(void) rw_unlock(&init_lk);
3287c478bd9Sstevel@tonic-gate 	(void) door_return((char *)ret, sizeof (picl_retattrvalbyname_t) +
3297c478bd9Sstevel@tonic-gate 	    (size_t)ret->nbytes, NULL, 0);
3307c478bd9Sstevel@tonic-gate }
3317c478bd9Sstevel@tonic-gate 
3327c478bd9Sstevel@tonic-gate /*
3337c478bd9Sstevel@tonic-gate  * This function sets a property value
3347c478bd9Sstevel@tonic-gate  */
3357c478bd9Sstevel@tonic-gate static void
3367c478bd9Sstevel@tonic-gate picld_set_attrval(picl_service_t *in)
3377c478bd9Sstevel@tonic-gate {
3387c478bd9Sstevel@tonic-gate 	picl_retsetattrval_t	ret;
3397c478bd9Sstevel@tonic-gate 	int			err;
3407c478bd9Sstevel@tonic-gate 	door_cred_t		cred;
3417c478bd9Sstevel@tonic-gate 	picl_prophdl_t		ptreeh;
3427c478bd9Sstevel@tonic-gate 	ptree_propinfo_t	pinfo;
3437c478bd9Sstevel@tonic-gate 
3447c478bd9Sstevel@tonic-gate 	if (door_cred(&cred) < 0)
3457c478bd9Sstevel@tonic-gate 		picld_return_error(in->in.cnum, PICL_FAILURE);
3467c478bd9Sstevel@tonic-gate 
3477c478bd9Sstevel@tonic-gate 	err = cvt_picl2ptree(in->req_setattrval.attr, &ptreeh);
3487c478bd9Sstevel@tonic-gate 	if (err != PICL_SUCCESS)
3497c478bd9Sstevel@tonic-gate 		picld_return_error(in->in.cnum, err);
3507c478bd9Sstevel@tonic-gate 
3517c478bd9Sstevel@tonic-gate 	err = ptree_get_propinfo(ptreeh, &pinfo);
3527c478bd9Sstevel@tonic-gate 	if (err != PICL_SUCCESS)
3537c478bd9Sstevel@tonic-gate 		picld_return_error(in->in.cnum, err);
3547c478bd9Sstevel@tonic-gate 
3557c478bd9Sstevel@tonic-gate 	if (!(pinfo.piclinfo.accessmode & PICL_WRITE))
3567c478bd9Sstevel@tonic-gate 		picld_return_error(in->in.cnum, PICL_NOTWRITABLE);
3577c478bd9Sstevel@tonic-gate 	/*
3587c478bd9Sstevel@tonic-gate 	 * For non-volatile prop, only super user can set its value.
3597c478bd9Sstevel@tonic-gate 	 */
3607c478bd9Sstevel@tonic-gate 	if (!(pinfo.piclinfo.accessmode & PICL_VOLATILE) &&
3617c478bd9Sstevel@tonic-gate 	    (cred.dc_euid != SUPER_USER))
3627c478bd9Sstevel@tonic-gate 		picld_return_error(in->in.cnum, PICL_PERMDENIED);
3637c478bd9Sstevel@tonic-gate 
3647c478bd9Sstevel@tonic-gate 	ret.cnum = PICL_CNUM_SETATTRVAL;
3657c478bd9Sstevel@tonic-gate 	ret.attr = in->req_setattrval.attr;
3667c478bd9Sstevel@tonic-gate 
3677c478bd9Sstevel@tonic-gate 	err = xptree_update_propval_with_cred(ptreeh, in->req_setattrval.valbuf,
3687c478bd9Sstevel@tonic-gate 	    (size_t)in->req_setattrval.bufsize, cred);
3697c478bd9Sstevel@tonic-gate 
3707c478bd9Sstevel@tonic-gate 	if (err != PICL_SUCCESS)
3717c478bd9Sstevel@tonic-gate 		picld_return_error(in->in.cnum, err);
3727c478bd9Sstevel@tonic-gate 
3737c478bd9Sstevel@tonic-gate 	(void) rw_unlock(&init_lk);
3747c478bd9Sstevel@tonic-gate 	(void) door_return((char *)&ret, sizeof (picl_retsetattrval_t), NULL,
3757c478bd9Sstevel@tonic-gate 	    0);
3767c478bd9Sstevel@tonic-gate }
3777c478bd9Sstevel@tonic-gate 
3787c478bd9Sstevel@tonic-gate /*
3797c478bd9Sstevel@tonic-gate  * This function sets the value of a property specified by its name.
3807c478bd9Sstevel@tonic-gate  */
3817c478bd9Sstevel@tonic-gate static void
3827c478bd9Sstevel@tonic-gate picld_set_attrval_by_name(picl_service_t *in)
3837c478bd9Sstevel@tonic-gate {
3847c478bd9Sstevel@tonic-gate 	picl_retsetattrvalbyname_t	ret;
3857c478bd9Sstevel@tonic-gate 	int				err;
3867c478bd9Sstevel@tonic-gate 	door_cred_t			cred;
3877c478bd9Sstevel@tonic-gate 	picl_prophdl_t			ptreeh;
3887c478bd9Sstevel@tonic-gate 	ptree_propinfo_t		pinfo;
3897c478bd9Sstevel@tonic-gate 
3907c478bd9Sstevel@tonic-gate 	if (door_cred(&cred) < 0)
3917c478bd9Sstevel@tonic-gate 		picld_return_error(in->in.cnum, PICL_FAILURE);
3927c478bd9Sstevel@tonic-gate 
3937c478bd9Sstevel@tonic-gate 	err = cvt_picl2ptree(in->req_setattrvalbyname.nodeh, &ptreeh);
3947c478bd9Sstevel@tonic-gate 	if (err != PICL_SUCCESS)
3957c478bd9Sstevel@tonic-gate 		picld_return_error(in->in.cnum, err);
3967c478bd9Sstevel@tonic-gate 
3977c478bd9Sstevel@tonic-gate 	err = xptree_get_propinfo_by_name(ptreeh,
3987c478bd9Sstevel@tonic-gate 	    in->req_setattrvalbyname.propname, &pinfo);
3997c478bd9Sstevel@tonic-gate 	if (err != PICL_SUCCESS)
4007c478bd9Sstevel@tonic-gate 		picld_return_error(in->in.cnum, err);
4017c478bd9Sstevel@tonic-gate 
4027c478bd9Sstevel@tonic-gate 	if (!(pinfo.piclinfo.accessmode & PICL_WRITE))
4037c478bd9Sstevel@tonic-gate 		picld_return_error(in->in.cnum, PICL_NOTWRITABLE);
4047c478bd9Sstevel@tonic-gate 
4057c478bd9Sstevel@tonic-gate 	/*
4067c478bd9Sstevel@tonic-gate 	 * For non-volatile prop, only super user can set its value.
4077c478bd9Sstevel@tonic-gate 	 */
4087c478bd9Sstevel@tonic-gate 	if (!(pinfo.piclinfo.accessmode & PICL_VOLATILE) &&
4097c478bd9Sstevel@tonic-gate 	    (cred.dc_euid != SUPER_USER))
4107c478bd9Sstevel@tonic-gate 		picld_return_error(in->in.cnum, PICL_PERMDENIED);
4117c478bd9Sstevel@tonic-gate 
4127c478bd9Sstevel@tonic-gate 	ret.cnum = PICL_CNUM_SETATTRVALBYNAME;
4137c478bd9Sstevel@tonic-gate 	ret.nodeh = in->req_setattrvalbyname.nodeh;
4147c478bd9Sstevel@tonic-gate 	(void) strcpy(ret.propname, in->req_setattrvalbyname.propname);
4157c478bd9Sstevel@tonic-gate 
4167c478bd9Sstevel@tonic-gate 	err = xptree_update_propval_by_name_with_cred(ptreeh,
4177c478bd9Sstevel@tonic-gate 		in->req_setattrvalbyname.propname,
4187c478bd9Sstevel@tonic-gate 		in->req_setattrvalbyname.valbuf,
4197c478bd9Sstevel@tonic-gate 		(size_t)in->req_setattrvalbyname.bufsize,
4207c478bd9Sstevel@tonic-gate 		cred);
4217c478bd9Sstevel@tonic-gate 
4227c478bd9Sstevel@tonic-gate 	if (err != PICL_SUCCESS)
4237c478bd9Sstevel@tonic-gate 		picld_return_error(in->in.cnum, err);
4247c478bd9Sstevel@tonic-gate 
4257c478bd9Sstevel@tonic-gate 	(void) rw_unlock(&init_lk);
4267c478bd9Sstevel@tonic-gate 	(void) door_return((char *)&ret, sizeof (picl_retsetattrvalbyname_t),
4277c478bd9Sstevel@tonic-gate 	    NULL, 0);
4287c478bd9Sstevel@tonic-gate }
4297c478bd9Sstevel@tonic-gate 
4307c478bd9Sstevel@tonic-gate /*
4317c478bd9Sstevel@tonic-gate  * This function returns the property information
4327c478bd9Sstevel@tonic-gate  */
4337c478bd9Sstevel@tonic-gate static void
4347c478bd9Sstevel@tonic-gate picld_get_attrinfo(picl_service_t *in)
4357c478bd9Sstevel@tonic-gate {
4367c478bd9Sstevel@tonic-gate 	picl_retattrinfo_t	ret;
4377c478bd9Sstevel@tonic-gate 	int			err;
4387c478bd9Sstevel@tonic-gate 	ptree_propinfo_t	pinfo;
4397c478bd9Sstevel@tonic-gate 	picl_prophdl_t		ptreeh;
4407c478bd9Sstevel@tonic-gate 
4417c478bd9Sstevel@tonic-gate 	err = cvt_picl2ptree(in->req_attrinfo.attr, &ptreeh);
4427c478bd9Sstevel@tonic-gate 	if (err != PICL_SUCCESS)
4437c478bd9Sstevel@tonic-gate 		picld_return_error(in->in.cnum, err);
4447c478bd9Sstevel@tonic-gate 
4457c478bd9Sstevel@tonic-gate 	ret.cnum = PICL_CNUM_GETATTRINFO;
4467c478bd9Sstevel@tonic-gate 	ret.attr = in->req_attrinfo.attr;
4477c478bd9Sstevel@tonic-gate 
4487c478bd9Sstevel@tonic-gate 	err = ptree_get_propinfo(ptreeh, &pinfo);
4497c478bd9Sstevel@tonic-gate 	if (err != PICL_SUCCESS)
4507c478bd9Sstevel@tonic-gate 		picld_return_error(in->in.cnum, err);
4517c478bd9Sstevel@tonic-gate 
4527c478bd9Sstevel@tonic-gate 	ret.type = pinfo.piclinfo.type;
4537c478bd9Sstevel@tonic-gate 	ret.accessmode = pinfo.piclinfo.accessmode;
4547c478bd9Sstevel@tonic-gate 	ret.size = (uint32_t)pinfo.piclinfo.size;
4557c478bd9Sstevel@tonic-gate 	(void) strcpy(ret.name, pinfo.piclinfo.name);
4567c478bd9Sstevel@tonic-gate 	(void) rw_unlock(&init_lk);
4577c478bd9Sstevel@tonic-gate 	(void) door_return((char *)&ret, sizeof (picl_retattrinfo_t), NULL, 0);
4587c478bd9Sstevel@tonic-gate }
4597c478bd9Sstevel@tonic-gate 
4607c478bd9Sstevel@tonic-gate /*
4617c478bd9Sstevel@tonic-gate  * This function returns the node's first property handle
4627c478bd9Sstevel@tonic-gate  */
4637c478bd9Sstevel@tonic-gate static void
4647c478bd9Sstevel@tonic-gate picld_get_first_attr(picl_service_t *in)
4657c478bd9Sstevel@tonic-gate {
4667c478bd9Sstevel@tonic-gate 	picl_retfirstattr_t	ret;
4677c478bd9Sstevel@tonic-gate 	int			err;
4687c478bd9Sstevel@tonic-gate 	picl_prophdl_t		ptreeh;
4697c478bd9Sstevel@tonic-gate 
4707c478bd9Sstevel@tonic-gate 	err = cvt_picl2ptree(in->req_firstattr.nodeh, &ptreeh);
4717c478bd9Sstevel@tonic-gate 	if (err != PICL_SUCCESS)
4727c478bd9Sstevel@tonic-gate 		picld_return_error(in->in.cnum, err);
4737c478bd9Sstevel@tonic-gate 
4747c478bd9Sstevel@tonic-gate 	ret.cnum = PICL_CNUM_GETFIRSTATTR;
4757c478bd9Sstevel@tonic-gate 	ret.nodeh = in->req_firstattr.nodeh;
4767c478bd9Sstevel@tonic-gate 
4777c478bd9Sstevel@tonic-gate 	err = ptree_get_first_prop(ptreeh, &ret.attr);
4787c478bd9Sstevel@tonic-gate 	if (err != PICL_SUCCESS)
4797c478bd9Sstevel@tonic-gate 		picld_return_error(in->in.cnum, err);
4807c478bd9Sstevel@tonic-gate 	cvt_ptree2picl(&ret.attr);
4817c478bd9Sstevel@tonic-gate 	(void) rw_unlock(&init_lk);
4827c478bd9Sstevel@tonic-gate 	(void) door_return((char *)&ret, sizeof (picl_retfirstattr_t), NULL, 0);
4837c478bd9Sstevel@tonic-gate }
4847c478bd9Sstevel@tonic-gate 
4857c478bd9Sstevel@tonic-gate /*
4867c478bd9Sstevel@tonic-gate  * This function returns the next property handle in list
4877c478bd9Sstevel@tonic-gate  */
4887c478bd9Sstevel@tonic-gate static void
4897c478bd9Sstevel@tonic-gate picld_get_next_attr(picl_service_t *in)
4907c478bd9Sstevel@tonic-gate {
4917c478bd9Sstevel@tonic-gate 	picl_retnextattr_t	ret;
4927c478bd9Sstevel@tonic-gate 	int			err;
4937c478bd9Sstevel@tonic-gate 	picl_prophdl_t		ptreeh;
4947c478bd9Sstevel@tonic-gate 
4957c478bd9Sstevel@tonic-gate 	err = cvt_picl2ptree(in->req_nextattr.attr, &ptreeh);
4967c478bd9Sstevel@tonic-gate 	if (err != PICL_SUCCESS)
4977c478bd9Sstevel@tonic-gate 		picld_return_error(in->in.cnum, err);
4987c478bd9Sstevel@tonic-gate 
4997c478bd9Sstevel@tonic-gate 	ret.cnum = PICL_CNUM_GETNEXTATTR;
5007c478bd9Sstevel@tonic-gate 	ret.attr = in->req_nextattr.attr;
5017c478bd9Sstevel@tonic-gate 
5027c478bd9Sstevel@tonic-gate 	err = ptree_get_next_prop(ptreeh, &ret.nextattr);
5037c478bd9Sstevel@tonic-gate 	if (err != PICL_SUCCESS)
5047c478bd9Sstevel@tonic-gate 		picld_return_error(in->in.cnum, err);
5057c478bd9Sstevel@tonic-gate 
5067c478bd9Sstevel@tonic-gate 	cvt_ptree2picl(&ret.nextattr);
5077c478bd9Sstevel@tonic-gate 
5087c478bd9Sstevel@tonic-gate 	(void) rw_unlock(&init_lk);
5097c478bd9Sstevel@tonic-gate 	(void) door_return((char *)&ret, sizeof (picl_retnextattr_t), NULL, 0);
5107c478bd9Sstevel@tonic-gate }
5117c478bd9Sstevel@tonic-gate 
5127c478bd9Sstevel@tonic-gate /*
5137c478bd9Sstevel@tonic-gate  * This function returns the handle of a property specified by its name
5147c478bd9Sstevel@tonic-gate  */
5157c478bd9Sstevel@tonic-gate static void
5167c478bd9Sstevel@tonic-gate picld_get_attr_by_name(picl_service_t *in)
5177c478bd9Sstevel@tonic-gate {
5187c478bd9Sstevel@tonic-gate 	picl_retattrbyname_t	ret;
5197c478bd9Sstevel@tonic-gate 	int			err;
5207c478bd9Sstevel@tonic-gate 	picl_prophdl_t		ptreeh;
5217c478bd9Sstevel@tonic-gate 
5227c478bd9Sstevel@tonic-gate 	err = cvt_picl2ptree(in->req_attrbyname.nodeh, &ptreeh);
5237c478bd9Sstevel@tonic-gate 	if (err != PICL_SUCCESS)
5247c478bd9Sstevel@tonic-gate 		picld_return_error(in->in.cnum, err);
5257c478bd9Sstevel@tonic-gate 
5267c478bd9Sstevel@tonic-gate 	ret.cnum = PICL_CNUM_GETATTRBYNAME;
5277c478bd9Sstevel@tonic-gate 	ret.nodeh = in->req_attrbyname.nodeh;
5287c478bd9Sstevel@tonic-gate 	(void) strcpy(ret.propname, in->req_attrbyname.propname);
5297c478bd9Sstevel@tonic-gate 
5307c478bd9Sstevel@tonic-gate 	err = ptree_get_prop_by_name(ptreeh, ret.propname, &ret.attr);
5317c478bd9Sstevel@tonic-gate 	if (err != PICL_SUCCESS)
5327c478bd9Sstevel@tonic-gate 		picld_return_error(in->in.cnum, err);
5337c478bd9Sstevel@tonic-gate 
5347c478bd9Sstevel@tonic-gate 	cvt_ptree2picl(&ret.attr);
5357c478bd9Sstevel@tonic-gate 	(void) rw_unlock(&init_lk);
5367c478bd9Sstevel@tonic-gate 	(void) door_return((char *)&ret, sizeof (picl_retattrbyname_t), NULL,
5377c478bd9Sstevel@tonic-gate 	    0);
5387c478bd9Sstevel@tonic-gate }
5397c478bd9Sstevel@tonic-gate 
5407c478bd9Sstevel@tonic-gate /*
5417c478bd9Sstevel@tonic-gate  * This function gets the next property on the same row in the table
5427c478bd9Sstevel@tonic-gate  */
5437c478bd9Sstevel@tonic-gate static void
5447c478bd9Sstevel@tonic-gate picld_get_attr_by_row(picl_service_t *in)
5457c478bd9Sstevel@tonic-gate {
5467c478bd9Sstevel@tonic-gate 	picl_retattrbyrow_t	ret;
5477c478bd9Sstevel@tonic-gate 	int			err;
5487c478bd9Sstevel@tonic-gate 	picl_prophdl_t		ptreeh;
5497c478bd9Sstevel@tonic-gate 
5507c478bd9Sstevel@tonic-gate 	err = cvt_picl2ptree(in->req_attrbyrow.attr, &ptreeh);
5517c478bd9Sstevel@tonic-gate 	if (err != PICL_SUCCESS)
5527c478bd9Sstevel@tonic-gate 		picld_return_error(in->in.cnum, err);
5537c478bd9Sstevel@tonic-gate 
5547c478bd9Sstevel@tonic-gate 	ret.cnum = PICL_CNUM_GETATTRBYROW;
5557c478bd9Sstevel@tonic-gate 	ret.attr = in->req_attrbyrow.attr;
5567c478bd9Sstevel@tonic-gate 
5577c478bd9Sstevel@tonic-gate 	err = ptree_get_next_by_row(ptreeh, &ret.rowattr);
5587c478bd9Sstevel@tonic-gate 	if (err != PICL_SUCCESS)
5597c478bd9Sstevel@tonic-gate 		picld_return_error(in->in.cnum, err);
5607c478bd9Sstevel@tonic-gate 	cvt_ptree2picl(&ret.rowattr);
5617c478bd9Sstevel@tonic-gate 
5627c478bd9Sstevel@tonic-gate 	(void) rw_unlock(&init_lk);
5637c478bd9Sstevel@tonic-gate 	(void) door_return((char *)&ret, sizeof (picl_retattrbyrow_t), NULL, 0);
5647c478bd9Sstevel@tonic-gate }
5657c478bd9Sstevel@tonic-gate 
5667c478bd9Sstevel@tonic-gate /*
5677c478bd9Sstevel@tonic-gate  * This function returns the handle of the next property in the same column
5687c478bd9Sstevel@tonic-gate  * of the table.
5697c478bd9Sstevel@tonic-gate  */
5707c478bd9Sstevel@tonic-gate static void
5717c478bd9Sstevel@tonic-gate picld_get_attr_by_col(picl_service_t *in)
5727c478bd9Sstevel@tonic-gate {
5737c478bd9Sstevel@tonic-gate 	picl_retattrbycol_t	ret;
5747c478bd9Sstevel@tonic-gate 	int			err;
5757c478bd9Sstevel@tonic-gate 	picl_prophdl_t		ptreeh;
5767c478bd9Sstevel@tonic-gate 
5777c478bd9Sstevel@tonic-gate 	err = cvt_picl2ptree(in->req_attrbycol.attr, &ptreeh);
5787c478bd9Sstevel@tonic-gate 	if (err != PICL_SUCCESS)
5797c478bd9Sstevel@tonic-gate 		picld_return_error(in->in.cnum, err);
5807c478bd9Sstevel@tonic-gate 
5817c478bd9Sstevel@tonic-gate 	ret.cnum = PICL_CNUM_GETATTRBYCOL;
5827c478bd9Sstevel@tonic-gate 	ret.attr = in->req_attrbycol.attr;
5837c478bd9Sstevel@tonic-gate 
5847c478bd9Sstevel@tonic-gate 	err = ptree_get_next_by_col(ptreeh, &ret.colattr);
5857c478bd9Sstevel@tonic-gate 	if (err != PICL_SUCCESS)
5867c478bd9Sstevel@tonic-gate 		picld_return_error(in->in.cnum, err);
5877c478bd9Sstevel@tonic-gate 
5887c478bd9Sstevel@tonic-gate 	cvt_ptree2picl(&ret.colattr);
5897c478bd9Sstevel@tonic-gate 
5907c478bd9Sstevel@tonic-gate 	(void) rw_unlock(&init_lk);
5917c478bd9Sstevel@tonic-gate 	(void) door_return((char *)&ret, sizeof (picl_retattrbycol_t), NULL, 0);
5927c478bd9Sstevel@tonic-gate }
5937c478bd9Sstevel@tonic-gate 
5947c478bd9Sstevel@tonic-gate /*
5957c478bd9Sstevel@tonic-gate  * This function finds the node in the PICLTREE that matches the given
5967c478bd9Sstevel@tonic-gate  * criteria and returns its handle.
5977c478bd9Sstevel@tonic-gate  */
5987c478bd9Sstevel@tonic-gate static void
5997c478bd9Sstevel@tonic-gate picld_find_node(picl_service_t *in)
6007c478bd9Sstevel@tonic-gate {
6017c478bd9Sstevel@tonic-gate 	picl_retfindnode_t	ret;
6027c478bd9Sstevel@tonic-gate 	int			err;
6037c478bd9Sstevel@tonic-gate 	picl_nodehdl_t		ptreeh;
6047c478bd9Sstevel@tonic-gate 
6057c478bd9Sstevel@tonic-gate 	err = cvt_picl2ptree(in->req_findnode.nodeh, &ptreeh);
6067c478bd9Sstevel@tonic-gate 	if (err != PICL_SUCCESS)
6077c478bd9Sstevel@tonic-gate 		picld_return_error(in->in.cnum, err);
6087c478bd9Sstevel@tonic-gate 
6097c478bd9Sstevel@tonic-gate 	ret.cnum = PICL_CNUM_FINDNODE;
6107c478bd9Sstevel@tonic-gate 
6117c478bd9Sstevel@tonic-gate 	err = ptree_find_node(ptreeh, in->req_findnode.propname,
6127c478bd9Sstevel@tonic-gate 	    in->req_findnode.ptype, in->req_findnode.valbuf,
6137c478bd9Sstevel@tonic-gate 	    in->req_findnode.valsize, &ret.rnodeh);
6147c478bd9Sstevel@tonic-gate 	if (err != PICL_SUCCESS)
6157c478bd9Sstevel@tonic-gate 		picld_return_error(in->in.cnum, err);
6167c478bd9Sstevel@tonic-gate 
6177c478bd9Sstevel@tonic-gate 	cvt_ptree2picl(&ret.rnodeh);
6187c478bd9Sstevel@tonic-gate 
6197c478bd9Sstevel@tonic-gate 	(void) rw_unlock(&init_lk);
6207c478bd9Sstevel@tonic-gate 	(void) door_return((char *)&ret, sizeof (ret), NULL, 0);
6217c478bd9Sstevel@tonic-gate }
6227c478bd9Sstevel@tonic-gate 
6237c478bd9Sstevel@tonic-gate /*
6247c478bd9Sstevel@tonic-gate  * This function finds the property/node that corresponds to the given path
6257c478bd9Sstevel@tonic-gate  * and returns its handle
6267c478bd9Sstevel@tonic-gate  */
6277c478bd9Sstevel@tonic-gate static void
6287c478bd9Sstevel@tonic-gate picld_get_node_by_path(picl_service_t *in)
6297c478bd9Sstevel@tonic-gate {
6307c478bd9Sstevel@tonic-gate 	picl_retnodebypath_t	ret;
6317c478bd9Sstevel@tonic-gate 	int			err;
6327c478bd9Sstevel@tonic-gate 
6337c478bd9Sstevel@tonic-gate 	ret.cnum = PICL_CNUM_NODEBYPATH;
6347c478bd9Sstevel@tonic-gate 	err = ptree_get_node_by_path(in->req_nodebypath.pathbuf, &ret.nodeh);
6357c478bd9Sstevel@tonic-gate 	if (err != PICL_SUCCESS)
6367c478bd9Sstevel@tonic-gate 		picld_return_error(in->in.cnum, err);
6377c478bd9Sstevel@tonic-gate 	cvt_ptree2picl(&ret.nodeh);
6387c478bd9Sstevel@tonic-gate 	(void) rw_unlock(&init_lk);
6397c478bd9Sstevel@tonic-gate 	(void) door_return((char *)&ret, sizeof (ret), NULL, 0);
6407c478bd9Sstevel@tonic-gate }
6417c478bd9Sstevel@tonic-gate 
6427c478bd9Sstevel@tonic-gate /*
6437c478bd9Sstevel@tonic-gate  * This function returns finds the frutree parent node for a given node
6447c478bd9Sstevel@tonic-gate  * and returns its handle
6457c478bd9Sstevel@tonic-gate  */
6467c478bd9Sstevel@tonic-gate static void
6477c478bd9Sstevel@tonic-gate picld_get_frutree_parent(picl_service_t *in)
6487c478bd9Sstevel@tonic-gate {
6497c478bd9Sstevel@tonic-gate 	picl_retfruparent_t	ret;
6507c478bd9Sstevel@tonic-gate 	int			err;
6517c478bd9Sstevel@tonic-gate 	picl_nodehdl_t		ptreeh;
6527c478bd9Sstevel@tonic-gate 
6537c478bd9Sstevel@tonic-gate 	err = cvt_picl2ptree(in->req_fruparent.devh, &ptreeh);
6547c478bd9Sstevel@tonic-gate 	if (err != PICL_SUCCESS)
6557c478bd9Sstevel@tonic-gate 		picld_return_error(in->in.cnum, err);
6567c478bd9Sstevel@tonic-gate 
6577c478bd9Sstevel@tonic-gate 	ret.cnum = PICL_CNUM_FRUTREEPARENT;
6587c478bd9Sstevel@tonic-gate 
6597c478bd9Sstevel@tonic-gate 	err = ptree_get_frutree_parent(ptreeh, &ret.fruh);
6607c478bd9Sstevel@tonic-gate 	if (err != PICL_SUCCESS)
6617c478bd9Sstevel@tonic-gate 		picld_return_error(in->in.cnum, err);
6627c478bd9Sstevel@tonic-gate 	cvt_ptree2picl(&ret.fruh);
6637c478bd9Sstevel@tonic-gate 
6647c478bd9Sstevel@tonic-gate 	(void) rw_unlock(&init_lk);
6657c478bd9Sstevel@tonic-gate 	(void) door_return((char *)&ret, sizeof (ret), NULL, 0);
6667c478bd9Sstevel@tonic-gate }
6677c478bd9Sstevel@tonic-gate 
6687c478bd9Sstevel@tonic-gate /*
6697c478bd9Sstevel@tonic-gate  * This function is called when an unknown client request is received.
6707c478bd9Sstevel@tonic-gate  */
6717c478bd9Sstevel@tonic-gate static void
6727c478bd9Sstevel@tonic-gate picld_unknown_service(picl_service_t *in)
6737c478bd9Sstevel@tonic-gate {
6747c478bd9Sstevel@tonic-gate 	picld_return_error(in->in.cnum, PICL_UNKNOWNSERVICE);
6757c478bd9Sstevel@tonic-gate }
6767c478bd9Sstevel@tonic-gate 
6777c478bd9Sstevel@tonic-gate static void
6787c478bd9Sstevel@tonic-gate check_denial_of_service(int cnum)
6797c478bd9Sstevel@tonic-gate {
6807c478bd9Sstevel@tonic-gate 	hrtime_t	window;
6817c478bd9Sstevel@tonic-gate 	hrtime_t	current;
6827c478bd9Sstevel@tonic-gate 	int		dos_flag;
6837c478bd9Sstevel@tonic-gate 
6847c478bd9Sstevel@tonic-gate 	current = gethrtime();
6857c478bd9Sstevel@tonic-gate 	dos_flag = 0;
6867c478bd9Sstevel@tonic-gate 
6877c478bd9Sstevel@tonic-gate 	if (pthread_mutex_lock(&dos_mutex) != 0)
6887c478bd9Sstevel@tonic-gate 		picld_return_error(cnum, PICL_FAILURE);
6897c478bd9Sstevel@tonic-gate 
6907c478bd9Sstevel@tonic-gate 	++service_requests;
6917c478bd9Sstevel@tonic-gate 	window = current - orig_time;
6927c478bd9Sstevel@tonic-gate 	if (window > MILLI_TO_NANO(sliding_interval_ms)) {
6937c478bd9Sstevel@tonic-gate 		orig_time = current;
6947c478bd9Sstevel@tonic-gate 		service_requests = 1;
6957c478bd9Sstevel@tonic-gate 	}
6967c478bd9Sstevel@tonic-gate 
6977c478bd9Sstevel@tonic-gate 	if (service_requests > dos_req_limit)
6987c478bd9Sstevel@tonic-gate 		dos_flag = 1;
6997c478bd9Sstevel@tonic-gate 
7007c478bd9Sstevel@tonic-gate 	if (pthread_mutex_unlock(&dos_mutex) != 0)
7017c478bd9Sstevel@tonic-gate 		picld_return_error(cnum, PICL_FAILURE);
7027c478bd9Sstevel@tonic-gate 
7037c478bd9Sstevel@tonic-gate 	if (dos_flag)
7047c478bd9Sstevel@tonic-gate 		(void) poll(NULL, 0, dos_ms);
7057c478bd9Sstevel@tonic-gate }
7067c478bd9Sstevel@tonic-gate 
7077c478bd9Sstevel@tonic-gate 
7087c478bd9Sstevel@tonic-gate /* ARGSUSED */
7097c478bd9Sstevel@tonic-gate static void
7107c478bd9Sstevel@tonic-gate picld_door_handler(void *cookie, char *argp, size_t asize,
7117c478bd9Sstevel@tonic-gate     door_desc_t *dp, uint_t n_desc)
7127c478bd9Sstevel@tonic-gate {
7137c478bd9Sstevel@tonic-gate 	picl_service_t  *req;
7147c478bd9Sstevel@tonic-gate 
7157c478bd9Sstevel@tonic-gate 	/*LINTED*/
7167c478bd9Sstevel@tonic-gate 	req = (picl_service_t *)argp;
7177c478bd9Sstevel@tonic-gate 
7187c478bd9Sstevel@tonic-gate 	if (req == NULL)
7197c478bd9Sstevel@tonic-gate 		(void) door_return((char *)req, 0, NULL, 0);
7207c478bd9Sstevel@tonic-gate 
7217c478bd9Sstevel@tonic-gate 	check_denial_of_service(req->in.cnum);
7227c478bd9Sstevel@tonic-gate 
7237c478bd9Sstevel@tonic-gate 	(void) rw_rdlock(&init_lk);
7247c478bd9Sstevel@tonic-gate 	switch (req->in.cnum) {	/* client call number */
7257c478bd9Sstevel@tonic-gate 	case PICL_CNUM_INIT:
7267c478bd9Sstevel@tonic-gate 		/*LINTED*/
7277c478bd9Sstevel@tonic-gate 		picld_init((picl_service_t *)argp);
7287c478bd9Sstevel@tonic-gate 		break;
7297c478bd9Sstevel@tonic-gate 	case PICL_CNUM_FINI:
7307c478bd9Sstevel@tonic-gate 		/*LINTED*/
7317c478bd9Sstevel@tonic-gate 		picld_fini((picl_service_t *)argp);
7327c478bd9Sstevel@tonic-gate 		break;
7337c478bd9Sstevel@tonic-gate 	case PICL_CNUM_GETROOT:
7347c478bd9Sstevel@tonic-gate 		/*LINTED*/
7357c478bd9Sstevel@tonic-gate 		picld_getroot((picl_service_t *)argp);
7367c478bd9Sstevel@tonic-gate 		break;
7377c478bd9Sstevel@tonic-gate 	case PICL_CNUM_GETATTRVAL:
7387c478bd9Sstevel@tonic-gate 		/*LINTED*/
7397c478bd9Sstevel@tonic-gate 		picld_get_attrval((picl_service_t *)argp);
7407c478bd9Sstevel@tonic-gate 		break;
7417c478bd9Sstevel@tonic-gate 	case PICL_CNUM_GETATTRVALBYNAME:
7427c478bd9Sstevel@tonic-gate 		/*LINTED*/
7437c478bd9Sstevel@tonic-gate 		picld_get_attrval_by_name((picl_service_t *)argp);
7447c478bd9Sstevel@tonic-gate 		break;
7457c478bd9Sstevel@tonic-gate 	case PICL_CNUM_GETATTRINFO:
7467c478bd9Sstevel@tonic-gate 		/*LINTED*/
7477c478bd9Sstevel@tonic-gate 		picld_get_attrinfo((picl_service_t *)argp);
7487c478bd9Sstevel@tonic-gate 		break;
7497c478bd9Sstevel@tonic-gate 	case PICL_CNUM_GETFIRSTATTR:
7507c478bd9Sstevel@tonic-gate 		/*LINTED*/
7517c478bd9Sstevel@tonic-gate 		picld_get_first_attr((picl_service_t *)argp);
7527c478bd9Sstevel@tonic-gate 		break;
7537c478bd9Sstevel@tonic-gate 	case PICL_CNUM_GETNEXTATTR:
7547c478bd9Sstevel@tonic-gate 		/*LINTED*/
7557c478bd9Sstevel@tonic-gate 		picld_get_next_attr((picl_service_t *)argp);
7567c478bd9Sstevel@tonic-gate 		break;
7577c478bd9Sstevel@tonic-gate 	case PICL_CNUM_GETATTRBYNAME:
7587c478bd9Sstevel@tonic-gate 		/*LINTED*/
7597c478bd9Sstevel@tonic-gate 		picld_get_attr_by_name((picl_service_t *)argp);
7607c478bd9Sstevel@tonic-gate 		break;
7617c478bd9Sstevel@tonic-gate 	case PICL_CNUM_GETATTRBYROW:
7627c478bd9Sstevel@tonic-gate 		/*LINTED*/
7637c478bd9Sstevel@tonic-gate 		picld_get_attr_by_row((picl_service_t *)argp);
7647c478bd9Sstevel@tonic-gate 		break;
7657c478bd9Sstevel@tonic-gate 	case PICL_CNUM_GETATTRBYCOL:
7667c478bd9Sstevel@tonic-gate 		/*LINTED*/
7677c478bd9Sstevel@tonic-gate 		picld_get_attr_by_col((picl_service_t *)argp);
7687c478bd9Sstevel@tonic-gate 		break;
7697c478bd9Sstevel@tonic-gate 	case PICL_CNUM_SETATTRVAL:
7707c478bd9Sstevel@tonic-gate 		/*LINTED*/
7717c478bd9Sstevel@tonic-gate 		picld_set_attrval((picl_service_t *)argp);
7727c478bd9Sstevel@tonic-gate 		break;
7737c478bd9Sstevel@tonic-gate 	case PICL_CNUM_SETATTRVALBYNAME:
7747c478bd9Sstevel@tonic-gate 		/*LINTED*/
7757c478bd9Sstevel@tonic-gate 		picld_set_attrval_by_name((picl_service_t *)argp);
7767c478bd9Sstevel@tonic-gate 		break;
7777c478bd9Sstevel@tonic-gate 	case PICL_CNUM_PING:
7787c478bd9Sstevel@tonic-gate 		/*LINTED*/
7797c478bd9Sstevel@tonic-gate 		picld_ping((picl_service_t *)argp);
7807c478bd9Sstevel@tonic-gate 		break;
7817c478bd9Sstevel@tonic-gate 	case PICL_CNUM_WAIT:
7827c478bd9Sstevel@tonic-gate 		/*LINTED*/
7837c478bd9Sstevel@tonic-gate 		picld_wait((picl_service_t *)argp);
7847c478bd9Sstevel@tonic-gate 		break;
7857c478bd9Sstevel@tonic-gate 	case PICL_CNUM_FINDNODE:
7867c478bd9Sstevel@tonic-gate 		/*LINTED*/
7877c478bd9Sstevel@tonic-gate 		picld_find_node((picl_service_t *)argp);
7887c478bd9Sstevel@tonic-gate 		break;
7897c478bd9Sstevel@tonic-gate 	case PICL_CNUM_NODEBYPATH:
7907c478bd9Sstevel@tonic-gate 		/*LINTED*/
7917c478bd9Sstevel@tonic-gate 		picld_get_node_by_path((picl_service_t *)argp);
7927c478bd9Sstevel@tonic-gate 		break;
7937c478bd9Sstevel@tonic-gate 	case PICL_CNUM_FRUTREEPARENT:
7947c478bd9Sstevel@tonic-gate 		/*LINTED*/
7957c478bd9Sstevel@tonic-gate 		picld_get_frutree_parent((picl_service_t *)argp);
7967c478bd9Sstevel@tonic-gate 		break;
7977c478bd9Sstevel@tonic-gate 	default:
7987c478bd9Sstevel@tonic-gate 		/*LINTED*/
7997c478bd9Sstevel@tonic-gate 		picld_unknown_service((picl_service_t *)argp);
8007c478bd9Sstevel@tonic-gate 		break;
8017c478bd9Sstevel@tonic-gate 	};
8027c478bd9Sstevel@tonic-gate 	/*NOTREACHED*/
8037c478bd9Sstevel@tonic-gate }
8047c478bd9Sstevel@tonic-gate 
8057c478bd9Sstevel@tonic-gate /* ARGSUSED */
8067c478bd9Sstevel@tonic-gate static void
8077c478bd9Sstevel@tonic-gate hup_handler(int sig, siginfo_t *siginfo, void *sigctx)
8087c478bd9Sstevel@tonic-gate {
8097c478bd9Sstevel@tonic-gate 	doreinit = 1;
8107c478bd9Sstevel@tonic-gate }
8117c478bd9Sstevel@tonic-gate 
8127c478bd9Sstevel@tonic-gate /*
8137c478bd9Sstevel@tonic-gate  * "ping" to see if a daemon is already running
8147c478bd9Sstevel@tonic-gate  */
8157c478bd9Sstevel@tonic-gate static int
8167c478bd9Sstevel@tonic-gate daemon_exists(void)
8177c478bd9Sstevel@tonic-gate {
8187c478bd9Sstevel@tonic-gate 	door_arg_t	darg;
8197c478bd9Sstevel@tonic-gate 	picl_reqping_t	req_ping;
8207c478bd9Sstevel@tonic-gate 	picl_retping_t	ret_ping;
8217c478bd9Sstevel@tonic-gate 	int		doorh;
8227c478bd9Sstevel@tonic-gate 	door_info_t	dinfo;
8237c478bd9Sstevel@tonic-gate 
8247c478bd9Sstevel@tonic-gate 	doorh = open(PICLD_DOOR, O_RDONLY);
8257c478bd9Sstevel@tonic-gate 	if (doorh < 0)
8267c478bd9Sstevel@tonic-gate 		return (0);
8277c478bd9Sstevel@tonic-gate 
8287c478bd9Sstevel@tonic-gate 	if (door_info(doorh, &dinfo) < 0) {
8297c478bd9Sstevel@tonic-gate 		(void) close(doorh);
8307c478bd9Sstevel@tonic-gate 		return (0);
8317c478bd9Sstevel@tonic-gate 	}
8327c478bd9Sstevel@tonic-gate 
8337c478bd9Sstevel@tonic-gate 	if ((dinfo.di_attributes & DOOR_REVOKED) ||
834*0ec57554Sraf 	    (dinfo.di_data != (uintptr_t)PICLD_DOOR_COOKIE)) {
8357c478bd9Sstevel@tonic-gate 		(void) close(doorh);
8367c478bd9Sstevel@tonic-gate 		return (0);
8377c478bd9Sstevel@tonic-gate 	}
8387c478bd9Sstevel@tonic-gate 
8397c478bd9Sstevel@tonic-gate 	if (dinfo.di_target != getpid()) {
8407c478bd9Sstevel@tonic-gate 		(void) close(doorh);
8417c478bd9Sstevel@tonic-gate 		return (1);
8427c478bd9Sstevel@tonic-gate 	}
8437c478bd9Sstevel@tonic-gate 
8447c478bd9Sstevel@tonic-gate 	req_ping.cnum = PICL_CNUM_PING;
8457c478bd9Sstevel@tonic-gate 
8467c478bd9Sstevel@tonic-gate 	darg.data_ptr = (char *)&req_ping;
8477c478bd9Sstevel@tonic-gate 	darg.data_size = sizeof (picl_reqping_t);
8487c478bd9Sstevel@tonic-gate 	darg.desc_ptr = NULL;
8497c478bd9Sstevel@tonic-gate 	darg.desc_num = 0;
8507c478bd9Sstevel@tonic-gate 	darg.rbuf = (char *)&ret_ping;
8517c478bd9Sstevel@tonic-gate 	darg.rsize = sizeof (picl_retping_t);
8527c478bd9Sstevel@tonic-gate 
8537c478bd9Sstevel@tonic-gate 	if (door_call(doorh, &darg) < 0) {
8547c478bd9Sstevel@tonic-gate 		(void) close(doorh);
8557c478bd9Sstevel@tonic-gate 		return (0);
8567c478bd9Sstevel@tonic-gate 	}
8577c478bd9Sstevel@tonic-gate 
8587c478bd9Sstevel@tonic-gate 	(void) close(doorh);
8597c478bd9Sstevel@tonic-gate 	return (1);
8607c478bd9Sstevel@tonic-gate }
8617c478bd9Sstevel@tonic-gate 
8627c478bd9Sstevel@tonic-gate /*
8637c478bd9Sstevel@tonic-gate  * Create the picld door
8647c478bd9Sstevel@tonic-gate  */
8657c478bd9Sstevel@tonic-gate static int
8667c478bd9Sstevel@tonic-gate setup_door(void)
8677c478bd9Sstevel@tonic-gate {
8687c478bd9Sstevel@tonic-gate 	struct stat	stbuf;
8697c478bd9Sstevel@tonic-gate 
8707c478bd9Sstevel@tonic-gate 	/*
8717c478bd9Sstevel@tonic-gate 	 * Create the door
8727c478bd9Sstevel@tonic-gate 	 */
8737c478bd9Sstevel@tonic-gate 	door_id = door_create(picld_door_handler, PICLD_DOOR_COOKIE,
8747c478bd9Sstevel@tonic-gate 	    DOOR_UNREF | DOOR_REFUSE_DESC | DOOR_NO_CANCEL);
8757c478bd9Sstevel@tonic-gate 
8767c478bd9Sstevel@tonic-gate 	if (door_id < 0) {
8777c478bd9Sstevel@tonic-gate 		return (-1);
8787c478bd9Sstevel@tonic-gate 	}
8797c478bd9Sstevel@tonic-gate 
8807c478bd9Sstevel@tonic-gate 	if (stat(PICLD_DOOR, &stbuf) < 0) {
8817c478bd9Sstevel@tonic-gate 		int newfd;
8827c478bd9Sstevel@tonic-gate 		if ((newfd = creat(PICLD_DOOR, 0444)) < 0)
8837c478bd9Sstevel@tonic-gate 			return (-1);
8847c478bd9Sstevel@tonic-gate 		(void) close(newfd);
8857c478bd9Sstevel@tonic-gate 	}
8867c478bd9Sstevel@tonic-gate 
8877c478bd9Sstevel@tonic-gate 	if (fattach(door_id, PICLD_DOOR) < 0) {
8887c478bd9Sstevel@tonic-gate 		if ((errno != EBUSY) ||
8897c478bd9Sstevel@tonic-gate 		    (fdetach(PICLD_DOOR) < 0) ||
8907c478bd9Sstevel@tonic-gate 		    (fattach(door_id, PICLD_DOOR) < 0))
8917c478bd9Sstevel@tonic-gate 			return (-1);
8927c478bd9Sstevel@tonic-gate 	}
8937c478bd9Sstevel@tonic-gate 
8947c478bd9Sstevel@tonic-gate 	return (0);
8957c478bd9Sstevel@tonic-gate }
8967c478bd9Sstevel@tonic-gate 
8977c478bd9Sstevel@tonic-gate /*
8987c478bd9Sstevel@tonic-gate  * Main function of picl daemon
8997c478bd9Sstevel@tonic-gate  */
9007c478bd9Sstevel@tonic-gate int
9017c478bd9Sstevel@tonic-gate main(int argc, char **argv)
9027c478bd9Sstevel@tonic-gate {
9037c478bd9Sstevel@tonic-gate 	struct	sigaction	act;
9047c478bd9Sstevel@tonic-gate 	int			c;
9057c478bd9Sstevel@tonic-gate 	sigset_t		ublk;
9067c478bd9Sstevel@tonic-gate 
9077c478bd9Sstevel@tonic-gate 
9087c478bd9Sstevel@tonic-gate 	(void) setlocale(LC_ALL, "");
9097c478bd9Sstevel@tonic-gate 	(void) textdomain(TEXT_DOMAIN);
9107c478bd9Sstevel@tonic-gate 
9117c478bd9Sstevel@tonic-gate 	if (getuid() != 0) {
9127c478bd9Sstevel@tonic-gate 		syslog(LOG_CRIT, MUST_BE_ROOT);
9137c478bd9Sstevel@tonic-gate 		return (0);
9147c478bd9Sstevel@tonic-gate 	}
9157c478bd9Sstevel@tonic-gate 
9167c478bd9Sstevel@tonic-gate 	(void) rwlock_init(&init_lk, USYNC_THREAD, NULL);
9177c478bd9Sstevel@tonic-gate 	doreinit = 0;
9187c478bd9Sstevel@tonic-gate 	logflag = 1;
9197c478bd9Sstevel@tonic-gate 	dos_req_limit = DOS_PICL_REQUESTS_LIMIT;
9207c478bd9Sstevel@tonic-gate 	sliding_interval_ms = SLIDING_INTERVAL_MILLISECONDS;
9217c478bd9Sstevel@tonic-gate 	dos_ms = DOS_SLEEPTIME_MS;
9227c478bd9Sstevel@tonic-gate 	verbose_level = 0;
9237c478bd9Sstevel@tonic-gate 
9247c478bd9Sstevel@tonic-gate 	/*
9257c478bd9Sstevel@tonic-gate 	 * parse arguments
9267c478bd9Sstevel@tonic-gate 	 */
9277c478bd9Sstevel@tonic-gate 	while ((c = getopt(argc, argv, "is:t:l:r:v:d:")) != EOF) {
9287c478bd9Sstevel@tonic-gate 		switch (c) {
9297c478bd9Sstevel@tonic-gate 		case 'd':
9307c478bd9Sstevel@tonic-gate 			dos_ms = strtol(optarg, (char **)NULL, 0);
9317c478bd9Sstevel@tonic-gate 			break;
9327c478bd9Sstevel@tonic-gate 		case 'i':
9337c478bd9Sstevel@tonic-gate 			logflag = 0;
9347c478bd9Sstevel@tonic-gate 			break;
9357c478bd9Sstevel@tonic-gate 		case 's':
9367c478bd9Sstevel@tonic-gate 			sliding_interval_ms = strtoll(optarg, (char **)NULL, 0);
9377c478bd9Sstevel@tonic-gate 			break;
9387c478bd9Sstevel@tonic-gate 		case 't':
9397c478bd9Sstevel@tonic-gate 			dos_req_limit = strtol(optarg, (char **)NULL, 0);
9407c478bd9Sstevel@tonic-gate 			break;
9417c478bd9Sstevel@tonic-gate 		case 'v':
9427c478bd9Sstevel@tonic-gate 			verbose_level = strtol(optarg, (char **)NULL, 0);
9437c478bd9Sstevel@tonic-gate 			logflag = 0;
9447c478bd9Sstevel@tonic-gate 			break;
9457c478bd9Sstevel@tonic-gate 		default:
9467c478bd9Sstevel@tonic-gate 			break;
9477c478bd9Sstevel@tonic-gate 		}
9487c478bd9Sstevel@tonic-gate 	}
9497c478bd9Sstevel@tonic-gate 
9507c478bd9Sstevel@tonic-gate 	orig_time = gethrtime();
9517c478bd9Sstevel@tonic-gate 
9527c478bd9Sstevel@tonic-gate 	/*
9537c478bd9Sstevel@tonic-gate 	 * is there a daemon already running?
9547c478bd9Sstevel@tonic-gate 	 */
9557c478bd9Sstevel@tonic-gate 
9567c478bd9Sstevel@tonic-gate 	if (daemon_exists()) {
9577c478bd9Sstevel@tonic-gate 		syslog(LOG_CRIT, DAEMON_RUNNING);
9587c478bd9Sstevel@tonic-gate 		exit(1);
9597c478bd9Sstevel@tonic-gate 	}
9607c478bd9Sstevel@tonic-gate 
9617c478bd9Sstevel@tonic-gate 	/*
9627c478bd9Sstevel@tonic-gate 	 * Mask off/block SIGALRM signal so that the environmental plug-in
9637c478bd9Sstevel@tonic-gate 	 * (piclenvd) can use it to simulate sleep() without being affected
9647c478bd9Sstevel@tonic-gate 	 * by time being set back. No other PICL plug-in should use SIGALRM
9657c478bd9Sstevel@tonic-gate 	 * or alarm() for now.
9667c478bd9Sstevel@tonic-gate 	 */
9677c478bd9Sstevel@tonic-gate 	(void) sigemptyset(&ublk);
9687c478bd9Sstevel@tonic-gate 	(void) sigaddset(&ublk, SIGALRM);
9697c478bd9Sstevel@tonic-gate 	(void) sigprocmask(SIG_BLOCK, &ublk, NULL);
9707c478bd9Sstevel@tonic-gate 
9717c478bd9Sstevel@tonic-gate 	/*
9727c478bd9Sstevel@tonic-gate 	 * Ignore SIGHUP until all the initialization is done.
9737c478bd9Sstevel@tonic-gate 	 */
9747c478bd9Sstevel@tonic-gate 	act.sa_handler = SIG_IGN;
9757c478bd9Sstevel@tonic-gate 	(void) sigemptyset(&act.sa_mask);
9767c478bd9Sstevel@tonic-gate 	act.sa_flags = 0;
9777c478bd9Sstevel@tonic-gate 	if (sigaction(SIGHUP, &act, NULL) == -1)
9787c478bd9Sstevel@tonic-gate 		syslog(LOG_ERR, SIGACT_FAILED, strsignal(SIGHUP),
9797c478bd9Sstevel@tonic-gate 		    strerror(errno));
9807c478bd9Sstevel@tonic-gate 
9817c478bd9Sstevel@tonic-gate 	if (logflag != 0) {	/* daemonize */
9827c478bd9Sstevel@tonic-gate 		pid_t pid;
9837c478bd9Sstevel@tonic-gate 
9847c478bd9Sstevel@tonic-gate 		pid = fork();
9857c478bd9Sstevel@tonic-gate 		if (pid < 0)
9867c478bd9Sstevel@tonic-gate 			exit(1);
9877c478bd9Sstevel@tonic-gate 		if (pid > 0)
9887c478bd9Sstevel@tonic-gate 			/* parent */
9897c478bd9Sstevel@tonic-gate 			exit(0);
9907c478bd9Sstevel@tonic-gate 
9917c478bd9Sstevel@tonic-gate 		/* child */
9927c478bd9Sstevel@tonic-gate 		if (chdir("/") == -1) {
9937c478bd9Sstevel@tonic-gate 			syslog(LOG_CRIT, CD_ROOT_FAILED);
9947c478bd9Sstevel@tonic-gate 			exit(1);
9957c478bd9Sstevel@tonic-gate 		}
9967c478bd9Sstevel@tonic-gate 
9977c478bd9Sstevel@tonic-gate 		(void) setsid();
9987c478bd9Sstevel@tonic-gate 		(void) close(STDIN_FILENO);
9997c478bd9Sstevel@tonic-gate 		(void) close(STDOUT_FILENO);
10007c478bd9Sstevel@tonic-gate 		(void) close(STDERR_FILENO);
10017c478bd9Sstevel@tonic-gate 		(void) open("/dev/null", O_RDWR, 0);
10027c478bd9Sstevel@tonic-gate 		(void) dup2(STDIN_FILENO, STDOUT_FILENO);
10037c478bd9Sstevel@tonic-gate 		(void) dup2(STDIN_FILENO, STDERR_FILENO);
10047c478bd9Sstevel@tonic-gate 		openlog(PICLD, LOG_PID, LOG_DAEMON);
10057c478bd9Sstevel@tonic-gate 	}
10067c478bd9Sstevel@tonic-gate 
10077c478bd9Sstevel@tonic-gate 	/*
10087c478bd9Sstevel@tonic-gate 	 * Initialize the PICL Tree
10097c478bd9Sstevel@tonic-gate 	 */
10107c478bd9Sstevel@tonic-gate 	if (xptree_initialize(NULL) != PICL_SUCCESS) {
10117c478bd9Sstevel@tonic-gate 		syslog(LOG_CRIT, INIT_FAILED);
10127c478bd9Sstevel@tonic-gate 		exit(1);
10137c478bd9Sstevel@tonic-gate 	}
10147c478bd9Sstevel@tonic-gate 
10157c478bd9Sstevel@tonic-gate 	if (setup_door()) {
10167c478bd9Sstevel@tonic-gate 		syslog(LOG_CRIT, DOOR_FAILED);
10177c478bd9Sstevel@tonic-gate 		exit(1);
10187c478bd9Sstevel@tonic-gate 	}
10197c478bd9Sstevel@tonic-gate 
10207c478bd9Sstevel@tonic-gate 	/*
10217c478bd9Sstevel@tonic-gate 	 * setup signal handlers for post-init
10227c478bd9Sstevel@tonic-gate 	 */
10237c478bd9Sstevel@tonic-gate 	act.sa_sigaction = hup_handler;
10247c478bd9Sstevel@tonic-gate 	(void) sigemptyset(&act.sa_mask);
10257c478bd9Sstevel@tonic-gate 	act.sa_flags = SA_SIGINFO;
10267c478bd9Sstevel@tonic-gate 	if (sigaction(SIGHUP, &act, NULL) == -1)
10277c478bd9Sstevel@tonic-gate 		syslog(LOG_ERR, SIGACT_FAILED, strsignal(SIGHUP),
10287c478bd9Sstevel@tonic-gate 		    strerror(errno));
10297c478bd9Sstevel@tonic-gate 
10307c478bd9Sstevel@tonic-gate 	/*
10317c478bd9Sstevel@tonic-gate 	 * wait for requests
10327c478bd9Sstevel@tonic-gate 	 */
10337c478bd9Sstevel@tonic-gate 	for (;;) {
10347c478bd9Sstevel@tonic-gate 		(void) pause();
10357c478bd9Sstevel@tonic-gate 		if (doreinit) {
10367c478bd9Sstevel@tonic-gate 			/*
10377c478bd9Sstevel@tonic-gate 			 * Block SIGHUP during reinitialization.
10387c478bd9Sstevel@tonic-gate 			 * Also mask off/block SIGALRM signal so that the
10397c478bd9Sstevel@tonic-gate 			 * environmental plug-in (piclenvd) can use it to
10407c478bd9Sstevel@tonic-gate 			 * simulate sleep() without being affected by time
10417c478bd9Sstevel@tonic-gate 			 * being set back. No ohter PICL plug-in should use
10427c478bd9Sstevel@tonic-gate 			 * SIGALRM or alarm() for now.
10437c478bd9Sstevel@tonic-gate 			 */
10447c478bd9Sstevel@tonic-gate 			(void) sigemptyset(&ublk);
10457c478bd9Sstevel@tonic-gate 			(void) sigaddset(&ublk, SIGHUP);
10467c478bd9Sstevel@tonic-gate 			(void) sigaddset(&ublk, SIGALRM);
10477c478bd9Sstevel@tonic-gate 			(void) sigprocmask(SIG_BLOCK, &ublk, NULL);
10487c478bd9Sstevel@tonic-gate 			(void) sigdelset(&ublk, SIGALRM);
10497c478bd9Sstevel@tonic-gate 			doreinit = 0;
10507c478bd9Sstevel@tonic-gate 			(void) rw_wrlock(&init_lk);
10517c478bd9Sstevel@tonic-gate 			xptree_destroy();
10527c478bd9Sstevel@tonic-gate 			(void) xptree_reinitialize();
10537c478bd9Sstevel@tonic-gate 			(void) rw_unlock(&init_lk);
10547c478bd9Sstevel@tonic-gate 			(void) sigprocmask(SIG_UNBLOCK, &ublk, NULL);
10557c478bd9Sstevel@tonic-gate 		}
10567c478bd9Sstevel@tonic-gate 	}
10577c478bd9Sstevel@tonic-gate }
1058