1*7c478bd9Sstevel@tonic-gate /* 2*7c478bd9Sstevel@tonic-gate * CDDL HEADER START 3*7c478bd9Sstevel@tonic-gate * 4*7c478bd9Sstevel@tonic-gate * The contents of this file are subject to the terms of the 5*7c478bd9Sstevel@tonic-gate * Common Development and Distribution License, Version 1.0 only 6*7c478bd9Sstevel@tonic-gate * (the "License"). You may not use this file except in compliance 7*7c478bd9Sstevel@tonic-gate * with the License. 8*7c478bd9Sstevel@tonic-gate * 9*7c478bd9Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 10*7c478bd9Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing. 11*7c478bd9Sstevel@tonic-gate * See the License for the specific language governing permissions 12*7c478bd9Sstevel@tonic-gate * and limitations under the License. 13*7c478bd9Sstevel@tonic-gate * 14*7c478bd9Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each 15*7c478bd9Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 16*7c478bd9Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the 17*7c478bd9Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying 18*7c478bd9Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner] 19*7c478bd9Sstevel@tonic-gate * 20*7c478bd9Sstevel@tonic-gate * CDDL HEADER END 21*7c478bd9Sstevel@tonic-gate */ 22*7c478bd9Sstevel@tonic-gate /* 23*7c478bd9Sstevel@tonic-gate * Copyright 2005 Sun Microsystems, Inc. All rights reserved. 24*7c478bd9Sstevel@tonic-gate * Use is subject to license terms. 25*7c478bd9Sstevel@tonic-gate */ 26*7c478bd9Sstevel@tonic-gate 27*7c478bd9Sstevel@tonic-gate #pragma ident "%Z%%M% %I% %E% SMI" 28*7c478bd9Sstevel@tonic-gate 29*7c478bd9Sstevel@tonic-gate /* 30*7c478bd9Sstevel@tonic-gate * PICL daemon 31*7c478bd9Sstevel@tonic-gate */ 32*7c478bd9Sstevel@tonic-gate 33*7c478bd9Sstevel@tonic-gate #include <stdio.h> 34*7c478bd9Sstevel@tonic-gate #include <stdlib.h> 35*7c478bd9Sstevel@tonic-gate #include <stdarg.h> 36*7c478bd9Sstevel@tonic-gate #include <string.h> 37*7c478bd9Sstevel@tonic-gate #include <libintl.h> 38*7c478bd9Sstevel@tonic-gate #include <locale.h> 39*7c478bd9Sstevel@tonic-gate #include <alloca.h> 40*7c478bd9Sstevel@tonic-gate #include <errno.h> 41*7c478bd9Sstevel@tonic-gate #include <assert.h> 42*7c478bd9Sstevel@tonic-gate #include <stropts.h> 43*7c478bd9Sstevel@tonic-gate #include <unistd.h> 44*7c478bd9Sstevel@tonic-gate #include <signal.h> 45*7c478bd9Sstevel@tonic-gate #include <pthread.h> 46*7c478bd9Sstevel@tonic-gate #include <synch.h> 47*7c478bd9Sstevel@tonic-gate #include <door.h> 48*7c478bd9Sstevel@tonic-gate #include <sys/door.h> 49*7c478bd9Sstevel@tonic-gate #include <fcntl.h> 50*7c478bd9Sstevel@tonic-gate #include <dlfcn.h> 51*7c478bd9Sstevel@tonic-gate #include <time.h> 52*7c478bd9Sstevel@tonic-gate #include <sys/utsname.h> 53*7c478bd9Sstevel@tonic-gate #include <sys/systeminfo.h> 54*7c478bd9Sstevel@tonic-gate #include <sys/stat.h> 55*7c478bd9Sstevel@tonic-gate #include <sys/wait.h> 56*7c478bd9Sstevel@tonic-gate #include <dirent.h> 57*7c478bd9Sstevel@tonic-gate #include <syslog.h> 58*7c478bd9Sstevel@tonic-gate #include <poll.h> 59*7c478bd9Sstevel@tonic-gate #include <limits.h> 60*7c478bd9Sstevel@tonic-gate #include <picl.h> 61*7c478bd9Sstevel@tonic-gate #include "picl2door.h" 62*7c478bd9Sstevel@tonic-gate #include <picltree.h> 63*7c478bd9Sstevel@tonic-gate #include "ptree_impl.h" 64*7c478bd9Sstevel@tonic-gate 65*7c478bd9Sstevel@tonic-gate /* 66*7c478bd9Sstevel@tonic-gate * Log text messages 67*7c478bd9Sstevel@tonic-gate */ 68*7c478bd9Sstevel@tonic-gate #define MUST_BE_ROOT gettext("this program must be run as root\n") 69*7c478bd9Sstevel@tonic-gate #define CD_ROOT_FAILED gettext("chdir to root failed\n") 70*7c478bd9Sstevel@tonic-gate #define INIT_FAILED gettext("ptree initialization failed\n") 71*7c478bd9Sstevel@tonic-gate #define DAEMON_RUNNING gettext("PICL daemon already running\n") 72*7c478bd9Sstevel@tonic-gate #define DOOR_FAILED gettext("Failed creating picld door\n") 73*7c478bd9Sstevel@tonic-gate #define SIGACT_FAILED \ 74*7c478bd9Sstevel@tonic-gate gettext("Failed to install signal handler for %s: %s\n") 75*7c478bd9Sstevel@tonic-gate 76*7c478bd9Sstevel@tonic-gate /* 77*7c478bd9Sstevel@tonic-gate * Constants 78*7c478bd9Sstevel@tonic-gate */ 79*7c478bd9Sstevel@tonic-gate #define PICLD "picld" 80*7c478bd9Sstevel@tonic-gate #define DOS_PICL_REQUESTS_LIMIT 10000 81*7c478bd9Sstevel@tonic-gate #define SLIDING_INTERVAL_MILLISECONDS 1000 82*7c478bd9Sstevel@tonic-gate #define PICLD_MAJOR_REV 0x1 83*7c478bd9Sstevel@tonic-gate #define PICLD_MINOR_REV 0x0 84*7c478bd9Sstevel@tonic-gate #define DOS_SLEEPTIME_MS 1000 85*7c478bd9Sstevel@tonic-gate 86*7c478bd9Sstevel@tonic-gate /* 87*7c478bd9Sstevel@tonic-gate * Macros 88*7c478bd9Sstevel@tonic-gate */ 89*7c478bd9Sstevel@tonic-gate #define PICLD_VERSION(x, y) ((x << 8) | y) 90*7c478bd9Sstevel@tonic-gate #define PICL_CLIENT_REV(x) (x & 0xff) 91*7c478bd9Sstevel@tonic-gate #define MILLI_TO_NANO(x) (x * 1000000) 92*7c478bd9Sstevel@tonic-gate 93*7c478bd9Sstevel@tonic-gate extern char **environ; 94*7c478bd9Sstevel@tonic-gate 95*7c478bd9Sstevel@tonic-gate /* 96*7c478bd9Sstevel@tonic-gate * Module Variables 97*7c478bd9Sstevel@tonic-gate */ 98*7c478bd9Sstevel@tonic-gate static int logflag = 1; 99*7c478bd9Sstevel@tonic-gate static int doreinit = 0; 100*7c478bd9Sstevel@tonic-gate static int door_id = -1; 101*7c478bd9Sstevel@tonic-gate static int service_requests = 0; 102*7c478bd9Sstevel@tonic-gate static hrtime_t orig_time; 103*7c478bd9Sstevel@tonic-gate static hrtime_t sliding_interval_ms; 104*7c478bd9Sstevel@tonic-gate static uint32_t dos_req_limit; 105*7c478bd9Sstevel@tonic-gate static uint32_t dos_ms; 106*7c478bd9Sstevel@tonic-gate static pthread_mutex_t dos_mutex = PTHREAD_MUTEX_INITIALIZER; 107*7c478bd9Sstevel@tonic-gate static rwlock_t init_lk; 108*7c478bd9Sstevel@tonic-gate 109*7c478bd9Sstevel@tonic-gate /* 110*7c478bd9Sstevel@tonic-gate * This returns an error message to libpicl 111*7c478bd9Sstevel@tonic-gate */ 112*7c478bd9Sstevel@tonic-gate static void 113*7c478bd9Sstevel@tonic-gate picld_return_error(picl_callnumber_t cnum, picl_errno_t err) 114*7c478bd9Sstevel@tonic-gate { 115*7c478bd9Sstevel@tonic-gate picl_reterror_t ret_error; 116*7c478bd9Sstevel@tonic-gate 117*7c478bd9Sstevel@tonic-gate ret_error.cnum = PICL_CNUM_ERROR; 118*7c478bd9Sstevel@tonic-gate ret_error.in_cnum = cnum; 119*7c478bd9Sstevel@tonic-gate ret_error.errnum = err; 120*7c478bd9Sstevel@tonic-gate (void) rw_unlock(&init_lk); 121*7c478bd9Sstevel@tonic-gate (void) door_return((char *)&ret_error, sizeof (picl_reterror_t), NULL, 122*7c478bd9Sstevel@tonic-gate 0); 123*7c478bd9Sstevel@tonic-gate } 124*7c478bd9Sstevel@tonic-gate 125*7c478bd9Sstevel@tonic-gate /* 126*7c478bd9Sstevel@tonic-gate * picld_init is called when a picl_initialize request is received 127*7c478bd9Sstevel@tonic-gate */ 128*7c478bd9Sstevel@tonic-gate static void 129*7c478bd9Sstevel@tonic-gate picld_init(picl_service_t *req) 130*7c478bd9Sstevel@tonic-gate { 131*7c478bd9Sstevel@tonic-gate picl_retinit_t ret_init; 132*7c478bd9Sstevel@tonic-gate int clmajrev; 133*7c478bd9Sstevel@tonic-gate 134*7c478bd9Sstevel@tonic-gate clmajrev = PICL_CLIENT_REV(req->req_init.clrev); 135*7c478bd9Sstevel@tonic-gate 136*7c478bd9Sstevel@tonic-gate if (clmajrev < PICL_VERSION_1) 137*7c478bd9Sstevel@tonic-gate picld_return_error(req->req_init.cnum, PICL_NOTSUPPORTED); 138*7c478bd9Sstevel@tonic-gate 139*7c478bd9Sstevel@tonic-gate ret_init.cnum = req->req_init.cnum; 140*7c478bd9Sstevel@tonic-gate ret_init.rev = PICLD_VERSION(PICLD_MAJOR_REV, PICLD_MINOR_REV); 141*7c478bd9Sstevel@tonic-gate 142*7c478bd9Sstevel@tonic-gate (void) rw_unlock(&init_lk); 143*7c478bd9Sstevel@tonic-gate (void) door_return((char *)&ret_init, sizeof (picl_retinit_t), NULL, 0); 144*7c478bd9Sstevel@tonic-gate } 145*7c478bd9Sstevel@tonic-gate 146*7c478bd9Sstevel@tonic-gate /* 147*7c478bd9Sstevel@tonic-gate * picld_fini is called when a picl_shutdown request is received 148*7c478bd9Sstevel@tonic-gate */ 149*7c478bd9Sstevel@tonic-gate static void 150*7c478bd9Sstevel@tonic-gate picld_fini(picl_service_t *in) 151*7c478bd9Sstevel@tonic-gate { 152*7c478bd9Sstevel@tonic-gate picl_retfini_t ret; 153*7c478bd9Sstevel@tonic-gate 154*7c478bd9Sstevel@tonic-gate ret.cnum = in->req_fini.cnum; 155*7c478bd9Sstevel@tonic-gate 156*7c478bd9Sstevel@tonic-gate (void) rw_unlock(&init_lk); 157*7c478bd9Sstevel@tonic-gate (void) door_return((char *)&ret, sizeof (picl_retfini_t), NULL, 0); 158*7c478bd9Sstevel@tonic-gate } 159*7c478bd9Sstevel@tonic-gate 160*7c478bd9Sstevel@tonic-gate static void 161*7c478bd9Sstevel@tonic-gate picld_ping(picl_service_t *in) 162*7c478bd9Sstevel@tonic-gate { 163*7c478bd9Sstevel@tonic-gate picl_retping_t ret; 164*7c478bd9Sstevel@tonic-gate 165*7c478bd9Sstevel@tonic-gate ret.cnum = in->req_ping.cnum; 166*7c478bd9Sstevel@tonic-gate 167*7c478bd9Sstevel@tonic-gate (void) rw_unlock(&init_lk); 168*7c478bd9Sstevel@tonic-gate (void) door_return((char *)&ret, sizeof (picl_retping_t), NULL, 0); 169*7c478bd9Sstevel@tonic-gate } 170*7c478bd9Sstevel@tonic-gate 171*7c478bd9Sstevel@tonic-gate /* 172*7c478bd9Sstevel@tonic-gate * picld_wait is called when a picl_wait request is received 173*7c478bd9Sstevel@tonic-gate */ 174*7c478bd9Sstevel@tonic-gate static void 175*7c478bd9Sstevel@tonic-gate picld_wait(picl_service_t *in) 176*7c478bd9Sstevel@tonic-gate { 177*7c478bd9Sstevel@tonic-gate picl_retwait_t ret; 178*7c478bd9Sstevel@tonic-gate int err; 179*7c478bd9Sstevel@tonic-gate 180*7c478bd9Sstevel@tonic-gate ret.cnum = in->req_wait.cnum; 181*7c478bd9Sstevel@tonic-gate 182*7c478bd9Sstevel@tonic-gate err = xptree_refresh_notify(in->req_wait.secs); 183*7c478bd9Sstevel@tonic-gate ret.retcode = err; 184*7c478bd9Sstevel@tonic-gate 185*7c478bd9Sstevel@tonic-gate (void) rw_unlock(&init_lk); 186*7c478bd9Sstevel@tonic-gate (void) door_return((char *)&ret, sizeof (picl_retwait_t), NULL, 0); 187*7c478bd9Sstevel@tonic-gate } 188*7c478bd9Sstevel@tonic-gate 189*7c478bd9Sstevel@tonic-gate /* 190*7c478bd9Sstevel@tonic-gate * This function returns the handle of the root node of the PICL tree 191*7c478bd9Sstevel@tonic-gate */ 192*7c478bd9Sstevel@tonic-gate static void 193*7c478bd9Sstevel@tonic-gate picld_getroot(picl_service_t *in) 194*7c478bd9Sstevel@tonic-gate { 195*7c478bd9Sstevel@tonic-gate picl_retroot_t ret; 196*7c478bd9Sstevel@tonic-gate int err; 197*7c478bd9Sstevel@tonic-gate 198*7c478bd9Sstevel@tonic-gate ret.cnum = PICL_CNUM_GETROOT; 199*7c478bd9Sstevel@tonic-gate err = ptree_get_root(&ret.rnode); 200*7c478bd9Sstevel@tonic-gate if (err != PICL_SUCCESS) 201*7c478bd9Sstevel@tonic-gate picld_return_error(in->in.cnum, err); 202*7c478bd9Sstevel@tonic-gate cvt_ptree2picl(&ret.rnode); 203*7c478bd9Sstevel@tonic-gate (void) rw_unlock(&init_lk); 204*7c478bd9Sstevel@tonic-gate (void) door_return((char *)&ret, sizeof (picl_retroot_t), NULL, 0); 205*7c478bd9Sstevel@tonic-gate } 206*7c478bd9Sstevel@tonic-gate 207*7c478bd9Sstevel@tonic-gate /* 208*7c478bd9Sstevel@tonic-gate * This function returns the value of the PICL property 209*7c478bd9Sstevel@tonic-gate */ 210*7c478bd9Sstevel@tonic-gate static void 211*7c478bd9Sstevel@tonic-gate picld_get_attrval(picl_service_t *in) 212*7c478bd9Sstevel@tonic-gate { 213*7c478bd9Sstevel@tonic-gate picl_retattrval_t *ret; 214*7c478bd9Sstevel@tonic-gate int err; 215*7c478bd9Sstevel@tonic-gate size_t vbufsize; 216*7c478bd9Sstevel@tonic-gate size_t len; 217*7c478bd9Sstevel@tonic-gate door_cred_t cred; 218*7c478bd9Sstevel@tonic-gate picl_prophdl_t ptreeh; 219*7c478bd9Sstevel@tonic-gate ptree_propinfo_t pinfo; 220*7c478bd9Sstevel@tonic-gate 221*7c478bd9Sstevel@tonic-gate if (door_cred(&cred) < 0) 222*7c478bd9Sstevel@tonic-gate picld_return_error(in->in.cnum, PICL_FAILURE); 223*7c478bd9Sstevel@tonic-gate 224*7c478bd9Sstevel@tonic-gate err = cvt_picl2ptree(in->req_attrval.attr, &ptreeh); 225*7c478bd9Sstevel@tonic-gate if (err != PICL_SUCCESS) 226*7c478bd9Sstevel@tonic-gate picld_return_error(in->in.cnum, err); 227*7c478bd9Sstevel@tonic-gate 228*7c478bd9Sstevel@tonic-gate err = ptree_get_propinfo(ptreeh, &pinfo); 229*7c478bd9Sstevel@tonic-gate if (err != PICL_SUCCESS) 230*7c478bd9Sstevel@tonic-gate picld_return_error(in->in.cnum, err); 231*7c478bd9Sstevel@tonic-gate 232*7c478bd9Sstevel@tonic-gate if (!(pinfo.piclinfo.accessmode & PICL_READ)) 233*7c478bd9Sstevel@tonic-gate picld_return_error(in->in.cnum, PICL_NOTREADABLE); 234*7c478bd9Sstevel@tonic-gate 235*7c478bd9Sstevel@tonic-gate vbufsize = pinfo.piclinfo.size; 236*7c478bd9Sstevel@tonic-gate vbufsize = MIN((size_t)in->req_attrval.bufsize, vbufsize); 237*7c478bd9Sstevel@tonic-gate 238*7c478bd9Sstevel@tonic-gate len = sizeof (picl_retattrval_t) + vbufsize; 239*7c478bd9Sstevel@tonic-gate ret = alloca(len); 240*7c478bd9Sstevel@tonic-gate if (ret == NULL) 241*7c478bd9Sstevel@tonic-gate picld_return_error(in->in.cnum, PICL_FAILURE); 242*7c478bd9Sstevel@tonic-gate ret->cnum = PICL_CNUM_GETATTRVAL; 243*7c478bd9Sstevel@tonic-gate ret->attr = in->req_attrval.attr; 244*7c478bd9Sstevel@tonic-gate ret->nbytes = (uint32_t)vbufsize; 245*7c478bd9Sstevel@tonic-gate err = xptree_get_propval_with_cred(ptreeh, ret->ret_buf, vbufsize, 246*7c478bd9Sstevel@tonic-gate cred); 247*7c478bd9Sstevel@tonic-gate if (err != PICL_SUCCESS) 248*7c478bd9Sstevel@tonic-gate picld_return_error(in->in.cnum, err); 249*7c478bd9Sstevel@tonic-gate 250*7c478bd9Sstevel@tonic-gate /* 251*7c478bd9Sstevel@tonic-gate * adjust returned bytes for charstrings 252*7c478bd9Sstevel@tonic-gate */ 253*7c478bd9Sstevel@tonic-gate if (pinfo.piclinfo.type == PICL_PTYPE_CHARSTRING) 254*7c478bd9Sstevel@tonic-gate ret->nbytes = (uint32_t)strlen(ret->ret_buf) + 1; 255*7c478bd9Sstevel@tonic-gate 256*7c478bd9Sstevel@tonic-gate /* 257*7c478bd9Sstevel@tonic-gate * convert handle values to picl handles 258*7c478bd9Sstevel@tonic-gate */ 259*7c478bd9Sstevel@tonic-gate if ((pinfo.piclinfo.type == PICL_PTYPE_TABLE) || 260*7c478bd9Sstevel@tonic-gate (pinfo.piclinfo.type == PICL_PTYPE_REFERENCE)) 261*7c478bd9Sstevel@tonic-gate cvt_ptree2picl(&ret->ret_nodeh); 262*7c478bd9Sstevel@tonic-gate (void) rw_unlock(&init_lk); 263*7c478bd9Sstevel@tonic-gate (void) door_return((char *)ret, sizeof (picl_retattrval_t) + 264*7c478bd9Sstevel@tonic-gate (size_t)ret->nbytes, NULL, 0); 265*7c478bd9Sstevel@tonic-gate } 266*7c478bd9Sstevel@tonic-gate 267*7c478bd9Sstevel@tonic-gate /* 268*7c478bd9Sstevel@tonic-gate * This function returns the value of the PICL property specified by 269*7c478bd9Sstevel@tonic-gate * its name. 270*7c478bd9Sstevel@tonic-gate */ 271*7c478bd9Sstevel@tonic-gate static void 272*7c478bd9Sstevel@tonic-gate picld_get_attrval_by_name(picl_service_t *in) 273*7c478bd9Sstevel@tonic-gate { 274*7c478bd9Sstevel@tonic-gate picl_retattrvalbyname_t *ret; 275*7c478bd9Sstevel@tonic-gate int err; 276*7c478bd9Sstevel@tonic-gate size_t vbufsize; 277*7c478bd9Sstevel@tonic-gate size_t len; 278*7c478bd9Sstevel@tonic-gate door_cred_t cred; 279*7c478bd9Sstevel@tonic-gate picl_nodehdl_t ptreeh; 280*7c478bd9Sstevel@tonic-gate ptree_propinfo_t pinfo; 281*7c478bd9Sstevel@tonic-gate 282*7c478bd9Sstevel@tonic-gate if (door_cred(&cred) < 0) 283*7c478bd9Sstevel@tonic-gate picld_return_error(in->in.cnum, PICL_FAILURE); 284*7c478bd9Sstevel@tonic-gate 285*7c478bd9Sstevel@tonic-gate err = cvt_picl2ptree(in->req_attrvalbyname.nodeh, &ptreeh); 286*7c478bd9Sstevel@tonic-gate if (err != PICL_SUCCESS) 287*7c478bd9Sstevel@tonic-gate picld_return_error(in->in.cnum, err); 288*7c478bd9Sstevel@tonic-gate 289*7c478bd9Sstevel@tonic-gate err = xptree_get_propinfo_by_name(ptreeh, 290*7c478bd9Sstevel@tonic-gate in->req_attrvalbyname.propname, &pinfo); 291*7c478bd9Sstevel@tonic-gate if (err != PICL_SUCCESS) 292*7c478bd9Sstevel@tonic-gate picld_return_error(in->in.cnum, err); 293*7c478bd9Sstevel@tonic-gate 294*7c478bd9Sstevel@tonic-gate if (!(pinfo.piclinfo.accessmode & PICL_READ)) 295*7c478bd9Sstevel@tonic-gate picld_return_error(in->in.cnum, PICL_NOTREADABLE); 296*7c478bd9Sstevel@tonic-gate 297*7c478bd9Sstevel@tonic-gate /* 298*7c478bd9Sstevel@tonic-gate * allocate the minimum of piclinfo.size and input bufsize 299*7c478bd9Sstevel@tonic-gate */ 300*7c478bd9Sstevel@tonic-gate vbufsize = pinfo.piclinfo.size; 301*7c478bd9Sstevel@tonic-gate vbufsize = MIN((size_t)in->req_attrvalbyname.bufsize, vbufsize); 302*7c478bd9Sstevel@tonic-gate len = sizeof (picl_retattrvalbyname_t) + vbufsize; 303*7c478bd9Sstevel@tonic-gate ret = alloca(len); 304*7c478bd9Sstevel@tonic-gate if (ret == NULL) 305*7c478bd9Sstevel@tonic-gate picld_return_error(in->in.cnum, PICL_FAILURE); 306*7c478bd9Sstevel@tonic-gate ret->cnum = PICL_CNUM_GETATTRVALBYNAME; 307*7c478bd9Sstevel@tonic-gate ret->nodeh = in->req_attrvalbyname.nodeh; 308*7c478bd9Sstevel@tonic-gate (void) strcpy(ret->propname, in->req_attrvalbyname.propname); 309*7c478bd9Sstevel@tonic-gate ret->nbytes = (uint32_t)vbufsize; 310*7c478bd9Sstevel@tonic-gate 311*7c478bd9Sstevel@tonic-gate err = xptree_get_propval_by_name_with_cred(ptreeh, 312*7c478bd9Sstevel@tonic-gate in->req_attrvalbyname.propname, ret->ret_buf, vbufsize, 313*7c478bd9Sstevel@tonic-gate cred); 314*7c478bd9Sstevel@tonic-gate if (err != PICL_SUCCESS) 315*7c478bd9Sstevel@tonic-gate picld_return_error(in->in.cnum, err); 316*7c478bd9Sstevel@tonic-gate /* 317*7c478bd9Sstevel@tonic-gate * adjust returned value size for charstrings 318*7c478bd9Sstevel@tonic-gate */ 319*7c478bd9Sstevel@tonic-gate if (pinfo.piclinfo.type == PICL_PTYPE_CHARSTRING) 320*7c478bd9Sstevel@tonic-gate ret->nbytes = (uint32_t)strlen(ret->ret_buf) + 1; 321*7c478bd9Sstevel@tonic-gate 322*7c478bd9Sstevel@tonic-gate if ((pinfo.piclinfo.type == PICL_PTYPE_TABLE) || 323*7c478bd9Sstevel@tonic-gate (pinfo.piclinfo.type == PICL_PTYPE_REFERENCE)) 324*7c478bd9Sstevel@tonic-gate cvt_ptree2picl(&ret->ret_nodeh); 325*7c478bd9Sstevel@tonic-gate 326*7c478bd9Sstevel@tonic-gate (void) rw_unlock(&init_lk); 327*7c478bd9Sstevel@tonic-gate (void) door_return((char *)ret, sizeof (picl_retattrvalbyname_t) + 328*7c478bd9Sstevel@tonic-gate (size_t)ret->nbytes, NULL, 0); 329*7c478bd9Sstevel@tonic-gate } 330*7c478bd9Sstevel@tonic-gate 331*7c478bd9Sstevel@tonic-gate /* 332*7c478bd9Sstevel@tonic-gate * This function sets a property value 333*7c478bd9Sstevel@tonic-gate */ 334*7c478bd9Sstevel@tonic-gate static void 335*7c478bd9Sstevel@tonic-gate picld_set_attrval(picl_service_t *in) 336*7c478bd9Sstevel@tonic-gate { 337*7c478bd9Sstevel@tonic-gate picl_retsetattrval_t ret; 338*7c478bd9Sstevel@tonic-gate int err; 339*7c478bd9Sstevel@tonic-gate door_cred_t cred; 340*7c478bd9Sstevel@tonic-gate picl_prophdl_t ptreeh; 341*7c478bd9Sstevel@tonic-gate ptree_propinfo_t pinfo; 342*7c478bd9Sstevel@tonic-gate 343*7c478bd9Sstevel@tonic-gate if (door_cred(&cred) < 0) 344*7c478bd9Sstevel@tonic-gate picld_return_error(in->in.cnum, PICL_FAILURE); 345*7c478bd9Sstevel@tonic-gate 346*7c478bd9Sstevel@tonic-gate err = cvt_picl2ptree(in->req_setattrval.attr, &ptreeh); 347*7c478bd9Sstevel@tonic-gate if (err != PICL_SUCCESS) 348*7c478bd9Sstevel@tonic-gate picld_return_error(in->in.cnum, err); 349*7c478bd9Sstevel@tonic-gate 350*7c478bd9Sstevel@tonic-gate err = ptree_get_propinfo(ptreeh, &pinfo); 351*7c478bd9Sstevel@tonic-gate if (err != PICL_SUCCESS) 352*7c478bd9Sstevel@tonic-gate picld_return_error(in->in.cnum, err); 353*7c478bd9Sstevel@tonic-gate 354*7c478bd9Sstevel@tonic-gate if (!(pinfo.piclinfo.accessmode & PICL_WRITE)) 355*7c478bd9Sstevel@tonic-gate picld_return_error(in->in.cnum, PICL_NOTWRITABLE); 356*7c478bd9Sstevel@tonic-gate /* 357*7c478bd9Sstevel@tonic-gate * For non-volatile prop, only super user can set its value. 358*7c478bd9Sstevel@tonic-gate */ 359*7c478bd9Sstevel@tonic-gate if (!(pinfo.piclinfo.accessmode & PICL_VOLATILE) && 360*7c478bd9Sstevel@tonic-gate (cred.dc_euid != SUPER_USER)) 361*7c478bd9Sstevel@tonic-gate picld_return_error(in->in.cnum, PICL_PERMDENIED); 362*7c478bd9Sstevel@tonic-gate 363*7c478bd9Sstevel@tonic-gate ret.cnum = PICL_CNUM_SETATTRVAL; 364*7c478bd9Sstevel@tonic-gate ret.attr = in->req_setattrval.attr; 365*7c478bd9Sstevel@tonic-gate 366*7c478bd9Sstevel@tonic-gate err = xptree_update_propval_with_cred(ptreeh, in->req_setattrval.valbuf, 367*7c478bd9Sstevel@tonic-gate (size_t)in->req_setattrval.bufsize, cred); 368*7c478bd9Sstevel@tonic-gate 369*7c478bd9Sstevel@tonic-gate if (err != PICL_SUCCESS) 370*7c478bd9Sstevel@tonic-gate picld_return_error(in->in.cnum, err); 371*7c478bd9Sstevel@tonic-gate 372*7c478bd9Sstevel@tonic-gate (void) rw_unlock(&init_lk); 373*7c478bd9Sstevel@tonic-gate (void) door_return((char *)&ret, sizeof (picl_retsetattrval_t), NULL, 374*7c478bd9Sstevel@tonic-gate 0); 375*7c478bd9Sstevel@tonic-gate } 376*7c478bd9Sstevel@tonic-gate 377*7c478bd9Sstevel@tonic-gate /* 378*7c478bd9Sstevel@tonic-gate * This function sets the value of a property specified by its name. 379*7c478bd9Sstevel@tonic-gate */ 380*7c478bd9Sstevel@tonic-gate static void 381*7c478bd9Sstevel@tonic-gate picld_set_attrval_by_name(picl_service_t *in) 382*7c478bd9Sstevel@tonic-gate { 383*7c478bd9Sstevel@tonic-gate picl_retsetattrvalbyname_t ret; 384*7c478bd9Sstevel@tonic-gate int err; 385*7c478bd9Sstevel@tonic-gate door_cred_t cred; 386*7c478bd9Sstevel@tonic-gate picl_prophdl_t ptreeh; 387*7c478bd9Sstevel@tonic-gate ptree_propinfo_t pinfo; 388*7c478bd9Sstevel@tonic-gate 389*7c478bd9Sstevel@tonic-gate if (door_cred(&cred) < 0) 390*7c478bd9Sstevel@tonic-gate picld_return_error(in->in.cnum, PICL_FAILURE); 391*7c478bd9Sstevel@tonic-gate 392*7c478bd9Sstevel@tonic-gate err = cvt_picl2ptree(in->req_setattrvalbyname.nodeh, &ptreeh); 393*7c478bd9Sstevel@tonic-gate if (err != PICL_SUCCESS) 394*7c478bd9Sstevel@tonic-gate picld_return_error(in->in.cnum, err); 395*7c478bd9Sstevel@tonic-gate 396*7c478bd9Sstevel@tonic-gate err = xptree_get_propinfo_by_name(ptreeh, 397*7c478bd9Sstevel@tonic-gate in->req_setattrvalbyname.propname, &pinfo); 398*7c478bd9Sstevel@tonic-gate if (err != PICL_SUCCESS) 399*7c478bd9Sstevel@tonic-gate picld_return_error(in->in.cnum, err); 400*7c478bd9Sstevel@tonic-gate 401*7c478bd9Sstevel@tonic-gate if (!(pinfo.piclinfo.accessmode & PICL_WRITE)) 402*7c478bd9Sstevel@tonic-gate picld_return_error(in->in.cnum, PICL_NOTWRITABLE); 403*7c478bd9Sstevel@tonic-gate 404*7c478bd9Sstevel@tonic-gate /* 405*7c478bd9Sstevel@tonic-gate * For non-volatile prop, only super user can set its value. 406*7c478bd9Sstevel@tonic-gate */ 407*7c478bd9Sstevel@tonic-gate if (!(pinfo.piclinfo.accessmode & PICL_VOLATILE) && 408*7c478bd9Sstevel@tonic-gate (cred.dc_euid != SUPER_USER)) 409*7c478bd9Sstevel@tonic-gate picld_return_error(in->in.cnum, PICL_PERMDENIED); 410*7c478bd9Sstevel@tonic-gate 411*7c478bd9Sstevel@tonic-gate ret.cnum = PICL_CNUM_SETATTRVALBYNAME; 412*7c478bd9Sstevel@tonic-gate ret.nodeh = in->req_setattrvalbyname.nodeh; 413*7c478bd9Sstevel@tonic-gate (void) strcpy(ret.propname, in->req_setattrvalbyname.propname); 414*7c478bd9Sstevel@tonic-gate 415*7c478bd9Sstevel@tonic-gate err = xptree_update_propval_by_name_with_cred(ptreeh, 416*7c478bd9Sstevel@tonic-gate in->req_setattrvalbyname.propname, 417*7c478bd9Sstevel@tonic-gate in->req_setattrvalbyname.valbuf, 418*7c478bd9Sstevel@tonic-gate (size_t)in->req_setattrvalbyname.bufsize, 419*7c478bd9Sstevel@tonic-gate cred); 420*7c478bd9Sstevel@tonic-gate 421*7c478bd9Sstevel@tonic-gate if (err != PICL_SUCCESS) 422*7c478bd9Sstevel@tonic-gate picld_return_error(in->in.cnum, err); 423*7c478bd9Sstevel@tonic-gate 424*7c478bd9Sstevel@tonic-gate (void) rw_unlock(&init_lk); 425*7c478bd9Sstevel@tonic-gate (void) door_return((char *)&ret, sizeof (picl_retsetattrvalbyname_t), 426*7c478bd9Sstevel@tonic-gate NULL, 0); 427*7c478bd9Sstevel@tonic-gate } 428*7c478bd9Sstevel@tonic-gate 429*7c478bd9Sstevel@tonic-gate /* 430*7c478bd9Sstevel@tonic-gate * This function returns the property information 431*7c478bd9Sstevel@tonic-gate */ 432*7c478bd9Sstevel@tonic-gate static void 433*7c478bd9Sstevel@tonic-gate picld_get_attrinfo(picl_service_t *in) 434*7c478bd9Sstevel@tonic-gate { 435*7c478bd9Sstevel@tonic-gate picl_retattrinfo_t ret; 436*7c478bd9Sstevel@tonic-gate int err; 437*7c478bd9Sstevel@tonic-gate ptree_propinfo_t pinfo; 438*7c478bd9Sstevel@tonic-gate picl_prophdl_t ptreeh; 439*7c478bd9Sstevel@tonic-gate 440*7c478bd9Sstevel@tonic-gate err = cvt_picl2ptree(in->req_attrinfo.attr, &ptreeh); 441*7c478bd9Sstevel@tonic-gate if (err != PICL_SUCCESS) 442*7c478bd9Sstevel@tonic-gate picld_return_error(in->in.cnum, err); 443*7c478bd9Sstevel@tonic-gate 444*7c478bd9Sstevel@tonic-gate ret.cnum = PICL_CNUM_GETATTRINFO; 445*7c478bd9Sstevel@tonic-gate ret.attr = in->req_attrinfo.attr; 446*7c478bd9Sstevel@tonic-gate 447*7c478bd9Sstevel@tonic-gate err = ptree_get_propinfo(ptreeh, &pinfo); 448*7c478bd9Sstevel@tonic-gate if (err != PICL_SUCCESS) 449*7c478bd9Sstevel@tonic-gate picld_return_error(in->in.cnum, err); 450*7c478bd9Sstevel@tonic-gate 451*7c478bd9Sstevel@tonic-gate ret.type = pinfo.piclinfo.type; 452*7c478bd9Sstevel@tonic-gate ret.accessmode = pinfo.piclinfo.accessmode; 453*7c478bd9Sstevel@tonic-gate ret.size = (uint32_t)pinfo.piclinfo.size; 454*7c478bd9Sstevel@tonic-gate (void) strcpy(ret.name, pinfo.piclinfo.name); 455*7c478bd9Sstevel@tonic-gate (void) rw_unlock(&init_lk); 456*7c478bd9Sstevel@tonic-gate (void) door_return((char *)&ret, sizeof (picl_retattrinfo_t), NULL, 0); 457*7c478bd9Sstevel@tonic-gate } 458*7c478bd9Sstevel@tonic-gate 459*7c478bd9Sstevel@tonic-gate /* 460*7c478bd9Sstevel@tonic-gate * This function returns the node's first property handle 461*7c478bd9Sstevel@tonic-gate */ 462*7c478bd9Sstevel@tonic-gate static void 463*7c478bd9Sstevel@tonic-gate picld_get_first_attr(picl_service_t *in) 464*7c478bd9Sstevel@tonic-gate { 465*7c478bd9Sstevel@tonic-gate picl_retfirstattr_t ret; 466*7c478bd9Sstevel@tonic-gate int err; 467*7c478bd9Sstevel@tonic-gate picl_prophdl_t ptreeh; 468*7c478bd9Sstevel@tonic-gate 469*7c478bd9Sstevel@tonic-gate err = cvt_picl2ptree(in->req_firstattr.nodeh, &ptreeh); 470*7c478bd9Sstevel@tonic-gate if (err != PICL_SUCCESS) 471*7c478bd9Sstevel@tonic-gate picld_return_error(in->in.cnum, err); 472*7c478bd9Sstevel@tonic-gate 473*7c478bd9Sstevel@tonic-gate ret.cnum = PICL_CNUM_GETFIRSTATTR; 474*7c478bd9Sstevel@tonic-gate ret.nodeh = in->req_firstattr.nodeh; 475*7c478bd9Sstevel@tonic-gate 476*7c478bd9Sstevel@tonic-gate err = ptree_get_first_prop(ptreeh, &ret.attr); 477*7c478bd9Sstevel@tonic-gate if (err != PICL_SUCCESS) 478*7c478bd9Sstevel@tonic-gate picld_return_error(in->in.cnum, err); 479*7c478bd9Sstevel@tonic-gate cvt_ptree2picl(&ret.attr); 480*7c478bd9Sstevel@tonic-gate (void) rw_unlock(&init_lk); 481*7c478bd9Sstevel@tonic-gate (void) door_return((char *)&ret, sizeof (picl_retfirstattr_t), NULL, 0); 482*7c478bd9Sstevel@tonic-gate } 483*7c478bd9Sstevel@tonic-gate 484*7c478bd9Sstevel@tonic-gate /* 485*7c478bd9Sstevel@tonic-gate * This function returns the next property handle in list 486*7c478bd9Sstevel@tonic-gate */ 487*7c478bd9Sstevel@tonic-gate static void 488*7c478bd9Sstevel@tonic-gate picld_get_next_attr(picl_service_t *in) 489*7c478bd9Sstevel@tonic-gate { 490*7c478bd9Sstevel@tonic-gate picl_retnextattr_t ret; 491*7c478bd9Sstevel@tonic-gate int err; 492*7c478bd9Sstevel@tonic-gate picl_prophdl_t ptreeh; 493*7c478bd9Sstevel@tonic-gate 494*7c478bd9Sstevel@tonic-gate err = cvt_picl2ptree(in->req_nextattr.attr, &ptreeh); 495*7c478bd9Sstevel@tonic-gate if (err != PICL_SUCCESS) 496*7c478bd9Sstevel@tonic-gate picld_return_error(in->in.cnum, err); 497*7c478bd9Sstevel@tonic-gate 498*7c478bd9Sstevel@tonic-gate ret.cnum = PICL_CNUM_GETNEXTATTR; 499*7c478bd9Sstevel@tonic-gate ret.attr = in->req_nextattr.attr; 500*7c478bd9Sstevel@tonic-gate 501*7c478bd9Sstevel@tonic-gate err = ptree_get_next_prop(ptreeh, &ret.nextattr); 502*7c478bd9Sstevel@tonic-gate if (err != PICL_SUCCESS) 503*7c478bd9Sstevel@tonic-gate picld_return_error(in->in.cnum, err); 504*7c478bd9Sstevel@tonic-gate 505*7c478bd9Sstevel@tonic-gate cvt_ptree2picl(&ret.nextattr); 506*7c478bd9Sstevel@tonic-gate 507*7c478bd9Sstevel@tonic-gate (void) rw_unlock(&init_lk); 508*7c478bd9Sstevel@tonic-gate (void) door_return((char *)&ret, sizeof (picl_retnextattr_t), NULL, 0); 509*7c478bd9Sstevel@tonic-gate } 510*7c478bd9Sstevel@tonic-gate 511*7c478bd9Sstevel@tonic-gate /* 512*7c478bd9Sstevel@tonic-gate * This function returns the handle of a property specified by its name 513*7c478bd9Sstevel@tonic-gate */ 514*7c478bd9Sstevel@tonic-gate static void 515*7c478bd9Sstevel@tonic-gate picld_get_attr_by_name(picl_service_t *in) 516*7c478bd9Sstevel@tonic-gate { 517*7c478bd9Sstevel@tonic-gate picl_retattrbyname_t ret; 518*7c478bd9Sstevel@tonic-gate int err; 519*7c478bd9Sstevel@tonic-gate picl_prophdl_t ptreeh; 520*7c478bd9Sstevel@tonic-gate 521*7c478bd9Sstevel@tonic-gate err = cvt_picl2ptree(in->req_attrbyname.nodeh, &ptreeh); 522*7c478bd9Sstevel@tonic-gate if (err != PICL_SUCCESS) 523*7c478bd9Sstevel@tonic-gate picld_return_error(in->in.cnum, err); 524*7c478bd9Sstevel@tonic-gate 525*7c478bd9Sstevel@tonic-gate ret.cnum = PICL_CNUM_GETATTRBYNAME; 526*7c478bd9Sstevel@tonic-gate ret.nodeh = in->req_attrbyname.nodeh; 527*7c478bd9Sstevel@tonic-gate (void) strcpy(ret.propname, in->req_attrbyname.propname); 528*7c478bd9Sstevel@tonic-gate 529*7c478bd9Sstevel@tonic-gate err = ptree_get_prop_by_name(ptreeh, ret.propname, &ret.attr); 530*7c478bd9Sstevel@tonic-gate if (err != PICL_SUCCESS) 531*7c478bd9Sstevel@tonic-gate picld_return_error(in->in.cnum, err); 532*7c478bd9Sstevel@tonic-gate 533*7c478bd9Sstevel@tonic-gate cvt_ptree2picl(&ret.attr); 534*7c478bd9Sstevel@tonic-gate (void) rw_unlock(&init_lk); 535*7c478bd9Sstevel@tonic-gate (void) door_return((char *)&ret, sizeof (picl_retattrbyname_t), NULL, 536*7c478bd9Sstevel@tonic-gate 0); 537*7c478bd9Sstevel@tonic-gate } 538*7c478bd9Sstevel@tonic-gate 539*7c478bd9Sstevel@tonic-gate /* 540*7c478bd9Sstevel@tonic-gate * This function gets the next property on the same row in the table 541*7c478bd9Sstevel@tonic-gate */ 542*7c478bd9Sstevel@tonic-gate static void 543*7c478bd9Sstevel@tonic-gate picld_get_attr_by_row(picl_service_t *in) 544*7c478bd9Sstevel@tonic-gate { 545*7c478bd9Sstevel@tonic-gate picl_retattrbyrow_t ret; 546*7c478bd9Sstevel@tonic-gate int err; 547*7c478bd9Sstevel@tonic-gate picl_prophdl_t ptreeh; 548*7c478bd9Sstevel@tonic-gate 549*7c478bd9Sstevel@tonic-gate err = cvt_picl2ptree(in->req_attrbyrow.attr, &ptreeh); 550*7c478bd9Sstevel@tonic-gate if (err != PICL_SUCCESS) 551*7c478bd9Sstevel@tonic-gate picld_return_error(in->in.cnum, err); 552*7c478bd9Sstevel@tonic-gate 553*7c478bd9Sstevel@tonic-gate ret.cnum = PICL_CNUM_GETATTRBYROW; 554*7c478bd9Sstevel@tonic-gate ret.attr = in->req_attrbyrow.attr; 555*7c478bd9Sstevel@tonic-gate 556*7c478bd9Sstevel@tonic-gate err = ptree_get_next_by_row(ptreeh, &ret.rowattr); 557*7c478bd9Sstevel@tonic-gate if (err != PICL_SUCCESS) 558*7c478bd9Sstevel@tonic-gate picld_return_error(in->in.cnum, err); 559*7c478bd9Sstevel@tonic-gate cvt_ptree2picl(&ret.rowattr); 560*7c478bd9Sstevel@tonic-gate 561*7c478bd9Sstevel@tonic-gate (void) rw_unlock(&init_lk); 562*7c478bd9Sstevel@tonic-gate (void) door_return((char *)&ret, sizeof (picl_retattrbyrow_t), NULL, 0); 563*7c478bd9Sstevel@tonic-gate } 564*7c478bd9Sstevel@tonic-gate 565*7c478bd9Sstevel@tonic-gate /* 566*7c478bd9Sstevel@tonic-gate * This function returns the handle of the next property in the same column 567*7c478bd9Sstevel@tonic-gate * of the table. 568*7c478bd9Sstevel@tonic-gate */ 569*7c478bd9Sstevel@tonic-gate static void 570*7c478bd9Sstevel@tonic-gate picld_get_attr_by_col(picl_service_t *in) 571*7c478bd9Sstevel@tonic-gate { 572*7c478bd9Sstevel@tonic-gate picl_retattrbycol_t ret; 573*7c478bd9Sstevel@tonic-gate int err; 574*7c478bd9Sstevel@tonic-gate picl_prophdl_t ptreeh; 575*7c478bd9Sstevel@tonic-gate 576*7c478bd9Sstevel@tonic-gate err = cvt_picl2ptree(in->req_attrbycol.attr, &ptreeh); 577*7c478bd9Sstevel@tonic-gate if (err != PICL_SUCCESS) 578*7c478bd9Sstevel@tonic-gate picld_return_error(in->in.cnum, err); 579*7c478bd9Sstevel@tonic-gate 580*7c478bd9Sstevel@tonic-gate ret.cnum = PICL_CNUM_GETATTRBYCOL; 581*7c478bd9Sstevel@tonic-gate ret.attr = in->req_attrbycol.attr; 582*7c478bd9Sstevel@tonic-gate 583*7c478bd9Sstevel@tonic-gate err = ptree_get_next_by_col(ptreeh, &ret.colattr); 584*7c478bd9Sstevel@tonic-gate if (err != PICL_SUCCESS) 585*7c478bd9Sstevel@tonic-gate picld_return_error(in->in.cnum, err); 586*7c478bd9Sstevel@tonic-gate 587*7c478bd9Sstevel@tonic-gate cvt_ptree2picl(&ret.colattr); 588*7c478bd9Sstevel@tonic-gate 589*7c478bd9Sstevel@tonic-gate (void) rw_unlock(&init_lk); 590*7c478bd9Sstevel@tonic-gate (void) door_return((char *)&ret, sizeof (picl_retattrbycol_t), NULL, 0); 591*7c478bd9Sstevel@tonic-gate } 592*7c478bd9Sstevel@tonic-gate 593*7c478bd9Sstevel@tonic-gate /* 594*7c478bd9Sstevel@tonic-gate * This function finds the node in the PICLTREE that matches the given 595*7c478bd9Sstevel@tonic-gate * criteria and returns its handle. 596*7c478bd9Sstevel@tonic-gate */ 597*7c478bd9Sstevel@tonic-gate static void 598*7c478bd9Sstevel@tonic-gate picld_find_node(picl_service_t *in) 599*7c478bd9Sstevel@tonic-gate { 600*7c478bd9Sstevel@tonic-gate picl_retfindnode_t ret; 601*7c478bd9Sstevel@tonic-gate int err; 602*7c478bd9Sstevel@tonic-gate picl_nodehdl_t ptreeh; 603*7c478bd9Sstevel@tonic-gate 604*7c478bd9Sstevel@tonic-gate err = cvt_picl2ptree(in->req_findnode.nodeh, &ptreeh); 605*7c478bd9Sstevel@tonic-gate if (err != PICL_SUCCESS) 606*7c478bd9Sstevel@tonic-gate picld_return_error(in->in.cnum, err); 607*7c478bd9Sstevel@tonic-gate 608*7c478bd9Sstevel@tonic-gate ret.cnum = PICL_CNUM_FINDNODE; 609*7c478bd9Sstevel@tonic-gate 610*7c478bd9Sstevel@tonic-gate err = ptree_find_node(ptreeh, in->req_findnode.propname, 611*7c478bd9Sstevel@tonic-gate in->req_findnode.ptype, in->req_findnode.valbuf, 612*7c478bd9Sstevel@tonic-gate in->req_findnode.valsize, &ret.rnodeh); 613*7c478bd9Sstevel@tonic-gate if (err != PICL_SUCCESS) 614*7c478bd9Sstevel@tonic-gate picld_return_error(in->in.cnum, err); 615*7c478bd9Sstevel@tonic-gate 616*7c478bd9Sstevel@tonic-gate cvt_ptree2picl(&ret.rnodeh); 617*7c478bd9Sstevel@tonic-gate 618*7c478bd9Sstevel@tonic-gate (void) rw_unlock(&init_lk); 619*7c478bd9Sstevel@tonic-gate (void) door_return((char *)&ret, sizeof (ret), NULL, 0); 620*7c478bd9Sstevel@tonic-gate } 621*7c478bd9Sstevel@tonic-gate 622*7c478bd9Sstevel@tonic-gate /* 623*7c478bd9Sstevel@tonic-gate * This function finds the property/node that corresponds to the given path 624*7c478bd9Sstevel@tonic-gate * and returns its handle 625*7c478bd9Sstevel@tonic-gate */ 626*7c478bd9Sstevel@tonic-gate static void 627*7c478bd9Sstevel@tonic-gate picld_get_node_by_path(picl_service_t *in) 628*7c478bd9Sstevel@tonic-gate { 629*7c478bd9Sstevel@tonic-gate picl_retnodebypath_t ret; 630*7c478bd9Sstevel@tonic-gate int err; 631*7c478bd9Sstevel@tonic-gate 632*7c478bd9Sstevel@tonic-gate ret.cnum = PICL_CNUM_NODEBYPATH; 633*7c478bd9Sstevel@tonic-gate err = ptree_get_node_by_path(in->req_nodebypath.pathbuf, &ret.nodeh); 634*7c478bd9Sstevel@tonic-gate if (err != PICL_SUCCESS) 635*7c478bd9Sstevel@tonic-gate picld_return_error(in->in.cnum, err); 636*7c478bd9Sstevel@tonic-gate cvt_ptree2picl(&ret.nodeh); 637*7c478bd9Sstevel@tonic-gate (void) rw_unlock(&init_lk); 638*7c478bd9Sstevel@tonic-gate (void) door_return((char *)&ret, sizeof (ret), NULL, 0); 639*7c478bd9Sstevel@tonic-gate } 640*7c478bd9Sstevel@tonic-gate 641*7c478bd9Sstevel@tonic-gate /* 642*7c478bd9Sstevel@tonic-gate * This function returns finds the frutree parent node for a given node 643*7c478bd9Sstevel@tonic-gate * and returns its handle 644*7c478bd9Sstevel@tonic-gate */ 645*7c478bd9Sstevel@tonic-gate static void 646*7c478bd9Sstevel@tonic-gate picld_get_frutree_parent(picl_service_t *in) 647*7c478bd9Sstevel@tonic-gate { 648*7c478bd9Sstevel@tonic-gate picl_retfruparent_t ret; 649*7c478bd9Sstevel@tonic-gate int err; 650*7c478bd9Sstevel@tonic-gate picl_nodehdl_t ptreeh; 651*7c478bd9Sstevel@tonic-gate 652*7c478bd9Sstevel@tonic-gate err = cvt_picl2ptree(in->req_fruparent.devh, &ptreeh); 653*7c478bd9Sstevel@tonic-gate if (err != PICL_SUCCESS) 654*7c478bd9Sstevel@tonic-gate picld_return_error(in->in.cnum, err); 655*7c478bd9Sstevel@tonic-gate 656*7c478bd9Sstevel@tonic-gate ret.cnum = PICL_CNUM_FRUTREEPARENT; 657*7c478bd9Sstevel@tonic-gate 658*7c478bd9Sstevel@tonic-gate err = ptree_get_frutree_parent(ptreeh, &ret.fruh); 659*7c478bd9Sstevel@tonic-gate if (err != PICL_SUCCESS) 660*7c478bd9Sstevel@tonic-gate picld_return_error(in->in.cnum, err); 661*7c478bd9Sstevel@tonic-gate cvt_ptree2picl(&ret.fruh); 662*7c478bd9Sstevel@tonic-gate 663*7c478bd9Sstevel@tonic-gate (void) rw_unlock(&init_lk); 664*7c478bd9Sstevel@tonic-gate (void) door_return((char *)&ret, sizeof (ret), NULL, 0); 665*7c478bd9Sstevel@tonic-gate } 666*7c478bd9Sstevel@tonic-gate 667*7c478bd9Sstevel@tonic-gate /* 668*7c478bd9Sstevel@tonic-gate * This function is called when an unknown client request is received. 669*7c478bd9Sstevel@tonic-gate */ 670*7c478bd9Sstevel@tonic-gate static void 671*7c478bd9Sstevel@tonic-gate picld_unknown_service(picl_service_t *in) 672*7c478bd9Sstevel@tonic-gate { 673*7c478bd9Sstevel@tonic-gate picld_return_error(in->in.cnum, PICL_UNKNOWNSERVICE); 674*7c478bd9Sstevel@tonic-gate } 675*7c478bd9Sstevel@tonic-gate 676*7c478bd9Sstevel@tonic-gate static void 677*7c478bd9Sstevel@tonic-gate check_denial_of_service(int cnum) 678*7c478bd9Sstevel@tonic-gate { 679*7c478bd9Sstevel@tonic-gate hrtime_t window; 680*7c478bd9Sstevel@tonic-gate hrtime_t current; 681*7c478bd9Sstevel@tonic-gate int dos_flag; 682*7c478bd9Sstevel@tonic-gate 683*7c478bd9Sstevel@tonic-gate current = gethrtime(); 684*7c478bd9Sstevel@tonic-gate dos_flag = 0; 685*7c478bd9Sstevel@tonic-gate 686*7c478bd9Sstevel@tonic-gate if (pthread_mutex_lock(&dos_mutex) != 0) 687*7c478bd9Sstevel@tonic-gate picld_return_error(cnum, PICL_FAILURE); 688*7c478bd9Sstevel@tonic-gate 689*7c478bd9Sstevel@tonic-gate ++service_requests; 690*7c478bd9Sstevel@tonic-gate window = current - orig_time; 691*7c478bd9Sstevel@tonic-gate if (window > MILLI_TO_NANO(sliding_interval_ms)) { 692*7c478bd9Sstevel@tonic-gate orig_time = current; 693*7c478bd9Sstevel@tonic-gate service_requests = 1; 694*7c478bd9Sstevel@tonic-gate } 695*7c478bd9Sstevel@tonic-gate 696*7c478bd9Sstevel@tonic-gate if (service_requests > dos_req_limit) 697*7c478bd9Sstevel@tonic-gate dos_flag = 1; 698*7c478bd9Sstevel@tonic-gate 699*7c478bd9Sstevel@tonic-gate if (pthread_mutex_unlock(&dos_mutex) != 0) 700*7c478bd9Sstevel@tonic-gate picld_return_error(cnum, PICL_FAILURE); 701*7c478bd9Sstevel@tonic-gate 702*7c478bd9Sstevel@tonic-gate if (dos_flag) 703*7c478bd9Sstevel@tonic-gate (void) poll(NULL, 0, dos_ms); 704*7c478bd9Sstevel@tonic-gate } 705*7c478bd9Sstevel@tonic-gate 706*7c478bd9Sstevel@tonic-gate 707*7c478bd9Sstevel@tonic-gate /* ARGSUSED */ 708*7c478bd9Sstevel@tonic-gate static void 709*7c478bd9Sstevel@tonic-gate picld_door_handler(void *cookie, char *argp, size_t asize, 710*7c478bd9Sstevel@tonic-gate door_desc_t *dp, uint_t n_desc) 711*7c478bd9Sstevel@tonic-gate { 712*7c478bd9Sstevel@tonic-gate picl_service_t *req; 713*7c478bd9Sstevel@tonic-gate 714*7c478bd9Sstevel@tonic-gate /*LINTED*/ 715*7c478bd9Sstevel@tonic-gate req = (picl_service_t *)argp; 716*7c478bd9Sstevel@tonic-gate 717*7c478bd9Sstevel@tonic-gate if (req == NULL) 718*7c478bd9Sstevel@tonic-gate (void) door_return((char *)req, 0, NULL, 0); 719*7c478bd9Sstevel@tonic-gate 720*7c478bd9Sstevel@tonic-gate check_denial_of_service(req->in.cnum); 721*7c478bd9Sstevel@tonic-gate 722*7c478bd9Sstevel@tonic-gate (void) rw_rdlock(&init_lk); 723*7c478bd9Sstevel@tonic-gate switch (req->in.cnum) { /* client call number */ 724*7c478bd9Sstevel@tonic-gate case PICL_CNUM_INIT: 725*7c478bd9Sstevel@tonic-gate /*LINTED*/ 726*7c478bd9Sstevel@tonic-gate picld_init((picl_service_t *)argp); 727*7c478bd9Sstevel@tonic-gate break; 728*7c478bd9Sstevel@tonic-gate case PICL_CNUM_FINI: 729*7c478bd9Sstevel@tonic-gate /*LINTED*/ 730*7c478bd9Sstevel@tonic-gate picld_fini((picl_service_t *)argp); 731*7c478bd9Sstevel@tonic-gate break; 732*7c478bd9Sstevel@tonic-gate case PICL_CNUM_GETROOT: 733*7c478bd9Sstevel@tonic-gate /*LINTED*/ 734*7c478bd9Sstevel@tonic-gate picld_getroot((picl_service_t *)argp); 735*7c478bd9Sstevel@tonic-gate break; 736*7c478bd9Sstevel@tonic-gate case PICL_CNUM_GETATTRVAL: 737*7c478bd9Sstevel@tonic-gate /*LINTED*/ 738*7c478bd9Sstevel@tonic-gate picld_get_attrval((picl_service_t *)argp); 739*7c478bd9Sstevel@tonic-gate break; 740*7c478bd9Sstevel@tonic-gate case PICL_CNUM_GETATTRVALBYNAME: 741*7c478bd9Sstevel@tonic-gate /*LINTED*/ 742*7c478bd9Sstevel@tonic-gate picld_get_attrval_by_name((picl_service_t *)argp); 743*7c478bd9Sstevel@tonic-gate break; 744*7c478bd9Sstevel@tonic-gate case PICL_CNUM_GETATTRINFO: 745*7c478bd9Sstevel@tonic-gate /*LINTED*/ 746*7c478bd9Sstevel@tonic-gate picld_get_attrinfo((picl_service_t *)argp); 747*7c478bd9Sstevel@tonic-gate break; 748*7c478bd9Sstevel@tonic-gate case PICL_CNUM_GETFIRSTATTR: 749*7c478bd9Sstevel@tonic-gate /*LINTED*/ 750*7c478bd9Sstevel@tonic-gate picld_get_first_attr((picl_service_t *)argp); 751*7c478bd9Sstevel@tonic-gate break; 752*7c478bd9Sstevel@tonic-gate case PICL_CNUM_GETNEXTATTR: 753*7c478bd9Sstevel@tonic-gate /*LINTED*/ 754*7c478bd9Sstevel@tonic-gate picld_get_next_attr((picl_service_t *)argp); 755*7c478bd9Sstevel@tonic-gate break; 756*7c478bd9Sstevel@tonic-gate case PICL_CNUM_GETATTRBYNAME: 757*7c478bd9Sstevel@tonic-gate /*LINTED*/ 758*7c478bd9Sstevel@tonic-gate picld_get_attr_by_name((picl_service_t *)argp); 759*7c478bd9Sstevel@tonic-gate break; 760*7c478bd9Sstevel@tonic-gate case PICL_CNUM_GETATTRBYROW: 761*7c478bd9Sstevel@tonic-gate /*LINTED*/ 762*7c478bd9Sstevel@tonic-gate picld_get_attr_by_row((picl_service_t *)argp); 763*7c478bd9Sstevel@tonic-gate break; 764*7c478bd9Sstevel@tonic-gate case PICL_CNUM_GETATTRBYCOL: 765*7c478bd9Sstevel@tonic-gate /*LINTED*/ 766*7c478bd9Sstevel@tonic-gate picld_get_attr_by_col((picl_service_t *)argp); 767*7c478bd9Sstevel@tonic-gate break; 768*7c478bd9Sstevel@tonic-gate case PICL_CNUM_SETATTRVAL: 769*7c478bd9Sstevel@tonic-gate /*LINTED*/ 770*7c478bd9Sstevel@tonic-gate picld_set_attrval((picl_service_t *)argp); 771*7c478bd9Sstevel@tonic-gate break; 772*7c478bd9Sstevel@tonic-gate case PICL_CNUM_SETATTRVALBYNAME: 773*7c478bd9Sstevel@tonic-gate /*LINTED*/ 774*7c478bd9Sstevel@tonic-gate picld_set_attrval_by_name((picl_service_t *)argp); 775*7c478bd9Sstevel@tonic-gate break; 776*7c478bd9Sstevel@tonic-gate case PICL_CNUM_PING: 777*7c478bd9Sstevel@tonic-gate /*LINTED*/ 778*7c478bd9Sstevel@tonic-gate picld_ping((picl_service_t *)argp); 779*7c478bd9Sstevel@tonic-gate break; 780*7c478bd9Sstevel@tonic-gate case PICL_CNUM_WAIT: 781*7c478bd9Sstevel@tonic-gate /*LINTED*/ 782*7c478bd9Sstevel@tonic-gate picld_wait((picl_service_t *)argp); 783*7c478bd9Sstevel@tonic-gate break; 784*7c478bd9Sstevel@tonic-gate case PICL_CNUM_FINDNODE: 785*7c478bd9Sstevel@tonic-gate /*LINTED*/ 786*7c478bd9Sstevel@tonic-gate picld_find_node((picl_service_t *)argp); 787*7c478bd9Sstevel@tonic-gate break; 788*7c478bd9Sstevel@tonic-gate case PICL_CNUM_NODEBYPATH: 789*7c478bd9Sstevel@tonic-gate /*LINTED*/ 790*7c478bd9Sstevel@tonic-gate picld_get_node_by_path((picl_service_t *)argp); 791*7c478bd9Sstevel@tonic-gate break; 792*7c478bd9Sstevel@tonic-gate case PICL_CNUM_FRUTREEPARENT: 793*7c478bd9Sstevel@tonic-gate /*LINTED*/ 794*7c478bd9Sstevel@tonic-gate picld_get_frutree_parent((picl_service_t *)argp); 795*7c478bd9Sstevel@tonic-gate break; 796*7c478bd9Sstevel@tonic-gate default: 797*7c478bd9Sstevel@tonic-gate /*LINTED*/ 798*7c478bd9Sstevel@tonic-gate picld_unknown_service((picl_service_t *)argp); 799*7c478bd9Sstevel@tonic-gate break; 800*7c478bd9Sstevel@tonic-gate }; 801*7c478bd9Sstevel@tonic-gate /*NOTREACHED*/ 802*7c478bd9Sstevel@tonic-gate } 803*7c478bd9Sstevel@tonic-gate 804*7c478bd9Sstevel@tonic-gate /* ARGSUSED */ 805*7c478bd9Sstevel@tonic-gate static void 806*7c478bd9Sstevel@tonic-gate hup_handler(int sig, siginfo_t *siginfo, void *sigctx) 807*7c478bd9Sstevel@tonic-gate { 808*7c478bd9Sstevel@tonic-gate doreinit = 1; 809*7c478bd9Sstevel@tonic-gate } 810*7c478bd9Sstevel@tonic-gate 811*7c478bd9Sstevel@tonic-gate /* 812*7c478bd9Sstevel@tonic-gate * "ping" to see if a daemon is already running 813*7c478bd9Sstevel@tonic-gate */ 814*7c478bd9Sstevel@tonic-gate static int 815*7c478bd9Sstevel@tonic-gate daemon_exists(void) 816*7c478bd9Sstevel@tonic-gate { 817*7c478bd9Sstevel@tonic-gate door_arg_t darg; 818*7c478bd9Sstevel@tonic-gate picl_reqping_t req_ping; 819*7c478bd9Sstevel@tonic-gate picl_retping_t ret_ping; 820*7c478bd9Sstevel@tonic-gate int doorh; 821*7c478bd9Sstevel@tonic-gate door_info_t dinfo; 822*7c478bd9Sstevel@tonic-gate 823*7c478bd9Sstevel@tonic-gate doorh = open(PICLD_DOOR, O_RDONLY); 824*7c478bd9Sstevel@tonic-gate if (doorh < 0) 825*7c478bd9Sstevel@tonic-gate return (0); 826*7c478bd9Sstevel@tonic-gate 827*7c478bd9Sstevel@tonic-gate if (door_info(doorh, &dinfo) < 0) { 828*7c478bd9Sstevel@tonic-gate (void) close(doorh); 829*7c478bd9Sstevel@tonic-gate return (0); 830*7c478bd9Sstevel@tonic-gate } 831*7c478bd9Sstevel@tonic-gate 832*7c478bd9Sstevel@tonic-gate if ((dinfo.di_attributes & DOOR_REVOKED) || 833*7c478bd9Sstevel@tonic-gate (dinfo.di_data != (door_ptr_t)PICLD_DOOR_COOKIE)) { 834*7c478bd9Sstevel@tonic-gate (void) close(doorh); 835*7c478bd9Sstevel@tonic-gate return (0); 836*7c478bd9Sstevel@tonic-gate } 837*7c478bd9Sstevel@tonic-gate 838*7c478bd9Sstevel@tonic-gate if (dinfo.di_target != getpid()) { 839*7c478bd9Sstevel@tonic-gate (void) close(doorh); 840*7c478bd9Sstevel@tonic-gate return (1); 841*7c478bd9Sstevel@tonic-gate } 842*7c478bd9Sstevel@tonic-gate 843*7c478bd9Sstevel@tonic-gate req_ping.cnum = PICL_CNUM_PING; 844*7c478bd9Sstevel@tonic-gate 845*7c478bd9Sstevel@tonic-gate darg.data_ptr = (char *)&req_ping; 846*7c478bd9Sstevel@tonic-gate darg.data_size = sizeof (picl_reqping_t); 847*7c478bd9Sstevel@tonic-gate darg.desc_ptr = NULL; 848*7c478bd9Sstevel@tonic-gate darg.desc_num = 0; 849*7c478bd9Sstevel@tonic-gate darg.rbuf = (char *)&ret_ping; 850*7c478bd9Sstevel@tonic-gate darg.rsize = sizeof (picl_retping_t); 851*7c478bd9Sstevel@tonic-gate 852*7c478bd9Sstevel@tonic-gate if (door_call(doorh, &darg) < 0) { 853*7c478bd9Sstevel@tonic-gate (void) close(doorh); 854*7c478bd9Sstevel@tonic-gate return (0); 855*7c478bd9Sstevel@tonic-gate } 856*7c478bd9Sstevel@tonic-gate 857*7c478bd9Sstevel@tonic-gate (void) close(doorh); 858*7c478bd9Sstevel@tonic-gate return (1); 859*7c478bd9Sstevel@tonic-gate } 860*7c478bd9Sstevel@tonic-gate 861*7c478bd9Sstevel@tonic-gate /* 862*7c478bd9Sstevel@tonic-gate * Create the picld door 863*7c478bd9Sstevel@tonic-gate */ 864*7c478bd9Sstevel@tonic-gate static int 865*7c478bd9Sstevel@tonic-gate setup_door(void) 866*7c478bd9Sstevel@tonic-gate { 867*7c478bd9Sstevel@tonic-gate struct stat stbuf; 868*7c478bd9Sstevel@tonic-gate 869*7c478bd9Sstevel@tonic-gate /* 870*7c478bd9Sstevel@tonic-gate * Create the door 871*7c478bd9Sstevel@tonic-gate */ 872*7c478bd9Sstevel@tonic-gate door_id = door_create(picld_door_handler, PICLD_DOOR_COOKIE, 873*7c478bd9Sstevel@tonic-gate DOOR_UNREF | DOOR_REFUSE_DESC | DOOR_NO_CANCEL); 874*7c478bd9Sstevel@tonic-gate 875*7c478bd9Sstevel@tonic-gate if (door_id < 0) { 876*7c478bd9Sstevel@tonic-gate return (-1); 877*7c478bd9Sstevel@tonic-gate } 878*7c478bd9Sstevel@tonic-gate 879*7c478bd9Sstevel@tonic-gate if (stat(PICLD_DOOR, &stbuf) < 0) { 880*7c478bd9Sstevel@tonic-gate int newfd; 881*7c478bd9Sstevel@tonic-gate if ((newfd = creat(PICLD_DOOR, 0444)) < 0) 882*7c478bd9Sstevel@tonic-gate return (-1); 883*7c478bd9Sstevel@tonic-gate (void) close(newfd); 884*7c478bd9Sstevel@tonic-gate } 885*7c478bd9Sstevel@tonic-gate 886*7c478bd9Sstevel@tonic-gate if (fattach(door_id, PICLD_DOOR) < 0) { 887*7c478bd9Sstevel@tonic-gate if ((errno != EBUSY) || 888*7c478bd9Sstevel@tonic-gate (fdetach(PICLD_DOOR) < 0) || 889*7c478bd9Sstevel@tonic-gate (fattach(door_id, PICLD_DOOR) < 0)) 890*7c478bd9Sstevel@tonic-gate return (-1); 891*7c478bd9Sstevel@tonic-gate } 892*7c478bd9Sstevel@tonic-gate 893*7c478bd9Sstevel@tonic-gate return (0); 894*7c478bd9Sstevel@tonic-gate } 895*7c478bd9Sstevel@tonic-gate 896*7c478bd9Sstevel@tonic-gate /* 897*7c478bd9Sstevel@tonic-gate * Main function of picl daemon 898*7c478bd9Sstevel@tonic-gate */ 899*7c478bd9Sstevel@tonic-gate int 900*7c478bd9Sstevel@tonic-gate main(int argc, char **argv) 901*7c478bd9Sstevel@tonic-gate { 902*7c478bd9Sstevel@tonic-gate struct sigaction act; 903*7c478bd9Sstevel@tonic-gate int c; 904*7c478bd9Sstevel@tonic-gate sigset_t ublk; 905*7c478bd9Sstevel@tonic-gate 906*7c478bd9Sstevel@tonic-gate 907*7c478bd9Sstevel@tonic-gate (void) setlocale(LC_ALL, ""); 908*7c478bd9Sstevel@tonic-gate (void) textdomain(TEXT_DOMAIN); 909*7c478bd9Sstevel@tonic-gate 910*7c478bd9Sstevel@tonic-gate if (getuid() != 0) { 911*7c478bd9Sstevel@tonic-gate syslog(LOG_CRIT, MUST_BE_ROOT); 912*7c478bd9Sstevel@tonic-gate return (0); 913*7c478bd9Sstevel@tonic-gate } 914*7c478bd9Sstevel@tonic-gate 915*7c478bd9Sstevel@tonic-gate (void) rwlock_init(&init_lk, USYNC_THREAD, NULL); 916*7c478bd9Sstevel@tonic-gate doreinit = 0; 917*7c478bd9Sstevel@tonic-gate logflag = 1; 918*7c478bd9Sstevel@tonic-gate dos_req_limit = DOS_PICL_REQUESTS_LIMIT; 919*7c478bd9Sstevel@tonic-gate sliding_interval_ms = SLIDING_INTERVAL_MILLISECONDS; 920*7c478bd9Sstevel@tonic-gate dos_ms = DOS_SLEEPTIME_MS; 921*7c478bd9Sstevel@tonic-gate verbose_level = 0; 922*7c478bd9Sstevel@tonic-gate 923*7c478bd9Sstevel@tonic-gate /* 924*7c478bd9Sstevel@tonic-gate * parse arguments 925*7c478bd9Sstevel@tonic-gate */ 926*7c478bd9Sstevel@tonic-gate while ((c = getopt(argc, argv, "is:t:l:r:v:d:")) != EOF) { 927*7c478bd9Sstevel@tonic-gate switch (c) { 928*7c478bd9Sstevel@tonic-gate case 'd': 929*7c478bd9Sstevel@tonic-gate dos_ms = strtol(optarg, (char **)NULL, 0); 930*7c478bd9Sstevel@tonic-gate break; 931*7c478bd9Sstevel@tonic-gate case 'i': 932*7c478bd9Sstevel@tonic-gate logflag = 0; 933*7c478bd9Sstevel@tonic-gate break; 934*7c478bd9Sstevel@tonic-gate case 's': 935*7c478bd9Sstevel@tonic-gate sliding_interval_ms = strtoll(optarg, (char **)NULL, 0); 936*7c478bd9Sstevel@tonic-gate break; 937*7c478bd9Sstevel@tonic-gate case 't': 938*7c478bd9Sstevel@tonic-gate dos_req_limit = strtol(optarg, (char **)NULL, 0); 939*7c478bd9Sstevel@tonic-gate break; 940*7c478bd9Sstevel@tonic-gate case 'v': 941*7c478bd9Sstevel@tonic-gate verbose_level = strtol(optarg, (char **)NULL, 0); 942*7c478bd9Sstevel@tonic-gate logflag = 0; 943*7c478bd9Sstevel@tonic-gate break; 944*7c478bd9Sstevel@tonic-gate default: 945*7c478bd9Sstevel@tonic-gate break; 946*7c478bd9Sstevel@tonic-gate } 947*7c478bd9Sstevel@tonic-gate } 948*7c478bd9Sstevel@tonic-gate 949*7c478bd9Sstevel@tonic-gate orig_time = gethrtime(); 950*7c478bd9Sstevel@tonic-gate 951*7c478bd9Sstevel@tonic-gate /* 952*7c478bd9Sstevel@tonic-gate * is there a daemon already running? 953*7c478bd9Sstevel@tonic-gate */ 954*7c478bd9Sstevel@tonic-gate 955*7c478bd9Sstevel@tonic-gate if (daemon_exists()) { 956*7c478bd9Sstevel@tonic-gate syslog(LOG_CRIT, DAEMON_RUNNING); 957*7c478bd9Sstevel@tonic-gate exit(1); 958*7c478bd9Sstevel@tonic-gate } 959*7c478bd9Sstevel@tonic-gate 960*7c478bd9Sstevel@tonic-gate /* 961*7c478bd9Sstevel@tonic-gate * Mask off/block SIGALRM signal so that the environmental plug-in 962*7c478bd9Sstevel@tonic-gate * (piclenvd) can use it to simulate sleep() without being affected 963*7c478bd9Sstevel@tonic-gate * by time being set back. No other PICL plug-in should use SIGALRM 964*7c478bd9Sstevel@tonic-gate * or alarm() for now. 965*7c478bd9Sstevel@tonic-gate */ 966*7c478bd9Sstevel@tonic-gate (void) sigemptyset(&ublk); 967*7c478bd9Sstevel@tonic-gate (void) sigaddset(&ublk, SIGALRM); 968*7c478bd9Sstevel@tonic-gate (void) sigprocmask(SIG_BLOCK, &ublk, NULL); 969*7c478bd9Sstevel@tonic-gate 970*7c478bd9Sstevel@tonic-gate /* 971*7c478bd9Sstevel@tonic-gate * Ignore SIGHUP until all the initialization is done. 972*7c478bd9Sstevel@tonic-gate */ 973*7c478bd9Sstevel@tonic-gate act.sa_handler = SIG_IGN; 974*7c478bd9Sstevel@tonic-gate (void) sigemptyset(&act.sa_mask); 975*7c478bd9Sstevel@tonic-gate act.sa_flags = 0; 976*7c478bd9Sstevel@tonic-gate if (sigaction(SIGHUP, &act, NULL) == -1) 977*7c478bd9Sstevel@tonic-gate syslog(LOG_ERR, SIGACT_FAILED, strsignal(SIGHUP), 978*7c478bd9Sstevel@tonic-gate strerror(errno)); 979*7c478bd9Sstevel@tonic-gate 980*7c478bd9Sstevel@tonic-gate if (logflag != 0) { /* daemonize */ 981*7c478bd9Sstevel@tonic-gate pid_t pid; 982*7c478bd9Sstevel@tonic-gate 983*7c478bd9Sstevel@tonic-gate pid = fork(); 984*7c478bd9Sstevel@tonic-gate if (pid < 0) 985*7c478bd9Sstevel@tonic-gate exit(1); 986*7c478bd9Sstevel@tonic-gate if (pid > 0) 987*7c478bd9Sstevel@tonic-gate /* parent */ 988*7c478bd9Sstevel@tonic-gate exit(0); 989*7c478bd9Sstevel@tonic-gate 990*7c478bd9Sstevel@tonic-gate /* child */ 991*7c478bd9Sstevel@tonic-gate if (chdir("/") == -1) { 992*7c478bd9Sstevel@tonic-gate syslog(LOG_CRIT, CD_ROOT_FAILED); 993*7c478bd9Sstevel@tonic-gate exit(1); 994*7c478bd9Sstevel@tonic-gate } 995*7c478bd9Sstevel@tonic-gate 996*7c478bd9Sstevel@tonic-gate (void) setsid(); 997*7c478bd9Sstevel@tonic-gate (void) close(STDIN_FILENO); 998*7c478bd9Sstevel@tonic-gate (void) close(STDOUT_FILENO); 999*7c478bd9Sstevel@tonic-gate (void) close(STDERR_FILENO); 1000*7c478bd9Sstevel@tonic-gate (void) open("/dev/null", O_RDWR, 0); 1001*7c478bd9Sstevel@tonic-gate (void) dup2(STDIN_FILENO, STDOUT_FILENO); 1002*7c478bd9Sstevel@tonic-gate (void) dup2(STDIN_FILENO, STDERR_FILENO); 1003*7c478bd9Sstevel@tonic-gate openlog(PICLD, LOG_PID, LOG_DAEMON); 1004*7c478bd9Sstevel@tonic-gate } 1005*7c478bd9Sstevel@tonic-gate 1006*7c478bd9Sstevel@tonic-gate /* 1007*7c478bd9Sstevel@tonic-gate * Initialize the PICL Tree 1008*7c478bd9Sstevel@tonic-gate */ 1009*7c478bd9Sstevel@tonic-gate if (xptree_initialize(NULL) != PICL_SUCCESS) { 1010*7c478bd9Sstevel@tonic-gate syslog(LOG_CRIT, INIT_FAILED); 1011*7c478bd9Sstevel@tonic-gate exit(1); 1012*7c478bd9Sstevel@tonic-gate } 1013*7c478bd9Sstevel@tonic-gate 1014*7c478bd9Sstevel@tonic-gate if (setup_door()) { 1015*7c478bd9Sstevel@tonic-gate syslog(LOG_CRIT, DOOR_FAILED); 1016*7c478bd9Sstevel@tonic-gate exit(1); 1017*7c478bd9Sstevel@tonic-gate } 1018*7c478bd9Sstevel@tonic-gate 1019*7c478bd9Sstevel@tonic-gate /* 1020*7c478bd9Sstevel@tonic-gate * setup signal handlers for post-init 1021*7c478bd9Sstevel@tonic-gate */ 1022*7c478bd9Sstevel@tonic-gate act.sa_sigaction = hup_handler; 1023*7c478bd9Sstevel@tonic-gate (void) sigemptyset(&act.sa_mask); 1024*7c478bd9Sstevel@tonic-gate act.sa_flags = SA_SIGINFO; 1025*7c478bd9Sstevel@tonic-gate if (sigaction(SIGHUP, &act, NULL) == -1) 1026*7c478bd9Sstevel@tonic-gate syslog(LOG_ERR, SIGACT_FAILED, strsignal(SIGHUP), 1027*7c478bd9Sstevel@tonic-gate strerror(errno)); 1028*7c478bd9Sstevel@tonic-gate 1029*7c478bd9Sstevel@tonic-gate /* 1030*7c478bd9Sstevel@tonic-gate * wait for requests 1031*7c478bd9Sstevel@tonic-gate */ 1032*7c478bd9Sstevel@tonic-gate for (;;) { 1033*7c478bd9Sstevel@tonic-gate (void) pause(); 1034*7c478bd9Sstevel@tonic-gate if (doreinit) { 1035*7c478bd9Sstevel@tonic-gate /* 1036*7c478bd9Sstevel@tonic-gate * Block SIGHUP during reinitialization. 1037*7c478bd9Sstevel@tonic-gate * Also mask off/block SIGALRM signal so that the 1038*7c478bd9Sstevel@tonic-gate * environmental plug-in (piclenvd) can use it to 1039*7c478bd9Sstevel@tonic-gate * simulate sleep() without being affected by time 1040*7c478bd9Sstevel@tonic-gate * being set back. No ohter PICL plug-in should use 1041*7c478bd9Sstevel@tonic-gate * SIGALRM or alarm() for now. 1042*7c478bd9Sstevel@tonic-gate */ 1043*7c478bd9Sstevel@tonic-gate (void) sigemptyset(&ublk); 1044*7c478bd9Sstevel@tonic-gate (void) sigaddset(&ublk, SIGHUP); 1045*7c478bd9Sstevel@tonic-gate (void) sigaddset(&ublk, SIGALRM); 1046*7c478bd9Sstevel@tonic-gate (void) sigprocmask(SIG_BLOCK, &ublk, NULL); 1047*7c478bd9Sstevel@tonic-gate (void) sigdelset(&ublk, SIGALRM); 1048*7c478bd9Sstevel@tonic-gate doreinit = 0; 1049*7c478bd9Sstevel@tonic-gate (void) rw_wrlock(&init_lk); 1050*7c478bd9Sstevel@tonic-gate xptree_destroy(); 1051*7c478bd9Sstevel@tonic-gate (void) xptree_reinitialize(); 1052*7c478bd9Sstevel@tonic-gate (void) rw_unlock(&init_lk); 1053*7c478bd9Sstevel@tonic-gate (void) sigprocmask(SIG_UNBLOCK, &ublk, NULL); 1054*7c478bd9Sstevel@tonic-gate } 1055*7c478bd9Sstevel@tonic-gate } 1056*7c478bd9Sstevel@tonic-gate } 1057