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
5*23a1cceaSRoger A. Faulkner * Common Development and Distribution License (the "License").
6*23a1cceaSRoger A. Faulkner * You may not use this file except in compliance with the License.
77c478bd9Sstevel@tonic-gate *
87c478bd9Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
97c478bd9Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing.
107c478bd9Sstevel@tonic-gate * See the License for the specific language governing permissions
117c478bd9Sstevel@tonic-gate * and limitations under the License.
127c478bd9Sstevel@tonic-gate *
137c478bd9Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each
147c478bd9Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
157c478bd9Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the
167c478bd9Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying
177c478bd9Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner]
187c478bd9Sstevel@tonic-gate *
197c478bd9Sstevel@tonic-gate * CDDL HEADER END
207c478bd9Sstevel@tonic-gate */
217c478bd9Sstevel@tonic-gate
22*23a1cceaSRoger A. Faulkner /*
23*23a1cceaSRoger A. Faulkner * Copyright (c) 2000, 2010, Oracle and/or its affiliates. All rights reserved.
24*23a1cceaSRoger A. Faulkner */
257c478bd9Sstevel@tonic-gate
267c478bd9Sstevel@tonic-gate /*
277c478bd9Sstevel@tonic-gate * This module implements the PTree interface and the PICL to PTree calls
287c478bd9Sstevel@tonic-gate */
297c478bd9Sstevel@tonic-gate
307c478bd9Sstevel@tonic-gate /*
317c478bd9Sstevel@tonic-gate * Note:
327c478bd9Sstevel@tonic-gate * PICL Node and Property Handles Table:
337c478bd9Sstevel@tonic-gate * A node or property in PICL tree has two handles: a ptree handle, which is
347c478bd9Sstevel@tonic-gate * used by plug-ins and the libpicltree interface, and a picl handle
357c478bd9Sstevel@tonic-gate * which is used by clients and the libpicl interface.
367c478bd9Sstevel@tonic-gate * The mapping of ptree handles to the internal PICL object (picl_obj_t) is
377c478bd9Sstevel@tonic-gate * kept in a ptree hash table (ptreetbl), and the mapping of a picl handle
387c478bd9Sstevel@tonic-gate * to its ptree handle is kept in the picl hash table (picltbl).
397c478bd9Sstevel@tonic-gate * The reader/writer lock, ptree_rwlock, is held when reading or modifying ptree
407c478bd9Sstevel@tonic-gate * hash table (ptreetbl) and/or the PICL tree structure (nodes and linkages
417c478bd9Sstevel@tonic-gate * between them). The reader/writer lock, picltbl_rwlock, is held when reading
427c478bd9Sstevel@tonic-gate * or modifying picl hash table (picltbl).
437c478bd9Sstevel@tonic-gate *
447c478bd9Sstevel@tonic-gate * The mutex, ptreehdl_lock, is used to control allocation of ptree handles.
457c478bd9Sstevel@tonic-gate * The mutex, piclhdl_lock, is used to control allocation of picl handles.
467c478bd9Sstevel@tonic-gate *
477c478bd9Sstevel@tonic-gate * The mutex, ptree_refresh_mutex, and the condition, ptree_refresh_cond,
487c478bd9Sstevel@tonic-gate * are used to synchronize PICL refreshes (ptree_refresh) and to wait/signal
497c478bd9Sstevel@tonic-gate * change in PICL tree structure.
507c478bd9Sstevel@tonic-gate *
517c478bd9Sstevel@tonic-gate * The counter, picl_hdl_hi, is the hi water mark for allocated picl handles.
527c478bd9Sstevel@tonic-gate * The counter, ptree_hdl_hi, is the hi water mark for allocated ptree handles.
537c478bd9Sstevel@tonic-gate * A stale handle error is returned for handle values below the hi water
547c478bd9Sstevel@tonic-gate * mark, and invalid handles are returned for handle values above the hi water
557c478bd9Sstevel@tonic-gate * mark or when the process id field of the handle does not match.
567c478bd9Sstevel@tonic-gate *
577c478bd9Sstevel@tonic-gate * Locking Scheme:
587c478bd9Sstevel@tonic-gate * The structure of the PICL tree is controlled by the ptree_rwlock. The
597c478bd9Sstevel@tonic-gate * properties of a node are controlled by individual node locks. The
607c478bd9Sstevel@tonic-gate * piclize-ing or unpiclize-ing of a node is controlled by picltbl_rwlock.
617c478bd9Sstevel@tonic-gate *
627c478bd9Sstevel@tonic-gate * Two-Phase Locking scheme: lock acquire phase and lock release phase.
637c478bd9Sstevel@tonic-gate *
647c478bd9Sstevel@tonic-gate * Lock Ordering:
657c478bd9Sstevel@tonic-gate * The ptree_rwlock and node locks are always acquired in the following order:
667c478bd9Sstevel@tonic-gate * lock ptree_rwlock
677c478bd9Sstevel@tonic-gate * lock node
687c478bd9Sstevel@tonic-gate *
697c478bd9Sstevel@tonic-gate * Lock Strategy:
707c478bd9Sstevel@tonic-gate * There are three locks:
717c478bd9Sstevel@tonic-gate * ptree_rwlock: a reader lock is obtained to do ptree hash table
727c478bd9Sstevel@tonic-gate * lookups and traverse tree. A writer lock is obtained
737c478bd9Sstevel@tonic-gate * when creating or destroying nodes from the ptree,
747c478bd9Sstevel@tonic-gate * or when modifying node linkages: parent, peer, child.
757c478bd9Sstevel@tonic-gate * picltbl_rwlock: a reader lock is obtained for picl hash table lookups.
767c478bd9Sstevel@tonic-gate * A writer lock is obtained when piclize-ing or
777c478bd9Sstevel@tonic-gate * unpiclize-ing nodes or properties.
787c478bd9Sstevel@tonic-gate * node_lock: This is a reader/writer lock for properties of a node.
797c478bd9Sstevel@tonic-gate * A reader lock is obtained before reading property
807c478bd9Sstevel@tonic-gate * values. A writer lock is obtained when adding or
817c478bd9Sstevel@tonic-gate * removing properties and when modifying a property value.
827c478bd9Sstevel@tonic-gate *
837c478bd9Sstevel@tonic-gate * Never hold more than one node lock at a time.
847c478bd9Sstevel@tonic-gate *
857c478bd9Sstevel@tonic-gate * Event Locking:
867c478bd9Sstevel@tonic-gate * There are two locks:
877c478bd9Sstevel@tonic-gate * evtq_lock: this lock protects the event queue. It is obtained
887c478bd9Sstevel@tonic-gate * to queue events that are posted and to unqueue
897c478bd9Sstevel@tonic-gate * events to be dispatched.
907c478bd9Sstevel@tonic-gate * evtq_cv: condition variable is protected by evtq_lock. It is
917c478bd9Sstevel@tonic-gate * used by the ptree event thread to wait for events
927c478bd9Sstevel@tonic-gate * until eventqp is not NULL.
937c478bd9Sstevel@tonic-gate * evtq_empty: condition variable protected by evtq_lock. It is
947c478bd9Sstevel@tonic-gate * used to signal when the eventq becomes empty. The
957c478bd9Sstevel@tonic-gate * reinitialization process waits on this condition.
967c478bd9Sstevel@tonic-gate * evthandler_lock: this protects the event handler list. It is obtained
977c478bd9Sstevel@tonic-gate * to add event handlers on registration and to remove
987c478bd9Sstevel@tonic-gate * event handlers on unregistration.
997c478bd9Sstevel@tonic-gate * (handler)->cv: condition variable per handler protected by
1007c478bd9Sstevel@tonic-gate * evthandler_lock. It is used to wait until the
1017c478bd9Sstevel@tonic-gate * event handler completes execution (execflg == 0)
1027c478bd9Sstevel@tonic-gate * before unregistering the handler.
1037c478bd9Sstevel@tonic-gate */
1047c478bd9Sstevel@tonic-gate
1057c478bd9Sstevel@tonic-gate #include <stdio.h>
1067c478bd9Sstevel@tonic-gate #include <string.h>
1077c478bd9Sstevel@tonic-gate #include <strings.h>
1087c478bd9Sstevel@tonic-gate #include <stdlib.h>
1097c478bd9Sstevel@tonic-gate #include <stdarg.h>
1107c478bd9Sstevel@tonic-gate #include <alloca.h>
1117c478bd9Sstevel@tonic-gate #include <assert.h>
1127c478bd9Sstevel@tonic-gate #include <errno.h>
1137c478bd9Sstevel@tonic-gate #include <unistd.h>
1147c478bd9Sstevel@tonic-gate #include <limits.h>
1157c478bd9Sstevel@tonic-gate #include <libintl.h>
1167c478bd9Sstevel@tonic-gate #include <syslog.h>
1177c478bd9Sstevel@tonic-gate #include <pthread.h>
1187c478bd9Sstevel@tonic-gate #include <synch.h>
1197c478bd9Sstevel@tonic-gate #include <setjmp.h>
1207c478bd9Sstevel@tonic-gate #include <signal.h>
1217c478bd9Sstevel@tonic-gate #include <dlfcn.h>
1227c478bd9Sstevel@tonic-gate #include <dirent.h>
1237c478bd9Sstevel@tonic-gate #include <door.h>
1247c478bd9Sstevel@tonic-gate #include <time.h>
1257c478bd9Sstevel@tonic-gate #include <inttypes.h>
1267c478bd9Sstevel@tonic-gate #include <sys/systeminfo.h>
1277c478bd9Sstevel@tonic-gate #include <sys/utsname.h>
1287c478bd9Sstevel@tonic-gate #include <picl.h>
1297c478bd9Sstevel@tonic-gate #include <picltree.h>
1307c478bd9Sstevel@tonic-gate #include "picldefs.h"
1317c478bd9Sstevel@tonic-gate #include "ptree_impl.h"
1327c478bd9Sstevel@tonic-gate
1337c478bd9Sstevel@tonic-gate #define SO_VERS ".so.1"
1347c478bd9Sstevel@tonic-gate
1357c478bd9Sstevel@tonic-gate static hash_t picltbl; /* client handles to picl obj */
1367c478bd9Sstevel@tonic-gate static hash_t ptreetbl; /* ptree handles to picl obj */
1377c478bd9Sstevel@tonic-gate static pthread_mutex_t ptreehdl_lock;
1387c478bd9Sstevel@tonic-gate static pthread_mutex_t piclhdl_lock;
1397c478bd9Sstevel@tonic-gate static pthread_mutex_t ptree_refresh_mutex;
1407c478bd9Sstevel@tonic-gate static rwlock_t picltbl_rwlock; /* PICL handle table lock */
1417c478bd9Sstevel@tonic-gate static rwlock_t ptree_rwlock; /* PICL tree lock */
1427c478bd9Sstevel@tonic-gate static pthread_cond_t ptree_refresh_cond = PTHREAD_COND_INITIALIZER;
1437c478bd9Sstevel@tonic-gate static uint32_t ptree_hdl_hi = 1;
1447c478bd9Sstevel@tonic-gate static uint32_t picl_hdl_hi = 1;
1457c478bd9Sstevel@tonic-gate static picl_obj_t *picl_root_obj = NULL;
1467c478bd9Sstevel@tonic-gate static picl_nodehdl_t ptree_root_hdl = PICL_INVALID_PICLHDL;
1477c478bd9Sstevel@tonic-gate static int ptree_generation = 0;
1487c478bd9Sstevel@tonic-gate static pid_t picld_pid;
1497c478bd9Sstevel@tonic-gate static door_cred_t picld_cred;
1507c478bd9Sstevel@tonic-gate static int qempty_wait; /* evtq_empty condition waiter flag */
1517c478bd9Sstevel@tonic-gate
1527c478bd9Sstevel@tonic-gate static picld_plugin_reg_list_t *plugin_reg_list = NULL;
1537c478bd9Sstevel@tonic-gate static picld_plugin_desc_t *plugin_desc;
1547c478bd9Sstevel@tonic-gate
1557c478bd9Sstevel@tonic-gate static eventq_t *eventqp; /* PICL events queue */
1567c478bd9Sstevel@tonic-gate static pthread_mutex_t evtq_lock = PTHREAD_MUTEX_INITIALIZER;
1577c478bd9Sstevel@tonic-gate static pthread_cond_t evtq_cv = PTHREAD_COND_INITIALIZER;
1587c478bd9Sstevel@tonic-gate static pthread_cond_t evtq_empty = PTHREAD_COND_INITIALIZER;
1597c478bd9Sstevel@tonic-gate static evt_handler_t *evt_handlers; /* Event handler list */
1607c478bd9Sstevel@tonic-gate static pthread_mutex_t evthandler_lock = PTHREAD_MUTEX_INITIALIZER;
1617c478bd9Sstevel@tonic-gate
1627c478bd9Sstevel@tonic-gate /*
1637c478bd9Sstevel@tonic-gate * PICL daemon verbose level
1647c478bd9Sstevel@tonic-gate */
1657c478bd9Sstevel@tonic-gate int verbose_level;
1667c478bd9Sstevel@tonic-gate
1677c478bd9Sstevel@tonic-gate
1687c478bd9Sstevel@tonic-gate /*
1697c478bd9Sstevel@tonic-gate * Event handler free functions
1707c478bd9Sstevel@tonic-gate */
1717c478bd9Sstevel@tonic-gate static void
free_handler(evt_handler_t * evhp)1727c478bd9Sstevel@tonic-gate free_handler(evt_handler_t *evhp)
1737c478bd9Sstevel@tonic-gate {
1747c478bd9Sstevel@tonic-gate if (evhp->ename)
1757c478bd9Sstevel@tonic-gate free(evhp->ename);
1767c478bd9Sstevel@tonic-gate (void) pthread_cond_broadcast(&evhp->cv);
1777c478bd9Sstevel@tonic-gate (void) pthread_cond_destroy(&evhp->cv);
1787c478bd9Sstevel@tonic-gate free(evhp);
1797c478bd9Sstevel@tonic-gate }
1807c478bd9Sstevel@tonic-gate
1817c478bd9Sstevel@tonic-gate
1827c478bd9Sstevel@tonic-gate /*
1837c478bd9Sstevel@tonic-gate * queue_event to events queue
1847c478bd9Sstevel@tonic-gate */
1857c478bd9Sstevel@tonic-gate static void
queue_event(eventq_t * evt)1867c478bd9Sstevel@tonic-gate queue_event(eventq_t *evt)
1877c478bd9Sstevel@tonic-gate {
1887c478bd9Sstevel@tonic-gate eventq_t *tmpp;
1897c478bd9Sstevel@tonic-gate
1907c478bd9Sstevel@tonic-gate evt->next = NULL;
1917c478bd9Sstevel@tonic-gate if (eventqp == NULL)
1927c478bd9Sstevel@tonic-gate eventqp = evt;
1937c478bd9Sstevel@tonic-gate else {
1947c478bd9Sstevel@tonic-gate tmpp = eventqp;
1957c478bd9Sstevel@tonic-gate while (tmpp->next != NULL)
1967c478bd9Sstevel@tonic-gate tmpp = tmpp->next;
1977c478bd9Sstevel@tonic-gate tmpp->next = evt;
1987c478bd9Sstevel@tonic-gate }
1997c478bd9Sstevel@tonic-gate }
2007c478bd9Sstevel@tonic-gate
2017c478bd9Sstevel@tonic-gate /*
2027c478bd9Sstevel@tonic-gate * unqueue_event from the specified eventq
2037c478bd9Sstevel@tonic-gate */
2047c478bd9Sstevel@tonic-gate static eventq_t *
unqueue_event(eventq_t ** qp)2057c478bd9Sstevel@tonic-gate unqueue_event(eventq_t **qp)
2067c478bd9Sstevel@tonic-gate {
2077c478bd9Sstevel@tonic-gate eventq_t *evtp;
2087c478bd9Sstevel@tonic-gate
2097c478bd9Sstevel@tonic-gate evtp = *qp;
2107c478bd9Sstevel@tonic-gate if (evtp != NULL)
2117c478bd9Sstevel@tonic-gate *qp = evtp->next;
2127c478bd9Sstevel@tonic-gate return (evtp);
2137c478bd9Sstevel@tonic-gate }
2147c478bd9Sstevel@tonic-gate
2157c478bd9Sstevel@tonic-gate /*
2167c478bd9Sstevel@tonic-gate * register an event handler by adding it to the list
2177c478bd9Sstevel@tonic-gate */
2187c478bd9Sstevel@tonic-gate int
ptree_register_handler(const char * ename,void (* evt_handler)(const char * ename,const void * earg,size_t size,void * cookie),void * cookie)2197c478bd9Sstevel@tonic-gate ptree_register_handler(const char *ename,
2207c478bd9Sstevel@tonic-gate void (*evt_handler)(const char *ename, const void *earg, size_t size,
2217c478bd9Sstevel@tonic-gate void *cookie), void *cookie)
2227c478bd9Sstevel@tonic-gate {
2237c478bd9Sstevel@tonic-gate evt_handler_t *ent;
2247c478bd9Sstevel@tonic-gate evt_handler_t *iter;
2257c478bd9Sstevel@tonic-gate
2267c478bd9Sstevel@tonic-gate if (ename == NULL)
2277c478bd9Sstevel@tonic-gate return (PICL_INVALIDARG);
2287c478bd9Sstevel@tonic-gate
2297c478bd9Sstevel@tonic-gate /*
2307c478bd9Sstevel@tonic-gate * Initialize event handler entry
2317c478bd9Sstevel@tonic-gate */
2327c478bd9Sstevel@tonic-gate ent = malloc(sizeof (*ent));
2337c478bd9Sstevel@tonic-gate if (ent == NULL)
2347c478bd9Sstevel@tonic-gate return (PICL_FAILURE);
2357c478bd9Sstevel@tonic-gate ent->ename = strdup(ename);
2367c478bd9Sstevel@tonic-gate if (ent->ename == NULL) {
2377c478bd9Sstevel@tonic-gate free(ent);
2387c478bd9Sstevel@tonic-gate return (PICL_FAILURE);
2397c478bd9Sstevel@tonic-gate }
2407c478bd9Sstevel@tonic-gate ent->cookie = cookie;
2417c478bd9Sstevel@tonic-gate ent->evt_handler = evt_handler;
2427c478bd9Sstevel@tonic-gate ent->execflg = 0;
2437c478bd9Sstevel@tonic-gate ent->wakeupflg = 0;
2447c478bd9Sstevel@tonic-gate (void) pthread_cond_init(&ent->cv, NULL);
2457c478bd9Sstevel@tonic-gate ent->next = NULL;
2467c478bd9Sstevel@tonic-gate
2477c478bd9Sstevel@tonic-gate /*
2487c478bd9Sstevel@tonic-gate * add handler to the handler list
2497c478bd9Sstevel@tonic-gate */
2507c478bd9Sstevel@tonic-gate (void) pthread_mutex_lock(&evthandler_lock);
2517c478bd9Sstevel@tonic-gate if (evt_handlers == NULL) {
2527c478bd9Sstevel@tonic-gate evt_handlers = ent;
2537c478bd9Sstevel@tonic-gate (void) pthread_mutex_unlock(&evthandler_lock);
2547c478bd9Sstevel@tonic-gate return (PICL_SUCCESS);
2557c478bd9Sstevel@tonic-gate }
2567c478bd9Sstevel@tonic-gate iter = evt_handlers;
2577c478bd9Sstevel@tonic-gate while (iter->next != NULL)
2587c478bd9Sstevel@tonic-gate iter = iter->next;
2597c478bd9Sstevel@tonic-gate iter->next = ent;
2607c478bd9Sstevel@tonic-gate (void) pthread_mutex_unlock(&evthandler_lock);
2617c478bd9Sstevel@tonic-gate
2627c478bd9Sstevel@tonic-gate return (PICL_SUCCESS);
2637c478bd9Sstevel@tonic-gate }
2647c478bd9Sstevel@tonic-gate
2657c478bd9Sstevel@tonic-gate /*
2667c478bd9Sstevel@tonic-gate * unregister handler
2677c478bd9Sstevel@tonic-gate */
2687c478bd9Sstevel@tonic-gate void
ptree_unregister_handler(const char * ename,void (* evt_handler)(const char * ename,const void * earg,size_t size,void * cookie),void * cookie)2697c478bd9Sstevel@tonic-gate ptree_unregister_handler(const char *ename,
2707c478bd9Sstevel@tonic-gate void (*evt_handler)(const char *ename, const void *earg, size_t size,
2717c478bd9Sstevel@tonic-gate void *cookie), void *cookie)
2727c478bd9Sstevel@tonic-gate {
2737c478bd9Sstevel@tonic-gate evt_handler_t *evhdlrp, **evhdlrpp;
2747c478bd9Sstevel@tonic-gate
2757c478bd9Sstevel@tonic-gate if (ename == NULL)
2767c478bd9Sstevel@tonic-gate return;
2777c478bd9Sstevel@tonic-gate
2787c478bd9Sstevel@tonic-gate /*
2797c478bd9Sstevel@tonic-gate * unlink handler from handler list
2807c478bd9Sstevel@tonic-gate */
2817c478bd9Sstevel@tonic-gate (void) pthread_mutex_lock(&evthandler_lock);
2827c478bd9Sstevel@tonic-gate
2837c478bd9Sstevel@tonic-gate retry:
2847c478bd9Sstevel@tonic-gate for (evhdlrpp = &evt_handlers; (evhdlrp = *evhdlrpp) != NULL;
2857c478bd9Sstevel@tonic-gate evhdlrpp = &evhdlrp->next) {
2867c478bd9Sstevel@tonic-gate if ((evhdlrp->cookie != cookie) ||
2877c478bd9Sstevel@tonic-gate (strcmp(evhdlrp->ename, ename) != 0) ||
2887c478bd9Sstevel@tonic-gate (evhdlrp->evt_handler != evt_handler))
2897c478bd9Sstevel@tonic-gate continue;
2907c478bd9Sstevel@tonic-gate
2917c478bd9Sstevel@tonic-gate /*
2927c478bd9Sstevel@tonic-gate * If the handler is in execution, release the lock
2937c478bd9Sstevel@tonic-gate * and wait for it to complete and retry.
2947c478bd9Sstevel@tonic-gate */
2957c478bd9Sstevel@tonic-gate if (evhdlrp->execflg) {
2967c478bd9Sstevel@tonic-gate evhdlrp->wakeupflg = 1;
2977c478bd9Sstevel@tonic-gate (void) pthread_cond_wait(&evhdlrp->cv,
2987c478bd9Sstevel@tonic-gate &evthandler_lock);
2997c478bd9Sstevel@tonic-gate goto retry;
3007c478bd9Sstevel@tonic-gate }
3017c478bd9Sstevel@tonic-gate
3027c478bd9Sstevel@tonic-gate /*
3037c478bd9Sstevel@tonic-gate * Unlink this handler from the linked list
3047c478bd9Sstevel@tonic-gate */
3057c478bd9Sstevel@tonic-gate *evhdlrpp = evhdlrp->next;
3067c478bd9Sstevel@tonic-gate free_handler(evhdlrp);
3077c478bd9Sstevel@tonic-gate break;
3087c478bd9Sstevel@tonic-gate }
3097c478bd9Sstevel@tonic-gate
3107c478bd9Sstevel@tonic-gate (void) pthread_mutex_unlock(&evthandler_lock);
3117c478bd9Sstevel@tonic-gate }
3127c478bd9Sstevel@tonic-gate
3137c478bd9Sstevel@tonic-gate /*
3147c478bd9Sstevel@tonic-gate * Call all registered handlers for the event
3157c478bd9Sstevel@tonic-gate */
3167c478bd9Sstevel@tonic-gate static void
call_event_handlers(eventq_t * ev)3177c478bd9Sstevel@tonic-gate call_event_handlers(eventq_t *ev)
3187c478bd9Sstevel@tonic-gate {
3197c478bd9Sstevel@tonic-gate evt_handler_t *iter;
3207c478bd9Sstevel@tonic-gate void (*evhandler)(const char *, const void *, size_t, void *);
3217c478bd9Sstevel@tonic-gate void (*completion_handler)(char *ename, void *earg, size_t size);
3227c478bd9Sstevel@tonic-gate
3237c478bd9Sstevel@tonic-gate (void) pthread_mutex_lock(&evthandler_lock);
3247c478bd9Sstevel@tonic-gate iter = evt_handlers;
3257c478bd9Sstevel@tonic-gate while (iter != NULL) {
3267c478bd9Sstevel@tonic-gate if (strcmp(iter->ename, ev->ename) == 0) {
3277c478bd9Sstevel@tonic-gate evhandler = iter->evt_handler;
3287c478bd9Sstevel@tonic-gate iter->execflg = 1;
3297c478bd9Sstevel@tonic-gate (void) pthread_mutex_unlock(&evthandler_lock);
3307c478bd9Sstevel@tonic-gate if (evhandler) {
3317c478bd9Sstevel@tonic-gate dbg_print(2, "ptree_evthr: Invoking evthdlr:%p"
3327c478bd9Sstevel@tonic-gate " ename:%s\n", evhandler, ev->ename);
3337c478bd9Sstevel@tonic-gate (*evhandler)(ev->ename, ev->earg, ev->size,
3347c478bd9Sstevel@tonic-gate iter->cookie);
3357c478bd9Sstevel@tonic-gate dbg_print(2, "ptree_evthr: done evthdlr:%p "
3367c478bd9Sstevel@tonic-gate "ename:%s\n", evhandler, ev->ename);
3377c478bd9Sstevel@tonic-gate }
3387c478bd9Sstevel@tonic-gate (void) pthread_mutex_lock(&evthandler_lock);
3397c478bd9Sstevel@tonic-gate iter->execflg = 0;
3407c478bd9Sstevel@tonic-gate if (iter->wakeupflg) {
3417c478bd9Sstevel@tonic-gate iter->wakeupflg = 0;
3427c478bd9Sstevel@tonic-gate (void) pthread_cond_broadcast(&iter->cv);
3437c478bd9Sstevel@tonic-gate }
3447c478bd9Sstevel@tonic-gate }
3457c478bd9Sstevel@tonic-gate iter = iter->next;
3467c478bd9Sstevel@tonic-gate }
3477c478bd9Sstevel@tonic-gate (void) pthread_mutex_unlock(&evthandler_lock);
3487c478bd9Sstevel@tonic-gate if ((completion_handler = ev->completion_handler) != NULL) {
3497c478bd9Sstevel@tonic-gate dbg_print(2,
3507c478bd9Sstevel@tonic-gate "ptree_evthr: Invoking completion hdlr:%p ename:%s\n",
3517c478bd9Sstevel@tonic-gate completion_handler, ev->ename);
3527c478bd9Sstevel@tonic-gate (*completion_handler)((char *)ev->ename, (void *)ev->earg,
3537c478bd9Sstevel@tonic-gate ev->size);
3547c478bd9Sstevel@tonic-gate dbg_print(2, "ptree_evthr: done completion hdlr:%p ename:%s\n",
3557c478bd9Sstevel@tonic-gate completion_handler, ev->ename);
3567c478bd9Sstevel@tonic-gate }
3577c478bd9Sstevel@tonic-gate (void) pthread_mutex_lock(&ptree_refresh_mutex);
3587c478bd9Sstevel@tonic-gate ++ptree_generation;
3597c478bd9Sstevel@tonic-gate (void) pthread_cond_broadcast(&ptree_refresh_cond);
3607c478bd9Sstevel@tonic-gate (void) pthread_mutex_unlock(&ptree_refresh_mutex);
3617c478bd9Sstevel@tonic-gate }
3627c478bd9Sstevel@tonic-gate
3637c478bd9Sstevel@tonic-gate /*
3647c478bd9Sstevel@tonic-gate * This function is called by a plug-in to post an event
3657c478bd9Sstevel@tonic-gate */
3667c478bd9Sstevel@tonic-gate int
ptree_post_event(const char * ename,const void * earg,size_t size,void (* completion_handler)(char * ename,void * earg,size_t size))3677c478bd9Sstevel@tonic-gate ptree_post_event(const char *ename, const void *earg, size_t size,
3687c478bd9Sstevel@tonic-gate void (*completion_handler)(char *ename, void *earg, size_t size))
3697c478bd9Sstevel@tonic-gate {
3707c478bd9Sstevel@tonic-gate eventq_t *evt;
3717c478bd9Sstevel@tonic-gate
3727c478bd9Sstevel@tonic-gate if (ename == NULL)
3737c478bd9Sstevel@tonic-gate return (PICL_INVALIDARG);
3747c478bd9Sstevel@tonic-gate
3757c478bd9Sstevel@tonic-gate evt = malloc(sizeof (*evt));
3767c478bd9Sstevel@tonic-gate if (evt == NULL)
3777c478bd9Sstevel@tonic-gate return (PICL_FAILURE);
3787c478bd9Sstevel@tonic-gate evt->ename = ename;
3797c478bd9Sstevel@tonic-gate evt->earg = earg;
3807c478bd9Sstevel@tonic-gate evt->size = size;
3817c478bd9Sstevel@tonic-gate evt->completion_handler = completion_handler;
3827c478bd9Sstevel@tonic-gate
3837c478bd9Sstevel@tonic-gate (void) pthread_mutex_lock(&evtq_lock);
3847c478bd9Sstevel@tonic-gate queue_event(evt);
3857c478bd9Sstevel@tonic-gate (void) pthread_cond_broadcast(&evtq_cv);
3867c478bd9Sstevel@tonic-gate (void) pthread_mutex_unlock(&evtq_lock);
3877c478bd9Sstevel@tonic-gate return (PICL_SUCCESS);
3887c478bd9Sstevel@tonic-gate }
3897c478bd9Sstevel@tonic-gate
3907c478bd9Sstevel@tonic-gate /*
3917c478bd9Sstevel@tonic-gate * PICLTREE event thread
3927c478bd9Sstevel@tonic-gate */
3937c478bd9Sstevel@tonic-gate /*ARGSUSED*/
3947c478bd9Sstevel@tonic-gate static void *
ptree_event_thread(void * argp)3957c478bd9Sstevel@tonic-gate ptree_event_thread(void *argp)
3967c478bd9Sstevel@tonic-gate {
3977c478bd9Sstevel@tonic-gate eventq_t *evt;
3987c478bd9Sstevel@tonic-gate
3997c478bd9Sstevel@tonic-gate for (;;) {
4007c478bd9Sstevel@tonic-gate (void) pthread_mutex_lock(&evtq_lock);
4017c478bd9Sstevel@tonic-gate while (eventqp == NULL) {
4027c478bd9Sstevel@tonic-gate /*
4037c478bd9Sstevel@tonic-gate * Signal empty queue
4047c478bd9Sstevel@tonic-gate */
4057c478bd9Sstevel@tonic-gate if (qempty_wait)
4067c478bd9Sstevel@tonic-gate (void) pthread_cond_broadcast(&evtq_empty);
4077c478bd9Sstevel@tonic-gate (void) pthread_cond_wait(&evtq_cv, &evtq_lock);
4087c478bd9Sstevel@tonic-gate }
4097c478bd9Sstevel@tonic-gate if ((evt = unqueue_event(&eventqp)) != NULL) {
4107c478bd9Sstevel@tonic-gate (void) pthread_mutex_unlock(&evtq_lock);
4117c478bd9Sstevel@tonic-gate call_event_handlers(evt);
4127c478bd9Sstevel@tonic-gate free(evt);
4137c478bd9Sstevel@tonic-gate } else
4147c478bd9Sstevel@tonic-gate (void) pthread_mutex_unlock(&evtq_lock);
4157c478bd9Sstevel@tonic-gate }
4167c478bd9Sstevel@tonic-gate /*NOTREACHED*/
4177c478bd9Sstevel@tonic-gate return (NULL);
4187c478bd9Sstevel@tonic-gate }
4197c478bd9Sstevel@tonic-gate
4207c478bd9Sstevel@tonic-gate
4217c478bd9Sstevel@tonic-gate /*
4227c478bd9Sstevel@tonic-gate * Create a new element
4237c478bd9Sstevel@tonic-gate */
4247c478bd9Sstevel@tonic-gate static hash_elem_t *
hash_newobj(uint32_t hdl_val,void * obj_val)4257c478bd9Sstevel@tonic-gate hash_newobj(uint32_t hdl_val, void *obj_val)
4267c478bd9Sstevel@tonic-gate {
4277c478bd9Sstevel@tonic-gate hash_elem_t *n;
4287c478bd9Sstevel@tonic-gate
4297c478bd9Sstevel@tonic-gate n = malloc(sizeof (*n));
4307c478bd9Sstevel@tonic-gate if (n == NULL)
4317c478bd9Sstevel@tonic-gate return (NULL);
4327c478bd9Sstevel@tonic-gate n->hdl = hdl_val;
4337c478bd9Sstevel@tonic-gate n->hash_obj = obj_val;
4347c478bd9Sstevel@tonic-gate n->next = NULL;
4357c478bd9Sstevel@tonic-gate return (n);
4367c478bd9Sstevel@tonic-gate }
4377c478bd9Sstevel@tonic-gate
4387c478bd9Sstevel@tonic-gate static hash_elem_t *
hash_newhdl(uint32_t picl_hdl,uint32_t ptreeh)4397c478bd9Sstevel@tonic-gate hash_newhdl(uint32_t picl_hdl, uint32_t ptreeh)
4407c478bd9Sstevel@tonic-gate {
4417c478bd9Sstevel@tonic-gate hash_elem_t *n;
4427c478bd9Sstevel@tonic-gate
4437c478bd9Sstevel@tonic-gate n = malloc(sizeof (*n));
4447c478bd9Sstevel@tonic-gate if (n == NULL)
4457c478bd9Sstevel@tonic-gate return (NULL);
4467c478bd9Sstevel@tonic-gate n->hdl = picl_hdl;
4477c478bd9Sstevel@tonic-gate n->hash_hdl = ptreeh;
4487c478bd9Sstevel@tonic-gate n->next = NULL;
4497c478bd9Sstevel@tonic-gate return (n);
4507c478bd9Sstevel@tonic-gate }
4517c478bd9Sstevel@tonic-gate
4527c478bd9Sstevel@tonic-gate /*
4537c478bd9Sstevel@tonic-gate * Initialize a hash table by setting all entries to NULL
4547c478bd9Sstevel@tonic-gate */
4557c478bd9Sstevel@tonic-gate static int
hash_init(hash_t * htbl)4567c478bd9Sstevel@tonic-gate hash_init(hash_t *htbl)
4577c478bd9Sstevel@tonic-gate {
4587c478bd9Sstevel@tonic-gate int i;
4597c478bd9Sstevel@tonic-gate
4607c478bd9Sstevel@tonic-gate htbl->hash_size = HASH_TBL_SIZE;
4617c478bd9Sstevel@tonic-gate htbl->tbl = malloc(sizeof (hash_elem_t *) * HASH_TBL_SIZE);
4627c478bd9Sstevel@tonic-gate if (htbl->tbl == NULL)
4637c478bd9Sstevel@tonic-gate return (-1);
4647c478bd9Sstevel@tonic-gate for (i = 0; i < htbl->hash_size; ++i)
4657c478bd9Sstevel@tonic-gate htbl->tbl[i] = NULL;
4667c478bd9Sstevel@tonic-gate return (0);
4677c478bd9Sstevel@tonic-gate }
4687c478bd9Sstevel@tonic-gate
4697c478bd9Sstevel@tonic-gate /*
4707c478bd9Sstevel@tonic-gate * Lock free function to add an entry in the hash table
4717c478bd9Sstevel@tonic-gate */
4727c478bd9Sstevel@tonic-gate static int
hash_add_newobj(hash_t * htbl,picl_hdl_t hdl,void * pobj)4737c478bd9Sstevel@tonic-gate hash_add_newobj(hash_t *htbl, picl_hdl_t hdl, void *pobj)
4747c478bd9Sstevel@tonic-gate {
4757c478bd9Sstevel@tonic-gate int indx;
4767c478bd9Sstevel@tonic-gate hash_elem_t *n;
4777c478bd9Sstevel@tonic-gate uint32_t hash_val = HASH_VAL(hdl);
4787c478bd9Sstevel@tonic-gate
4797c478bd9Sstevel@tonic-gate n = hash_newobj(hash_val, pobj);
4807c478bd9Sstevel@tonic-gate if (n == NULL)
4817c478bd9Sstevel@tonic-gate return (-1);
4827c478bd9Sstevel@tonic-gate indx = HASH_INDEX(htbl->hash_size, hash_val);
4837c478bd9Sstevel@tonic-gate n->next = htbl->tbl[indx];
4847c478bd9Sstevel@tonic-gate htbl->tbl[indx] = n;
4857c478bd9Sstevel@tonic-gate return (0);
4867c478bd9Sstevel@tonic-gate }
4877c478bd9Sstevel@tonic-gate
4887c478bd9Sstevel@tonic-gate static int
hash_add_newhdl(hash_t * htbl,picl_hdl_t piclh,picl_hdl_t ptreeh)4897c478bd9Sstevel@tonic-gate hash_add_newhdl(hash_t *htbl, picl_hdl_t piclh, picl_hdl_t ptreeh)
4907c478bd9Sstevel@tonic-gate {
4917c478bd9Sstevel@tonic-gate int indx;
4927c478bd9Sstevel@tonic-gate hash_elem_t *n;
4937c478bd9Sstevel@tonic-gate uint32_t picl_val = HASH_VAL(piclh);
4947c478bd9Sstevel@tonic-gate uint32_t ptree_val = HASH_VAL(ptreeh);
4957c478bd9Sstevel@tonic-gate
4967c478bd9Sstevel@tonic-gate n = hash_newhdl(picl_val, ptree_val);
4977c478bd9Sstevel@tonic-gate if (n == NULL)
4987c478bd9Sstevel@tonic-gate return (-1);
4997c478bd9Sstevel@tonic-gate
5007c478bd9Sstevel@tonic-gate indx = HASH_INDEX(htbl->hash_size, picl_val);
5017c478bd9Sstevel@tonic-gate n->next = htbl->tbl[indx];
5027c478bd9Sstevel@tonic-gate htbl->tbl[indx] = n;
5037c478bd9Sstevel@tonic-gate return (0);
5047c478bd9Sstevel@tonic-gate }
5057c478bd9Sstevel@tonic-gate
5067c478bd9Sstevel@tonic-gate /*
5077c478bd9Sstevel@tonic-gate * Lock free function to remove the handle from the hash table
5087c478bd9Sstevel@tonic-gate * Returns -1 if element not found, 0 if successful
5097c478bd9Sstevel@tonic-gate */
5107c478bd9Sstevel@tonic-gate static int
hash_remove(hash_t * htbl,picl_hdl_t hdl)5117c478bd9Sstevel@tonic-gate hash_remove(hash_t *htbl, picl_hdl_t hdl)
5127c478bd9Sstevel@tonic-gate {
5137c478bd9Sstevel@tonic-gate hash_elem_t *nxt;
5147c478bd9Sstevel@tonic-gate hash_elem_t *cur;
5157c478bd9Sstevel@tonic-gate int i;
5167c478bd9Sstevel@tonic-gate uint32_t hash_val = HASH_VAL(hdl);
5177c478bd9Sstevel@tonic-gate
5187c478bd9Sstevel@tonic-gate i = HASH_INDEX(htbl->hash_size, hash_val);
5197c478bd9Sstevel@tonic-gate if (htbl->tbl[i] == NULL)
5207c478bd9Sstevel@tonic-gate return (-1);
5217c478bd9Sstevel@tonic-gate
5227c478bd9Sstevel@tonic-gate cur = htbl->tbl[i];
5237c478bd9Sstevel@tonic-gate if (cur->hdl == hash_val) {
5247c478bd9Sstevel@tonic-gate htbl->tbl[i] = cur->next;
5257c478bd9Sstevel@tonic-gate free(cur);
5267c478bd9Sstevel@tonic-gate return (0);
5277c478bd9Sstevel@tonic-gate }
5287c478bd9Sstevel@tonic-gate nxt = cur->next;
5297c478bd9Sstevel@tonic-gate while (nxt != NULL) {
5307c478bd9Sstevel@tonic-gate if (nxt->hdl == hash_val) {
5317c478bd9Sstevel@tonic-gate cur->next = nxt->next;
5327c478bd9Sstevel@tonic-gate free(nxt);
5337c478bd9Sstevel@tonic-gate return (0);
5347c478bd9Sstevel@tonic-gate }
5357c478bd9Sstevel@tonic-gate cur = nxt;
5367c478bd9Sstevel@tonic-gate nxt = nxt->next;
5377c478bd9Sstevel@tonic-gate }
5387c478bd9Sstevel@tonic-gate return (-1);
5397c478bd9Sstevel@tonic-gate }
5407c478bd9Sstevel@tonic-gate
5417c478bd9Sstevel@tonic-gate /*
5427c478bd9Sstevel@tonic-gate * Lock free function to lookup the hash table for a given handle
5437c478bd9Sstevel@tonic-gate * Returns NULL if not found
5447c478bd9Sstevel@tonic-gate */
5457c478bd9Sstevel@tonic-gate static void *
hash_lookup_obj(hash_t * htbl,picl_hdl_t hdl)5467c478bd9Sstevel@tonic-gate hash_lookup_obj(hash_t *htbl, picl_hdl_t hdl)
5477c478bd9Sstevel@tonic-gate {
5487c478bd9Sstevel@tonic-gate hash_elem_t *tmp;
5497c478bd9Sstevel@tonic-gate int i;
5507c478bd9Sstevel@tonic-gate uint32_t hash_val;
5517c478bd9Sstevel@tonic-gate
5527c478bd9Sstevel@tonic-gate hash_val = HASH_VAL(hdl);
5537c478bd9Sstevel@tonic-gate i = HASH_INDEX(htbl->hash_size, hash_val);
5547c478bd9Sstevel@tonic-gate tmp = htbl->tbl[i];
5557c478bd9Sstevel@tonic-gate while (tmp != NULL) {
5567c478bd9Sstevel@tonic-gate if (tmp->hdl == hash_val)
5577c478bd9Sstevel@tonic-gate return (tmp->hash_obj);
5587c478bd9Sstevel@tonic-gate tmp = tmp->next;
5597c478bd9Sstevel@tonic-gate }
5607c478bd9Sstevel@tonic-gate return (NULL);
5617c478bd9Sstevel@tonic-gate }
5627c478bd9Sstevel@tonic-gate
5637c478bd9Sstevel@tonic-gate static picl_hdl_t
hash_lookup_hdl(hash_t * htbl,picl_hdl_t hdl)5647c478bd9Sstevel@tonic-gate hash_lookup_hdl(hash_t *htbl, picl_hdl_t hdl)
5657c478bd9Sstevel@tonic-gate {
5667c478bd9Sstevel@tonic-gate hash_elem_t *tmp;
5677c478bd9Sstevel@tonic-gate int i;
5687c478bd9Sstevel@tonic-gate uint32_t hash_val;
5697c478bd9Sstevel@tonic-gate
5707c478bd9Sstevel@tonic-gate hash_val = HASH_VAL(hdl);
5717c478bd9Sstevel@tonic-gate i = HASH_INDEX(htbl->hash_size, hash_val);
5727c478bd9Sstevel@tonic-gate tmp = htbl->tbl[i];
5737c478bd9Sstevel@tonic-gate while (tmp != NULL) {
5747c478bd9Sstevel@tonic-gate if (tmp->hdl == hash_val)
5757c478bd9Sstevel@tonic-gate return (MAKE_HANDLE(picld_pid, tmp->hash_hdl));
5767c478bd9Sstevel@tonic-gate tmp = tmp->next;
5777c478bd9Sstevel@tonic-gate }
5787c478bd9Sstevel@tonic-gate return (PICL_INVALID_PICLHDL);
5797c478bd9Sstevel@tonic-gate }
5807c478bd9Sstevel@tonic-gate
5817c478bd9Sstevel@tonic-gate /*
5827c478bd9Sstevel@tonic-gate * Is the PICL handle stale or invalid handle?
5837c478bd9Sstevel@tonic-gate */
5847c478bd9Sstevel@tonic-gate static int
picl_hdl_error(picl_hdl_t hdl)5857c478bd9Sstevel@tonic-gate picl_hdl_error(picl_hdl_t hdl)
5867c478bd9Sstevel@tonic-gate {
5877c478bd9Sstevel@tonic-gate uint32_t hash_val = HASH_VAL(hdl);
5887c478bd9Sstevel@tonic-gate pid_t pid = GET_PID(hdl);
5897c478bd9Sstevel@tonic-gate int err;
5907c478bd9Sstevel@tonic-gate
5917c478bd9Sstevel@tonic-gate (void) pthread_mutex_lock(&piclhdl_lock);
5927c478bd9Sstevel@tonic-gate err = PICL_STALEHANDLE;
5937c478bd9Sstevel@tonic-gate if ((pid != picld_pid) || (hash_val >= picl_hdl_hi) ||
5947c478bd9Sstevel@tonic-gate (hash_val == NULL))
5957c478bd9Sstevel@tonic-gate err = PICL_INVALIDHANDLE;
5967c478bd9Sstevel@tonic-gate (void) pthread_mutex_unlock(&piclhdl_lock);
5977c478bd9Sstevel@tonic-gate return (err);
5987c478bd9Sstevel@tonic-gate }
5997c478bd9Sstevel@tonic-gate
6007c478bd9Sstevel@tonic-gate /*
6017c478bd9Sstevel@tonic-gate * Is the Ptree handle stale or invalid handle?
6027c478bd9Sstevel@tonic-gate */
6037c478bd9Sstevel@tonic-gate static int
ptree_hdl_error(picl_hdl_t hdl)6047c478bd9Sstevel@tonic-gate ptree_hdl_error(picl_hdl_t hdl)
6057c478bd9Sstevel@tonic-gate {
6067c478bd9Sstevel@tonic-gate uint32_t hash_val = HASH_VAL(hdl);
6077c478bd9Sstevel@tonic-gate pid_t pid = GET_PID(hdl);
6087c478bd9Sstevel@tonic-gate int err;
6097c478bd9Sstevel@tonic-gate
6107c478bd9Sstevel@tonic-gate (void) pthread_mutex_lock(&ptreehdl_lock);
6117c478bd9Sstevel@tonic-gate err = PICL_STALEHANDLE;
6127c478bd9Sstevel@tonic-gate if ((pid != picld_pid) || (hash_val >= ptree_hdl_hi) ||
6137c478bd9Sstevel@tonic-gate (hash_val == NULL))
6147c478bd9Sstevel@tonic-gate err = PICL_INVALIDHANDLE;
6157c478bd9Sstevel@tonic-gate (void) pthread_mutex_unlock(&ptreehdl_lock);
6167c478bd9Sstevel@tonic-gate return (err);
6177c478bd9Sstevel@tonic-gate }
6187c478bd9Sstevel@tonic-gate
6197c478bd9Sstevel@tonic-gate /*
6207c478bd9Sstevel@tonic-gate * For a PICL handle, return the PTree handle and the PICL object
6217c478bd9Sstevel@tonic-gate * Locks and releases the PICL table.
6227c478bd9Sstevel@tonic-gate */
6237c478bd9Sstevel@tonic-gate int
cvt_picl2ptree(picl_hdl_t hdl,picl_hdl_t * ptree_hdl)6247c478bd9Sstevel@tonic-gate cvt_picl2ptree(picl_hdl_t hdl, picl_hdl_t *ptree_hdl)
6257c478bd9Sstevel@tonic-gate {
6267c478bd9Sstevel@tonic-gate picl_hdl_t tmph;
6277c478bd9Sstevel@tonic-gate int err;
6287c478bd9Sstevel@tonic-gate
6297c478bd9Sstevel@tonic-gate (void) rw_rdlock(&picltbl_rwlock); /* lock picl */
6307c478bd9Sstevel@tonic-gate tmph = hash_lookup_hdl(&picltbl, hdl);
6317c478bd9Sstevel@tonic-gate if (tmph == PICL_INVALID_PICLHDL) {
6327c478bd9Sstevel@tonic-gate err = picl_hdl_error(hdl);
6337c478bd9Sstevel@tonic-gate (void) rw_unlock(&picltbl_rwlock); /* unlock picl */
6347c478bd9Sstevel@tonic-gate return (err);
6357c478bd9Sstevel@tonic-gate }
6367c478bd9Sstevel@tonic-gate *ptree_hdl = tmph;
6377c478bd9Sstevel@tonic-gate (void) rw_unlock(&picltbl_rwlock); /* unlock picl */
6387c478bd9Sstevel@tonic-gate return (PICL_SUCCESS);
6397c478bd9Sstevel@tonic-gate }
6407c478bd9Sstevel@tonic-gate
6417c478bd9Sstevel@tonic-gate /*
6427c478bd9Sstevel@tonic-gate * Allocate a ptree handle
6437c478bd9Sstevel@tonic-gate */
6447c478bd9Sstevel@tonic-gate static picl_hdl_t
alloc_ptreehdl(void)6457c478bd9Sstevel@tonic-gate alloc_ptreehdl(void)
6467c478bd9Sstevel@tonic-gate {
6477c478bd9Sstevel@tonic-gate picl_hdl_t hdl;
6487c478bd9Sstevel@tonic-gate
6497c478bd9Sstevel@tonic-gate (void) pthread_mutex_lock(&ptreehdl_lock); /* lock ptreehdl */
6507c478bd9Sstevel@tonic-gate hdl = MAKE_HANDLE(picld_pid, ptree_hdl_hi);
6517c478bd9Sstevel@tonic-gate ++ptree_hdl_hi;
6527c478bd9Sstevel@tonic-gate (void) pthread_mutex_unlock(&ptreehdl_lock); /* unlock ptreehdl */
6537c478bd9Sstevel@tonic-gate return (hdl);
6547c478bd9Sstevel@tonic-gate }
6557c478bd9Sstevel@tonic-gate
6567c478bd9Sstevel@tonic-gate /*
6577c478bd9Sstevel@tonic-gate * Allocate a picl handle
6587c478bd9Sstevel@tonic-gate * A PICL handle is ptree_hdl value with 1 in MSB of handle value.
6597c478bd9Sstevel@tonic-gate * If a ptree handle already has 1 in MSB, then it cannot be piclized
6607c478bd9Sstevel@tonic-gate * and the daemon must be restarted.
6617c478bd9Sstevel@tonic-gate */
6627c478bd9Sstevel@tonic-gate static picl_hdl_t
alloc_piclhdl(void)6637c478bd9Sstevel@tonic-gate alloc_piclhdl(void)
6647c478bd9Sstevel@tonic-gate {
6657c478bd9Sstevel@tonic-gate picl_hdl_t hdl;
6667c478bd9Sstevel@tonic-gate
6677c478bd9Sstevel@tonic-gate (void) pthread_mutex_lock(&piclhdl_lock); /* lock piclhdl */
6687c478bd9Sstevel@tonic-gate hdl = MAKE_HANDLE(picld_pid, picl_hdl_hi);
6697c478bd9Sstevel@tonic-gate ++picl_hdl_hi;
6707c478bd9Sstevel@tonic-gate (void) pthread_mutex_unlock(&piclhdl_lock); /* unlock piclhdl */
6717c478bd9Sstevel@tonic-gate return (hdl);
6727c478bd9Sstevel@tonic-gate }
6737c478bd9Sstevel@tonic-gate
6747c478bd9Sstevel@tonic-gate /*
6757c478bd9Sstevel@tonic-gate * Allocate and add handle to PTree hash table
6767c478bd9Sstevel@tonic-gate */
6777c478bd9Sstevel@tonic-gate static void
alloc_and_add_to_ptree(picl_obj_t * pobj)6787c478bd9Sstevel@tonic-gate alloc_and_add_to_ptree(picl_obj_t *pobj)
6797c478bd9Sstevel@tonic-gate {
6807c478bd9Sstevel@tonic-gate pobj->ptree_hdl = alloc_ptreehdl();
6817c478bd9Sstevel@tonic-gate (void) rw_wrlock(&ptree_rwlock);
6827c478bd9Sstevel@tonic-gate (void) hash_add_newobj(&ptreetbl, pobj->ptree_hdl, pobj);
6837c478bd9Sstevel@tonic-gate (void) rw_unlock(&ptree_rwlock);
6847c478bd9Sstevel@tonic-gate }
6857c478bd9Sstevel@tonic-gate
6867c478bd9Sstevel@tonic-gate /*
6877c478bd9Sstevel@tonic-gate * Lock a picl node object
6887c478bd9Sstevel@tonic-gate */
6897c478bd9Sstevel@tonic-gate static int
lock_obj(int rw,picl_obj_t * nodep)6907c478bd9Sstevel@tonic-gate lock_obj(int rw, picl_obj_t *nodep)
6917c478bd9Sstevel@tonic-gate {
6927c478bd9Sstevel@tonic-gate if (rw == RDLOCK_NODE)
6937c478bd9Sstevel@tonic-gate (void) rw_rdlock(&nodep->node_lock);
6947c478bd9Sstevel@tonic-gate else if (rw == WRLOCK_NODE)
6957c478bd9Sstevel@tonic-gate (void) rw_wrlock(&nodep->node_lock);
6967c478bd9Sstevel@tonic-gate else
6977c478bd9Sstevel@tonic-gate return (-1);
6987c478bd9Sstevel@tonic-gate return (0);
6997c478bd9Sstevel@tonic-gate }
7007c478bd9Sstevel@tonic-gate
7017c478bd9Sstevel@tonic-gate /*
7027c478bd9Sstevel@tonic-gate * Release the picl node object.
7037c478bd9Sstevel@tonic-gate * This function may be called with a NULL object pointer.
7047c478bd9Sstevel@tonic-gate */
7057c478bd9Sstevel@tonic-gate static void
unlock_node(picl_obj_t * nodep)7067c478bd9Sstevel@tonic-gate unlock_node(picl_obj_t *nodep)
7077c478bd9Sstevel@tonic-gate {
7087c478bd9Sstevel@tonic-gate if (nodep == NULL)
7097c478bd9Sstevel@tonic-gate return;
7107c478bd9Sstevel@tonic-gate (void) rw_unlock(&nodep->node_lock);
7117c478bd9Sstevel@tonic-gate }
7127c478bd9Sstevel@tonic-gate
7137c478bd9Sstevel@tonic-gate /*
7147c478bd9Sstevel@tonic-gate * This function locks the node of a property and returns the node object
7157c478bd9Sstevel@tonic-gate * and the property object.
7167c478bd9Sstevel@tonic-gate */
7177c478bd9Sstevel@tonic-gate static int
lookup_and_lock_propnode(int rw,picl_prophdl_t proph,picl_obj_t ** nodep,picl_obj_t ** propp)7187c478bd9Sstevel@tonic-gate lookup_and_lock_propnode(int rw, picl_prophdl_t proph, picl_obj_t **nodep,
7197c478bd9Sstevel@tonic-gate picl_obj_t **propp)
7207c478bd9Sstevel@tonic-gate {
7217c478bd9Sstevel@tonic-gate picl_obj_t *pobj;
7227c478bd9Sstevel@tonic-gate picl_obj_t *nobj;
7237c478bd9Sstevel@tonic-gate
7247c478bd9Sstevel@tonic-gate pobj = hash_lookup_obj(&ptreetbl, proph);
7257c478bd9Sstevel@tonic-gate if (pobj == NULL)
7267c478bd9Sstevel@tonic-gate return (ptree_hdl_error(proph));
7277c478bd9Sstevel@tonic-gate
7287c478bd9Sstevel@tonic-gate /*
7297c478bd9Sstevel@tonic-gate * Get the property's or table entry's node object
7307c478bd9Sstevel@tonic-gate */
7317c478bd9Sstevel@tonic-gate nobj = NULL;
7327c478bd9Sstevel@tonic-gate if (pobj->obj_type == PICL_OBJ_PROP)
7337c478bd9Sstevel@tonic-gate nobj = pobj->prop_node;
7347c478bd9Sstevel@tonic-gate else if (pobj->obj_type == (PICL_OBJ_PROP|PICL_OBJ_TABLEENTRY))
7357c478bd9Sstevel@tonic-gate nobj = pobj->prop_table->prop_node;
7367c478bd9Sstevel@tonic-gate else {
7377c478bd9Sstevel@tonic-gate *propp = pobj; /* return the prop */
7387c478bd9Sstevel@tonic-gate return (PICL_NOTPROP);
7397c478bd9Sstevel@tonic-gate }
7407c478bd9Sstevel@tonic-gate
7417c478bd9Sstevel@tonic-gate if (nobj && (lock_obj(rw, nobj) < 0)) /* Lock node */
7427c478bd9Sstevel@tonic-gate return (PICL_FAILURE);
7437c478bd9Sstevel@tonic-gate
7447c478bd9Sstevel@tonic-gate *nodep = nobj;
7457c478bd9Sstevel@tonic-gate *propp = pobj;
7467c478bd9Sstevel@tonic-gate
7477c478bd9Sstevel@tonic-gate return (PICL_SUCCESS);
7487c478bd9Sstevel@tonic-gate }
7497c478bd9Sstevel@tonic-gate
7507c478bd9Sstevel@tonic-gate /*
7517c478bd9Sstevel@tonic-gate * This function locks the node of a table and returns the node object
7527c478bd9Sstevel@tonic-gate * and the table object.
7537c478bd9Sstevel@tonic-gate */
7547c478bd9Sstevel@tonic-gate static int
lookup_and_lock_tablenode(int rw,picl_prophdl_t tblh,picl_obj_t ** nodep,picl_obj_t ** tblobj)7557c478bd9Sstevel@tonic-gate lookup_and_lock_tablenode(int rw, picl_prophdl_t tblh, picl_obj_t **nodep,
7567c478bd9Sstevel@tonic-gate picl_obj_t **tblobj)
7577c478bd9Sstevel@tonic-gate {
7587c478bd9Sstevel@tonic-gate picl_obj_t *pobj;
7597c478bd9Sstevel@tonic-gate picl_obj_t *nobj;
7607c478bd9Sstevel@tonic-gate
7617c478bd9Sstevel@tonic-gate pobj = hash_lookup_obj(&ptreetbl, tblh);
7627c478bd9Sstevel@tonic-gate if (pobj == NULL)
7637c478bd9Sstevel@tonic-gate return (ptree_hdl_error(tblh));
7647c478bd9Sstevel@tonic-gate
7657c478bd9Sstevel@tonic-gate /*
7667c478bd9Sstevel@tonic-gate * Get the property's or table entry's node object
7677c478bd9Sstevel@tonic-gate */
7687c478bd9Sstevel@tonic-gate nobj = NULL;
7697c478bd9Sstevel@tonic-gate if (pobj->obj_type != PICL_OBJ_TABLE)
7707c478bd9Sstevel@tonic-gate return (PICL_NOTTABLE);
7717c478bd9Sstevel@tonic-gate nobj = pobj->prop_node;
7727c478bd9Sstevel@tonic-gate
7737c478bd9Sstevel@tonic-gate if (nobj && (lock_obj(rw, nobj) < 0)) /* Lock node */
7747c478bd9Sstevel@tonic-gate return (PICL_FAILURE);
7757c478bd9Sstevel@tonic-gate
7767c478bd9Sstevel@tonic-gate *nodep = nobj;
7777c478bd9Sstevel@tonic-gate *tblobj = pobj;
7787c478bd9Sstevel@tonic-gate
7797c478bd9Sstevel@tonic-gate return (PICL_SUCCESS);
7807c478bd9Sstevel@tonic-gate }
7817c478bd9Sstevel@tonic-gate
7827c478bd9Sstevel@tonic-gate /*
7837c478bd9Sstevel@tonic-gate * This locks the node of a table or a table entry and returns the
7847c478bd9Sstevel@tonic-gate * node object and the table or table entry object
7857c478bd9Sstevel@tonic-gate */
7867c478bd9Sstevel@tonic-gate static int
lookup_and_lock_tableprop_node(int rw,picl_prophdl_t tblproph,picl_obj_t ** nodep,picl_obj_t ** tblpropp)7877c478bd9Sstevel@tonic-gate lookup_and_lock_tableprop_node(int rw, picl_prophdl_t tblproph,
7887c478bd9Sstevel@tonic-gate picl_obj_t **nodep, picl_obj_t **tblpropp)
7897c478bd9Sstevel@tonic-gate {
7907c478bd9Sstevel@tonic-gate picl_obj_t *pobj;
7917c478bd9Sstevel@tonic-gate picl_obj_t *nobj;
7927c478bd9Sstevel@tonic-gate
7937c478bd9Sstevel@tonic-gate pobj = hash_lookup_obj(&ptreetbl, tblproph);
7947c478bd9Sstevel@tonic-gate if (pobj == NULL)
7957c478bd9Sstevel@tonic-gate return (ptree_hdl_error(tblproph));
7967c478bd9Sstevel@tonic-gate
7977c478bd9Sstevel@tonic-gate /*
7987c478bd9Sstevel@tonic-gate * Get the property's or table entry's node object
7997c478bd9Sstevel@tonic-gate */
8007c478bd9Sstevel@tonic-gate nobj = NULL;
8017c478bd9Sstevel@tonic-gate if ((pobj->obj_type != PICL_OBJ_TABLE) && /* not a table */
8027c478bd9Sstevel@tonic-gate !(pobj->obj_type & PICL_OBJ_TABLEENTRY)) /* or an entry */
8037c478bd9Sstevel@tonic-gate return (PICL_NOTTABLE);
8047c478bd9Sstevel@tonic-gate if (pobj->obj_type == PICL_OBJ_TABLE)
8057c478bd9Sstevel@tonic-gate nobj = pobj->prop_node;
8067c478bd9Sstevel@tonic-gate else
8077c478bd9Sstevel@tonic-gate nobj = pobj->prop_table->prop_node;
8087c478bd9Sstevel@tonic-gate
8097c478bd9Sstevel@tonic-gate if (nobj && (lock_obj(rw, nobj) < 0)) /* Lock node */
8107c478bd9Sstevel@tonic-gate return (PICL_FAILURE);
8117c478bd9Sstevel@tonic-gate
8127c478bd9Sstevel@tonic-gate *tblpropp = pobj;
8137c478bd9Sstevel@tonic-gate *nodep = nobj;
8147c478bd9Sstevel@tonic-gate
8157c478bd9Sstevel@tonic-gate return (PICL_SUCCESS);
8167c478bd9Sstevel@tonic-gate }
8177c478bd9Sstevel@tonic-gate
8187c478bd9Sstevel@tonic-gate /*
8197c478bd9Sstevel@tonic-gate * Lock the node corresponding to the given handle and return its object
8207c478bd9Sstevel@tonic-gate */
8217c478bd9Sstevel@tonic-gate static int
lookup_and_lock_node(int rw,picl_nodehdl_t nodeh,picl_obj_t ** nodep)8227c478bd9Sstevel@tonic-gate lookup_and_lock_node(int rw, picl_nodehdl_t nodeh, picl_obj_t **nodep)
8237c478bd9Sstevel@tonic-gate {
8247c478bd9Sstevel@tonic-gate picl_obj_t *nobj;
8257c478bd9Sstevel@tonic-gate
8267c478bd9Sstevel@tonic-gate nobj = hash_lookup_obj(&ptreetbl, nodeh);
8277c478bd9Sstevel@tonic-gate if (nobj == NULL)
8287c478bd9Sstevel@tonic-gate return (ptree_hdl_error(nodeh));
8297c478bd9Sstevel@tonic-gate else if (nobj->obj_type != PICL_OBJ_NODE)
8307c478bd9Sstevel@tonic-gate return (PICL_NOTNODE);
8317c478bd9Sstevel@tonic-gate if (lock_obj(rw, nobj) < 0) /* Lock node */
8327c478bd9Sstevel@tonic-gate return (PICL_FAILURE);
8337c478bd9Sstevel@tonic-gate *nodep = nobj;
8347c478bd9Sstevel@tonic-gate return (PICL_SUCCESS);
8357c478bd9Sstevel@tonic-gate }
8367c478bd9Sstevel@tonic-gate
8377c478bd9Sstevel@tonic-gate /*
8387c478bd9Sstevel@tonic-gate * Is the property name a restricted property name?
8397c478bd9Sstevel@tonic-gate */
8407c478bd9Sstevel@tonic-gate static int
picl_restricted(const char * name)8417c478bd9Sstevel@tonic-gate picl_restricted(const char *name)
8427c478bd9Sstevel@tonic-gate {
8437c478bd9Sstevel@tonic-gate if (strcmp(name, PICL_PROP_CLASSNAME) == 0)
8447c478bd9Sstevel@tonic-gate return (0); /* not restricted */
8457c478bd9Sstevel@tonic-gate
8467c478bd9Sstevel@tonic-gate if ((name[0] == '_') && (strchr(&name[1], '_') == NULL))
8477c478bd9Sstevel@tonic-gate return (1);
8487c478bd9Sstevel@tonic-gate return (0);
8497c478bd9Sstevel@tonic-gate }
8507c478bd9Sstevel@tonic-gate
8517c478bd9Sstevel@tonic-gate /*
8527c478bd9Sstevel@tonic-gate * Check the value size with the property size
8537c478bd9Sstevel@tonic-gate * Return PICL_INVALIDARG if the size does not match exactly for strongly
8547c478bd9Sstevel@tonic-gate * typed properties.
8557c478bd9Sstevel@tonic-gate * For charstring reads allow sizes that match the value size
8567c478bd9Sstevel@tonic-gate * For bytearray return PICL_VALUETOOBIG
8577c478bd9Sstevel@tonic-gate * if the size is greater than the buffer size.
8587c478bd9Sstevel@tonic-gate */
8597c478bd9Sstevel@tonic-gate static int
check_propsize(int op,picl_obj_t * propp,size_t sz)8607c478bd9Sstevel@tonic-gate check_propsize(int op, picl_obj_t *propp, size_t sz)
8617c478bd9Sstevel@tonic-gate {
8627c478bd9Sstevel@tonic-gate if (propp->prop_mode & PICL_VOLATILE) {
8637c478bd9Sstevel@tonic-gate if (sz != propp->prop_size)
8647c478bd9Sstevel@tonic-gate return (PICL_INVALIDARG);
8657c478bd9Sstevel@tonic-gate else
8667c478bd9Sstevel@tonic-gate return (PICL_SUCCESS);
8677c478bd9Sstevel@tonic-gate }
8687c478bd9Sstevel@tonic-gate
8697c478bd9Sstevel@tonic-gate /*
8707c478bd9Sstevel@tonic-gate * check size for non-volatile properties
8717c478bd9Sstevel@tonic-gate */
8727c478bd9Sstevel@tonic-gate switch (propp->prop_type) {
8737c478bd9Sstevel@tonic-gate case PICL_PTYPE_CHARSTRING:
8747c478bd9Sstevel@tonic-gate if ((op == PROP_READ) &&
8757c478bd9Sstevel@tonic-gate (strlen(propp->prop_val) >= sz))
8767c478bd9Sstevel@tonic-gate return (PICL_VALUETOOBIG);
8777c478bd9Sstevel@tonic-gate if ((op == PROP_WRITE) && (sz > propp->prop_size))
8787c478bd9Sstevel@tonic-gate return (PICL_VALUETOOBIG);
8797c478bd9Sstevel@tonic-gate break;
8807c478bd9Sstevel@tonic-gate case PICL_PTYPE_BYTEARRAY:
8817c478bd9Sstevel@tonic-gate if (op == PROP_WRITE) {
8827c478bd9Sstevel@tonic-gate if (sz > propp->prop_size)
8837c478bd9Sstevel@tonic-gate return (PICL_VALUETOOBIG);
8847c478bd9Sstevel@tonic-gate return (PICL_SUCCESS); /* allow small writes */
8857c478bd9Sstevel@tonic-gate }
8867c478bd9Sstevel@tonic-gate /* fall through for reads */
8877c478bd9Sstevel@tonic-gate default:
8887c478bd9Sstevel@tonic-gate if (propp->prop_size != sz)
8897c478bd9Sstevel@tonic-gate return (PICL_INVALIDARG);
8907c478bd9Sstevel@tonic-gate break;
8917c478bd9Sstevel@tonic-gate }
8927c478bd9Sstevel@tonic-gate return (PICL_SUCCESS);
8937c478bd9Sstevel@tonic-gate }
8947c478bd9Sstevel@tonic-gate
8957c478bd9Sstevel@tonic-gate void
cvt_ptree2picl(picl_hdl_t * handlep)8967c478bd9Sstevel@tonic-gate cvt_ptree2picl(picl_hdl_t *handlep)
8977c478bd9Sstevel@tonic-gate {
8987c478bd9Sstevel@tonic-gate picl_obj_t *pobj;
8997c478bd9Sstevel@tonic-gate
9007c478bd9Sstevel@tonic-gate (void) rw_rdlock(&ptree_rwlock);
9017c478bd9Sstevel@tonic-gate pobj = hash_lookup_obj(&ptreetbl, *handlep);
9027c478bd9Sstevel@tonic-gate if (pobj == NULL)
9037c478bd9Sstevel@tonic-gate *handlep = PICL_INVALID_PICLHDL;
9047c478bd9Sstevel@tonic-gate else
9057c478bd9Sstevel@tonic-gate (void) memcpy(handlep, &pobj->picl_hdl, sizeof (*handlep));
9067c478bd9Sstevel@tonic-gate (void) rw_unlock(&ptree_rwlock);
9077c478bd9Sstevel@tonic-gate }
9087c478bd9Sstevel@tonic-gate
9097c478bd9Sstevel@tonic-gate /*
9107c478bd9Sstevel@tonic-gate * The caller of the piclize() set of functions is assumed to hold
9117c478bd9Sstevel@tonic-gate * the ptree_rwlock().
9127c478bd9Sstevel@tonic-gate */
9137c478bd9Sstevel@tonic-gate static void
piclize_obj(picl_obj_t * pobj)9147c478bd9Sstevel@tonic-gate piclize_obj(picl_obj_t *pobj)
9157c478bd9Sstevel@tonic-gate {
9167c478bd9Sstevel@tonic-gate (void) rw_wrlock(&picltbl_rwlock);
9177c478bd9Sstevel@tonic-gate pobj->picl_hdl = alloc_piclhdl();
9187c478bd9Sstevel@tonic-gate (void) hash_add_newhdl(&picltbl, pobj->picl_hdl, pobj->ptree_hdl);
9197c478bd9Sstevel@tonic-gate (void) rw_unlock(&picltbl_rwlock);
9207c478bd9Sstevel@tonic-gate }
9217c478bd9Sstevel@tonic-gate
9227c478bd9Sstevel@tonic-gate static void
piclize_table(picl_obj_t * tbl_obj)9237c478bd9Sstevel@tonic-gate piclize_table(picl_obj_t *tbl_obj)
9247c478bd9Sstevel@tonic-gate {
9257c478bd9Sstevel@tonic-gate picl_obj_t *rowp;
9267c478bd9Sstevel@tonic-gate picl_obj_t *colp;
9277c478bd9Sstevel@tonic-gate
9287c478bd9Sstevel@tonic-gate for (rowp = tbl_obj->next_row; rowp != NULL; rowp = rowp->next_col)
9297c478bd9Sstevel@tonic-gate for (colp = rowp; colp != NULL; colp = colp->next_row)
9307c478bd9Sstevel@tonic-gate piclize_obj(colp);
9317c478bd9Sstevel@tonic-gate }
9327c478bd9Sstevel@tonic-gate
9337c478bd9Sstevel@tonic-gate static void
piclize_prop(picl_obj_t * propp)9347c478bd9Sstevel@tonic-gate piclize_prop(picl_obj_t *propp)
9357c478bd9Sstevel@tonic-gate {
9367c478bd9Sstevel@tonic-gate picl_obj_t *tbl_obj;
9377c478bd9Sstevel@tonic-gate picl_prophdl_t tblh;
9387c478bd9Sstevel@tonic-gate
9397c478bd9Sstevel@tonic-gate piclize_obj(propp);
9407c478bd9Sstevel@tonic-gate if (!(propp->prop_mode & PICL_VOLATILE) &&
9417c478bd9Sstevel@tonic-gate (propp->prop_type == PICL_PTYPE_TABLE)) {
9427c478bd9Sstevel@tonic-gate tblh = *(picl_prophdl_t *)propp->prop_val;
9437c478bd9Sstevel@tonic-gate tbl_obj = hash_lookup_obj(&ptreetbl, tblh);
9447c478bd9Sstevel@tonic-gate if (tbl_obj == NULL)
9457c478bd9Sstevel@tonic-gate return;
9467c478bd9Sstevel@tonic-gate piclize_obj(tbl_obj);
9477c478bd9Sstevel@tonic-gate piclize_table(tbl_obj);
9487c478bd9Sstevel@tonic-gate }
9497c478bd9Sstevel@tonic-gate }
9507c478bd9Sstevel@tonic-gate
9517c478bd9Sstevel@tonic-gate /*
9527c478bd9Sstevel@tonic-gate * Function to create PICL handles for a subtree and add them to
9537c478bd9Sstevel@tonic-gate * the table
9547c478bd9Sstevel@tonic-gate */
9557c478bd9Sstevel@tonic-gate static void
piclize_node(picl_obj_t * nodep)9567c478bd9Sstevel@tonic-gate piclize_node(picl_obj_t *nodep)
9577c478bd9Sstevel@tonic-gate {
9587c478bd9Sstevel@tonic-gate picl_obj_t *propp;
9597c478bd9Sstevel@tonic-gate picl_obj_t *chdp;
9607c478bd9Sstevel@tonic-gate
9617c478bd9Sstevel@tonic-gate piclize_obj(nodep);
9627c478bd9Sstevel@tonic-gate propp = nodep->first_prop;
9637c478bd9Sstevel@tonic-gate while (propp != NULL) {
9647c478bd9Sstevel@tonic-gate piclize_prop(propp);
9657c478bd9Sstevel@tonic-gate propp = propp->next_prop;
9667c478bd9Sstevel@tonic-gate }
9677c478bd9Sstevel@tonic-gate
9687c478bd9Sstevel@tonic-gate /* go through the children */
9697c478bd9Sstevel@tonic-gate for (chdp = nodep->child_node; chdp != NULL; chdp = chdp->sibling_node)
9707c478bd9Sstevel@tonic-gate piclize_node(chdp);
9717c478bd9Sstevel@tonic-gate }
9727c478bd9Sstevel@tonic-gate
9737c478bd9Sstevel@tonic-gate /*
9747c478bd9Sstevel@tonic-gate * Function to remove PICL handles
9757c478bd9Sstevel@tonic-gate */
9767c478bd9Sstevel@tonic-gate static void
unpiclize_obj(picl_obj_t * pobj)9777c478bd9Sstevel@tonic-gate unpiclize_obj(picl_obj_t *pobj)
9787c478bd9Sstevel@tonic-gate {
9797c478bd9Sstevel@tonic-gate (void) rw_wrlock(&picltbl_rwlock);
9807c478bd9Sstevel@tonic-gate (void) hash_remove(&picltbl, pobj->picl_hdl);
9817c478bd9Sstevel@tonic-gate pobj->picl_hdl = PICL_INVALID_PICLHDL;
9827c478bd9Sstevel@tonic-gate (void) rw_unlock(&picltbl_rwlock);
9837c478bd9Sstevel@tonic-gate }
9847c478bd9Sstevel@tonic-gate
9857c478bd9Sstevel@tonic-gate static void
unpiclize_table(picl_obj_t * tbl_obj)9867c478bd9Sstevel@tonic-gate unpiclize_table(picl_obj_t *tbl_obj)
9877c478bd9Sstevel@tonic-gate {
9887c478bd9Sstevel@tonic-gate picl_obj_t *rowp;
9897c478bd9Sstevel@tonic-gate picl_obj_t *colp;
9907c478bd9Sstevel@tonic-gate
9917c478bd9Sstevel@tonic-gate for (rowp = tbl_obj->next_row; rowp != NULL; rowp = rowp->next_col)
9927c478bd9Sstevel@tonic-gate for (colp = rowp; colp != NULL; colp = colp->next_row)
9937c478bd9Sstevel@tonic-gate unpiclize_obj(colp);
9947c478bd9Sstevel@tonic-gate unpiclize_obj(tbl_obj);
9957c478bd9Sstevel@tonic-gate }
9967c478bd9Sstevel@tonic-gate
9977c478bd9Sstevel@tonic-gate static void
unpiclize_prop(picl_obj_t * propp)9987c478bd9Sstevel@tonic-gate unpiclize_prop(picl_obj_t *propp)
9997c478bd9Sstevel@tonic-gate {
10007c478bd9Sstevel@tonic-gate picl_obj_t *tbl_obj;
10017c478bd9Sstevel@tonic-gate picl_prophdl_t tblh;
10027c478bd9Sstevel@tonic-gate
10037c478bd9Sstevel@tonic-gate if (!IS_PICLIZED(propp))
10047c478bd9Sstevel@tonic-gate return;
10057c478bd9Sstevel@tonic-gate unpiclize_obj(propp);
10067c478bd9Sstevel@tonic-gate if (!(propp->prop_mode & PICL_VOLATILE) &&
10077c478bd9Sstevel@tonic-gate (propp->prop_type == PICL_PTYPE_TABLE)) {
10087c478bd9Sstevel@tonic-gate tblh = *(picl_prophdl_t *)propp->prop_val;
10097c478bd9Sstevel@tonic-gate tbl_obj = hash_lookup_obj(&ptreetbl, tblh);
10107c478bd9Sstevel@tonic-gate unpiclize_table(tbl_obj);
10117c478bd9Sstevel@tonic-gate }
10127c478bd9Sstevel@tonic-gate }
10137c478bd9Sstevel@tonic-gate
10147c478bd9Sstevel@tonic-gate /*
10157c478bd9Sstevel@tonic-gate * Function to remove PICL handles for a subtree and its
10167c478bd9Sstevel@tonic-gate * properties
10177c478bd9Sstevel@tonic-gate */
10187c478bd9Sstevel@tonic-gate static void
unpiclize_node(picl_obj_t * nodep)10197c478bd9Sstevel@tonic-gate unpiclize_node(picl_obj_t *nodep)
10207c478bd9Sstevel@tonic-gate {
10217c478bd9Sstevel@tonic-gate picl_obj_t *propp;
10227c478bd9Sstevel@tonic-gate picl_obj_t *chdp;
10237c478bd9Sstevel@tonic-gate
10247c478bd9Sstevel@tonic-gate
10257c478bd9Sstevel@tonic-gate if (!IS_PICLIZED(nodep))
10267c478bd9Sstevel@tonic-gate return;
10277c478bd9Sstevel@tonic-gate
10287c478bd9Sstevel@tonic-gate unpiclize_obj(nodep);
10297c478bd9Sstevel@tonic-gate propp = nodep->first_prop;
10307c478bd9Sstevel@tonic-gate while (propp != NULL) {
10317c478bd9Sstevel@tonic-gate unpiclize_prop(propp);
10327c478bd9Sstevel@tonic-gate propp = propp->next_prop;
10337c478bd9Sstevel@tonic-gate }
10347c478bd9Sstevel@tonic-gate
10357c478bd9Sstevel@tonic-gate /* go through the children */
10367c478bd9Sstevel@tonic-gate for (chdp = nodep->child_node; chdp != NULL; chdp = chdp->sibling_node)
10377c478bd9Sstevel@tonic-gate unpiclize_node(chdp);
10387c478bd9Sstevel@tonic-gate }
10397c478bd9Sstevel@tonic-gate
10407c478bd9Sstevel@tonic-gate
10417c478bd9Sstevel@tonic-gate /*
10427c478bd9Sstevel@tonic-gate * The caller holds the lock on the ptree_lock when calling this.
10437c478bd9Sstevel@tonic-gate * If ret is not NULL then this function returns the referenced object.
10447c478bd9Sstevel@tonic-gate */
10457c478bd9Sstevel@tonic-gate static int
lookup_verify_ref_prop(picl_obj_t * propp,picl_obj_t ** ret)10467c478bd9Sstevel@tonic-gate lookup_verify_ref_prop(picl_obj_t *propp, picl_obj_t **ret)
10477c478bd9Sstevel@tonic-gate {
10487c478bd9Sstevel@tonic-gate picl_nodehdl_t refh;
10497c478bd9Sstevel@tonic-gate picl_obj_t *refobj;
10507c478bd9Sstevel@tonic-gate
10517c478bd9Sstevel@tonic-gate refh = *(picl_nodehdl_t *)propp->prop_val;
10527c478bd9Sstevel@tonic-gate refobj = hash_lookup_obj(&ptreetbl, refh);
10537c478bd9Sstevel@tonic-gate if (refobj == NULL)
10547c478bd9Sstevel@tonic-gate return (ptree_hdl_error(refh));
10557c478bd9Sstevel@tonic-gate else if (refobj->obj_type != PICL_OBJ_NODE)
10567c478bd9Sstevel@tonic-gate return (PICL_INVREFERENCE);
10577c478bd9Sstevel@tonic-gate if (ret)
10587c478bd9Sstevel@tonic-gate *ret = refobj;
10597c478bd9Sstevel@tonic-gate return (PICL_SUCCESS);
10607c478bd9Sstevel@tonic-gate }
10617c478bd9Sstevel@tonic-gate
10627c478bd9Sstevel@tonic-gate /*
10637c478bd9Sstevel@tonic-gate * The caller holds the lock on ptree_lock when calling this.
10647c478bd9Sstevel@tonic-gate * If ret is not NULL, then this function returns the table object
10657c478bd9Sstevel@tonic-gate */
10667c478bd9Sstevel@tonic-gate static int
lookup_verify_table_prop(picl_obj_t * propp,picl_obj_t ** ret)10677c478bd9Sstevel@tonic-gate lookup_verify_table_prop(picl_obj_t *propp, picl_obj_t **ret)
10687c478bd9Sstevel@tonic-gate {
10697c478bd9Sstevel@tonic-gate picl_prophdl_t tblh;
10707c478bd9Sstevel@tonic-gate picl_obj_t *tbl_obj;
10717c478bd9Sstevel@tonic-gate
10727c478bd9Sstevel@tonic-gate tblh = *(picl_prophdl_t *)propp->prop_val;
10737c478bd9Sstevel@tonic-gate tbl_obj = hash_lookup_obj(&ptreetbl, tblh);
10747c478bd9Sstevel@tonic-gate if (tbl_obj == NULL)
10757c478bd9Sstevel@tonic-gate return (ptree_hdl_error(tblh));
10767c478bd9Sstevel@tonic-gate else if (!(tbl_obj->obj_type & PICL_OBJ_TABLE))
10777c478bd9Sstevel@tonic-gate return (PICL_NOTTABLE);
10787c478bd9Sstevel@tonic-gate if (ret)
10797c478bd9Sstevel@tonic-gate *ret = tbl_obj;
10807c478bd9Sstevel@tonic-gate return (PICL_SUCCESS);
10817c478bd9Sstevel@tonic-gate }
10827c478bd9Sstevel@tonic-gate
10837c478bd9Sstevel@tonic-gate static int
lookup_verify_prop_handle(picl_prophdl_t proph,picl_obj_t ** ret)10847c478bd9Sstevel@tonic-gate lookup_verify_prop_handle(picl_prophdl_t proph, picl_obj_t **ret)
10857c478bd9Sstevel@tonic-gate {
10867c478bd9Sstevel@tonic-gate picl_obj_t *propp;
10877c478bd9Sstevel@tonic-gate
10887c478bd9Sstevel@tonic-gate propp = hash_lookup_obj(&ptreetbl, proph);
10897c478bd9Sstevel@tonic-gate if (propp == NULL)
10907c478bd9Sstevel@tonic-gate return (ptree_hdl_error(proph));
10917c478bd9Sstevel@tonic-gate else if (!(propp->obj_type & PICL_OBJ_PROP))
10927c478bd9Sstevel@tonic-gate return (PICL_NOTPROP);
10937c478bd9Sstevel@tonic-gate if (ret)
10947c478bd9Sstevel@tonic-gate *ret = propp;
10957c478bd9Sstevel@tonic-gate return (PICL_SUCCESS);
10967c478bd9Sstevel@tonic-gate }
10977c478bd9Sstevel@tonic-gate
10987c478bd9Sstevel@tonic-gate static int
lookup_verify_node_handle(picl_nodehdl_t nodeh,picl_obj_t ** ret)10997c478bd9Sstevel@tonic-gate lookup_verify_node_handle(picl_nodehdl_t nodeh, picl_obj_t **ret)
11007c478bd9Sstevel@tonic-gate {
11017c478bd9Sstevel@tonic-gate picl_obj_t *nodep;
11027c478bd9Sstevel@tonic-gate
11037c478bd9Sstevel@tonic-gate nodep = hash_lookup_obj(&ptreetbl, nodeh);
11047c478bd9Sstevel@tonic-gate if (nodep == NULL)
11057c478bd9Sstevel@tonic-gate return (ptree_hdl_error(nodeh));
11067c478bd9Sstevel@tonic-gate else if (nodep->obj_type != PICL_OBJ_NODE)
11077c478bd9Sstevel@tonic-gate return (PICL_NOTNODE);
11087c478bd9Sstevel@tonic-gate if (ret)
11097c478bd9Sstevel@tonic-gate *ret = nodep;
11107c478bd9Sstevel@tonic-gate return (PICL_SUCCESS);
11117c478bd9Sstevel@tonic-gate }
11127c478bd9Sstevel@tonic-gate
11137c478bd9Sstevel@tonic-gate static int
lookup_prop_by_name(picl_obj_t * nodep,const char * pname,picl_obj_t ** ret)11147c478bd9Sstevel@tonic-gate lookup_prop_by_name(picl_obj_t *nodep, const char *pname, picl_obj_t **ret)
11157c478bd9Sstevel@tonic-gate {
11167c478bd9Sstevel@tonic-gate picl_obj_t *propp;
11177c478bd9Sstevel@tonic-gate
11187c478bd9Sstevel@tonic-gate if (strcmp(pname, PICL_PROP_PARENT) == 0) {
11197c478bd9Sstevel@tonic-gate if (nodep->parent_node == NULL)
11207c478bd9Sstevel@tonic-gate return (PICL_PROPNOTFOUND);
11217c478bd9Sstevel@tonic-gate else
11227c478bd9Sstevel@tonic-gate return (PICL_SUCCESS);
11237c478bd9Sstevel@tonic-gate }
11247c478bd9Sstevel@tonic-gate if (strcmp(pname, PICL_PROP_CHILD) == 0) {
11257c478bd9Sstevel@tonic-gate if (nodep->child_node == NULL)
11267c478bd9Sstevel@tonic-gate return (PICL_PROPNOTFOUND);
11277c478bd9Sstevel@tonic-gate else
11287c478bd9Sstevel@tonic-gate return (PICL_SUCCESS);
11297c478bd9Sstevel@tonic-gate }
11307c478bd9Sstevel@tonic-gate if (strcmp(pname, PICL_PROP_PEER) == 0) {
11317c478bd9Sstevel@tonic-gate if (nodep->sibling_node == NULL)
11327c478bd9Sstevel@tonic-gate return (PICL_PROPNOTFOUND);
11337c478bd9Sstevel@tonic-gate else
11347c478bd9Sstevel@tonic-gate return (PICL_SUCCESS);
11357c478bd9Sstevel@tonic-gate }
11367c478bd9Sstevel@tonic-gate
11377c478bd9Sstevel@tonic-gate propp = nodep->first_prop;
11387c478bd9Sstevel@tonic-gate while (propp != NULL) {
11397c478bd9Sstevel@tonic-gate if (strcmp(propp->prop_name, pname) == 0) {
11407c478bd9Sstevel@tonic-gate if (ret)
11417c478bd9Sstevel@tonic-gate *ret = propp;
11427c478bd9Sstevel@tonic-gate return (PICL_SUCCESS);
11437c478bd9Sstevel@tonic-gate }
11447c478bd9Sstevel@tonic-gate propp = propp->next_prop;
11457c478bd9Sstevel@tonic-gate }
11467c478bd9Sstevel@tonic-gate return (PICL_PROPNOTFOUND);
11477c478bd9Sstevel@tonic-gate }
11487c478bd9Sstevel@tonic-gate
11497c478bd9Sstevel@tonic-gate /*
11507c478bd9Sstevel@tonic-gate * This function locks the ptree, verifies that the handle is a reference
11517c478bd9Sstevel@tonic-gate * to a node of specified class name, releases the lock
11527c478bd9Sstevel@tonic-gate */
11537c478bd9Sstevel@tonic-gate static int
check_ref_handle(picl_nodehdl_t refh,char * clname)11547c478bd9Sstevel@tonic-gate check_ref_handle(picl_nodehdl_t refh, char *clname)
11557c478bd9Sstevel@tonic-gate {
11567c478bd9Sstevel@tonic-gate picl_obj_t *refobj;
11577c478bd9Sstevel@tonic-gate picl_obj_t *propp;
11587c478bd9Sstevel@tonic-gate int err;
11597c478bd9Sstevel@tonic-gate
11607c478bd9Sstevel@tonic-gate (void) rw_rdlock(&ptree_rwlock); /* Lock ptree */
11617c478bd9Sstevel@tonic-gate refobj = hash_lookup_obj(&ptreetbl, refh);
11627c478bd9Sstevel@tonic-gate if ((refobj == NULL) || !(refobj->obj_type & PICL_OBJ_NODE)) {
11637c478bd9Sstevel@tonic-gate (void) rw_unlock(&ptree_rwlock);
11647c478bd9Sstevel@tonic-gate return (PICL_INVREFERENCE);
11657c478bd9Sstevel@tonic-gate }
11667c478bd9Sstevel@tonic-gate
11677c478bd9Sstevel@tonic-gate err = lookup_prop_by_name(refobj, PICL_PROP_CLASSNAME, &propp);
11687c478bd9Sstevel@tonic-gate if ((err != PICL_SUCCESS) || (propp->prop_val == NULL) ||
11697c478bd9Sstevel@tonic-gate (strcmp(propp->prop_val, clname) != 0))
11707c478bd9Sstevel@tonic-gate err = PICL_INVREFERENCE;
11717c478bd9Sstevel@tonic-gate (void) rw_unlock(&ptree_rwlock); /* unlock ptree */
11727c478bd9Sstevel@tonic-gate return (err);
11737c478bd9Sstevel@tonic-gate }
11747c478bd9Sstevel@tonic-gate
11757c478bd9Sstevel@tonic-gate static int
check_table_handle(picl_prophdl_t tblh)11767c478bd9Sstevel@tonic-gate check_table_handle(picl_prophdl_t tblh)
11777c478bd9Sstevel@tonic-gate {
11787c478bd9Sstevel@tonic-gate picl_obj_t *tbl_obj;
11797c478bd9Sstevel@tonic-gate int err;
11807c478bd9Sstevel@tonic-gate
11817c478bd9Sstevel@tonic-gate (void) rw_rdlock(&ptree_rwlock);
11827c478bd9Sstevel@tonic-gate err = PICL_SUCCESS;
11837c478bd9Sstevel@tonic-gate tbl_obj = hash_lookup_obj(&ptreetbl, tblh);
11847c478bd9Sstevel@tonic-gate if ((tbl_obj == NULL) || !(tbl_obj->obj_type & PICL_OBJ_TABLE))
11857c478bd9Sstevel@tonic-gate err = PICL_NOTTABLE;
11867c478bd9Sstevel@tonic-gate (void) rw_unlock(&ptree_rwlock);
11877c478bd9Sstevel@tonic-gate return (err);
11887c478bd9Sstevel@tonic-gate }
11897c478bd9Sstevel@tonic-gate
11907c478bd9Sstevel@tonic-gate /*
11917c478bd9Sstevel@tonic-gate * PICLTree Interface routines for plug-in modules
11927c478bd9Sstevel@tonic-gate */
11937c478bd9Sstevel@tonic-gate int
ptree_get_root(picl_nodehdl_t * rooth)11947c478bd9Sstevel@tonic-gate ptree_get_root(picl_nodehdl_t *rooth)
11957c478bd9Sstevel@tonic-gate {
11967c478bd9Sstevel@tonic-gate *rooth = ptree_root_hdl;
11977c478bd9Sstevel@tonic-gate return (PICL_SUCCESS);
11987c478bd9Sstevel@tonic-gate }
11997c478bd9Sstevel@tonic-gate
12007c478bd9Sstevel@tonic-gate /*
12017c478bd9Sstevel@tonic-gate * Lock free create a property object
12027c478bd9Sstevel@tonic-gate */
12037c478bd9Sstevel@tonic-gate static int
create_propobj(const ptree_propinfo_t * pinfo,const void * valbuf,picl_obj_t ** pobjp)12047c478bd9Sstevel@tonic-gate create_propobj(const ptree_propinfo_t *pinfo, const void *valbuf,
12057c478bd9Sstevel@tonic-gate picl_obj_t **pobjp)
12067c478bd9Sstevel@tonic-gate {
12077c478bd9Sstevel@tonic-gate picl_obj_t *pobj;
12087c478bd9Sstevel@tonic-gate
12097c478bd9Sstevel@tonic-gate if (pinfo->version != PTREE_PROPINFO_VERSION_1)
12107c478bd9Sstevel@tonic-gate return (PICL_NOTSUPPORTED);
12117c478bd9Sstevel@tonic-gate
12127c478bd9Sstevel@tonic-gate if (!(pinfo->piclinfo.accessmode & PICL_VOLATILE) &&
12137c478bd9Sstevel@tonic-gate (pinfo->piclinfo.type != PICL_PTYPE_VOID) &&
12147c478bd9Sstevel@tonic-gate (valbuf == NULL))
12157c478bd9Sstevel@tonic-gate return (PICL_INVALIDARG);
12167c478bd9Sstevel@tonic-gate
12177c478bd9Sstevel@tonic-gate pobj = malloc(sizeof (picl_obj_t));
12187c478bd9Sstevel@tonic-gate if (pobj == NULL)
12197c478bd9Sstevel@tonic-gate return (PICL_FAILURE);
12207c478bd9Sstevel@tonic-gate
12217c478bd9Sstevel@tonic-gate pobj->obj_type = PICL_OBJ_PROP;
12227c478bd9Sstevel@tonic-gate pobj->pinfo_ver = pinfo->version;
12237c478bd9Sstevel@tonic-gate pobj->prop_type = pinfo->piclinfo.type;
12247c478bd9Sstevel@tonic-gate pobj->prop_mode = pinfo->piclinfo.accessmode;
12257c478bd9Sstevel@tonic-gate pobj->prop_size = pinfo->piclinfo.size;
12267c478bd9Sstevel@tonic-gate (void) strcpy(pobj->prop_name, pinfo->piclinfo.name);
12277c478bd9Sstevel@tonic-gate pobj->read_func = pinfo->read;
12287c478bd9Sstevel@tonic-gate pobj->write_func = pinfo->write;
12297c478bd9Sstevel@tonic-gate
12307c478bd9Sstevel@tonic-gate pobj->prop_val = NULL;
12317c478bd9Sstevel@tonic-gate if (!(pinfo->piclinfo.accessmode & PICL_VOLATILE)) {
12327c478bd9Sstevel@tonic-gate pobj->prop_val = malloc(pinfo->piclinfo.size);
12337c478bd9Sstevel@tonic-gate if (pobj->prop_val == NULL) {
12347c478bd9Sstevel@tonic-gate free(pobj);
12357c478bd9Sstevel@tonic-gate return (PICL_FAILURE);
12367c478bd9Sstevel@tonic-gate }
12377c478bd9Sstevel@tonic-gate if (pobj->prop_type == PICL_PTYPE_CHARSTRING)
12387c478bd9Sstevel@tonic-gate (void) strlcpy(pobj->prop_val, valbuf,
12397c478bd9Sstevel@tonic-gate pinfo->piclinfo.size);
12407c478bd9Sstevel@tonic-gate else
12417c478bd9Sstevel@tonic-gate (void) memcpy(pobj->prop_val, valbuf,
12427c478bd9Sstevel@tonic-gate pinfo->piclinfo.size);
12437c478bd9Sstevel@tonic-gate }
12447c478bd9Sstevel@tonic-gate pobj->prop_node = NULL;
12457c478bd9Sstevel@tonic-gate pobj->ptree_hdl = PICL_INVALID_PICLHDL;
12467c478bd9Sstevel@tonic-gate pobj->picl_hdl = PICL_INVALID_PICLHDL;
12477c478bd9Sstevel@tonic-gate pobj->next_prop = NULL;
12487c478bd9Sstevel@tonic-gate pobj->next_row = NULL;
12497c478bd9Sstevel@tonic-gate pobj->next_col = NULL;
12507c478bd9Sstevel@tonic-gate
12517c478bd9Sstevel@tonic-gate *pobjp = pobj;
12527c478bd9Sstevel@tonic-gate return (PICL_SUCCESS);
12537c478bd9Sstevel@tonic-gate }
12547c478bd9Sstevel@tonic-gate
12557c478bd9Sstevel@tonic-gate /*
12567c478bd9Sstevel@tonic-gate * Check for valid arguments, create a property object,
12577c478bd9Sstevel@tonic-gate * Lock ptree_rwlock, add the new property handle, release the lock
12587c478bd9Sstevel@tonic-gate * For reference properties and table properties, the handles are verified
12597c478bd9Sstevel@tonic-gate * before creating the property.
12607c478bd9Sstevel@tonic-gate */
12617c478bd9Sstevel@tonic-gate int
ptree_create_prop(const ptree_propinfo_t * pinfo,const void * valbuf,picl_prophdl_t * proph)12627c478bd9Sstevel@tonic-gate ptree_create_prop(const ptree_propinfo_t *pinfo, const void *valbuf,
12637c478bd9Sstevel@tonic-gate picl_prophdl_t *proph)
12647c478bd9Sstevel@tonic-gate {
12657c478bd9Sstevel@tonic-gate picl_obj_t *pobj;
12667c478bd9Sstevel@tonic-gate picl_nodehdl_t refh;
12677c478bd9Sstevel@tonic-gate picl_prophdl_t tblh;
12687c478bd9Sstevel@tonic-gate int err;
12697c478bd9Sstevel@tonic-gate char *ptr;
12707c478bd9Sstevel@tonic-gate int refflag;
12717c478bd9Sstevel@tonic-gate char classname[PICL_PROPNAMELEN_MAX];
12727c478bd9Sstevel@tonic-gate
12737c478bd9Sstevel@tonic-gate if (pinfo == NULL)
12747c478bd9Sstevel@tonic-gate return (PICL_INVALIDARG);
12757c478bd9Sstevel@tonic-gate if (pinfo->version != PTREE_PROPINFO_VERSION_1)
12767c478bd9Sstevel@tonic-gate return (PICL_NOTSUPPORTED);
12777c478bd9Sstevel@tonic-gate if (pinfo->piclinfo.size >= PICL_PROPSIZE_MAX)
12787c478bd9Sstevel@tonic-gate return (PICL_VALUETOOBIG);
12797c478bd9Sstevel@tonic-gate if (picl_restricted(pinfo->piclinfo.name))
12807c478bd9Sstevel@tonic-gate return (PICL_RESERVEDNAME);
12817c478bd9Sstevel@tonic-gate
12827c478bd9Sstevel@tonic-gate refflag = 0;
12837c478bd9Sstevel@tonic-gate if ((pinfo->piclinfo.name[0] == '_') &&
12847c478bd9Sstevel@tonic-gate (strchr(&pinfo->piclinfo.name[1], '_') != NULL))
12857c478bd9Sstevel@tonic-gate refflag = 1;
12867c478bd9Sstevel@tonic-gate
12877c478bd9Sstevel@tonic-gate if (pinfo->piclinfo.type == PICL_PTYPE_REFERENCE) {
12887c478bd9Sstevel@tonic-gate if (refflag == 0)
12897c478bd9Sstevel@tonic-gate return (PICL_INVREFERENCE);
12907c478bd9Sstevel@tonic-gate /*
12917c478bd9Sstevel@tonic-gate * check valid reference handle for non-volatiles
12927c478bd9Sstevel@tonic-gate */
12937c478bd9Sstevel@tonic-gate if (!(pinfo->piclinfo.accessmode & PICL_VOLATILE)) {
12947c478bd9Sstevel@tonic-gate if (valbuf == NULL)
12957c478bd9Sstevel@tonic-gate return (PICL_INVREFERENCE);
12967c478bd9Sstevel@tonic-gate if (pinfo->piclinfo.size != sizeof (picl_nodehdl_t))
12977c478bd9Sstevel@tonic-gate return (PICL_INVREFERENCE);
12987c478bd9Sstevel@tonic-gate (void) strcpy(classname, pinfo->piclinfo.name);
12997c478bd9Sstevel@tonic-gate ptr = strchr(&classname[1], '_');
13007c478bd9Sstevel@tonic-gate *ptr = '\0';
13017c478bd9Sstevel@tonic-gate refh = *(picl_hdl_t *)valbuf;
13027c478bd9Sstevel@tonic-gate err = check_ref_handle(refh, &classname[1]);
13037c478bd9Sstevel@tonic-gate if (err != PICL_SUCCESS)
13047c478bd9Sstevel@tonic-gate return (err);
13057c478bd9Sstevel@tonic-gate }
13067c478bd9Sstevel@tonic-gate } else if (refflag == 1)
13077c478bd9Sstevel@tonic-gate return (PICL_INVREFERENCE);
13087c478bd9Sstevel@tonic-gate else if ((pinfo->piclinfo.type == PICL_PTYPE_TABLE) &&
13097c478bd9Sstevel@tonic-gate (!(pinfo->piclinfo.accessmode & PICL_VOLATILE))) {
13107c478bd9Sstevel@tonic-gate if (pinfo->piclinfo.size != sizeof (picl_prophdl_t))
13117c478bd9Sstevel@tonic-gate return (PICL_INVALIDARG);
13127c478bd9Sstevel@tonic-gate tblh = *(picl_prophdl_t *)valbuf;
13137c478bd9Sstevel@tonic-gate err = check_table_handle(tblh);
13147c478bd9Sstevel@tonic-gate if (err != PICL_SUCCESS)
13157c478bd9Sstevel@tonic-gate return (err);
13167c478bd9Sstevel@tonic-gate } else if ((strcmp(pinfo->piclinfo.name, PICL_PROP_CLASSNAME) == 0) &&
13177c478bd9Sstevel@tonic-gate ((pinfo->piclinfo.type != PICL_PTYPE_CHARSTRING) ||
13187c478bd9Sstevel@tonic-gate (strlen(valbuf) >= PICL_CLASSNAMELEN_MAX)))
13197c478bd9Sstevel@tonic-gate return (PICL_RESERVEDNAME);
13207c478bd9Sstevel@tonic-gate else if ((strcmp(pinfo->piclinfo.name, PICL_PROP_NAME) == 0) &&
13217c478bd9Sstevel@tonic-gate (pinfo->piclinfo.type != PICL_PTYPE_CHARSTRING))
13227c478bd9Sstevel@tonic-gate return (PICL_RESERVEDNAME);
13237c478bd9Sstevel@tonic-gate /*
13247c478bd9Sstevel@tonic-gate * No locks held when you get here
13257c478bd9Sstevel@tonic-gate */
13267c478bd9Sstevel@tonic-gate err = create_propobj(pinfo, valbuf, &pobj);
13277c478bd9Sstevel@tonic-gate if (err != PICL_SUCCESS)
13287c478bd9Sstevel@tonic-gate return (err);
13297c478bd9Sstevel@tonic-gate
13307c478bd9Sstevel@tonic-gate alloc_and_add_to_ptree(pobj);
13317c478bd9Sstevel@tonic-gate *proph = pobj->ptree_hdl;
13327c478bd9Sstevel@tonic-gate return (PICL_SUCCESS);
13337c478bd9Sstevel@tonic-gate }
13347c478bd9Sstevel@tonic-gate
13357c478bd9Sstevel@tonic-gate /*
13367c478bd9Sstevel@tonic-gate * Lock free routine to destroy table entries
13377c478bd9Sstevel@tonic-gate * This function removes the destroyed handles from the hash table
13387c478bd9Sstevel@tonic-gate * Uses lock free routines: hash_lookup() and hash_remove()
13397c478bd9Sstevel@tonic-gate */
13407c478bd9Sstevel@tonic-gate static void
destroy_table(picl_obj_t * pobj)13417c478bd9Sstevel@tonic-gate destroy_table(picl_obj_t *pobj)
13427c478bd9Sstevel@tonic-gate {
13437c478bd9Sstevel@tonic-gate picl_prophdl_t tblh;
13447c478bd9Sstevel@tonic-gate picl_obj_t *tbl_obj;
13457c478bd9Sstevel@tonic-gate picl_obj_t *rowp;
13467c478bd9Sstevel@tonic-gate picl_obj_t *colp;
13477c478bd9Sstevel@tonic-gate picl_obj_t *freep;
13487c478bd9Sstevel@tonic-gate
13497c478bd9Sstevel@tonic-gate tblh = *(picl_prophdl_t *)pobj->prop_val;
13507c478bd9Sstevel@tonic-gate tbl_obj = hash_lookup_obj(&ptreetbl, tblh);
13517c478bd9Sstevel@tonic-gate if (tbl_obj == NULL)
13527c478bd9Sstevel@tonic-gate return;
13537c478bd9Sstevel@tonic-gate
13547c478bd9Sstevel@tonic-gate assert(tbl_obj->obj_type & PICL_OBJ_TABLE);
13557c478bd9Sstevel@tonic-gate
13567c478bd9Sstevel@tonic-gate /* Delete all entries */
13577c478bd9Sstevel@tonic-gate rowp = tbl_obj->next_row;
13587c478bd9Sstevel@tonic-gate while (rowp != NULL) {
13597c478bd9Sstevel@tonic-gate colp = rowp;
13607c478bd9Sstevel@tonic-gate rowp = rowp->next_col;
13617c478bd9Sstevel@tonic-gate while (colp != NULL) {
13627c478bd9Sstevel@tonic-gate freep = colp;
13637c478bd9Sstevel@tonic-gate colp = colp->next_row;
13647c478bd9Sstevel@tonic-gate (void) hash_remove(&ptreetbl, freep->ptree_hdl);
13657c478bd9Sstevel@tonic-gate if (freep->prop_val)
13667c478bd9Sstevel@tonic-gate free(freep->prop_val);
13677c478bd9Sstevel@tonic-gate free(freep);
13687c478bd9Sstevel@tonic-gate }
13697c478bd9Sstevel@tonic-gate }
13707c478bd9Sstevel@tonic-gate
13717c478bd9Sstevel@tonic-gate (void) hash_remove(&ptreetbl, tbl_obj->ptree_hdl);
13727c478bd9Sstevel@tonic-gate free(tbl_obj);
13737c478bd9Sstevel@tonic-gate }
13747c478bd9Sstevel@tonic-gate
13757c478bd9Sstevel@tonic-gate
13767c478bd9Sstevel@tonic-gate /*
13777c478bd9Sstevel@tonic-gate * Lock free function that frees up a property object and removes the
13787c478bd9Sstevel@tonic-gate * handles from Ptree table
13797c478bd9Sstevel@tonic-gate */
13807c478bd9Sstevel@tonic-gate static void
destroy_propobj(picl_obj_t * propp)13817c478bd9Sstevel@tonic-gate destroy_propobj(picl_obj_t *propp)
13827c478bd9Sstevel@tonic-gate {
13837c478bd9Sstevel@tonic-gate if (propp->prop_type == PICL_PTYPE_TABLE)
13847c478bd9Sstevel@tonic-gate destroy_table(propp);
13857c478bd9Sstevel@tonic-gate
13867c478bd9Sstevel@tonic-gate (void) hash_remove(&ptreetbl, propp->ptree_hdl);
13877c478bd9Sstevel@tonic-gate if (propp->prop_val)
13887c478bd9Sstevel@tonic-gate free(propp->prop_val);
13897c478bd9Sstevel@tonic-gate free(propp);
13907c478bd9Sstevel@tonic-gate }
13917c478bd9Sstevel@tonic-gate
13927c478bd9Sstevel@tonic-gate /*
13937c478bd9Sstevel@tonic-gate * This function destroys a previously deleted property.
13947c478bd9Sstevel@tonic-gate * A deleted property does not have an associated node.
13957c478bd9Sstevel@tonic-gate * All memory allocated for this property are freed
13967c478bd9Sstevel@tonic-gate */
13977c478bd9Sstevel@tonic-gate int
ptree_destroy_prop(picl_prophdl_t proph)13987c478bd9Sstevel@tonic-gate ptree_destroy_prop(picl_prophdl_t proph)
13997c478bd9Sstevel@tonic-gate {
14007c478bd9Sstevel@tonic-gate picl_obj_t *propp;
14017c478bd9Sstevel@tonic-gate
14027c478bd9Sstevel@tonic-gate (void) rw_wrlock(&ptree_rwlock); /* Exclusive Lock ptree */
14037c478bd9Sstevel@tonic-gate
14047c478bd9Sstevel@tonic-gate propp = hash_lookup_obj(&ptreetbl, proph);
14057c478bd9Sstevel@tonic-gate if (propp == NULL) {
14067c478bd9Sstevel@tonic-gate (void) rw_unlock(&ptree_rwlock); /* Unlock ptree */
14077c478bd9Sstevel@tonic-gate return (ptree_hdl_error(proph));
14087c478bd9Sstevel@tonic-gate }
14097c478bd9Sstevel@tonic-gate
14107c478bd9Sstevel@tonic-gate /* Is the prop still attached to a node? */
14117c478bd9Sstevel@tonic-gate if (propp->prop_node != NULL) {
14127c478bd9Sstevel@tonic-gate (void) rw_unlock(&ptree_rwlock); /* Unlock ptree */
14137c478bd9Sstevel@tonic-gate return (PICL_CANTDESTROY);
14147c478bd9Sstevel@tonic-gate }
14157c478bd9Sstevel@tonic-gate
14167c478bd9Sstevel@tonic-gate destroy_propobj(propp);
14177c478bd9Sstevel@tonic-gate
14187c478bd9Sstevel@tonic-gate (void) rw_unlock(&ptree_rwlock); /* Unlock ptree */
14197c478bd9Sstevel@tonic-gate return (PICL_SUCCESS);
14207c478bd9Sstevel@tonic-gate }
14217c478bd9Sstevel@tonic-gate
14227c478bd9Sstevel@tonic-gate /*
14237c478bd9Sstevel@tonic-gate * This function adds a property to the property list of a node and adds
14247c478bd9Sstevel@tonic-gate * it to the PICL table if the node has a PICL handle.
14257c478bd9Sstevel@tonic-gate * This function locks the picl_rwlock and ptree_rwlock.
14267c478bd9Sstevel@tonic-gate */
14277c478bd9Sstevel@tonic-gate int
ptree_add_prop(picl_nodehdl_t nodeh,picl_prophdl_t proph)14287c478bd9Sstevel@tonic-gate ptree_add_prop(picl_nodehdl_t nodeh, picl_prophdl_t proph)
14297c478bd9Sstevel@tonic-gate {
14307c478bd9Sstevel@tonic-gate int err;
14317c478bd9Sstevel@tonic-gate picl_obj_t *nodep;
14327c478bd9Sstevel@tonic-gate picl_obj_t *propp;
14337c478bd9Sstevel@tonic-gate picl_obj_t *tbl_obj;
14347c478bd9Sstevel@tonic-gate picl_obj_t *refobj;
14357c478bd9Sstevel@tonic-gate
14367c478bd9Sstevel@tonic-gate (void) rw_rdlock(&ptree_rwlock); /* RDLock ptree */
14377c478bd9Sstevel@tonic-gate
14387c478bd9Sstevel@tonic-gate /*
14397c478bd9Sstevel@tonic-gate * Verify property handle
14407c478bd9Sstevel@tonic-gate */
14417c478bd9Sstevel@tonic-gate err = lookup_verify_prop_handle(proph, &propp);
14427c478bd9Sstevel@tonic-gate if (err != PICL_SUCCESS) {
14437c478bd9Sstevel@tonic-gate (void) rw_unlock(&ptree_rwlock); /* Unlock ptree */
14447c478bd9Sstevel@tonic-gate return (err);
14457c478bd9Sstevel@tonic-gate }
14467c478bd9Sstevel@tonic-gate
14477c478bd9Sstevel@tonic-gate if (propp->prop_node != NULL) {
14487c478bd9Sstevel@tonic-gate (void) rw_unlock(&ptree_rwlock);
14497c478bd9Sstevel@tonic-gate return (PICL_INVALIDARG);
14507c478bd9Sstevel@tonic-gate }
14517c478bd9Sstevel@tonic-gate
14527c478bd9Sstevel@tonic-gate nodep = NULL;
14537c478bd9Sstevel@tonic-gate /*
14547c478bd9Sstevel@tonic-gate * Exclusive Lock the node's properties
14557c478bd9Sstevel@tonic-gate */
14567c478bd9Sstevel@tonic-gate err = lookup_and_lock_node(WRLOCK_NODE, nodeh, &nodep);
14577c478bd9Sstevel@tonic-gate if (err != PICL_SUCCESS) {
14587c478bd9Sstevel@tonic-gate (void) rw_unlock(&ptree_rwlock); /* Unlock ptree */
14597c478bd9Sstevel@tonic-gate return (err);
14607c478bd9Sstevel@tonic-gate }
14617c478bd9Sstevel@tonic-gate
14627c478bd9Sstevel@tonic-gate /*
14637c478bd9Sstevel@tonic-gate * check if prop already exists
14647c478bd9Sstevel@tonic-gate */
14657c478bd9Sstevel@tonic-gate err = lookup_prop_by_name(nodep, propp->prop_name, NULL);
14667c478bd9Sstevel@tonic-gate if (err == PICL_SUCCESS) {
14677c478bd9Sstevel@tonic-gate unlock_node(nodep); /* Unlock node */
14687c478bd9Sstevel@tonic-gate (void) rw_unlock(&ptree_rwlock); /* Unlock table */
14697c478bd9Sstevel@tonic-gate return (PICL_PROPEXISTS);
14707c478bd9Sstevel@tonic-gate }
14717c478bd9Sstevel@tonic-gate
14727c478bd9Sstevel@tonic-gate /*
14737c478bd9Sstevel@tonic-gate * Verify property's value
14747c478bd9Sstevel@tonic-gate */
14757c478bd9Sstevel@tonic-gate tbl_obj = NULL;
14767c478bd9Sstevel@tonic-gate switch (propp->prop_type) {
14777c478bd9Sstevel@tonic-gate case PICL_PTYPE_TABLE:
14787c478bd9Sstevel@tonic-gate if (propp->prop_mode & PICL_VOLATILE)
14797c478bd9Sstevel@tonic-gate break;
14807c478bd9Sstevel@tonic-gate err = lookup_verify_table_prop(propp, &tbl_obj);
14817c478bd9Sstevel@tonic-gate if (err != PICL_SUCCESS) {
14827c478bd9Sstevel@tonic-gate unlock_node(nodep);
14837c478bd9Sstevel@tonic-gate (void) rw_unlock(&ptree_rwlock);
14847c478bd9Sstevel@tonic-gate return (err);
14857c478bd9Sstevel@tonic-gate }
14867c478bd9Sstevel@tonic-gate tbl_obj->prop_node = nodep; /* set table's nodep */
14877c478bd9Sstevel@tonic-gate tbl_obj->table_prop = propp; /* set table prop */
14887c478bd9Sstevel@tonic-gate break;
14897c478bd9Sstevel@tonic-gate case PICL_PTYPE_REFERENCE:
14907c478bd9Sstevel@tonic-gate if (propp->prop_mode & PICL_VOLATILE)
14917c478bd9Sstevel@tonic-gate break;
14927c478bd9Sstevel@tonic-gate err = lookup_verify_ref_prop(propp, &refobj);
14937c478bd9Sstevel@tonic-gate if (err != PICL_SUCCESS) {
14947c478bd9Sstevel@tonic-gate unlock_node(nodep);
14957c478bd9Sstevel@tonic-gate (void) rw_unlock(&ptree_rwlock);
14967c478bd9Sstevel@tonic-gate return (err);
14977c478bd9Sstevel@tonic-gate }
14987c478bd9Sstevel@tonic-gate if (IS_PICLIZED(nodep) && !IS_PICLIZED(refobj)) {
14997c478bd9Sstevel@tonic-gate unlock_node(nodep);
15007c478bd9Sstevel@tonic-gate (void) rw_unlock(&ptree_rwlock);
15017c478bd9Sstevel@tonic-gate return (err);
15027c478bd9Sstevel@tonic-gate }
15037c478bd9Sstevel@tonic-gate break;
15047c478bd9Sstevel@tonic-gate default:
15057c478bd9Sstevel@tonic-gate break;
15067c478bd9Sstevel@tonic-gate }
15077c478bd9Sstevel@tonic-gate
15087c478bd9Sstevel@tonic-gate if (IS_PICLIZED(nodep))
15097c478bd9Sstevel@tonic-gate piclize_prop(propp);
15107c478bd9Sstevel@tonic-gate /*
15117c478bd9Sstevel@tonic-gate * Add prop to beginning of list
15127c478bd9Sstevel@tonic-gate */
15137c478bd9Sstevel@tonic-gate propp->prop_node = nodep; /* set prop's nodep */
15147c478bd9Sstevel@tonic-gate propp->next_prop = nodep->first_prop;
15157c478bd9Sstevel@tonic-gate nodep->first_prop = propp;
15167c478bd9Sstevel@tonic-gate
15177c478bd9Sstevel@tonic-gate unlock_node(nodep); /* Unlock node */
15187c478bd9Sstevel@tonic-gate (void) rw_unlock(&ptree_rwlock); /* Unlock table */
15197c478bd9Sstevel@tonic-gate return (PICL_SUCCESS);
15207c478bd9Sstevel@tonic-gate }
15217c478bd9Sstevel@tonic-gate
15227c478bd9Sstevel@tonic-gate /*
15237c478bd9Sstevel@tonic-gate * Lock free function that unlinks a property from its node
15247c478bd9Sstevel@tonic-gate */
15257c478bd9Sstevel@tonic-gate static int
unlink_prop(picl_obj_t * nodep,picl_obj_t * propp)15267c478bd9Sstevel@tonic-gate unlink_prop(picl_obj_t *nodep, picl_obj_t *propp)
15277c478bd9Sstevel@tonic-gate {
15287c478bd9Sstevel@tonic-gate picl_obj_t *iterp;
15297c478bd9Sstevel@tonic-gate
15307c478bd9Sstevel@tonic-gate iterp = nodep->first_prop;
15317c478bd9Sstevel@tonic-gate if (iterp == propp) { /* first property */
15327c478bd9Sstevel@tonic-gate nodep->first_prop = iterp->next_prop;
15337c478bd9Sstevel@tonic-gate return (PICL_SUCCESS);
15347c478bd9Sstevel@tonic-gate }
15357c478bd9Sstevel@tonic-gate while ((iterp != NULL) && (iterp->next_prop != propp))
15367c478bd9Sstevel@tonic-gate iterp = iterp->next_prop;
15377c478bd9Sstevel@tonic-gate if (iterp == NULL)
15387c478bd9Sstevel@tonic-gate return (PICL_PROPNOTFOUND);
15397c478bd9Sstevel@tonic-gate iterp->next_prop = propp->next_prop;
15407c478bd9Sstevel@tonic-gate return (PICL_SUCCESS);
15417c478bd9Sstevel@tonic-gate }
15427c478bd9Sstevel@tonic-gate
15437c478bd9Sstevel@tonic-gate /*
15447c478bd9Sstevel@tonic-gate * This function deletes the specified property from the property list
15457c478bd9Sstevel@tonic-gate * of its node and removes the handle from PICL table, if the node
15467c478bd9Sstevel@tonic-gate * was piclized.
15477c478bd9Sstevel@tonic-gate */
15487c478bd9Sstevel@tonic-gate int
ptree_delete_prop(picl_prophdl_t proph)15497c478bd9Sstevel@tonic-gate ptree_delete_prop(picl_prophdl_t proph)
15507c478bd9Sstevel@tonic-gate {
15517c478bd9Sstevel@tonic-gate int err;
15527c478bd9Sstevel@tonic-gate picl_obj_t *nodep;
15537c478bd9Sstevel@tonic-gate picl_obj_t *propp;
15547c478bd9Sstevel@tonic-gate
15557c478bd9Sstevel@tonic-gate (void) rw_rdlock(&ptree_rwlock); /* lock ptree */
15567c478bd9Sstevel@tonic-gate /*
15577c478bd9Sstevel@tonic-gate * Lookup the property's node and lock it if there is one
15587c478bd9Sstevel@tonic-gate * return the objects for the property and the node
15597c478bd9Sstevel@tonic-gate */
15607c478bd9Sstevel@tonic-gate nodep = propp = NULL;
15617c478bd9Sstevel@tonic-gate err = lookup_and_lock_propnode(WRLOCK_NODE, proph, &nodep, &propp);
15627c478bd9Sstevel@tonic-gate if (err != PICL_SUCCESS) {
15637c478bd9Sstevel@tonic-gate (void) rw_unlock(&ptree_rwlock); /* unlock ptree */
15647c478bd9Sstevel@tonic-gate return (err);
15657c478bd9Sstevel@tonic-gate } else if (nodep == NULL) {
15667c478bd9Sstevel@tonic-gate /* Nothing to do - already deleted! */
15677c478bd9Sstevel@tonic-gate (void) rw_unlock(&ptree_rwlock); /* unlock ptree */
15687c478bd9Sstevel@tonic-gate return (PICL_SUCCESS);
15697c478bd9Sstevel@tonic-gate }
15707c478bd9Sstevel@tonic-gate
15717c478bd9Sstevel@tonic-gate if (propp->obj_type & PICL_OBJ_TABLEENTRY) {
15727c478bd9Sstevel@tonic-gate unlock_node(nodep); /* Unlock node */
15737c478bd9Sstevel@tonic-gate (void) rw_unlock(&ptree_rwlock); /* unlock ptree */
15747c478bd9Sstevel@tonic-gate return (PICL_NOTPROP);
15757c478bd9Sstevel@tonic-gate }
15767c478bd9Sstevel@tonic-gate
15777c478bd9Sstevel@tonic-gate err = unlink_prop(nodep, propp);
15787c478bd9Sstevel@tonic-gate if (err != PICL_SUCCESS) {
15797c478bd9Sstevel@tonic-gate unlock_node(nodep); /* Unlock node */
15807c478bd9Sstevel@tonic-gate (void) rw_unlock(&ptree_rwlock); /* unlock ptree */
15817c478bd9Sstevel@tonic-gate return (err);
15827c478bd9Sstevel@tonic-gate }
15837c478bd9Sstevel@tonic-gate
15847c478bd9Sstevel@tonic-gate propp->prop_node = NULL; /* reset prop's nodep */
15857c478bd9Sstevel@tonic-gate propp->next_prop = NULL;
15867c478bd9Sstevel@tonic-gate
15877c478bd9Sstevel@tonic-gate unpiclize_prop(propp);
15887c478bd9Sstevel@tonic-gate
15897c478bd9Sstevel@tonic-gate unlock_node(nodep); /* Unlock node */
15907c478bd9Sstevel@tonic-gate (void) rw_unlock(&ptree_rwlock); /* unlock ptree */
15917c478bd9Sstevel@tonic-gate return (PICL_SUCCESS);
15927c478bd9Sstevel@tonic-gate }
15937c478bd9Sstevel@tonic-gate
15947c478bd9Sstevel@tonic-gate /*
15957c478bd9Sstevel@tonic-gate * Create a table object and return its handle
15967c478bd9Sstevel@tonic-gate */
15977c478bd9Sstevel@tonic-gate int
ptree_create_table(picl_prophdl_t * tblh)15987c478bd9Sstevel@tonic-gate ptree_create_table(picl_prophdl_t *tblh)
15997c478bd9Sstevel@tonic-gate {
16007c478bd9Sstevel@tonic-gate picl_obj_t *pobj;
16017c478bd9Sstevel@tonic-gate
16027c478bd9Sstevel@tonic-gate pobj = malloc(sizeof (picl_obj_t));
16037c478bd9Sstevel@tonic-gate if (pobj == NULL)
16047c478bd9Sstevel@tonic-gate return (PICL_FAILURE);
16057c478bd9Sstevel@tonic-gate pobj->obj_type = PICL_OBJ_TABLE;
16067c478bd9Sstevel@tonic-gate pobj->prop_val = NULL;
16077c478bd9Sstevel@tonic-gate pobj->prop_node = NULL;
16087c478bd9Sstevel@tonic-gate pobj->ptree_hdl = PICL_INVALID_PICLHDL;
16097c478bd9Sstevel@tonic-gate pobj->picl_hdl = PICL_INVALID_PICLHDL;
16107c478bd9Sstevel@tonic-gate pobj->table_prop = NULL;
16117c478bd9Sstevel@tonic-gate pobj->next_row = NULL;
16127c478bd9Sstevel@tonic-gate pobj->next_col = NULL;
16137c478bd9Sstevel@tonic-gate
16147c478bd9Sstevel@tonic-gate alloc_and_add_to_ptree(pobj);
16157c478bd9Sstevel@tonic-gate *tblh = pobj->ptree_hdl;
16167c478bd9Sstevel@tonic-gate return (PICL_SUCCESS);
16177c478bd9Sstevel@tonic-gate }
16187c478bd9Sstevel@tonic-gate
16197c478bd9Sstevel@tonic-gate /*
16207c478bd9Sstevel@tonic-gate * Add the properties in <props> array as a row in the table
16217c478bd9Sstevel@tonic-gate * Add PICL handles if the table has a valid PICL handle
16227c478bd9Sstevel@tonic-gate */
16237c478bd9Sstevel@tonic-gate int
ptree_add_row_to_table(picl_prophdl_t tblh,int nprops,const picl_prophdl_t * props)16247c478bd9Sstevel@tonic-gate ptree_add_row_to_table(picl_prophdl_t tblh, int nprops,
16257c478bd9Sstevel@tonic-gate const picl_prophdl_t *props)
16267c478bd9Sstevel@tonic-gate {
16277c478bd9Sstevel@tonic-gate picl_obj_t *tbl_obj;
16287c478bd9Sstevel@tonic-gate picl_obj_t *nodep;
16297c478bd9Sstevel@tonic-gate picl_obj_t *lastrow;
16307c478bd9Sstevel@tonic-gate picl_obj_t **newrow;
16317c478bd9Sstevel@tonic-gate int i;
16327c478bd9Sstevel@tonic-gate int err;
16337c478bd9Sstevel@tonic-gate picl_obj_t *pobj;
16347c478bd9Sstevel@tonic-gate int picl_it;
16357c478bd9Sstevel@tonic-gate
16367c478bd9Sstevel@tonic-gate if (nprops < 1)
16377c478bd9Sstevel@tonic-gate return (PICL_INVALIDARG);
16387c478bd9Sstevel@tonic-gate
16397c478bd9Sstevel@tonic-gate newrow = malloc(sizeof (picl_obj_t *) * nprops);
16407c478bd9Sstevel@tonic-gate if (newrow == NULL)
16417c478bd9Sstevel@tonic-gate return (PICL_FAILURE);
16427c478bd9Sstevel@tonic-gate
16437c478bd9Sstevel@tonic-gate (void) rw_rdlock(&ptree_rwlock); /* Lock ptree */
16447c478bd9Sstevel@tonic-gate
16457c478bd9Sstevel@tonic-gate err = lookup_and_lock_tablenode(WRLOCK_NODE, tblh, &nodep, &tbl_obj);
16467c478bd9Sstevel@tonic-gate if (err != PICL_SUCCESS) {
16477c478bd9Sstevel@tonic-gate free(newrow);
16487c478bd9Sstevel@tonic-gate (void) rw_unlock(&ptree_rwlock); /* Unlock table */
16497c478bd9Sstevel@tonic-gate return (err);
16507c478bd9Sstevel@tonic-gate }
16517c478bd9Sstevel@tonic-gate
16527c478bd9Sstevel@tonic-gate /*
16537c478bd9Sstevel@tonic-gate * make sure all are either props or table handles
16547c478bd9Sstevel@tonic-gate */
16557c478bd9Sstevel@tonic-gate for (i = 0; i < nprops; ++i) {
16567c478bd9Sstevel@tonic-gate pobj = newrow[i] = hash_lookup_obj(&ptreetbl, props[i]);
16577c478bd9Sstevel@tonic-gate if (pobj == NULL) { /* no object */
16587c478bd9Sstevel@tonic-gate err = ptree_hdl_error(props[i]);
16597c478bd9Sstevel@tonic-gate break;
16607c478bd9Sstevel@tonic-gate }
16617c478bd9Sstevel@tonic-gate if ((!(pobj->obj_type & PICL_OBJ_PROP)) &&
16627c478bd9Sstevel@tonic-gate (!(pobj->obj_type & PICL_OBJ_TABLE))) {
16637c478bd9Sstevel@tonic-gate err = PICL_NOTPROP;
16647c478bd9Sstevel@tonic-gate break;
16657c478bd9Sstevel@tonic-gate }
16667c478bd9Sstevel@tonic-gate if (IS_PICLIZED(pobj) || (pobj->prop_table != NULL) ||
16677c478bd9Sstevel@tonic-gate (pobj->prop_node != NULL)) {
16687c478bd9Sstevel@tonic-gate err = PICL_INVALIDARG;
16697c478bd9Sstevel@tonic-gate break;
16707c478bd9Sstevel@tonic-gate }
16717c478bd9Sstevel@tonic-gate
16727c478bd9Sstevel@tonic-gate }
16737c478bd9Sstevel@tonic-gate if (err != PICL_SUCCESS) {
16747c478bd9Sstevel@tonic-gate free(newrow);
16757c478bd9Sstevel@tonic-gate unlock_node(nodep);
16767c478bd9Sstevel@tonic-gate (void) rw_unlock(&ptree_rwlock); /* Unlock table */
16777c478bd9Sstevel@tonic-gate return (err);
16787c478bd9Sstevel@tonic-gate }
16797c478bd9Sstevel@tonic-gate
16807c478bd9Sstevel@tonic-gate /*
16817c478bd9Sstevel@tonic-gate * Mark all props as table entries, set up row linkages
16827c478bd9Sstevel@tonic-gate */
16837c478bd9Sstevel@tonic-gate picl_it = 0;
16847c478bd9Sstevel@tonic-gate if (IS_PICLIZED(tbl_obj))
16857c478bd9Sstevel@tonic-gate picl_it = 1;
16867c478bd9Sstevel@tonic-gate for (i = 0; i < nprops; ++i) {
16877c478bd9Sstevel@tonic-gate newrow[i]->obj_type |= PICL_OBJ_TABLEENTRY;
16887c478bd9Sstevel@tonic-gate newrow[i]->prop_table = tbl_obj;
16897c478bd9Sstevel@tonic-gate newrow[i]->next_prop = NULL;
16907c478bd9Sstevel@tonic-gate newrow[i]->next_col = NULL;
16917c478bd9Sstevel@tonic-gate if (picl_it)
16927c478bd9Sstevel@tonic-gate piclize_obj(newrow[i]);
16937c478bd9Sstevel@tonic-gate if (i != nprops - 1)
16947c478bd9Sstevel@tonic-gate newrow[i]->next_row = newrow[i+1];
16957c478bd9Sstevel@tonic-gate }
16967c478bd9Sstevel@tonic-gate newrow[nprops - 1]->next_row = NULL;
16977c478bd9Sstevel@tonic-gate
16987c478bd9Sstevel@tonic-gate if (tbl_obj->next_row == NULL) { /* add first row */
16997c478bd9Sstevel@tonic-gate tbl_obj->next_row = newrow[0];
17007c478bd9Sstevel@tonic-gate tbl_obj->next_col = newrow[0];
17017c478bd9Sstevel@tonic-gate } else {
17027c478bd9Sstevel@tonic-gate lastrow = tbl_obj->next_row;
17037c478bd9Sstevel@tonic-gate while (lastrow->next_col != NULL)
17047c478bd9Sstevel@tonic-gate lastrow = lastrow->next_col;
17057c478bd9Sstevel@tonic-gate i = 0;
17067c478bd9Sstevel@tonic-gate while (lastrow != NULL) {
17077c478bd9Sstevel@tonic-gate lastrow->next_col = newrow[i];
17087c478bd9Sstevel@tonic-gate lastrow = lastrow->next_row;
17097c478bd9Sstevel@tonic-gate ++i;
17107c478bd9Sstevel@tonic-gate }
17117c478bd9Sstevel@tonic-gate }
17127c478bd9Sstevel@tonic-gate
17137c478bd9Sstevel@tonic-gate unlock_node(nodep); /* unlock node */
17147c478bd9Sstevel@tonic-gate (void) rw_unlock(&ptree_rwlock); /* Unlock ptree */
17157c478bd9Sstevel@tonic-gate free(newrow);
17167c478bd9Sstevel@tonic-gate return (PICL_SUCCESS);
17177c478bd9Sstevel@tonic-gate }
17187c478bd9Sstevel@tonic-gate
17197c478bd9Sstevel@tonic-gate /*
17207c478bd9Sstevel@tonic-gate * This function returns the handle of the next property in the row
17217c478bd9Sstevel@tonic-gate */
17227c478bd9Sstevel@tonic-gate int
ptree_get_next_by_row(picl_prophdl_t proph,picl_prophdl_t * nextrowh)17237c478bd9Sstevel@tonic-gate ptree_get_next_by_row(picl_prophdl_t proph, picl_prophdl_t *nextrowh)
17247c478bd9Sstevel@tonic-gate {
17257c478bd9Sstevel@tonic-gate int err;
17267c478bd9Sstevel@tonic-gate picl_obj_t *nodep;
17277c478bd9Sstevel@tonic-gate picl_obj_t *propp;
17287c478bd9Sstevel@tonic-gate
17297c478bd9Sstevel@tonic-gate (void) rw_rdlock(&ptree_rwlock); /* lock ptree */
17307c478bd9Sstevel@tonic-gate
17317c478bd9Sstevel@tonic-gate nodep = propp = NULL;
17327c478bd9Sstevel@tonic-gate /*
17337c478bd9Sstevel@tonic-gate * proph could be a table handle or a table entry handle
17347c478bd9Sstevel@tonic-gate * Look it up as a table entry handle first, check error code
17357c478bd9Sstevel@tonic-gate * to see if it is a table handle
17367c478bd9Sstevel@tonic-gate */
17377c478bd9Sstevel@tonic-gate err = lookup_and_lock_tableprop_node(RDLOCK_NODE, proph, &nodep,
17387c478bd9Sstevel@tonic-gate &propp);
17397c478bd9Sstevel@tonic-gate if (err != PICL_SUCCESS) {
17407c478bd9Sstevel@tonic-gate (void) rw_unlock(&ptree_rwlock);
17417c478bd9Sstevel@tonic-gate return (err);
17427c478bd9Sstevel@tonic-gate }
17437c478bd9Sstevel@tonic-gate
17447c478bd9Sstevel@tonic-gate if (propp->next_row)
17457c478bd9Sstevel@tonic-gate *nextrowh = propp->next_row->ptree_hdl;
17467c478bd9Sstevel@tonic-gate else
17477c478bd9Sstevel@tonic-gate err = PICL_ENDOFLIST;
17487c478bd9Sstevel@tonic-gate
17497c478bd9Sstevel@tonic-gate unlock_node(nodep); /* unlock node */
17507c478bd9Sstevel@tonic-gate (void) rw_unlock(&ptree_rwlock); /* unlock ptree */
17517c478bd9Sstevel@tonic-gate return (err);
17527c478bd9Sstevel@tonic-gate }
17537c478bd9Sstevel@tonic-gate
17547c478bd9Sstevel@tonic-gate int
ptree_get_next_by_col(picl_prophdl_t proph,picl_prophdl_t * nextcolh)17557c478bd9Sstevel@tonic-gate ptree_get_next_by_col(picl_prophdl_t proph, picl_prophdl_t *nextcolh)
17567c478bd9Sstevel@tonic-gate {
17577c478bd9Sstevel@tonic-gate int err;
17587c478bd9Sstevel@tonic-gate picl_obj_t *propp;
17597c478bd9Sstevel@tonic-gate picl_obj_t *nodep;
17607c478bd9Sstevel@tonic-gate
17617c478bd9Sstevel@tonic-gate (void) rw_rdlock(&ptree_rwlock); /* lock ptree */
17627c478bd9Sstevel@tonic-gate nodep = propp = NULL;
17637c478bd9Sstevel@tonic-gate /*
17647c478bd9Sstevel@tonic-gate * proph could be a table handle or a table entry handle
17657c478bd9Sstevel@tonic-gate * Look it up as a table entry handle first, check error code
17667c478bd9Sstevel@tonic-gate * to see if it is a table handle
17677c478bd9Sstevel@tonic-gate */
17687c478bd9Sstevel@tonic-gate err = lookup_and_lock_tableprop_node(RDLOCK_NODE, proph, &nodep,
17697c478bd9Sstevel@tonic-gate &propp);
17707c478bd9Sstevel@tonic-gate if (err != PICL_SUCCESS) {
17717c478bd9Sstevel@tonic-gate (void) rw_unlock(&ptree_rwlock);
17727c478bd9Sstevel@tonic-gate return (err);
17737c478bd9Sstevel@tonic-gate }
17747c478bd9Sstevel@tonic-gate
17757c478bd9Sstevel@tonic-gate if (propp->next_col)
17767c478bd9Sstevel@tonic-gate *nextcolh = propp->next_col->ptree_hdl;
17777c478bd9Sstevel@tonic-gate else
17787c478bd9Sstevel@tonic-gate err = PICL_ENDOFLIST;
17797c478bd9Sstevel@tonic-gate
17807c478bd9Sstevel@tonic-gate unlock_node(nodep); /* unlock node */
17817c478bd9Sstevel@tonic-gate (void) rw_unlock(&ptree_rwlock); /* unlock ptree */
17827c478bd9Sstevel@tonic-gate return (err);
17837c478bd9Sstevel@tonic-gate }
17847c478bd9Sstevel@tonic-gate
17857c478bd9Sstevel@tonic-gate /*
17867c478bd9Sstevel@tonic-gate * This function creates node object and adds its handle to the Ptree
17877c478bd9Sstevel@tonic-gate */
17887c478bd9Sstevel@tonic-gate int
ptree_create_node(const char * name,const char * clname,picl_nodehdl_t * nodeh)17897c478bd9Sstevel@tonic-gate ptree_create_node(const char *name, const char *clname, picl_nodehdl_t *nodeh)
17907c478bd9Sstevel@tonic-gate {
17917c478bd9Sstevel@tonic-gate picl_obj_t *pobj;
17927c478bd9Sstevel@tonic-gate ptree_propinfo_t propinfo;
17937c478bd9Sstevel@tonic-gate picl_prophdl_t phdl;
17947c478bd9Sstevel@tonic-gate picl_prophdl_t cphdl;
17957c478bd9Sstevel@tonic-gate int err;
17967c478bd9Sstevel@tonic-gate
17977c478bd9Sstevel@tonic-gate if ((name == NULL) || (*name == '\0') ||
17987c478bd9Sstevel@tonic-gate (clname == NULL) || (*clname == '\0'))
17997c478bd9Sstevel@tonic-gate return (PICL_INVALIDARG);
18007c478bd9Sstevel@tonic-gate
18017c478bd9Sstevel@tonic-gate if ((strlen(name) >= PICL_PROPNAMELEN_MAX) ||
18027c478bd9Sstevel@tonic-gate (strlen(clname) >= PICL_CLASSNAMELEN_MAX))
18037c478bd9Sstevel@tonic-gate return (PICL_VALUETOOBIG);
18047c478bd9Sstevel@tonic-gate
18057c478bd9Sstevel@tonic-gate /*
18067c478bd9Sstevel@tonic-gate * Create the picl object for node
18077c478bd9Sstevel@tonic-gate */
18087c478bd9Sstevel@tonic-gate pobj = malloc(sizeof (picl_obj_t));
18097c478bd9Sstevel@tonic-gate if (pobj == NULL)
18107c478bd9Sstevel@tonic-gate return (PICL_FAILURE);
18117c478bd9Sstevel@tonic-gate pobj->obj_type = PICL_OBJ_NODE;
18127c478bd9Sstevel@tonic-gate pobj->first_prop = NULL;
18137c478bd9Sstevel@tonic-gate pobj->ptree_hdl = PICL_INVALID_PICLHDL;
18147c478bd9Sstevel@tonic-gate pobj->picl_hdl = PICL_INVALID_PICLHDL;
18157c478bd9Sstevel@tonic-gate pobj->parent_node = NULL;
18167c478bd9Sstevel@tonic-gate pobj->sibling_node = NULL;
18177c478bd9Sstevel@tonic-gate pobj->child_node = NULL;
18187c478bd9Sstevel@tonic-gate pobj->node_classname = strdup(clname);
18197c478bd9Sstevel@tonic-gate if (pobj->node_classname == NULL) {
18207c478bd9Sstevel@tonic-gate free(pobj);
18217c478bd9Sstevel@tonic-gate return (PICL_FAILURE);
18227c478bd9Sstevel@tonic-gate }
18237c478bd9Sstevel@tonic-gate (void) rwlock_init(&pobj->node_lock, USYNC_THREAD, NULL);
18247c478bd9Sstevel@tonic-gate
18257c478bd9Sstevel@tonic-gate alloc_and_add_to_ptree(pobj); /* commit the node */
18267c478bd9Sstevel@tonic-gate
18277c478bd9Sstevel@tonic-gate /*
18287c478bd9Sstevel@tonic-gate * create name property
18297c478bd9Sstevel@tonic-gate */
18307c478bd9Sstevel@tonic-gate propinfo.version = PTREE_PROPINFO_VERSION_1;
18317c478bd9Sstevel@tonic-gate propinfo.piclinfo.type = PICL_PTYPE_CHARSTRING;
18327c478bd9Sstevel@tonic-gate propinfo.piclinfo.accessmode = PICL_READ;
18337c478bd9Sstevel@tonic-gate propinfo.piclinfo.size = strlen(name) + 1;
18347c478bd9Sstevel@tonic-gate (void) strcpy(propinfo.piclinfo.name, PICL_PROP_NAME);
18357c478bd9Sstevel@tonic-gate propinfo.read = NULL;
18367c478bd9Sstevel@tonic-gate propinfo.write = NULL;
18377c478bd9Sstevel@tonic-gate err = ptree_create_prop(&propinfo, (const void *)name, &phdl);
18387c478bd9Sstevel@tonic-gate if (err != PICL_SUCCESS) {
18397c478bd9Sstevel@tonic-gate (void) ptree_destroy_node(pobj->ptree_hdl);
18407c478bd9Sstevel@tonic-gate return (err);
18417c478bd9Sstevel@tonic-gate }
18427c478bd9Sstevel@tonic-gate err = ptree_add_prop(pobj->ptree_hdl, phdl);
18437c478bd9Sstevel@tonic-gate if (err != PICL_SUCCESS) {
18447c478bd9Sstevel@tonic-gate (void) ptree_destroy_prop(phdl);
18457c478bd9Sstevel@tonic-gate (void) ptree_destroy_node(pobj->ptree_hdl);
18467c478bd9Sstevel@tonic-gate return (err);
18477c478bd9Sstevel@tonic-gate }
18487c478bd9Sstevel@tonic-gate
18497c478bd9Sstevel@tonic-gate /*
18507c478bd9Sstevel@tonic-gate * create picl classname property
18517c478bd9Sstevel@tonic-gate */
18527c478bd9Sstevel@tonic-gate propinfo.piclinfo.size = strlen(clname) + 1;
18537c478bd9Sstevel@tonic-gate (void) strcpy(propinfo.piclinfo.name, PICL_PROP_CLASSNAME);
18547c478bd9Sstevel@tonic-gate propinfo.read = NULL;
18557c478bd9Sstevel@tonic-gate propinfo.write = NULL;
18567c478bd9Sstevel@tonic-gate err = ptree_create_prop(&propinfo, (const void *)clname, &cphdl);
18577c478bd9Sstevel@tonic-gate if (err != PICL_SUCCESS) {
18587c478bd9Sstevel@tonic-gate (void) ptree_destroy_node(pobj->ptree_hdl);
18597c478bd9Sstevel@tonic-gate return (err);
18607c478bd9Sstevel@tonic-gate }
18617c478bd9Sstevel@tonic-gate err = ptree_add_prop(pobj->ptree_hdl, cphdl);
18627c478bd9Sstevel@tonic-gate if (err != PICL_SUCCESS) {
18637c478bd9Sstevel@tonic-gate (void) ptree_destroy_prop(cphdl);
18647c478bd9Sstevel@tonic-gate (void) ptree_destroy_node(pobj->ptree_hdl);
18657c478bd9Sstevel@tonic-gate return (err);
18667c478bd9Sstevel@tonic-gate }
18677c478bd9Sstevel@tonic-gate
18687c478bd9Sstevel@tonic-gate *nodeh = pobj->ptree_hdl;
18697c478bd9Sstevel@tonic-gate return (PICL_SUCCESS);
18707c478bd9Sstevel@tonic-gate }
18717c478bd9Sstevel@tonic-gate
18727c478bd9Sstevel@tonic-gate /*
18737c478bd9Sstevel@tonic-gate * Destroy a node/subtree freeing up space
18747c478bd9Sstevel@tonic-gate * Removed destroyed objects' handles from PTree table
18757c478bd9Sstevel@tonic-gate */
18767c478bd9Sstevel@tonic-gate static void
destroy_subtree(picl_obj_t * nodep)18777c478bd9Sstevel@tonic-gate destroy_subtree(picl_obj_t *nodep)
18787c478bd9Sstevel@tonic-gate {
18797c478bd9Sstevel@tonic-gate picl_obj_t *iterp;
18807c478bd9Sstevel@tonic-gate picl_obj_t *freep;
18817c478bd9Sstevel@tonic-gate picl_obj_t *chdp;
18827c478bd9Sstevel@tonic-gate
18837c478bd9Sstevel@tonic-gate if (nodep == NULL)
18847c478bd9Sstevel@tonic-gate return;
18857c478bd9Sstevel@tonic-gate
18867c478bd9Sstevel@tonic-gate chdp = nodep->child_node;
18877c478bd9Sstevel@tonic-gate while (chdp != NULL) {
18887c478bd9Sstevel@tonic-gate freep = chdp;
18897c478bd9Sstevel@tonic-gate chdp = chdp->sibling_node;
18907c478bd9Sstevel@tonic-gate destroy_subtree(freep);
18917c478bd9Sstevel@tonic-gate }
18927c478bd9Sstevel@tonic-gate
18937c478bd9Sstevel@tonic-gate /*
18947c478bd9Sstevel@tonic-gate * Lock the node
18957c478bd9Sstevel@tonic-gate */
18967c478bd9Sstevel@tonic-gate (void) lock_obj(WRLOCK_NODE, nodep);
18977c478bd9Sstevel@tonic-gate
18987c478bd9Sstevel@tonic-gate /*
18997c478bd9Sstevel@tonic-gate * destroy all properties associated with this node
19007c478bd9Sstevel@tonic-gate */
19017c478bd9Sstevel@tonic-gate iterp = nodep->first_prop;
19027c478bd9Sstevel@tonic-gate while (iterp != NULL) {
19037c478bd9Sstevel@tonic-gate freep = iterp;
19047c478bd9Sstevel@tonic-gate iterp = iterp->next_prop;
19057c478bd9Sstevel@tonic-gate destroy_propobj(freep);
19067c478bd9Sstevel@tonic-gate }
19077c478bd9Sstevel@tonic-gate
19087c478bd9Sstevel@tonic-gate (void) hash_remove(&ptreetbl, nodep->ptree_hdl);
19097c478bd9Sstevel@tonic-gate (void) rwlock_destroy(&nodep->node_lock);
19107c478bd9Sstevel@tonic-gate free(nodep->node_classname);
19117c478bd9Sstevel@tonic-gate free(nodep);
19127c478bd9Sstevel@tonic-gate }
19137c478bd9Sstevel@tonic-gate
19147c478bd9Sstevel@tonic-gate /*
19157c478bd9Sstevel@tonic-gate * This function destroys a previously deleted node/subtree. All the properties
19167c478bd9Sstevel@tonic-gate * are freed and removed from the PTree table.
19177c478bd9Sstevel@tonic-gate * Only one destroy is in progress at any time.
19187c478bd9Sstevel@tonic-gate */
19197c478bd9Sstevel@tonic-gate int
ptree_destroy_node(picl_nodehdl_t nodeh)19207c478bd9Sstevel@tonic-gate ptree_destroy_node(picl_nodehdl_t nodeh)
19217c478bd9Sstevel@tonic-gate {
19227c478bd9Sstevel@tonic-gate picl_obj_t *nodep;
19237c478bd9Sstevel@tonic-gate picl_obj_t *parp;
19247c478bd9Sstevel@tonic-gate picl_obj_t *np;
19257c478bd9Sstevel@tonic-gate int err;
19267c478bd9Sstevel@tonic-gate
19277c478bd9Sstevel@tonic-gate (void) rw_wrlock(&ptree_rwlock); /* exclusive wrlock ptree */
19287c478bd9Sstevel@tonic-gate nodep = NULL;
19297c478bd9Sstevel@tonic-gate err = lookup_verify_node_handle(nodeh, &nodep);
19307c478bd9Sstevel@tonic-gate if (err != PICL_SUCCESS) {
19317c478bd9Sstevel@tonic-gate (void) rw_unlock(&ptree_rwlock); /* unlock ptree */
19327c478bd9Sstevel@tonic-gate return (err);
19337c478bd9Sstevel@tonic-gate }
19347c478bd9Sstevel@tonic-gate
19357c478bd9Sstevel@tonic-gate /*
19367c478bd9Sstevel@tonic-gate * Has this node/subtree been deleted?
19377c478bd9Sstevel@tonic-gate */
19387c478bd9Sstevel@tonic-gate if (IS_PICLIZED(nodep)) {
19397c478bd9Sstevel@tonic-gate (void) rw_unlock(&ptree_rwlock); /* unlock ptree */
19407c478bd9Sstevel@tonic-gate return (PICL_CANTDESTROY);
19417c478bd9Sstevel@tonic-gate }
19427c478bd9Sstevel@tonic-gate
19437c478bd9Sstevel@tonic-gate /*
19447c478bd9Sstevel@tonic-gate * update parent's child list to repair the tree when
19457c478bd9Sstevel@tonic-gate * parent is not null
19467c478bd9Sstevel@tonic-gate */
19477c478bd9Sstevel@tonic-gate parp = nodep->parent_node;
19487c478bd9Sstevel@tonic-gate if (parp == NULL) { /* root */
19497c478bd9Sstevel@tonic-gate destroy_subtree(nodep);
19507c478bd9Sstevel@tonic-gate (void) rw_unlock(&ptree_rwlock); /* unlock ptree */
19517c478bd9Sstevel@tonic-gate return (PICL_SUCCESS);
19527c478bd9Sstevel@tonic-gate }
19537c478bd9Sstevel@tonic-gate
19547c478bd9Sstevel@tonic-gate np = parp->child_node;
19557c478bd9Sstevel@tonic-gate if (np == nodep) { /* first child */
19567c478bd9Sstevel@tonic-gate parp->child_node = nodep->sibling_node;
19577c478bd9Sstevel@tonic-gate } else {
19587c478bd9Sstevel@tonic-gate while ((np != NULL) && (np->sibling_node != nodep))
19597c478bd9Sstevel@tonic-gate np = np->sibling_node;
19607c478bd9Sstevel@tonic-gate if (np != NULL)
19617c478bd9Sstevel@tonic-gate np->sibling_node = nodep->sibling_node;
19627c478bd9Sstevel@tonic-gate }
19637c478bd9Sstevel@tonic-gate
19647c478bd9Sstevel@tonic-gate destroy_subtree(nodep);
19657c478bd9Sstevel@tonic-gate (void) rw_unlock(&ptree_rwlock); /* unlock ptree */
19667c478bd9Sstevel@tonic-gate return (PICL_SUCCESS);
19677c478bd9Sstevel@tonic-gate }
19687c478bd9Sstevel@tonic-gate
19697c478bd9Sstevel@tonic-gate /*
19707c478bd9Sstevel@tonic-gate * This function deletes a node/subtree from the tree and removes the handles
19717c478bd9Sstevel@tonic-gate * from PICL table
19727c478bd9Sstevel@tonic-gate */
19737c478bd9Sstevel@tonic-gate int
ptree_delete_node(picl_nodehdl_t nodeh)19747c478bd9Sstevel@tonic-gate ptree_delete_node(picl_nodehdl_t nodeh)
19757c478bd9Sstevel@tonic-gate {
19767c478bd9Sstevel@tonic-gate picl_obj_t *nodep;
19777c478bd9Sstevel@tonic-gate picl_obj_t *parp;
19787c478bd9Sstevel@tonic-gate picl_obj_t *np;
19797c478bd9Sstevel@tonic-gate int err;
19807c478bd9Sstevel@tonic-gate
19817c478bd9Sstevel@tonic-gate (void) rw_wrlock(&ptree_rwlock); /* exclusive wrlock ptree */
19827c478bd9Sstevel@tonic-gate
19837c478bd9Sstevel@tonic-gate nodep = NULL;
19847c478bd9Sstevel@tonic-gate err = lookup_verify_node_handle(nodeh, &nodep);
19857c478bd9Sstevel@tonic-gate if (err != PICL_SUCCESS) {
19867c478bd9Sstevel@tonic-gate (void) rw_unlock(&ptree_rwlock); /* unlock ptree */
19877c478bd9Sstevel@tonic-gate return (err);
19887c478bd9Sstevel@tonic-gate }
19897c478bd9Sstevel@tonic-gate
19907c478bd9Sstevel@tonic-gate /*
19917c478bd9Sstevel@tonic-gate * unparent it
19927c478bd9Sstevel@tonic-gate */
19937c478bd9Sstevel@tonic-gate parp = nodep->parent_node;
19947c478bd9Sstevel@tonic-gate if (parp != NULL) {
19957c478bd9Sstevel@tonic-gate np = parp->child_node;
19967c478bd9Sstevel@tonic-gate if (np == nodep) /* first child */
19977c478bd9Sstevel@tonic-gate parp->child_node = nodep->sibling_node;
19987c478bd9Sstevel@tonic-gate else {
19997c478bd9Sstevel@tonic-gate while ((np != NULL) && (np->sibling_node != nodep))
20007c478bd9Sstevel@tonic-gate np = np->sibling_node;
20017c478bd9Sstevel@tonic-gate if (np != NULL)
20027c478bd9Sstevel@tonic-gate np->sibling_node = nodep->sibling_node;
20037c478bd9Sstevel@tonic-gate }
20047c478bd9Sstevel@tonic-gate }
20057c478bd9Sstevel@tonic-gate
20067c478bd9Sstevel@tonic-gate nodep->parent_node = NULL;
20077c478bd9Sstevel@tonic-gate nodep->sibling_node = NULL;
20087c478bd9Sstevel@tonic-gate
20097c478bd9Sstevel@tonic-gate unpiclize_node(nodep);
20107c478bd9Sstevel@tonic-gate
20117c478bd9Sstevel@tonic-gate (void) rw_unlock(&ptree_rwlock); /* unlock ptree */
20127c478bd9Sstevel@tonic-gate return (PICL_SUCCESS);
20137c478bd9Sstevel@tonic-gate }
20147c478bd9Sstevel@tonic-gate
20157c478bd9Sstevel@tonic-gate /*
20167c478bd9Sstevel@tonic-gate * This function adds a node as a child of another node
20177c478bd9Sstevel@tonic-gate */
20187c478bd9Sstevel@tonic-gate int
ptree_add_node(picl_nodehdl_t parh,picl_nodehdl_t chdh)20197c478bd9Sstevel@tonic-gate ptree_add_node(picl_nodehdl_t parh, picl_nodehdl_t chdh)
20207c478bd9Sstevel@tonic-gate {
20217c478bd9Sstevel@tonic-gate picl_obj_t *pnodep;
20227c478bd9Sstevel@tonic-gate picl_obj_t *cnodep;
20237c478bd9Sstevel@tonic-gate picl_obj_t *nodep;
20247c478bd9Sstevel@tonic-gate int err;
20257c478bd9Sstevel@tonic-gate
20267c478bd9Sstevel@tonic-gate (void) rw_wrlock(&ptree_rwlock); /* exclusive lock ptree */
20277c478bd9Sstevel@tonic-gate
20287c478bd9Sstevel@tonic-gate pnodep = cnodep = NULL;
20297c478bd9Sstevel@tonic-gate err = lookup_verify_node_handle(parh, &pnodep);
20307c478bd9Sstevel@tonic-gate if (err != PICL_SUCCESS) {
20317c478bd9Sstevel@tonic-gate (void) rw_unlock(&ptree_rwlock); /* unlock ptree */
20327c478bd9Sstevel@tonic-gate return (err);
20337c478bd9Sstevel@tonic-gate }
20347c478bd9Sstevel@tonic-gate
20357c478bd9Sstevel@tonic-gate err = lookup_verify_node_handle(chdh, &cnodep);
20367c478bd9Sstevel@tonic-gate if (err != PICL_SUCCESS) {
20377c478bd9Sstevel@tonic-gate (void) rw_unlock(&ptree_rwlock); /* unlock ptree */
20387c478bd9Sstevel@tonic-gate return (err);
20397c478bd9Sstevel@tonic-gate }
20407c478bd9Sstevel@tonic-gate
20417c478bd9Sstevel@tonic-gate /* is chdh already a child? */
20427c478bd9Sstevel@tonic-gate if (cnodep->parent_node != NULL) {
20437c478bd9Sstevel@tonic-gate (void) rw_unlock(&ptree_rwlock); /* unlock ptree */
20447c478bd9Sstevel@tonic-gate return (PICL_CANTPARENT);
20457c478bd9Sstevel@tonic-gate }
20467c478bd9Sstevel@tonic-gate
20477c478bd9Sstevel@tonic-gate /*
20487c478bd9Sstevel@tonic-gate * append child to children list
20497c478bd9Sstevel@tonic-gate */
20507c478bd9Sstevel@tonic-gate cnodep->parent_node = pnodep;
20517c478bd9Sstevel@tonic-gate if (pnodep->child_node == NULL)
20527c478bd9Sstevel@tonic-gate pnodep->child_node = cnodep;
20537c478bd9Sstevel@tonic-gate else {
20547c478bd9Sstevel@tonic-gate for (nodep = pnodep->child_node; nodep->sibling_node != NULL;
20557c478bd9Sstevel@tonic-gate nodep = nodep->sibling_node)
20567c478bd9Sstevel@tonic-gate continue;
20577c478bd9Sstevel@tonic-gate nodep->sibling_node = cnodep;
20587c478bd9Sstevel@tonic-gate
20597c478bd9Sstevel@tonic-gate }
20607c478bd9Sstevel@tonic-gate
20617c478bd9Sstevel@tonic-gate /* piclize */
20627c478bd9Sstevel@tonic-gate if (IS_PICLIZED(pnodep))
20637c478bd9Sstevel@tonic-gate piclize_node(cnodep);
20647c478bd9Sstevel@tonic-gate (void) rw_unlock(&ptree_rwlock); /* unlock ptree */
20657c478bd9Sstevel@tonic-gate return (PICL_SUCCESS);
20667c478bd9Sstevel@tonic-gate }
20677c478bd9Sstevel@tonic-gate
20687c478bd9Sstevel@tonic-gate static void
copy_propinfo_ver_1(ptree_propinfo_t * pinfo,picl_obj_t * propp)20697c478bd9Sstevel@tonic-gate copy_propinfo_ver_1(ptree_propinfo_t *pinfo, picl_obj_t *propp)
20707c478bd9Sstevel@tonic-gate {
20717c478bd9Sstevel@tonic-gate pinfo->version = propp->pinfo_ver;
20727c478bd9Sstevel@tonic-gate pinfo->piclinfo.type = propp->prop_type;
20737c478bd9Sstevel@tonic-gate pinfo->piclinfo.accessmode = propp->prop_mode;
20747c478bd9Sstevel@tonic-gate pinfo->piclinfo.size = propp->prop_size;
20757c478bd9Sstevel@tonic-gate (void) strcpy(pinfo->piclinfo.name, propp->prop_name);
20767c478bd9Sstevel@tonic-gate pinfo->read = propp->read_func;
20777c478bd9Sstevel@tonic-gate pinfo->write = propp->write_func;
20787c478bd9Sstevel@tonic-gate }
20797c478bd9Sstevel@tonic-gate
20807c478bd9Sstevel@tonic-gate static void
copy_reserved_propinfo_ver_1(ptree_propinfo_t * pinfo,const char * pname)20817c478bd9Sstevel@tonic-gate copy_reserved_propinfo_ver_1(ptree_propinfo_t *pinfo, const char *pname)
20827c478bd9Sstevel@tonic-gate {
20837c478bd9Sstevel@tonic-gate pinfo->version = PTREE_PROPINFO_VERSION_1;
20847c478bd9Sstevel@tonic-gate pinfo->piclinfo.type = PICL_PTYPE_REFERENCE;
20857c478bd9Sstevel@tonic-gate pinfo->piclinfo.accessmode = PICL_READ;
20867c478bd9Sstevel@tonic-gate pinfo->piclinfo.size = sizeof (picl_nodehdl_t);
20877c478bd9Sstevel@tonic-gate (void) strcpy(pinfo->piclinfo.name, pname);
20887c478bd9Sstevel@tonic-gate pinfo->read = NULL;
20897c478bd9Sstevel@tonic-gate pinfo->write = NULL;
20907c478bd9Sstevel@tonic-gate }
20917c478bd9Sstevel@tonic-gate
20927c478bd9Sstevel@tonic-gate /*
20937c478bd9Sstevel@tonic-gate * This function returns the property information to a plug-in
20947c478bd9Sstevel@tonic-gate */
20957c478bd9Sstevel@tonic-gate int
ptree_get_propinfo(picl_prophdl_t proph,ptree_propinfo_t * pinfo)20967c478bd9Sstevel@tonic-gate ptree_get_propinfo(picl_prophdl_t proph, ptree_propinfo_t *pinfo)
20977c478bd9Sstevel@tonic-gate {
20987c478bd9Sstevel@tonic-gate int err;
20997c478bd9Sstevel@tonic-gate picl_obj_t *nodep;
21007c478bd9Sstevel@tonic-gate picl_obj_t *propp;
21017c478bd9Sstevel@tonic-gate
21027c478bd9Sstevel@tonic-gate (void) rw_rdlock(&ptree_rwlock); /* lock ptree */
21037c478bd9Sstevel@tonic-gate nodep = propp = NULL;
21047c478bd9Sstevel@tonic-gate err = lookup_and_lock_propnode(RDLOCK_NODE, proph, &nodep, &propp);
21057c478bd9Sstevel@tonic-gate if (err != PICL_SUCCESS) {
21067c478bd9Sstevel@tonic-gate (void) rw_unlock(&ptree_rwlock); /* unlock ptree */
21077c478bd9Sstevel@tonic-gate return (err);
21087c478bd9Sstevel@tonic-gate }
21097c478bd9Sstevel@tonic-gate
21107c478bd9Sstevel@tonic-gate if (propp->pinfo_ver == PTREE_PROPINFO_VERSION_1)
21117c478bd9Sstevel@tonic-gate copy_propinfo_ver_1(pinfo, propp);
21127c478bd9Sstevel@tonic-gate else
21137c478bd9Sstevel@tonic-gate err = PICL_FAILURE;
21147c478bd9Sstevel@tonic-gate
21157c478bd9Sstevel@tonic-gate unlock_node(nodep); /* unlock node */
21167c478bd9Sstevel@tonic-gate (void) rw_unlock(&ptree_rwlock); /* unlock ptree */
21177c478bd9Sstevel@tonic-gate return (err);
21187c478bd9Sstevel@tonic-gate }
21197c478bd9Sstevel@tonic-gate
21207c478bd9Sstevel@tonic-gate /*
21217c478bd9Sstevel@tonic-gate * This function returns the property information to a plug-in
21227c478bd9Sstevel@tonic-gate */
21237c478bd9Sstevel@tonic-gate int
xptree_get_propinfo_by_name(picl_nodehdl_t nodeh,const char * pname,ptree_propinfo_t * pinfo)21247c478bd9Sstevel@tonic-gate xptree_get_propinfo_by_name(picl_nodehdl_t nodeh, const char *pname,
21257c478bd9Sstevel@tonic-gate ptree_propinfo_t *pinfo)
21267c478bd9Sstevel@tonic-gate {
21277c478bd9Sstevel@tonic-gate int err;
21287c478bd9Sstevel@tonic-gate picl_obj_t *nodep;
21297c478bd9Sstevel@tonic-gate picl_obj_t *propp;
21307c478bd9Sstevel@tonic-gate
21317c478bd9Sstevel@tonic-gate (void) rw_rdlock(&ptree_rwlock); /* lock ptree */
21327c478bd9Sstevel@tonic-gate nodep = propp = NULL;
21337c478bd9Sstevel@tonic-gate err = lookup_and_lock_node(RDLOCK_NODE, nodeh, &nodep); /* lock node */
21347c478bd9Sstevel@tonic-gate if (err != PICL_SUCCESS) {
21357c478bd9Sstevel@tonic-gate (void) rw_unlock(&ptree_rwlock); /* unlock ptree */
21367c478bd9Sstevel@tonic-gate return (err);
21377c478bd9Sstevel@tonic-gate }
21387c478bd9Sstevel@tonic-gate
21397c478bd9Sstevel@tonic-gate err = lookup_prop_by_name(nodep, pname, &propp);
21407c478bd9Sstevel@tonic-gate if (err != PICL_SUCCESS) {
21417c478bd9Sstevel@tonic-gate unlock_node(nodep);
21427c478bd9Sstevel@tonic-gate (void) rw_unlock(&ptree_rwlock);
21437c478bd9Sstevel@tonic-gate return (err);
21447c478bd9Sstevel@tonic-gate }
21457c478bd9Sstevel@tonic-gate
21467c478bd9Sstevel@tonic-gate if (picl_restricted(pname))
21477c478bd9Sstevel@tonic-gate copy_reserved_propinfo_ver_1(pinfo, pname);
21487c478bd9Sstevel@tonic-gate else if (propp->pinfo_ver == PTREE_PROPINFO_VERSION_1)
21497c478bd9Sstevel@tonic-gate copy_propinfo_ver_1(pinfo, propp);
21507c478bd9Sstevel@tonic-gate else
21517c478bd9Sstevel@tonic-gate err = PICL_FAILURE;
21527c478bd9Sstevel@tonic-gate
21537c478bd9Sstevel@tonic-gate unlock_node(nodep); /* unlock node */
21547c478bd9Sstevel@tonic-gate (void) rw_unlock(&ptree_rwlock); /* unlock ptree */
21557c478bd9Sstevel@tonic-gate return (err);
21567c478bd9Sstevel@tonic-gate }
21577c478bd9Sstevel@tonic-gate
21587c478bd9Sstevel@tonic-gate /*
21597c478bd9Sstevel@tonic-gate * This function must be called only after a lookup_prop_by_name() returns
21607c478bd9Sstevel@tonic-gate * success and only if picl_restricted() returns true.
21617c478bd9Sstevel@tonic-gate */
21627c478bd9Sstevel@tonic-gate static int
read_reserved_propval_and_unlock(picl_obj_t * nodep,const char * pname,void * vbuf,size_t size)21637c478bd9Sstevel@tonic-gate read_reserved_propval_and_unlock(picl_obj_t *nodep, const char *pname,
21647c478bd9Sstevel@tonic-gate void *vbuf, size_t size)
21657c478bd9Sstevel@tonic-gate {
21667c478bd9Sstevel@tonic-gate void *srcp;
21677c478bd9Sstevel@tonic-gate
21687c478bd9Sstevel@tonic-gate if (size != sizeof (picl_nodehdl_t))
21697c478bd9Sstevel@tonic-gate return (PICL_VALUETOOBIG);
21707c478bd9Sstevel@tonic-gate
21717c478bd9Sstevel@tonic-gate if (strcmp(pname, PICL_PROP_PARENT) == 0)
21727c478bd9Sstevel@tonic-gate srcp = &nodep->parent_node->ptree_hdl;
21737c478bd9Sstevel@tonic-gate else if (strcmp(pname, PICL_PROP_CHILD) == 0)
21747c478bd9Sstevel@tonic-gate srcp = &nodep->child_node->ptree_hdl;
21757c478bd9Sstevel@tonic-gate else if (strcmp(pname, PICL_PROP_PEER) == 0)
21767c478bd9Sstevel@tonic-gate srcp = &nodep->sibling_node->ptree_hdl;
21777c478bd9Sstevel@tonic-gate else
21787c478bd9Sstevel@tonic-gate return (PICL_FAILURE);
21797c478bd9Sstevel@tonic-gate
21807c478bd9Sstevel@tonic-gate (void) memcpy(vbuf, srcp, sizeof (picl_nodehdl_t));
21817c478bd9Sstevel@tonic-gate unlock_node(nodep);
21827c478bd9Sstevel@tonic-gate (void) rw_unlock(&ptree_rwlock);
21837c478bd9Sstevel@tonic-gate return (PICL_SUCCESS);
21847c478bd9Sstevel@tonic-gate }
21857c478bd9Sstevel@tonic-gate
21867c478bd9Sstevel@tonic-gate /*
21877c478bd9Sstevel@tonic-gate * Returns the property value in the buffer and releases the node and
21887c478bd9Sstevel@tonic-gate * ptree locks.
21897c478bd9Sstevel@tonic-gate * For volatile properties, this function releases the locks on ptree
21907c478bd9Sstevel@tonic-gate * table and the node before calling the plug-in provided access function
21917c478bd9Sstevel@tonic-gate */
21927c478bd9Sstevel@tonic-gate static int
read_propval_and_unlock(picl_obj_t * nodep,picl_obj_t * propp,void * vbuf,door_cred_t cred)21937c478bd9Sstevel@tonic-gate read_propval_and_unlock(picl_obj_t *nodep, picl_obj_t *propp, void *vbuf,
21947c478bd9Sstevel@tonic-gate door_cred_t cred)
21957c478bd9Sstevel@tonic-gate {
21967c478bd9Sstevel@tonic-gate int err;
21977c478bd9Sstevel@tonic-gate int (*volrd)(ptree_rarg_t *arg, void *buf);
21987c478bd9Sstevel@tonic-gate
21997c478bd9Sstevel@tonic-gate err = PICL_SUCCESS;
22007c478bd9Sstevel@tonic-gate if (propp->prop_mode & PICL_VOLATILE) {
22017c478bd9Sstevel@tonic-gate ptree_rarg_t rarg;
22027c478bd9Sstevel@tonic-gate
22037c478bd9Sstevel@tonic-gate if (nodep)
22047c478bd9Sstevel@tonic-gate rarg.nodeh = nodep->ptree_hdl;
22057c478bd9Sstevel@tonic-gate else
22067c478bd9Sstevel@tonic-gate rarg.nodeh = PICL_INVALID_PICLHDL;
22077c478bd9Sstevel@tonic-gate rarg.proph = propp->ptree_hdl;
22087c478bd9Sstevel@tonic-gate rarg.cred = cred;
22097c478bd9Sstevel@tonic-gate volrd = propp->read_func;
22107c478bd9Sstevel@tonic-gate
22117c478bd9Sstevel@tonic-gate unlock_node(nodep); /* unlock node */
22127c478bd9Sstevel@tonic-gate (void) rw_unlock(&ptree_rwlock); /* unlock ptree */
22137c478bd9Sstevel@tonic-gate
22147c478bd9Sstevel@tonic-gate if (volrd == NULL)
22157c478bd9Sstevel@tonic-gate err = PICL_FAILURE;
22167c478bd9Sstevel@tonic-gate else
22177c478bd9Sstevel@tonic-gate err = (volrd)(&rarg, vbuf);
22187c478bd9Sstevel@tonic-gate return (err);
22197c478bd9Sstevel@tonic-gate } else if (propp->prop_type == PICL_PTYPE_CHARSTRING)
22207c478bd9Sstevel@tonic-gate (void) strlcpy(vbuf, propp->prop_val, propp->prop_size);
22217c478bd9Sstevel@tonic-gate else
22227c478bd9Sstevel@tonic-gate (void) memcpy(vbuf, propp->prop_val, propp->prop_size);
22237c478bd9Sstevel@tonic-gate
22247c478bd9Sstevel@tonic-gate unlock_node(nodep);
22257c478bd9Sstevel@tonic-gate (void) rw_unlock(&ptree_rwlock);
22267c478bd9Sstevel@tonic-gate return (err);
22277c478bd9Sstevel@tonic-gate }
22287c478bd9Sstevel@tonic-gate
22297c478bd9Sstevel@tonic-gate int
xptree_get_propval_with_cred(picl_prophdl_t proph,void * vbuf,size_t size,door_cred_t cred)22307c478bd9Sstevel@tonic-gate xptree_get_propval_with_cred(picl_prophdl_t proph, void *vbuf, size_t size,
22317c478bd9Sstevel@tonic-gate door_cred_t cred)
22327c478bd9Sstevel@tonic-gate {
22337c478bd9Sstevel@tonic-gate picl_obj_t *propp;
22347c478bd9Sstevel@tonic-gate picl_obj_t *nodep;
22357c478bd9Sstevel@tonic-gate int err;
22367c478bd9Sstevel@tonic-gate
22377c478bd9Sstevel@tonic-gate (void) rw_rdlock(&ptree_rwlock); /* lock ptree */
22387c478bd9Sstevel@tonic-gate nodep = propp = NULL;
22397c478bd9Sstevel@tonic-gate err = lookup_and_lock_propnode(RDLOCK_NODE, proph, &nodep, &propp);
22407c478bd9Sstevel@tonic-gate if (err != PICL_SUCCESS) {
22417c478bd9Sstevel@tonic-gate (void) rw_unlock(&ptree_rwlock); /* unlock ptree */
22427c478bd9Sstevel@tonic-gate return (err);
22437c478bd9Sstevel@tonic-gate }
22447c478bd9Sstevel@tonic-gate
22457c478bd9Sstevel@tonic-gate err = check_propsize(PROP_READ, propp, size);
22467c478bd9Sstevel@tonic-gate if (err != PICL_SUCCESS) {
22477c478bd9Sstevel@tonic-gate unlock_node(nodep); /* unlock node */
22487c478bd9Sstevel@tonic-gate (void) rw_unlock(&ptree_rwlock); /* unlock ptree */
22497c478bd9Sstevel@tonic-gate return (err);
22507c478bd9Sstevel@tonic-gate }
22517c478bd9Sstevel@tonic-gate
22527c478bd9Sstevel@tonic-gate return (read_propval_and_unlock(nodep, propp, vbuf, cred));
22537c478bd9Sstevel@tonic-gate }
22547c478bd9Sstevel@tonic-gate
22557c478bd9Sstevel@tonic-gate /*
22567c478bd9Sstevel@tonic-gate * This function gets the credentials and calls get_propval_with_cred.
22577c478bd9Sstevel@tonic-gate */
22587c478bd9Sstevel@tonic-gate int
ptree_get_propval(picl_prophdl_t proph,void * vbuf,size_t size)22597c478bd9Sstevel@tonic-gate ptree_get_propval(picl_prophdl_t proph, void *vbuf, size_t size)
22607c478bd9Sstevel@tonic-gate {
22617c478bd9Sstevel@tonic-gate return (xptree_get_propval_with_cred(proph, vbuf, size, picld_cred));
22627c478bd9Sstevel@tonic-gate }
22637c478bd9Sstevel@tonic-gate
22647c478bd9Sstevel@tonic-gate /*
22657c478bd9Sstevel@tonic-gate * This function retrieves a property's value by by its name
22667c478bd9Sstevel@tonic-gate * For volatile properties, the locks on ptree and node are released
22677c478bd9Sstevel@tonic-gate * before calling the plug-in provided access function
22687c478bd9Sstevel@tonic-gate */
22697c478bd9Sstevel@tonic-gate int
xptree_get_propval_by_name_with_cred(picl_nodehdl_t nodeh,const char * pname,void * vbuf,size_t size,door_cred_t cred)22707c478bd9Sstevel@tonic-gate xptree_get_propval_by_name_with_cred(picl_nodehdl_t nodeh, const char *pname,
22717c478bd9Sstevel@tonic-gate void *vbuf, size_t size, door_cred_t cred)
22727c478bd9Sstevel@tonic-gate {
22737c478bd9Sstevel@tonic-gate picl_obj_t *nodep;
22747c478bd9Sstevel@tonic-gate picl_obj_t *propp;
22757c478bd9Sstevel@tonic-gate int err;
22767c478bd9Sstevel@tonic-gate
22777c478bd9Sstevel@tonic-gate (void) rw_rdlock(&ptree_rwlock); /* lock ptree */
22787c478bd9Sstevel@tonic-gate
22797c478bd9Sstevel@tonic-gate nodep = NULL;
22807c478bd9Sstevel@tonic-gate err = lookup_and_lock_node(RDLOCK_NODE, nodeh, &nodep); /* lock node */
22817c478bd9Sstevel@tonic-gate if (err != PICL_SUCCESS) {
22827c478bd9Sstevel@tonic-gate (void) rw_unlock(&ptree_rwlock); /* unlock ptree */
22837c478bd9Sstevel@tonic-gate return (err);
22847c478bd9Sstevel@tonic-gate }
22857c478bd9Sstevel@tonic-gate
22867c478bd9Sstevel@tonic-gate err = lookup_prop_by_name(nodep, pname, &propp);
22877c478bd9Sstevel@tonic-gate if (err != PICL_SUCCESS) {
22887c478bd9Sstevel@tonic-gate unlock_node(nodep);
22897c478bd9Sstevel@tonic-gate (void) rw_unlock(&ptree_rwlock);
22907c478bd9Sstevel@tonic-gate return (err);
22917c478bd9Sstevel@tonic-gate }
22927c478bd9Sstevel@tonic-gate
22937c478bd9Sstevel@tonic-gate if (picl_restricted(pname))
22947c478bd9Sstevel@tonic-gate return (read_reserved_propval_and_unlock(nodep, pname, vbuf,
22957c478bd9Sstevel@tonic-gate size));
22967c478bd9Sstevel@tonic-gate
22977c478bd9Sstevel@tonic-gate err = check_propsize(PROP_READ, propp, size);
22987c478bd9Sstevel@tonic-gate if (err != PICL_SUCCESS) {
22997c478bd9Sstevel@tonic-gate unlock_node(nodep);
23007c478bd9Sstevel@tonic-gate (void) rw_unlock(&ptree_rwlock);
23017c478bd9Sstevel@tonic-gate return (err);
23027c478bd9Sstevel@tonic-gate }
23037c478bd9Sstevel@tonic-gate
23047c478bd9Sstevel@tonic-gate return (read_propval_and_unlock(nodep, propp, vbuf, cred));
23057c478bd9Sstevel@tonic-gate }
23067c478bd9Sstevel@tonic-gate
23077c478bd9Sstevel@tonic-gate /*
23087c478bd9Sstevel@tonic-gate * This function is used by plugins to get a value of a property
23097c478bd9Sstevel@tonic-gate * looking it up by its name.
23107c478bd9Sstevel@tonic-gate */
23117c478bd9Sstevel@tonic-gate int
ptree_get_propval_by_name(picl_nodehdl_t nodeh,const char * pname,void * vbuf,size_t size)23127c478bd9Sstevel@tonic-gate ptree_get_propval_by_name(picl_nodehdl_t nodeh, const char *pname, void *vbuf,
23137c478bd9Sstevel@tonic-gate size_t size)
23147c478bd9Sstevel@tonic-gate {
23157c478bd9Sstevel@tonic-gate return (xptree_get_propval_by_name_with_cred(nodeh, pname, vbuf, size,
23167c478bd9Sstevel@tonic-gate picld_cred));
23177c478bd9Sstevel@tonic-gate }
23187c478bd9Sstevel@tonic-gate
23197c478bd9Sstevel@tonic-gate /*
23207c478bd9Sstevel@tonic-gate * This function updates a property's value.
23217c478bd9Sstevel@tonic-gate * For volatile properties, the locks on the node and the ptree table
23227c478bd9Sstevel@tonic-gate * are released before calling the plug-in provided access function.
23237c478bd9Sstevel@tonic-gate */
23247c478bd9Sstevel@tonic-gate static int
write_propval_and_unlock(picl_obj_t * nodep,picl_obj_t * propp,const void * vbuf,size_t size,door_cred_t cred)23257c478bd9Sstevel@tonic-gate write_propval_and_unlock(picl_obj_t *nodep, picl_obj_t *propp, const void *vbuf,
23267c478bd9Sstevel@tonic-gate size_t size, door_cred_t cred)
23277c478bd9Sstevel@tonic-gate {
23287c478bd9Sstevel@tonic-gate int err;
23297c478bd9Sstevel@tonic-gate int (*volwr)(ptree_warg_t *arg, const void *buf);
23307c478bd9Sstevel@tonic-gate
23317c478bd9Sstevel@tonic-gate err = PICL_SUCCESS;
23327c478bd9Sstevel@tonic-gate if (propp->prop_mode & PICL_VOLATILE) {
23337c478bd9Sstevel@tonic-gate ptree_warg_t warg;
23347c478bd9Sstevel@tonic-gate
23357c478bd9Sstevel@tonic-gate if (nodep)
23367c478bd9Sstevel@tonic-gate warg.nodeh = nodep->ptree_hdl;
23377c478bd9Sstevel@tonic-gate else
23387c478bd9Sstevel@tonic-gate warg.nodeh = PICL_INVALID_PICLHDL;
23397c478bd9Sstevel@tonic-gate warg.proph = propp->ptree_hdl;
23407c478bd9Sstevel@tonic-gate warg.cred = cred;
23417c478bd9Sstevel@tonic-gate volwr = propp->write_func;
23427c478bd9Sstevel@tonic-gate
23437c478bd9Sstevel@tonic-gate unlock_node(nodep); /* unlock node */
23447c478bd9Sstevel@tonic-gate (void) rw_unlock(&ptree_rwlock); /* unlock ptree */
23457c478bd9Sstevel@tonic-gate
23467c478bd9Sstevel@tonic-gate if (volwr == NULL)
23477c478bd9Sstevel@tonic-gate err = PICL_FAILURE;
23487c478bd9Sstevel@tonic-gate else
23497c478bd9Sstevel@tonic-gate err = (volwr)(&warg, vbuf);
23507c478bd9Sstevel@tonic-gate return (err);
23517c478bd9Sstevel@tonic-gate } else
23527c478bd9Sstevel@tonic-gate (void) memcpy(propp->prop_val, vbuf, size);
23537c478bd9Sstevel@tonic-gate
23547c478bd9Sstevel@tonic-gate unlock_node(nodep); /* unlock node */
23557c478bd9Sstevel@tonic-gate (void) rw_unlock(&ptree_rwlock); /* unlock ptree */
23567c478bd9Sstevel@tonic-gate return (err);
23577c478bd9Sstevel@tonic-gate }
23587c478bd9Sstevel@tonic-gate
23597c478bd9Sstevel@tonic-gate int
xptree_update_propval_with_cred(picl_prophdl_t proph,const void * vbuf,size_t size,door_cred_t cred)23607c478bd9Sstevel@tonic-gate xptree_update_propval_with_cred(picl_prophdl_t proph, const void *vbuf,
23617c478bd9Sstevel@tonic-gate size_t size, door_cred_t cred)
23627c478bd9Sstevel@tonic-gate {
23637c478bd9Sstevel@tonic-gate picl_obj_t *nodep;
23647c478bd9Sstevel@tonic-gate picl_obj_t *propp;
23657c478bd9Sstevel@tonic-gate int err;
23667c478bd9Sstevel@tonic-gate
23677c478bd9Sstevel@tonic-gate (void) rw_rdlock(&ptree_rwlock); /* lock ptree */
23687c478bd9Sstevel@tonic-gate nodep = propp = NULL;
23697c478bd9Sstevel@tonic-gate err = lookup_and_lock_propnode(WRLOCK_NODE, proph, &nodep, &propp);
23707c478bd9Sstevel@tonic-gate if (err != PICL_SUCCESS) {
23717c478bd9Sstevel@tonic-gate (void) rw_unlock(&ptree_rwlock); /* unlock ptree */
23727c478bd9Sstevel@tonic-gate return (err);
23737c478bd9Sstevel@tonic-gate }
23747c478bd9Sstevel@tonic-gate
23757c478bd9Sstevel@tonic-gate err = check_propsize(PROP_WRITE, propp, size);
23767c478bd9Sstevel@tonic-gate if (err != PICL_SUCCESS) {
23777c478bd9Sstevel@tonic-gate unlock_node(nodep); /* unlock node */
23787c478bd9Sstevel@tonic-gate (void) rw_unlock(&ptree_rwlock); /* unlock ptree */
23797c478bd9Sstevel@tonic-gate return (err);
23807c478bd9Sstevel@tonic-gate }
23817c478bd9Sstevel@tonic-gate
23827c478bd9Sstevel@tonic-gate return (write_propval_and_unlock(nodep, propp, vbuf, size, cred));
23837c478bd9Sstevel@tonic-gate }
23847c478bd9Sstevel@tonic-gate
23857c478bd9Sstevel@tonic-gate /*
23867c478bd9Sstevel@tonic-gate * Ptree function used by plug-ins to update a property's value
23877c478bd9Sstevel@tonic-gate * calls update_propval_with_cred(), which releases locks for volatile props
23887c478bd9Sstevel@tonic-gate */
23897c478bd9Sstevel@tonic-gate int
ptree_update_propval(picl_prophdl_t proph,const void * vbuf,size_t size)23907c478bd9Sstevel@tonic-gate ptree_update_propval(picl_prophdl_t proph, const void *vbuf, size_t size)
23917c478bd9Sstevel@tonic-gate {
23927c478bd9Sstevel@tonic-gate return (xptree_update_propval_with_cred(proph, vbuf, size, picld_cred));
23937c478bd9Sstevel@tonic-gate }
23947c478bd9Sstevel@tonic-gate
23957c478bd9Sstevel@tonic-gate /*
23967c478bd9Sstevel@tonic-gate * This function writes/updates a property's value by looking it up
23977c478bd9Sstevel@tonic-gate * by its name.
23987c478bd9Sstevel@tonic-gate * For volatile properties this function releases the locks on the
23997c478bd9Sstevel@tonic-gate * node and the ptree table.
24007c478bd9Sstevel@tonic-gate */
24017c478bd9Sstevel@tonic-gate int
xptree_update_propval_by_name_with_cred(picl_nodehdl_t nodeh,const char * pname,const void * vbuf,size_t size,door_cred_t cred)24027c478bd9Sstevel@tonic-gate xptree_update_propval_by_name_with_cred(picl_nodehdl_t nodeh, const char *pname,
24037c478bd9Sstevel@tonic-gate const void *vbuf, size_t size, door_cred_t cred)
24047c478bd9Sstevel@tonic-gate {
24057c478bd9Sstevel@tonic-gate picl_obj_t *nodep;
24067c478bd9Sstevel@tonic-gate picl_obj_t *propp;
24077c478bd9Sstevel@tonic-gate int err;
24087c478bd9Sstevel@tonic-gate
24097c478bd9Sstevel@tonic-gate (void) rw_rdlock(&ptree_rwlock); /* lock ptree */
24107c478bd9Sstevel@tonic-gate nodep = NULL;
24117c478bd9Sstevel@tonic-gate err = lookup_and_lock_node(WRLOCK_NODE, nodeh, &nodep); /* lock node */
24127c478bd9Sstevel@tonic-gate if (err != PICL_SUCCESS) {
24137c478bd9Sstevel@tonic-gate (void) rw_unlock(&ptree_rwlock); /* unlock ptree */
24147c478bd9Sstevel@tonic-gate return (err);
24157c478bd9Sstevel@tonic-gate }
24167c478bd9Sstevel@tonic-gate
24177c478bd9Sstevel@tonic-gate if (picl_restricted(pname)) {
24187c478bd9Sstevel@tonic-gate unlock_node(nodep);
24197c478bd9Sstevel@tonic-gate (void) rw_unlock(&ptree_rwlock);
24207c478bd9Sstevel@tonic-gate return (PICL_RESERVEDNAME);
24217c478bd9Sstevel@tonic-gate }
24227c478bd9Sstevel@tonic-gate
24237c478bd9Sstevel@tonic-gate err = lookup_prop_by_name(nodep, pname, &propp);
24247c478bd9Sstevel@tonic-gate if (err != PICL_SUCCESS) {
24257c478bd9Sstevel@tonic-gate unlock_node(nodep);
24267c478bd9Sstevel@tonic-gate (void) rw_unlock(&ptree_rwlock);
24277c478bd9Sstevel@tonic-gate return (err);
24287c478bd9Sstevel@tonic-gate }
24297c478bd9Sstevel@tonic-gate
24307c478bd9Sstevel@tonic-gate err = check_propsize(PROP_WRITE, propp, size);
24317c478bd9Sstevel@tonic-gate if (err != PICL_SUCCESS) {
24327c478bd9Sstevel@tonic-gate unlock_node(nodep);
24337c478bd9Sstevel@tonic-gate (void) rw_unlock(&ptree_rwlock);
24347c478bd9Sstevel@tonic-gate return (err);
24357c478bd9Sstevel@tonic-gate }
24367c478bd9Sstevel@tonic-gate
24377c478bd9Sstevel@tonic-gate return (write_propval_and_unlock(nodep, propp, vbuf, size, cred));
24387c478bd9Sstevel@tonic-gate }
24397c478bd9Sstevel@tonic-gate
24407c478bd9Sstevel@tonic-gate /*
24417c478bd9Sstevel@tonic-gate * This function updates the value of a property specified by its name
24427c478bd9Sstevel@tonic-gate */
24437c478bd9Sstevel@tonic-gate int
ptree_update_propval_by_name(picl_nodehdl_t nodeh,const char * pname,const void * vbuf,size_t size)24447c478bd9Sstevel@tonic-gate ptree_update_propval_by_name(picl_nodehdl_t nodeh, const char *pname,
24457c478bd9Sstevel@tonic-gate const void *vbuf, size_t size)
24467c478bd9Sstevel@tonic-gate {
24477c478bd9Sstevel@tonic-gate return (xptree_update_propval_by_name_with_cred(nodeh, pname, vbuf,
24487c478bd9Sstevel@tonic-gate size, picld_cred));
24497c478bd9Sstevel@tonic-gate }
24507c478bd9Sstevel@tonic-gate
24517c478bd9Sstevel@tonic-gate /*
24527c478bd9Sstevel@tonic-gate * This function retrieves the handle of a property by its name
24537c478bd9Sstevel@tonic-gate */
24547c478bd9Sstevel@tonic-gate int
ptree_get_prop_by_name(picl_nodehdl_t nodeh,const char * pname,picl_prophdl_t * proph)24557c478bd9Sstevel@tonic-gate ptree_get_prop_by_name(picl_nodehdl_t nodeh, const char *pname,
24567c478bd9Sstevel@tonic-gate picl_prophdl_t *proph)
24577c478bd9Sstevel@tonic-gate {
24587c478bd9Sstevel@tonic-gate picl_obj_t *nodep;
24597c478bd9Sstevel@tonic-gate picl_obj_t *propp;
24607c478bd9Sstevel@tonic-gate int err;
24617c478bd9Sstevel@tonic-gate
24627c478bd9Sstevel@tonic-gate (void) rw_rdlock(&ptree_rwlock); /* lock ptree */
24637c478bd9Sstevel@tonic-gate nodep = NULL;
24647c478bd9Sstevel@tonic-gate err = lookup_and_lock_node(RDLOCK_NODE, nodeh, &nodep); /* lock node */
24657c478bd9Sstevel@tonic-gate if (err != PICL_SUCCESS) {
24667c478bd9Sstevel@tonic-gate (void) rw_unlock(&ptree_rwlock); /* unlock ptree */
24677c478bd9Sstevel@tonic-gate return (err);
24687c478bd9Sstevel@tonic-gate }
24697c478bd9Sstevel@tonic-gate
24707c478bd9Sstevel@tonic-gate if (picl_restricted(pname)) {
24717c478bd9Sstevel@tonic-gate err = PICL_RESERVEDNAME;
24727c478bd9Sstevel@tonic-gate unlock_node(nodep); /* unlock node */
24737c478bd9Sstevel@tonic-gate (void) rw_unlock(&ptree_rwlock); /* unlock ptree */
24747c478bd9Sstevel@tonic-gate return (err);
24757c478bd9Sstevel@tonic-gate }
24767c478bd9Sstevel@tonic-gate
24777c478bd9Sstevel@tonic-gate err = lookup_prop_by_name(nodep, pname, &propp);
24787c478bd9Sstevel@tonic-gate if (err == PICL_SUCCESS)
24797c478bd9Sstevel@tonic-gate *proph = propp->ptree_hdl;
24807c478bd9Sstevel@tonic-gate
24817c478bd9Sstevel@tonic-gate unlock_node(nodep); /* unlock node */
24827c478bd9Sstevel@tonic-gate (void) rw_unlock(&ptree_rwlock); /* unlock ptree */
24837c478bd9Sstevel@tonic-gate return (err);
24847c478bd9Sstevel@tonic-gate }
24857c478bd9Sstevel@tonic-gate
24867c478bd9Sstevel@tonic-gate /*
24877c478bd9Sstevel@tonic-gate * This function returns the handle of the first property
24887c478bd9Sstevel@tonic-gate */
24897c478bd9Sstevel@tonic-gate int
ptree_get_first_prop(picl_nodehdl_t nodeh,picl_prophdl_t * proph)24907c478bd9Sstevel@tonic-gate ptree_get_first_prop(picl_nodehdl_t nodeh, picl_prophdl_t *proph)
24917c478bd9Sstevel@tonic-gate {
24927c478bd9Sstevel@tonic-gate picl_obj_t *pobj;
24937c478bd9Sstevel@tonic-gate int err;
24947c478bd9Sstevel@tonic-gate
24957c478bd9Sstevel@tonic-gate (void) rw_rdlock(&ptree_rwlock); /* lock ptree */
24967c478bd9Sstevel@tonic-gate pobj = NULL;
24977c478bd9Sstevel@tonic-gate err = lookup_and_lock_node(RDLOCK_NODE, nodeh, &pobj); /* lock node */
24987c478bd9Sstevel@tonic-gate if (err != PICL_SUCCESS) {
24997c478bd9Sstevel@tonic-gate (void) rw_unlock(&ptree_rwlock); /* unlock ptree */
25007c478bd9Sstevel@tonic-gate return (err);
25017c478bd9Sstevel@tonic-gate }
25027c478bd9Sstevel@tonic-gate
25037c478bd9Sstevel@tonic-gate if (pobj->first_prop)
25047c478bd9Sstevel@tonic-gate *proph = pobj->first_prop->ptree_hdl;
25057c478bd9Sstevel@tonic-gate else
25067c478bd9Sstevel@tonic-gate err = PICL_ENDOFLIST;
25077c478bd9Sstevel@tonic-gate
25087c478bd9Sstevel@tonic-gate unlock_node(pobj); /* unlock node */
25097c478bd9Sstevel@tonic-gate (void) rw_unlock(&ptree_rwlock); /* unlock ptree */
25107c478bd9Sstevel@tonic-gate return (err);
25117c478bd9Sstevel@tonic-gate }
25127c478bd9Sstevel@tonic-gate
25137c478bd9Sstevel@tonic-gate /*
25147c478bd9Sstevel@tonic-gate * This function returns the handle of next property in the list
25157c478bd9Sstevel@tonic-gate */
25167c478bd9Sstevel@tonic-gate int
ptree_get_next_prop(picl_prophdl_t proph,picl_prophdl_t * nextproph)25177c478bd9Sstevel@tonic-gate ptree_get_next_prop(picl_prophdl_t proph, picl_prophdl_t *nextproph)
25187c478bd9Sstevel@tonic-gate {
25197c478bd9Sstevel@tonic-gate picl_obj_t *nodep;
25207c478bd9Sstevel@tonic-gate picl_obj_t *propp;
25217c478bd9Sstevel@tonic-gate int err;
25227c478bd9Sstevel@tonic-gate
25237c478bd9Sstevel@tonic-gate (void) rw_rdlock(&ptree_rwlock); /* lock ptree */
25247c478bd9Sstevel@tonic-gate nodep = propp = NULL;
25257c478bd9Sstevel@tonic-gate err = lookup_and_lock_propnode(RDLOCK_NODE, proph, &nodep, &propp);
25267c478bd9Sstevel@tonic-gate if (err != PICL_SUCCESS) {
25277c478bd9Sstevel@tonic-gate (void) rw_unlock(&ptree_rwlock); /* unlock ptree */
25287c478bd9Sstevel@tonic-gate return (err);
25297c478bd9Sstevel@tonic-gate }
25307c478bd9Sstevel@tonic-gate
25317c478bd9Sstevel@tonic-gate if (propp->next_prop) {
25327c478bd9Sstevel@tonic-gate *nextproph = propp->next_prop->ptree_hdl;
25337c478bd9Sstevel@tonic-gate } else
25347c478bd9Sstevel@tonic-gate err = PICL_ENDOFLIST;
25357c478bd9Sstevel@tonic-gate
25367c478bd9Sstevel@tonic-gate unlock_node(nodep); /* unlock node */
25377c478bd9Sstevel@tonic-gate (void) rw_unlock(&ptree_rwlock); /* unlock ptree */
25387c478bd9Sstevel@tonic-gate return (err);
25397c478bd9Sstevel@tonic-gate }
25407c478bd9Sstevel@tonic-gate
25417c478bd9Sstevel@tonic-gate /*
25427c478bd9Sstevel@tonic-gate * These functions are called by ptree_get_node_by_path()
25437c478bd9Sstevel@tonic-gate * Append a prop expression entry to the list
25447c478bd9Sstevel@tonic-gate */
25457c478bd9Sstevel@tonic-gate static prop_list_t *
append_entry_to_list(prop_list_t * el,prop_list_t * list)25467c478bd9Sstevel@tonic-gate append_entry_to_list(prop_list_t *el, prop_list_t *list)
25477c478bd9Sstevel@tonic-gate {
25487c478bd9Sstevel@tonic-gate prop_list_t *ptr;
25497c478bd9Sstevel@tonic-gate
25507c478bd9Sstevel@tonic-gate if (el == NULL)
25517c478bd9Sstevel@tonic-gate return (list);
25527c478bd9Sstevel@tonic-gate
25537c478bd9Sstevel@tonic-gate if (list == NULL) {
25547c478bd9Sstevel@tonic-gate list = el;
25557c478bd9Sstevel@tonic-gate return (list);
25567c478bd9Sstevel@tonic-gate }
25577c478bd9Sstevel@tonic-gate
25587c478bd9Sstevel@tonic-gate /*
25597c478bd9Sstevel@tonic-gate * Add it to the end of list
25607c478bd9Sstevel@tonic-gate */
25617c478bd9Sstevel@tonic-gate ptr = list;
25627c478bd9Sstevel@tonic-gate
25637c478bd9Sstevel@tonic-gate while (ptr->next != NULL)
25647c478bd9Sstevel@tonic-gate ptr = ptr->next;
25657c478bd9Sstevel@tonic-gate
25667c478bd9Sstevel@tonic-gate ptr->next = el;
25677c478bd9Sstevel@tonic-gate
25687c478bd9Sstevel@tonic-gate return (list);
25697c478bd9Sstevel@tonic-gate }
25707c478bd9Sstevel@tonic-gate
25717c478bd9Sstevel@tonic-gate /*
25727c478bd9Sstevel@tonic-gate * Free the property expression list
25737c478bd9Sstevel@tonic-gate */
25747c478bd9Sstevel@tonic-gate static void
free_list(prop_list_t * list)25757c478bd9Sstevel@tonic-gate free_list(prop_list_t *list)
25767c478bd9Sstevel@tonic-gate {
25777c478bd9Sstevel@tonic-gate prop_list_t *ptr;
25787c478bd9Sstevel@tonic-gate prop_list_t *tmp;
25797c478bd9Sstevel@tonic-gate
25807c478bd9Sstevel@tonic-gate for (ptr = list; ptr != NULL; ptr = tmp) {
25817c478bd9Sstevel@tonic-gate tmp = ptr->next;
25827c478bd9Sstevel@tonic-gate free(ptr);
25837c478bd9Sstevel@tonic-gate }
25847c478bd9Sstevel@tonic-gate }
25857c478bd9Sstevel@tonic-gate
25867c478bd9Sstevel@tonic-gate static int
parse_prl(char * prl,char ** name,char ** baddr,prop_list_t ** plist)25877c478bd9Sstevel@tonic-gate parse_prl(char *prl, char **name, char **baddr, prop_list_t **plist)
25887c478bd9Sstevel@tonic-gate {
25897c478bd9Sstevel@tonic-gate char *propptr;
25907c478bd9Sstevel@tonic-gate char *ptr;
25917c478bd9Sstevel@tonic-gate char *pname;
25927c478bd9Sstevel@tonic-gate char *pval;
25937c478bd9Sstevel@tonic-gate prop_list_t *el;
25947c478bd9Sstevel@tonic-gate
25957c478bd9Sstevel@tonic-gate if (prl == NULL)
25967c478bd9Sstevel@tonic-gate return (PICL_FAILURE);
25977c478bd9Sstevel@tonic-gate
25987c478bd9Sstevel@tonic-gate if ((prl[0] == '@') || (prl[0] == '?'))
25997c478bd9Sstevel@tonic-gate return (PICL_FAILURE);
26007c478bd9Sstevel@tonic-gate
26017c478bd9Sstevel@tonic-gate *name = prl;
26027c478bd9Sstevel@tonic-gate
26037c478bd9Sstevel@tonic-gate /*
26047c478bd9Sstevel@tonic-gate * get property expression
26057c478bd9Sstevel@tonic-gate */
26067c478bd9Sstevel@tonic-gate ptr = strchr(prl, '?');
26077c478bd9Sstevel@tonic-gate
26087c478bd9Sstevel@tonic-gate if (ptr != NULL) {
26097c478bd9Sstevel@tonic-gate *ptr = '\0';
26107c478bd9Sstevel@tonic-gate propptr = ptr + 1;
26117c478bd9Sstevel@tonic-gate } else
26127c478bd9Sstevel@tonic-gate propptr = NULL;
26137c478bd9Sstevel@tonic-gate
26147c478bd9Sstevel@tonic-gate /*
26157c478bd9Sstevel@tonic-gate * get bus value
26167c478bd9Sstevel@tonic-gate */
26177c478bd9Sstevel@tonic-gate ptr = strchr(prl, '@');
26187c478bd9Sstevel@tonic-gate
26197c478bd9Sstevel@tonic-gate if (ptr != NULL) {
26207c478bd9Sstevel@tonic-gate *ptr = '\0';
26217c478bd9Sstevel@tonic-gate *baddr = ptr + 1;
26227c478bd9Sstevel@tonic-gate if (strlen(*baddr) == 0) /* no bus value after @ */
26237c478bd9Sstevel@tonic-gate return (PICL_FAILURE);
26247c478bd9Sstevel@tonic-gate }
26257c478bd9Sstevel@tonic-gate
26267c478bd9Sstevel@tonic-gate /*
26277c478bd9Sstevel@tonic-gate * create the prop list
26287c478bd9Sstevel@tonic-gate */
26297c478bd9Sstevel@tonic-gate while (propptr != NULL) {
26307c478bd9Sstevel@tonic-gate pname = propptr;
26317c478bd9Sstevel@tonic-gate pval = NULL;
26327c478bd9Sstevel@tonic-gate
26337c478bd9Sstevel@tonic-gate ptr = strchr(propptr, '?');
26347c478bd9Sstevel@tonic-gate
26357c478bd9Sstevel@tonic-gate if (ptr != NULL) { /* more ?<prop>=<propval> */
26367c478bd9Sstevel@tonic-gate *ptr = '\0';
26377c478bd9Sstevel@tonic-gate propptr = ptr + 1;
26387c478bd9Sstevel@tonic-gate } else
26397c478bd9Sstevel@tonic-gate propptr = NULL;
26407c478bd9Sstevel@tonic-gate
26417c478bd9Sstevel@tonic-gate if (strlen(pname) == 0) /* no prop exp after ? */
26427c478bd9Sstevel@tonic-gate return (PICL_FAILURE);
26437c478bd9Sstevel@tonic-gate
26447c478bd9Sstevel@tonic-gate ptr = strchr(pname, '=');
26457c478bd9Sstevel@tonic-gate if (ptr != NULL) { /* not void prop */
26467c478bd9Sstevel@tonic-gate *ptr = '\0';
26477c478bd9Sstevel@tonic-gate pval = ptr + 1;
26487c478bd9Sstevel@tonic-gate /*
26497c478bd9Sstevel@tonic-gate * <prop>= is treated as void property
26507c478bd9Sstevel@tonic-gate */
26517c478bd9Sstevel@tonic-gate if (strlen(pval) == 0)
26527c478bd9Sstevel@tonic-gate pval = NULL;
26537c478bd9Sstevel@tonic-gate }
26547c478bd9Sstevel@tonic-gate
26557c478bd9Sstevel@tonic-gate el = (prop_list_t *)malloc(sizeof (prop_list_t));
26567c478bd9Sstevel@tonic-gate el->pname = pname;
26577c478bd9Sstevel@tonic-gate el->pval = pval;
26587c478bd9Sstevel@tonic-gate el->next = NULL;
26597c478bd9Sstevel@tonic-gate *plist = append_entry_to_list(el, *plist);
26607c478bd9Sstevel@tonic-gate }
26617c478bd9Sstevel@tonic-gate
26627c478bd9Sstevel@tonic-gate return (PICL_SUCCESS);
26637c478bd9Sstevel@tonic-gate }
26647c478bd9Sstevel@tonic-gate
26657c478bd9Sstevel@tonic-gate static int
prop_match(ptree_propinfo_t pinfo,void * vbuf,char * val)26667c478bd9Sstevel@tonic-gate prop_match(ptree_propinfo_t pinfo, void *vbuf, char *val)
26677c478bd9Sstevel@tonic-gate {
26687c478bd9Sstevel@tonic-gate int8_t cval;
26697c478bd9Sstevel@tonic-gate uint8_t ucval;
26707c478bd9Sstevel@tonic-gate int16_t sval;
26717c478bd9Sstevel@tonic-gate uint16_t usval;
26727c478bd9Sstevel@tonic-gate int32_t intval;
26737c478bd9Sstevel@tonic-gate uint32_t uintval;
26747c478bd9Sstevel@tonic-gate int64_t llval;
26757c478bd9Sstevel@tonic-gate uint64_t ullval;
26767c478bd9Sstevel@tonic-gate float fval;
26777c478bd9Sstevel@tonic-gate double dval;
26787c478bd9Sstevel@tonic-gate
26797c478bd9Sstevel@tonic-gate switch (pinfo.piclinfo.type) {
26807c478bd9Sstevel@tonic-gate case PICL_PTYPE_CHARSTRING:
26817c478bd9Sstevel@tonic-gate if (strcasecmp(pinfo.piclinfo.name, PICL_PROP_CLASSNAME) == 0) {
26827c478bd9Sstevel@tonic-gate if (strcmp(val, PICL_CLASS_PICL) == 0)
26837c478bd9Sstevel@tonic-gate return (1);
26847c478bd9Sstevel@tonic-gate }
26857c478bd9Sstevel@tonic-gate if (strcmp(val, (char *)vbuf) == 0)
26867c478bd9Sstevel@tonic-gate return (1);
26877c478bd9Sstevel@tonic-gate else
26887c478bd9Sstevel@tonic-gate return (0);
26897c478bd9Sstevel@tonic-gate case PICL_PTYPE_INT:
26907c478bd9Sstevel@tonic-gate switch (pinfo.piclinfo.size) {
26917c478bd9Sstevel@tonic-gate case sizeof (int8_t):
26927c478bd9Sstevel@tonic-gate cval = (int8_t)strtol(val, (char **)NULL, 0);
26937c478bd9Sstevel@tonic-gate return (cval == *(char *)vbuf);
26947c478bd9Sstevel@tonic-gate case sizeof (int16_t):
26957c478bd9Sstevel@tonic-gate sval = (int16_t)strtol(val, (char **)NULL, 0);
26967c478bd9Sstevel@tonic-gate return (sval == *(int16_t *)vbuf);
26977c478bd9Sstevel@tonic-gate case sizeof (int32_t):
26987c478bd9Sstevel@tonic-gate intval = (int32_t)strtol(val, (char **)NULL, 0);
26997c478bd9Sstevel@tonic-gate return (intval == *(int32_t *)vbuf);
27007c478bd9Sstevel@tonic-gate case sizeof (int64_t):
27017c478bd9Sstevel@tonic-gate llval = strtoll(val, (char **)NULL, 0);
27027c478bd9Sstevel@tonic-gate return (llval == *(int64_t *)vbuf);
27037c478bd9Sstevel@tonic-gate default:
27047c478bd9Sstevel@tonic-gate return (0);
27057c478bd9Sstevel@tonic-gate }
27067c478bd9Sstevel@tonic-gate case PICL_PTYPE_UNSIGNED_INT:
27077c478bd9Sstevel@tonic-gate switch (pinfo.piclinfo.size) {
27087c478bd9Sstevel@tonic-gate case sizeof (uint8_t):
27097c478bd9Sstevel@tonic-gate ucval = (uint8_t)strtoul(val, (char **)NULL, 0);
27107c478bd9Sstevel@tonic-gate return (ucval == *(uint8_t *)vbuf);
27117c478bd9Sstevel@tonic-gate case sizeof (uint16_t):
27127c478bd9Sstevel@tonic-gate usval = (uint16_t)strtoul(val, (char **)NULL, 0);
27137c478bd9Sstevel@tonic-gate return (usval == *(uint16_t *)vbuf);
27147c478bd9Sstevel@tonic-gate case sizeof (uint32_t):
27157c478bd9Sstevel@tonic-gate uintval = (uint32_t)strtoul(val, (char **)NULL, 0);
27167c478bd9Sstevel@tonic-gate return (uintval == *(uint32_t *)vbuf);
27177c478bd9Sstevel@tonic-gate case sizeof (uint64_t):
27187c478bd9Sstevel@tonic-gate ullval = strtoull(val, (char **)NULL, 0);
27197c478bd9Sstevel@tonic-gate return (ullval == *(uint64_t *)vbuf);
27207c478bd9Sstevel@tonic-gate default:
27217c478bd9Sstevel@tonic-gate return (0);
27227c478bd9Sstevel@tonic-gate }
27237c478bd9Sstevel@tonic-gate case PICL_PTYPE_FLOAT:
27247c478bd9Sstevel@tonic-gate switch (pinfo.piclinfo.size) {
27257c478bd9Sstevel@tonic-gate case sizeof (float):
27267c478bd9Sstevel@tonic-gate fval = (float)strtod(val, (char **)NULL);
27277c478bd9Sstevel@tonic-gate return (fval == *(float *)vbuf);
27287c478bd9Sstevel@tonic-gate case sizeof (double):
27297c478bd9Sstevel@tonic-gate dval = strtod(val, (char **)NULL);
27307c478bd9Sstevel@tonic-gate return (dval == *(double *)vbuf);
27317c478bd9Sstevel@tonic-gate default:
27327c478bd9Sstevel@tonic-gate return (0);
27337c478bd9Sstevel@tonic-gate }
27347c478bd9Sstevel@tonic-gate case PICL_PTYPE_VOID:
27357c478bd9Sstevel@tonic-gate case PICL_PTYPE_TIMESTAMP:
27367c478bd9Sstevel@tonic-gate case PICL_PTYPE_TABLE:
27377c478bd9Sstevel@tonic-gate case PICL_PTYPE_REFERENCE:
27387c478bd9Sstevel@tonic-gate case PICL_PTYPE_BYTEARRAY:
27397c478bd9Sstevel@tonic-gate case PICL_PTYPE_UNKNOWN:
27407c478bd9Sstevel@tonic-gate default:
27417c478bd9Sstevel@tonic-gate return (0);
27427c478bd9Sstevel@tonic-gate }
27437c478bd9Sstevel@tonic-gate }
27447c478bd9Sstevel@tonic-gate
27457c478bd9Sstevel@tonic-gate static int
check_propval(picl_nodehdl_t nodeh,char * pname,char * pval)27467c478bd9Sstevel@tonic-gate check_propval(picl_nodehdl_t nodeh, char *pname, char *pval)
27477c478bd9Sstevel@tonic-gate {
27487c478bd9Sstevel@tonic-gate int err;
27497c478bd9Sstevel@tonic-gate picl_prophdl_t proph;
27507c478bd9Sstevel@tonic-gate ptree_propinfo_t pinfo;
27517c478bd9Sstevel@tonic-gate void *vbuf;
27527c478bd9Sstevel@tonic-gate
27537c478bd9Sstevel@tonic-gate err = ptree_get_prop_by_name(nodeh, pname, &proph);
27547c478bd9Sstevel@tonic-gate if (err != PICL_SUCCESS)
27557c478bd9Sstevel@tonic-gate return (err);
27567c478bd9Sstevel@tonic-gate
27577c478bd9Sstevel@tonic-gate err = ptree_get_propinfo(proph, &pinfo);
27587c478bd9Sstevel@tonic-gate if (err != PICL_SUCCESS)
27597c478bd9Sstevel@tonic-gate return (err);
27607c478bd9Sstevel@tonic-gate
27617c478bd9Sstevel@tonic-gate if (pval == NULL) { /* void type */
27627c478bd9Sstevel@tonic-gate if (pinfo.piclinfo.type != PICL_PTYPE_VOID)
27637c478bd9Sstevel@tonic-gate return (PICL_FAILURE);
27647c478bd9Sstevel@tonic-gate } else {
27657c478bd9Sstevel@tonic-gate vbuf = alloca(pinfo.piclinfo.size);
27667c478bd9Sstevel@tonic-gate if (vbuf == NULL)
27677c478bd9Sstevel@tonic-gate return (PICL_FAILURE);
27687c478bd9Sstevel@tonic-gate err = ptree_get_propval(proph, vbuf,
27697c478bd9Sstevel@tonic-gate pinfo.piclinfo.size);
27707c478bd9Sstevel@tonic-gate if (err != PICL_SUCCESS)
27717c478bd9Sstevel@tonic-gate return (err);
27727c478bd9Sstevel@tonic-gate
27737c478bd9Sstevel@tonic-gate if (!prop_match(pinfo, vbuf, pval))
27747c478bd9Sstevel@tonic-gate return (PICL_FAILURE);
27757c478bd9Sstevel@tonic-gate }
27767c478bd9Sstevel@tonic-gate return (PICL_SUCCESS);
27777c478bd9Sstevel@tonic-gate }
27787c478bd9Sstevel@tonic-gate
27797c478bd9Sstevel@tonic-gate static int
get_child_by_path(picl_nodehdl_t rooth,char * prl,picl_nodehdl_t * nodeh,char * pname)27807c478bd9Sstevel@tonic-gate get_child_by_path(picl_nodehdl_t rooth, char *prl,
27817c478bd9Sstevel@tonic-gate picl_nodehdl_t *nodeh, char *pname)
27827c478bd9Sstevel@tonic-gate {
27837c478bd9Sstevel@tonic-gate picl_nodehdl_t chdh;
27847c478bd9Sstevel@tonic-gate int err;
27857c478bd9Sstevel@tonic-gate char *nameval;
27867c478bd9Sstevel@tonic-gate char *nodename;
27877c478bd9Sstevel@tonic-gate char *path;
27887c478bd9Sstevel@tonic-gate char *baddr;
27897c478bd9Sstevel@tonic-gate char *busval;
27907c478bd9Sstevel@tonic-gate prop_list_t *plist;
27917c478bd9Sstevel@tonic-gate prop_list_t *ptr;
27927c478bd9Sstevel@tonic-gate
27937c478bd9Sstevel@tonic-gate if (prl == NULL)
27947c478bd9Sstevel@tonic-gate return (PICL_FAILURE);
27957c478bd9Sstevel@tonic-gate
2796*23a1cceaSRoger A. Faulkner path = strdupa(prl);
27977c478bd9Sstevel@tonic-gate if (path == NULL)
27987c478bd9Sstevel@tonic-gate return (PICL_FAILURE);
27997c478bd9Sstevel@tonic-gate
28007c478bd9Sstevel@tonic-gate plist = NULL;
28017c478bd9Sstevel@tonic-gate nodename = NULL;
28027c478bd9Sstevel@tonic-gate baddr = NULL;
28037c478bd9Sstevel@tonic-gate
28047c478bd9Sstevel@tonic-gate err = parse_prl(path, &nodename, &baddr, &plist);
28057c478bd9Sstevel@tonic-gate if (err != PICL_SUCCESS) {
28067c478bd9Sstevel@tonic-gate free_list(plist);
28077c478bd9Sstevel@tonic-gate return (err);
28087c478bd9Sstevel@tonic-gate }
28097c478bd9Sstevel@tonic-gate
28107c478bd9Sstevel@tonic-gate if (nodename == NULL)
28117c478bd9Sstevel@tonic-gate return (PICL_FAILURE);
28127c478bd9Sstevel@tonic-gate
28137c478bd9Sstevel@tonic-gate nameval = alloca(strlen(nodename) + 1);
28147c478bd9Sstevel@tonic-gate if (nameval == NULL) {
28157c478bd9Sstevel@tonic-gate free_list(plist);
28167c478bd9Sstevel@tonic-gate return (PICL_FAILURE);
28177c478bd9Sstevel@tonic-gate }
28187c478bd9Sstevel@tonic-gate
28197c478bd9Sstevel@tonic-gate if (baddr != NULL) {
28207c478bd9Sstevel@tonic-gate busval = alloca(strlen(baddr) + 1);
28217c478bd9Sstevel@tonic-gate if (busval == NULL) {
28227c478bd9Sstevel@tonic-gate free_list(plist);
28237c478bd9Sstevel@tonic-gate return (PICL_FAILURE);
28247c478bd9Sstevel@tonic-gate }
28257c478bd9Sstevel@tonic-gate }
28267c478bd9Sstevel@tonic-gate
28277c478bd9Sstevel@tonic-gate for (err = ptree_get_propval_by_name(rooth, PICL_PROP_CHILD, &chdh,
28287c478bd9Sstevel@tonic-gate sizeof (picl_nodehdl_t)); err != PICL_PROPNOTFOUND;
28297c478bd9Sstevel@tonic-gate err = ptree_get_propval_by_name(chdh, PICL_PROP_PEER, &chdh,
28307c478bd9Sstevel@tonic-gate sizeof (picl_nodehdl_t))) {
28317c478bd9Sstevel@tonic-gate if (err != PICL_SUCCESS) {
28327c478bd9Sstevel@tonic-gate free_list(plist);
28337c478bd9Sstevel@tonic-gate return (PICL_FAILURE);
28347c478bd9Sstevel@tonic-gate }
28357c478bd9Sstevel@tonic-gate
28367c478bd9Sstevel@tonic-gate /*
28377c478bd9Sstevel@tonic-gate * compare name
28387c478bd9Sstevel@tonic-gate */
28397c478bd9Sstevel@tonic-gate if ((strcmp(pname, PICL_PROP_CLASSNAME) != 0) ||
28407c478bd9Sstevel@tonic-gate (strcmp(nodename, PICL_CLASS_PICL) != 0)) {
28417c478bd9Sstevel@tonic-gate err = ptree_get_propval_by_name(chdh, pname,
28427c478bd9Sstevel@tonic-gate nameval, (strlen(nodename) + 1));
28437c478bd9Sstevel@tonic-gate
28447c478bd9Sstevel@tonic-gate if (err != PICL_SUCCESS)
28457c478bd9Sstevel@tonic-gate continue;
28467c478bd9Sstevel@tonic-gate if (strcmp(nameval, nodename) != 0)
28477c478bd9Sstevel@tonic-gate continue;
28487c478bd9Sstevel@tonic-gate }
28497c478bd9Sstevel@tonic-gate
28507c478bd9Sstevel@tonic-gate /*
28517c478bd9Sstevel@tonic-gate * compare device address with bus-addr prop first
28527c478bd9Sstevel@tonic-gate * then with UnitAddress property
28537c478bd9Sstevel@tonic-gate */
28547c478bd9Sstevel@tonic-gate if (baddr != NULL) { /* compare bus-addr prop */
28557c478bd9Sstevel@tonic-gate if ((ptree_get_propval_by_name(chdh, PICL_PROP_BUS_ADDR,
28567c478bd9Sstevel@tonic-gate busval, (strlen(baddr) + 1)) != PICL_SUCCESS) &&
28577c478bd9Sstevel@tonic-gate (ptree_get_propval_by_name(chdh,
28587c478bd9Sstevel@tonic-gate PICL_PROP_UNIT_ADDRESS, busval,
28597c478bd9Sstevel@tonic-gate (strlen(baddr) + 1)) != PICL_SUCCESS))
28607c478bd9Sstevel@tonic-gate continue;
28617c478bd9Sstevel@tonic-gate
28627c478bd9Sstevel@tonic-gate if (strcmp(busval, baddr) != 0)
28637c478bd9Sstevel@tonic-gate continue; /* not match */
28647c478bd9Sstevel@tonic-gate }
28657c478bd9Sstevel@tonic-gate
28667c478bd9Sstevel@tonic-gate if (plist == NULL) { /* no prop expression */
28677c478bd9Sstevel@tonic-gate *nodeh = chdh;
28687c478bd9Sstevel@tonic-gate return (PICL_SUCCESS);
28697c478bd9Sstevel@tonic-gate }
28707c478bd9Sstevel@tonic-gate
28717c478bd9Sstevel@tonic-gate /*
28727c478bd9Sstevel@tonic-gate * compare the property expression list
28737c478bd9Sstevel@tonic-gate */
28747c478bd9Sstevel@tonic-gate ptr = plist;
28757c478bd9Sstevel@tonic-gate
28767c478bd9Sstevel@tonic-gate while (ptr != NULL) {
28777c478bd9Sstevel@tonic-gate err = check_propval(chdh, ptr->pname, ptr->pval);
28787c478bd9Sstevel@tonic-gate if (err != PICL_SUCCESS)
28797c478bd9Sstevel@tonic-gate break;
28807c478bd9Sstevel@tonic-gate
28817c478bd9Sstevel@tonic-gate ptr = ptr->next;
28827c478bd9Sstevel@tonic-gate }
28837c478bd9Sstevel@tonic-gate if (ptr == NULL) {
28847c478bd9Sstevel@tonic-gate *nodeh = chdh;
28857c478bd9Sstevel@tonic-gate free_list(plist);
28867c478bd9Sstevel@tonic-gate return (PICL_SUCCESS);
28877c478bd9Sstevel@tonic-gate }
28887c478bd9Sstevel@tonic-gate }
28897c478bd9Sstevel@tonic-gate free_list(plist);
28907c478bd9Sstevel@tonic-gate return (PICL_NOTNODE);
28917c478bd9Sstevel@tonic-gate }
28927c478bd9Sstevel@tonic-gate
28937c478bd9Sstevel@tonic-gate /*
28947c478bd9Sstevel@tonic-gate * This functions returns the handle of node specified by its path
28957c478bd9Sstevel@tonic-gate */
28967c478bd9Sstevel@tonic-gate int
ptree_get_node_by_path(const char * piclprl,picl_nodehdl_t * handle)28977c478bd9Sstevel@tonic-gate ptree_get_node_by_path(const char *piclprl, picl_nodehdl_t *handle)
28987c478bd9Sstevel@tonic-gate {
28997c478bd9Sstevel@tonic-gate picl_nodehdl_t rooth;
29007c478bd9Sstevel@tonic-gate picl_nodehdl_t chdh;
29017c478bd9Sstevel@tonic-gate char *path;
29027c478bd9Sstevel@tonic-gate char *ptr;
29037c478bd9Sstevel@tonic-gate char *defprop;
29047c478bd9Sstevel@tonic-gate char *tokindex;
29057c478bd9Sstevel@tonic-gate int err;
29067c478bd9Sstevel@tonic-gate int len;
29077c478bd9Sstevel@tonic-gate int npflg; /* namepath flag */
29087c478bd9Sstevel@tonic-gate
29097c478bd9Sstevel@tonic-gate
2910*23a1cceaSRoger A. Faulkner path = strdupa(piclprl);
29117c478bd9Sstevel@tonic-gate if (path == NULL)
29127c478bd9Sstevel@tonic-gate return (PICL_FAILURE);
29137c478bd9Sstevel@tonic-gate
29147c478bd9Sstevel@tonic-gate npflg = 1; /* default */
29157c478bd9Sstevel@tonic-gate defprop = path;
29167c478bd9Sstevel@tonic-gate if (path[0] == '/') {
29177c478bd9Sstevel@tonic-gate ptr = &path[1];
29187c478bd9Sstevel@tonic-gate } else if ((tokindex = strchr(path, ':')) != NULL) {
29197c478bd9Sstevel@tonic-gate *tokindex = '\0';
29207c478bd9Sstevel@tonic-gate ++tokindex;
29217c478bd9Sstevel@tonic-gate if (*tokindex == '/')
29227c478bd9Sstevel@tonic-gate ptr = tokindex + 1;
29237c478bd9Sstevel@tonic-gate else
29247c478bd9Sstevel@tonic-gate return (PICL_NOTNODE);
29257c478bd9Sstevel@tonic-gate npflg = 0;
29267c478bd9Sstevel@tonic-gate } else
29277c478bd9Sstevel@tonic-gate return (PICL_NOTNODE);
29287c478bd9Sstevel@tonic-gate
29297c478bd9Sstevel@tonic-gate err = ptree_get_root(&rooth);
29307c478bd9Sstevel@tonic-gate if (err != PICL_SUCCESS)
29317c478bd9Sstevel@tonic-gate return (err);
29327c478bd9Sstevel@tonic-gate
29337c478bd9Sstevel@tonic-gate for (chdh = rooth, tokindex = strchr(ptr, '/');
29347c478bd9Sstevel@tonic-gate tokindex != NULL;
29357c478bd9Sstevel@tonic-gate ptr = tokindex + 1, tokindex = strchr(ptr, '/')) {
29367c478bd9Sstevel@tonic-gate *tokindex = '\0';
29377c478bd9Sstevel@tonic-gate if (npflg)
29387c478bd9Sstevel@tonic-gate err = get_child_by_path(chdh, ptr, &chdh,
29397c478bd9Sstevel@tonic-gate PICL_PROP_NAME);
29407c478bd9Sstevel@tonic-gate else
29417c478bd9Sstevel@tonic-gate err = get_child_by_path(chdh, ptr, &chdh,
29427c478bd9Sstevel@tonic-gate defprop);
29437c478bd9Sstevel@tonic-gate
29447c478bd9Sstevel@tonic-gate if (err != PICL_SUCCESS)
29457c478bd9Sstevel@tonic-gate return (err);
29467c478bd9Sstevel@tonic-gate }
29477c478bd9Sstevel@tonic-gate
29487c478bd9Sstevel@tonic-gate /*
29497c478bd9Sstevel@tonic-gate * check if last token is empty or not
29507c478bd9Sstevel@tonic-gate * eg. /a/b/c/ or /a/b/c
29517c478bd9Sstevel@tonic-gate */
29527c478bd9Sstevel@tonic-gate if (*ptr == '\0') {
29537c478bd9Sstevel@tonic-gate *handle = chdh;
29547c478bd9Sstevel@tonic-gate return (PICL_SUCCESS);
29557c478bd9Sstevel@tonic-gate }
29567c478bd9Sstevel@tonic-gate
29577c478bd9Sstevel@tonic-gate len = strcspn(ptr, " \t\n");
29587c478bd9Sstevel@tonic-gate if (len == 0) {
29597c478bd9Sstevel@tonic-gate *handle = chdh;
29607c478bd9Sstevel@tonic-gate return (PICL_SUCCESS);
29617c478bd9Sstevel@tonic-gate }
29627c478bd9Sstevel@tonic-gate
29637c478bd9Sstevel@tonic-gate ptr[len] = '\0';
29647c478bd9Sstevel@tonic-gate if (npflg)
29657c478bd9Sstevel@tonic-gate err = get_child_by_path(chdh, ptr, &chdh, PICL_PROP_NAME);
29667c478bd9Sstevel@tonic-gate else
29677c478bd9Sstevel@tonic-gate err = get_child_by_path(chdh, ptr, &chdh, defprop);
29687c478bd9Sstevel@tonic-gate
29697c478bd9Sstevel@tonic-gate if (err != PICL_SUCCESS)
29707c478bd9Sstevel@tonic-gate return (err);
29717c478bd9Sstevel@tonic-gate
29727c478bd9Sstevel@tonic-gate *handle = chdh;
29737c478bd9Sstevel@tonic-gate return (PICL_SUCCESS);
29747c478bd9Sstevel@tonic-gate }
29757c478bd9Sstevel@tonic-gate
29767c478bd9Sstevel@tonic-gate /*
29777c478bd9Sstevel@tonic-gate * Initialize propinfo
29787c478bd9Sstevel@tonic-gate */
29797c478bd9Sstevel@tonic-gate int
ptree_init_propinfo(ptree_propinfo_t * infop,int version,int ptype,int pmode,size_t psize,char * pname,int (* readfn)(ptree_rarg_t *,void *),int (* writefn)(ptree_warg_t *,const void *))29807c478bd9Sstevel@tonic-gate ptree_init_propinfo(ptree_propinfo_t *infop, int version, int ptype, int pmode,
29817c478bd9Sstevel@tonic-gate size_t psize, char *pname, int (*readfn)(ptree_rarg_t *, void *),
29827c478bd9Sstevel@tonic-gate int (*writefn)(ptree_warg_t *, const void *))
29837c478bd9Sstevel@tonic-gate {
29847c478bd9Sstevel@tonic-gate if (version != PTREE_PROPINFO_VERSION_1)
29857c478bd9Sstevel@tonic-gate return (PICL_NOTSUPPORTED);
29867c478bd9Sstevel@tonic-gate if ((infop == NULL) || (pname == NULL))
29877c478bd9Sstevel@tonic-gate return (PICL_INVALIDARG);
29887c478bd9Sstevel@tonic-gate infop->version = version;
29897c478bd9Sstevel@tonic-gate infop->piclinfo.type = ptype;
29907c478bd9Sstevel@tonic-gate infop->piclinfo.accessmode = pmode;
29917c478bd9Sstevel@tonic-gate infop->piclinfo.size = psize;
29927c478bd9Sstevel@tonic-gate infop->read = readfn;
29937c478bd9Sstevel@tonic-gate infop->write = writefn;
29947c478bd9Sstevel@tonic-gate (void) strlcpy(infop->piclinfo.name, pname, PICL_PROPNAMELEN_MAX);
29957c478bd9Sstevel@tonic-gate return (PICL_SUCCESS);
29967c478bd9Sstevel@tonic-gate }
29977c478bd9Sstevel@tonic-gate
29987c478bd9Sstevel@tonic-gate /*
29997c478bd9Sstevel@tonic-gate * Creates a property, adds it to the node, and returns the property
30007c478bd9Sstevel@tonic-gate * handle to the caller if successful and proph is not NULL
30017c478bd9Sstevel@tonic-gate */
30027c478bd9Sstevel@tonic-gate int
ptree_create_and_add_prop(picl_nodehdl_t nodeh,ptree_propinfo_t * infop,void * vbuf,picl_prophdl_t * proph)30037c478bd9Sstevel@tonic-gate ptree_create_and_add_prop(picl_nodehdl_t nodeh, ptree_propinfo_t *infop,
30047c478bd9Sstevel@tonic-gate void *vbuf, picl_prophdl_t *proph)
30057c478bd9Sstevel@tonic-gate {
30067c478bd9Sstevel@tonic-gate int err;
30077c478bd9Sstevel@tonic-gate picl_prophdl_t tmph;
30087c478bd9Sstevel@tonic-gate
30097c478bd9Sstevel@tonic-gate err = ptree_create_prop(infop, vbuf, &tmph);
30107c478bd9Sstevel@tonic-gate if (err != PICL_SUCCESS)
30117c478bd9Sstevel@tonic-gate return (err);
30127c478bd9Sstevel@tonic-gate err = ptree_add_prop(nodeh, tmph);
30137c478bd9Sstevel@tonic-gate if (err != PICL_SUCCESS) {
30147c478bd9Sstevel@tonic-gate (void) ptree_destroy_prop(tmph);
30157c478bd9Sstevel@tonic-gate return (err);
30167c478bd9Sstevel@tonic-gate }
30177c478bd9Sstevel@tonic-gate if (proph)
30187c478bd9Sstevel@tonic-gate *proph = tmph;
30197c478bd9Sstevel@tonic-gate return (PICL_SUCCESS);
30207c478bd9Sstevel@tonic-gate }
30217c478bd9Sstevel@tonic-gate
30227c478bd9Sstevel@tonic-gate /*
30237c478bd9Sstevel@tonic-gate * Creates a node, adds it to its parent node, and returns the node
30247c478bd9Sstevel@tonic-gate * handle to the caller if successful
30257c478bd9Sstevel@tonic-gate */
30267c478bd9Sstevel@tonic-gate int
ptree_create_and_add_node(picl_nodehdl_t rooth,const char * name,const char * classname,picl_nodehdl_t * nodeh)30277c478bd9Sstevel@tonic-gate ptree_create_and_add_node(picl_nodehdl_t rooth, const char *name,
30287c478bd9Sstevel@tonic-gate const char *classname, picl_nodehdl_t *nodeh)
30297c478bd9Sstevel@tonic-gate {
30307c478bd9Sstevel@tonic-gate picl_nodehdl_t tmph;
30317c478bd9Sstevel@tonic-gate int err;
30327c478bd9Sstevel@tonic-gate
30337c478bd9Sstevel@tonic-gate err = ptree_create_node(name, classname, &tmph);
30347c478bd9Sstevel@tonic-gate
30357c478bd9Sstevel@tonic-gate if (err != PICL_SUCCESS)
30367c478bd9Sstevel@tonic-gate return (err);
30377c478bd9Sstevel@tonic-gate
30387c478bd9Sstevel@tonic-gate err = ptree_add_node(rooth, tmph);
30397c478bd9Sstevel@tonic-gate if (err != PICL_SUCCESS) {
30407c478bd9Sstevel@tonic-gate (void) ptree_destroy_node(tmph);
30417c478bd9Sstevel@tonic-gate return (err);
30427c478bd9Sstevel@tonic-gate }
30437c478bd9Sstevel@tonic-gate
30447c478bd9Sstevel@tonic-gate *nodeh = tmph;
30457c478bd9Sstevel@tonic-gate return (PICL_SUCCESS);
30467c478bd9Sstevel@tonic-gate }
30477c478bd9Sstevel@tonic-gate
30487c478bd9Sstevel@tonic-gate
30497c478bd9Sstevel@tonic-gate /*
30507c478bd9Sstevel@tonic-gate * recursively visit all nodes
30517c478bd9Sstevel@tonic-gate */
30527c478bd9Sstevel@tonic-gate static int
do_walk(picl_nodehdl_t rooth,const char * classname,void * c_args,int (* callback_fn)(picl_nodehdl_t hdl,void * args))30537c478bd9Sstevel@tonic-gate do_walk(picl_nodehdl_t rooth, const char *classname,
30547c478bd9Sstevel@tonic-gate void *c_args, int (*callback_fn)(picl_nodehdl_t hdl, void *args))
30557c478bd9Sstevel@tonic-gate {
30567c478bd9Sstevel@tonic-gate int err;
30577c478bd9Sstevel@tonic-gate picl_nodehdl_t chdh;
30587c478bd9Sstevel@tonic-gate char classval[PICL_CLASSNAMELEN_MAX];
30597c478bd9Sstevel@tonic-gate
30607c478bd9Sstevel@tonic-gate err = ptree_get_propval_by_name(rooth, PICL_PROP_CHILD, &chdh,
30617c478bd9Sstevel@tonic-gate sizeof (chdh));
30627c478bd9Sstevel@tonic-gate while (err == PICL_SUCCESS) {
30637c478bd9Sstevel@tonic-gate err = ptree_get_propval_by_name(chdh, PICL_PROP_CLASSNAME,
30647c478bd9Sstevel@tonic-gate classval, sizeof (classval));
30657c478bd9Sstevel@tonic-gate if (err != PICL_SUCCESS)
30667c478bd9Sstevel@tonic-gate return (err);
30677c478bd9Sstevel@tonic-gate
30687c478bd9Sstevel@tonic-gate if ((classname == NULL) || (strcmp(classname, classval) == 0)) {
30697c478bd9Sstevel@tonic-gate err = callback_fn(chdh, c_args);
30707c478bd9Sstevel@tonic-gate if (err != PICL_WALK_CONTINUE)
30717c478bd9Sstevel@tonic-gate return (err);
30727c478bd9Sstevel@tonic-gate }
30737c478bd9Sstevel@tonic-gate
30747c478bd9Sstevel@tonic-gate if ((err = do_walk(chdh, classname, c_args, callback_fn)) !=
30757c478bd9Sstevel@tonic-gate PICL_WALK_CONTINUE)
30767c478bd9Sstevel@tonic-gate return (err);
30777c478bd9Sstevel@tonic-gate
30787c478bd9Sstevel@tonic-gate err = ptree_get_propval_by_name(chdh, PICL_PROP_PEER, &chdh,
30797c478bd9Sstevel@tonic-gate sizeof (chdh));
30807c478bd9Sstevel@tonic-gate }
30817c478bd9Sstevel@tonic-gate if (err == PICL_PROPNOTFOUND) /* end of a branch */
30827c478bd9Sstevel@tonic-gate return (PICL_WALK_CONTINUE);
30837c478bd9Sstevel@tonic-gate return (err);
30847c478bd9Sstevel@tonic-gate
30857c478bd9Sstevel@tonic-gate }
30867c478bd9Sstevel@tonic-gate
30877c478bd9Sstevel@tonic-gate /*
30887c478bd9Sstevel@tonic-gate * This function visits all the nodes in the subtree rooted at <rooth>.
30897c478bd9Sstevel@tonic-gate * For each node that matches the class name specified, the callback
30907c478bd9Sstevel@tonic-gate * function is invoked.
30917c478bd9Sstevel@tonic-gate */
30927c478bd9Sstevel@tonic-gate int
ptree_walk_tree_by_class(picl_nodehdl_t rooth,const char * classname,void * c_args,int (* callback_fn)(picl_nodehdl_t hdl,void * args))30937c478bd9Sstevel@tonic-gate ptree_walk_tree_by_class(picl_nodehdl_t rooth, const char *classname,
30947c478bd9Sstevel@tonic-gate void *c_args, int (*callback_fn)(picl_nodehdl_t hdl, void *args))
30957c478bd9Sstevel@tonic-gate {
30967c478bd9Sstevel@tonic-gate int err;
30977c478bd9Sstevel@tonic-gate
30987c478bd9Sstevel@tonic-gate if (callback_fn == NULL)
30997c478bd9Sstevel@tonic-gate return (PICL_INVALIDARG);
31007c478bd9Sstevel@tonic-gate err = do_walk(rooth, classname, c_args, callback_fn);
31017c478bd9Sstevel@tonic-gate if ((err == PICL_WALK_CONTINUE) || (err == PICL_WALK_TERMINATE))
31027c478bd9Sstevel@tonic-gate return (PICL_SUCCESS);
31037c478bd9Sstevel@tonic-gate return (err);
31047c478bd9Sstevel@tonic-gate }
31057c478bd9Sstevel@tonic-gate
31067c478bd9Sstevel@tonic-gate static int
compare_propval(picl_nodehdl_t nodeh,char * pname,picl_prop_type_t ptype,void * pval,size_t valsize)31077c478bd9Sstevel@tonic-gate compare_propval(picl_nodehdl_t nodeh, char *pname, picl_prop_type_t ptype,
31087c478bd9Sstevel@tonic-gate void *pval, size_t valsize)
31097c478bd9Sstevel@tonic-gate {
31107c478bd9Sstevel@tonic-gate int err;
31117c478bd9Sstevel@tonic-gate picl_prophdl_t proph;
31127c478bd9Sstevel@tonic-gate ptree_propinfo_t propinfo;
31137c478bd9Sstevel@tonic-gate void *vbuf;
31147c478bd9Sstevel@tonic-gate
31157c478bd9Sstevel@tonic-gate err = ptree_get_prop_by_name(nodeh, pname, &proph);
31167c478bd9Sstevel@tonic-gate if (err != PICL_SUCCESS)
31177c478bd9Sstevel@tonic-gate return (0);
31187c478bd9Sstevel@tonic-gate err = ptree_get_propinfo(proph, &propinfo);
31197c478bd9Sstevel@tonic-gate if (err != PICL_SUCCESS)
31207c478bd9Sstevel@tonic-gate return (0);
31217c478bd9Sstevel@tonic-gate if (propinfo.piclinfo.type != ptype)
31227c478bd9Sstevel@tonic-gate return (0);
31237c478bd9Sstevel@tonic-gate if (propinfo.piclinfo.type == PICL_PTYPE_VOID)
31247c478bd9Sstevel@tonic-gate return (1);
31257c478bd9Sstevel@tonic-gate if (pval == NULL)
31267c478bd9Sstevel@tonic-gate return (0);
31277c478bd9Sstevel@tonic-gate if (valsize > propinfo.piclinfo.size)
31287c478bd9Sstevel@tonic-gate return (0);
31297c478bd9Sstevel@tonic-gate vbuf = alloca(propinfo.piclinfo.size);
31307c478bd9Sstevel@tonic-gate if (vbuf == NULL)
31317c478bd9Sstevel@tonic-gate return (0);
31327c478bd9Sstevel@tonic-gate err = ptree_get_propval(proph, vbuf, propinfo.piclinfo.size);
31337c478bd9Sstevel@tonic-gate if (err != PICL_SUCCESS)
31347c478bd9Sstevel@tonic-gate return (0);
31357c478bd9Sstevel@tonic-gate if (memcmp(vbuf, pval, valsize) == 0)
31367c478bd9Sstevel@tonic-gate return (1);
31377c478bd9Sstevel@tonic-gate return (0);
31387c478bd9Sstevel@tonic-gate }
31397c478bd9Sstevel@tonic-gate
31407c478bd9Sstevel@tonic-gate
31417c478bd9Sstevel@tonic-gate /*
31427c478bd9Sstevel@tonic-gate * This function traverses the subtree and finds a node that has a property
31437c478bd9Sstevel@tonic-gate * of the specified name and type with the specified value.
31447c478bd9Sstevel@tonic-gate * The matched node in the tree is returned in retnodeh. If there is
31457c478bd9Sstevel@tonic-gate * no node with that property, then PICL_NODENOTFOUND is returned.
31467c478bd9Sstevel@tonic-gate */
31477c478bd9Sstevel@tonic-gate int
ptree_find_node(picl_nodehdl_t rooth,char * pname,picl_prop_type_t ptype,void * pval,size_t valsize,picl_nodehdl_t * retnodeh)31487c478bd9Sstevel@tonic-gate ptree_find_node(picl_nodehdl_t rooth, char *pname, picl_prop_type_t ptype,
31497c478bd9Sstevel@tonic-gate void *pval, size_t valsize, picl_nodehdl_t *retnodeh)
31507c478bd9Sstevel@tonic-gate {
31517c478bd9Sstevel@tonic-gate int err;
31527c478bd9Sstevel@tonic-gate picl_nodehdl_t chdh;
31537c478bd9Sstevel@tonic-gate
31547c478bd9Sstevel@tonic-gate if (pname == NULL)
31557c478bd9Sstevel@tonic-gate return (PICL_INVALIDARG);
31567c478bd9Sstevel@tonic-gate err = ptree_get_propval_by_name(rooth, PICL_PROP_CHILD, &chdh,
31577c478bd9Sstevel@tonic-gate sizeof (chdh));
31587c478bd9Sstevel@tonic-gate
31597c478bd9Sstevel@tonic-gate while (err == PICL_SUCCESS) {
31607c478bd9Sstevel@tonic-gate if (compare_propval(chdh, pname, ptype, pval, valsize)) {
31617c478bd9Sstevel@tonic-gate if (retnodeh)
31627c478bd9Sstevel@tonic-gate *retnodeh = chdh;
31637c478bd9Sstevel@tonic-gate return (PICL_SUCCESS);
31647c478bd9Sstevel@tonic-gate }
31657c478bd9Sstevel@tonic-gate
31667c478bd9Sstevel@tonic-gate err = ptree_find_node(chdh, pname, ptype, pval, valsize,
31677c478bd9Sstevel@tonic-gate retnodeh);
31687c478bd9Sstevel@tonic-gate if (err != PICL_NODENOTFOUND)
31697c478bd9Sstevel@tonic-gate return (err);
31707c478bd9Sstevel@tonic-gate
31717c478bd9Sstevel@tonic-gate err = ptree_get_propval_by_name(chdh, PICL_PROP_PEER, &chdh,
31727c478bd9Sstevel@tonic-gate sizeof (chdh));
31737c478bd9Sstevel@tonic-gate }
31747c478bd9Sstevel@tonic-gate if (err == PICL_PROPNOTFOUND)
31757c478bd9Sstevel@tonic-gate return (PICL_NODENOTFOUND);
31767c478bd9Sstevel@tonic-gate return (err);
31777c478bd9Sstevel@tonic-gate }
31787c478bd9Sstevel@tonic-gate
31797c478bd9Sstevel@tonic-gate /*
31807c478bd9Sstevel@tonic-gate * This function gets the frutree parent for a given node.
31817c478bd9Sstevel@tonic-gate * Traverse up the tree and look for the following properties:
31827c478bd9Sstevel@tonic-gate * Frutree parent reference properties:
31837c478bd9Sstevel@tonic-gate * _fru_parent
31847c478bd9Sstevel@tonic-gate * _location_parent
31857c478bd9Sstevel@tonic-gate * _port_parent
31867c478bd9Sstevel@tonic-gate * If the frutree reference property is found, return its value.
31877c478bd9Sstevel@tonic-gate * Else, return the handle of /frutree/chassis.
31887c478bd9Sstevel@tonic-gate */
31897c478bd9Sstevel@tonic-gate int
ptree_get_frutree_parent(picl_nodehdl_t nodeh,picl_nodehdl_t * fruh)31907c478bd9Sstevel@tonic-gate ptree_get_frutree_parent(picl_nodehdl_t nodeh, picl_nodehdl_t *fruh)
31917c478bd9Sstevel@tonic-gate {
31927c478bd9Sstevel@tonic-gate int err;
31937c478bd9Sstevel@tonic-gate picl_nodehdl_t nparh;
31947c478bd9Sstevel@tonic-gate picl_nodehdl_t fruparh;
31957c478bd9Sstevel@tonic-gate
31967c478bd9Sstevel@tonic-gate err = PICL_SUCCESS;
31977c478bd9Sstevel@tonic-gate nparh = nodeh;
31987c478bd9Sstevel@tonic-gate while (err == PICL_SUCCESS) {
31997c478bd9Sstevel@tonic-gate err = ptree_get_propval_by_name(nparh, PICL_REFPROP_FRU_PARENT,
32007c478bd9Sstevel@tonic-gate &fruparh, sizeof (fruparh));
32017c478bd9Sstevel@tonic-gate if (err == PICL_SUCCESS) {
32027c478bd9Sstevel@tonic-gate *fruh = fruparh;
32037c478bd9Sstevel@tonic-gate return (PICL_SUCCESS);
32047c478bd9Sstevel@tonic-gate }
32057c478bd9Sstevel@tonic-gate err = ptree_get_propval_by_name(nparh,
32067c478bd9Sstevel@tonic-gate PICL_REFPROP_LOC_PARENT, &fruparh, sizeof (fruparh));
32077c478bd9Sstevel@tonic-gate if (err == PICL_SUCCESS) {
32087c478bd9Sstevel@tonic-gate *fruh = fruparh;
32097c478bd9Sstevel@tonic-gate return (PICL_SUCCESS);
32107c478bd9Sstevel@tonic-gate }
32117c478bd9Sstevel@tonic-gate err = ptree_get_propval_by_name(nparh, PICL_REFPROP_PORT_PARENT,
32127c478bd9Sstevel@tonic-gate &fruparh, sizeof (fruparh));
32137c478bd9Sstevel@tonic-gate if (err == PICL_SUCCESS) {
32147c478bd9Sstevel@tonic-gate *fruh = fruparh;
32157c478bd9Sstevel@tonic-gate return (PICL_SUCCESS);
32167c478bd9Sstevel@tonic-gate }
32177c478bd9Sstevel@tonic-gate
32187c478bd9Sstevel@tonic-gate err = ptree_get_propval_by_name(nparh, PICL_PROP_PARENT, &nparh,
32197c478bd9Sstevel@tonic-gate sizeof (nparh));
32207c478bd9Sstevel@tonic-gate }
32217c478bd9Sstevel@tonic-gate
32227c478bd9Sstevel@tonic-gate if (err == PICL_PROPNOTFOUND) { /* return /frutree/chassis handle */
32237c478bd9Sstevel@tonic-gate err = ptree_get_node_by_path(PICL_FRUTREE_CHASSIS, &fruparh);
32247c478bd9Sstevel@tonic-gate if (err == PICL_SUCCESS) {
32257c478bd9Sstevel@tonic-gate *fruh = fruparh;
32267c478bd9Sstevel@tonic-gate return (PICL_SUCCESS);
32277c478bd9Sstevel@tonic-gate }
32287c478bd9Sstevel@tonic-gate }
32297c478bd9Sstevel@tonic-gate return (err);
32307c478bd9Sstevel@tonic-gate }
32317c478bd9Sstevel@tonic-gate
32327c478bd9Sstevel@tonic-gate /*
32337c478bd9Sstevel@tonic-gate * This function is called by plug-ins to register with the daemon
32347c478bd9Sstevel@tonic-gate */
32357c478bd9Sstevel@tonic-gate int
picld_plugin_register(picld_plugin_reg_t * regp)32367c478bd9Sstevel@tonic-gate picld_plugin_register(picld_plugin_reg_t *regp)
32377c478bd9Sstevel@tonic-gate {
32387c478bd9Sstevel@tonic-gate picld_plugin_reg_list_t *el;
32397c478bd9Sstevel@tonic-gate picld_plugin_reg_list_t *tmp;
32407c478bd9Sstevel@tonic-gate
32417c478bd9Sstevel@tonic-gate if (regp == NULL)
32427c478bd9Sstevel@tonic-gate return (PICL_FAILURE);
32437c478bd9Sstevel@tonic-gate
32447c478bd9Sstevel@tonic-gate if (regp->version != PICLD_PLUGIN_VERSION_1)
32457c478bd9Sstevel@tonic-gate return (PICL_NOTSUPPORTED);
32467c478bd9Sstevel@tonic-gate
32477c478bd9Sstevel@tonic-gate el = malloc(sizeof (picld_plugin_reg_list_t));
32487c478bd9Sstevel@tonic-gate if (el == NULL)
32497c478bd9Sstevel@tonic-gate return (PICL_FAILURE);
32507c478bd9Sstevel@tonic-gate el->reg.version = regp->version;
32517c478bd9Sstevel@tonic-gate el->reg.critical = regp->critical;
32527c478bd9Sstevel@tonic-gate if (regp->name)
32537c478bd9Sstevel@tonic-gate el->reg.name = strdup(regp->name);
32547c478bd9Sstevel@tonic-gate if (el->reg.name == NULL)
32557c478bd9Sstevel@tonic-gate return (PICL_FAILURE);
32567c478bd9Sstevel@tonic-gate
32577c478bd9Sstevel@tonic-gate el->reg.plugin_init = regp->plugin_init;
32587c478bd9Sstevel@tonic-gate el->reg.plugin_fini = regp->plugin_fini;
32597c478bd9Sstevel@tonic-gate el->next = NULL;
32607c478bd9Sstevel@tonic-gate
32617c478bd9Sstevel@tonic-gate if (plugin_reg_list == NULL) {
32627c478bd9Sstevel@tonic-gate plugin_reg_list = el;
32637c478bd9Sstevel@tonic-gate } else { /* add to end */
32647c478bd9Sstevel@tonic-gate tmp = plugin_reg_list;
32657c478bd9Sstevel@tonic-gate while (tmp->next != NULL)
32667c478bd9Sstevel@tonic-gate tmp = tmp->next;
32677c478bd9Sstevel@tonic-gate tmp->next = el;
32687c478bd9Sstevel@tonic-gate }
32697c478bd9Sstevel@tonic-gate
32707c478bd9Sstevel@tonic-gate return (PICL_SUCCESS);
32717c478bd9Sstevel@tonic-gate }
32727c478bd9Sstevel@tonic-gate
32737c478bd9Sstevel@tonic-gate /*
32747c478bd9Sstevel@tonic-gate * Call fini routines of the registered plugins
32757c478bd9Sstevel@tonic-gate */
32767c478bd9Sstevel@tonic-gate static void
plugin_fini(picld_plugin_reg_list_t * p)32777c478bd9Sstevel@tonic-gate plugin_fini(picld_plugin_reg_list_t *p)
32787c478bd9Sstevel@tonic-gate {
32797c478bd9Sstevel@tonic-gate if (p == NULL)
32807c478bd9Sstevel@tonic-gate return;
32817c478bd9Sstevel@tonic-gate
32827c478bd9Sstevel@tonic-gate plugin_fini(p->next);
32837c478bd9Sstevel@tonic-gate if (p->reg.plugin_fini)
32847c478bd9Sstevel@tonic-gate (p->reg.plugin_fini)();
32857c478bd9Sstevel@tonic-gate }
32867c478bd9Sstevel@tonic-gate
32877c478bd9Sstevel@tonic-gate /*
32887c478bd9Sstevel@tonic-gate * Create PICL Tree
32897c478bd9Sstevel@tonic-gate */
32907c478bd9Sstevel@tonic-gate
32917c478bd9Sstevel@tonic-gate static void
init_plugin_reg_list(void)32927c478bd9Sstevel@tonic-gate init_plugin_reg_list(void)
32937c478bd9Sstevel@tonic-gate {
32947c478bd9Sstevel@tonic-gate plugin_reg_list = NULL;
32957c478bd9Sstevel@tonic-gate }
32967c478bd9Sstevel@tonic-gate
32977c478bd9Sstevel@tonic-gate static int
picltree_set_root(picl_nodehdl_t rooth)32987c478bd9Sstevel@tonic-gate picltree_set_root(picl_nodehdl_t rooth)
32997c478bd9Sstevel@tonic-gate {
33007c478bd9Sstevel@tonic-gate picl_obj_t *pobj;
33017c478bd9Sstevel@tonic-gate int err;
33027c478bd9Sstevel@tonic-gate
33037c478bd9Sstevel@tonic-gate (void) rw_rdlock(&ptree_rwlock); /* lock ptree */
33047c478bd9Sstevel@tonic-gate pobj = NULL;
33057c478bd9Sstevel@tonic-gate err = lookup_and_lock_node(RDLOCK_NODE, rooth, &pobj); /* lock node */
33067c478bd9Sstevel@tonic-gate if (err != PICL_SUCCESS) {
33077c478bd9Sstevel@tonic-gate (void) rw_unlock(&ptree_rwlock);
33087c478bd9Sstevel@tonic-gate return (PICL_FAILURE);
33097c478bd9Sstevel@tonic-gate }
33107c478bd9Sstevel@tonic-gate piclize_node(pobj);
33117c478bd9Sstevel@tonic-gate picl_root_obj = pobj;
33127c478bd9Sstevel@tonic-gate ptree_root_hdl = pobj->ptree_hdl;
33137c478bd9Sstevel@tonic-gate unlock_node(pobj); /* unlock node */
33147c478bd9Sstevel@tonic-gate (void) rw_unlock(&ptree_rwlock); /* unlock ptree */
33157c478bd9Sstevel@tonic-gate return (PICL_SUCCESS);
33167c478bd9Sstevel@tonic-gate }
33177c478bd9Sstevel@tonic-gate
33187c478bd9Sstevel@tonic-gate static int
picltree_init(void)33197c478bd9Sstevel@tonic-gate picltree_init(void)
33207c478bd9Sstevel@tonic-gate {
33217c478bd9Sstevel@tonic-gate (void) rwlock_init(&ptree_rwlock, USYNC_THREAD, NULL);
33227c478bd9Sstevel@tonic-gate (void) rwlock_init(&picltbl_rwlock, USYNC_THREAD, NULL);
33237c478bd9Sstevel@tonic-gate
33247c478bd9Sstevel@tonic-gate if (hash_init(&picltbl) < 0)
33257c478bd9Sstevel@tonic-gate return (PICL_FAILURE);
33267c478bd9Sstevel@tonic-gate if (hash_init(&ptreetbl) < 0)
33277c478bd9Sstevel@tonic-gate return (PICL_FAILURE);
33287c478bd9Sstevel@tonic-gate
33297c478bd9Sstevel@tonic-gate if (pthread_mutex_init(&ptreehdl_lock, NULL) != 0)
33307c478bd9Sstevel@tonic-gate return (PICL_FAILURE);
33317c478bd9Sstevel@tonic-gate
33327c478bd9Sstevel@tonic-gate if (pthread_mutex_init(&piclhdl_lock, NULL) != 0)
33337c478bd9Sstevel@tonic-gate return (PICL_FAILURE);
33347c478bd9Sstevel@tonic-gate
33357c478bd9Sstevel@tonic-gate if (pthread_mutex_init(&evtq_lock, NULL) != 0)
33367c478bd9Sstevel@tonic-gate return (PICL_FAILURE);
33377c478bd9Sstevel@tonic-gate if (pthread_cond_init(&evtq_cv, NULL) != 0)
33387c478bd9Sstevel@tonic-gate return (PICL_FAILURE);
33397c478bd9Sstevel@tonic-gate if (pthread_mutex_init(&evthandler_lock, NULL) != 0)
33407c478bd9Sstevel@tonic-gate return (PICL_FAILURE);
33417c478bd9Sstevel@tonic-gate
33427c478bd9Sstevel@tonic-gate picl_root_obj = NULL;
33437c478bd9Sstevel@tonic-gate eventqp = NULL;
33447c478bd9Sstevel@tonic-gate evt_handlers = NULL;
33457c478bd9Sstevel@tonic-gate ptree_root_hdl = PICL_INVALID_PICLHDL;
33467c478bd9Sstevel@tonic-gate
33477c478bd9Sstevel@tonic-gate return (PICL_SUCCESS);
33487c478bd9Sstevel@tonic-gate }
33497c478bd9Sstevel@tonic-gate
33507c478bd9Sstevel@tonic-gate static void
add_unique_plugin_to_list(char * path,char * name)33517c478bd9Sstevel@tonic-gate add_unique_plugin_to_list(char *path, char *name)
33527c478bd9Sstevel@tonic-gate {
33537c478bd9Sstevel@tonic-gate char *buf;
33547c478bd9Sstevel@tonic-gate picld_plugin_desc_t *pl;
33557c478bd9Sstevel@tonic-gate picld_plugin_desc_t *tmp;
33567c478bd9Sstevel@tonic-gate
33577c478bd9Sstevel@tonic-gate pl = plugin_desc;
33587c478bd9Sstevel@tonic-gate while (pl != NULL) {
33597c478bd9Sstevel@tonic-gate if (strcmp(pl->libname, name) == 0)
33607c478bd9Sstevel@tonic-gate return;
33617c478bd9Sstevel@tonic-gate else
33627c478bd9Sstevel@tonic-gate pl = pl->next;
33637c478bd9Sstevel@tonic-gate }
33647c478bd9Sstevel@tonic-gate
33657c478bd9Sstevel@tonic-gate pl = malloc(sizeof (picld_plugin_desc_t));
33667c478bd9Sstevel@tonic-gate if (pl == NULL)
33677c478bd9Sstevel@tonic-gate return;
33687c478bd9Sstevel@tonic-gate
33697c478bd9Sstevel@tonic-gate pl->libname = strdup(name);
33707c478bd9Sstevel@tonic-gate if (pl->libname == NULL)
33717c478bd9Sstevel@tonic-gate return;
33727c478bd9Sstevel@tonic-gate buf = alloca(strlen(name) + strlen(path) + 2);
33737c478bd9Sstevel@tonic-gate if (buf == NULL)
33747c478bd9Sstevel@tonic-gate return;
33757c478bd9Sstevel@tonic-gate (void) strcpy(buf, path);
33767c478bd9Sstevel@tonic-gate (void) strcat(buf, name);
33777c478bd9Sstevel@tonic-gate pl->pathname = strdup(buf);
33787c478bd9Sstevel@tonic-gate if (pl->pathname == NULL)
33797c478bd9Sstevel@tonic-gate return;
33807c478bd9Sstevel@tonic-gate
33817c478bd9Sstevel@tonic-gate pl->next = NULL;
33827c478bd9Sstevel@tonic-gate
33837c478bd9Sstevel@tonic-gate if (plugin_desc == NULL)
33847c478bd9Sstevel@tonic-gate plugin_desc = pl;
33857c478bd9Sstevel@tonic-gate else {
33867c478bd9Sstevel@tonic-gate tmp = plugin_desc;
33877c478bd9Sstevel@tonic-gate while (tmp->next != NULL)
33887c478bd9Sstevel@tonic-gate tmp = tmp->next;
33897c478bd9Sstevel@tonic-gate tmp->next = pl;
33907c478bd9Sstevel@tonic-gate }
33917c478bd9Sstevel@tonic-gate }
33927c478bd9Sstevel@tonic-gate
33937c478bd9Sstevel@tonic-gate static void
get_plugins_from_dir(char * dirname)33947c478bd9Sstevel@tonic-gate get_plugins_from_dir(char *dirname)
33957c478bd9Sstevel@tonic-gate {
33967c478bd9Sstevel@tonic-gate struct dirent *ent;
33977c478bd9Sstevel@tonic-gate DIR *dir;
33987c478bd9Sstevel@tonic-gate int len;
33997c478bd9Sstevel@tonic-gate int solen = strlen(SO_VERS) + 1;
34007c478bd9Sstevel@tonic-gate
34017c478bd9Sstevel@tonic-gate if ((dir = opendir(dirname)) == NULL)
34027c478bd9Sstevel@tonic-gate return;
34037c478bd9Sstevel@tonic-gate
34047c478bd9Sstevel@tonic-gate while ((ent = readdir(dir)) != NULL) {
34057c478bd9Sstevel@tonic-gate if ((strcmp(ent->d_name, ".") == 0) ||
34067c478bd9Sstevel@tonic-gate (strcmp(ent->d_name, "..") == 0))
34077c478bd9Sstevel@tonic-gate continue;
34087c478bd9Sstevel@tonic-gate
34097c478bd9Sstevel@tonic-gate len = strlen(ent->d_name) + 1;
34107c478bd9Sstevel@tonic-gate if (len < solen)
34117c478bd9Sstevel@tonic-gate continue;
34127c478bd9Sstevel@tonic-gate
34137c478bd9Sstevel@tonic-gate if (strcmp(ent->d_name + (len - solen), SO_VERS) == 0)
34147c478bd9Sstevel@tonic-gate add_unique_plugin_to_list(dirname, ent->d_name);
34157c478bd9Sstevel@tonic-gate }
34167c478bd9Sstevel@tonic-gate
34177c478bd9Sstevel@tonic-gate (void) closedir(dir);
34187c478bd9Sstevel@tonic-gate }
34197c478bd9Sstevel@tonic-gate
34207c478bd9Sstevel@tonic-gate
34217c478bd9Sstevel@tonic-gate static void
init_plugin_list(void)34227c478bd9Sstevel@tonic-gate init_plugin_list(void)
34237c478bd9Sstevel@tonic-gate {
34247c478bd9Sstevel@tonic-gate char nmbuf[SYS_NMLN];
34257c478bd9Sstevel@tonic-gate char pname[PATH_MAX];
34267c478bd9Sstevel@tonic-gate
34277c478bd9Sstevel@tonic-gate plugin_desc = NULL;
34287c478bd9Sstevel@tonic-gate if (sysinfo(SI_PLATFORM, nmbuf, sizeof (nmbuf)) != -1) {
34297c478bd9Sstevel@tonic-gate (void) snprintf(pname, PATH_MAX, PICLD_PLAT_PLUGIN_DIRF, nmbuf);
34307c478bd9Sstevel@tonic-gate if (access(pname, R_OK) == 0)
34317c478bd9Sstevel@tonic-gate get_plugins_from_dir(pname);
34327c478bd9Sstevel@tonic-gate }
34337c478bd9Sstevel@tonic-gate
34347c478bd9Sstevel@tonic-gate if (sysinfo(SI_MACHINE, nmbuf, sizeof (nmbuf)) != -1) {
34357c478bd9Sstevel@tonic-gate (void) snprintf(pname, PATH_MAX, PICLD_PLAT_PLUGIN_DIRF, nmbuf);
34367c478bd9Sstevel@tonic-gate if (access(pname, R_OK) == 0)
34377c478bd9Sstevel@tonic-gate get_plugins_from_dir(pname);
34387c478bd9Sstevel@tonic-gate }
34397c478bd9Sstevel@tonic-gate
34407c478bd9Sstevel@tonic-gate (void) snprintf(pname, PATH_MAX, "%s/", PICLD_COMMON_PLUGIN_DIR);
34417c478bd9Sstevel@tonic-gate if (access(pname, R_OK) == 0)
34427c478bd9Sstevel@tonic-gate get_plugins_from_dir(pname);
34437c478bd9Sstevel@tonic-gate }
34447c478bd9Sstevel@tonic-gate
34457c478bd9Sstevel@tonic-gate static void
load_plugins(void)34467c478bd9Sstevel@tonic-gate load_plugins(void)
34477c478bd9Sstevel@tonic-gate {
34487c478bd9Sstevel@tonic-gate picld_plugin_desc_t *pl;
34497c478bd9Sstevel@tonic-gate
34507c478bd9Sstevel@tonic-gate pl = plugin_desc;
34517c478bd9Sstevel@tonic-gate while (pl != NULL) {
34527c478bd9Sstevel@tonic-gate pl->dlh = dlopen(pl->pathname, RTLD_LAZY|RTLD_LOCAL);
34537c478bd9Sstevel@tonic-gate if (pl->dlh == NULL) {
34547c478bd9Sstevel@tonic-gate syslog(LOG_CRIT, dlerror());
34557c478bd9Sstevel@tonic-gate return;
34567c478bd9Sstevel@tonic-gate }
34577c478bd9Sstevel@tonic-gate pl = pl->next;
34587c478bd9Sstevel@tonic-gate }
34597c478bd9Sstevel@tonic-gate }
34607c478bd9Sstevel@tonic-gate
34617c478bd9Sstevel@tonic-gate
34627c478bd9Sstevel@tonic-gate
34637c478bd9Sstevel@tonic-gate static int
add_root_props(picl_nodehdl_t rooth)34647c478bd9Sstevel@tonic-gate add_root_props(picl_nodehdl_t rooth)
34657c478bd9Sstevel@tonic-gate {
34667c478bd9Sstevel@tonic-gate int err;
34677c478bd9Sstevel@tonic-gate picl_prophdl_t proph;
34687c478bd9Sstevel@tonic-gate ptree_propinfo_t pinfo;
34697c478bd9Sstevel@tonic-gate float picl_vers;
34707c478bd9Sstevel@tonic-gate
34717c478bd9Sstevel@tonic-gate #define PICL_PROP_PICL_VERSION "PICLVersion"
34727c478bd9Sstevel@tonic-gate #define PICL_VERSION 1.1
34737c478bd9Sstevel@tonic-gate
34747c478bd9Sstevel@tonic-gate err = ptree_init_propinfo(&pinfo, PTREE_PROPINFO_VERSION_1,
34757c478bd9Sstevel@tonic-gate PICL_PTYPE_FLOAT, PICL_READ, sizeof (picl_vers),
34767c478bd9Sstevel@tonic-gate PICL_PROP_PICL_VERSION, NULL, NULL);
34777c478bd9Sstevel@tonic-gate if (err != PICL_SUCCESS)
34787c478bd9Sstevel@tonic-gate return (err);
34797c478bd9Sstevel@tonic-gate
34807c478bd9Sstevel@tonic-gate picl_vers = PICL_VERSION;
34817c478bd9Sstevel@tonic-gate err = ptree_create_and_add_prop(rooth, &pinfo, &picl_vers, &proph);
34827c478bd9Sstevel@tonic-gate return (err);
34837c478bd9Sstevel@tonic-gate }
34847c478bd9Sstevel@tonic-gate
34857c478bd9Sstevel@tonic-gate static int
construct_picltree(void)34867c478bd9Sstevel@tonic-gate construct_picltree(void)
34877c478bd9Sstevel@tonic-gate {
34887c478bd9Sstevel@tonic-gate int err;
34897c478bd9Sstevel@tonic-gate picld_plugin_reg_list_t *iter;
34907c478bd9Sstevel@tonic-gate picl_nodehdl_t rhdl;
34917c478bd9Sstevel@tonic-gate
34927c478bd9Sstevel@tonic-gate /*
34937c478bd9Sstevel@tonic-gate * Create "/" node
34947c478bd9Sstevel@tonic-gate */
34957c478bd9Sstevel@tonic-gate if ((err = ptree_create_node(PICL_NODE_ROOT, PICL_CLASS_PICL,
34967c478bd9Sstevel@tonic-gate &rhdl)) != PICL_SUCCESS) {
34977c478bd9Sstevel@tonic-gate return (err);
34987c478bd9Sstevel@tonic-gate }
34997c478bd9Sstevel@tonic-gate
35007c478bd9Sstevel@tonic-gate if (picltree_set_root(rhdl) != PICL_SUCCESS) {
35017c478bd9Sstevel@tonic-gate return (PICL_FAILURE);
35027c478bd9Sstevel@tonic-gate }
35037c478bd9Sstevel@tonic-gate
35047c478bd9Sstevel@tonic-gate err = add_root_props(rhdl);
35057c478bd9Sstevel@tonic-gate if (err != PICL_SUCCESS)
35067c478bd9Sstevel@tonic-gate return (err);
35077c478bd9Sstevel@tonic-gate
35087c478bd9Sstevel@tonic-gate /*
35097c478bd9Sstevel@tonic-gate * Initialize the registered plug-in modules
35107c478bd9Sstevel@tonic-gate */
35117c478bd9Sstevel@tonic-gate iter = plugin_reg_list;
35127c478bd9Sstevel@tonic-gate while (iter != NULL) {
35137c478bd9Sstevel@tonic-gate if (iter->reg.plugin_init)
35147c478bd9Sstevel@tonic-gate (iter->reg.plugin_init)();
35157c478bd9Sstevel@tonic-gate iter = iter->next;
35167c478bd9Sstevel@tonic-gate }
35177c478bd9Sstevel@tonic-gate return (PICL_SUCCESS);
35187c478bd9Sstevel@tonic-gate }
35197c478bd9Sstevel@tonic-gate
35207c478bd9Sstevel@tonic-gate void
xptree_destroy(void)35217c478bd9Sstevel@tonic-gate xptree_destroy(void)
35227c478bd9Sstevel@tonic-gate {
35237c478bd9Sstevel@tonic-gate dbg_print(1, "xptree_destroy: picl_root_obj = %s\n",
35247c478bd9Sstevel@tonic-gate (picl_root_obj == NULL ? "NULL" : "not-NULL"));
35257c478bd9Sstevel@tonic-gate
35267c478bd9Sstevel@tonic-gate if (picl_root_obj == NULL)
35277c478bd9Sstevel@tonic-gate return;
35287c478bd9Sstevel@tonic-gate
35297c478bd9Sstevel@tonic-gate dbg_print(1, "xptree_destroy: call plugin_fini\n");
35307c478bd9Sstevel@tonic-gate plugin_fini(plugin_reg_list);
35317c478bd9Sstevel@tonic-gate dbg_print(1, "xptree_destroy: plugin_fini DONE\n");
35327c478bd9Sstevel@tonic-gate
35337c478bd9Sstevel@tonic-gate (void) ptree_delete_node(picl_root_obj->ptree_hdl);
35347c478bd9Sstevel@tonic-gate (void) ptree_destroy_node(picl_root_obj->ptree_hdl);
35357c478bd9Sstevel@tonic-gate
35367c478bd9Sstevel@tonic-gate (void) rw_wrlock(&ptree_rwlock);
35377c478bd9Sstevel@tonic-gate picl_root_obj = NULL;
35387c478bd9Sstevel@tonic-gate (void) rw_unlock(&ptree_rwlock);
35397c478bd9Sstevel@tonic-gate }
35407c478bd9Sstevel@tonic-gate
35417c478bd9Sstevel@tonic-gate /*ARGSUSED*/
35427c478bd9Sstevel@tonic-gate int
xptree_initialize(int flg)35437c478bd9Sstevel@tonic-gate xptree_initialize(int flg)
35447c478bd9Sstevel@tonic-gate {
35457c478bd9Sstevel@tonic-gate int err;
35467c478bd9Sstevel@tonic-gate pthread_attr_t attr;
35477c478bd9Sstevel@tonic-gate pthread_t tid;
35487c478bd9Sstevel@tonic-gate
35497c478bd9Sstevel@tonic-gate picld_pid = getpid();
35507c478bd9Sstevel@tonic-gate picld_cred.dc_euid = geteuid();
35517c478bd9Sstevel@tonic-gate picld_cred.dc_egid = getegid();
35527c478bd9Sstevel@tonic-gate picld_cred.dc_ruid = getuid();
35537c478bd9Sstevel@tonic-gate picld_cred.dc_rgid = getgid();
35547c478bd9Sstevel@tonic-gate picld_cred.dc_pid = getpid();
35557c478bd9Sstevel@tonic-gate
35567c478bd9Sstevel@tonic-gate picl_hdl_hi = 1;
35577c478bd9Sstevel@tonic-gate ptree_hdl_hi = 1;
35587c478bd9Sstevel@tonic-gate ptree_generation = 1;
35597c478bd9Sstevel@tonic-gate qempty_wait = 0;
35607c478bd9Sstevel@tonic-gate
35617c478bd9Sstevel@tonic-gate if (pthread_mutex_init(&ptree_refresh_mutex, NULL) != 0)
35627c478bd9Sstevel@tonic-gate return (PICL_FAILURE);
35637c478bd9Sstevel@tonic-gate
35647c478bd9Sstevel@tonic-gate if (picltree_init() != PICL_SUCCESS)
35657c478bd9Sstevel@tonic-gate return (PICL_FAILURE);
35667c478bd9Sstevel@tonic-gate
35677c478bd9Sstevel@tonic-gate init_plugin_reg_list();
35687c478bd9Sstevel@tonic-gate init_plugin_list();
35697c478bd9Sstevel@tonic-gate load_plugins();
35707c478bd9Sstevel@tonic-gate
35717c478bd9Sstevel@tonic-gate err = construct_picltree();
35727c478bd9Sstevel@tonic-gate if (err != PICL_SUCCESS)
35737c478bd9Sstevel@tonic-gate return (err);
35747c478bd9Sstevel@tonic-gate
35757c478bd9Sstevel@tonic-gate /*
35767c478bd9Sstevel@tonic-gate * Dispatch events after all plug-ins have initialized
35777c478bd9Sstevel@tonic-gate */
35787c478bd9Sstevel@tonic-gate if (pthread_attr_init(&attr) != 0)
35797c478bd9Sstevel@tonic-gate return (PICL_FAILURE);
35807c478bd9Sstevel@tonic-gate
35817c478bd9Sstevel@tonic-gate (void) pthread_attr_setscope(&attr, PTHREAD_SCOPE_SYSTEM);
35827c478bd9Sstevel@tonic-gate if (pthread_create(&tid, &attr, ptree_event_thread, NULL))
35837c478bd9Sstevel@tonic-gate return (PICL_FAILURE);
35847c478bd9Sstevel@tonic-gate
35857c478bd9Sstevel@tonic-gate return (PICL_SUCCESS);
35867c478bd9Sstevel@tonic-gate }
35877c478bd9Sstevel@tonic-gate
35887c478bd9Sstevel@tonic-gate int
xptree_reinitialize(void)35897c478bd9Sstevel@tonic-gate xptree_reinitialize(void)
35907c478bd9Sstevel@tonic-gate {
35917c478bd9Sstevel@tonic-gate int err;
35927c478bd9Sstevel@tonic-gate
35937c478bd9Sstevel@tonic-gate /*
35947c478bd9Sstevel@tonic-gate * Wait for eventq to become empty
35957c478bd9Sstevel@tonic-gate */
35967c478bd9Sstevel@tonic-gate dbg_print(1, "xptree_reinitialize: wait for evtq empty\n");
35977c478bd9Sstevel@tonic-gate (void) pthread_mutex_lock(&evtq_lock);
35987c478bd9Sstevel@tonic-gate qempty_wait = 1;
35997c478bd9Sstevel@tonic-gate while (eventqp != NULL)
36007c478bd9Sstevel@tonic-gate (void) pthread_cond_wait(&evtq_empty, &evtq_lock);
36017c478bd9Sstevel@tonic-gate qempty_wait = 0;
36027c478bd9Sstevel@tonic-gate (void) pthread_mutex_unlock(&evtq_lock);
36037c478bd9Sstevel@tonic-gate dbg_print(1, "xptree_reinitialize: evtq empty is EMPTY\n");
36047c478bd9Sstevel@tonic-gate
36057c478bd9Sstevel@tonic-gate (void) rw_wrlock(&ptree_rwlock);
36067c478bd9Sstevel@tonic-gate picl_root_obj = NULL;
36077c478bd9Sstevel@tonic-gate ptree_root_hdl = PICL_INVALID_PICLHDL;
36087c478bd9Sstevel@tonic-gate (void) rw_unlock(&ptree_rwlock);
36097c478bd9Sstevel@tonic-gate (void) pthread_mutex_lock(&ptree_refresh_mutex);
36107c478bd9Sstevel@tonic-gate ++ptree_generation;
36117c478bd9Sstevel@tonic-gate (void) pthread_mutex_unlock(&ptree_refresh_mutex);
36127c478bd9Sstevel@tonic-gate
36137c478bd9Sstevel@tonic-gate err = construct_picltree();
36147c478bd9Sstevel@tonic-gate (void) pthread_mutex_lock(&ptree_refresh_mutex);
36157c478bd9Sstevel@tonic-gate (void) pthread_cond_broadcast(&ptree_refresh_cond);
36167c478bd9Sstevel@tonic-gate (void) pthread_mutex_unlock(&ptree_refresh_mutex);
36177c478bd9Sstevel@tonic-gate
36187c478bd9Sstevel@tonic-gate (void) pthread_mutex_lock(&evtq_lock);
36197c478bd9Sstevel@tonic-gate (void) pthread_cond_broadcast(&evtq_cv);
36207c478bd9Sstevel@tonic-gate (void) pthread_mutex_unlock(&evtq_lock);
36217c478bd9Sstevel@tonic-gate
36227c478bd9Sstevel@tonic-gate return (err);
36237c478bd9Sstevel@tonic-gate }
36247c478bd9Sstevel@tonic-gate
36257c478bd9Sstevel@tonic-gate /*
36267c478bd9Sstevel@tonic-gate * This function is called by the PICL daemon on behalf of clients to
36277c478bd9Sstevel@tonic-gate * wait for a tree refresh
36287c478bd9Sstevel@tonic-gate */
36297c478bd9Sstevel@tonic-gate int
xptree_refresh_notify(uint32_t secs)36307c478bd9Sstevel@tonic-gate xptree_refresh_notify(uint32_t secs)
36317c478bd9Sstevel@tonic-gate {
36327c478bd9Sstevel@tonic-gate int curgen;
36337c478bd9Sstevel@tonic-gate int ret;
36347c478bd9Sstevel@tonic-gate timespec_t to;
36357c478bd9Sstevel@tonic-gate
3636cec46d77Sanbui if (secs != 0) {
36377c478bd9Sstevel@tonic-gate if (pthread_mutex_lock(&ptree_refresh_mutex) != 0)
36387c478bd9Sstevel@tonic-gate return (PICL_FAILURE);
36397c478bd9Sstevel@tonic-gate
36407c478bd9Sstevel@tonic-gate curgen = ptree_generation;
36417c478bd9Sstevel@tonic-gate
36427c478bd9Sstevel@tonic-gate while (curgen == ptree_generation) {
36434c4e8250Sanbui if (secs == UINT32_MAX) /* wait forever */
36447c478bd9Sstevel@tonic-gate (void) pthread_cond_wait(&ptree_refresh_cond,
36457c478bd9Sstevel@tonic-gate &ptree_refresh_mutex);
36467c478bd9Sstevel@tonic-gate else {
36477c478bd9Sstevel@tonic-gate to.tv_sec = secs;
36487c478bd9Sstevel@tonic-gate to.tv_nsec = 0;
3649cec46d77Sanbui ret = pthread_cond_reltimedwait_np(
3650cec46d77Sanbui &ptree_refresh_cond,
36517c478bd9Sstevel@tonic-gate &ptree_refresh_mutex, &to);
36527c478bd9Sstevel@tonic-gate if (ret == ETIMEDOUT)
36537c478bd9Sstevel@tonic-gate break;
36547c478bd9Sstevel@tonic-gate }
36557c478bd9Sstevel@tonic-gate }
36567c478bd9Sstevel@tonic-gate
36577c478bd9Sstevel@tonic-gate (void) pthread_mutex_unlock(&ptree_refresh_mutex);
3658cec46d77Sanbui }
3659cec46d77Sanbui
36607c478bd9Sstevel@tonic-gate return (PICL_SUCCESS);
36617c478bd9Sstevel@tonic-gate }
36627c478bd9Sstevel@tonic-gate
36637c478bd9Sstevel@tonic-gate /*VARARGS2*/
36647c478bd9Sstevel@tonic-gate void
dbg_print(int level,const char * fmt,...)36657c478bd9Sstevel@tonic-gate dbg_print(int level, const char *fmt, ...)
36667c478bd9Sstevel@tonic-gate {
36677c478bd9Sstevel@tonic-gate if (verbose_level >= level) {
36687c478bd9Sstevel@tonic-gate va_list ap;
36697c478bd9Sstevel@tonic-gate
36707c478bd9Sstevel@tonic-gate va_start(ap, fmt);
36717c478bd9Sstevel@tonic-gate (void) vprintf(fmt, ap);
36727c478bd9Sstevel@tonic-gate va_end(ap);
36737c478bd9Sstevel@tonic-gate }
36747c478bd9Sstevel@tonic-gate }
36757c478bd9Sstevel@tonic-gate
36767c478bd9Sstevel@tonic-gate /*ARGSUSED*/
36777c478bd9Sstevel@tonic-gate void
dbg_exec(int level,void (* fn)(void * args),void * args)36787c478bd9Sstevel@tonic-gate dbg_exec(int level, void (*fn)(void *args), void *args)
36797c478bd9Sstevel@tonic-gate {
36807c478bd9Sstevel@tonic-gate if (verbose_level > level)
36817c478bd9Sstevel@tonic-gate (*fn)(args);
36827c478bd9Sstevel@tonic-gate }
3683