xref: /onnv-gate/usr/src/lib/libstmf/common/store.c (revision 12682:c1fa75665a52)
17836SJohn.Forte@Sun.COM /*
27836SJohn.Forte@Sun.COM  * CDDL HEADER START
37836SJohn.Forte@Sun.COM  *
47836SJohn.Forte@Sun.COM  * The contents of this file are subject to the terms of the
57836SJohn.Forte@Sun.COM  * Common Development and Distribution License (the "License").
67836SJohn.Forte@Sun.COM  * You may not use this file except in compliance with the License.
77836SJohn.Forte@Sun.COM  *
87836SJohn.Forte@Sun.COM  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
97836SJohn.Forte@Sun.COM  * or http://www.opensolaris.org/os/licensing.
107836SJohn.Forte@Sun.COM  * See the License for the specific language governing permissions
117836SJohn.Forte@Sun.COM  * and limitations under the License.
127836SJohn.Forte@Sun.COM  *
137836SJohn.Forte@Sun.COM  * When distributing Covered Code, include this CDDL HEADER in each
147836SJohn.Forte@Sun.COM  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
157836SJohn.Forte@Sun.COM  * If applicable, add the following below this CDDL HEADER, with the
167836SJohn.Forte@Sun.COM  * fields enclosed by brackets "[]" replaced with your own identifying
177836SJohn.Forte@Sun.COM  * information: Portions Copyright [yyyy] [name of copyright owner]
187836SJohn.Forte@Sun.COM  *
197836SJohn.Forte@Sun.COM  * CDDL HEADER END
207836SJohn.Forte@Sun.COM  */
217836SJohn.Forte@Sun.COM /*
22*12682SSrivijitha.Dugganapalli@Sun.COM  * Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved.
237836SJohn.Forte@Sun.COM  */
247836SJohn.Forte@Sun.COM 
257836SJohn.Forte@Sun.COM #include <libscf.h>
267836SJohn.Forte@Sun.COM #include <stdio.h>
277836SJohn.Forte@Sun.COM #include <stdlib.h>
287836SJohn.Forte@Sun.COM #include <errno.h>
297836SJohn.Forte@Sun.COM #include <assert.h>
307836SJohn.Forte@Sun.COM #include <strings.h>
317836SJohn.Forte@Sun.COM #include <libstmf.h>
327836SJohn.Forte@Sun.COM #include <store.h>
337836SJohn.Forte@Sun.COM #include <syslog.h>
347836SJohn.Forte@Sun.COM #include <signal.h>
357836SJohn.Forte@Sun.COM #include <pthread.h>
367836SJohn.Forte@Sun.COM #include <libnvpair.h>
377836SJohn.Forte@Sun.COM #include <limits.h>
387836SJohn.Forte@Sun.COM #include <unistd.h>
397836SJohn.Forte@Sun.COM 
407836SJohn.Forte@Sun.COM /*
417836SJohn.Forte@Sun.COM  * This file's functions are responsible for all store and retrieve operations
427836SJohn.Forte@Sun.COM  * against the STMF smf(5) database. The following shows the currently defined
437836SJohn.Forte@Sun.COM  * schema for the STMF database:
447836SJohn.Forte@Sun.COM  *
457836SJohn.Forte@Sun.COM  * Description of property groups for service: svc:/system/stmf
467836SJohn.Forte@Sun.COM  *
477836SJohn.Forte@Sun.COM  * Stability: Volatile
487836SJohn.Forte@Sun.COM  *
497836SJohn.Forte@Sun.COM  * 1. Property Group: host_groups
507836SJohn.Forte@Sun.COM  *        Properties: group_name-<N> where <N> is an unsigned integer
517836SJohn.Forte@Sun.COM  *                        type: ustring
527836SJohn.Forte@Sun.COM  *                        contains: group name
537836SJohn.Forte@Sun.COM  *                    group_name-<N>-member_list where <N> is an unsigned
547836SJohn.Forte@Sun.COM  *                            integer matching a group_name-<N> property.
557836SJohn.Forte@Sun.COM  *                        type: ustring
567836SJohn.Forte@Sun.COM  *                        contains: list of members
577836SJohn.Forte@Sun.COM  *
587836SJohn.Forte@Sun.COM  *        Description:
597836SJohn.Forte@Sun.COM  *             Contains the host group names as well as the host group members
607836SJohn.Forte@Sun.COM  *             for each host group.
617836SJohn.Forte@Sun.COM  *
627836SJohn.Forte@Sun.COM  * 2. Property Group: target_groups
637836SJohn.Forte@Sun.COM  *        Properties: group_name-<N> where <N> is an unsigned integer
647836SJohn.Forte@Sun.COM  *                        type: ustring
657836SJohn.Forte@Sun.COM  *                        contains: group name
667836SJohn.Forte@Sun.COM  *                    group_name-<N>-member_list where <N> is an unsigned
677836SJohn.Forte@Sun.COM  *                            integer matching a group_name-<N> property.
687836SJohn.Forte@Sun.COM  *                        type: ustring
697836SJohn.Forte@Sun.COM  *                        contains: list of members
707836SJohn.Forte@Sun.COM  *
717836SJohn.Forte@Sun.COM  *        Description:
727836SJohn.Forte@Sun.COM  *             Contains the target group names as well as the target group
737836SJohn.Forte@Sun.COM  *             members for each target group.
747836SJohn.Forte@Sun.COM  *
757836SJohn.Forte@Sun.COM  * 3. Property Group: lu-<GUID>
767836SJohn.Forte@Sun.COM  *                        where <GUID> is a 32 character hexadecimal string.
777836SJohn.Forte@Sun.COM  *        Properties: ve_cnt
787836SJohn.Forte@Sun.COM  *                        type: count
797836SJohn.Forte@Sun.COM  *                        contains: the number of current view entries
807836SJohn.Forte@Sun.COM  *                    view-entry-<N>-<GUID> where <N> is an unsigned integer
817836SJohn.Forte@Sun.COM  *                        type: ustring
827836SJohn.Forte@Sun.COM  *                        contains: nothing. Used as reference to the view
837836SJohn.Forte@Sun.COM  *                                  entry property group
847836SJohn.Forte@Sun.COM  *
857836SJohn.Forte@Sun.COM  *        Description:
867836SJohn.Forte@Sun.COM  *             Contains the references to each view entry. One lu-<GUID>
877836SJohn.Forte@Sun.COM  *             property group will exist for each logical unit with 1 or more
887836SJohn.Forte@Sun.COM  *             view entries.
897836SJohn.Forte@Sun.COM  *             Potentially can hold any other data that can be managed on a per
907836SJohn.Forte@Sun.COM  *             logical unit basis.
917836SJohn.Forte@Sun.COM  *
927836SJohn.Forte@Sun.COM  * 4. Property Group: view_entry-<N>-<GUID> (matches property in lu-<GUID>
937836SJohn.Forte@Sun.COM  *                    property group)
947836SJohn.Forte@Sun.COM  *        Properties: all_hosts
957836SJohn.Forte@Sun.COM  *                        type: boolean
967836SJohn.Forte@Sun.COM  *                        contains: when true, the value of host_group is
977836SJohn.Forte@Sun.COM  *                                  ignored
987836SJohn.Forte@Sun.COM  *                    all_targets
997836SJohn.Forte@Sun.COM  *                        type: boolean
1007836SJohn.Forte@Sun.COM  *                        contains: when true, the value of target_group is
1017836SJohn.Forte@Sun.COM  *                                  ignored
1027836SJohn.Forte@Sun.COM  *                    host_group
1037836SJohn.Forte@Sun.COM  *                        type: ustring
1047836SJohn.Forte@Sun.COM  *                        contains: host group for logical unit mapping and
1057836SJohn.Forte@Sun.COM  *                                  masking purposes
1067836SJohn.Forte@Sun.COM  *                    target_group
1077836SJohn.Forte@Sun.COM  *                        type: ustring
1087836SJohn.Forte@Sun.COM  *                        contains: target group for logical unit mapping and
1097836SJohn.Forte@Sun.COM  *                                  masking purposes
1107836SJohn.Forte@Sun.COM  *                    lu_nbr
1117836SJohn.Forte@Sun.COM  *                        type: opaque
1127836SJohn.Forte@Sun.COM  *                        contains: the 8-byte SCSI logical unit number for
1137836SJohn.Forte@Sun.COM  *                                  mapping and masking purposes
1147836SJohn.Forte@Sun.COM  *        Description:
1157836SJohn.Forte@Sun.COM  *             One "view_entry-<N>-<GUID>" property group will exist for each
1167836SJohn.Forte@Sun.COM  *             view entry in the system. This property group name maps
1177836SJohn.Forte@Sun.COM  *             directly to the "lu-<GUID>" property group with a matching
1187836SJohn.Forte@Sun.COM  *             <GUID>.
1197836SJohn.Forte@Sun.COM  *
1207836SJohn.Forte@Sun.COM  * 5. Property Group: provider_data_pg_<provider-name>
1217836SJohn.Forte@Sun.COM  *                        where <provider-name> is the name of the provider
1227836SJohn.Forte@Sun.COM  *                           registered with stmf.
1237836SJohn.Forte@Sun.COM  *        Properties: provider_data_prop-<N>
1247836SJohn.Forte@Sun.COM  *                        where <N> is a sequential identifier for the data
1257836SJohn.Forte@Sun.COM  *                           chunk.
1267836SJohn.Forte@Sun.COM  *                        type: opaque
1277836SJohn.Forte@Sun.COM  *                        contains: up to STMF_PROVIDER_DATA_PROP_SIZE bytes
1287836SJohn.Forte@Sun.COM  *                                  of nvlist packed data.
1297836SJohn.Forte@Sun.COM  *                    provider_data_count
1307836SJohn.Forte@Sun.COM  *                        type: count
1317836SJohn.Forte@Sun.COM  *                        contains: the number of provider data chunks
1327836SJohn.Forte@Sun.COM  *                    provider_data_type
1337836SJohn.Forte@Sun.COM  *                        type: integer
1347836SJohn.Forte@Sun.COM  *                        contains: STMF_PORT_PROVIDER_TYPE or
1357836SJohn.Forte@Sun.COM  *                                  STMF_LU_PROVIDER_TYPE
1367836SJohn.Forte@Sun.COM  *
1377836SJohn.Forte@Sun.COM  *        Description:
1387836SJohn.Forte@Sun.COM  *             Holds the nvlist packed provider data set via
1397836SJohn.Forte@Sun.COM  *             stmfSetProviderData and retrieved via stmfGetProviderData. Data
1407836SJohn.Forte@Sun.COM  *             is stored in STMF_PROVIDER_DATA_PROP_SIZE chunks. On retrieve,
1417836SJohn.Forte@Sun.COM  *             these chunks are reassembled and unpacked.
1427836SJohn.Forte@Sun.COM  *
1437836SJohn.Forte@Sun.COM  */
1447836SJohn.Forte@Sun.COM 
1457836SJohn.Forte@Sun.COM static int iPsInit(scf_handle_t **, scf_service_t **);
1467836SJohn.Forte@Sun.COM static int iPsCreateDeleteGroup(char *, char *, int);
1477836SJohn.Forte@Sun.COM static int iPsAddRemoveGroupMember(char *, char *, char *, int);
1487836SJohn.Forte@Sun.COM static int iPsGetGroupList(char *, stmfGroupList **);
1497836SJohn.Forte@Sun.COM static int iPsGetGroupMemberList(char *, char *, stmfGroupProperties **);
1507836SJohn.Forte@Sun.COM static int iPsAddViewEntry(char *, char *, stmfViewEntry *);
1517836SJohn.Forte@Sun.COM static int iPsAddRemoveLuViewEntry(char *, char *, int);
1527836SJohn.Forte@Sun.COM static int iPsGetViewEntry(char *, stmfViewEntry *);
1537836SJohn.Forte@Sun.COM static int iPsGetActualGroupName(char *, char *, char *);
1547836SJohn.Forte@Sun.COM static int iPsGetServiceVersion(uint64_t *, scf_handle_t *, scf_service_t *);
1559585STim.Szeto@Sun.COM static int iPsGetSetPersistType(uint8_t *, scf_handle_t *, scf_service_t *,
1569585STim.Szeto@Sun.COM     int);
157*12682SSrivijitha.Dugganapalli@Sun.COM static int iPsGetSetStmfProp(int, char *, int);
1587836SJohn.Forte@Sun.COM static int viewEntryCompare(const void *, const void *);
1597836SJohn.Forte@Sun.COM static int holdSignal(sigset_t *);
1607836SJohn.Forte@Sun.COM static int releaseSignal(sigset_t *);
1617836SJohn.Forte@Sun.COM static void sigHandler();
1627836SJohn.Forte@Sun.COM 
1637836SJohn.Forte@Sun.COM static pthread_mutex_t sigSetLock = PTHREAD_MUTEX_INITIALIZER;
1647836SJohn.Forte@Sun.COM 
1657836SJohn.Forte@Sun.COM sigset_t sigSet;
1667836SJohn.Forte@Sun.COM sigset_t signalsCaught;
1677836SJohn.Forte@Sun.COM 
1687836SJohn.Forte@Sun.COM struct sigaction currentActionQuit;
1697836SJohn.Forte@Sun.COM struct sigaction currentActionTerm;
1707836SJohn.Forte@Sun.COM struct sigaction currentActionInt;
1717836SJohn.Forte@Sun.COM 
1727836SJohn.Forte@Sun.COM boolean_t actionSet = B_FALSE;
1737836SJohn.Forte@Sun.COM 
1747836SJohn.Forte@Sun.COM /*
1757836SJohn.Forte@Sun.COM  * Version info for the SMF schema
1767836SJohn.Forte@Sun.COM  */
1777836SJohn.Forte@Sun.COM #define	STMF_SMF_VERSION    1
1787836SJohn.Forte@Sun.COM 
1797836SJohn.Forte@Sun.COM /*
1809585STim.Szeto@Sun.COM  * Note: Do not change these property names and size values.
1819585STim.Szeto@Sun.COM  * They represent fields in the persistent config and once modified
1829585STim.Szeto@Sun.COM  * will have a nasty side effect of invalidating the existing store.
1839585STim.Szeto@Sun.COM  * If you do need to change them, you'll need to use the versioning above
1849585STim.Szeto@Sun.COM  * to retain backward compatiblity with the previous configuration schema.
1859585STim.Szeto@Sun.COM  */
1869585STim.Szeto@Sun.COM 
1879585STim.Szeto@Sun.COM /* BEGIN STORE PROPERTY DEFINITIONS */
1889585STim.Szeto@Sun.COM /*
1897836SJohn.Forte@Sun.COM  * Property Group Names and prefixes
1907836SJohn.Forte@Sun.COM  */
1917836SJohn.Forte@Sun.COM #define	STMF_HOST_GROUPS	"host_groups"
1927836SJohn.Forte@Sun.COM #define	STMF_TARGET_GROUPS	"target_groups"
1937836SJohn.Forte@Sun.COM #define	STMF_VE_PREFIX		"view_entry"
1947836SJohn.Forte@Sun.COM #define	STMF_LU_PREFIX		"lu"
1957836SJohn.Forte@Sun.COM #define	STMF_DATA_GROUP		"stmf_data"
1967836SJohn.Forte@Sun.COM 
1977836SJohn.Forte@Sun.COM /*
1987836SJohn.Forte@Sun.COM  * Property names and prefix for logical unit property group
1997836SJohn.Forte@Sun.COM  */
2007836SJohn.Forte@Sun.COM #define	STMF_VE_CNT		"ve_cnt"
2017836SJohn.Forte@Sun.COM #define	STMF_GROUP_PREFIX	"group_name"
2027836SJohn.Forte@Sun.COM #define	STMF_MEMBER_LIST_SUFFIX	"member_list"
2037836SJohn.Forte@Sun.COM #define	STMF_VERSION_NAME	"version_name"
2049585STim.Szeto@Sun.COM #define	STMF_PERSIST_TYPE	"persist_method"
2057836SJohn.Forte@Sun.COM 
206*12682SSrivijitha.Dugganapalli@Sun.COM /* Property names for stmf properties */
207*12682SSrivijitha.Dugganapalli@Sun.COM 
208*12682SSrivijitha.Dugganapalli@Sun.COM #define	DEFAULT_LU_STATE		"default_lu_state"
209*12682SSrivijitha.Dugganapalli@Sun.COM #define	DEFAULT_TARGET_PORT_STATE	"default_target_state"
210*12682SSrivijitha.Dugganapalli@Sun.COM 
2117836SJohn.Forte@Sun.COM /*
2127836SJohn.Forte@Sun.COM  * Property names for view entry
2137836SJohn.Forte@Sun.COM  */
2147836SJohn.Forte@Sun.COM #define	STMF_VE_ALLHOSTS	    "all_hosts"
2157836SJohn.Forte@Sun.COM #define	STMF_VE_HOSTGROUP	    "host_group"
2167836SJohn.Forte@Sun.COM #define	STMF_VE_ALLTARGETS	    "all_targets"
2177836SJohn.Forte@Sun.COM #define	STMF_VE_TARGETGROUP	    "target_group"
2187836SJohn.Forte@Sun.COM #define	STMF_VE_LUNBR		    "lu_nbr"
2197836SJohn.Forte@Sun.COM 
2207836SJohn.Forte@Sun.COM /* Property group suffix for provider data */
2217836SJohn.Forte@Sun.COM #define	STMF_PROVIDER_DATA_PREFIX "provider_data_pg_"
2227836SJohn.Forte@Sun.COM #define	STMF_PROVIDER_DATA_PROP_PREFIX "provider_data_prop"
2237836SJohn.Forte@Sun.COM #define	STMF_PROVIDER_DATA_PROP_NAME_SIZE 256
2247836SJohn.Forte@Sun.COM #define	STMF_PROVIDER_DATA_PROP_TYPE "provider_type"
2257836SJohn.Forte@Sun.COM #define	STMF_PROVIDER_DATA_PROP_SET_COUNT "provider_data_set_cnt"
2267836SJohn.Forte@Sun.COM #define	STMF_PROVIDER_DATA_PROP_COUNT "provider_data_cnt"
2279585STim.Szeto@Sun.COM 
2287836SJohn.Forte@Sun.COM 
2297836SJohn.Forte@Sun.COM #define	STMF_SMF_READ_ATTR	"solaris.smf.read.stmf"
2307836SJohn.Forte@Sun.COM 
2319585STim.Szeto@Sun.COM #define	STMF_PS_PERSIST_NONE	"none"
2329585STim.Szeto@Sun.COM #define	STMF_PS_PERSIST_SMF	"smf"
2339585STim.Szeto@Sun.COM #define	STMF_PROVIDER_DATA_PROP_SIZE 4000
234*12682SSrivijitha.Dugganapalli@Sun.COM 
235*12682SSrivijitha.Dugganapalli@Sun.COM #define	STMF_PS_LU_ONLINE		"default_lu_online"
236*12682SSrivijitha.Dugganapalli@Sun.COM #define	STMF_PS_LU_OFFLINE		"default_lu_offline"
237*12682SSrivijitha.Dugganapalli@Sun.COM #define	STMF_PS_TARGET_PORT_ONLINE	"default_target_online"
238*12682SSrivijitha.Dugganapalli@Sun.COM #define	STMF_PS_TARGET_PORT_OFFLINE	"default_target_offline"
239*12682SSrivijitha.Dugganapalli@Sun.COM 
2409585STim.Szeto@Sun.COM /* END STORE PROPERTY DEFINITIONS */
2417836SJohn.Forte@Sun.COM 
2427836SJohn.Forte@Sun.COM /* service name */
2437836SJohn.Forte@Sun.COM #define	STMF_SERVICE	"system/stmf"
2447836SJohn.Forte@Sun.COM 
2457836SJohn.Forte@Sun.COM /* limits and flag values */
2467836SJohn.Forte@Sun.COM #define	GROUP_MEMBER_ALLOC 100
2477836SJohn.Forte@Sun.COM #define	VIEW_ENTRY_STRUCT_CNT 6
2487836SJohn.Forte@Sun.COM #define	VIEW_ENTRY_PG_SIZE 256
2497836SJohn.Forte@Sun.COM #define	LOGICAL_UNIT_PG_SIZE 256
2507836SJohn.Forte@Sun.COM #define	VIEW_ENTRY_MAX UINT32_MAX
2517836SJohn.Forte@Sun.COM #define	GROUP_MAX UINT64_MAX
2527836SJohn.Forte@Sun.COM #define	ADD 0
2537836SJohn.Forte@Sun.COM #define	REMOVE 1
2549585STim.Szeto@Sun.COM #define	GET 0
2559585STim.Szeto@Sun.COM #define	SET 1
2567836SJohn.Forte@Sun.COM 
2577836SJohn.Forte@Sun.COM /*
2587836SJohn.Forte@Sun.COM  * sigHandler
2597836SJohn.Forte@Sun.COM  *
2607836SJohn.Forte@Sun.COM  * Catch the signal and set the global signalsCaught to the signal received
2617836SJohn.Forte@Sun.COM  *
2627836SJohn.Forte@Sun.COM  * signalsCaught will be used by releaseSignal to raise this signal when
2637836SJohn.Forte@Sun.COM  * we're done processing our critical code.
2647836SJohn.Forte@Sun.COM  *
2657836SJohn.Forte@Sun.COM  */
2667836SJohn.Forte@Sun.COM static void
sigHandler(int sig)2677836SJohn.Forte@Sun.COM sigHandler(int sig)
2687836SJohn.Forte@Sun.COM {
2697836SJohn.Forte@Sun.COM 	(void) sigaddset(&signalsCaught, sig);
2707836SJohn.Forte@Sun.COM }
2717836SJohn.Forte@Sun.COM 
2727836SJohn.Forte@Sun.COM /*
2737836SJohn.Forte@Sun.COM  * iPsAddRemoveGroupMember
2747836SJohn.Forte@Sun.COM  *
2757836SJohn.Forte@Sun.COM  * Add or remove a member for a given group
2767836SJohn.Forte@Sun.COM  *
2777836SJohn.Forte@Sun.COM  * pgName - Property group name
2787836SJohn.Forte@Sun.COM  * groupName - group name to which the member is added/removed
2797836SJohn.Forte@Sun.COM  * memberName - member to be added/removed
2807836SJohn.Forte@Sun.COM  * addRemoveFlag - ADD/REMOVE
2817836SJohn.Forte@Sun.COM  *
2827836SJohn.Forte@Sun.COM  * returns:
2837836SJohn.Forte@Sun.COM  *  STMF_PS_SUCCESS on success
2847836SJohn.Forte@Sun.COM  *  STMF_PS_ERROR_* on failure
2857836SJohn.Forte@Sun.COM  */
2867836SJohn.Forte@Sun.COM static int
iPsAddRemoveGroupMember(char * pgName,char * groupName,char * memberName,int addRemoveFlag)2877836SJohn.Forte@Sun.COM iPsAddRemoveGroupMember(char *pgName, char *groupName, char *memberName,
2887836SJohn.Forte@Sun.COM int addRemoveFlag)
2897836SJohn.Forte@Sun.COM {
2907836SJohn.Forte@Sun.COM 	scf_handle_t *handle = NULL;
2917836SJohn.Forte@Sun.COM 	scf_service_t *svc = NULL;
2927836SJohn.Forte@Sun.COM 	scf_propertygroup_t *pg = NULL;
2937836SJohn.Forte@Sun.COM 	scf_property_t *prop = NULL;
2947836SJohn.Forte@Sun.COM 	scf_value_t *valueLookup = NULL;
2957836SJohn.Forte@Sun.COM 	scf_value_t **valueSet = NULL;
2967836SJohn.Forte@Sun.COM 	scf_iter_t *valueIter = NULL;
2977836SJohn.Forte@Sun.COM 	scf_transaction_t *tran = NULL;
2987836SJohn.Forte@Sun.COM 	scf_transaction_entry_t *entry = NULL;
2997836SJohn.Forte@Sun.COM 	int i = 0;
3007836SJohn.Forte@Sun.COM 	int lastAlloc;
3017836SJohn.Forte@Sun.COM 	int valueArraySize = 0;
3027836SJohn.Forte@Sun.COM 	int ret = STMF_PS_SUCCESS;
3037836SJohn.Forte@Sun.COM 	char buf[STMF_IDENT_LENGTH];
3047836SJohn.Forte@Sun.COM 	int commitRet;
3057836SJohn.Forte@Sun.COM 	boolean_t found = B_FALSE;
3067836SJohn.Forte@Sun.COM 
3077836SJohn.Forte@Sun.COM 	assert(pgName != NULL && groupName != NULL && memberName != NULL);
3087836SJohn.Forte@Sun.COM 
3097836SJohn.Forte@Sun.COM 	/*
3107836SJohn.Forte@Sun.COM 	 * Init the service handle
3117836SJohn.Forte@Sun.COM 	 */
3127836SJohn.Forte@Sun.COM 	ret = iPsInit(&handle, &svc);
3137836SJohn.Forte@Sun.COM 	if (ret != STMF_PS_SUCCESS) {
3147836SJohn.Forte@Sun.COM 		goto out;
3157836SJohn.Forte@Sun.COM 	}
3167836SJohn.Forte@Sun.COM 
3177836SJohn.Forte@Sun.COM 	/*
3187836SJohn.Forte@Sun.COM 	 * Allocate scf resources
3197836SJohn.Forte@Sun.COM 	 */
3207836SJohn.Forte@Sun.COM 	if (((pg = scf_pg_create(handle)) == NULL) ||
3217836SJohn.Forte@Sun.COM 	    ((tran = scf_transaction_create(handle)) == NULL) ||
3227836SJohn.Forte@Sun.COM 	    ((entry = scf_entry_create(handle)) == NULL) ||
3237836SJohn.Forte@Sun.COM 	    ((prop = scf_property_create(handle)) == NULL) ||
3247836SJohn.Forte@Sun.COM 	    ((valueIter = scf_iter_create(handle)) == NULL)) {
3257836SJohn.Forte@Sun.COM 		syslog(LOG_ERR, "scf alloc resource failed - %s",
3267836SJohn.Forte@Sun.COM 		    scf_strerror(scf_error()));
3277836SJohn.Forte@Sun.COM 		ret = STMF_PS_ERROR;
3287836SJohn.Forte@Sun.COM 		goto out;
3297836SJohn.Forte@Sun.COM 	}
3307836SJohn.Forte@Sun.COM 
3317836SJohn.Forte@Sun.COM 	/*
3327836SJohn.Forte@Sun.COM 	 * Get the service property group handle
3337836SJohn.Forte@Sun.COM 	 */
3347836SJohn.Forte@Sun.COM 	if (scf_service_get_pg(svc, pgName, pg) == -1) {
3357836SJohn.Forte@Sun.COM 		if (scf_error() == SCF_ERROR_NOT_FOUND) {
3367836SJohn.Forte@Sun.COM 			ret = STMF_PS_ERROR_NOT_FOUND;
3377836SJohn.Forte@Sun.COM 		} else {
3387836SJohn.Forte@Sun.COM 			ret = STMF_PS_ERROR;
3397836SJohn.Forte@Sun.COM 		}
34011909SPeter.Gill@Sun.COM 		syslog(LOG_ERR, "get pg %s failed - %s",
34111909SPeter.Gill@Sun.COM 		    pgName, scf_strerror(scf_error()));
34211909SPeter.Gill@Sun.COM 
3437836SJohn.Forte@Sun.COM 		goto out;
3447836SJohn.Forte@Sun.COM 	}
3457836SJohn.Forte@Sun.COM 
3467836SJohn.Forte@Sun.COM 	/*
3477836SJohn.Forte@Sun.COM 	 * Begin the transaction
3487836SJohn.Forte@Sun.COM 	 */
3497836SJohn.Forte@Sun.COM 	if (scf_transaction_start(tran, pg) == -1) {
35011909SPeter.Gill@Sun.COM 		syslog(LOG_ERR, "start transaction for %s failed - %s",
35111909SPeter.Gill@Sun.COM 		    pgName, scf_strerror(scf_error()));
3527836SJohn.Forte@Sun.COM 		ret = STMF_PS_ERROR;
3537836SJohn.Forte@Sun.COM 		goto out;
3547836SJohn.Forte@Sun.COM 	}
3557836SJohn.Forte@Sun.COM 
3567836SJohn.Forte@Sun.COM 	/*
3577836SJohn.Forte@Sun.COM 	 * We're changing an existing property by adding a propval
3587836SJohn.Forte@Sun.COM 	 * There are no add semantics in libscf for a property value. We'll
3597836SJohn.Forte@Sun.COM 	 * need to read in the current properties and apply them all to the
3607836SJohn.Forte@Sun.COM 	 * set and then add the one we were asked to add or omit the one
3617836SJohn.Forte@Sun.COM 	 * we were asked to remove.
3627836SJohn.Forte@Sun.COM 	 */
3637836SJohn.Forte@Sun.COM 	if (scf_transaction_property_change(tran, entry, groupName,
3647836SJohn.Forte@Sun.COM 	    SCF_TYPE_USTRING) == -1) {
3657836SJohn.Forte@Sun.COM 		if (scf_error() == SCF_ERROR_NOT_FOUND) {
3667836SJohn.Forte@Sun.COM 			ret = STMF_PS_ERROR_GROUP_NOT_FOUND;
3677836SJohn.Forte@Sun.COM 		} else {
3687836SJohn.Forte@Sun.COM 			ret = STMF_PS_ERROR;
36911909SPeter.Gill@Sun.COM 			syslog(LOG_ERR, "tran property change %s/%s "
37011909SPeter.Gill@Sun.COM 			    "failed - %s", pgName, groupName,
3717836SJohn.Forte@Sun.COM 			    scf_strerror(scf_error()));
3727836SJohn.Forte@Sun.COM 		}
3737836SJohn.Forte@Sun.COM 		goto out;
3747836SJohn.Forte@Sun.COM 	}
3757836SJohn.Forte@Sun.COM 
3767836SJohn.Forte@Sun.COM 	/*
3777836SJohn.Forte@Sun.COM 	 * Get the property handle
3787836SJohn.Forte@Sun.COM 	 */
3797836SJohn.Forte@Sun.COM 	if (scf_pg_get_property(pg, groupName, prop) == -1) {
38011909SPeter.Gill@Sun.COM 		syslog(LOG_ERR, "get property %s/%s failed - %s",
38111909SPeter.Gill@Sun.COM 		    pgName, groupName, scf_strerror(scf_error()));
3827836SJohn.Forte@Sun.COM 		ret = STMF_PS_ERROR;
3837836SJohn.Forte@Sun.COM 		goto out;
3847836SJohn.Forte@Sun.COM 	}
3857836SJohn.Forte@Sun.COM 
3867836SJohn.Forte@Sun.COM 	/*
3877836SJohn.Forte@Sun.COM 	 * Value lookup is used to lookup the existing values
3887836SJohn.Forte@Sun.COM 	 */
3897836SJohn.Forte@Sun.COM 	valueLookup = scf_value_create(handle);
3907836SJohn.Forte@Sun.COM 	if (valueLookup == NULL) {
39111909SPeter.Gill@Sun.COM 		syslog(LOG_ERR, "scf value alloc for %s failed - %s",
39211909SPeter.Gill@Sun.COM 		    pgName, scf_strerror(scf_error()));
3937836SJohn.Forte@Sun.COM 		ret = STMF_PS_ERROR;
3947836SJohn.Forte@Sun.COM 		goto out;
3957836SJohn.Forte@Sun.COM 	}
3967836SJohn.Forte@Sun.COM 
3977836SJohn.Forte@Sun.COM 	/*
3987836SJohn.Forte@Sun.COM 	 * valueIter is the iterator handle, create the resource
3997836SJohn.Forte@Sun.COM 	 */
4007836SJohn.Forte@Sun.COM 	if (scf_iter_property_values(valueIter, prop) == -1) {
40111909SPeter.Gill@Sun.COM 		syslog(LOG_ERR, "iter values for %s/%s failed - %s",
40211909SPeter.Gill@Sun.COM 		    pgName, groupName, scf_strerror(scf_error()));
4037836SJohn.Forte@Sun.COM 		ret = STMF_PS_ERROR;
4047836SJohn.Forte@Sun.COM 		goto out;
4057836SJohn.Forte@Sun.COM 	}
4067836SJohn.Forte@Sun.COM 
4077836SJohn.Forte@Sun.COM 	/*
4087836SJohn.Forte@Sun.COM 	 * Allocate value resource pointers.
4097836SJohn.Forte@Sun.COM 	 * We need a value resource for each value as value pointers passed
4107836SJohn.Forte@Sun.COM 	 * to libscf cannot be destroyed until the commit or destroy on the
4117836SJohn.Forte@Sun.COM 	 * transaction is done.
4127836SJohn.Forte@Sun.COM 	 *
4137836SJohn.Forte@Sun.COM 	 * We're using GROUP_MEMBER_ALLOC initially. If it's not large
4147836SJohn.Forte@Sun.COM 	 * enough, we'll realloc on the fly
4157836SJohn.Forte@Sun.COM 	 */
4167836SJohn.Forte@Sun.COM 	valueSet = (scf_value_t **)calloc(1, sizeof (*valueSet)
4177836SJohn.Forte@Sun.COM 	    * (lastAlloc = GROUP_MEMBER_ALLOC));
4187836SJohn.Forte@Sun.COM 	if (valueSet == NULL) {
4197836SJohn.Forte@Sun.COM 		ret = STMF_PS_ERROR_NOMEM;
4207836SJohn.Forte@Sun.COM 		goto out;
4217836SJohn.Forte@Sun.COM 	}
4227836SJohn.Forte@Sun.COM 
4237836SJohn.Forte@Sun.COM 	/*
4247836SJohn.Forte@Sun.COM 	 * Iterate through the existing values
4257836SJohn.Forte@Sun.COM 	 */
4267836SJohn.Forte@Sun.COM 	while (scf_iter_next_value(valueIter, valueLookup) == 1) {
4277836SJohn.Forte@Sun.COM 		bzero(buf, sizeof (buf));
4287836SJohn.Forte@Sun.COM 		if (scf_value_get_ustring(valueLookup, buf, MAXNAMELEN) == -1) {
42911909SPeter.Gill@Sun.COM 			syslog(LOG_ERR, "iter %s/%s value failed - %s",
43011909SPeter.Gill@Sun.COM 			    pgName, groupName, scf_strerror(scf_error()));
4317836SJohn.Forte@Sun.COM 			ret = STMF_PS_ERROR;
4327836SJohn.Forte@Sun.COM 			break;
4337836SJohn.Forte@Sun.COM 		}
4347836SJohn.Forte@Sun.COM 
4357836SJohn.Forte@Sun.COM 		/*
4367836SJohn.Forte@Sun.COM 		 * Check for existing
4377836SJohn.Forte@Sun.COM 		 * If we're adding, it's an error
4387836SJohn.Forte@Sun.COM 		 * If we're removing, we skip it and simply not
4397836SJohn.Forte@Sun.COM 		 * add it to the set. Subtraction by omission.
4407836SJohn.Forte@Sun.COM 		 */
4417836SJohn.Forte@Sun.COM 		if ((strlen(buf) == strlen(memberName)) &&
4427836SJohn.Forte@Sun.COM 		    bcmp(buf, memberName, strlen(buf)) == 0) {
4437836SJohn.Forte@Sun.COM 			if (addRemoveFlag == ADD) {
4447836SJohn.Forte@Sun.COM 				ret = STMF_PS_ERROR_EXISTS;
4457836SJohn.Forte@Sun.COM 				break;
4467836SJohn.Forte@Sun.COM 			} else {
4477836SJohn.Forte@Sun.COM 				found = B_TRUE;
4487836SJohn.Forte@Sun.COM 				continue;
4497836SJohn.Forte@Sun.COM 			}
4507836SJohn.Forte@Sun.COM 		}
4517836SJohn.Forte@Sun.COM 
4527836SJohn.Forte@Sun.COM 		/*
4537836SJohn.Forte@Sun.COM 		 * Create the value resource for this iteration
4547836SJohn.Forte@Sun.COM 		 */
4557836SJohn.Forte@Sun.COM 		valueSet[i] = scf_value_create(handle);
4567836SJohn.Forte@Sun.COM 		if (valueSet[i] == NULL) {
45711909SPeter.Gill@Sun.COM 			syslog(LOG_ERR, "scf value alloc for %s failed - %s",
45811909SPeter.Gill@Sun.COM 			    pgName, scf_strerror(scf_error()));
4597836SJohn.Forte@Sun.COM 			ret = STMF_PS_ERROR;
4607836SJohn.Forte@Sun.COM 			break;
4617836SJohn.Forte@Sun.COM 		}
4627836SJohn.Forte@Sun.COM 
4637836SJohn.Forte@Sun.COM 		/*
4647836SJohn.Forte@Sun.COM 		 * Set the value
4657836SJohn.Forte@Sun.COM 		 */
4667836SJohn.Forte@Sun.COM 		if (scf_value_set_ustring(valueSet[i], buf) == -1) {
46711909SPeter.Gill@Sun.COM 			syslog(LOG_ERR, "set value for %s/%s failed - %s",
46811909SPeter.Gill@Sun.COM 			    pgName, groupName, scf_strerror(scf_error()));
4697836SJohn.Forte@Sun.COM 			ret = STMF_PS_ERROR;
4707836SJohn.Forte@Sun.COM 			break;
4717836SJohn.Forte@Sun.COM 		}
4727836SJohn.Forte@Sun.COM 
4737836SJohn.Forte@Sun.COM 		/*
4747836SJohn.Forte@Sun.COM 		 * Now add the value
4757836SJohn.Forte@Sun.COM 		 */
4767836SJohn.Forte@Sun.COM 		if (scf_entry_add_value(entry, valueSet[i]) == -1) {
47711909SPeter.Gill@Sun.COM 			syslog(LOG_ERR, "add value for %s/%s failed - %s",
47811909SPeter.Gill@Sun.COM 			    pgName, groupName, scf_strerror(scf_error()));
4797836SJohn.Forte@Sun.COM 			ret = STMF_PS_ERROR;
4807836SJohn.Forte@Sun.COM 			break;
4817836SJohn.Forte@Sun.COM 		}
4827836SJohn.Forte@Sun.COM 
4837836SJohn.Forte@Sun.COM 		i++;
4847836SJohn.Forte@Sun.COM 
4857836SJohn.Forte@Sun.COM 		/*
4867836SJohn.Forte@Sun.COM 		 * realloc if we've hit the previous alloc size
4877836SJohn.Forte@Sun.COM 		 */
4887836SJohn.Forte@Sun.COM 		if (i >= lastAlloc) {
4897836SJohn.Forte@Sun.COM 			lastAlloc += GROUP_MEMBER_ALLOC;
4907836SJohn.Forte@Sun.COM 			valueSet = realloc(valueSet,
4917836SJohn.Forte@Sun.COM 			    sizeof (*valueSet) * lastAlloc);
4927836SJohn.Forte@Sun.COM 			if (valueSet == NULL) {
4937836SJohn.Forte@Sun.COM 				ret = STMF_PS_ERROR;
4947836SJohn.Forte@Sun.COM 				break;
4957836SJohn.Forte@Sun.COM 			}
4967836SJohn.Forte@Sun.COM 		}
4977836SJohn.Forte@Sun.COM 	}
4987836SJohn.Forte@Sun.COM 
4997836SJohn.Forte@Sun.COM 	/*
5007836SJohn.Forte@Sun.COM 	 * set valueArraySize to final allocated length
5017836SJohn.Forte@Sun.COM 	 * so we can use it to destroy the resources correctly
5027836SJohn.Forte@Sun.COM 	 */
5037836SJohn.Forte@Sun.COM 	valueArraySize = i;
5047836SJohn.Forte@Sun.COM 
5057836SJohn.Forte@Sun.COM 	if (!found && (addRemoveFlag == REMOVE)) {
5067836SJohn.Forte@Sun.COM 		ret = STMF_PS_ERROR_MEMBER_NOT_FOUND;
5077836SJohn.Forte@Sun.COM 	}
5087836SJohn.Forte@Sun.COM 
5097836SJohn.Forte@Sun.COM 	if (ret != STMF_PS_SUCCESS) {
5107836SJohn.Forte@Sun.COM 		goto out;
5117836SJohn.Forte@Sun.COM 	}
5127836SJohn.Forte@Sun.COM 
5137836SJohn.Forte@Sun.COM 	/*
5147836SJohn.Forte@Sun.COM 	 * If we're adding, we have one more step. Add the member to the
5157836SJohn.Forte@Sun.COM 	 * propval list
5167836SJohn.Forte@Sun.COM 	 */
5177836SJohn.Forte@Sun.COM 	if (addRemoveFlag == ADD) {
5187836SJohn.Forte@Sun.COM 		/*
5197836SJohn.Forte@Sun.COM 		 * Now create the new entry
5207836SJohn.Forte@Sun.COM 		 */
5217836SJohn.Forte@Sun.COM 		valueSet[i] = scf_value_create(handle);
5227836SJohn.Forte@Sun.COM 		if (valueSet[i] == NULL) {
52311909SPeter.Gill@Sun.COM 			syslog(LOG_ERR, "scf value alloc for %s/%s failed - %s",
52411909SPeter.Gill@Sun.COM 			    pgName, groupName, scf_strerror(scf_error()));
5257836SJohn.Forte@Sun.COM 			ret = STMF_PS_ERROR;
5267836SJohn.Forte@Sun.COM 			goto out;
5277836SJohn.Forte@Sun.COM 		} else {
5287836SJohn.Forte@Sun.COM 			valueArraySize++;
5297836SJohn.Forte@Sun.COM 		}
5307836SJohn.Forte@Sun.COM 
5317836SJohn.Forte@Sun.COM 		/*
5327836SJohn.Forte@Sun.COM 		 * Set the new member name
5337836SJohn.Forte@Sun.COM 		 */
5347836SJohn.Forte@Sun.COM 		if (scf_value_set_ustring(valueSet[i], memberName) == -1) {
53511909SPeter.Gill@Sun.COM 			syslog(LOG_ERR, "set value for %s/%s failed - %s",
53611909SPeter.Gill@Sun.COM 			    pgName, groupName, scf_strerror(scf_error()));
5377836SJohn.Forte@Sun.COM 			ret = STMF_PS_ERROR;
5387836SJohn.Forte@Sun.COM 			goto out;
5397836SJohn.Forte@Sun.COM 		}
5407836SJohn.Forte@Sun.COM 
5417836SJohn.Forte@Sun.COM 		/*
5427836SJohn.Forte@Sun.COM 		 * Add the new member
5437836SJohn.Forte@Sun.COM 		 */
5447836SJohn.Forte@Sun.COM 		if (scf_entry_add_value(entry, valueSet[i]) == -1) {
54511909SPeter.Gill@Sun.COM 			syslog(LOG_ERR, "add value for %s/%s failed - %s",
54611909SPeter.Gill@Sun.COM 			    pgName, groupName, scf_strerror(scf_error()));
5477836SJohn.Forte@Sun.COM 			ret = STMF_PS_ERROR;
5487836SJohn.Forte@Sun.COM 			goto out;
5497836SJohn.Forte@Sun.COM 		}
5507836SJohn.Forte@Sun.COM 	}
5517836SJohn.Forte@Sun.COM 
5527836SJohn.Forte@Sun.COM 	/*
5537836SJohn.Forte@Sun.COM 	 * Yes, we're finally done. We actually added or removed one entry
5547836SJohn.Forte@Sun.COM 	 * from the list.
5557836SJohn.Forte@Sun.COM 	 * Woohoo!
5567836SJohn.Forte@Sun.COM 	 */
5577836SJohn.Forte@Sun.COM 	if ((commitRet = scf_transaction_commit(tran)) != 1) {
55811909SPeter.Gill@Sun.COM 		syslog(LOG_ERR, "transaction commit for %s failed - %s",
55911909SPeter.Gill@Sun.COM 		    pgName, scf_strerror(scf_error()));
5607836SJohn.Forte@Sun.COM 		if (commitRet == 0) {
5617836SJohn.Forte@Sun.COM 			ret = STMF_PS_ERROR_BUSY;
5627836SJohn.Forte@Sun.COM 		} else {
5637836SJohn.Forte@Sun.COM 			ret = STMF_PS_ERROR;
5647836SJohn.Forte@Sun.COM 		}
5657836SJohn.Forte@Sun.COM 		goto out;
5667836SJohn.Forte@Sun.COM 	}
5677836SJohn.Forte@Sun.COM 
5687836SJohn.Forte@Sun.COM out:
5697836SJohn.Forte@Sun.COM 	/*
5707836SJohn.Forte@Sun.COM 	 * Free resources
5717836SJohn.Forte@Sun.COM 	 */
5727836SJohn.Forte@Sun.COM 	if (handle != NULL) {
5737836SJohn.Forte@Sun.COM 		scf_handle_destroy(handle);
5747836SJohn.Forte@Sun.COM 	}
5757836SJohn.Forte@Sun.COM 	if (svc != NULL) {
5767836SJohn.Forte@Sun.COM 		scf_service_destroy(svc);
5777836SJohn.Forte@Sun.COM 	}
5787836SJohn.Forte@Sun.COM 	if (pg != NULL) {
5797836SJohn.Forte@Sun.COM 		scf_pg_destroy(pg);
5807836SJohn.Forte@Sun.COM 	}
5817836SJohn.Forte@Sun.COM 	if (tran != NULL) {
5827836SJohn.Forte@Sun.COM 		scf_transaction_destroy(tran);
5837836SJohn.Forte@Sun.COM 	}
5847836SJohn.Forte@Sun.COM 	if (entry != NULL) {
5857836SJohn.Forte@Sun.COM 		scf_entry_destroy(entry);
5867836SJohn.Forte@Sun.COM 	}
5877836SJohn.Forte@Sun.COM 	if (prop != NULL) {
5887836SJohn.Forte@Sun.COM 		scf_property_destroy(prop);
5897836SJohn.Forte@Sun.COM 	}
5907836SJohn.Forte@Sun.COM 	if (valueLookup != NULL) {
5917836SJohn.Forte@Sun.COM 		scf_value_destroy(valueLookup);
5927836SJohn.Forte@Sun.COM 	}
5937836SJohn.Forte@Sun.COM 	if (valueIter != NULL) {
5947836SJohn.Forte@Sun.COM 		scf_iter_destroy(valueIter);
5957836SJohn.Forte@Sun.COM 	}
5967836SJohn.Forte@Sun.COM 
5977836SJohn.Forte@Sun.COM 	/*
5987836SJohn.Forte@Sun.COM 	 * Free valueSet scf resources
5997836SJohn.Forte@Sun.COM 	 */
6007836SJohn.Forte@Sun.COM 	if (valueArraySize > 0) {
6017836SJohn.Forte@Sun.COM 		for (i = 0; i < valueArraySize; i++) {
6027836SJohn.Forte@Sun.COM 			scf_value_destroy(valueSet[i]);
6037836SJohn.Forte@Sun.COM 		}
6047836SJohn.Forte@Sun.COM 	}
6057836SJohn.Forte@Sun.COM 	/*
6067836SJohn.Forte@Sun.COM 	 * Now free the pointer array to the resources
6077836SJohn.Forte@Sun.COM 	 */
6087836SJohn.Forte@Sun.COM 	if (valueSet != NULL) {
6097836SJohn.Forte@Sun.COM 		free(valueSet);
6107836SJohn.Forte@Sun.COM 	}
6117836SJohn.Forte@Sun.COM 
6127836SJohn.Forte@Sun.COM 	return (ret);
6137836SJohn.Forte@Sun.COM }
6147836SJohn.Forte@Sun.COM 
6157836SJohn.Forte@Sun.COM /*
6167836SJohn.Forte@Sun.COM  * iPsAddRemoveLuViewEntry
6177836SJohn.Forte@Sun.COM  *
6187836SJohn.Forte@Sun.COM  * Adds or removes a view entry name property for a given logical unit
6197836SJohn.Forte@Sun.COM  * property group. There is one logical unit property group for every logical
6207836SJohn.Forte@Sun.COM  * unit that has one or more associated view entries.
6217836SJohn.Forte@Sun.COM  *
6227836SJohn.Forte@Sun.COM  * luPgName - Property group name of logical unit
6237836SJohn.Forte@Sun.COM  * viewEntryPgName - Property group name of view entry
6247836SJohn.Forte@Sun.COM  * addRemoveFlag - ADD_VE/REMOVE_VE
6257836SJohn.Forte@Sun.COM  *
6267836SJohn.Forte@Sun.COM  * returns:
6277836SJohn.Forte@Sun.COM  *  STMF_PS_SUCCESS on success
6287836SJohn.Forte@Sun.COM  *  STMF_PS_ERROR_* on failure
6297836SJohn.Forte@Sun.COM  */
6307836SJohn.Forte@Sun.COM static int
iPsAddRemoveLuViewEntry(char * luPgName,char * viewEntryPgName,int addRemoveFlag)6317836SJohn.Forte@Sun.COM iPsAddRemoveLuViewEntry(char *luPgName, char *viewEntryPgName,
6327836SJohn.Forte@Sun.COM     int addRemoveFlag)
6337836SJohn.Forte@Sun.COM {
6347836SJohn.Forte@Sun.COM 	scf_handle_t	*handle = NULL;
6357836SJohn.Forte@Sun.COM 	scf_service_t	*svc = NULL;
6367836SJohn.Forte@Sun.COM 	scf_propertygroup_t	*pg = NULL;
6377836SJohn.Forte@Sun.COM 	scf_property_t	*prop = NULL;
6387836SJohn.Forte@Sun.COM 	scf_value_t	*value = NULL;
6397836SJohn.Forte@Sun.COM 	scf_transaction_t   *tran = NULL;
6407836SJohn.Forte@Sun.COM 	scf_transaction_entry_t *entry = NULL;
6417836SJohn.Forte@Sun.COM 	scf_transaction_entry_t *entryVeName = NULL;
6427836SJohn.Forte@Sun.COM 	boolean_t createVeCnt = B_FALSE;
6437836SJohn.Forte@Sun.COM 	uint64_t veCnt = 0;
6447836SJohn.Forte@Sun.COM 	int ret = STMF_PS_SUCCESS;
6457836SJohn.Forte@Sun.COM 	int commitRet;
6467836SJohn.Forte@Sun.COM 
6477836SJohn.Forte@Sun.COM 	assert(luPgName != NULL || viewEntryPgName != NULL);
6487836SJohn.Forte@Sun.COM 	assert(!(addRemoveFlag != ADD && addRemoveFlag != REMOVE));
6497836SJohn.Forte@Sun.COM 
6507836SJohn.Forte@Sun.COM 	/*
6517836SJohn.Forte@Sun.COM 	 * Init the service handle
6527836SJohn.Forte@Sun.COM 	 */
6537836SJohn.Forte@Sun.COM 	ret = iPsInit(&handle, &svc);
6547836SJohn.Forte@Sun.COM 	if (ret != STMF_PS_SUCCESS) {
6557836SJohn.Forte@Sun.COM 		goto out;
6567836SJohn.Forte@Sun.COM 	}
6577836SJohn.Forte@Sun.COM 
6587836SJohn.Forte@Sun.COM 	/*
6597836SJohn.Forte@Sun.COM 	 * Allocate scf resources
6607836SJohn.Forte@Sun.COM 	 */
6617836SJohn.Forte@Sun.COM 	if (((pg = scf_pg_create(handle)) == NULL) ||
6627836SJohn.Forte@Sun.COM 	    ((tran = scf_transaction_create(handle)) == NULL) ||
6637836SJohn.Forte@Sun.COM 	    ((entry = scf_entry_create(handle)) == NULL) ||
6647836SJohn.Forte@Sun.COM 	    ((prop = scf_property_create(handle)) == NULL) ||
6657836SJohn.Forte@Sun.COM 	    ((value = scf_value_create(handle)) == NULL)) {
6667836SJohn.Forte@Sun.COM 		syslog(LOG_ERR, "scf alloc resource failed - %s",
6677836SJohn.Forte@Sun.COM 		    scf_strerror(scf_error()));
6687836SJohn.Forte@Sun.COM 		ret = STMF_PS_ERROR;
6697836SJohn.Forte@Sun.COM 		goto out;
6707836SJohn.Forte@Sun.COM 	}
6717836SJohn.Forte@Sun.COM 
6727836SJohn.Forte@Sun.COM 	/* get the LU property group */
6737836SJohn.Forte@Sun.COM 	if (scf_service_get_pg(svc, luPgName, pg) == -1) {
6747836SJohn.Forte@Sun.COM 		if (scf_error() == SCF_ERROR_NOT_FOUND &&
6757836SJohn.Forte@Sun.COM 		    addRemoveFlag == ADD) {
6767836SJohn.Forte@Sun.COM 			/* if it doesn't exist, create it */
6777836SJohn.Forte@Sun.COM 			if (scf_service_add_pg(svc, luPgName,
6787836SJohn.Forte@Sun.COM 			    SCF_GROUP_APPLICATION, 0, pg) == -1) {
67911909SPeter.Gill@Sun.COM 				syslog(LOG_ERR, "add pg %s failed - %s",
68011909SPeter.Gill@Sun.COM 				    luPgName, scf_strerror(scf_error()));
6817836SJohn.Forte@Sun.COM 				ret = STMF_PS_ERROR;
6827836SJohn.Forte@Sun.COM 			} else {
6837836SJohn.Forte@Sun.COM 				/* we need to create the VE_CNT property */
6847836SJohn.Forte@Sun.COM 				createVeCnt = B_TRUE;
6857836SJohn.Forte@Sun.COM 				ret = STMF_PS_SUCCESS;
6867836SJohn.Forte@Sun.COM 			}
6877836SJohn.Forte@Sun.COM 		} else if (scf_error() == SCF_ERROR_NOT_FOUND) {
6887836SJohn.Forte@Sun.COM 			ret = STMF_PS_ERROR_NOT_FOUND;
6897836SJohn.Forte@Sun.COM 		} else {
69011909SPeter.Gill@Sun.COM 			syslog(LOG_ERR, "get lu pg %s failed - %s",
69111909SPeter.Gill@Sun.COM 			    luPgName, scf_strerror(scf_error()));
6927836SJohn.Forte@Sun.COM 			ret = STMF_PS_ERROR;
6937836SJohn.Forte@Sun.COM 		}
6947836SJohn.Forte@Sun.COM 		if (ret != STMF_PS_SUCCESS) {
6957836SJohn.Forte@Sun.COM 			goto out;
6967836SJohn.Forte@Sun.COM 		}
6977836SJohn.Forte@Sun.COM 	}
6987836SJohn.Forte@Sun.COM 
6997836SJohn.Forte@Sun.COM 
7007836SJohn.Forte@Sun.COM 	/*
7017836SJohn.Forte@Sun.COM 	 * Begin the transaction
7027836SJohn.Forte@Sun.COM 	 */
7037836SJohn.Forte@Sun.COM 	if (scf_transaction_start(tran, pg) == -1) {
70411909SPeter.Gill@Sun.COM 		syslog(LOG_ERR, "start transaction for %s failed - %s",
70511909SPeter.Gill@Sun.COM 		    luPgName, scf_strerror(scf_error()));
7067836SJohn.Forte@Sun.COM 		ret = STMF_PS_ERROR;
7077836SJohn.Forte@Sun.COM 		goto out;
7087836SJohn.Forte@Sun.COM 	}
7097836SJohn.Forte@Sun.COM 
7107836SJohn.Forte@Sun.COM 
7117836SJohn.Forte@Sun.COM 	if (createVeCnt) {
7127836SJohn.Forte@Sun.COM 		/*
7137836SJohn.Forte@Sun.COM 		 * Create the STMF_VE_CNT property. This will keep the current
7147836SJohn.Forte@Sun.COM 		 * total view entries for this logical unit.
7157836SJohn.Forte@Sun.COM 		 */
7167836SJohn.Forte@Sun.COM 		if (scf_transaction_property_new(tran, entry, STMF_VE_CNT,
7177836SJohn.Forte@Sun.COM 		    SCF_TYPE_COUNT) == -1) {
7187836SJohn.Forte@Sun.COM 			if (scf_error() == SCF_ERROR_EXISTS) {
7197836SJohn.Forte@Sun.COM 				ret = STMF_PS_ERROR_EXISTS;
7207836SJohn.Forte@Sun.COM 			} else {
7217836SJohn.Forte@Sun.COM 				syslog(LOG_ERR,
72211909SPeter.Gill@Sun.COM 				    "transaction property new %s/%s "
72311909SPeter.Gill@Sun.COM 				    "failed - %s", luPgName, STMF_VE_CNT,
7247836SJohn.Forte@Sun.COM 				    scf_strerror(scf_error()));
7257836SJohn.Forte@Sun.COM 				ret = STMF_PS_ERROR;
7267836SJohn.Forte@Sun.COM 			}
7277836SJohn.Forte@Sun.COM 			goto out;
7287836SJohn.Forte@Sun.COM 		}
7297836SJohn.Forte@Sun.COM 	} else {
7307836SJohn.Forte@Sun.COM 		/*
7317836SJohn.Forte@Sun.COM 		 * The STMF_VE_CNT property already exists. Just update
7327836SJohn.Forte@Sun.COM 		 * it.
7337836SJohn.Forte@Sun.COM 		 */
7347836SJohn.Forte@Sun.COM 		if (scf_transaction_property_change(tran, entry,
7357836SJohn.Forte@Sun.COM 		    STMF_VE_CNT, SCF_TYPE_COUNT) == -1) {
73611909SPeter.Gill@Sun.COM 			syslog(LOG_ERR, "transaction property %s/%s change "
73711909SPeter.Gill@Sun.COM 			    "failed - %s", luPgName, STMF_VE_CNT,
7387836SJohn.Forte@Sun.COM 			    scf_strerror(scf_error()));
7397836SJohn.Forte@Sun.COM 			ret = STMF_PS_ERROR;
7407836SJohn.Forte@Sun.COM 			goto out;
7417836SJohn.Forte@Sun.COM 		}
7427836SJohn.Forte@Sun.COM 
7437836SJohn.Forte@Sun.COM 		/*
7447836SJohn.Forte@Sun.COM 		 * Get the STMF_VE_CNT property
7457836SJohn.Forte@Sun.COM 		 */
7467836SJohn.Forte@Sun.COM 		if (scf_pg_get_property(pg, STMF_VE_CNT, prop) == -1) {
74711909SPeter.Gill@Sun.COM 			syslog(LOG_ERR, "get property %s/%s failed - %s",
74811909SPeter.Gill@Sun.COM 			    luPgName, STMF_VE_CNT, scf_strerror(scf_error()));
7497836SJohn.Forte@Sun.COM 			ret = STMF_PS_ERROR;
7507836SJohn.Forte@Sun.COM 			goto out;
7517836SJohn.Forte@Sun.COM 		}
7527836SJohn.Forte@Sun.COM 
7537836SJohn.Forte@Sun.COM 		/*
7547836SJohn.Forte@Sun.COM 		 * Get the STMF_VE_CNT value
7557836SJohn.Forte@Sun.COM 		 */
7567836SJohn.Forte@Sun.COM 		if (scf_property_get_value(prop, value) == -1) {
75711909SPeter.Gill@Sun.COM 			syslog(LOG_ERR, "get property %s/%s value failed - %s",
75811909SPeter.Gill@Sun.COM 			    luPgName, STMF_VE_CNT, scf_strerror(scf_error()));
7597836SJohn.Forte@Sun.COM 			ret = STMF_PS_ERROR;
7607836SJohn.Forte@Sun.COM 			goto out;
7617836SJohn.Forte@Sun.COM 		}
7627836SJohn.Forte@Sun.COM 
7637836SJohn.Forte@Sun.COM 		/*
7647836SJohn.Forte@Sun.COM 		 * Now get the actual value from the value handle
7657836SJohn.Forte@Sun.COM 		 */
7667836SJohn.Forte@Sun.COM 		if (scf_value_get_count(value, &veCnt) == -1) {
76711909SPeter.Gill@Sun.COM 			syslog(LOG_ERR, "get count value %s/%s failed - %s",
76811909SPeter.Gill@Sun.COM 			    luPgName, STMF_VE_CNT, scf_strerror(scf_error()));
7697836SJohn.Forte@Sun.COM 			ret = STMF_PS_ERROR;
7707836SJohn.Forte@Sun.COM 			goto out;
7717836SJohn.Forte@Sun.COM 		}
7727836SJohn.Forte@Sun.COM 
7737836SJohn.Forte@Sun.COM 		/*
7747836SJohn.Forte@Sun.COM 		 * Reset the value resource as it is used below
7757836SJohn.Forte@Sun.COM 		 */
7767836SJohn.Forte@Sun.COM 		scf_value_reset(value);
7777836SJohn.Forte@Sun.COM 	}
7787836SJohn.Forte@Sun.COM 
7797836SJohn.Forte@Sun.COM 	if (addRemoveFlag == ADD) {
7807836SJohn.Forte@Sun.COM 		veCnt++;
7817836SJohn.Forte@Sun.COM 	} else {
7827836SJohn.Forte@Sun.COM 		/* Check if this is the last one being removed */
7837836SJohn.Forte@Sun.COM 		if (veCnt == 1) {
7847836SJohn.Forte@Sun.COM 			/*
7857836SJohn.Forte@Sun.COM 			 * Delete the pg and get out if this is the last
7867836SJohn.Forte@Sun.COM 			 * view entry
7877836SJohn.Forte@Sun.COM 			 */
7887836SJohn.Forte@Sun.COM 			if (scf_pg_delete(pg) == -1) {
78911909SPeter.Gill@Sun.COM 				syslog(LOG_ERR, "delete pg %s failed - %s",
79011909SPeter.Gill@Sun.COM 				    luPgName, scf_strerror(scf_error()));
79111909SPeter.Gill@Sun.COM 
7927836SJohn.Forte@Sun.COM 				ret = STMF_PS_ERROR;
7937836SJohn.Forte@Sun.COM 			}
7947836SJohn.Forte@Sun.COM 			goto out;
7957836SJohn.Forte@Sun.COM 		} else {
7967836SJohn.Forte@Sun.COM 			veCnt--;
7977836SJohn.Forte@Sun.COM 		}
7987836SJohn.Forte@Sun.COM 	}
7997836SJohn.Forte@Sun.COM 
8007836SJohn.Forte@Sun.COM 
8017836SJohn.Forte@Sun.COM 	/*
8027836SJohn.Forte@Sun.COM 	 * Set the view entry count
8037836SJohn.Forte@Sun.COM 	 */
8047836SJohn.Forte@Sun.COM 	scf_value_set_count(value, veCnt);
8057836SJohn.Forte@Sun.COM 
8067836SJohn.Forte@Sun.COM 	/*
8077836SJohn.Forte@Sun.COM 	 * Add the value to the transaction entry
8087836SJohn.Forte@Sun.COM 	 */
8097836SJohn.Forte@Sun.COM 	if (scf_entry_add_value(entry, value) == -1) {
81011909SPeter.Gill@Sun.COM 		syslog(LOG_ERR, "add value %s/%s failed - %s",
81111909SPeter.Gill@Sun.COM 		    luPgName, STMF_VE_CNT, scf_strerror(scf_error()));
8127836SJohn.Forte@Sun.COM 		ret = STMF_PS_ERROR;
8137836SJohn.Forte@Sun.COM 		goto out;
8147836SJohn.Forte@Sun.COM 	}
8157836SJohn.Forte@Sun.COM 
8167836SJohn.Forte@Sun.COM 	/*
8177836SJohn.Forte@Sun.COM 	 * Create a transaction entry resource for the view entry name
8187836SJohn.Forte@Sun.COM 	 */
8197836SJohn.Forte@Sun.COM 	entryVeName = scf_entry_create(handle);
8207836SJohn.Forte@Sun.COM 	if (entryVeName == NULL) {
82111909SPeter.Gill@Sun.COM 		syslog(LOG_ERR, "scf transaction entry alloc %s/%s failed - %s",
82211909SPeter.Gill@Sun.COM 		    luPgName, viewEntryPgName, scf_strerror(scf_error()));
8237836SJohn.Forte@Sun.COM 		ret = STMF_PS_ERROR;
8247836SJohn.Forte@Sun.COM 		goto out;
8257836SJohn.Forte@Sun.COM 	}
8267836SJohn.Forte@Sun.COM 
8277836SJohn.Forte@Sun.COM 	if (addRemoveFlag == ADD) {
8287836SJohn.Forte@Sun.COM 		/*
8297836SJohn.Forte@Sun.COM 		 * If adding, create a property with the view entry name
8307836SJohn.Forte@Sun.COM 		 */
8317836SJohn.Forte@Sun.COM 		if (scf_transaction_property_new(tran, entryVeName,
8327836SJohn.Forte@Sun.COM 		    viewEntryPgName, SCF_TYPE_USTRING) == -1) {
8337836SJohn.Forte@Sun.COM 			if (scf_error() == SCF_ERROR_EXISTS) {
8347836SJohn.Forte@Sun.COM 				ret = STMF_PS_ERROR_EXISTS;
8357836SJohn.Forte@Sun.COM 			} else {
8367836SJohn.Forte@Sun.COM 				syslog(LOG_ERR,
83711909SPeter.Gill@Sun.COM 				    "transaction property new %s/%s "
83811909SPeter.Gill@Sun.COM 				    "failed - %s", luPgName, viewEntryPgName,
8397836SJohn.Forte@Sun.COM 				    scf_strerror(scf_error()));
8407836SJohn.Forte@Sun.COM 				ret = STMF_PS_ERROR;
8417836SJohn.Forte@Sun.COM 			}
8427836SJohn.Forte@Sun.COM 			goto out;
8437836SJohn.Forte@Sun.COM 		}
8447836SJohn.Forte@Sun.COM 	} else {
8457836SJohn.Forte@Sun.COM 		/*
8467836SJohn.Forte@Sun.COM 		 * If removing, delete the existing property with the view
8477836SJohn.Forte@Sun.COM 		 * entry name
8487836SJohn.Forte@Sun.COM 		 */
8497836SJohn.Forte@Sun.COM 		if (scf_transaction_property_delete(tran, entryVeName,
8507836SJohn.Forte@Sun.COM 		    viewEntryPgName) == -1) {
8517836SJohn.Forte@Sun.COM 			if (scf_error() == SCF_ERROR_NOT_FOUND) {
8527836SJohn.Forte@Sun.COM 				ret = STMF_PS_ERROR_NOT_FOUND;
8537836SJohn.Forte@Sun.COM 			} else {
8547836SJohn.Forte@Sun.COM 				syslog(LOG_ERR,
85511909SPeter.Gill@Sun.COM 				    "transaction property delete %s/%s "
85611909SPeter.Gill@Sun.COM 				    "failed - %s", luPgName, viewEntryPgName,
8577836SJohn.Forte@Sun.COM 				    scf_strerror(scf_error()));
8587836SJohn.Forte@Sun.COM 				ret = STMF_PS_ERROR;
8597836SJohn.Forte@Sun.COM 			}
8607836SJohn.Forte@Sun.COM 			goto out;
8617836SJohn.Forte@Sun.COM 		}
8627836SJohn.Forte@Sun.COM 	}
8637836SJohn.Forte@Sun.COM 
8647836SJohn.Forte@Sun.COM 	/*
8657836SJohn.Forte@Sun.COM 	 * Commit property transaction
8667836SJohn.Forte@Sun.COM 	 */
8677836SJohn.Forte@Sun.COM 	if ((commitRet = scf_transaction_commit(tran)) != 1) {
86811909SPeter.Gill@Sun.COM 		syslog(LOG_ERR, "transaction commit for %s failed - %s",
86911909SPeter.Gill@Sun.COM 		    luPgName, scf_strerror(scf_error()));
8707836SJohn.Forte@Sun.COM 		if (commitRet == 0) {
8717836SJohn.Forte@Sun.COM 			ret = STMF_PS_ERROR_BUSY;
8727836SJohn.Forte@Sun.COM 		} else {
8737836SJohn.Forte@Sun.COM 			ret = STMF_PS_ERROR;
8747836SJohn.Forte@Sun.COM 		}
8757836SJohn.Forte@Sun.COM 		goto out;
8767836SJohn.Forte@Sun.COM 	}
8777836SJohn.Forte@Sun.COM 
8787836SJohn.Forte@Sun.COM out:
8797836SJohn.Forte@Sun.COM 	/*
8807836SJohn.Forte@Sun.COM 	 * Free resources
8817836SJohn.Forte@Sun.COM 	 */
8827836SJohn.Forte@Sun.COM 	if (handle != NULL) {
8837836SJohn.Forte@Sun.COM 		scf_handle_destroy(handle);
8847836SJohn.Forte@Sun.COM 	}
8857836SJohn.Forte@Sun.COM 	if (svc != NULL) {
8867836SJohn.Forte@Sun.COM 		scf_service_destroy(svc);
8877836SJohn.Forte@Sun.COM 	}
8887836SJohn.Forte@Sun.COM 	if (pg != NULL) {
8897836SJohn.Forte@Sun.COM 		scf_pg_destroy(pg);
8907836SJohn.Forte@Sun.COM 	}
8917836SJohn.Forte@Sun.COM 	if (tran != NULL) {
8927836SJohn.Forte@Sun.COM 		scf_transaction_destroy(tran);
8937836SJohn.Forte@Sun.COM 	}
8947836SJohn.Forte@Sun.COM 	if (entry != NULL) {
8957836SJohn.Forte@Sun.COM 		scf_entry_destroy(entry);
8967836SJohn.Forte@Sun.COM 	}
8977836SJohn.Forte@Sun.COM 	if (entryVeName != NULL) {
8987836SJohn.Forte@Sun.COM 		scf_entry_destroy(entryVeName);
8997836SJohn.Forte@Sun.COM 	}
9007836SJohn.Forte@Sun.COM 	if (prop != NULL) {
9017836SJohn.Forte@Sun.COM 		scf_property_destroy(prop);
9027836SJohn.Forte@Sun.COM 	}
9037836SJohn.Forte@Sun.COM 	if (value != NULL) {
9047836SJohn.Forte@Sun.COM 		scf_value_destroy(value);
9057836SJohn.Forte@Sun.COM 	}
9067836SJohn.Forte@Sun.COM 
9077836SJohn.Forte@Sun.COM 	return (ret);
9087836SJohn.Forte@Sun.COM }
9097836SJohn.Forte@Sun.COM 
9107836SJohn.Forte@Sun.COM /*
9117836SJohn.Forte@Sun.COM  * iPsAddViewEntry
9127836SJohn.Forte@Sun.COM  *
9137836SJohn.Forte@Sun.COM  * Add a view entry property group and optionally, a logical unit property
9147836SJohn.Forte@Sun.COM  * group if it does not exist.
9157836SJohn.Forte@Sun.COM  *
9167836SJohn.Forte@Sun.COM  * luName - ascii hexadecimal logical unit identifier
9177836SJohn.Forte@Sun.COM  * viewEntryName - name of view entry (VIEW_ENTRY_nn)
9187836SJohn.Forte@Sun.COM  * viewEntry - pointer to stmfViewEntry structure
9197836SJohn.Forte@Sun.COM  */
9207836SJohn.Forte@Sun.COM static int
iPsAddViewEntry(char * luPgName,char * viewEntryPgName,stmfViewEntry * viewEntry)9217836SJohn.Forte@Sun.COM iPsAddViewEntry(char *luPgName, char *viewEntryPgName, stmfViewEntry *viewEntry)
9227836SJohn.Forte@Sun.COM {
9237836SJohn.Forte@Sun.COM 	scf_handle_t	*handle = NULL;
9247836SJohn.Forte@Sun.COM 	scf_service_t	*svc = NULL;
9257836SJohn.Forte@Sun.COM 	scf_propertygroup_t	*pg = NULL;
9267836SJohn.Forte@Sun.COM 	scf_value_t	*value[VIEW_ENTRY_STRUCT_CNT];
9277836SJohn.Forte@Sun.COM 	scf_transaction_t   *tran = NULL;
9287836SJohn.Forte@Sun.COM 	scf_transaction_entry_t *entry[VIEW_ENTRY_STRUCT_CNT];
9297836SJohn.Forte@Sun.COM 	int i = 0;
9307836SJohn.Forte@Sun.COM 	int j = 0;
9317836SJohn.Forte@Sun.COM 	int ret;
9327836SJohn.Forte@Sun.COM 	uint8_t scfBool;
9337836SJohn.Forte@Sun.COM 	boolean_t createdVePg = B_FALSE;
9347836SJohn.Forte@Sun.COM 	int backoutRet;
9357836SJohn.Forte@Sun.COM 	int commitRet;
9367836SJohn.Forte@Sun.COM 
9377836SJohn.Forte@Sun.COM 	assert(luPgName != NULL || viewEntryPgName != NULL ||
9387836SJohn.Forte@Sun.COM 	    viewEntry == NULL);
9397836SJohn.Forte@Sun.COM 
9407836SJohn.Forte@Sun.COM 	bzero(value, sizeof (value));
9417836SJohn.Forte@Sun.COM 	bzero(entry, sizeof (entry));
9427836SJohn.Forte@Sun.COM 
9437836SJohn.Forte@Sun.COM 	/*
9447836SJohn.Forte@Sun.COM 	 * Init the service handle
9457836SJohn.Forte@Sun.COM 	 */
9467836SJohn.Forte@Sun.COM 	ret = iPsInit(&handle, &svc);
9477836SJohn.Forte@Sun.COM 	if (ret != STMF_PS_SUCCESS) {
9487836SJohn.Forte@Sun.COM 		goto out;
9497836SJohn.Forte@Sun.COM 	}
9507836SJohn.Forte@Sun.COM 
9517836SJohn.Forte@Sun.COM 	/*
9527836SJohn.Forte@Sun.COM 	 * Allocate scf resources
9537836SJohn.Forte@Sun.COM 	 */
9547836SJohn.Forte@Sun.COM 	if (((pg = scf_pg_create(handle)) == NULL) ||
9557836SJohn.Forte@Sun.COM 	    ((tran = scf_transaction_create(handle)) == NULL)) {
9567836SJohn.Forte@Sun.COM 		syslog(LOG_ERR, "scf alloc resource failed - %s",
9577836SJohn.Forte@Sun.COM 		    scf_strerror(scf_error()));
9587836SJohn.Forte@Sun.COM 		ret = STMF_PS_ERROR;
9597836SJohn.Forte@Sun.COM 		goto out;
9607836SJohn.Forte@Sun.COM 	}
9617836SJohn.Forte@Sun.COM 
9627836SJohn.Forte@Sun.COM 	/*
9637836SJohn.Forte@Sun.COM 	 * allocate value and entry resources for scf
9647836SJohn.Forte@Sun.COM 	 */
9657836SJohn.Forte@Sun.COM 	for (i = 0; i < VIEW_ENTRY_STRUCT_CNT; i++) {
9667836SJohn.Forte@Sun.COM 		if (((value[i] = scf_value_create(handle)) == NULL) ||
9677836SJohn.Forte@Sun.COM 		    ((entry[i] = scf_entry_create(handle)) == NULL)) {
9687836SJohn.Forte@Sun.COM 			syslog(LOG_ERR, "scf alloc resource failed - %s",
9697836SJohn.Forte@Sun.COM 			    scf_strerror(scf_error()));
9707836SJohn.Forte@Sun.COM 			ret = STMF_PS_ERROR;
9717836SJohn.Forte@Sun.COM 			goto out;
9727836SJohn.Forte@Sun.COM 		}
9737836SJohn.Forte@Sun.COM 	}
9747836SJohn.Forte@Sun.COM 
9757836SJohn.Forte@Sun.COM 	i = 0;
9767836SJohn.Forte@Sun.COM 
9777836SJohn.Forte@Sun.COM 	/*
9787836SJohn.Forte@Sun.COM 	 * Create the View Entry property group
9797836SJohn.Forte@Sun.COM 	 */
9807836SJohn.Forte@Sun.COM 	if (scf_service_add_pg(svc, viewEntryPgName, SCF_GROUP_APPLICATION,
9817836SJohn.Forte@Sun.COM 	    0, pg) == -1) {
9827836SJohn.Forte@Sun.COM 		if (scf_error() == SCF_ERROR_EXISTS) {
9837836SJohn.Forte@Sun.COM 			ret = STMF_PS_ERROR_EXISTS;
9847836SJohn.Forte@Sun.COM 		} else {
98511909SPeter.Gill@Sun.COM 			syslog(LOG_ERR, "add pg %s failed - %s",
98611909SPeter.Gill@Sun.COM 			    viewEntryPgName, scf_strerror(scf_error()));
9877836SJohn.Forte@Sun.COM 			ret = STMF_PS_ERROR;
9887836SJohn.Forte@Sun.COM 		}
9897836SJohn.Forte@Sun.COM 		goto out;
9907836SJohn.Forte@Sun.COM 	}
9917836SJohn.Forte@Sun.COM 
9927836SJohn.Forte@Sun.COM 	createdVePg = B_TRUE;
9937836SJohn.Forte@Sun.COM 
9947836SJohn.Forte@Sun.COM 	/*
9957836SJohn.Forte@Sun.COM 	 * Add the view entry as properties on the view entry group
9967836SJohn.Forte@Sun.COM 	 */
9977836SJohn.Forte@Sun.COM 
9987836SJohn.Forte@Sun.COM 	/*
9997836SJohn.Forte@Sun.COM 	 * Begin property update transaction
10007836SJohn.Forte@Sun.COM 	 */
10017836SJohn.Forte@Sun.COM 	if (scf_transaction_start(tran, pg) == -1) {
100211909SPeter.Gill@Sun.COM 		syslog(LOG_ERR, "start transaction for add %s failed - %s",
100311909SPeter.Gill@Sun.COM 		    viewEntryPgName, scf_strerror(scf_error()));
10047836SJohn.Forte@Sun.COM 		ret = STMF_PS_ERROR;
10057836SJohn.Forte@Sun.COM 		goto out;
10067836SJohn.Forte@Sun.COM 	}
10077836SJohn.Forte@Sun.COM 
10087836SJohn.Forte@Sun.COM 	/*
10097836SJohn.Forte@Sun.COM 	 * Add allHosts property
10107836SJohn.Forte@Sun.COM 	 */
10117836SJohn.Forte@Sun.COM 	if (scf_transaction_property_new(tran, entry[i],
10127836SJohn.Forte@Sun.COM 	    STMF_VE_ALLHOSTS, SCF_TYPE_BOOLEAN) == -1) {
10137836SJohn.Forte@Sun.COM 		if (scf_error() == SCF_ERROR_EXISTS) {
10147836SJohn.Forte@Sun.COM 			ret = STMF_PS_ERROR_EXISTS;
10157836SJohn.Forte@Sun.COM 		} else {
101611909SPeter.Gill@Sun.COM 			syslog(LOG_ERR, "transaction property new %s/%s "
101711909SPeter.Gill@Sun.COM 			    "failed - %s", viewEntryPgName, STMF_VE_ALLHOSTS,
10187836SJohn.Forte@Sun.COM 			    scf_strerror(scf_error()));
10197836SJohn.Forte@Sun.COM 			ret = STMF_PS_ERROR;
10207836SJohn.Forte@Sun.COM 		}
10217836SJohn.Forte@Sun.COM 		goto out;
10227836SJohn.Forte@Sun.COM 	}
10237836SJohn.Forte@Sun.COM 
10247836SJohn.Forte@Sun.COM 	/* Set the allHosts value */
10257836SJohn.Forte@Sun.COM 	scfBool = viewEntry->allHosts;
10267836SJohn.Forte@Sun.COM 	scf_value_set_boolean(value[i], scfBool);
10277836SJohn.Forte@Sun.COM 
10287836SJohn.Forte@Sun.COM 	/*
10297836SJohn.Forte@Sun.COM 	 * Add the allHosts value to the transaction
10307836SJohn.Forte@Sun.COM 	 */
10317836SJohn.Forte@Sun.COM 	if (scf_entry_add_value(entry[i], value[i]) == -1) {
103211909SPeter.Gill@Sun.COM 		syslog(LOG_ERR, "add value %s/%s failed - %s",
103311909SPeter.Gill@Sun.COM 		    viewEntryPgName, STMF_VE_ALLHOSTS,
10347836SJohn.Forte@Sun.COM 		    scf_strerror(scf_error()));
10357836SJohn.Forte@Sun.COM 		ret = STMF_PS_ERROR;
10367836SJohn.Forte@Sun.COM 		goto out;
10377836SJohn.Forte@Sun.COM 	}
10387836SJohn.Forte@Sun.COM 
10397836SJohn.Forte@Sun.COM 	i++;
10407836SJohn.Forte@Sun.COM 
10417836SJohn.Forte@Sun.COM 	/*
10427836SJohn.Forte@Sun.COM 	 * Create hostGroup property
10437836SJohn.Forte@Sun.COM 	 */
10447836SJohn.Forte@Sun.COM 	if (scf_transaction_property_new(tran, entry[i],
10457836SJohn.Forte@Sun.COM 	    STMF_VE_HOSTGROUP, SCF_TYPE_USTRING) == -1) {
10467836SJohn.Forte@Sun.COM 		if (scf_error() == SCF_ERROR_EXISTS) {
10477836SJohn.Forte@Sun.COM 			ret = STMF_PS_ERROR_EXISTS;
10487836SJohn.Forte@Sun.COM 		} else {
104911909SPeter.Gill@Sun.COM 			syslog(LOG_ERR, "transaction property new %s/%s "
105011909SPeter.Gill@Sun.COM 			    "failed - %s", viewEntryPgName, STMF_VE_HOSTGROUP,
10517836SJohn.Forte@Sun.COM 			    scf_strerror(scf_error()));
10527836SJohn.Forte@Sun.COM 			ret = STMF_PS_ERROR;
10537836SJohn.Forte@Sun.COM 		}
10547836SJohn.Forte@Sun.COM 		goto out;
10557836SJohn.Forte@Sun.COM 	}
10567836SJohn.Forte@Sun.COM 
10577836SJohn.Forte@Sun.COM 	/*
10587836SJohn.Forte@Sun.COM 	 * Set the value for hostGroup
10597836SJohn.Forte@Sun.COM 	 */
10607836SJohn.Forte@Sun.COM 	if (scf_value_set_ustring(value[i], viewEntry->hostGroup) == -1) {
106111909SPeter.Gill@Sun.COM 		syslog(LOG_ERR, "set value %s/%s failed - %s",
106211909SPeter.Gill@Sun.COM 		    viewEntryPgName, STMF_VE_HOSTGROUP,
10637836SJohn.Forte@Sun.COM 		    scf_strerror(scf_error()));
10647836SJohn.Forte@Sun.COM 		ret = STMF_PS_ERROR;
10657836SJohn.Forte@Sun.COM 		goto out;
10667836SJohn.Forte@Sun.COM 	}
10677836SJohn.Forte@Sun.COM 
10687836SJohn.Forte@Sun.COM 	/*
10697836SJohn.Forte@Sun.COM 	 * Add the hostGroup value to the transaction entry
10707836SJohn.Forte@Sun.COM 	 */
10717836SJohn.Forte@Sun.COM 	if (scf_entry_add_value(entry[i], value[i]) == -1) {
107211909SPeter.Gill@Sun.COM 		syslog(LOG_ERR, "add value %s/%s failed - %s",
107311909SPeter.Gill@Sun.COM 		    viewEntryPgName, STMF_VE_HOSTGROUP,
10747836SJohn.Forte@Sun.COM 		    scf_strerror(scf_error()));
10757836SJohn.Forte@Sun.COM 		ret = STMF_PS_ERROR;
10767836SJohn.Forte@Sun.COM 		goto out;
10777836SJohn.Forte@Sun.COM 	}
10787836SJohn.Forte@Sun.COM 
10797836SJohn.Forte@Sun.COM 	i++;
10807836SJohn.Forte@Sun.COM 
10817836SJohn.Forte@Sun.COM 	/*
10827836SJohn.Forte@Sun.COM 	 * Create the allTargets property
10837836SJohn.Forte@Sun.COM 	 */
10847836SJohn.Forte@Sun.COM 	if (scf_transaction_property_new(tran, entry[i],
10857836SJohn.Forte@Sun.COM 	    STMF_VE_ALLTARGETS, SCF_TYPE_BOOLEAN) == -1) {
10867836SJohn.Forte@Sun.COM 		if (scf_error() == SCF_ERROR_EXISTS) {
10877836SJohn.Forte@Sun.COM 			ret = STMF_PS_ERROR_EXISTS;
10887836SJohn.Forte@Sun.COM 		} else {
108911909SPeter.Gill@Sun.COM 			syslog(LOG_ERR, "transaction property new %s/%s "
109011909SPeter.Gill@Sun.COM 			    "failed - %s", viewEntryPgName, STMF_VE_ALLTARGETS,
10917836SJohn.Forte@Sun.COM 			    scf_strerror(scf_error()));
10927836SJohn.Forte@Sun.COM 			ret = STMF_PS_ERROR;
10937836SJohn.Forte@Sun.COM 		}
10947836SJohn.Forte@Sun.COM 		goto out;
10957836SJohn.Forte@Sun.COM 	}
10967836SJohn.Forte@Sun.COM 
10977836SJohn.Forte@Sun.COM 	/*
10987836SJohn.Forte@Sun.COM 	 * Set the allTargets value
10997836SJohn.Forte@Sun.COM 	 */
11007836SJohn.Forte@Sun.COM 	scfBool = viewEntry->allTargets;
11017836SJohn.Forte@Sun.COM 	scf_value_set_boolean(value[i], scfBool);
11027836SJohn.Forte@Sun.COM 
11037836SJohn.Forte@Sun.COM 	/*
11047836SJohn.Forte@Sun.COM 	 * Add the allTargets value to the transaction
11057836SJohn.Forte@Sun.COM 	 */
11067836SJohn.Forte@Sun.COM 	if (scf_entry_add_value(entry[i], value[i]) == -1) {
110711909SPeter.Gill@Sun.COM 		syslog(LOG_ERR, "add value %s/%s failed - %s",
110811909SPeter.Gill@Sun.COM 		    viewEntryPgName, STMF_VE_ALLTARGETS,
11097836SJohn.Forte@Sun.COM 		    scf_strerror(scf_error()));
11107836SJohn.Forte@Sun.COM 		ret = STMF_PS_ERROR;
11117836SJohn.Forte@Sun.COM 		goto out;
11127836SJohn.Forte@Sun.COM 	}
11137836SJohn.Forte@Sun.COM 
11147836SJohn.Forte@Sun.COM 	i++;
11157836SJohn.Forte@Sun.COM 
11167836SJohn.Forte@Sun.COM 	/*
11177836SJohn.Forte@Sun.COM 	 * Create targetGroup property
11187836SJohn.Forte@Sun.COM 	 */
11197836SJohn.Forte@Sun.COM 	if (scf_transaction_property_new(tran, entry[i],
11207836SJohn.Forte@Sun.COM 	    STMF_VE_TARGETGROUP, SCF_TYPE_USTRING) == -1) {
11217836SJohn.Forte@Sun.COM 		if (scf_error() == SCF_ERROR_EXISTS) {
11227836SJohn.Forte@Sun.COM 			ret = STMF_PS_ERROR_EXISTS;
11237836SJohn.Forte@Sun.COM 		} else {
112411909SPeter.Gill@Sun.COM 			syslog(LOG_ERR, "transaction property new %s/%s "
112511909SPeter.Gill@Sun.COM 			    "failed - %s", viewEntryPgName,
112611909SPeter.Gill@Sun.COM 			    STMF_VE_TARGETGROUP, scf_strerror(scf_error()));
11277836SJohn.Forte@Sun.COM 			ret = STMF_PS_ERROR;
11287836SJohn.Forte@Sun.COM 		}
11297836SJohn.Forte@Sun.COM 		goto out;
11307836SJohn.Forte@Sun.COM 	}
11317836SJohn.Forte@Sun.COM 
11327836SJohn.Forte@Sun.COM 	/*
11337836SJohn.Forte@Sun.COM 	 * Set the value for targetGroup
11347836SJohn.Forte@Sun.COM 	 */
11357836SJohn.Forte@Sun.COM 	if (scf_value_set_ustring(value[i], viewEntry->targetGroup) == -1) {
113611909SPeter.Gill@Sun.COM 		syslog(LOG_ERR, "set value %s/%s failed - %s",
113711909SPeter.Gill@Sun.COM 		    viewEntryPgName, STMF_VE_TARGETGROUP,
11387836SJohn.Forte@Sun.COM 		    scf_strerror(scf_error()));
11397836SJohn.Forte@Sun.COM 		ret = STMF_PS_ERROR;
11407836SJohn.Forte@Sun.COM 		goto out;
11417836SJohn.Forte@Sun.COM 	}
11427836SJohn.Forte@Sun.COM 
11437836SJohn.Forte@Sun.COM 	/*
11447836SJohn.Forte@Sun.COM 	 * Add targetGroup value to the transaction
11457836SJohn.Forte@Sun.COM 	 */
11467836SJohn.Forte@Sun.COM 	if (scf_entry_add_value(entry[i], value[i]) == -1) {
114711909SPeter.Gill@Sun.COM 		syslog(LOG_ERR, "add value %s/%s failed - %s",
114811909SPeter.Gill@Sun.COM 		    viewEntryPgName, STMF_VE_TARGETGROUP,
11497836SJohn.Forte@Sun.COM 		    scf_strerror(scf_error()));
11507836SJohn.Forte@Sun.COM 		ret = STMF_PS_ERROR;
11517836SJohn.Forte@Sun.COM 		goto out;
11527836SJohn.Forte@Sun.COM 	}
11537836SJohn.Forte@Sun.COM 
11547836SJohn.Forte@Sun.COM 	i++;
11557836SJohn.Forte@Sun.COM 
11567836SJohn.Forte@Sun.COM 	/*
11577836SJohn.Forte@Sun.COM 	 * Create the luNbr property
11587836SJohn.Forte@Sun.COM 	 */
11597836SJohn.Forte@Sun.COM 	if (scf_transaction_property_new(tran, entry[i], STMF_VE_LUNBR,
11607836SJohn.Forte@Sun.COM 	    SCF_TYPE_OPAQUE) == -1) {
11617836SJohn.Forte@Sun.COM 		if (scf_error() == SCF_ERROR_EXISTS) {
11627836SJohn.Forte@Sun.COM 			ret = STMF_PS_ERROR_EXISTS;
11637836SJohn.Forte@Sun.COM 		} else {
116411909SPeter.Gill@Sun.COM 			syslog(LOG_ERR, "transaction property new %s/%s "
116511909SPeter.Gill@Sun.COM 			    "failed - %s", viewEntryPgName, STMF_VE_LUNBR,
11667836SJohn.Forte@Sun.COM 			    scf_strerror(scf_error()));
11677836SJohn.Forte@Sun.COM 			ret = STMF_PS_ERROR;
11687836SJohn.Forte@Sun.COM 		}
11697836SJohn.Forte@Sun.COM 		goto out;
11707836SJohn.Forte@Sun.COM 	}
11717836SJohn.Forte@Sun.COM 
11727836SJohn.Forte@Sun.COM 	/*
11737836SJohn.Forte@Sun.COM 	 * Set the luNbr
11747836SJohn.Forte@Sun.COM 	 */
11757836SJohn.Forte@Sun.COM 	if (scf_value_set_opaque(value[i], (char *)viewEntry->luNbr,
11767836SJohn.Forte@Sun.COM 	    sizeof (viewEntry->luNbr)) == -1) {
117711909SPeter.Gill@Sun.COM 		syslog(LOG_ERR, "set value %s/%s failed - %s",
117811909SPeter.Gill@Sun.COM 		    viewEntryPgName, STMF_VE_LUNBR, scf_strerror(scf_error()));
11797836SJohn.Forte@Sun.COM 		ret = STMF_PS_ERROR;
11807836SJohn.Forte@Sun.COM 		goto out;
11817836SJohn.Forte@Sun.COM 	}
11827836SJohn.Forte@Sun.COM 
11837836SJohn.Forte@Sun.COM 	/*
11847836SJohn.Forte@Sun.COM 	 * Add luNbr to the transaction entry
11857836SJohn.Forte@Sun.COM 	 */
11867836SJohn.Forte@Sun.COM 	if (scf_entry_add_value(entry[i], value[i]) == -1) {
118711909SPeter.Gill@Sun.COM 		syslog(LOG_ERR, "add value %s/%s failed - %s",
118811909SPeter.Gill@Sun.COM 		    viewEntryPgName, STMF_VE_LUNBR, scf_strerror(scf_error()));
11897836SJohn.Forte@Sun.COM 		ret = STMF_PS_ERROR;
11907836SJohn.Forte@Sun.COM 		goto out;
11917836SJohn.Forte@Sun.COM 	}
11927836SJohn.Forte@Sun.COM 
11937836SJohn.Forte@Sun.COM 	/*
11947836SJohn.Forte@Sun.COM 	 * Now that we've successfully added the view entry,
11957836SJohn.Forte@Sun.COM 	 * update the logical unit property group or create
11967836SJohn.Forte@Sun.COM 	 * it if it does not exist
11977836SJohn.Forte@Sun.COM 	 */
11987836SJohn.Forte@Sun.COM 	ret = iPsAddRemoveLuViewEntry(luPgName, viewEntryPgName, ADD);
11997836SJohn.Forte@Sun.COM 
12007836SJohn.Forte@Sun.COM 	/*
12017836SJohn.Forte@Sun.COM 	 * If we did not add the view entry name to the logical unit,
12027836SJohn.Forte@Sun.COM 	 * make sure we do not commit the transaction
12037836SJohn.Forte@Sun.COM 	 */
12047836SJohn.Forte@Sun.COM 	if (ret != STMF_PS_SUCCESS) {
12057836SJohn.Forte@Sun.COM 		goto out;
12067836SJohn.Forte@Sun.COM 	}
12077836SJohn.Forte@Sun.COM 
12087836SJohn.Forte@Sun.COM 	/*
12097836SJohn.Forte@Sun.COM 	 * Commit property transaction
12107836SJohn.Forte@Sun.COM 	 */
12117836SJohn.Forte@Sun.COM 	if ((commitRet = scf_transaction_commit(tran)) != 1) {
121211909SPeter.Gill@Sun.COM 		syslog(LOG_ERR, "transaction commit for add %s failed - %s",
121311909SPeter.Gill@Sun.COM 		    viewEntryPgName, scf_strerror(scf_error()));
12147836SJohn.Forte@Sun.COM 		if (commitRet == 0) {
12157836SJohn.Forte@Sun.COM 			ret = STMF_PS_ERROR_BUSY;
12167836SJohn.Forte@Sun.COM 		} else {
12177836SJohn.Forte@Sun.COM 			ret = STMF_PS_ERROR;
12187836SJohn.Forte@Sun.COM 		}
12197836SJohn.Forte@Sun.COM 	}
12207836SJohn.Forte@Sun.COM 
12217836SJohn.Forte@Sun.COM 	if (ret != STMF_PS_SUCCESS) {
12227836SJohn.Forte@Sun.COM 		/*
12237836SJohn.Forte@Sun.COM 		 * If we did not commit, try to remove the view entry name
12247836SJohn.Forte@Sun.COM 		 * from the logical unit.
12257836SJohn.Forte@Sun.COM 		 * If that fails, we're now inconsistent.
12267836SJohn.Forte@Sun.COM 		 */
12277836SJohn.Forte@Sun.COM 		backoutRet = iPsAddRemoveLuViewEntry(luPgName, viewEntryPgName,
12287836SJohn.Forte@Sun.COM 		    REMOVE);
12297836SJohn.Forte@Sun.COM 
12307836SJohn.Forte@Sun.COM 		if (backoutRet != STMF_PS_SUCCESS) {
123111909SPeter.Gill@Sun.COM 			syslog(LOG_ERR, "remove lu view entry %s failed"
123211909SPeter.Gill@Sun.COM 			    "possible inconsistency - %s", luPgName,
12337836SJohn.Forte@Sun.COM 			    scf_strerror(scf_error()));
12347836SJohn.Forte@Sun.COM 		}
12357836SJohn.Forte@Sun.COM 		/*
12367836SJohn.Forte@Sun.COM 		 * We are still in an error scenario even though the remove
12377836SJohn.Forte@Sun.COM 		 * lu view entry succeeded.
12387836SJohn.Forte@Sun.COM 		 */
12397836SJohn.Forte@Sun.COM 		goto out;
12407836SJohn.Forte@Sun.COM 	}
12417836SJohn.Forte@Sun.COM 
12427836SJohn.Forte@Sun.COM out:
12437836SJohn.Forte@Sun.COM 	/*
12447836SJohn.Forte@Sun.COM 	 * Free resources
12457836SJohn.Forte@Sun.COM 	 */
12467836SJohn.Forte@Sun.COM 	if (handle != NULL) {
12477836SJohn.Forte@Sun.COM 		scf_handle_destroy(handle);
12487836SJohn.Forte@Sun.COM 	}
12497836SJohn.Forte@Sun.COM 	if (svc != NULL) {
12507836SJohn.Forte@Sun.COM 		scf_service_destroy(svc);
12517836SJohn.Forte@Sun.COM 	}
12527836SJohn.Forte@Sun.COM 	/* if there was an error, delete the created pg if one was created */
12537836SJohn.Forte@Sun.COM 	if ((ret != STMF_PS_SUCCESS) && createdVePg) {
12547836SJohn.Forte@Sun.COM 		if (scf_pg_delete(pg) == -1) {
125511909SPeter.Gill@Sun.COM 			syslog(LOG_ERR, "delete VE pg %s failed - %s",
125611909SPeter.Gill@Sun.COM 			    viewEntryPgName, scf_strerror(scf_error()));
12577836SJohn.Forte@Sun.COM 		}
12587836SJohn.Forte@Sun.COM 	}
12597836SJohn.Forte@Sun.COM 	if (pg != NULL) {
12607836SJohn.Forte@Sun.COM 		scf_pg_destroy(pg);
12617836SJohn.Forte@Sun.COM 	}
12627836SJohn.Forte@Sun.COM 	if (tran != NULL) {
12637836SJohn.Forte@Sun.COM 		scf_transaction_destroy(tran);
12647836SJohn.Forte@Sun.COM 	}
12657836SJohn.Forte@Sun.COM 	/*
12667836SJohn.Forte@Sun.COM 	 * Free value and entry scf resources
12677836SJohn.Forte@Sun.COM 	 */
12687836SJohn.Forte@Sun.COM 	if (i > 0) {
12697836SJohn.Forte@Sun.COM 		for (j = 0; j < VIEW_ENTRY_STRUCT_CNT; j++) {
12707836SJohn.Forte@Sun.COM 			if (value[j] != NULL)
12717836SJohn.Forte@Sun.COM 				scf_value_destroy(value[j]);
12727836SJohn.Forte@Sun.COM 			if (entry[j] != NULL)
12737836SJohn.Forte@Sun.COM 				scf_entry_destroy(entry[j]);
12747836SJohn.Forte@Sun.COM 		}
12757836SJohn.Forte@Sun.COM 	}
12767836SJohn.Forte@Sun.COM 
12777836SJohn.Forte@Sun.COM 	return (ret);
12787836SJohn.Forte@Sun.COM }
12797836SJohn.Forte@Sun.COM /*
12807836SJohn.Forte@Sun.COM  * psClearProviderData
12817836SJohn.Forte@Sun.COM  *
12827836SJohn.Forte@Sun.COM  * providerName - name of provider data to clear
12837836SJohn.Forte@Sun.COM  */
12847836SJohn.Forte@Sun.COM int
psClearProviderData(char * providerName,int providerType)12857836SJohn.Forte@Sun.COM psClearProviderData(char *providerName, int providerType)
12867836SJohn.Forte@Sun.COM {
12877836SJohn.Forte@Sun.COM 	scf_handle_t	*handle = NULL;
12887836SJohn.Forte@Sun.COM 	scf_service_t	*svc = NULL;
12897836SJohn.Forte@Sun.COM 	scf_propertygroup_t	*pg = NULL;
12907836SJohn.Forte@Sun.COM 	char pgName[MAXPATHLEN];
12917836SJohn.Forte@Sun.COM 	int ret = STMF_PS_SUCCESS;
12927836SJohn.Forte@Sun.COM 	boolean_t pgNotFound = B_FALSE;
12937836SJohn.Forte@Sun.COM 
12947836SJohn.Forte@Sun.COM 	if (providerName == NULL || (providerType != STMF_LU_PROVIDER_TYPE &&
12957836SJohn.Forte@Sun.COM 	    providerType != STMF_PORT_PROVIDER_TYPE)) {
12967836SJohn.Forte@Sun.COM 		ret = STMF_PS_ERROR_INVALID_ARG;
12977836SJohn.Forte@Sun.COM 		goto out;
12987836SJohn.Forte@Sun.COM 	}
12997836SJohn.Forte@Sun.COM 
13007836SJohn.Forte@Sun.COM 	ret = iPsInit(&handle, &svc);
13017836SJohn.Forte@Sun.COM 	if (ret != STMF_PS_SUCCESS) {
13027836SJohn.Forte@Sun.COM 		goto out;
13037836SJohn.Forte@Sun.COM 	}
13047836SJohn.Forte@Sun.COM 
13057836SJohn.Forte@Sun.COM 	/*
13067836SJohn.Forte@Sun.COM 	 * Allocate scf resources
13077836SJohn.Forte@Sun.COM 	 */
13087836SJohn.Forte@Sun.COM 	if ((pg = scf_pg_create(handle)) == NULL) {
13097836SJohn.Forte@Sun.COM 		syslog(LOG_ERR, "scf alloc resource failed - %s",
13107836SJohn.Forte@Sun.COM 		    scf_strerror(scf_error()));
13117836SJohn.Forte@Sun.COM 		ret = STMF_PS_ERROR;
13127836SJohn.Forte@Sun.COM 		goto out;
13137836SJohn.Forte@Sun.COM 	}
13147836SJohn.Forte@Sun.COM 
13157836SJohn.Forte@Sun.COM 	/*
13167836SJohn.Forte@Sun.COM 	 * create the property group name
13177836SJohn.Forte@Sun.COM 	 */
13187836SJohn.Forte@Sun.COM 	(void) snprintf(pgName, sizeof (pgName), "%s%s",
13197836SJohn.Forte@Sun.COM 	    STMF_PROVIDER_DATA_PREFIX, providerName);
13207836SJohn.Forte@Sun.COM 
13217836SJohn.Forte@Sun.COM 	/*
13227836SJohn.Forte@Sun.COM 	 * delete provider property group
13237836SJohn.Forte@Sun.COM 	 */
13247836SJohn.Forte@Sun.COM 	if (scf_service_get_pg(svc, pgName, pg) == -1) {
13257836SJohn.Forte@Sun.COM 		if (scf_error() != SCF_ERROR_NOT_FOUND) {
132611909SPeter.Gill@Sun.COM 			syslog(LOG_ERR, "get pg %s failed - %s",
132711909SPeter.Gill@Sun.COM 			    pgName, scf_strerror(scf_error()));
13287836SJohn.Forte@Sun.COM 			ret = STMF_PS_ERROR;
13297836SJohn.Forte@Sun.COM 			goto out;
13307836SJohn.Forte@Sun.COM 		} else {
13317836SJohn.Forte@Sun.COM 			pgNotFound = B_TRUE;
13327836SJohn.Forte@Sun.COM 		}
13337836SJohn.Forte@Sun.COM 	}
13347836SJohn.Forte@Sun.COM 
13357836SJohn.Forte@Sun.COM 	if (!pgNotFound && (scf_pg_delete(pg) == -1)) {
133611909SPeter.Gill@Sun.COM 		syslog(LOG_ERR, "delete pg %s failed - %s",
133711909SPeter.Gill@Sun.COM 		    pgName, scf_strerror(scf_error()));
13387836SJohn.Forte@Sun.COM 		ret = STMF_PS_ERROR;
13397836SJohn.Forte@Sun.COM 		goto out;
13407836SJohn.Forte@Sun.COM 	}
13417836SJohn.Forte@Sun.COM 
13427836SJohn.Forte@Sun.COM 	if (pgNotFound) {
13437836SJohn.Forte@Sun.COM 		ret = STMF_PS_ERROR_NOT_FOUND;
13447836SJohn.Forte@Sun.COM 	}
13457836SJohn.Forte@Sun.COM 
13467836SJohn.Forte@Sun.COM out:
13477836SJohn.Forte@Sun.COM 	/*
13487836SJohn.Forte@Sun.COM 	 * Free resources
13497836SJohn.Forte@Sun.COM 	 */
13507836SJohn.Forte@Sun.COM 	if (handle != NULL) {
13517836SJohn.Forte@Sun.COM 		scf_handle_destroy(handle);
13527836SJohn.Forte@Sun.COM 	}
13537836SJohn.Forte@Sun.COM 	if (svc != NULL) {
13547836SJohn.Forte@Sun.COM 		scf_service_destroy(svc);
13557836SJohn.Forte@Sun.COM 	}
13567836SJohn.Forte@Sun.COM 	if (pg != NULL) {
13577836SJohn.Forte@Sun.COM 		scf_pg_destroy(pg);
13587836SJohn.Forte@Sun.COM 	}
13597836SJohn.Forte@Sun.COM 
13607836SJohn.Forte@Sun.COM 	return (ret);
13617836SJohn.Forte@Sun.COM }
13627836SJohn.Forte@Sun.COM 
13637836SJohn.Forte@Sun.COM /*
13647836SJohn.Forte@Sun.COM  * iPsCreateDeleteGroup
13657836SJohn.Forte@Sun.COM  *
13667836SJohn.Forte@Sun.COM  * Creates or deletes a group (target or host)
13677836SJohn.Forte@Sun.COM  *
13687836SJohn.Forte@Sun.COM  * When creating a group, two properties are created. One to hold the group
13697836SJohn.Forte@Sun.COM  * name and the other to hold the group members.
13707836SJohn.Forte@Sun.COM  *
13717836SJohn.Forte@Sun.COM  * pgName - Property group name
13727836SJohn.Forte@Sun.COM  * groupName - group name to create
13737836SJohn.Forte@Sun.COM  * addRemoveFlag - ADD_GROUP/REMOVE_GROUP
13747836SJohn.Forte@Sun.COM  *
13757836SJohn.Forte@Sun.COM  * returns:
13767836SJohn.Forte@Sun.COM  *  STMF_PS_SUCCESS on success
13777836SJohn.Forte@Sun.COM  *  STMF_PS_ERROR_* on failure
13787836SJohn.Forte@Sun.COM  */
13797836SJohn.Forte@Sun.COM static int
iPsCreateDeleteGroup(char * pgRefName,char * groupName,int addRemoveFlag)13807836SJohn.Forte@Sun.COM iPsCreateDeleteGroup(char *pgRefName, char *groupName, int addRemoveFlag)
13817836SJohn.Forte@Sun.COM {
13827836SJohn.Forte@Sun.COM 	scf_handle_t	*handle = NULL;
13837836SJohn.Forte@Sun.COM 	scf_service_t	*svc = NULL;
13847836SJohn.Forte@Sun.COM 	scf_propertygroup_t	*pg = NULL;
13857836SJohn.Forte@Sun.COM 	scf_property_t	*prop = NULL;
13867836SJohn.Forte@Sun.COM 	scf_iter_t	*propIter = NULL;
13877836SJohn.Forte@Sun.COM 	scf_transaction_t   *tran = NULL;
13887836SJohn.Forte@Sun.COM 	scf_transaction_entry_t *entry1 = NULL;
13897836SJohn.Forte@Sun.COM 	scf_transaction_entry_t *entry2 = NULL;
13907836SJohn.Forte@Sun.COM 	scf_value_t *value = NULL;
13917836SJohn.Forte@Sun.COM 	uint64_t groupIdx;
13927836SJohn.Forte@Sun.COM 	char buf1[MAXNAMELEN];
13937836SJohn.Forte@Sun.COM 	char buf2[MAXNAMELEN];
13947836SJohn.Forte@Sun.COM 	char tmpbuf[MAXNAMELEN];
13957836SJohn.Forte@Sun.COM 	boolean_t found = B_FALSE;
13967836SJohn.Forte@Sun.COM 	int ret = STMF_PS_SUCCESS;
13977836SJohn.Forte@Sun.COM 	int commitRet;
13987836SJohn.Forte@Sun.COM 
13997836SJohn.Forte@Sun.COM 	assert(groupName != NULL);
14007836SJohn.Forte@Sun.COM 
14017836SJohn.Forte@Sun.COM 	ret = iPsInit(&handle, &svc);
14027836SJohn.Forte@Sun.COM 	if (ret != STMF_PS_SUCCESS) {
14037836SJohn.Forte@Sun.COM 		goto out;
14047836SJohn.Forte@Sun.COM 	}
14057836SJohn.Forte@Sun.COM 
14067836SJohn.Forte@Sun.COM 	/*
14077836SJohn.Forte@Sun.COM 	 * Allocate scf resources
14087836SJohn.Forte@Sun.COM 	 */
14097836SJohn.Forte@Sun.COM 	if (((pg = scf_pg_create(handle)) == NULL) ||
14107836SJohn.Forte@Sun.COM 	    ((tran = scf_transaction_create(handle)) == NULL) ||
14117836SJohn.Forte@Sun.COM 	    ((entry1 = scf_entry_create(handle)) == NULL) ||
14127836SJohn.Forte@Sun.COM 	    ((entry2 = scf_entry_create(handle)) == NULL) ||
14137836SJohn.Forte@Sun.COM 	    ((prop = scf_property_create(handle)) == NULL) ||
14147836SJohn.Forte@Sun.COM 	    ((propIter = scf_iter_create(handle)) == NULL) ||
14157836SJohn.Forte@Sun.COM 	    ((value = scf_value_create(handle)) == NULL)) {
14167836SJohn.Forte@Sun.COM 		syslog(LOG_ERR, "scf alloc resource failed - %s",
14177836SJohn.Forte@Sun.COM 		    scf_strerror(scf_error()));
14187836SJohn.Forte@Sun.COM 		ret = STMF_PS_ERROR;
14197836SJohn.Forte@Sun.COM 		goto out;
14207836SJohn.Forte@Sun.COM 	}
14217836SJohn.Forte@Sun.COM 
14227836SJohn.Forte@Sun.COM 	/*
14237836SJohn.Forte@Sun.COM 	 * Get the property group being modified
14247836SJohn.Forte@Sun.COM 	 */
14257836SJohn.Forte@Sun.COM 	if (scf_service_get_pg(svc, pgRefName, pg) == -1) {
14267836SJohn.Forte@Sun.COM 		if (scf_error() == SCF_ERROR_NOT_FOUND &&
14277836SJohn.Forte@Sun.COM 		    addRemoveFlag == ADD) {
14287836SJohn.Forte@Sun.COM 			if (scf_service_add_pg(svc, pgRefName,
14297836SJohn.Forte@Sun.COM 			    SCF_GROUP_APPLICATION, 0, pg) == -1) {
143011909SPeter.Gill@Sun.COM 				syslog(LOG_ERR, "add pg %s failed - %s",
143111909SPeter.Gill@Sun.COM 				    pgRefName, scf_strerror(scf_error()));
14327836SJohn.Forte@Sun.COM 				ret = STMF_PS_ERROR;
14337836SJohn.Forte@Sun.COM 			}
14347836SJohn.Forte@Sun.COM 		} else if (scf_error() == SCF_ERROR_NOT_FOUND) {
143511909SPeter.Gill@Sun.COM 			syslog(LOG_ERR, "get pg %s failed - %s",
143611909SPeter.Gill@Sun.COM 			    pgRefName, scf_strerror(scf_error()));
14377836SJohn.Forte@Sun.COM 			ret = STMF_PS_ERROR_NOT_FOUND;
14387836SJohn.Forte@Sun.COM 		} else {
143911909SPeter.Gill@Sun.COM 			syslog(LOG_ERR, "get pg %s failed - %s",
144011909SPeter.Gill@Sun.COM 			    pgRefName, scf_strerror(scf_error()));
14417836SJohn.Forte@Sun.COM 			ret = STMF_PS_ERROR;
14427836SJohn.Forte@Sun.COM 		}
14437836SJohn.Forte@Sun.COM 		if (ret != STMF_PS_SUCCESS) {
14447836SJohn.Forte@Sun.COM 			goto out;
14457836SJohn.Forte@Sun.COM 		}
14467836SJohn.Forte@Sun.COM 	}
14477836SJohn.Forte@Sun.COM 
14487836SJohn.Forte@Sun.COM 	/*
14497836SJohn.Forte@Sun.COM 	 * propIter is the iterator handle
14507836SJohn.Forte@Sun.COM 	 */
14517836SJohn.Forte@Sun.COM 	if (scf_iter_pg_properties(propIter, pg) == -1) {
145211909SPeter.Gill@Sun.COM 		syslog(LOG_ERR, "iter properties for %s failed - %s",
145311909SPeter.Gill@Sun.COM 		    pgRefName, scf_strerror(scf_error()));
14547836SJohn.Forte@Sun.COM 		ret = STMF_PS_ERROR;
14557836SJohn.Forte@Sun.COM 		goto out;
14567836SJohn.Forte@Sun.COM 	}
14577836SJohn.Forte@Sun.COM 
14587836SJohn.Forte@Sun.COM 	/*
14597836SJohn.Forte@Sun.COM 	 * Iterate through the group names.
14607836SJohn.Forte@Sun.COM 	 * If we find it in the list, it's an error when addRemoveFlag == ADD.
14617836SJohn.Forte@Sun.COM 	 */
14627836SJohn.Forte@Sun.COM 	while (scf_iter_next_property(propIter, prop) == 1) {
14637836SJohn.Forte@Sun.COM 		if (scf_property_get_name(prop, buf1, sizeof (buf1)) == -1) {
146411909SPeter.Gill@Sun.COM 			syslog(LOG_ERR, "get name from %s iter failed - %s",
146511909SPeter.Gill@Sun.COM 			    pgRefName, scf_strerror(scf_error()));
14667836SJohn.Forte@Sun.COM 			ret = STMF_PS_ERROR;
14677836SJohn.Forte@Sun.COM 			break;
14687836SJohn.Forte@Sun.COM 		}
14697836SJohn.Forte@Sun.COM 		/*
14707836SJohn.Forte@Sun.COM 		 * Skip over member list properties
14717836SJohn.Forte@Sun.COM 		 */
14727836SJohn.Forte@Sun.COM 		if (strstr(buf1, STMF_MEMBER_LIST_SUFFIX)) {
14737836SJohn.Forte@Sun.COM 			continue;
14747836SJohn.Forte@Sun.COM 		}
14757836SJohn.Forte@Sun.COM 		if (scf_property_get_value(prop, value) == -1) {
147611909SPeter.Gill@Sun.COM 			syslog(LOG_ERR, "get property value %s/%s failed - %s",
147711909SPeter.Gill@Sun.COM 			    pgRefName, buf1, scf_strerror(scf_error()));
14787836SJohn.Forte@Sun.COM 			ret = STMF_PS_ERROR;
14797836SJohn.Forte@Sun.COM 			break;
14807836SJohn.Forte@Sun.COM 		}
14817836SJohn.Forte@Sun.COM 		if (scf_value_get_ustring(value, tmpbuf,
14827836SJohn.Forte@Sun.COM 		    sizeof (tmpbuf)) == -1) {
148311909SPeter.Gill@Sun.COM 			syslog(LOG_ERR, "get ustring %s/%s failed - %s",
148411909SPeter.Gill@Sun.COM 			    pgRefName, buf1, scf_strerror(scf_error()));
14857836SJohn.Forte@Sun.COM 			ret = STMF_PS_ERROR;
14867836SJohn.Forte@Sun.COM 			break;
14877836SJohn.Forte@Sun.COM 		}
14887836SJohn.Forte@Sun.COM 
14897836SJohn.Forte@Sun.COM 		if ((strlen(tmpbuf) == strlen(groupName)) &&
14907836SJohn.Forte@Sun.COM 		    bcmp(tmpbuf, groupName, strlen(tmpbuf)) == 0) {
14917836SJohn.Forte@Sun.COM 			if (addRemoveFlag == ADD) {
14927836SJohn.Forte@Sun.COM 				ret = STMF_PS_ERROR_EXISTS;
14937836SJohn.Forte@Sun.COM 			}
14947836SJohn.Forte@Sun.COM 			found = B_TRUE;
14957836SJohn.Forte@Sun.COM 			/*
14967836SJohn.Forte@Sun.COM 			 * buf1 contains the name for REMOVE
14977836SJohn.Forte@Sun.COM 			 */
14987836SJohn.Forte@Sun.COM 			break;
14997836SJohn.Forte@Sun.COM 		}
15007836SJohn.Forte@Sun.COM 	}
15017836SJohn.Forte@Sun.COM 
15027836SJohn.Forte@Sun.COM 	if (ret != STMF_PS_SUCCESS) {
15037836SJohn.Forte@Sun.COM 		goto out;
15047836SJohn.Forte@Sun.COM 	}
15057836SJohn.Forte@Sun.COM 
15067836SJohn.Forte@Sun.COM 	scf_value_reset(value);
15077836SJohn.Forte@Sun.COM 
15087836SJohn.Forte@Sun.COM 	if (!found && addRemoveFlag == REMOVE) {
15097836SJohn.Forte@Sun.COM 		ret = STMF_PS_ERROR_NOT_FOUND;
15107836SJohn.Forte@Sun.COM 		goto out;
15117836SJohn.Forte@Sun.COM 	}
15127836SJohn.Forte@Sun.COM 
15137836SJohn.Forte@Sun.COM 	/*
15147836SJohn.Forte@Sun.COM 	 * If we're adding, we need to create a new property name for the
15157836SJohn.Forte@Sun.COM 	 * new group
15167836SJohn.Forte@Sun.COM 	 */
15177836SJohn.Forte@Sun.COM 	if (addRemoveFlag == ADD) {
15187836SJohn.Forte@Sun.COM 		for (groupIdx = 0; groupIdx < GROUP_MAX; groupIdx++) {
15197836SJohn.Forte@Sun.COM 			if (snprintf(buf1, sizeof (buf1), "%s-%lld",
15207836SJohn.Forte@Sun.COM 			    STMF_GROUP_PREFIX, groupIdx) > sizeof (buf1)) {
15217836SJohn.Forte@Sun.COM 				syslog(LOG_ERR,
15227836SJohn.Forte@Sun.COM 				    "buffer overflow on property name %s",
15237836SJohn.Forte@Sun.COM 				    buf1);
15247836SJohn.Forte@Sun.COM 				ret = STMF_PS_ERROR;
15257836SJohn.Forte@Sun.COM 				break;
15267836SJohn.Forte@Sun.COM 			}
15277836SJohn.Forte@Sun.COM 			if (scf_pg_get_property(pg, buf1, prop) == -1) {
15287836SJohn.Forte@Sun.COM 				if (scf_error() != SCF_ERROR_NOT_FOUND) {
152911909SPeter.Gill@Sun.COM 					syslog(LOG_ERR, "get property %s/%s "
153011909SPeter.Gill@Sun.COM 					    "failed - %s", pgRefName, buf1,
15317836SJohn.Forte@Sun.COM 					    scf_strerror(scf_error()));
15327836SJohn.Forte@Sun.COM 					ret = STMF_PS_ERROR;
15337836SJohn.Forte@Sun.COM 				}
15347836SJohn.Forte@Sun.COM 				break;
15357836SJohn.Forte@Sun.COM 			}
15367836SJohn.Forte@Sun.COM 		}
15377836SJohn.Forte@Sun.COM 	}
15387836SJohn.Forte@Sun.COM 
15397836SJohn.Forte@Sun.COM 	/*
15407836SJohn.Forte@Sun.COM 	 * Now create the new member list property for the new group
15417836SJohn.Forte@Sun.COM 	 */
15427836SJohn.Forte@Sun.COM 	if (snprintf(buf2, sizeof (buf2), "%s-%s", buf1,
15437836SJohn.Forte@Sun.COM 	    STMF_MEMBER_LIST_SUFFIX) > sizeof (buf2)) {
15447836SJohn.Forte@Sun.COM 		syslog(LOG_ERR, "buffer overflow on property name %s",
15457836SJohn.Forte@Sun.COM 		    buf1);
15467836SJohn.Forte@Sun.COM 		ret = STMF_PS_ERROR;
15477836SJohn.Forte@Sun.COM 		goto out;
15487836SJohn.Forte@Sun.COM 	}
15497836SJohn.Forte@Sun.COM 
15507836SJohn.Forte@Sun.COM 	/*
15517836SJohn.Forte@Sun.COM 	 * buf1 now contains the name of the property if it was found in the
15527836SJohn.Forte@Sun.COM 	 * list in the case of delete or the next available property name
15537836SJohn.Forte@Sun.COM 	 * in the case of create
15547836SJohn.Forte@Sun.COM 	 *
15557836SJohn.Forte@Sun.COM 	 * buf2 now contains the member list property name
15567836SJohn.Forte@Sun.COM 	 */
15577836SJohn.Forte@Sun.COM 	if (scf_transaction_start(tran, pg) == -1) {
155811909SPeter.Gill@Sun.COM 		syslog(LOG_ERR, "start transaction for %s failed - %s",
155911909SPeter.Gill@Sun.COM 		    pgRefName, scf_strerror(scf_error()));
15607836SJohn.Forte@Sun.COM 		ret = STMF_PS_ERROR;
15617836SJohn.Forte@Sun.COM 		goto out;
15627836SJohn.Forte@Sun.COM 	}
15637836SJohn.Forte@Sun.COM 
15647836SJohn.Forte@Sun.COM 	if (addRemoveFlag == ADD) {
15657836SJohn.Forte@Sun.COM 		/*
15667836SJohn.Forte@Sun.COM 		 * Create the property 'group name'
15677836SJohn.Forte@Sun.COM 		 * This is the container for the group name
15687836SJohn.Forte@Sun.COM 		 */
15697836SJohn.Forte@Sun.COM 		if (scf_transaction_property_new(tran, entry1, buf1,
15707836SJohn.Forte@Sun.COM 		    SCF_TYPE_USTRING) == -1) {
157111909SPeter.Gill@Sun.COM 			syslog(LOG_ERR, "transaction property new %s/%s "
157211909SPeter.Gill@Sun.COM 			    "failed - %s", pgRefName, buf1,
15737836SJohn.Forte@Sun.COM 			    scf_strerror(scf_error()));
15747836SJohn.Forte@Sun.COM 			ret = STMF_PS_ERROR;
15757836SJohn.Forte@Sun.COM 			goto out;
15767836SJohn.Forte@Sun.COM 		}
15777836SJohn.Forte@Sun.COM 		if (scf_value_set_ustring(value, groupName) == -1) {
157811909SPeter.Gill@Sun.COM 			syslog(LOG_ERR, "set ustring %s/%s failed - %s",
157911909SPeter.Gill@Sun.COM 			    pgRefName, buf1, scf_strerror(scf_error()));
15807836SJohn.Forte@Sun.COM 			ret = STMF_PS_ERROR;
15817836SJohn.Forte@Sun.COM 			goto out;
15827836SJohn.Forte@Sun.COM 		}
15837836SJohn.Forte@Sun.COM 		if (scf_entry_add_value(entry1, value) == -1) {
158411909SPeter.Gill@Sun.COM 			syslog(LOG_ERR, "add value %s/%s failed - %s",
158511909SPeter.Gill@Sun.COM 			    pgRefName, buf1, scf_strerror(scf_error()));
15867836SJohn.Forte@Sun.COM 			ret = STMF_PS_ERROR;
15877836SJohn.Forte@Sun.COM 			goto out;
15887836SJohn.Forte@Sun.COM 		}
15897836SJohn.Forte@Sun.COM 		/*
15907836SJohn.Forte@Sun.COM 		 * Create the property 'group list'
15917836SJohn.Forte@Sun.COM 		 * This is the container for the group members
15927836SJohn.Forte@Sun.COM 		 */
15937836SJohn.Forte@Sun.COM 		if (scf_transaction_property_new(tran, entry2, buf2,
15947836SJohn.Forte@Sun.COM 		    SCF_TYPE_USTRING) == -1) {
159511909SPeter.Gill@Sun.COM 			syslog(LOG_ERR, "transaction property new %s/%s "
159611909SPeter.Gill@Sun.COM 			    "failed - %s", pgRefName, buf2,
15977836SJohn.Forte@Sun.COM 			    scf_strerror(scf_error()));
15987836SJohn.Forte@Sun.COM 			ret = STMF_PS_ERROR;
15997836SJohn.Forte@Sun.COM 			goto out;
16007836SJohn.Forte@Sun.COM 		}
16017836SJohn.Forte@Sun.COM 	} else {
16027836SJohn.Forte@Sun.COM 		/*
16037836SJohn.Forte@Sun.COM 		 * Delete the property 'group name'
16047836SJohn.Forte@Sun.COM 		 */
16057836SJohn.Forte@Sun.COM 		if (scf_transaction_property_delete(tran, entry1, buf1)
16067836SJohn.Forte@Sun.COM 		    == -1) {
16077836SJohn.Forte@Sun.COM 			syslog(LOG_ERR,
160811909SPeter.Gill@Sun.COM 			    "transaction property delete %s/%s failed - %s",
160911909SPeter.Gill@Sun.COM 			    pgRefName, buf1, scf_strerror(scf_error()));
16107836SJohn.Forte@Sun.COM 			ret = STMF_PS_ERROR;
16117836SJohn.Forte@Sun.COM 			goto out;
16127836SJohn.Forte@Sun.COM 		}
16137836SJohn.Forte@Sun.COM 		/*
16147836SJohn.Forte@Sun.COM 		 * Delete the property 'group list'
16157836SJohn.Forte@Sun.COM 		 */
16167836SJohn.Forte@Sun.COM 		if (scf_transaction_property_delete(tran, entry2, buf2)
16177836SJohn.Forte@Sun.COM 		    == -1) {
161811909SPeter.Gill@Sun.COM 			syslog(LOG_ERR, "transaction property delete %s/%s "
161911909SPeter.Gill@Sun.COM 			    "failed - %s", pgRefName, buf2,
16207836SJohn.Forte@Sun.COM 			    scf_strerror(scf_error()));
16217836SJohn.Forte@Sun.COM 			ret = STMF_PS_ERROR;
16227836SJohn.Forte@Sun.COM 			goto out;
16237836SJohn.Forte@Sun.COM 		}
16247836SJohn.Forte@Sun.COM 	}
16257836SJohn.Forte@Sun.COM 
16267836SJohn.Forte@Sun.COM 	if (ret != STMF_PS_SUCCESS) {
16277836SJohn.Forte@Sun.COM 		goto out;
16287836SJohn.Forte@Sun.COM 	}
16297836SJohn.Forte@Sun.COM 
16307836SJohn.Forte@Sun.COM 	if ((commitRet = scf_transaction_commit(tran)) != 1) {
163111909SPeter.Gill@Sun.COM 		syslog(LOG_ERR, "transaction commit for %s failed - %s",
163211909SPeter.Gill@Sun.COM 		    pgRefName, scf_strerror(scf_error()));
16337836SJohn.Forte@Sun.COM 		if (commitRet == 0) {
16347836SJohn.Forte@Sun.COM 			ret = STMF_PS_ERROR_BUSY;
16357836SJohn.Forte@Sun.COM 		} else {
16367836SJohn.Forte@Sun.COM 			ret = STMF_PS_ERROR;
16377836SJohn.Forte@Sun.COM 		}
16387836SJohn.Forte@Sun.COM 	}
16397836SJohn.Forte@Sun.COM 
16407836SJohn.Forte@Sun.COM out:
16417836SJohn.Forte@Sun.COM 	/*
16427836SJohn.Forte@Sun.COM 	 * Free resources
16437836SJohn.Forte@Sun.COM 	 */
16447836SJohn.Forte@Sun.COM 	if (handle != NULL) {
16457836SJohn.Forte@Sun.COM 		scf_handle_destroy(handle);
16467836SJohn.Forte@Sun.COM 	}
16477836SJohn.Forte@Sun.COM 	if (svc != NULL) {
16487836SJohn.Forte@Sun.COM 		scf_service_destroy(svc);
16497836SJohn.Forte@Sun.COM 	}
16507836SJohn.Forte@Sun.COM 	if (pg != NULL) {
16517836SJohn.Forte@Sun.COM 		scf_pg_destroy(pg);
16527836SJohn.Forte@Sun.COM 	}
16537836SJohn.Forte@Sun.COM 	if (tran != NULL) {
16547836SJohn.Forte@Sun.COM 		scf_transaction_destroy(tran);
16557836SJohn.Forte@Sun.COM 	}
16567836SJohn.Forte@Sun.COM 	if (entry1 != NULL) {
16577836SJohn.Forte@Sun.COM 		scf_entry_destroy(entry1);
16587836SJohn.Forte@Sun.COM 	}
16597836SJohn.Forte@Sun.COM 	if (entry2 != NULL) {
16607836SJohn.Forte@Sun.COM 		scf_entry_destroy(entry2);
16617836SJohn.Forte@Sun.COM 	}
16627836SJohn.Forte@Sun.COM 	if (prop != NULL) {
16637836SJohn.Forte@Sun.COM 		scf_property_destroy(prop);
16647836SJohn.Forte@Sun.COM 	}
16657836SJohn.Forte@Sun.COM 	if (propIter != NULL) {
16667836SJohn.Forte@Sun.COM 		scf_iter_destroy(propIter);
16677836SJohn.Forte@Sun.COM 	}
16687836SJohn.Forte@Sun.COM 	if (value != NULL) {
16697836SJohn.Forte@Sun.COM 		scf_value_destroy(value);
16707836SJohn.Forte@Sun.COM 	}
16717836SJohn.Forte@Sun.COM 
16727836SJohn.Forte@Sun.COM 	return (ret);
16737836SJohn.Forte@Sun.COM }
16747836SJohn.Forte@Sun.COM 
16757836SJohn.Forte@Sun.COM /*
16767836SJohn.Forte@Sun.COM  * iPsGetGroupList
16777836SJohn.Forte@Sun.COM  *
16787836SJohn.Forte@Sun.COM  * pgName - Property group name
16797836SJohn.Forte@Sun.COM  * groupList - pointer to pointer to stmfGroupList structure. On success,
16807836SJohn.Forte@Sun.COM  * contains the list of groups
16817836SJohn.Forte@Sun.COM  *
16827836SJohn.Forte@Sun.COM  * returns:
16837836SJohn.Forte@Sun.COM  *  STMF_PS_SUCCESS on success
16847836SJohn.Forte@Sun.COM  *  STMF_PS_ERROR_* on failure
16857836SJohn.Forte@Sun.COM  */
16867836SJohn.Forte@Sun.COM static int
iPsGetGroupList(char * pgName,stmfGroupList ** groupList)16877836SJohn.Forte@Sun.COM iPsGetGroupList(char *pgName, stmfGroupList **groupList)
16887836SJohn.Forte@Sun.COM {
16897836SJohn.Forte@Sun.COM 	scf_handle_t	*handle = NULL;
16907836SJohn.Forte@Sun.COM 	scf_service_t	*svc = NULL;
16917836SJohn.Forte@Sun.COM 	scf_propertygroup_t	*pg = NULL;
16927836SJohn.Forte@Sun.COM 	scf_property_t	*prop = NULL;
16937836SJohn.Forte@Sun.COM 	scf_iter_t	*propIter = NULL;
16947836SJohn.Forte@Sun.COM 	scf_value_t	*value = NULL;
16957836SJohn.Forte@Sun.COM 	char buf[MAXNAMELEN];
16967836SJohn.Forte@Sun.COM 	int memberCnt = 0;
16977836SJohn.Forte@Sun.COM 	int i = 0;
16987836SJohn.Forte@Sun.COM 	int ret = STMF_PS_SUCCESS;
16997836SJohn.Forte@Sun.COM 
17007836SJohn.Forte@Sun.COM 	assert(groupList != NULL);
17017836SJohn.Forte@Sun.COM 
17027836SJohn.Forte@Sun.COM 	ret = iPsInit(&handle, &svc);
17037836SJohn.Forte@Sun.COM 	if (ret != STMF_PS_SUCCESS) {
17047836SJohn.Forte@Sun.COM 		goto out;
17057836SJohn.Forte@Sun.COM 	}
17067836SJohn.Forte@Sun.COM 
17077836SJohn.Forte@Sun.COM 	/*
17087836SJohn.Forte@Sun.COM 	 * Allocate scf resources
17097836SJohn.Forte@Sun.COM 	 */
17107836SJohn.Forte@Sun.COM 	if (((pg = scf_pg_create(handle)) == NULL) ||
17117836SJohn.Forte@Sun.COM 	    ((prop = scf_property_create(handle)) == NULL) ||
17127836SJohn.Forte@Sun.COM 	    ((propIter = scf_iter_create(handle)) == NULL) ||
17137836SJohn.Forte@Sun.COM 	    ((value = scf_value_create(handle)) == NULL)) {
17147836SJohn.Forte@Sun.COM 		syslog(LOG_ERR, "scf alloc resource failed - %s",
17157836SJohn.Forte@Sun.COM 		    scf_strerror(scf_error()));
17167836SJohn.Forte@Sun.COM 		ret = STMF_PS_ERROR;
17177836SJohn.Forte@Sun.COM 		goto out;
17187836SJohn.Forte@Sun.COM 	}
17197836SJohn.Forte@Sun.COM 
17207836SJohn.Forte@Sun.COM 	if (scf_service_get_pg(svc, pgName, pg) == -1) {
17217836SJohn.Forte@Sun.COM 		if (scf_error() == SCF_ERROR_NOT_FOUND) {
172211909SPeter.Gill@Sun.COM 			syslog(LOG_ERR, "get pg %s failed - %s",
172311909SPeter.Gill@Sun.COM 			    pgName, scf_strerror(scf_error()));
17247836SJohn.Forte@Sun.COM 			ret = STMF_PS_ERROR_NOT_FOUND;
17257836SJohn.Forte@Sun.COM 		} else {
172611909SPeter.Gill@Sun.COM 			syslog(LOG_ERR, "get pg %s failed - %s",
172711909SPeter.Gill@Sun.COM 			    pgName, scf_strerror(scf_error()));
17287836SJohn.Forte@Sun.COM 			ret = STMF_PS_ERROR;
17297836SJohn.Forte@Sun.COM 		}
17307836SJohn.Forte@Sun.COM 		goto out;
17317836SJohn.Forte@Sun.COM 	}
17327836SJohn.Forte@Sun.COM 
17337836SJohn.Forte@Sun.COM 	/*
17347836SJohn.Forte@Sun.COM 	 * propIter is the iterator handle
17357836SJohn.Forte@Sun.COM 	 */
17367836SJohn.Forte@Sun.COM 	if (scf_iter_pg_properties(propIter, pg) == -1) {
173711909SPeter.Gill@Sun.COM 		syslog(LOG_ERR, "iter properties for %s failed - %s",
173811909SPeter.Gill@Sun.COM 		    pgName, scf_strerror(scf_error()));
17397836SJohn.Forte@Sun.COM 		ret = STMF_PS_ERROR;
17407836SJohn.Forte@Sun.COM 		goto out;
17417836SJohn.Forte@Sun.COM 	}
17427836SJohn.Forte@Sun.COM 
17437836SJohn.Forte@Sun.COM 	while (scf_iter_next_property(propIter, prop) == 1) {
17447836SJohn.Forte@Sun.COM 		if (scf_property_get_name(prop, buf, sizeof (buf)) == -1) {
174511909SPeter.Gill@Sun.COM 			syslog(LOG_ERR, "get name from %s iter failed - %s",
174611909SPeter.Gill@Sun.COM 			    pgName, scf_strerror(scf_error()));
17477836SJohn.Forte@Sun.COM 			ret = STMF_PS_ERROR;
17487836SJohn.Forte@Sun.COM 			break;
17497836SJohn.Forte@Sun.COM 		}
17507836SJohn.Forte@Sun.COM 		/*
17517836SJohn.Forte@Sun.COM 		 * Skip over member list properties
17527836SJohn.Forte@Sun.COM 		 */
17537836SJohn.Forte@Sun.COM 		if (strstr(buf, STMF_MEMBER_LIST_SUFFIX)) {
17547836SJohn.Forte@Sun.COM 			continue;
17557836SJohn.Forte@Sun.COM 		}
17567836SJohn.Forte@Sun.COM 		memberCnt++;
17577836SJohn.Forte@Sun.COM 	}
17587836SJohn.Forte@Sun.COM 
17597836SJohn.Forte@Sun.COM 	/*
17607836SJohn.Forte@Sun.COM 	 * propIter is the iterator handle
17617836SJohn.Forte@Sun.COM 	 */
17627836SJohn.Forte@Sun.COM 	if (scf_iter_pg_properties(propIter, pg) == -1) {
176311909SPeter.Gill@Sun.COM 		syslog(LOG_ERR, "iter properties for %s failed - %s",
176411909SPeter.Gill@Sun.COM 		    pgName, scf_strerror(scf_error()));
17657836SJohn.Forte@Sun.COM 		ret = STMF_PS_ERROR;
17667836SJohn.Forte@Sun.COM 		goto out;
17677836SJohn.Forte@Sun.COM 	}
17687836SJohn.Forte@Sun.COM 
17697836SJohn.Forte@Sun.COM 	*groupList = (stmfGroupList *)calloc(1, sizeof (stmfGroupList) +
17707836SJohn.Forte@Sun.COM 	    memberCnt * sizeof (stmfGroupName));
17717836SJohn.Forte@Sun.COM 
17727836SJohn.Forte@Sun.COM 	if (*groupList == NULL) {
17737836SJohn.Forte@Sun.COM 		ret = STMF_PS_ERROR_NOMEM;
17747836SJohn.Forte@Sun.COM 		goto out;
17757836SJohn.Forte@Sun.COM 	}
17767836SJohn.Forte@Sun.COM 
17777836SJohn.Forte@Sun.COM 	/*
17787836SJohn.Forte@Sun.COM 	 * In order to get a list of groups, simply get all of the
17797836SJohn.Forte@Sun.COM 	 * properties that are not member list properties, i.e. the group
17807836SJohn.Forte@Sun.COM 	 * name properties.
17817836SJohn.Forte@Sun.COM 	 * It's possible for this list to grow beyond what was originally
17827836SJohn.Forte@Sun.COM 	 * read so just ensure we're not writing beyond our allocated buffer
17837836SJohn.Forte@Sun.COM 	 * by ensuring i < memberCnt
17847836SJohn.Forte@Sun.COM 	 */
17857836SJohn.Forte@Sun.COM 	while ((scf_iter_next_property(propIter, prop) == 1) &&
17867836SJohn.Forte@Sun.COM 	    (i < memberCnt)) {
17877836SJohn.Forte@Sun.COM 		if (scf_property_get_name(prop, buf, sizeof (buf)) == -1) {
178811909SPeter.Gill@Sun.COM 			syslog(LOG_ERR, "get name from %s iter failed - %s",
178911909SPeter.Gill@Sun.COM 			    pgName, scf_strerror(scf_error()));
17907836SJohn.Forte@Sun.COM 			ret = STMF_PS_ERROR;
17917836SJohn.Forte@Sun.COM 			break;
17927836SJohn.Forte@Sun.COM 		}
17937836SJohn.Forte@Sun.COM 		/*
17947836SJohn.Forte@Sun.COM 		 * Skip over member list properties
17957836SJohn.Forte@Sun.COM 		 */
17967836SJohn.Forte@Sun.COM 		if (strstr(buf, STMF_MEMBER_LIST_SUFFIX)) {
17977836SJohn.Forte@Sun.COM 			continue;
17987836SJohn.Forte@Sun.COM 		}
17997836SJohn.Forte@Sun.COM 		if (scf_property_get_value(prop, value) == -1) {
180011909SPeter.Gill@Sun.COM 			syslog(LOG_ERR, "get property value %s/%s failed - %s",
180111909SPeter.Gill@Sun.COM 			    pgName, buf, scf_strerror(scf_error()));
18027836SJohn.Forte@Sun.COM 			ret = STMF_PS_ERROR;
18037836SJohn.Forte@Sun.COM 			break;
18047836SJohn.Forte@Sun.COM 		}
18057836SJohn.Forte@Sun.COM 		if (scf_value_get_ustring(value, buf, sizeof (buf)) == -1) {
180611909SPeter.Gill@Sun.COM 			syslog(LOG_ERR, "get ustring %s/%s failed - %s",
180711909SPeter.Gill@Sun.COM 			    pgName, buf, scf_strerror(scf_error()));
18087836SJohn.Forte@Sun.COM 			ret = STMF_PS_ERROR;
18097836SJohn.Forte@Sun.COM 			break;
18107836SJohn.Forte@Sun.COM 		}
18117836SJohn.Forte@Sun.COM 		bcopy(buf, (*groupList)->name[i++], strlen(buf));
18127836SJohn.Forte@Sun.COM 		(*groupList)->cnt++;
18137836SJohn.Forte@Sun.COM 	}
18147836SJohn.Forte@Sun.COM 
18157836SJohn.Forte@Sun.COM 	if (ret != STMF_PS_SUCCESS) {
18167836SJohn.Forte@Sun.COM 		free(*groupList);
18177836SJohn.Forte@Sun.COM 		goto out;
18187836SJohn.Forte@Sun.COM 	}
18197836SJohn.Forte@Sun.COM 
18207836SJohn.Forte@Sun.COM out:
18217836SJohn.Forte@Sun.COM 	/*
18227836SJohn.Forte@Sun.COM 	 * Free resources
18237836SJohn.Forte@Sun.COM 	 */
18247836SJohn.Forte@Sun.COM 	if (handle != NULL) {
18257836SJohn.Forte@Sun.COM 		scf_handle_destroy(handle);
18267836SJohn.Forte@Sun.COM 	}
18277836SJohn.Forte@Sun.COM 	if (svc != NULL) {
18287836SJohn.Forte@Sun.COM 		scf_service_destroy(svc);
18297836SJohn.Forte@Sun.COM 	}
18307836SJohn.Forte@Sun.COM 	if (pg != NULL) {
18317836SJohn.Forte@Sun.COM 		scf_pg_destroy(pg);
18327836SJohn.Forte@Sun.COM 	}
18337836SJohn.Forte@Sun.COM 	if (propIter != NULL) {
18347836SJohn.Forte@Sun.COM 		scf_iter_destroy(propIter);
18357836SJohn.Forte@Sun.COM 	}
18367836SJohn.Forte@Sun.COM 	if (prop != NULL) {
18377836SJohn.Forte@Sun.COM 		scf_property_destroy(prop);
18387836SJohn.Forte@Sun.COM 	}
18397836SJohn.Forte@Sun.COM 	if (value != NULL) {
18407836SJohn.Forte@Sun.COM 		scf_value_destroy(value);
18417836SJohn.Forte@Sun.COM 	}
18427836SJohn.Forte@Sun.COM 
18437836SJohn.Forte@Sun.COM 	return (ret);
18447836SJohn.Forte@Sun.COM }
18457836SJohn.Forte@Sun.COM 
18467836SJohn.Forte@Sun.COM /*
18477836SJohn.Forte@Sun.COM  * iPsGetGroupMemberList
18487836SJohn.Forte@Sun.COM  *
18497836SJohn.Forte@Sun.COM  * pgName - Property group name
18507836SJohn.Forte@Sun.COM  * groupName - group name (host group or target group)
18517836SJohn.Forte@Sun.COM  * groupMemberList - pointer to pointer to stmfGroupProperties structure. On
18527836SJohn.Forte@Sun.COM  * success, contains the list of group members
18537836SJohn.Forte@Sun.COM  *
18547836SJohn.Forte@Sun.COM  * returns:
18557836SJohn.Forte@Sun.COM  *  STMF_PS_SUCCESS on success
18567836SJohn.Forte@Sun.COM  *  STMF_PS_ERROR_* on failure
18577836SJohn.Forte@Sun.COM  */
18587836SJohn.Forte@Sun.COM static int
iPsGetGroupMemberList(char * pgName,char * groupName,stmfGroupProperties ** groupMemberList)18597836SJohn.Forte@Sun.COM iPsGetGroupMemberList(char *pgName, char *groupName,
18607836SJohn.Forte@Sun.COM     stmfGroupProperties **groupMemberList)
18617836SJohn.Forte@Sun.COM {
18627836SJohn.Forte@Sun.COM 	scf_handle_t	*handle = NULL;
18637836SJohn.Forte@Sun.COM 	scf_service_t	*svc = NULL;
18647836SJohn.Forte@Sun.COM 	scf_propertygroup_t	*pg = NULL;
18657836SJohn.Forte@Sun.COM 	scf_property_t	*prop = NULL;
18667836SJohn.Forte@Sun.COM 	scf_value_t	*valueLookup = NULL;
18677836SJohn.Forte@Sun.COM 	scf_iter_t	*valueIter = NULL;
18687836SJohn.Forte@Sun.COM 	int i = 0;
18697836SJohn.Forte@Sun.COM 	int memberCnt;
18707836SJohn.Forte@Sun.COM 	int len;
18717836SJohn.Forte@Sun.COM 	int ret = STMF_PS_SUCCESS;
18727836SJohn.Forte@Sun.COM 	char buf[MAXNAMELEN];
18737836SJohn.Forte@Sun.COM 
18747836SJohn.Forte@Sun.COM 	assert(pgName != NULL && groupName != NULL);
18757836SJohn.Forte@Sun.COM 
18767836SJohn.Forte@Sun.COM 	/*
18777836SJohn.Forte@Sun.COM 	 * init the service handle
18787836SJohn.Forte@Sun.COM 	 */
18797836SJohn.Forte@Sun.COM 	ret = iPsInit(&handle, &svc);
18807836SJohn.Forte@Sun.COM 	if (ret != STMF_PS_SUCCESS) {
18817836SJohn.Forte@Sun.COM 		goto out;
18827836SJohn.Forte@Sun.COM 	}
18837836SJohn.Forte@Sun.COM 
18847836SJohn.Forte@Sun.COM 	/*
18857836SJohn.Forte@Sun.COM 	 * Allocate scf resources
18867836SJohn.Forte@Sun.COM 	 */
18877836SJohn.Forte@Sun.COM 	if (((pg = scf_pg_create(handle)) == NULL) ||
18887836SJohn.Forte@Sun.COM 	    ((prop = scf_property_create(handle)) == NULL) ||
18897836SJohn.Forte@Sun.COM 	    ((valueIter = scf_iter_create(handle)) == NULL) ||
18907836SJohn.Forte@Sun.COM 	    ((valueLookup = scf_value_create(handle)) == NULL)) {
18917836SJohn.Forte@Sun.COM 		syslog(LOG_ERR, "scf alloc resource failed - %s",
18927836SJohn.Forte@Sun.COM 		    scf_strerror(scf_error()));
18937836SJohn.Forte@Sun.COM 		ret = STMF_PS_ERROR;
18947836SJohn.Forte@Sun.COM 		goto out;
18957836SJohn.Forte@Sun.COM 	}
18967836SJohn.Forte@Sun.COM 
18977836SJohn.Forte@Sun.COM 	/*
18987836SJohn.Forte@Sun.COM 	 * get the service property group handle
18997836SJohn.Forte@Sun.COM 	 */
19007836SJohn.Forte@Sun.COM 	if (scf_service_get_pg(svc, pgName, pg) == -1) {
19017836SJohn.Forte@Sun.COM 		if (scf_error() == SCF_ERROR_NOT_FOUND) {
19027836SJohn.Forte@Sun.COM 			ret = STMF_PS_ERROR_NOT_FOUND;
19037836SJohn.Forte@Sun.COM 		} else {
19047836SJohn.Forte@Sun.COM 			ret = STMF_PS_ERROR;
19057836SJohn.Forte@Sun.COM 		}
190611909SPeter.Gill@Sun.COM 		syslog(LOG_ERR, "get pg %s failed - %s",
190711909SPeter.Gill@Sun.COM 		    pgName, scf_strerror(scf_error()));
19087836SJohn.Forte@Sun.COM 		goto out;
19097836SJohn.Forte@Sun.COM 	}
19107836SJohn.Forte@Sun.COM 
19117836SJohn.Forte@Sun.COM 	/*
19127836SJohn.Forte@Sun.COM 	 * Get the property handle
19137836SJohn.Forte@Sun.COM 	 * based on the target or host group name
19147836SJohn.Forte@Sun.COM 	 */
19157836SJohn.Forte@Sun.COM 	if (scf_pg_get_property(pg, groupName, prop) == -1) {
191611909SPeter.Gill@Sun.COM 		syslog(LOG_ERR, "get property %s/%s failed - %s",
191711909SPeter.Gill@Sun.COM 		    pgName, groupName, scf_strerror(scf_error()));
19187836SJohn.Forte@Sun.COM 		ret = STMF_PS_ERROR;
19197836SJohn.Forte@Sun.COM 		goto out;
19207836SJohn.Forte@Sun.COM 	}
19217836SJohn.Forte@Sun.COM 
19227836SJohn.Forte@Sun.COM 	/*
19237836SJohn.Forte@Sun.COM 	 * valueIter is the iterator handle
19247836SJohn.Forte@Sun.COM 	 */
19257836SJohn.Forte@Sun.COM 	if (scf_iter_property_values(valueIter, prop) == -1) {
192611909SPeter.Gill@Sun.COM 		syslog(LOG_ERR, "iter value %s/%s failed - %s",
192711909SPeter.Gill@Sun.COM 		    pgName, groupName, scf_strerror(scf_error()));
19287836SJohn.Forte@Sun.COM 		ret = STMF_PS_ERROR;
19297836SJohn.Forte@Sun.COM 		goto out;
19307836SJohn.Forte@Sun.COM 	}
19317836SJohn.Forte@Sun.COM 
19327836SJohn.Forte@Sun.COM 	while (scf_iter_next_value(valueIter, valueLookup) == 1) {
19337836SJohn.Forte@Sun.COM 		if (scf_value_get_ustring(valueLookup, buf, MAXNAMELEN) == -1) {
193411909SPeter.Gill@Sun.COM 			syslog(LOG_ERR, "iter value %s/%s failed - %s",
193511909SPeter.Gill@Sun.COM 			    pgName, groupName, scf_strerror(scf_error()));
19367836SJohn.Forte@Sun.COM 			ret = STMF_PS_ERROR;
19377836SJohn.Forte@Sun.COM 			break;
19387836SJohn.Forte@Sun.COM 		}
19397836SJohn.Forte@Sun.COM 		i++;
19407836SJohn.Forte@Sun.COM 	}
19417836SJohn.Forte@Sun.COM 
19427836SJohn.Forte@Sun.COM 	/*
19437836SJohn.Forte@Sun.COM 	 * valueIter is the iterator handle
19447836SJohn.Forte@Sun.COM 	 */
19457836SJohn.Forte@Sun.COM 	if (scf_iter_property_values(valueIter, prop) == -1) {
194611909SPeter.Gill@Sun.COM 		syslog(LOG_ERR, "iter value %s/%s failed - %s",
194711909SPeter.Gill@Sun.COM 		    pgName, groupName, scf_strerror(scf_error()));
19487836SJohn.Forte@Sun.COM 		ret = STMF_PS_ERROR;
19497836SJohn.Forte@Sun.COM 		goto out;
19507836SJohn.Forte@Sun.COM 	}
19517836SJohn.Forte@Sun.COM 
19527836SJohn.Forte@Sun.COM 	memberCnt = i;
19537836SJohn.Forte@Sun.COM 
19547836SJohn.Forte@Sun.COM 	*groupMemberList = (stmfGroupProperties *)calloc(1,
19557836SJohn.Forte@Sun.COM 	    sizeof (stmfGroupProperties) + memberCnt * sizeof (stmfDevid));
19567836SJohn.Forte@Sun.COM 	if (*groupMemberList == NULL) {
19577836SJohn.Forte@Sun.COM 		ret = STMF_PS_ERROR_NOMEM;
19587836SJohn.Forte@Sun.COM 		goto out;
19597836SJohn.Forte@Sun.COM 	}
19607836SJohn.Forte@Sun.COM 
19617836SJohn.Forte@Sun.COM 	i = 0;
19627836SJohn.Forte@Sun.COM 	while ((scf_iter_next_value(valueIter, valueLookup) == 1) &&
19637836SJohn.Forte@Sun.COM 	    (i < memberCnt)) {
19647836SJohn.Forte@Sun.COM 		if ((len = scf_value_get_ustring(valueLookup, buf, MAXNAMELEN))
19657836SJohn.Forte@Sun.COM 		    == -1) {
196611909SPeter.Gill@Sun.COM 			syslog(LOG_ERR, "iter value %s/%s failed - %s",
196711909SPeter.Gill@Sun.COM 			    pgName, groupName, scf_strerror(scf_error()));
19687836SJohn.Forte@Sun.COM 			ret = STMF_PS_ERROR;
19697836SJohn.Forte@Sun.COM 			break;
19707836SJohn.Forte@Sun.COM 		}
19717836SJohn.Forte@Sun.COM 		if (len < sizeof (stmfDevid) - 1) {
19727836SJohn.Forte@Sun.COM 			(*groupMemberList)->name[i].identLength = len;
19737836SJohn.Forte@Sun.COM 			bcopy(buf,
19747836SJohn.Forte@Sun.COM 			    (*groupMemberList)->name[i++].ident, len);
19757836SJohn.Forte@Sun.COM 			(*groupMemberList)->cnt++;
19767836SJohn.Forte@Sun.COM 		} else {
19777836SJohn.Forte@Sun.COM 			ret = STMF_PS_ERROR;
19787836SJohn.Forte@Sun.COM 			break;
19797836SJohn.Forte@Sun.COM 		}
19807836SJohn.Forte@Sun.COM 	}
19817836SJohn.Forte@Sun.COM 
19827836SJohn.Forte@Sun.COM 	if (ret != STMF_PS_SUCCESS) {
19837836SJohn.Forte@Sun.COM 		free(*groupMemberList);
19847836SJohn.Forte@Sun.COM 		goto out;
19857836SJohn.Forte@Sun.COM 	}
19867836SJohn.Forte@Sun.COM 
19877836SJohn.Forte@Sun.COM out:
19887836SJohn.Forte@Sun.COM 	/*
19897836SJohn.Forte@Sun.COM 	 * Free resources
19907836SJohn.Forte@Sun.COM 	 */
19917836SJohn.Forte@Sun.COM 	if (handle != NULL) {
19927836SJohn.Forte@Sun.COM 		scf_handle_destroy(handle);
19937836SJohn.Forte@Sun.COM 	}
19947836SJohn.Forte@Sun.COM 	if (svc != NULL) {
19957836SJohn.Forte@Sun.COM 		scf_service_destroy(svc);
19967836SJohn.Forte@Sun.COM 	}
19977836SJohn.Forte@Sun.COM 	if (pg != NULL) {
19987836SJohn.Forte@Sun.COM 		scf_pg_destroy(pg);
19997836SJohn.Forte@Sun.COM 	}
20007836SJohn.Forte@Sun.COM 	if (prop != NULL) {
20017836SJohn.Forte@Sun.COM 		scf_property_destroy(prop);
20027836SJohn.Forte@Sun.COM 	}
20037836SJohn.Forte@Sun.COM 	if (valueLookup != NULL) {
20047836SJohn.Forte@Sun.COM 		scf_value_destroy(valueLookup);
20057836SJohn.Forte@Sun.COM 	}
20067836SJohn.Forte@Sun.COM 	if (valueIter != NULL) {
20077836SJohn.Forte@Sun.COM 		scf_iter_destroy(valueIter);
20087836SJohn.Forte@Sun.COM 	}
20097836SJohn.Forte@Sun.COM 
20107836SJohn.Forte@Sun.COM 	return (ret);
20117836SJohn.Forte@Sun.COM }
20127836SJohn.Forte@Sun.COM 
20139585STim.Szeto@Sun.COM int
psGetServicePersist(uint8_t * persistType)20149585STim.Szeto@Sun.COM psGetServicePersist(uint8_t *persistType)
20159585STim.Szeto@Sun.COM {
20169585STim.Szeto@Sun.COM 	scf_handle_t	*handle = NULL;
20179585STim.Szeto@Sun.COM 	scf_service_t	*svc = NULL;
20189585STim.Szeto@Sun.COM 	int ret;
20199585STim.Szeto@Sun.COM 
20209585STim.Szeto@Sun.COM 
20219585STim.Szeto@Sun.COM 	ret = iPsInit(&handle, &svc);
20229585STim.Szeto@Sun.COM 	if (ret != STMF_PS_SUCCESS) {
20239585STim.Szeto@Sun.COM 		return (STMF_PS_ERROR);
20249585STim.Szeto@Sun.COM 	}
20259585STim.Szeto@Sun.COM 
20269585STim.Szeto@Sun.COM 	ret = iPsGetSetPersistType(persistType, handle, svc, GET);
20279585STim.Szeto@Sun.COM 
20289585STim.Szeto@Sun.COM 	/*
20299585STim.Szeto@Sun.COM 	 * Free resources
20309585STim.Szeto@Sun.COM 	 */
20319585STim.Szeto@Sun.COM 	if (handle != NULL) {
20329585STim.Szeto@Sun.COM 		scf_handle_destroy(handle);
20339585STim.Szeto@Sun.COM 	}
20349585STim.Szeto@Sun.COM 	if (svc != NULL) {
20359585STim.Szeto@Sun.COM 		scf_service_destroy(svc);
20369585STim.Szeto@Sun.COM 	}
20379585STim.Szeto@Sun.COM 	return (ret);
20389585STim.Szeto@Sun.COM }
20399585STim.Szeto@Sun.COM 
20409585STim.Szeto@Sun.COM int
psSetServicePersist(uint8_t persistType)20419585STim.Szeto@Sun.COM psSetServicePersist(uint8_t persistType)
20429585STim.Szeto@Sun.COM {
20439585STim.Szeto@Sun.COM 	scf_handle_t	*handle = NULL;
20449585STim.Szeto@Sun.COM 	scf_service_t	*svc = NULL;
20459585STim.Szeto@Sun.COM 	int ret;
20469585STim.Szeto@Sun.COM 
20479585STim.Szeto@Sun.COM 
20489585STim.Szeto@Sun.COM 	ret = iPsInit(&handle, &svc);
20499585STim.Szeto@Sun.COM 	if (ret != STMF_PS_SUCCESS) {
20509585STim.Szeto@Sun.COM 		return (STMF_PS_ERROR);
20519585STim.Szeto@Sun.COM 	}
20529585STim.Szeto@Sun.COM 
20539585STim.Szeto@Sun.COM 	ret = iPsGetSetPersistType(&persistType, handle, svc, SET);
20549585STim.Szeto@Sun.COM 
20559585STim.Szeto@Sun.COM 	/*
20569585STim.Szeto@Sun.COM 	 * Free resources
20579585STim.Szeto@Sun.COM 	 */
20589585STim.Szeto@Sun.COM 	if (handle != NULL) {
20599585STim.Szeto@Sun.COM 		scf_handle_destroy(handle);
20609585STim.Szeto@Sun.COM 	}
20619585STim.Szeto@Sun.COM 	if (svc != NULL) {
20629585STim.Szeto@Sun.COM 		scf_service_destroy(svc);
20639585STim.Szeto@Sun.COM 	}
20649585STim.Szeto@Sun.COM 	return (ret);
20659585STim.Szeto@Sun.COM }
20669585STim.Szeto@Sun.COM 
20679585STim.Szeto@Sun.COM static int
iPsGetSetPersistType(uint8_t * persistType,scf_handle_t * handle,scf_service_t * svc,int getSet)20689585STim.Szeto@Sun.COM iPsGetSetPersistType(uint8_t *persistType, scf_handle_t *handle,
20699585STim.Szeto@Sun.COM scf_service_t *svc, int getSet)
20709585STim.Szeto@Sun.COM {
20719585STim.Szeto@Sun.COM 	scf_propertygroup_t	*pg = NULL;
20729585STim.Szeto@Sun.COM 	scf_property_t	*prop = NULL;
20739585STim.Szeto@Sun.COM 	scf_value_t	*value = NULL;
20749585STim.Szeto@Sun.COM 	scf_transaction_t *tran = NULL;
20759585STim.Szeto@Sun.COM 	scf_transaction_entry_t *entry = NULL;
20769585STim.Szeto@Sun.COM 	char iPersistTypeGet[MAXNAMELEN] = {0};
20779585STim.Szeto@Sun.COM 	char *iPersistType;
20789585STim.Szeto@Sun.COM 	int ret = STMF_PS_SUCCESS;
20799585STim.Szeto@Sun.COM 	int commitRet;
20809585STim.Szeto@Sun.COM 
20819585STim.Szeto@Sun.COM 	if (((pg = scf_pg_create(handle)) == NULL) ||
20829585STim.Szeto@Sun.COM 	    ((prop = scf_property_create(handle)) == NULL) ||
20839585STim.Szeto@Sun.COM 	    ((entry = scf_entry_create(handle)) == NULL) ||
20849585STim.Szeto@Sun.COM 	    ((tran = scf_transaction_create(handle)) == NULL) ||
20859585STim.Szeto@Sun.COM 	    ((value = scf_value_create(handle)) == NULL)) {
20869585STim.Szeto@Sun.COM 		syslog(LOG_ERR, "scf alloc resource failed - %s",
20879585STim.Szeto@Sun.COM 		    scf_strerror(scf_error()));
20889585STim.Szeto@Sun.COM 		ret = STMF_PS_ERROR;
20899585STim.Szeto@Sun.COM 		goto out;
20909585STim.Szeto@Sun.COM 	}
20919585STim.Szeto@Sun.COM 
20929585STim.Szeto@Sun.COM 	if (getSet == GET) {
20939585STim.Szeto@Sun.COM 		/* set to default */
20949585STim.Szeto@Sun.COM 		*persistType = STMF_PERSIST_SMF;
20959585STim.Szeto@Sun.COM 		iPersistType = STMF_PS_PERSIST_SMF;
20969585STim.Szeto@Sun.COM 	}
20979585STim.Szeto@Sun.COM 
20989585STim.Szeto@Sun.COM 	if (getSet == SET) {
20999585STim.Szeto@Sun.COM 		if (*persistType == STMF_PERSIST_SMF) {
21009585STim.Szeto@Sun.COM 			iPersistType = STMF_PS_PERSIST_SMF;
21019585STim.Szeto@Sun.COM 		} else if (*persistType == STMF_PERSIST_NONE) {
21029585STim.Szeto@Sun.COM 			iPersistType = STMF_PS_PERSIST_NONE;
21039585STim.Szeto@Sun.COM 		} else {
21049585STim.Szeto@Sun.COM 			ret = STMF_PS_ERROR;
21059585STim.Szeto@Sun.COM 			goto out;
21069585STim.Szeto@Sun.COM 		}
21079585STim.Szeto@Sun.COM 	}
21089585STim.Szeto@Sun.COM 
21099585STim.Szeto@Sun.COM 	/*
21109585STim.Szeto@Sun.COM 	 * get stmf data property group
21119585STim.Szeto@Sun.COM 	 */
21129585STim.Szeto@Sun.COM 	if (scf_service_get_pg(svc, STMF_DATA_GROUP, pg) == -1) {
21139585STim.Szeto@Sun.COM 		if (scf_error() == SCF_ERROR_NOT_FOUND) {
21149585STim.Szeto@Sun.COM 			ret = STMF_PS_ERROR_NOT_FOUND;
21159585STim.Szeto@Sun.COM 		} else {
21169585STim.Szeto@Sun.COM 			ret = STMF_PS_ERROR;
21179585STim.Szeto@Sun.COM 		}
211811909SPeter.Gill@Sun.COM 		syslog(LOG_ERR, "get pg %s failed - %s",
211911909SPeter.Gill@Sun.COM 		    STMF_DATA_GROUP, scf_strerror(scf_error()));
212011909SPeter.Gill@Sun.COM 
21219585STim.Szeto@Sun.COM 		goto out;
21229585STim.Szeto@Sun.COM 	}
21239585STim.Szeto@Sun.COM 
21249585STim.Szeto@Sun.COM 	/* find persistence property */
21259585STim.Szeto@Sun.COM 	/*
21269585STim.Szeto@Sun.COM 	 * Get the persistence property
21279585STim.Szeto@Sun.COM 	 */
21289585STim.Szeto@Sun.COM 	if (scf_pg_get_property(pg, STMF_PERSIST_TYPE, prop) == -1) {
21299585STim.Szeto@Sun.COM 		if (scf_error() == SCF_ERROR_NOT_FOUND) {
21309585STim.Szeto@Sun.COM 			ret = STMF_PS_ERROR_NOT_FOUND;
21319585STim.Szeto@Sun.COM 		} else {
213211909SPeter.Gill@Sun.COM 			syslog(LOG_ERR, "get property %s/%s failed - %s",
213311909SPeter.Gill@Sun.COM 			    STMF_DATA_GROUP, STMF_PERSIST_TYPE,
21349585STim.Szeto@Sun.COM 			    scf_strerror(scf_error()));
21359585STim.Szeto@Sun.COM 			ret = STMF_PS_ERROR;
21369585STim.Szeto@Sun.COM 			goto out;
21379585STim.Szeto@Sun.COM 		}
21389585STim.Szeto@Sun.COM 	}
21399585STim.Szeto@Sun.COM 
21409585STim.Szeto@Sun.COM 	/* no persist property found */
21419585STim.Szeto@Sun.COM 	if (ret == STMF_PS_ERROR_NOT_FOUND || getSet == SET) {
21429585STim.Szeto@Sun.COM 		/*
21439585STim.Szeto@Sun.COM 		 * If we have no persistType property, go ahead
21449585STim.Szeto@Sun.COM 		 * and create it with the user specified value or
21459585STim.Szeto@Sun.COM 		 * the default value.
21469585STim.Szeto@Sun.COM 		 */
21479585STim.Szeto@Sun.COM 		/*
21489585STim.Szeto@Sun.COM 		 * Begin the transaction
21499585STim.Szeto@Sun.COM 		 */
21509585STim.Szeto@Sun.COM 		if (scf_transaction_start(tran, pg) == -1) {
215111909SPeter.Gill@Sun.COM 			syslog(LOG_ERR, "start transaction for %s failed - %s",
215211909SPeter.Gill@Sun.COM 			    STMF_DATA_GROUP, scf_strerror(scf_error()));
21539585STim.Szeto@Sun.COM 			ret = STMF_PS_ERROR;
21549585STim.Szeto@Sun.COM 			goto out;
21559585STim.Szeto@Sun.COM 		}
21569585STim.Szeto@Sun.COM 
21579585STim.Szeto@Sun.COM 		/* is this a SET or GET w/error? */
21589585STim.Szeto@Sun.COM 		if (ret) {
21599585STim.Szeto@Sun.COM 			if (scf_transaction_property_new(tran, entry,
21609585STim.Szeto@Sun.COM 			    STMF_PERSIST_TYPE, SCF_TYPE_ASTRING) == -1) {
216111909SPeter.Gill@Sun.COM 				syslog(LOG_ERR, "transaction property new "
216211909SPeter.Gill@Sun.COM 				    "%s/%s failed - %s", STMF_DATA_GROUP,
216311909SPeter.Gill@Sun.COM 				    STMF_PERSIST_TYPE,
21649585STim.Szeto@Sun.COM 				    scf_strerror(scf_error()));
21659585STim.Szeto@Sun.COM 				ret = STMF_PS_ERROR;
21669585STim.Szeto@Sun.COM 				goto out;
21679585STim.Szeto@Sun.COM 			}
21689585STim.Szeto@Sun.COM 		} else {
21699585STim.Szeto@Sun.COM 			if (scf_transaction_property_change(tran, entry,
21709585STim.Szeto@Sun.COM 			    STMF_PERSIST_TYPE, SCF_TYPE_ASTRING) == -1) {
217111909SPeter.Gill@Sun.COM 				syslog(LOG_ERR, "transaction property change "
217211909SPeter.Gill@Sun.COM 				    "%s/%s failed - %s", STMF_DATA_GROUP,
217311909SPeter.Gill@Sun.COM 				    STMF_PERSIST_TYPE,
21749585STim.Szeto@Sun.COM 				    scf_strerror(scf_error()));
21759585STim.Szeto@Sun.COM 				ret = STMF_PS_ERROR;
21769585STim.Szeto@Sun.COM 				goto out;
21779585STim.Szeto@Sun.COM 			}
21789585STim.Szeto@Sun.COM 		}
21799585STim.Szeto@Sun.COM 
21809585STim.Szeto@Sun.COM 		/*
21819585STim.Szeto@Sun.COM 		 * set the persist type
21829585STim.Szeto@Sun.COM 		 */
21839585STim.Szeto@Sun.COM 		if (scf_value_set_astring(value, iPersistType) == -1) {
218411909SPeter.Gill@Sun.COM 			syslog(LOG_ERR, "set value %s/%s failed - %s",
218511909SPeter.Gill@Sun.COM 			    STMF_DATA_GROUP, STMF_PERSIST_TYPE,
21869585STim.Szeto@Sun.COM 			    scf_strerror(scf_error()));
21879585STim.Szeto@Sun.COM 			ret = STMF_PS_ERROR;
21889585STim.Szeto@Sun.COM 			goto out;
21899585STim.Szeto@Sun.COM 		}
21909585STim.Szeto@Sun.COM 
21919585STim.Szeto@Sun.COM 		/*
21929585STim.Szeto@Sun.COM 		 * add the value to the transaction
21939585STim.Szeto@Sun.COM 		 */
21949585STim.Szeto@Sun.COM 		if (scf_entry_add_value(entry, value) == -1) {
219511909SPeter.Gill@Sun.COM 			syslog(LOG_ERR, "add value %s/%s failed - %s",
219611909SPeter.Gill@Sun.COM 			    STMF_DATA_GROUP, STMF_PERSIST_TYPE,
21979585STim.Szeto@Sun.COM 			    scf_strerror(scf_error()));
21989585STim.Szeto@Sun.COM 			ret = STMF_PS_ERROR;
21999585STim.Szeto@Sun.COM 			goto out;
22009585STim.Szeto@Sun.COM 		}
22019585STim.Szeto@Sun.COM 		if ((commitRet = scf_transaction_commit(tran)) != 1) {
220211909SPeter.Gill@Sun.COM 			syslog(LOG_ERR, "transaction commit for %s failed - %s",
220311909SPeter.Gill@Sun.COM 			    STMF_DATA_GROUP, scf_strerror(scf_error()));
22049585STim.Szeto@Sun.COM 			if (commitRet == 0) {
22059585STim.Szeto@Sun.COM 				ret = STMF_PS_ERROR_BUSY;
22069585STim.Szeto@Sun.COM 			} else {
22079585STim.Szeto@Sun.COM 				ret = STMF_PS_ERROR;
22089585STim.Szeto@Sun.COM 			}
22099585STim.Szeto@Sun.COM 			goto out;
22109585STim.Szeto@Sun.COM 		}
22119585STim.Szeto@Sun.COM 		/* reset return value */
22129585STim.Szeto@Sun.COM 		ret = STMF_PS_SUCCESS;
22139585STim.Szeto@Sun.COM 	} else if (getSet == GET) {
22149585STim.Szeto@Sun.COM 		/* get the persist property */
22159585STim.Szeto@Sun.COM 		if (scf_property_get_value(prop, value) == -1) {
221611909SPeter.Gill@Sun.COM 			syslog(LOG_ERR, "get property value %s/%s failed - %s",
221711909SPeter.Gill@Sun.COM 			    STMF_DATA_GROUP, STMF_PERSIST_TYPE,
22189585STim.Szeto@Sun.COM 			    scf_strerror(scf_error()));
22199585STim.Szeto@Sun.COM 			ret = STMF_PS_ERROR;
22209585STim.Szeto@Sun.COM 			goto out;
22219585STim.Szeto@Sun.COM 		}
22229585STim.Szeto@Sun.COM 
22239585STim.Szeto@Sun.COM 		/*
22249585STim.Szeto@Sun.COM 		 * Get the value of the persist property
22259585STim.Szeto@Sun.COM 		 */
22269585STim.Szeto@Sun.COM 		if (scf_value_get_astring(value, iPersistTypeGet, MAXNAMELEN)
22279585STim.Szeto@Sun.COM 		    == -1) {
222811909SPeter.Gill@Sun.COM 			syslog(LOG_ERR, "get string value %s/%s failed - %s",
222911909SPeter.Gill@Sun.COM 			    STMF_DATA_GROUP, STMF_PERSIST_TYPE,
22309585STim.Szeto@Sun.COM 			    scf_strerror(scf_error()));
22319585STim.Szeto@Sun.COM 			ret = STMF_PS_ERROR;
22329585STim.Szeto@Sun.COM 			goto out;
22339585STim.Szeto@Sun.COM 		}
22349585STim.Szeto@Sun.COM 	}
22359585STim.Szeto@Sun.COM 
22369585STim.Szeto@Sun.COM 	if (getSet == GET) {
22379585STim.Szeto@Sun.COM 		if (strcmp(iPersistTypeGet, STMF_PS_PERSIST_NONE) == 0) {
22389585STim.Szeto@Sun.COM 			*persistType = STMF_PERSIST_NONE;
22399585STim.Szeto@Sun.COM 		} else if (strcmp(iPersistTypeGet, STMF_PS_PERSIST_SMF) == 0) {
22409585STim.Szeto@Sun.COM 			*persistType = STMF_PERSIST_SMF;
22419585STim.Szeto@Sun.COM 		} else {
22429585STim.Szeto@Sun.COM 			ret = STMF_PS_ERROR;
22439585STim.Szeto@Sun.COM 			goto out;
22449585STim.Szeto@Sun.COM 		}
22459585STim.Szeto@Sun.COM 	}
22469585STim.Szeto@Sun.COM out:
22479585STim.Szeto@Sun.COM 	/*
22489585STim.Szeto@Sun.COM 	 * Free resources.
22499585STim.Szeto@Sun.COM 	 * handle and svc should not be free'd here. They're
22509585STim.Szeto@Sun.COM 	 * free'd elsewhere
22519585STim.Szeto@Sun.COM 	 */
22529585STim.Szeto@Sun.COM 	if (pg != NULL) {
22539585STim.Szeto@Sun.COM 		scf_pg_destroy(pg);
22549585STim.Szeto@Sun.COM 	}
22559585STim.Szeto@Sun.COM 	if (prop != NULL) {
22569585STim.Szeto@Sun.COM 		scf_property_destroy(prop);
22579585STim.Szeto@Sun.COM 	}
22589585STim.Szeto@Sun.COM 	if (entry != NULL) {
22599585STim.Szeto@Sun.COM 		scf_entry_destroy(entry);
22609585STim.Szeto@Sun.COM 	}
22619585STim.Szeto@Sun.COM 	if (tran != NULL) {
22629585STim.Szeto@Sun.COM 		scf_transaction_destroy(tran);
22639585STim.Szeto@Sun.COM 	}
22649585STim.Szeto@Sun.COM 	if (value != NULL) {
22659585STim.Szeto@Sun.COM 		scf_value_destroy(value);
22669585STim.Szeto@Sun.COM 	}
22679585STim.Szeto@Sun.COM 	return (ret);
22689585STim.Szeto@Sun.COM }
22699585STim.Szeto@Sun.COM 
2270*12682SSrivijitha.Dugganapalli@Sun.COM int
psSetStmfProp(int propType,char * propVal)2271*12682SSrivijitha.Dugganapalli@Sun.COM psSetStmfProp(int propType, char *propVal)
2272*12682SSrivijitha.Dugganapalli@Sun.COM {
2273*12682SSrivijitha.Dugganapalli@Sun.COM 	return (iPsGetSetStmfProp(propType, propVal, SET));
2274*12682SSrivijitha.Dugganapalli@Sun.COM }
2275*12682SSrivijitha.Dugganapalli@Sun.COM 
2276*12682SSrivijitha.Dugganapalli@Sun.COM int
psGetStmfProp(int propType,char * propVal)2277*12682SSrivijitha.Dugganapalli@Sun.COM psGetStmfProp(int propType, char *propVal)
2278*12682SSrivijitha.Dugganapalli@Sun.COM {
2279*12682SSrivijitha.Dugganapalli@Sun.COM 	return (iPsGetSetStmfProp(propType, propVal, GET));
2280*12682SSrivijitha.Dugganapalli@Sun.COM }
2281*12682SSrivijitha.Dugganapalli@Sun.COM 
2282*12682SSrivijitha.Dugganapalli@Sun.COM static int
iPsGetSetStmfProp(int propType,char * propVal,int getSet)2283*12682SSrivijitha.Dugganapalli@Sun.COM iPsGetSetStmfProp(int propType, char *propVal, int getSet)
2284*12682SSrivijitha.Dugganapalli@Sun.COM {
2285*12682SSrivijitha.Dugganapalli@Sun.COM 	scf_handle_t	*handle = NULL;
2286*12682SSrivijitha.Dugganapalli@Sun.COM 	scf_service_t	*svc = NULL;
2287*12682SSrivijitha.Dugganapalli@Sun.COM 	scf_property_t *prop = NULL;
2288*12682SSrivijitha.Dugganapalli@Sun.COM 	scf_propertygroup_t	*pg = NULL;
2289*12682SSrivijitha.Dugganapalli@Sun.COM 	scf_transaction_t *tran = NULL;
2290*12682SSrivijitha.Dugganapalli@Sun.COM 	scf_transaction_entry_t *entry = NULL;
2291*12682SSrivijitha.Dugganapalli@Sun.COM 	scf_value_t	*value = NULL;
2292*12682SSrivijitha.Dugganapalli@Sun.COM 	char *psStmfPropVal;
2293*12682SSrivijitha.Dugganapalli@Sun.COM 	char *psStmfProp;
2294*12682SSrivijitha.Dugganapalli@Sun.COM 	char stmfPropGet[MAXNAMELEN] = {0};
2295*12682SSrivijitha.Dugganapalli@Sun.COM 	int ret = STMF_PS_SUCCESS;
2296*12682SSrivijitha.Dugganapalli@Sun.COM 	int commitRet;
2297*12682SSrivijitha.Dugganapalli@Sun.COM 
2298*12682SSrivijitha.Dugganapalli@Sun.COM 	if (propVal == NULL || (getSet != GET && getSet != SET)) {
2299*12682SSrivijitha.Dugganapalli@Sun.COM 		ret = STMF_PS_ERROR;
2300*12682SSrivijitha.Dugganapalli@Sun.COM 		goto out;
2301*12682SSrivijitha.Dugganapalli@Sun.COM 	}
2302*12682SSrivijitha.Dugganapalli@Sun.COM 
2303*12682SSrivijitha.Dugganapalli@Sun.COM 	/*
2304*12682SSrivijitha.Dugganapalli@Sun.COM 	 * Init the service handle
2305*12682SSrivijitha.Dugganapalli@Sun.COM 	 */
2306*12682SSrivijitha.Dugganapalli@Sun.COM 
2307*12682SSrivijitha.Dugganapalli@Sun.COM 	ret = iPsInit(&handle, &svc);
2308*12682SSrivijitha.Dugganapalli@Sun.COM 	if (ret != STMF_PS_SUCCESS) {
2309*12682SSrivijitha.Dugganapalli@Sun.COM 		goto out;
2310*12682SSrivijitha.Dugganapalli@Sun.COM 	}
2311*12682SSrivijitha.Dugganapalli@Sun.COM 
2312*12682SSrivijitha.Dugganapalli@Sun.COM 	/*
2313*12682SSrivijitha.Dugganapalli@Sun.COM 	 * Allocate scf resources
2314*12682SSrivijitha.Dugganapalli@Sun.COM 	 */
2315*12682SSrivijitha.Dugganapalli@Sun.COM 
2316*12682SSrivijitha.Dugganapalli@Sun.COM 	if (((pg = scf_pg_create(handle)) == NULL) ||
2317*12682SSrivijitha.Dugganapalli@Sun.COM 	    ((prop = scf_property_create(handle)) == NULL) ||
2318*12682SSrivijitha.Dugganapalli@Sun.COM 	    ((entry = scf_entry_create(handle)) == NULL) ||
2319*12682SSrivijitha.Dugganapalli@Sun.COM 	    ((tran = scf_transaction_create(handle)) == NULL) ||
2320*12682SSrivijitha.Dugganapalli@Sun.COM 	    ((value = scf_value_create(handle)) == NULL)) {
2321*12682SSrivijitha.Dugganapalli@Sun.COM 		syslog(LOG_ERR, "scf alloc resource failed - %s",
2322*12682SSrivijitha.Dugganapalli@Sun.COM 		    scf_strerror(scf_error()));
2323*12682SSrivijitha.Dugganapalli@Sun.COM 		ret = STMF_PS_ERROR;
2324*12682SSrivijitha.Dugganapalli@Sun.COM 		goto out;
2325*12682SSrivijitha.Dugganapalli@Sun.COM 	}
2326*12682SSrivijitha.Dugganapalli@Sun.COM 	if (getSet == GET) {
2327*12682SSrivijitha.Dugganapalli@Sun.COM 		switch (propType) {
2328*12682SSrivijitha.Dugganapalli@Sun.COM 			case STMF_DEFAULT_LU_STATE :
2329*12682SSrivijitha.Dugganapalli@Sun.COM 				psStmfProp = DEFAULT_LU_STATE;
2330*12682SSrivijitha.Dugganapalli@Sun.COM 				psStmfPropVal = STMF_PS_LU_ONLINE;
2331*12682SSrivijitha.Dugganapalli@Sun.COM 				(void) strcpy(stmfPropGet, psStmfPropVal);
2332*12682SSrivijitha.Dugganapalli@Sun.COM 				break;
2333*12682SSrivijitha.Dugganapalli@Sun.COM 			case STMF_DEFAULT_TARGET_PORT_STATE :
2334*12682SSrivijitha.Dugganapalli@Sun.COM 				psStmfProp = DEFAULT_TARGET_PORT_STATE;
2335*12682SSrivijitha.Dugganapalli@Sun.COM 				psStmfPropVal = STMF_PS_TARGET_PORT_ONLINE;
2336*12682SSrivijitha.Dugganapalli@Sun.COM 				(void) strcpy(stmfPropGet, psStmfPropVal);
2337*12682SSrivijitha.Dugganapalli@Sun.COM 				break;
2338*12682SSrivijitha.Dugganapalli@Sun.COM 			default :
2339*12682SSrivijitha.Dugganapalli@Sun.COM 				ret = STMF_PS_ERROR;
2340*12682SSrivijitha.Dugganapalli@Sun.COM 				goto out;
2341*12682SSrivijitha.Dugganapalli@Sun.COM 				break;
2342*12682SSrivijitha.Dugganapalli@Sun.COM 		}
2343*12682SSrivijitha.Dugganapalli@Sun.COM 	}
2344*12682SSrivijitha.Dugganapalli@Sun.COM 	if (getSet == SET) {
2345*12682SSrivijitha.Dugganapalli@Sun.COM 		switch (propType) {
2346*12682SSrivijitha.Dugganapalli@Sun.COM 			case STMF_DEFAULT_LU_STATE :
2347*12682SSrivijitha.Dugganapalli@Sun.COM 				psStmfProp = DEFAULT_LU_STATE;
2348*12682SSrivijitha.Dugganapalli@Sun.COM 				if (strcasecmp(propVal, "online") == 0)
2349*12682SSrivijitha.Dugganapalli@Sun.COM 					psStmfPropVal = STMF_PS_LU_ONLINE;
2350*12682SSrivijitha.Dugganapalli@Sun.COM 				else if (strcasecmp(propVal, "offline") == 0)
2351*12682SSrivijitha.Dugganapalli@Sun.COM 					psStmfPropVal = STMF_PS_LU_OFFLINE;
2352*12682SSrivijitha.Dugganapalli@Sun.COM 				else
2353*12682SSrivijitha.Dugganapalli@Sun.COM 					ret = STMF_PS_ERROR;
2354*12682SSrivijitha.Dugganapalli@Sun.COM 					goto out;
2355*12682SSrivijitha.Dugganapalli@Sun.COM 				break;
2356*12682SSrivijitha.Dugganapalli@Sun.COM 			case STMF_DEFAULT_TARGET_PORT_STATE :
2357*12682SSrivijitha.Dugganapalli@Sun.COM 				psStmfProp = DEFAULT_TARGET_PORT_STATE;
2358*12682SSrivijitha.Dugganapalli@Sun.COM 				if (strcasecmp(propVal, "online") == 0)
2359*12682SSrivijitha.Dugganapalli@Sun.COM 					psStmfPropVal =
2360*12682SSrivijitha.Dugganapalli@Sun.COM 					    STMF_PS_TARGET_PORT_ONLINE;
2361*12682SSrivijitha.Dugganapalli@Sun.COM 				else if (strcasecmp(propVal, "offline") == 0)
2362*12682SSrivijitha.Dugganapalli@Sun.COM 					psStmfPropVal =
2363*12682SSrivijitha.Dugganapalli@Sun.COM 					    STMF_PS_TARGET_PORT_OFFLINE;
2364*12682SSrivijitha.Dugganapalli@Sun.COM 				else
2365*12682SSrivijitha.Dugganapalli@Sun.COM 					ret = STMF_PS_ERROR;
2366*12682SSrivijitha.Dugganapalli@Sun.COM 					goto out;
2367*12682SSrivijitha.Dugganapalli@Sun.COM 				break;
2368*12682SSrivijitha.Dugganapalli@Sun.COM 			default :
2369*12682SSrivijitha.Dugganapalli@Sun.COM 				ret = STMF_PS_ERROR;
2370*12682SSrivijitha.Dugganapalli@Sun.COM 				goto out;
2371*12682SSrivijitha.Dugganapalli@Sun.COM 				break;
2372*12682SSrivijitha.Dugganapalli@Sun.COM 		}
2373*12682SSrivijitha.Dugganapalli@Sun.COM 	}
2374*12682SSrivijitha.Dugganapalli@Sun.COM 
2375*12682SSrivijitha.Dugganapalli@Sun.COM 	/*
2376*12682SSrivijitha.Dugganapalli@Sun.COM 	 * get stmf data property group
2377*12682SSrivijitha.Dugganapalli@Sun.COM 	 */
2378*12682SSrivijitha.Dugganapalli@Sun.COM 
2379*12682SSrivijitha.Dugganapalli@Sun.COM 	if (scf_service_get_pg(svc, STMF_DATA_GROUP, pg) == -1) {
2380*12682SSrivijitha.Dugganapalli@Sun.COM 		if (scf_error() == SCF_ERROR_NOT_FOUND) {
2381*12682SSrivijitha.Dugganapalli@Sun.COM 			ret = STMF_PS_ERROR_NOT_FOUND;
2382*12682SSrivijitha.Dugganapalli@Sun.COM 		} else {
2383*12682SSrivijitha.Dugganapalli@Sun.COM 			ret = STMF_PS_ERROR;
2384*12682SSrivijitha.Dugganapalli@Sun.COM 		}
2385*12682SSrivijitha.Dugganapalli@Sun.COM 		syslog(LOG_ERR, "get pg %s failed - %s",
2386*12682SSrivijitha.Dugganapalli@Sun.COM 		    STMF_DATA_GROUP, scf_strerror(scf_error()));
2387*12682SSrivijitha.Dugganapalli@Sun.COM 		goto out;
2388*12682SSrivijitha.Dugganapalli@Sun.COM 	}
2389*12682SSrivijitha.Dugganapalli@Sun.COM 
2390*12682SSrivijitha.Dugganapalli@Sun.COM 	/*
2391*12682SSrivijitha.Dugganapalli@Sun.COM 	 * get the stmf props property, if exists
2392*12682SSrivijitha.Dugganapalli@Sun.COM 	 */
2393*12682SSrivijitha.Dugganapalli@Sun.COM 
2394*12682SSrivijitha.Dugganapalli@Sun.COM 	if (scf_pg_get_property(pg, psStmfProp, prop) == -1) {
2395*12682SSrivijitha.Dugganapalli@Sun.COM 		if (scf_error() == SCF_ERROR_NOT_FOUND) {
2396*12682SSrivijitha.Dugganapalli@Sun.COM 			ret = STMF_PS_ERROR_NOT_FOUND;
2397*12682SSrivijitha.Dugganapalli@Sun.COM 		} else {
2398*12682SSrivijitha.Dugganapalli@Sun.COM 			syslog(LOG_ERR, "start transaction for %s/%s "
2399*12682SSrivijitha.Dugganapalli@Sun.COM 			    "failed - %s", STMF_DATA_GROUP, psStmfProp,
2400*12682SSrivijitha.Dugganapalli@Sun.COM 			    scf_strerror(scf_error()));
2401*12682SSrivijitha.Dugganapalli@Sun.COM 			ret = STMF_PS_ERROR;
2402*12682SSrivijitha.Dugganapalli@Sun.COM 			goto out;
2403*12682SSrivijitha.Dugganapalli@Sun.COM 		}
2404*12682SSrivijitha.Dugganapalli@Sun.COM 	}
2405*12682SSrivijitha.Dugganapalli@Sun.COM 
2406*12682SSrivijitha.Dugganapalli@Sun.COM 	/* if stmf prop is not found or while setting the prop */
2407*12682SSrivijitha.Dugganapalli@Sun.COM 
2408*12682SSrivijitha.Dugganapalli@Sun.COM 	if (ret == STMF_PS_ERROR_NOT_FOUND || getSet == SET) {
2409*12682SSrivijitha.Dugganapalli@Sun.COM 		/*
2410*12682SSrivijitha.Dugganapalli@Sun.COM 		 * Begin the transaction
2411*12682SSrivijitha.Dugganapalli@Sun.COM 		 */
2412*12682SSrivijitha.Dugganapalli@Sun.COM 		if (scf_transaction_start(tran, pg) == -1) {
2413*12682SSrivijitha.Dugganapalli@Sun.COM 			syslog(LOG_ERR, "start transaction for %s failed - %s",
2414*12682SSrivijitha.Dugganapalli@Sun.COM 			    STMF_DATA_GROUP, scf_strerror(scf_error()));
2415*12682SSrivijitha.Dugganapalli@Sun.COM 			ret = STMF_PS_ERROR;
2416*12682SSrivijitha.Dugganapalli@Sun.COM 			goto out;
2417*12682SSrivijitha.Dugganapalli@Sun.COM 		}
2418*12682SSrivijitha.Dugganapalli@Sun.COM 		if (ret) {
2419*12682SSrivijitha.Dugganapalli@Sun.COM 			if (scf_transaction_property_new(tran, entry,
2420*12682SSrivijitha.Dugganapalli@Sun.COM 			    psStmfProp, SCF_TYPE_ASTRING) == -1) {
2421*12682SSrivijitha.Dugganapalli@Sun.COM 				syslog(LOG_ERR, "transaction property new "
2422*12682SSrivijitha.Dugganapalli@Sun.COM 				    "%s/%s failed - %s", STMF_DATA_GROUP,
2423*12682SSrivijitha.Dugganapalli@Sun.COM 				    psStmfProp, scf_strerror(scf_error()));
2424*12682SSrivijitha.Dugganapalli@Sun.COM 				ret = STMF_PS_ERROR;
2425*12682SSrivijitha.Dugganapalli@Sun.COM 				goto out;
2426*12682SSrivijitha.Dugganapalli@Sun.COM 			}
2427*12682SSrivijitha.Dugganapalli@Sun.COM 		} else {
2428*12682SSrivijitha.Dugganapalli@Sun.COM 			if (scf_transaction_property_change(tran, entry,
2429*12682SSrivijitha.Dugganapalli@Sun.COM 			    psStmfProp, SCF_TYPE_ASTRING) == -1) {
2430*12682SSrivijitha.Dugganapalli@Sun.COM 					syslog(LOG_ERR,
2431*12682SSrivijitha.Dugganapalli@Sun.COM 					    "transaction property change "
2432*12682SSrivijitha.Dugganapalli@Sun.COM 					    "%s/%s failed - %s",
2433*12682SSrivijitha.Dugganapalli@Sun.COM 					    STMF_DATA_GROUP, psStmfProp,
2434*12682SSrivijitha.Dugganapalli@Sun.COM 					    scf_strerror(scf_error()));
2435*12682SSrivijitha.Dugganapalli@Sun.COM 					ret = STMF_PS_ERROR;
2436*12682SSrivijitha.Dugganapalli@Sun.COM 					goto out;
2437*12682SSrivijitha.Dugganapalli@Sun.COM 			}
2438*12682SSrivijitha.Dugganapalli@Sun.COM 		}
2439*12682SSrivijitha.Dugganapalli@Sun.COM 
2440*12682SSrivijitha.Dugganapalli@Sun.COM 		/*
2441*12682SSrivijitha.Dugganapalli@Sun.COM 		 * set stmf prop value
2442*12682SSrivijitha.Dugganapalli@Sun.COM 		 */
2443*12682SSrivijitha.Dugganapalli@Sun.COM 
2444*12682SSrivijitha.Dugganapalli@Sun.COM 		if (scf_value_set_astring(value, psStmfPropVal) == -1) {
2445*12682SSrivijitha.Dugganapalli@Sun.COM 			syslog(LOG_ERR, "set value %s/%s failed - %s",
2446*12682SSrivijitha.Dugganapalli@Sun.COM 			    STMF_DATA_GROUP, psStmfProp,
2447*12682SSrivijitha.Dugganapalli@Sun.COM 			    scf_strerror(scf_error()));
2448*12682SSrivijitha.Dugganapalli@Sun.COM 			ret = STMF_PS_ERROR;
2449*12682SSrivijitha.Dugganapalli@Sun.COM 			goto out;
2450*12682SSrivijitha.Dugganapalli@Sun.COM 		}
2451*12682SSrivijitha.Dugganapalli@Sun.COM 
2452*12682SSrivijitha.Dugganapalli@Sun.COM 		/*
2453*12682SSrivijitha.Dugganapalli@Sun.COM 		 * add the value to the transaction
2454*12682SSrivijitha.Dugganapalli@Sun.COM 		 */
2455*12682SSrivijitha.Dugganapalli@Sun.COM 
2456*12682SSrivijitha.Dugganapalli@Sun.COM 		if (scf_entry_add_value(entry, value) == -1) {
2457*12682SSrivijitha.Dugganapalli@Sun.COM 			syslog(LOG_ERR, "add value %s/%s failed - %s",
2458*12682SSrivijitha.Dugganapalli@Sun.COM 			    STMF_DATA_GROUP, psStmfProp,
2459*12682SSrivijitha.Dugganapalli@Sun.COM 			    scf_strerror(scf_error()));
2460*12682SSrivijitha.Dugganapalli@Sun.COM 			ret = STMF_PS_ERROR;
2461*12682SSrivijitha.Dugganapalli@Sun.COM 			goto out;
2462*12682SSrivijitha.Dugganapalli@Sun.COM 		}
2463*12682SSrivijitha.Dugganapalli@Sun.COM 		if ((commitRet = scf_transaction_commit(tran)) != 1) {
2464*12682SSrivijitha.Dugganapalli@Sun.COM 			syslog(LOG_ERR, "transaction commit for %s"
2465*12682SSrivijitha.Dugganapalli@Sun.COM 			    "failed - %s", STMF_DATA_GROUP,
2466*12682SSrivijitha.Dugganapalli@Sun.COM 			    scf_strerror(scf_error()));
2467*12682SSrivijitha.Dugganapalli@Sun.COM 			if (commitRet == 0) {
2468*12682SSrivijitha.Dugganapalli@Sun.COM 				ret = STMF_PS_ERROR_BUSY;
2469*12682SSrivijitha.Dugganapalli@Sun.COM 			} else {
2470*12682SSrivijitha.Dugganapalli@Sun.COM 				ret = STMF_PS_ERROR;
2471*12682SSrivijitha.Dugganapalli@Sun.COM 			}
2472*12682SSrivijitha.Dugganapalli@Sun.COM 			goto out;
2473*12682SSrivijitha.Dugganapalli@Sun.COM 		}
2474*12682SSrivijitha.Dugganapalli@Sun.COM 		ret = STMF_PS_SUCCESS;
2475*12682SSrivijitha.Dugganapalli@Sun.COM 	} else if (getSet == GET) {
2476*12682SSrivijitha.Dugganapalli@Sun.COM 		if (scf_property_get_value(prop, value) == -1) {
2477*12682SSrivijitha.Dugganapalli@Sun.COM 			syslog(LOG_ERR, "get property value "
2478*12682SSrivijitha.Dugganapalli@Sun.COM 			    "%s/%s failed - %s",
2479*12682SSrivijitha.Dugganapalli@Sun.COM 			    STMF_DATA_GROUP, psStmfProp,
2480*12682SSrivijitha.Dugganapalli@Sun.COM 			    scf_strerror(scf_error()));
2481*12682SSrivijitha.Dugganapalli@Sun.COM 			ret = STMF_PS_ERROR;
2482*12682SSrivijitha.Dugganapalli@Sun.COM 			goto out;
2483*12682SSrivijitha.Dugganapalli@Sun.COM 		}
2484*12682SSrivijitha.Dugganapalli@Sun.COM 
2485*12682SSrivijitha.Dugganapalli@Sun.COM 		/* get stmfProp */
2486*12682SSrivijitha.Dugganapalli@Sun.COM 
2487*12682SSrivijitha.Dugganapalli@Sun.COM 		if (scf_value_get_astring(value, stmfPropGet, MAXNAMELEN)
2488*12682SSrivijitha.Dugganapalli@Sun.COM 		    == -1) {
2489*12682SSrivijitha.Dugganapalli@Sun.COM 			syslog(LOG_ERR, "get string value %s/%s failed - %s",
2490*12682SSrivijitha.Dugganapalli@Sun.COM 			    STMF_DATA_GROUP, psStmfProp,
2491*12682SSrivijitha.Dugganapalli@Sun.COM 			    scf_strerror(scf_error()));
2492*12682SSrivijitha.Dugganapalli@Sun.COM 			ret = STMF_PS_ERROR;
2493*12682SSrivijitha.Dugganapalli@Sun.COM 			goto out;
2494*12682SSrivijitha.Dugganapalli@Sun.COM 		}
2495*12682SSrivijitha.Dugganapalli@Sun.COM 	}
2496*12682SSrivijitha.Dugganapalli@Sun.COM 	if (getSet == GET) {
2497*12682SSrivijitha.Dugganapalli@Sun.COM 		if (strcmp(stmfPropGet, STMF_PS_LU_ONLINE) == 0) {
2498*12682SSrivijitha.Dugganapalli@Sun.COM 			(void) strcpy(propVal, "online");
2499*12682SSrivijitha.Dugganapalli@Sun.COM 		} else if (strcmp(stmfPropGet, STMF_PS_LU_OFFLINE) == 0) {
2500*12682SSrivijitha.Dugganapalli@Sun.COM 			(void) strcpy(propVal, "offline");
2501*12682SSrivijitha.Dugganapalli@Sun.COM 		} else if (strcmp(stmfPropGet, STMF_PS_TARGET_PORT_ONLINE)
2502*12682SSrivijitha.Dugganapalli@Sun.COM 		    == 0) {
2503*12682SSrivijitha.Dugganapalli@Sun.COM 			(void) strcpy(propVal, "online");
2504*12682SSrivijitha.Dugganapalli@Sun.COM 		} else if (strcmp(stmfPropGet, STMF_PS_TARGET_PORT_OFFLINE)
2505*12682SSrivijitha.Dugganapalli@Sun.COM 		    == 0) {
2506*12682SSrivijitha.Dugganapalli@Sun.COM 			(void) strcpy(propVal, "offline");
2507*12682SSrivijitha.Dugganapalli@Sun.COM 		} else {
2508*12682SSrivijitha.Dugganapalli@Sun.COM 			ret = STMF_PS_ERROR;
2509*12682SSrivijitha.Dugganapalli@Sun.COM 			goto out;
2510*12682SSrivijitha.Dugganapalli@Sun.COM 		}
2511*12682SSrivijitha.Dugganapalli@Sun.COM 	}
2512*12682SSrivijitha.Dugganapalli@Sun.COM out:
2513*12682SSrivijitha.Dugganapalli@Sun.COM 	/*
2514*12682SSrivijitha.Dugganapalli@Sun.COM 	 * Free resources.
2515*12682SSrivijitha.Dugganapalli@Sun.COM 	 */
2516*12682SSrivijitha.Dugganapalli@Sun.COM 
2517*12682SSrivijitha.Dugganapalli@Sun.COM 	if (handle != NULL) {
2518*12682SSrivijitha.Dugganapalli@Sun.COM 		scf_handle_destroy(handle);
2519*12682SSrivijitha.Dugganapalli@Sun.COM 	}
2520*12682SSrivijitha.Dugganapalli@Sun.COM 	if (svc != NULL) {
2521*12682SSrivijitha.Dugganapalli@Sun.COM 		scf_service_destroy(svc);
2522*12682SSrivijitha.Dugganapalli@Sun.COM 	}
2523*12682SSrivijitha.Dugganapalli@Sun.COM 	if (pg != NULL) {
2524*12682SSrivijitha.Dugganapalli@Sun.COM 		scf_pg_destroy(pg);
2525*12682SSrivijitha.Dugganapalli@Sun.COM 	}
2526*12682SSrivijitha.Dugganapalli@Sun.COM 	if (prop != NULL) {
2527*12682SSrivijitha.Dugganapalli@Sun.COM 		scf_property_destroy(prop);
2528*12682SSrivijitha.Dugganapalli@Sun.COM 	}
2529*12682SSrivijitha.Dugganapalli@Sun.COM 	if (entry != NULL) {
2530*12682SSrivijitha.Dugganapalli@Sun.COM 		scf_entry_destroy(entry);
2531*12682SSrivijitha.Dugganapalli@Sun.COM 	}
2532*12682SSrivijitha.Dugganapalli@Sun.COM 	if (tran != NULL) {
2533*12682SSrivijitha.Dugganapalli@Sun.COM 		scf_transaction_destroy(tran);
2534*12682SSrivijitha.Dugganapalli@Sun.COM 	}
2535*12682SSrivijitha.Dugganapalli@Sun.COM 	if (value != NULL) {
2536*12682SSrivijitha.Dugganapalli@Sun.COM 		scf_value_destroy(value);
2537*12682SSrivijitha.Dugganapalli@Sun.COM 	}
2538*12682SSrivijitha.Dugganapalli@Sun.COM 	return (ret);
2539*12682SSrivijitha.Dugganapalli@Sun.COM }
2540*12682SSrivijitha.Dugganapalli@Sun.COM 
25417836SJohn.Forte@Sun.COM /*
25427836SJohn.Forte@Sun.COM  * Initialize scf stmf service access
25437836SJohn.Forte@Sun.COM  * handle - returned handle
25447836SJohn.Forte@Sun.COM  * service - returned service handle
25457836SJohn.Forte@Sun.COM  *
25467836SJohn.Forte@Sun.COM  * Both handle and service must be destroyed by the caller
25477836SJohn.Forte@Sun.COM  */
25487836SJohn.Forte@Sun.COM static int
iPsInit(scf_handle_t ** handle,scf_service_t ** service)25497836SJohn.Forte@Sun.COM iPsInit(scf_handle_t **handle, scf_service_t **service)
25507836SJohn.Forte@Sun.COM {
25517836SJohn.Forte@Sun.COM 	scf_scope_t	*scope = NULL;
25527836SJohn.Forte@Sun.COM 	uint64_t version;
25537836SJohn.Forte@Sun.COM 	int ret;
25547836SJohn.Forte@Sun.COM 
25557836SJohn.Forte@Sun.COM 	assert(handle != NULL && service != NULL);
25567836SJohn.Forte@Sun.COM 
25577836SJohn.Forte@Sun.COM 	if ((*handle = scf_handle_create(SCF_VERSION)) == NULL) {
25587836SJohn.Forte@Sun.COM 		syslog(LOG_ERR, "scf_handle_create failed - %s",
25597836SJohn.Forte@Sun.COM 		    scf_strerror(scf_error()));
25607836SJohn.Forte@Sun.COM 		ret = STMF_PS_ERROR;
25617836SJohn.Forte@Sun.COM 		goto err;
25627836SJohn.Forte@Sun.COM 	}
25637836SJohn.Forte@Sun.COM 
25647836SJohn.Forte@Sun.COM 	if (scf_handle_bind(*handle) == -1) {
25657836SJohn.Forte@Sun.COM 		syslog(LOG_ERR, "scf_handle_bind failed - %s",
25667836SJohn.Forte@Sun.COM 		    scf_strerror(scf_error()));
25677836SJohn.Forte@Sun.COM 		ret = STMF_PS_ERROR;
25687836SJohn.Forte@Sun.COM 		goto err;
25697836SJohn.Forte@Sun.COM 	}
25707836SJohn.Forte@Sun.COM 
25717836SJohn.Forte@Sun.COM 	if ((*service = scf_service_create(*handle)) == NULL) {
25727836SJohn.Forte@Sun.COM 		syslog(LOG_ERR, "scf_service_create failed - %s",
25737836SJohn.Forte@Sun.COM 		    scf_strerror(scf_error()));
25747836SJohn.Forte@Sun.COM 		ret = STMF_PS_ERROR;
25757836SJohn.Forte@Sun.COM 		goto err;
25767836SJohn.Forte@Sun.COM 	}
25777836SJohn.Forte@Sun.COM 
25787836SJohn.Forte@Sun.COM 	if ((scope = scf_scope_create(*handle)) == NULL) {
25797836SJohn.Forte@Sun.COM 		syslog(LOG_ERR, "scf_scope_create failed - %s",
25807836SJohn.Forte@Sun.COM 		    scf_strerror(scf_error()));
25817836SJohn.Forte@Sun.COM 		ret = STMF_PS_ERROR;
25827836SJohn.Forte@Sun.COM 		goto err;
25837836SJohn.Forte@Sun.COM 	}
25847836SJohn.Forte@Sun.COM 
25857836SJohn.Forte@Sun.COM 	if (scf_handle_get_scope(*handle, SCF_SCOPE_LOCAL, scope) == -1) {
25867836SJohn.Forte@Sun.COM 		syslog(LOG_ERR, "scf_handle_get_scope failed - %s",
25877836SJohn.Forte@Sun.COM 		    scf_strerror(scf_error()));
25887836SJohn.Forte@Sun.COM 		ret = STMF_PS_ERROR;
25897836SJohn.Forte@Sun.COM 		goto err;
25907836SJohn.Forte@Sun.COM 	}
25917836SJohn.Forte@Sun.COM 
25927836SJohn.Forte@Sun.COM 	if (scf_scope_get_service(scope, STMF_SERVICE, *service) == -1) {
25937836SJohn.Forte@Sun.COM 		syslog(LOG_ERR, "scf_scope_get_service failed - %s",
25947836SJohn.Forte@Sun.COM 		    scf_strerror(scf_error()));
25957836SJohn.Forte@Sun.COM 		ret = STMF_PS_ERROR_SERVICE_NOT_FOUND;
25967836SJohn.Forte@Sun.COM 		goto err;
25977836SJohn.Forte@Sun.COM 	}
25987836SJohn.Forte@Sun.COM 
25997836SJohn.Forte@Sun.COM 
26007836SJohn.Forte@Sun.COM 	/*
26017836SJohn.Forte@Sun.COM 	 * Get and check the version number
26027836SJohn.Forte@Sun.COM 	 */
26037836SJohn.Forte@Sun.COM 	ret = iPsGetServiceVersion(&version, *handle, *service);
26047836SJohn.Forte@Sun.COM 	if (ret != STMF_PS_SUCCESS) {
26057836SJohn.Forte@Sun.COM 		goto err;
26067836SJohn.Forte@Sun.COM 	}
26077836SJohn.Forte@Sun.COM 
26087836SJohn.Forte@Sun.COM 	if (version != STMF_SMF_VERSION) {
26097836SJohn.Forte@Sun.COM 		ret = STMF_PS_ERROR_VERSION_MISMATCH;
26107836SJohn.Forte@Sun.COM 		goto err;
26117836SJohn.Forte@Sun.COM 	}
26127836SJohn.Forte@Sun.COM 
26137836SJohn.Forte@Sun.COM 	/* we only need destroy the scope here */
26147836SJohn.Forte@Sun.COM 	scf_scope_destroy(scope);
26157836SJohn.Forte@Sun.COM 
26167836SJohn.Forte@Sun.COM 	return (STMF_PS_SUCCESS);
26177836SJohn.Forte@Sun.COM 
26187836SJohn.Forte@Sun.COM err:
26197836SJohn.Forte@Sun.COM 	if (*handle != NULL) {
26207836SJohn.Forte@Sun.COM 		scf_handle_destroy(*handle);
26217836SJohn.Forte@Sun.COM 	}
26227836SJohn.Forte@Sun.COM 	if (*service != NULL) {
26237836SJohn.Forte@Sun.COM 		scf_service_destroy(*service);
26247836SJohn.Forte@Sun.COM 		*service = NULL;
26257836SJohn.Forte@Sun.COM 	}
26267836SJohn.Forte@Sun.COM 	if (scope != NULL) {
26277836SJohn.Forte@Sun.COM 		scf_scope_destroy(scope);
26287836SJohn.Forte@Sun.COM 	}
26297836SJohn.Forte@Sun.COM 	return (ret);
26307836SJohn.Forte@Sun.COM }
26317836SJohn.Forte@Sun.COM 
26329585STim.Szeto@Sun.COM 
26337836SJohn.Forte@Sun.COM /*
26347836SJohn.Forte@Sun.COM  * called by iPsInit only
26357836SJohn.Forte@Sun.COM  * iPsGetServiceVersion
26367836SJohn.Forte@Sun.COM  */
26377836SJohn.Forte@Sun.COM static int
iPsGetServiceVersion(uint64_t * version,scf_handle_t * handle,scf_service_t * svc)26387836SJohn.Forte@Sun.COM iPsGetServiceVersion(uint64_t *version, scf_handle_t *handle,
26397836SJohn.Forte@Sun.COM scf_service_t *svc)
26407836SJohn.Forte@Sun.COM {
26417836SJohn.Forte@Sun.COM 	scf_propertygroup_t	*pg = NULL;
26427836SJohn.Forte@Sun.COM 	scf_property_t	*prop = NULL;
26437836SJohn.Forte@Sun.COM 	scf_value_t	*value = NULL;
26447836SJohn.Forte@Sun.COM 	scf_transaction_t *tran = NULL;
26457836SJohn.Forte@Sun.COM 	scf_transaction_entry_t *entry = NULL;
26467836SJohn.Forte@Sun.COM 	int ret = STMF_PS_SUCCESS;
26477836SJohn.Forte@Sun.COM 	int commitRet;
26487836SJohn.Forte@Sun.COM 
26497836SJohn.Forte@Sun.COM 	if (((pg = scf_pg_create(handle)) == NULL) ||
26507836SJohn.Forte@Sun.COM 	    ((prop = scf_property_create(handle)) == NULL) ||
26517836SJohn.Forte@Sun.COM 	    ((entry = scf_entry_create(handle)) == NULL) ||
26527836SJohn.Forte@Sun.COM 	    ((tran = scf_transaction_create(handle)) == NULL) ||
26537836SJohn.Forte@Sun.COM 	    ((value = scf_value_create(handle)) == NULL)) {
26547836SJohn.Forte@Sun.COM 		syslog(LOG_ERR, "scf alloc resource failed - %s",
26557836SJohn.Forte@Sun.COM 		    scf_strerror(scf_error()));
26567836SJohn.Forte@Sun.COM 		ret = STMF_PS_ERROR;
26577836SJohn.Forte@Sun.COM 		goto out;
26587836SJohn.Forte@Sun.COM 	}
26597836SJohn.Forte@Sun.COM 
26607836SJohn.Forte@Sun.COM 	*version = STMF_SMF_VERSION;
26617836SJohn.Forte@Sun.COM 
26627836SJohn.Forte@Sun.COM 	/*
26637836SJohn.Forte@Sun.COM 	 * get stmf data property group
26647836SJohn.Forte@Sun.COM 	 */
26657836SJohn.Forte@Sun.COM 	if (scf_service_get_pg(svc, STMF_DATA_GROUP, pg) == -1) {
26667836SJohn.Forte@Sun.COM 		if (scf_error() == SCF_ERROR_NOT_FOUND) {
26677836SJohn.Forte@Sun.COM 			ret = STMF_PS_ERROR_NOT_FOUND;
26687836SJohn.Forte@Sun.COM 		} else {
266911909SPeter.Gill@Sun.COM 			syslog(LOG_ERR, "get pg %s failed - %s",
267011909SPeter.Gill@Sun.COM 			    STMF_DATA_GROUP, scf_strerror(scf_error()));
26717836SJohn.Forte@Sun.COM 			ret = STMF_PS_ERROR;
26727836SJohn.Forte@Sun.COM 			goto out;
26737836SJohn.Forte@Sun.COM 		}
26747836SJohn.Forte@Sun.COM 	}
26757836SJohn.Forte@Sun.COM 
26767836SJohn.Forte@Sun.COM 	/* create the group */
26777836SJohn.Forte@Sun.COM 	if (ret == STMF_PS_ERROR_NOT_FOUND) {
26787836SJohn.Forte@Sun.COM 		/*
26797836SJohn.Forte@Sun.COM 		 * create the property group.
26807836SJohn.Forte@Sun.COM 		 */
26817836SJohn.Forte@Sun.COM 		if (scf_service_add_pg(svc, STMF_DATA_GROUP,
26827836SJohn.Forte@Sun.COM 		    SCF_GROUP_APPLICATION, 0, pg) == -1) {
268311909SPeter.Gill@Sun.COM 			syslog(LOG_ERR, "add pg %s failed - %s",
268411909SPeter.Gill@Sun.COM 			    STMF_DATA_GROUP, scf_strerror(scf_error()));
26857836SJohn.Forte@Sun.COM 			ret = STMF_PS_ERROR;
26867836SJohn.Forte@Sun.COM 			goto out;
26877836SJohn.Forte@Sun.COM 		}
26887836SJohn.Forte@Sun.COM 		/* reset return value */
26897836SJohn.Forte@Sun.COM 		ret = STMF_PS_SUCCESS;
26907836SJohn.Forte@Sun.COM 	}
26917836SJohn.Forte@Sun.COM 
26927836SJohn.Forte@Sun.COM 	/* find version property */
26937836SJohn.Forte@Sun.COM 	/*
26947836SJohn.Forte@Sun.COM 	 * Get the version property
26957836SJohn.Forte@Sun.COM 	 */
26967836SJohn.Forte@Sun.COM 	if (scf_pg_get_property(pg, STMF_VERSION_NAME, prop) == -1) {
26977836SJohn.Forte@Sun.COM 		if (scf_error() == SCF_ERROR_NOT_FOUND) {
26987836SJohn.Forte@Sun.COM 			ret = STMF_PS_ERROR_NOT_FOUND;
26997836SJohn.Forte@Sun.COM 		} else {
270011909SPeter.Gill@Sun.COM 			syslog(LOG_ERR, "get property %s/%s failed - %s",
270111909SPeter.Gill@Sun.COM 			    STMF_DATA_GROUP, STMF_VERSION_NAME,
27027836SJohn.Forte@Sun.COM 			    scf_strerror(scf_error()));
27037836SJohn.Forte@Sun.COM 			ret = STMF_PS_ERROR;
27047836SJohn.Forte@Sun.COM 			goto out;
27057836SJohn.Forte@Sun.COM 		}
27067836SJohn.Forte@Sun.COM 	}
27077836SJohn.Forte@Sun.COM 
27087836SJohn.Forte@Sun.COM 	/* no version property found */
27097836SJohn.Forte@Sun.COM 	if (ret == STMF_PS_ERROR_NOT_FOUND) {
27107836SJohn.Forte@Sun.COM 		/*
27117836SJohn.Forte@Sun.COM 		 * If we have no version property, go ahead
27127836SJohn.Forte@Sun.COM 		 * and create it. We're obviously making an assumption
27137836SJohn.Forte@Sun.COM 		 * here that someone did not delete the existing property
27147836SJohn.Forte@Sun.COM 		 * and that this is the initial set and the initial call
27157836SJohn.Forte@Sun.COM 		 * to iPsInit.
27167836SJohn.Forte@Sun.COM 		 * If they did delete it, this will simply plant this
27177836SJohn.Forte@Sun.COM 		 * library's version on this service. That may or may not be
27187836SJohn.Forte@Sun.COM 		 * correct and we have no way of determining that.
27197836SJohn.Forte@Sun.COM 		 */
27207836SJohn.Forte@Sun.COM 		/*
27217836SJohn.Forte@Sun.COM 		 * Begin the transaction
27227836SJohn.Forte@Sun.COM 		 */
27237836SJohn.Forte@Sun.COM 		if (scf_transaction_start(tran, pg) == -1) {
272411909SPeter.Gill@Sun.COM 			syslog(LOG_ERR, "start transaction for %s failed - %s",
272511909SPeter.Gill@Sun.COM 			    STMF_DATA_GROUP, scf_strerror(scf_error()));
27267836SJohn.Forte@Sun.COM 			ret = STMF_PS_ERROR;
27277836SJohn.Forte@Sun.COM 			goto out;
27287836SJohn.Forte@Sun.COM 		}
27297836SJohn.Forte@Sun.COM 
27307836SJohn.Forte@Sun.COM 		if (scf_transaction_property_new(tran, entry,
27317836SJohn.Forte@Sun.COM 		    STMF_VERSION_NAME, SCF_TYPE_COUNT) == -1) {
27327836SJohn.Forte@Sun.COM 			syslog(LOG_ERR,
273311909SPeter.Gill@Sun.COM 			    "transaction property new %s/%s failed - %s",
273411909SPeter.Gill@Sun.COM 			    STMF_DATA_GROUP, STMF_VERSION_NAME,
27357836SJohn.Forte@Sun.COM 			    scf_strerror(scf_error()));
27367836SJohn.Forte@Sun.COM 			ret = STMF_PS_ERROR;
27377836SJohn.Forte@Sun.COM 			goto out;
27387836SJohn.Forte@Sun.COM 		}
27397836SJohn.Forte@Sun.COM 
27407836SJohn.Forte@Sun.COM 		/*
27417836SJohn.Forte@Sun.COM 		 * set the version number
27427836SJohn.Forte@Sun.COM 		 */
27437836SJohn.Forte@Sun.COM 		scf_value_set_count(value, *version);
27447836SJohn.Forte@Sun.COM 
27457836SJohn.Forte@Sun.COM 		/*
27467836SJohn.Forte@Sun.COM 		 * add the value to the transaction
27477836SJohn.Forte@Sun.COM 		 */
27487836SJohn.Forte@Sun.COM 		if (scf_entry_add_value(entry, value) == -1) {
274911909SPeter.Gill@Sun.COM 			syslog(LOG_ERR, "add value %s/%s failed - %s",
275011909SPeter.Gill@Sun.COM 			    STMF_DATA_GROUP, STMF_VERSION_NAME,
27517836SJohn.Forte@Sun.COM 			    scf_strerror(scf_error()));
27527836SJohn.Forte@Sun.COM 			ret = STMF_PS_ERROR;
27537836SJohn.Forte@Sun.COM 			goto out;
27547836SJohn.Forte@Sun.COM 		}
27557836SJohn.Forte@Sun.COM 		if ((commitRet = scf_transaction_commit(tran)) != 1) {
275611909SPeter.Gill@Sun.COM 			syslog(LOG_ERR, "transaction commit for %s failed - %s",
275711909SPeter.Gill@Sun.COM 			    STMF_DATA_GROUP, scf_strerror(scf_error()));
27587836SJohn.Forte@Sun.COM 			if (commitRet == 0) {
27597836SJohn.Forte@Sun.COM 				ret = STMF_PS_ERROR_BUSY;
27607836SJohn.Forte@Sun.COM 			} else {
27617836SJohn.Forte@Sun.COM 				ret = STMF_PS_ERROR;
27627836SJohn.Forte@Sun.COM 			}
27637836SJohn.Forte@Sun.COM 			goto out;
27647836SJohn.Forte@Sun.COM 		}
27657836SJohn.Forte@Sun.COM 		/* reset return value */
27667836SJohn.Forte@Sun.COM 		ret = STMF_PS_SUCCESS;
27677836SJohn.Forte@Sun.COM 	} else {
27687836SJohn.Forte@Sun.COM 		/* get the version property */
27697836SJohn.Forte@Sun.COM 		if (scf_pg_get_property(pg, STMF_VERSION_NAME, prop) == -1) {
277011909SPeter.Gill@Sun.COM 			syslog(LOG_ERR, "get property %s/%s failed - %s",
277111909SPeter.Gill@Sun.COM 			    STMF_DATA_GROUP, STMF_VERSION_NAME,
27727836SJohn.Forte@Sun.COM 			    scf_strerror(scf_error()));
27737836SJohn.Forte@Sun.COM 			ret = STMF_PS_ERROR;
27747836SJohn.Forte@Sun.COM 			goto out;
27757836SJohn.Forte@Sun.COM 		}
27767836SJohn.Forte@Sun.COM 
27777836SJohn.Forte@Sun.COM 		if (scf_property_get_value(prop, value) == -1) {
277811909SPeter.Gill@Sun.COM 			syslog(LOG_ERR, "get property value %s/%s failed - %s",
277911909SPeter.Gill@Sun.COM 			    STMF_DATA_GROUP, STMF_VERSION_NAME,
27807836SJohn.Forte@Sun.COM 			    scf_strerror(scf_error()));
27817836SJohn.Forte@Sun.COM 			ret = STMF_PS_ERROR;
27827836SJohn.Forte@Sun.COM 			goto out;
27837836SJohn.Forte@Sun.COM 		}
27847836SJohn.Forte@Sun.COM 
27857836SJohn.Forte@Sun.COM 		/*
27867836SJohn.Forte@Sun.COM 		 * Get the actual value of the view entry count property
27877836SJohn.Forte@Sun.COM 		 */
27887836SJohn.Forte@Sun.COM 		if (scf_value_get_count(value, version) == -1) {
278911909SPeter.Gill@Sun.COM 			syslog(LOG_ERR, "get count value %s/%s failed - %s",
279011909SPeter.Gill@Sun.COM 			    STMF_DATA_GROUP, STMF_VERSION_NAME,
27917836SJohn.Forte@Sun.COM 			    scf_strerror(scf_error()));
27927836SJohn.Forte@Sun.COM 			ret = STMF_PS_ERROR;
27937836SJohn.Forte@Sun.COM 			goto out;
27947836SJohn.Forte@Sun.COM 		}
27957836SJohn.Forte@Sun.COM 	}
27967836SJohn.Forte@Sun.COM 
27977836SJohn.Forte@Sun.COM out:
27987836SJohn.Forte@Sun.COM 	/*
27997836SJohn.Forte@Sun.COM 	 * Free resources.
28007836SJohn.Forte@Sun.COM 	 * handle and svc should not be free'd here. They're
28017836SJohn.Forte@Sun.COM 	 * free'd elsewhere
28027836SJohn.Forte@Sun.COM 	 */
28037836SJohn.Forte@Sun.COM 	if (pg != NULL) {
28047836SJohn.Forte@Sun.COM 		scf_pg_destroy(pg);
28057836SJohn.Forte@Sun.COM 	}
28067836SJohn.Forte@Sun.COM 	if (prop != NULL) {
28077836SJohn.Forte@Sun.COM 		scf_property_destroy(prop);
28087836SJohn.Forte@Sun.COM 	}
28097836SJohn.Forte@Sun.COM 	if (entry != NULL) {
28107836SJohn.Forte@Sun.COM 		scf_entry_destroy(entry);
28117836SJohn.Forte@Sun.COM 	}
28127836SJohn.Forte@Sun.COM 	if (tran != NULL) {
28137836SJohn.Forte@Sun.COM 		scf_transaction_destroy(tran);
28147836SJohn.Forte@Sun.COM 	}
28157836SJohn.Forte@Sun.COM 	if (value != NULL) {
28167836SJohn.Forte@Sun.COM 		scf_value_destroy(value);
28177836SJohn.Forte@Sun.COM 	}
28187836SJohn.Forte@Sun.COM 	return (ret);
28197836SJohn.Forte@Sun.COM }
28207836SJohn.Forte@Sun.COM 
28217836SJohn.Forte@Sun.COM 
28227836SJohn.Forte@Sun.COM 
28237836SJohn.Forte@Sun.COM /*
28247836SJohn.Forte@Sun.COM  * iPsGetActualGroupName
28257836SJohn.Forte@Sun.COM  *
28267836SJohn.Forte@Sun.COM  * pgName - Property group name
28277836SJohn.Forte@Sun.COM  * groupName - requested group name
28287836SJohn.Forte@Sun.COM  * actualName - actual group name to reference (len must be >= MAXNAMELEN)
28297836SJohn.Forte@Sun.COM  *
28307836SJohn.Forte@Sun.COM  * returns:
28317836SJohn.Forte@Sun.COM  *  STMF_PS_SUCCESS on success
28327836SJohn.Forte@Sun.COM  *  STMF_PS_ERROR_* on failure
28337836SJohn.Forte@Sun.COM  */
28347836SJohn.Forte@Sun.COM static int
iPsGetActualGroupName(char * pgName,char * groupName,char * actualName)28357836SJohn.Forte@Sun.COM iPsGetActualGroupName(char *pgName, char *groupName, char *actualName)
28367836SJohn.Forte@Sun.COM {
28377836SJohn.Forte@Sun.COM 	scf_handle_t	*handle = NULL;
28387836SJohn.Forte@Sun.COM 	scf_service_t	*svc = NULL;
28397836SJohn.Forte@Sun.COM 	scf_propertygroup_t	*pg = NULL;
28407836SJohn.Forte@Sun.COM 	scf_property_t	*prop = NULL;
28417836SJohn.Forte@Sun.COM 	scf_iter_t	*propIter = NULL;
28427836SJohn.Forte@Sun.COM 	scf_value_t	*value = NULL;
28437836SJohn.Forte@Sun.COM 	char buf[MAXNAMELEN];
28447836SJohn.Forte@Sun.COM 	int ret;
28457836SJohn.Forte@Sun.COM 
28467836SJohn.Forte@Sun.COM 	ret = iPsInit(&handle, &svc);
28477836SJohn.Forte@Sun.COM 	if (ret != STMF_PS_SUCCESS) {
28487836SJohn.Forte@Sun.COM 		goto out;
28497836SJohn.Forte@Sun.COM 	}
28507836SJohn.Forte@Sun.COM 
28517836SJohn.Forte@Sun.COM 	/*
28527836SJohn.Forte@Sun.COM 	 * Allocate scf resources
28537836SJohn.Forte@Sun.COM 	 */
28547836SJohn.Forte@Sun.COM 	if (((pg = scf_pg_create(handle)) == NULL) ||
28557836SJohn.Forte@Sun.COM 	    ((prop = scf_property_create(handle)) == NULL) ||
28567836SJohn.Forte@Sun.COM 	    ((propIter = scf_iter_create(handle)) == NULL) ||
28577836SJohn.Forte@Sun.COM 	    ((value = scf_value_create(handle)) == NULL)) {
28587836SJohn.Forte@Sun.COM 		syslog(LOG_ERR, "scf alloc resource failed - %s",
28597836SJohn.Forte@Sun.COM 		    scf_strerror(scf_error()));
28607836SJohn.Forte@Sun.COM 		ret = STMF_PS_ERROR;
28617836SJohn.Forte@Sun.COM 		goto out;
28627836SJohn.Forte@Sun.COM 	}
28637836SJohn.Forte@Sun.COM 
28647836SJohn.Forte@Sun.COM 	/*
28657836SJohn.Forte@Sun.COM 	 * get group list property group
28667836SJohn.Forte@Sun.COM 	 */
28677836SJohn.Forte@Sun.COM 	if (scf_service_get_pg(svc, pgName, pg) == -1) {
28687836SJohn.Forte@Sun.COM 		if (scf_error() == SCF_ERROR_NOT_FOUND) {
28697836SJohn.Forte@Sun.COM 			ret = STMF_PS_ERROR_GROUP_NOT_FOUND;
28707836SJohn.Forte@Sun.COM 		} else {
287111909SPeter.Gill@Sun.COM 			syslog(LOG_ERR, "get pg %s failed - %s",
287211909SPeter.Gill@Sun.COM 			    pgName, scf_strerror(scf_error()));
28737836SJohn.Forte@Sun.COM 			ret = STMF_PS_ERROR;
28747836SJohn.Forte@Sun.COM 		}
28757836SJohn.Forte@Sun.COM 		goto out;
28767836SJohn.Forte@Sun.COM 	}
28777836SJohn.Forte@Sun.COM 
28787836SJohn.Forte@Sun.COM 	/*
28797836SJohn.Forte@Sun.COM 	 * propIter is the iterator handle
28807836SJohn.Forte@Sun.COM 	 */
28817836SJohn.Forte@Sun.COM 	if (scf_iter_pg_properties(propIter, pg) == -1) {
288211909SPeter.Gill@Sun.COM 		syslog(LOG_ERR, "iter properties for %s failed - %s",
288311909SPeter.Gill@Sun.COM 		    pgName, scf_strerror(scf_error()));
28847836SJohn.Forte@Sun.COM 		ret = STMF_PS_ERROR;
28857836SJohn.Forte@Sun.COM 		goto out;
28867836SJohn.Forte@Sun.COM 	}
28877836SJohn.Forte@Sun.COM 
28887836SJohn.Forte@Sun.COM 	/*
28897836SJohn.Forte@Sun.COM 	 * Iterate through group properties searching for the requested
28907836SJohn.Forte@Sun.COM 	 * group name. When we find it, we need to get the property name
28917836SJohn.Forte@Sun.COM 	 * since it refers to the actual group name.
28927836SJohn.Forte@Sun.COM 	 */
28937836SJohn.Forte@Sun.COM 
28947836SJohn.Forte@Sun.COM 	/* initialize to not found */
28957836SJohn.Forte@Sun.COM 	ret = STMF_PS_ERROR_GROUP_NOT_FOUND;
28967836SJohn.Forte@Sun.COM 	while (scf_iter_next_property(propIter, prop) == 1) {
28977836SJohn.Forte@Sun.COM 		if (scf_property_get_name(prop, actualName, MAXNAMELEN) == -1) {
289811909SPeter.Gill@Sun.COM 			syslog(LOG_ERR, "get name from %s iter failed - %s",
289911909SPeter.Gill@Sun.COM 			    pgName, scf_strerror(scf_error()));
29007836SJohn.Forte@Sun.COM 			ret = STMF_PS_ERROR;
29017836SJohn.Forte@Sun.COM 			break;
29027836SJohn.Forte@Sun.COM 		}
29037836SJohn.Forte@Sun.COM 		/*
29047836SJohn.Forte@Sun.COM 		 * Skip over non-member list properties
29057836SJohn.Forte@Sun.COM 		 */
29067836SJohn.Forte@Sun.COM 		if (strstr(actualName, STMF_MEMBER_LIST_SUFFIX)) {
29077836SJohn.Forte@Sun.COM 			continue;
29087836SJohn.Forte@Sun.COM 		}
29097836SJohn.Forte@Sun.COM 		if (scf_property_get_value(prop, value) == -1) {
291011909SPeter.Gill@Sun.COM 			syslog(LOG_ERR, "get property value %s/%s failed - %s",
291111909SPeter.Gill@Sun.COM 			    pgName, actualName, scf_strerror(scf_error()));
29127836SJohn.Forte@Sun.COM 			ret = STMF_PS_ERROR;
29137836SJohn.Forte@Sun.COM 			break;
29147836SJohn.Forte@Sun.COM 		}
29157836SJohn.Forte@Sun.COM 		if (scf_value_get_ustring(value, buf, sizeof (buf)) == -1) {
291611909SPeter.Gill@Sun.COM 			syslog(LOG_ERR, "get ustring %s/%s failed - %s",
291711909SPeter.Gill@Sun.COM 			    pgName, actualName, scf_strerror(scf_error()));
29187836SJohn.Forte@Sun.COM 			ret = STMF_PS_ERROR;
29197836SJohn.Forte@Sun.COM 			break;
29207836SJohn.Forte@Sun.COM 		}
29217836SJohn.Forte@Sun.COM 
29227836SJohn.Forte@Sun.COM 		/*
29237836SJohn.Forte@Sun.COM 		 * When we find a match, set success and break
29247836SJohn.Forte@Sun.COM 		 */
29257836SJohn.Forte@Sun.COM 		if ((strlen(buf) == strlen(groupName)) &&
29267836SJohn.Forte@Sun.COM 		    bcmp(buf, groupName, strlen(buf)) == 0) {
29277836SJohn.Forte@Sun.COM 			ret = STMF_PS_SUCCESS;
29287836SJohn.Forte@Sun.COM 			break;
29297836SJohn.Forte@Sun.COM 		}
29307836SJohn.Forte@Sun.COM 	}
29317836SJohn.Forte@Sun.COM 
29327836SJohn.Forte@Sun.COM 	/*
29337836SJohn.Forte@Sun.COM 	 * if we didn't find it, ret is set to STMF_PS_ERROR_GROUP_NOT_FOUND
29347836SJohn.Forte@Sun.COM 	 */
29357836SJohn.Forte@Sun.COM 
29367836SJohn.Forte@Sun.COM out:
29377836SJohn.Forte@Sun.COM 	/*
29387836SJohn.Forte@Sun.COM 	 * Free resources
29397836SJohn.Forte@Sun.COM 	 */
29407836SJohn.Forte@Sun.COM 	if (handle != NULL) {
29417836SJohn.Forte@Sun.COM 		scf_handle_destroy(handle);
29427836SJohn.Forte@Sun.COM 	}
29437836SJohn.Forte@Sun.COM 	if (svc != NULL) {
29447836SJohn.Forte@Sun.COM 		scf_service_destroy(svc);
29457836SJohn.Forte@Sun.COM 	}
29467836SJohn.Forte@Sun.COM 	if (pg != NULL) {
29477836SJohn.Forte@Sun.COM 		scf_pg_destroy(pg);
29487836SJohn.Forte@Sun.COM 	}
29497836SJohn.Forte@Sun.COM 	if (propIter != NULL) {
29507836SJohn.Forte@Sun.COM 		scf_iter_destroy(propIter);
29517836SJohn.Forte@Sun.COM 	}
29527836SJohn.Forte@Sun.COM 	if (prop != NULL) {
29537836SJohn.Forte@Sun.COM 		scf_property_destroy(prop);
29547836SJohn.Forte@Sun.COM 	}
29557836SJohn.Forte@Sun.COM 	if (value != NULL) {
29567836SJohn.Forte@Sun.COM 		scf_value_destroy(value);
29577836SJohn.Forte@Sun.COM 	}
29587836SJohn.Forte@Sun.COM 
29597836SJohn.Forte@Sun.COM 	return (ret);
29607836SJohn.Forte@Sun.COM }
29617836SJohn.Forte@Sun.COM 
29627836SJohn.Forte@Sun.COM /*
29637836SJohn.Forte@Sun.COM  * psAddHostGroupMember
29647836SJohn.Forte@Sun.COM  *
29657836SJohn.Forte@Sun.COM  * Add a host group member to a host group,
29667836SJohn.Forte@Sun.COM  *
29677836SJohn.Forte@Sun.COM  * Input: groupName - name of group to which the member is added
29687836SJohn.Forte@Sun.COM  *        memberName - name of group member to add
29697836SJohn.Forte@Sun.COM  */
29707836SJohn.Forte@Sun.COM int
psAddHostGroupMember(char * groupName,char * memberName)29717836SJohn.Forte@Sun.COM psAddHostGroupMember(char *groupName, char *memberName)
29727836SJohn.Forte@Sun.COM {
29737836SJohn.Forte@Sun.COM 	int ret;
29747836SJohn.Forte@Sun.COM 	char groupPropListName[MAXNAMELEN];
29757836SJohn.Forte@Sun.COM 	char groupPropName[MAXNAMELEN];
29767836SJohn.Forte@Sun.COM 
29777836SJohn.Forte@Sun.COM 	ret = iPsGetActualGroupName(STMF_HOST_GROUPS, groupName,
29787836SJohn.Forte@Sun.COM 	    groupPropName);
29797836SJohn.Forte@Sun.COM 	if (ret != STMF_PS_SUCCESS) {
29807836SJohn.Forte@Sun.COM 		return (ret);
29817836SJohn.Forte@Sun.COM 	}
29827836SJohn.Forte@Sun.COM 
29837836SJohn.Forte@Sun.COM 	if (snprintf(groupPropListName, sizeof (groupPropListName),
29847836SJohn.Forte@Sun.COM 	    "%s-%s", groupPropName, STMF_MEMBER_LIST_SUFFIX) >
29857836SJohn.Forte@Sun.COM 	    sizeof (groupPropListName)) {
29867836SJohn.Forte@Sun.COM 		syslog(LOG_ERR, "buffer overflow on property name %s",
29877836SJohn.Forte@Sun.COM 		    groupPropName);
29887836SJohn.Forte@Sun.COM 		return (STMF_PS_ERROR);
29897836SJohn.Forte@Sun.COM 	}
29907836SJohn.Forte@Sun.COM 
29917836SJohn.Forte@Sun.COM 	return (iPsAddRemoveGroupMember(STMF_HOST_GROUPS, groupPropListName,
29927836SJohn.Forte@Sun.COM 	    memberName, ADD));
29937836SJohn.Forte@Sun.COM }
29947836SJohn.Forte@Sun.COM 
29957836SJohn.Forte@Sun.COM /*
29967836SJohn.Forte@Sun.COM  * psAddTargetGroupMember
29977836SJohn.Forte@Sun.COM  *
29987836SJohn.Forte@Sun.COM  * Add a target port group member to a target group
29997836SJohn.Forte@Sun.COM  *
30007836SJohn.Forte@Sun.COM  * Input: groupName - name of group to which the member is added
30017836SJohn.Forte@Sun.COM  *        memberName - name of group member to add. Must be nul terminated.
30027836SJohn.Forte@Sun.COM  */
30037836SJohn.Forte@Sun.COM int
psAddTargetGroupMember(char * groupName,char * memberName)30047836SJohn.Forte@Sun.COM psAddTargetGroupMember(char *groupName, char *memberName)
30057836SJohn.Forte@Sun.COM {
30067836SJohn.Forte@Sun.COM 	int ret;
30077836SJohn.Forte@Sun.COM 	char groupPropListName[MAXNAMELEN];
30087836SJohn.Forte@Sun.COM 	char groupPropName[MAXNAMELEN];
30097836SJohn.Forte@Sun.COM 
30107836SJohn.Forte@Sun.COM 	ret = iPsGetActualGroupName(STMF_TARGET_GROUPS, groupName,
30117836SJohn.Forte@Sun.COM 	    groupPropName);
30127836SJohn.Forte@Sun.COM 	if (ret != STMF_PS_SUCCESS) {
30137836SJohn.Forte@Sun.COM 		return (ret);
30147836SJohn.Forte@Sun.COM 	}
30157836SJohn.Forte@Sun.COM 
30167836SJohn.Forte@Sun.COM 	if (snprintf(groupPropListName, sizeof (groupPropListName),
30177836SJohn.Forte@Sun.COM 	    "%s-%s", groupPropName, STMF_MEMBER_LIST_SUFFIX) >
30187836SJohn.Forte@Sun.COM 	    sizeof (groupPropListName)) {
30197836SJohn.Forte@Sun.COM 		syslog(LOG_ERR, "buffer overflow on property name %s",
30207836SJohn.Forte@Sun.COM 		    groupPropName);
30217836SJohn.Forte@Sun.COM 		return (STMF_PS_ERROR);
30227836SJohn.Forte@Sun.COM 	}
30237836SJohn.Forte@Sun.COM 
30247836SJohn.Forte@Sun.COM 	return (iPsAddRemoveGroupMember(STMF_TARGET_GROUPS, groupPropListName,
30257836SJohn.Forte@Sun.COM 	    memberName, ADD));
30267836SJohn.Forte@Sun.COM }
30277836SJohn.Forte@Sun.COM 
30287836SJohn.Forte@Sun.COM 
30297836SJohn.Forte@Sun.COM /*
30307836SJohn.Forte@Sun.COM  * psAddViewEntry
30317836SJohn.Forte@Sun.COM  *
30327836SJohn.Forte@Sun.COM  * luGuid - logical unit identifier
30337836SJohn.Forte@Sun.COM  * viewEntry - pointer to viewEntry allocated by the caller that contains
30347836SJohn.Forte@Sun.COM  *             the values to set for this view entry
30357836SJohn.Forte@Sun.COM  *
30367836SJohn.Forte@Sun.COM  * returns:
30377836SJohn.Forte@Sun.COM  *  STMF_PS_SUCCESS on success
30387836SJohn.Forte@Sun.COM  *  STMF_PS_ERROR_* on failure
30397836SJohn.Forte@Sun.COM  */
30407836SJohn.Forte@Sun.COM int
psAddViewEntry(stmfGuid * lu,stmfViewEntry * viewEntry)30417836SJohn.Forte@Sun.COM psAddViewEntry(stmfGuid *lu, stmfViewEntry *viewEntry)
30427836SJohn.Forte@Sun.COM {
30437836SJohn.Forte@Sun.COM 	scf_handle_t	*handle = NULL;
30447836SJohn.Forte@Sun.COM 	scf_service_t	*svc = NULL;
30457836SJohn.Forte@Sun.COM 	scf_propertygroup_t	*pg = NULL;
30467836SJohn.Forte@Sun.COM 	char guidAsciiBuf[33]; /* size of ascii hex 16 byte guid with NULL */
30477836SJohn.Forte@Sun.COM 	char viewEntryPgName[VIEW_ENTRY_PG_SIZE];
30487836SJohn.Forte@Sun.COM 	char scfLuPgName[LOGICAL_UNIT_PG_SIZE];
30497836SJohn.Forte@Sun.COM 	int ret = STMF_PS_SUCCESS;
30507836SJohn.Forte@Sun.COM 	sigset_t sigmaskRestore;
30517836SJohn.Forte@Sun.COM 
30527836SJohn.Forte@Sun.COM 	/* grab the signal hold lock */
30537836SJohn.Forte@Sun.COM 	(void) pthread_mutex_lock(&sigSetLock);
30547836SJohn.Forte@Sun.COM 
30557836SJohn.Forte@Sun.COM 	/*
30567836SJohn.Forte@Sun.COM 	 * hold signals until we're done
30577836SJohn.Forte@Sun.COM 	 */
30587836SJohn.Forte@Sun.COM 	if (holdSignal(&sigmaskRestore) != 0) {
30597836SJohn.Forte@Sun.COM 		(void) pthread_mutex_unlock(&sigSetLock);
30607836SJohn.Forte@Sun.COM 		return (STMF_PS_ERROR);
30617836SJohn.Forte@Sun.COM 	}
30627836SJohn.Forte@Sun.COM 
30637836SJohn.Forte@Sun.COM 	ret = iPsInit(&handle, &svc);
30647836SJohn.Forte@Sun.COM 	if (ret != STMF_PS_SUCCESS) {
30657836SJohn.Forte@Sun.COM 		goto out;
30667836SJohn.Forte@Sun.COM 	}
30677836SJohn.Forte@Sun.COM 
30687836SJohn.Forte@Sun.COM 	pg = scf_pg_create(handle);
30697836SJohn.Forte@Sun.COM 	if (pg == NULL) {
30707836SJohn.Forte@Sun.COM 		syslog(LOG_ERR, "scf pg alloc failed - %s",
30717836SJohn.Forte@Sun.COM 		    scf_strerror(scf_error()));
30727836SJohn.Forte@Sun.COM 		ret = STMF_PS_ERROR;
30737836SJohn.Forte@Sun.COM 		goto out;
30747836SJohn.Forte@Sun.COM 	}
30757836SJohn.Forte@Sun.COM 
30767836SJohn.Forte@Sun.COM 	/* Convert to ASCII uppercase hexadecimal string */
30777836SJohn.Forte@Sun.COM 	(void) snprintf(guidAsciiBuf, sizeof (guidAsciiBuf),
30787836SJohn.Forte@Sun.COM 	    "%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X",
30797836SJohn.Forte@Sun.COM 	    lu->guid[0], lu->guid[1], lu->guid[2], lu->guid[3], lu->guid[4],
30807836SJohn.Forte@Sun.COM 	    lu->guid[5], lu->guid[6], lu->guid[7], lu->guid[8], lu->guid[9],
30817836SJohn.Forte@Sun.COM 	    lu->guid[10], lu->guid[11], lu->guid[12], lu->guid[13],
30827836SJohn.Forte@Sun.COM 	    lu->guid[14], lu->guid[15]);
30837836SJohn.Forte@Sun.COM 
30847836SJohn.Forte@Sun.COM 	(void) snprintf(scfLuPgName, sizeof (scfLuPgName), "%s-%s",
30857836SJohn.Forte@Sun.COM 	    STMF_LU_PREFIX, guidAsciiBuf);
30867836SJohn.Forte@Sun.COM 
30877836SJohn.Forte@Sun.COM 	bzero(viewEntryPgName, sizeof (viewEntryPgName));
30887836SJohn.Forte@Sun.COM 	/*
30897836SJohn.Forte@Sun.COM 	 * Format of view entry property group name:
30907836SJohn.Forte@Sun.COM 	 *	VE-<view_entry_name>-<lu_name>
30917836SJohn.Forte@Sun.COM 	 */
30927836SJohn.Forte@Sun.COM 	(void) snprintf(viewEntryPgName, sizeof (viewEntryPgName),
30937836SJohn.Forte@Sun.COM 	    "%s-%d-%s", STMF_VE_PREFIX, viewEntry->veIndex, guidAsciiBuf);
30947836SJohn.Forte@Sun.COM 
30957836SJohn.Forte@Sun.COM 	ret = iPsAddViewEntry(scfLuPgName, viewEntryPgName, viewEntry);
30967836SJohn.Forte@Sun.COM 
30977836SJohn.Forte@Sun.COM out:
30987836SJohn.Forte@Sun.COM 	/*
30997836SJohn.Forte@Sun.COM 	 * Okay, we're done. Release the signals
31007836SJohn.Forte@Sun.COM 	 */
31017836SJohn.Forte@Sun.COM 	if (releaseSignal(&sigmaskRestore) != 0) {
31027836SJohn.Forte@Sun.COM 		/*
31037836SJohn.Forte@Sun.COM 		 * Don't set this as an STMF_PS_ERROR_*. We succeeded
31047836SJohn.Forte@Sun.COM 		 * the requested operation. But we do need to log it.
31057836SJohn.Forte@Sun.COM 		 */
31067836SJohn.Forte@Sun.COM 		syslog(LOG_ERR, "Unable to release one or more signals - %s",
31077836SJohn.Forte@Sun.COM 		    strerror(errno));
31087836SJohn.Forte@Sun.COM 	}
31097836SJohn.Forte@Sun.COM 
31107836SJohn.Forte@Sun.COM 	/*
31117836SJohn.Forte@Sun.COM 	 * Free resources
31127836SJohn.Forte@Sun.COM 	 */
31137836SJohn.Forte@Sun.COM 	if (handle != NULL) {
31147836SJohn.Forte@Sun.COM 		scf_handle_destroy(handle);
31157836SJohn.Forte@Sun.COM 	}
31167836SJohn.Forte@Sun.COM 	if (svc != NULL) {
31177836SJohn.Forte@Sun.COM 		scf_service_destroy(svc);
31187836SJohn.Forte@Sun.COM 	}
31197836SJohn.Forte@Sun.COM 	if (pg != NULL) {
31207836SJohn.Forte@Sun.COM 		scf_pg_destroy(pg);
31217836SJohn.Forte@Sun.COM 	}
31227836SJohn.Forte@Sun.COM 
31237836SJohn.Forte@Sun.COM 	/* release the signal hold lock */
31247836SJohn.Forte@Sun.COM 	(void) pthread_mutex_unlock(&sigSetLock);
31257836SJohn.Forte@Sun.COM 
31267836SJohn.Forte@Sun.COM 	return (ret);
31277836SJohn.Forte@Sun.COM }
31287836SJohn.Forte@Sun.COM 
31297836SJohn.Forte@Sun.COM /*
31307836SJohn.Forte@Sun.COM  * psCheckService
31317836SJohn.Forte@Sun.COM  *
31327836SJohn.Forte@Sun.COM  * Purpose: Checks whether service exists
31337836SJohn.Forte@Sun.COM  *
31347836SJohn.Forte@Sun.COM  */
31357836SJohn.Forte@Sun.COM int
psCheckService()31367836SJohn.Forte@Sun.COM psCheckService()
31377836SJohn.Forte@Sun.COM {
31387836SJohn.Forte@Sun.COM 	int ret;
31397836SJohn.Forte@Sun.COM 	scf_handle_t	*handle = NULL;
31407836SJohn.Forte@Sun.COM 	scf_service_t	*svc = NULL;
31417836SJohn.Forte@Sun.COM 
31427836SJohn.Forte@Sun.COM 	ret = iPsInit(&handle, &svc);
31437836SJohn.Forte@Sun.COM 
31447836SJohn.Forte@Sun.COM 	/*
31457836SJohn.Forte@Sun.COM 	 * Free resources
31467836SJohn.Forte@Sun.COM 	 */
31477836SJohn.Forte@Sun.COM 	if (handle != NULL) {
31487836SJohn.Forte@Sun.COM 		scf_handle_destroy(handle);
31497836SJohn.Forte@Sun.COM 	}
31507836SJohn.Forte@Sun.COM 	if (svc != NULL) {
31517836SJohn.Forte@Sun.COM 		scf_service_destroy(svc);
31527836SJohn.Forte@Sun.COM 	}
31537836SJohn.Forte@Sun.COM 
31547836SJohn.Forte@Sun.COM 	return (ret);
31557836SJohn.Forte@Sun.COM }
31567836SJohn.Forte@Sun.COM 
31577836SJohn.Forte@Sun.COM /*
31587836SJohn.Forte@Sun.COM  * psCreateHostGroup
31597836SJohn.Forte@Sun.COM  *
31607836SJohn.Forte@Sun.COM  * groupName - name of group to create
31617836SJohn.Forte@Sun.COM  *
31627836SJohn.Forte@Sun.COM  * returns:
31637836SJohn.Forte@Sun.COM  *  STMF_PS_SUCCESS on success
31647836SJohn.Forte@Sun.COM  *  STMF_PS_ERROR_* on failure
31657836SJohn.Forte@Sun.COM  */
31667836SJohn.Forte@Sun.COM int
psCreateHostGroup(char * groupName)31677836SJohn.Forte@Sun.COM psCreateHostGroup(char *groupName)
31687836SJohn.Forte@Sun.COM {
31697836SJohn.Forte@Sun.COM 	return (iPsCreateDeleteGroup(STMF_HOST_GROUPS, groupName, ADD));
31707836SJohn.Forte@Sun.COM }
31717836SJohn.Forte@Sun.COM 
31727836SJohn.Forte@Sun.COM /*
31737836SJohn.Forte@Sun.COM  * psCreateTargetGroup
31747836SJohn.Forte@Sun.COM  *
31757836SJohn.Forte@Sun.COM  * groupName - name of group to create
31767836SJohn.Forte@Sun.COM  *
31777836SJohn.Forte@Sun.COM  * returns:
31787836SJohn.Forte@Sun.COM  *  STMF_PS_SUCCESS on success
31797836SJohn.Forte@Sun.COM  *  STMF_PS_ERROR_* on failure
31807836SJohn.Forte@Sun.COM  */
31817836SJohn.Forte@Sun.COM int
psCreateTargetGroup(char * groupName)31827836SJohn.Forte@Sun.COM psCreateTargetGroup(char *groupName)
31837836SJohn.Forte@Sun.COM {
31847836SJohn.Forte@Sun.COM 	return (iPsCreateDeleteGroup(STMF_TARGET_GROUPS, groupName, ADD));
31857836SJohn.Forte@Sun.COM }
31867836SJohn.Forte@Sun.COM 
31877836SJohn.Forte@Sun.COM /*
31887836SJohn.Forte@Sun.COM  * psDeleteHostGroup
31897836SJohn.Forte@Sun.COM  *
31907836SJohn.Forte@Sun.COM  * groupName - name of group to delete
31917836SJohn.Forte@Sun.COM  *
31927836SJohn.Forte@Sun.COM  * returns:
31937836SJohn.Forte@Sun.COM  *  STMF_PS_SUCCESS on success
31947836SJohn.Forte@Sun.COM  *  STMF_PS_ERROR_* on failure
31957836SJohn.Forte@Sun.COM  */
31967836SJohn.Forte@Sun.COM int
psDeleteHostGroup(char * groupName)31977836SJohn.Forte@Sun.COM psDeleteHostGroup(char *groupName)
31987836SJohn.Forte@Sun.COM {
31997836SJohn.Forte@Sun.COM 	return (iPsCreateDeleteGroup(STMF_HOST_GROUPS, groupName, REMOVE));
32007836SJohn.Forte@Sun.COM }
32017836SJohn.Forte@Sun.COM 
32027836SJohn.Forte@Sun.COM /*
32037836SJohn.Forte@Sun.COM  * psDeleteTargetGroup
32047836SJohn.Forte@Sun.COM  *
32057836SJohn.Forte@Sun.COM  * groupName - name of group to delete
32067836SJohn.Forte@Sun.COM  *
32077836SJohn.Forte@Sun.COM  * returns:
32087836SJohn.Forte@Sun.COM  *  STMF_PS_SUCCESS on success
32097836SJohn.Forte@Sun.COM  *  STMF_PS_ERROR_* on failure
32107836SJohn.Forte@Sun.COM  */
32117836SJohn.Forte@Sun.COM int
psDeleteTargetGroup(char * groupName)32127836SJohn.Forte@Sun.COM psDeleteTargetGroup(char *groupName)
32137836SJohn.Forte@Sun.COM {
32147836SJohn.Forte@Sun.COM 	return (iPsCreateDeleteGroup(STMF_TARGET_GROUPS, groupName,
32157836SJohn.Forte@Sun.COM 	    REMOVE));
32167836SJohn.Forte@Sun.COM }
32177836SJohn.Forte@Sun.COM 
32187836SJohn.Forte@Sun.COM /*
32197836SJohn.Forte@Sun.COM  * psGetHostGroupList
32207836SJohn.Forte@Sun.COM  *
32217836SJohn.Forte@Sun.COM  * groupList - pointer to pointer to stmfGroupList. Contains the list
32227836SJohn.Forte@Sun.COM  *             of host groups on successful return.
32237836SJohn.Forte@Sun.COM  *
32247836SJohn.Forte@Sun.COM  * returns:
32257836SJohn.Forte@Sun.COM  *  STMF_PS_SUCCESS on success
32267836SJohn.Forte@Sun.COM  *  STMF_PS_ERROR_* on failure
32277836SJohn.Forte@Sun.COM  */
32287836SJohn.Forte@Sun.COM int
psGetHostGroupList(stmfGroupList ** groupList)32297836SJohn.Forte@Sun.COM psGetHostGroupList(stmfGroupList **groupList)
32307836SJohn.Forte@Sun.COM {
32317836SJohn.Forte@Sun.COM 	return (iPsGetGroupList(STMF_HOST_GROUPS, groupList));
32327836SJohn.Forte@Sun.COM }
32337836SJohn.Forte@Sun.COM 
32347836SJohn.Forte@Sun.COM /*
32357836SJohn.Forte@Sun.COM  * psGetLogicalUnitList
32367836SJohn.Forte@Sun.COM  *
32377836SJohn.Forte@Sun.COM  *
32387836SJohn.Forte@Sun.COM  */
32397836SJohn.Forte@Sun.COM int
psGetLogicalUnitList(stmfGuidList ** guidList)32407836SJohn.Forte@Sun.COM psGetLogicalUnitList(stmfGuidList **guidList)
32417836SJohn.Forte@Sun.COM {
32427836SJohn.Forte@Sun.COM 	scf_handle_t	*handle = NULL;
32437836SJohn.Forte@Sun.COM 	scf_service_t	*svc = NULL;
32447836SJohn.Forte@Sun.COM 	scf_propertygroup_t	*pg = NULL;
32457836SJohn.Forte@Sun.COM 	scf_iter_t	*pgIter = NULL;
32467836SJohn.Forte@Sun.COM 	char buf[MAXNAMELEN];
32477836SJohn.Forte@Sun.COM 	int guidCnt = 0;
32487836SJohn.Forte@Sun.COM 	int i = 0, j;
32497836SJohn.Forte@Sun.COM 	int ret = STMF_PS_SUCCESS;
32507836SJohn.Forte@Sun.COM 	unsigned int guid[sizeof (stmfGuid)];
32517836SJohn.Forte@Sun.COM 	stmfGuid outGuid;
32527836SJohn.Forte@Sun.COM 
32537836SJohn.Forte@Sun.COM 	assert(guidList != NULL);
32547836SJohn.Forte@Sun.COM 
32557836SJohn.Forte@Sun.COM 	ret = iPsInit(&handle, &svc);
32567836SJohn.Forte@Sun.COM 	if (ret != STMF_PS_SUCCESS) {
32577836SJohn.Forte@Sun.COM 		goto out;
32587836SJohn.Forte@Sun.COM 	}
32597836SJohn.Forte@Sun.COM 
32607836SJohn.Forte@Sun.COM 	/*
32617836SJohn.Forte@Sun.COM 	 * Allocate scf resources
32627836SJohn.Forte@Sun.COM 	 */
32637836SJohn.Forte@Sun.COM 	if (((pg = scf_pg_create(handle)) == NULL) ||
32647836SJohn.Forte@Sun.COM 	    ((pgIter = scf_iter_create(handle)) == NULL)) {
32657836SJohn.Forte@Sun.COM 		syslog(LOG_ERR, "scf alloc resource failed - %s",
32667836SJohn.Forte@Sun.COM 		    scf_strerror(scf_error()));
32677836SJohn.Forte@Sun.COM 		ret = STMF_PS_ERROR;
32687836SJohn.Forte@Sun.COM 		goto out;
32697836SJohn.Forte@Sun.COM 	}
32707836SJohn.Forte@Sun.COM 
32717836SJohn.Forte@Sun.COM 	/*
32727836SJohn.Forte@Sun.COM 	 * pgIter is the iterator handle
32737836SJohn.Forte@Sun.COM 	 */
32747836SJohn.Forte@Sun.COM 	if (scf_iter_service_pgs(pgIter, svc) == -1) {
32757836SJohn.Forte@Sun.COM 		syslog(LOG_ERR, "iter property groups failed - %s",
32767836SJohn.Forte@Sun.COM 		    scf_strerror(scf_error()));
32777836SJohn.Forte@Sun.COM 		ret = STMF_PS_ERROR;
32787836SJohn.Forte@Sun.COM 		goto out;
32797836SJohn.Forte@Sun.COM 	}
32807836SJohn.Forte@Sun.COM 
32817836SJohn.Forte@Sun.COM 	while (scf_iter_next_pg(pgIter, pg) == 1) {
32827836SJohn.Forte@Sun.COM 		if (scf_pg_get_name(pg, buf, sizeof (buf)) == -1) {
328311909SPeter.Gill@Sun.COM 			syslog(LOG_ERR, "get pg name failed - %s",
32847836SJohn.Forte@Sun.COM 			    scf_strerror(scf_error()));
32857836SJohn.Forte@Sun.COM 			ret = STMF_PS_ERROR;
32867836SJohn.Forte@Sun.COM 			break;
32877836SJohn.Forte@Sun.COM 		}
32887836SJohn.Forte@Sun.COM 		/*
32897836SJohn.Forte@Sun.COM 		 * Only count LU property groups
32907836SJohn.Forte@Sun.COM 		 */
32917836SJohn.Forte@Sun.COM 		if (strncmp(buf, STMF_LU_PREFIX, strlen(STMF_LU_PREFIX)) == 0) {
32927836SJohn.Forte@Sun.COM 			guidCnt++;
32937836SJohn.Forte@Sun.COM 		}
32947836SJohn.Forte@Sun.COM 	}
32957836SJohn.Forte@Sun.COM 
32967836SJohn.Forte@Sun.COM 	/*
32977836SJohn.Forte@Sun.COM 	 * pgIter is the iterator handle
32987836SJohn.Forte@Sun.COM 	 */
32997836SJohn.Forte@Sun.COM 	if (scf_iter_service_pgs(pgIter, svc) == -1) {
33007836SJohn.Forte@Sun.COM 		syslog(LOG_ERR, "iter property groups failed - %s",
33017836SJohn.Forte@Sun.COM 		    scf_strerror(scf_error()));
33027836SJohn.Forte@Sun.COM 		ret = STMF_PS_ERROR;
33037836SJohn.Forte@Sun.COM 		goto out;
33047836SJohn.Forte@Sun.COM 	}
33057836SJohn.Forte@Sun.COM 
33067836SJohn.Forte@Sun.COM 	*guidList = (stmfGuidList *)calloc(1, sizeof (stmfGuidList) +
33077836SJohn.Forte@Sun.COM 	    guidCnt * sizeof (stmfGuid));
33087836SJohn.Forte@Sun.COM 	if (*guidList == NULL) {
33097836SJohn.Forte@Sun.COM 		ret = STMF_PS_ERROR_NOMEM;
33107836SJohn.Forte@Sun.COM 		goto out;
33117836SJohn.Forte@Sun.COM 	}
33127836SJohn.Forte@Sun.COM 
33137836SJohn.Forte@Sun.COM 	/*
33147836SJohn.Forte@Sun.COM 	 * it's possible for entries to be added/removed while we're retrieving
33157836SJohn.Forte@Sun.COM 	 * the property groups. Just make sure we don't write beyond our
33167836SJohn.Forte@Sun.COM 	 * allocated buffer by checking to ensure i < guidCnt.
33177836SJohn.Forte@Sun.COM 	 */
33187836SJohn.Forte@Sun.COM 	while ((scf_iter_next_pg(pgIter, pg) == 1) && (i < guidCnt)) {
33197836SJohn.Forte@Sun.COM 		if (scf_pg_get_name(pg, buf, sizeof (buf)) == -1) {
332011909SPeter.Gill@Sun.COM 			syslog(LOG_ERR, "get pg name failed - %s",
33217836SJohn.Forte@Sun.COM 			    scf_strerror(scf_error()));
33227836SJohn.Forte@Sun.COM 			ret = STMF_PS_ERROR;
33237836SJohn.Forte@Sun.COM 			break;
33247836SJohn.Forte@Sun.COM 		}
33257836SJohn.Forte@Sun.COM 		/*
33267836SJohn.Forte@Sun.COM 		 * Only use LU property groups
33277836SJohn.Forte@Sun.COM 		 */
33287836SJohn.Forte@Sun.COM 		if (strncmp(buf, STMF_LU_PREFIX, strlen(STMF_LU_PREFIX)) != 0) {
33297836SJohn.Forte@Sun.COM 			continue;
33307836SJohn.Forte@Sun.COM 		}
33317836SJohn.Forte@Sun.COM 
33327836SJohn.Forte@Sun.COM 		j = strlen(STMF_LU_PREFIX) + strlen("-");
33337836SJohn.Forte@Sun.COM 
33347836SJohn.Forte@Sun.COM 		(void) sscanf(buf + j,
33357836SJohn.Forte@Sun.COM 		    "%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x",
33367836SJohn.Forte@Sun.COM 		    &guid[0], &guid[1], &guid[2], &guid[3], &guid[4], &guid[5],
33377836SJohn.Forte@Sun.COM 		    &guid[6], &guid[7], &guid[8], &guid[9], &guid[10],
33387836SJohn.Forte@Sun.COM 		    &guid[11], &guid[12], &guid[13], &guid[14], &guid[15]);
33397836SJohn.Forte@Sun.COM 
33407836SJohn.Forte@Sun.COM 		for (j = 0; j < sizeof (stmfGuid); j++) {
33417836SJohn.Forte@Sun.COM 			outGuid.guid[j] = guid[j];
33427836SJohn.Forte@Sun.COM 		}
33437836SJohn.Forte@Sun.COM 
33447836SJohn.Forte@Sun.COM 		bcopy(&outGuid, (*guidList)->guid[i++].guid, sizeof (stmfGuid));
33457836SJohn.Forte@Sun.COM 		(*guidList)->cnt++;
33467836SJohn.Forte@Sun.COM 	}
33477836SJohn.Forte@Sun.COM 
33487836SJohn.Forte@Sun.COM 	if (ret != STMF_PS_SUCCESS) {
33497836SJohn.Forte@Sun.COM 		free(*guidList);
33507836SJohn.Forte@Sun.COM 		goto out;
33517836SJohn.Forte@Sun.COM 	}
33527836SJohn.Forte@Sun.COM 
33537836SJohn.Forte@Sun.COM out:
33547836SJohn.Forte@Sun.COM 	/*
33557836SJohn.Forte@Sun.COM 	 * Free resources
33567836SJohn.Forte@Sun.COM 	 */
33577836SJohn.Forte@Sun.COM 	if (handle != NULL) {
33587836SJohn.Forte@Sun.COM 		scf_handle_destroy(handle);
33597836SJohn.Forte@Sun.COM 	}
33607836SJohn.Forte@Sun.COM 	if (svc != NULL) {
33617836SJohn.Forte@Sun.COM 		scf_service_destroy(svc);
33627836SJohn.Forte@Sun.COM 	}
33637836SJohn.Forte@Sun.COM 	if (pg != NULL) {
33647836SJohn.Forte@Sun.COM 		scf_pg_destroy(pg);
33657836SJohn.Forte@Sun.COM 	}
33667836SJohn.Forte@Sun.COM 	if (pgIter != NULL) {
33677836SJohn.Forte@Sun.COM 		scf_iter_destroy(pgIter);
33687836SJohn.Forte@Sun.COM 	}
33697836SJohn.Forte@Sun.COM 
33707836SJohn.Forte@Sun.COM 	return (ret);
33717836SJohn.Forte@Sun.COM }
33727836SJohn.Forte@Sun.COM 
33737836SJohn.Forte@Sun.COM /*
33747836SJohn.Forte@Sun.COM  * psGetTargetGroupList
33757836SJohn.Forte@Sun.COM  *
33767836SJohn.Forte@Sun.COM  * groupList - pointer to pointer to stmfGroupList. Contains the list
33777836SJohn.Forte@Sun.COM  *             of target groups on successful return.
33787836SJohn.Forte@Sun.COM  *
33797836SJohn.Forte@Sun.COM  * returns:
33807836SJohn.Forte@Sun.COM  *  STMF_PS_SUCCESS on success
33817836SJohn.Forte@Sun.COM  *  STMF_PS_ERROR_* on failure
33827836SJohn.Forte@Sun.COM  */
33837836SJohn.Forte@Sun.COM int
psGetTargetGroupList(stmfGroupList ** groupList)33847836SJohn.Forte@Sun.COM psGetTargetGroupList(stmfGroupList **groupList)
33857836SJohn.Forte@Sun.COM {
33867836SJohn.Forte@Sun.COM 	return (iPsGetGroupList(STMF_TARGET_GROUPS, groupList));
33877836SJohn.Forte@Sun.COM }
33887836SJohn.Forte@Sun.COM 
33897836SJohn.Forte@Sun.COM /*
33907836SJohn.Forte@Sun.COM  * psGetHostGroupMemberList
33917836SJohn.Forte@Sun.COM  *
33927836SJohn.Forte@Sun.COM  * groupName - group name for which to retrieve a member list
33937836SJohn.Forte@Sun.COM  * groupMemberList - pointer to pointer to stmfGroupProperties list
33947836SJohn.Forte@Sun.COM  *
33957836SJohn.Forte@Sun.COM  * returns:
33967836SJohn.Forte@Sun.COM  *  STMF_PS_SUCCESS on success
33977836SJohn.Forte@Sun.COM  *  STMF_PS_ERROR_* on failure
33987836SJohn.Forte@Sun.COM  */
33997836SJohn.Forte@Sun.COM int
psGetHostGroupMemberList(char * groupName,stmfGroupProperties ** groupMemberList)34007836SJohn.Forte@Sun.COM psGetHostGroupMemberList(char *groupName, stmfGroupProperties **groupMemberList)
34017836SJohn.Forte@Sun.COM {
34027836SJohn.Forte@Sun.COM 	int ret;
34037836SJohn.Forte@Sun.COM 	char groupPropListName[MAXNAMELEN];
34047836SJohn.Forte@Sun.COM 	char groupPropName[MAXNAMELEN];
34057836SJohn.Forte@Sun.COM 
34067836SJohn.Forte@Sun.COM 	ret = iPsGetActualGroupName(STMF_HOST_GROUPS, groupName,
34077836SJohn.Forte@Sun.COM 	    groupPropName);
34087836SJohn.Forte@Sun.COM 	if (ret != STMF_PS_SUCCESS) {
34097836SJohn.Forte@Sun.COM 		return (ret);
34107836SJohn.Forte@Sun.COM 	}
34117836SJohn.Forte@Sun.COM 
34127836SJohn.Forte@Sun.COM 	if (snprintf(groupPropListName, sizeof (groupPropListName),
34137836SJohn.Forte@Sun.COM 	    "%s-%s", groupPropName, STMF_MEMBER_LIST_SUFFIX) >
34147836SJohn.Forte@Sun.COM 	    sizeof (groupPropListName)) {
34157836SJohn.Forte@Sun.COM 		syslog(LOG_ERR, "buffer overflow on property name %s",
34167836SJohn.Forte@Sun.COM 		    groupPropName);
34177836SJohn.Forte@Sun.COM 		return (STMF_PS_ERROR);
34187836SJohn.Forte@Sun.COM 	}
34197836SJohn.Forte@Sun.COM 
34207836SJohn.Forte@Sun.COM 	return (iPsGetGroupMemberList(STMF_HOST_GROUPS, groupPropListName,
34217836SJohn.Forte@Sun.COM 	    groupMemberList));
34227836SJohn.Forte@Sun.COM }
34237836SJohn.Forte@Sun.COM 
34247836SJohn.Forte@Sun.COM /*
34257836SJohn.Forte@Sun.COM  * psGetTargetGroupMemberList
34267836SJohn.Forte@Sun.COM  *
34277836SJohn.Forte@Sun.COM  * groupName - group name for which to retrieve a member list
34287836SJohn.Forte@Sun.COM  * groupMemberList - pointer to pointer to stmfGroupProperties list
34297836SJohn.Forte@Sun.COM  *
34307836SJohn.Forte@Sun.COM  * returns:
34317836SJohn.Forte@Sun.COM  *  STMF_PS_SUCCESS on success
34327836SJohn.Forte@Sun.COM  *  STMF_PS_ERROR_* on failure
34337836SJohn.Forte@Sun.COM  */
34347836SJohn.Forte@Sun.COM int
psGetTargetGroupMemberList(char * groupName,stmfGroupProperties ** groupMemberList)34357836SJohn.Forte@Sun.COM psGetTargetGroupMemberList(char *groupName,
34367836SJohn.Forte@Sun.COM     stmfGroupProperties **groupMemberList)
34377836SJohn.Forte@Sun.COM {
34387836SJohn.Forte@Sun.COM 	int ret;
34397836SJohn.Forte@Sun.COM 	char groupPropListName[MAXNAMELEN];
34407836SJohn.Forte@Sun.COM 	char groupPropName[MAXNAMELEN];
34417836SJohn.Forte@Sun.COM 
34427836SJohn.Forte@Sun.COM 	ret = iPsGetActualGroupName(STMF_TARGET_GROUPS, groupName,
34437836SJohn.Forte@Sun.COM 	    groupPropName);
34447836SJohn.Forte@Sun.COM 	if (ret != STMF_PS_SUCCESS) {
34457836SJohn.Forte@Sun.COM 		return (ret);
34467836SJohn.Forte@Sun.COM 	}
34477836SJohn.Forte@Sun.COM 
34487836SJohn.Forte@Sun.COM 	if (snprintf(groupPropListName, sizeof (groupPropListName),
34497836SJohn.Forte@Sun.COM 	    "%s-%s", groupPropName, STMF_MEMBER_LIST_SUFFIX) >
34507836SJohn.Forte@Sun.COM 	    sizeof (groupPropListName)) {
34517836SJohn.Forte@Sun.COM 		syslog(LOG_ERR, "buffer overflow on property name %s",
34527836SJohn.Forte@Sun.COM 		    groupPropName);
34537836SJohn.Forte@Sun.COM 		return (STMF_PS_ERROR);
34547836SJohn.Forte@Sun.COM 	}
34557836SJohn.Forte@Sun.COM 
34567836SJohn.Forte@Sun.COM 	return (iPsGetGroupMemberList(STMF_TARGET_GROUPS,
34577836SJohn.Forte@Sun.COM 	    groupPropListName, groupMemberList));
34587836SJohn.Forte@Sun.COM }
34597836SJohn.Forte@Sun.COM 
34607836SJohn.Forte@Sun.COM /*
34617836SJohn.Forte@Sun.COM  * qsort function
34627836SJohn.Forte@Sun.COM  * sort on veIndex
34637836SJohn.Forte@Sun.COM  */
34647836SJohn.Forte@Sun.COM static int
viewEntryCompare(const void * p1,const void * p2)34657836SJohn.Forte@Sun.COM viewEntryCompare(const void *p1, const void *p2)
34667836SJohn.Forte@Sun.COM {
34677836SJohn.Forte@Sun.COM 
34687836SJohn.Forte@Sun.COM 	stmfViewEntry *v1 = (stmfViewEntry *)p1, *v2 = (stmfViewEntry *)p2;
34697836SJohn.Forte@Sun.COM 	if (v1->veIndex > v2->veIndex)
34707836SJohn.Forte@Sun.COM 		return (1);
34717836SJohn.Forte@Sun.COM 	if (v1->veIndex < v2->veIndex)
34727836SJohn.Forte@Sun.COM 		return (-1);
34737836SJohn.Forte@Sun.COM 	return (0);
34747836SJohn.Forte@Sun.COM }
34757836SJohn.Forte@Sun.COM 
34767836SJohn.Forte@Sun.COM /*
34777836SJohn.Forte@Sun.COM  * psGetViewEntryList
34787836SJohn.Forte@Sun.COM  *
34797836SJohn.Forte@Sun.COM  * luGuid - identifier of logical unit for which to retrieve a view entry list
34807836SJohn.Forte@Sun.COM  * viewEntryList - pointer to pointer to stmfViewEntryList. It will be allocated
34817836SJohn.Forte@Sun.COM  *                 on successful return.
34827836SJohn.Forte@Sun.COM  *
34837836SJohn.Forte@Sun.COM  * returns:
34847836SJohn.Forte@Sun.COM  *  STMF_PS_SUCCESS on success
34857836SJohn.Forte@Sun.COM  *  STMF_PS_ERROR_* on failure
34867836SJohn.Forte@Sun.COM  */
34877836SJohn.Forte@Sun.COM int
psGetViewEntryList(stmfGuid * lu,stmfViewEntryList ** viewEntryList)34887836SJohn.Forte@Sun.COM psGetViewEntryList(stmfGuid *lu, stmfViewEntryList **viewEntryList)
34897836SJohn.Forte@Sun.COM {
34907836SJohn.Forte@Sun.COM 	scf_handle_t	*handle = NULL;
34917836SJohn.Forte@Sun.COM 	scf_service_t	*svc = NULL;
34927836SJohn.Forte@Sun.COM 	scf_propertygroup_t	*pg = NULL;
34937836SJohn.Forte@Sun.COM 	scf_property_t	*prop = NULL;
34947836SJohn.Forte@Sun.COM 	scf_value_t *value = NULL;
34957836SJohn.Forte@Sun.COM 	scf_iter_t  *propIter = NULL;
34967836SJohn.Forte@Sun.COM 	char guidAsciiBuf[33]; /* size of ascii hex 16 byte guid with NULL */
34977836SJohn.Forte@Sun.COM 	char viewEntryPgName[VIEW_ENTRY_PG_SIZE];
34987836SJohn.Forte@Sun.COM 	char luPgName[LOGICAL_UNIT_PG_SIZE];
34997836SJohn.Forte@Sun.COM 	int ret = STMF_PS_SUCCESS;
35007836SJohn.Forte@Sun.COM 	uint64_t i = 0;
35017836SJohn.Forte@Sun.COM 	uint64_t veCnt;
35027836SJohn.Forte@Sun.COM 
35037836SJohn.Forte@Sun.COM 
35047836SJohn.Forte@Sun.COM 	ret = iPsInit(&handle, &svc);
35057836SJohn.Forte@Sun.COM 	if (ret != STMF_PS_SUCCESS) {
35067836SJohn.Forte@Sun.COM 		goto out;
35077836SJohn.Forte@Sun.COM 	}
35087836SJohn.Forte@Sun.COM 
35097836SJohn.Forte@Sun.COM 	/*
35107836SJohn.Forte@Sun.COM 	 * Allocate scf resources
35117836SJohn.Forte@Sun.COM 	 */
35127836SJohn.Forte@Sun.COM 	if (((pg = scf_pg_create(handle)) == NULL) ||
35137836SJohn.Forte@Sun.COM 	    ((prop = scf_property_create(handle)) == NULL) ||
35147836SJohn.Forte@Sun.COM 	    ((propIter = scf_iter_create(handle)) == NULL) ||
35157836SJohn.Forte@Sun.COM 	    ((value = scf_value_create(handle)) == NULL)) {
35167836SJohn.Forte@Sun.COM 		syslog(LOG_ERR, "scf alloc resource failed - %s",
35177836SJohn.Forte@Sun.COM 		    scf_strerror(scf_error()));
35187836SJohn.Forte@Sun.COM 		ret = STMF_PS_ERROR;
35197836SJohn.Forte@Sun.COM 		goto out;
35207836SJohn.Forte@Sun.COM 	}
35217836SJohn.Forte@Sun.COM 
35227836SJohn.Forte@Sun.COM 	/* Convert to ASCII uppercase hexadecimal string */
35237836SJohn.Forte@Sun.COM 	(void) snprintf(guidAsciiBuf, sizeof (guidAsciiBuf),
35247836SJohn.Forte@Sun.COM 	    "%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X",
35257836SJohn.Forte@Sun.COM 	    lu->guid[0], lu->guid[1], lu->guid[2], lu->guid[3], lu->guid[4],
35267836SJohn.Forte@Sun.COM 	    lu->guid[5], lu->guid[6], lu->guid[7], lu->guid[8], lu->guid[9],
35277836SJohn.Forte@Sun.COM 	    lu->guid[10], lu->guid[11], lu->guid[12], lu->guid[13],
35287836SJohn.Forte@Sun.COM 	    lu->guid[14], lu->guid[15]);
35297836SJohn.Forte@Sun.COM 
35307836SJohn.Forte@Sun.COM 	/* form the LU property group name (LU-<guid>) */
35317836SJohn.Forte@Sun.COM 	(void) snprintf(luPgName, sizeof (luPgName), "%s-%s",
35327836SJohn.Forte@Sun.COM 	    STMF_LU_PREFIX, guidAsciiBuf);
35337836SJohn.Forte@Sun.COM 
35347836SJohn.Forte@Sun.COM 	/* get the property group associated with this LU */
35357836SJohn.Forte@Sun.COM 	if (scf_service_get_pg(svc, luPgName, pg) == -1) {
35367836SJohn.Forte@Sun.COM 		if (scf_error() == SCF_ERROR_NOT_FOUND) {
35377836SJohn.Forte@Sun.COM 			ret = STMF_PS_ERROR_NOT_FOUND;
35387836SJohn.Forte@Sun.COM 		} else {
353911909SPeter.Gill@Sun.COM 			syslog(LOG_ERR, "get pg %s failed - %s",
354011909SPeter.Gill@Sun.COM 			    luPgName, scf_strerror(scf_error()));
35417836SJohn.Forte@Sun.COM 			ret = STMF_PS_ERROR;
35427836SJohn.Forte@Sun.COM 		}
35437836SJohn.Forte@Sun.COM 		goto out;
35447836SJohn.Forte@Sun.COM 	}
35457836SJohn.Forte@Sun.COM 
35467836SJohn.Forte@Sun.COM 	/* get the view entry count property */
35477836SJohn.Forte@Sun.COM 	if (scf_pg_get_property(pg, STMF_VE_CNT, prop) == -1) {
354811909SPeter.Gill@Sun.COM 		syslog(LOG_ERR, "get property %s/%s failed - %s",
354911909SPeter.Gill@Sun.COM 		    luPgName, STMF_VE_CNT, scf_strerror(scf_error()));
35507836SJohn.Forte@Sun.COM 		ret = STMF_PS_ERROR;
35517836SJohn.Forte@Sun.COM 		goto out;
35527836SJohn.Forte@Sun.COM 	}
35537836SJohn.Forte@Sun.COM 
35547836SJohn.Forte@Sun.COM 	if (scf_property_get_value(prop, value) == -1) {
355511909SPeter.Gill@Sun.COM 		syslog(LOG_ERR, "get property value %s/%s failed - %s",
355611909SPeter.Gill@Sun.COM 		    luPgName, STMF_VE_CNT, scf_strerror(scf_error()));
35577836SJohn.Forte@Sun.COM 		ret = STMF_PS_ERROR;
35587836SJohn.Forte@Sun.COM 		goto out;
35597836SJohn.Forte@Sun.COM 	}
35607836SJohn.Forte@Sun.COM 
35617836SJohn.Forte@Sun.COM 	/*
35627836SJohn.Forte@Sun.COM 	 * Get the actual value of the view entry count property
35637836SJohn.Forte@Sun.COM 	 */
35647836SJohn.Forte@Sun.COM 	if (scf_value_get_count(value, &veCnt) == -1) {
356511909SPeter.Gill@Sun.COM 		syslog(LOG_ERR, "get integer value %s/%s failed - %s",
356611909SPeter.Gill@Sun.COM 		    luPgName, STMF_VE_CNT, scf_strerror(scf_error()));
35677836SJohn.Forte@Sun.COM 		ret = STMF_PS_ERROR;
35687836SJohn.Forte@Sun.COM 		goto out;
35697836SJohn.Forte@Sun.COM 	}
35707836SJohn.Forte@Sun.COM 
35717836SJohn.Forte@Sun.COM 	/*
35727836SJohn.Forte@Sun.COM 	 * propIter is the iterator handle
35737836SJohn.Forte@Sun.COM 	 */
35747836SJohn.Forte@Sun.COM 	if (scf_iter_pg_properties(propIter, pg) == -1) {
357511909SPeter.Gill@Sun.COM 		syslog(LOG_ERR, "iter properties for %s failed - %s",
357611909SPeter.Gill@Sun.COM 		    luPgName, scf_strerror(scf_error()));
35777836SJohn.Forte@Sun.COM 		ret = STMF_PS_ERROR;
35787836SJohn.Forte@Sun.COM 		goto out;
35797836SJohn.Forte@Sun.COM 	}
35807836SJohn.Forte@Sun.COM 
35817836SJohn.Forte@Sun.COM 	/*
35827836SJohn.Forte@Sun.COM 	 * alloc the list based on the view entry count
35837836SJohn.Forte@Sun.COM 	 */
35847836SJohn.Forte@Sun.COM 	*viewEntryList = (stmfViewEntryList *)calloc(1,
35857836SJohn.Forte@Sun.COM 	    sizeof (stmfViewEntryList) + veCnt * sizeof (stmfViewEntry));
35867836SJohn.Forte@Sun.COM 	if (*viewEntryList == NULL) {
35877836SJohn.Forte@Sun.COM 		ret = STMF_PS_ERROR_NOMEM;
35887836SJohn.Forte@Sun.COM 		goto out;
35897836SJohn.Forte@Sun.COM 	}
35907836SJohn.Forte@Sun.COM 
35917836SJohn.Forte@Sun.COM 	i = 0;
35927836SJohn.Forte@Sun.COM 	/*
35937836SJohn.Forte@Sun.COM 	 * iterate through the view entry properties to find the
35947836SJohn.Forte@Sun.COM 	 * view entries
35957836SJohn.Forte@Sun.COM 	 */
35967836SJohn.Forte@Sun.COM 	while (scf_iter_next_property(propIter, prop) == 1) {
35977836SJohn.Forte@Sun.COM 		/* find match for view entry property */
35987836SJohn.Forte@Sun.COM 		if (scf_property_get_name(prop, viewEntryPgName,
35997836SJohn.Forte@Sun.COM 		    sizeof (viewEntryPgName)) != -1) {
36007836SJohn.Forte@Sun.COM 			if (strncmp(viewEntryPgName, STMF_VE_PREFIX,
36017836SJohn.Forte@Sun.COM 			    strlen(STMF_VE_PREFIX)) != 0) {
36027836SJohn.Forte@Sun.COM 				continue;
36037836SJohn.Forte@Sun.COM 			}
36047836SJohn.Forte@Sun.COM 			/*
36057836SJohn.Forte@Sun.COM 			 * We've exceeded our alloc limit
36067836SJohn.Forte@Sun.COM 			 * break with error
36077836SJohn.Forte@Sun.COM 			 */
36087836SJohn.Forte@Sun.COM 			if (i == veCnt) {
36097836SJohn.Forte@Sun.COM 				ret = STMF_PS_ERROR;
36107836SJohn.Forte@Sun.COM 				break;
36117836SJohn.Forte@Sun.COM 			}
36127836SJohn.Forte@Sun.COM 
36137836SJohn.Forte@Sun.COM 			if ((ret = iPsGetViewEntry(viewEntryPgName,
36147836SJohn.Forte@Sun.COM 			    &((*viewEntryList)->ve[i]))) != STMF_PS_SUCCESS) {
36157836SJohn.Forte@Sun.COM 				break;
36167836SJohn.Forte@Sun.COM 			}
36177836SJohn.Forte@Sun.COM 
36187836SJohn.Forte@Sun.COM 			i++;
36197836SJohn.Forte@Sun.COM 
36207836SJohn.Forte@Sun.COM 			/* set the list count */
36217836SJohn.Forte@Sun.COM 			(*viewEntryList)->cnt++;
36227836SJohn.Forte@Sun.COM 		} else {
362311909SPeter.Gill@Sun.COM 			syslog(LOG_ERR, "scf iter %s properties failed - %s",
362411909SPeter.Gill@Sun.COM 			    luPgName, scf_strerror(scf_error()));
36257836SJohn.Forte@Sun.COM 			ret = STMF_PS_ERROR;
36267836SJohn.Forte@Sun.COM 			break;
36277836SJohn.Forte@Sun.COM 		}
36287836SJohn.Forte@Sun.COM 
36297836SJohn.Forte@Sun.COM 	}
36307836SJohn.Forte@Sun.COM 
36317836SJohn.Forte@Sun.COM 	if (ret != STMF_PS_SUCCESS) {
36327836SJohn.Forte@Sun.COM 		free(*viewEntryList);
36337836SJohn.Forte@Sun.COM 		goto out;
36347836SJohn.Forte@Sun.COM 	}
36357836SJohn.Forte@Sun.COM 
36367836SJohn.Forte@Sun.COM 	/*
36377836SJohn.Forte@Sun.COM 	 * We're sorting the final list here based on the veIndex
36387836SJohn.Forte@Sun.COM 	 * If we don't, the caller is going to have to do it to reap
36397836SJohn.Forte@Sun.COM 	 * some intelligent output.
36407836SJohn.Forte@Sun.COM 	 */
36417836SJohn.Forte@Sun.COM 	qsort((void *)&((*viewEntryList)->ve[0]), (*viewEntryList)->cnt,
36427836SJohn.Forte@Sun.COM 	    sizeof (stmfViewEntry), viewEntryCompare);
36437836SJohn.Forte@Sun.COM 
36447836SJohn.Forte@Sun.COM out:
36457836SJohn.Forte@Sun.COM 	/*
36467836SJohn.Forte@Sun.COM 	 * Free resources
36477836SJohn.Forte@Sun.COM 	 */
36487836SJohn.Forte@Sun.COM 	if (handle != NULL) {
36497836SJohn.Forte@Sun.COM 		scf_handle_destroy(handle);
36507836SJohn.Forte@Sun.COM 	}
36517836SJohn.Forte@Sun.COM 	if (svc != NULL) {
36527836SJohn.Forte@Sun.COM 		scf_service_destroy(svc);
36537836SJohn.Forte@Sun.COM 	}
36547836SJohn.Forte@Sun.COM 	if (pg != NULL) {
36557836SJohn.Forte@Sun.COM 		scf_pg_destroy(pg);
36567836SJohn.Forte@Sun.COM 	}
36577836SJohn.Forte@Sun.COM 	if (prop != NULL) {
36587836SJohn.Forte@Sun.COM 		scf_property_destroy(prop);
36597836SJohn.Forte@Sun.COM 	}
36607836SJohn.Forte@Sun.COM 	if (value != NULL) {
36617836SJohn.Forte@Sun.COM 		scf_value_destroy(value);
36627836SJohn.Forte@Sun.COM 	}
36637836SJohn.Forte@Sun.COM 	if (propIter != NULL) {
36647836SJohn.Forte@Sun.COM 		scf_iter_destroy(propIter);
36657836SJohn.Forte@Sun.COM 	}
36667836SJohn.Forte@Sun.COM 
36677836SJohn.Forte@Sun.COM 	return (ret);
36687836SJohn.Forte@Sun.COM }
36697836SJohn.Forte@Sun.COM 
36707836SJohn.Forte@Sun.COM /*
36717836SJohn.Forte@Sun.COM  * iPsGetViewEntry
36727836SJohn.Forte@Sun.COM  *
36737836SJohn.Forte@Sun.COM  * viewEntryPgName - view entry property group name to retrieve
36747836SJohn.Forte@Sun.COM  * viewEntry - pointer to stmfViewEntry structure allocated by the caller
36757836SJohn.Forte@Sun.COM  *
36767836SJohn.Forte@Sun.COM  * returns:
36777836SJohn.Forte@Sun.COM  *  STMF_PS_SUCCESS on success
36787836SJohn.Forte@Sun.COM  *  STMF_PS_ERROR_* on failure
36797836SJohn.Forte@Sun.COM  */
36807836SJohn.Forte@Sun.COM static int
iPsGetViewEntry(char * viewEntryPgName,stmfViewEntry * viewEntry)36817836SJohn.Forte@Sun.COM iPsGetViewEntry(char *viewEntryPgName, stmfViewEntry *viewEntry)
36827836SJohn.Forte@Sun.COM {
36837836SJohn.Forte@Sun.COM 	scf_handle_t	*handle = NULL;
36847836SJohn.Forte@Sun.COM 	scf_service_t	*svc = NULL;
36857836SJohn.Forte@Sun.COM 	scf_propertygroup_t	*pg = NULL;
36867836SJohn.Forte@Sun.COM 	scf_property_t	*prop = NULL;
36877836SJohn.Forte@Sun.COM 	scf_value_t *value = NULL;
36887836SJohn.Forte@Sun.COM 	uint8_t scfBool;
36897836SJohn.Forte@Sun.COM 	char *indexPtr;
36907836SJohn.Forte@Sun.COM 	char groupName[sizeof (stmfGroupName)];
36917836SJohn.Forte@Sun.COM 	int ret = STMF_PS_SUCCESS;
36927836SJohn.Forte@Sun.COM 
36937836SJohn.Forte@Sun.COM 
36947836SJohn.Forte@Sun.COM 	ret = iPsInit(&handle, &svc);
36957836SJohn.Forte@Sun.COM 	if (ret != STMF_PS_SUCCESS) {
36967836SJohn.Forte@Sun.COM 		goto out;
36977836SJohn.Forte@Sun.COM 	}
36987836SJohn.Forte@Sun.COM 
36997836SJohn.Forte@Sun.COM 	/*
37007836SJohn.Forte@Sun.COM 	 * Allocate scf resources
37017836SJohn.Forte@Sun.COM 	 */
37027836SJohn.Forte@Sun.COM 	if (((pg = scf_pg_create(handle)) == NULL) ||
37037836SJohn.Forte@Sun.COM 	    ((prop = scf_property_create(handle)) == NULL) ||
37047836SJohn.Forte@Sun.COM 	    ((value = scf_value_create(handle)) == NULL)) {
37057836SJohn.Forte@Sun.COM 		syslog(LOG_ERR, "scf alloc resource failed - %s",
37067836SJohn.Forte@Sun.COM 		    scf_strerror(scf_error()));
37077836SJohn.Forte@Sun.COM 		ret = STMF_PS_ERROR;
37087836SJohn.Forte@Sun.COM 		goto out;
37097836SJohn.Forte@Sun.COM 	}
37107836SJohn.Forte@Sun.COM 
37117836SJohn.Forte@Sun.COM 	bzero(viewEntry, sizeof (stmfViewEntry));
37127836SJohn.Forte@Sun.COM 
37137836SJohn.Forte@Sun.COM 	/*
37147836SJohn.Forte@Sun.COM 	 * get the service property group view entry handle
37157836SJohn.Forte@Sun.COM 	 */
37167836SJohn.Forte@Sun.COM 	if (scf_service_get_pg(svc, viewEntryPgName, pg) == -1) {
37177836SJohn.Forte@Sun.COM 		if (scf_error() == SCF_ERROR_NOT_FOUND) {
37187836SJohn.Forte@Sun.COM 			ret = STMF_PS_ERROR_NOT_FOUND;
37197836SJohn.Forte@Sun.COM 		} else {
372011909SPeter.Gill@Sun.COM 			syslog(LOG_ERR, "get pg %s failed - %s",
372111909SPeter.Gill@Sun.COM 			    viewEntryPgName, scf_strerror(scf_error()));
37227836SJohn.Forte@Sun.COM 			ret = STMF_PS_ERROR;
37237836SJohn.Forte@Sun.COM 		}
37247836SJohn.Forte@Sun.COM 		goto out;
37257836SJohn.Forte@Sun.COM 	}
37267836SJohn.Forte@Sun.COM 
37277836SJohn.Forte@Sun.COM 
37287836SJohn.Forte@Sun.COM 	/*
37297836SJohn.Forte@Sun.COM 	 * get index
37307836SJohn.Forte@Sun.COM 	 * format is: VE-<veIndex>-GUID
37317836SJohn.Forte@Sun.COM 	 */
37327836SJohn.Forte@Sun.COM 	indexPtr = strchr(viewEntryPgName, '-');
37337836SJohn.Forte@Sun.COM 	if (!indexPtr) {
37347836SJohn.Forte@Sun.COM 		ret = STMF_PS_ERROR;
37357836SJohn.Forte@Sun.COM 		goto out;
37367836SJohn.Forte@Sun.COM 	}
37377836SJohn.Forte@Sun.COM 
37387836SJohn.Forte@Sun.COM 	/* Set the index */
37397836SJohn.Forte@Sun.COM 	viewEntry->veIndex = atoi(strtok(++indexPtr, "-"));
37407836SJohn.Forte@Sun.COM 
37417836SJohn.Forte@Sun.COM 	viewEntry->veIndexValid = B_TRUE;
37427836SJohn.Forte@Sun.COM 
37437836SJohn.Forte@Sun.COM 	/* get allHosts property */
37447836SJohn.Forte@Sun.COM 	if (scf_pg_get_property(pg, STMF_VE_ALLHOSTS,
37457836SJohn.Forte@Sun.COM 	    prop) == -1) {
374611909SPeter.Gill@Sun.COM 		syslog(LOG_ERR, "get property %s/%s failed - %s",
374711909SPeter.Gill@Sun.COM 		    viewEntryPgName, STMF_VE_ALLHOSTS,
37487836SJohn.Forte@Sun.COM 		    scf_strerror(scf_error()));
37497836SJohn.Forte@Sun.COM 		ret = STMF_PS_ERROR;
37507836SJohn.Forte@Sun.COM 		goto out;
37517836SJohn.Forte@Sun.COM 	}
37527836SJohn.Forte@Sun.COM 
37537836SJohn.Forte@Sun.COM 	if (scf_property_get_value(prop, value) == -1) {
375411909SPeter.Gill@Sun.COM 		syslog(LOG_ERR, "get property %s/%s failed - %s",
375511909SPeter.Gill@Sun.COM 		    viewEntryPgName, STMF_VE_ALLHOSTS,
37567836SJohn.Forte@Sun.COM 		    scf_strerror(scf_error()));
37577836SJohn.Forte@Sun.COM 		ret = STMF_PS_ERROR;
37587836SJohn.Forte@Sun.COM 		goto out;
37597836SJohn.Forte@Sun.COM 	}
37607836SJohn.Forte@Sun.COM 
37617836SJohn.Forte@Sun.COM 	/* set allHosts */
37627836SJohn.Forte@Sun.COM 	if (scf_value_get_boolean(value, (uint8_t *)&scfBool) == -1) {
376311909SPeter.Gill@Sun.COM 		syslog(LOG_ERR, "get property %s/%s failed - %s",
376411909SPeter.Gill@Sun.COM 		    viewEntryPgName, STMF_VE_ALLHOSTS,
37657836SJohn.Forte@Sun.COM 		    scf_strerror(scf_error()));
37667836SJohn.Forte@Sun.COM 		ret = STMF_PS_ERROR;
37677836SJohn.Forte@Sun.COM 		goto out;
37687836SJohn.Forte@Sun.COM 	}
37697836SJohn.Forte@Sun.COM 	viewEntry->allHosts = scfBool;
37707836SJohn.Forte@Sun.COM 
37717836SJohn.Forte@Sun.COM 	/* get hostGroup property */
37727836SJohn.Forte@Sun.COM 	if (scf_pg_get_property(pg, STMF_VE_HOSTGROUP,
37737836SJohn.Forte@Sun.COM 	    prop) == -1) {
377411909SPeter.Gill@Sun.COM 		syslog(LOG_ERR, "get property %s/%s failed - %s",
377511909SPeter.Gill@Sun.COM 		    viewEntryPgName, STMF_VE_HOSTGROUP,
37767836SJohn.Forte@Sun.COM 		    scf_strerror(scf_error()));
37777836SJohn.Forte@Sun.COM 		ret = STMF_PS_ERROR;
37787836SJohn.Forte@Sun.COM 		goto out;
37797836SJohn.Forte@Sun.COM 	}
37807836SJohn.Forte@Sun.COM 
37817836SJohn.Forte@Sun.COM 	if (scf_property_get_value(prop, value) == -1) {
378211909SPeter.Gill@Sun.COM 		syslog(LOG_ERR, "get property %s/%s failed - %s",
378311909SPeter.Gill@Sun.COM 		    viewEntryPgName, STMF_VE_HOSTGROUP,
37847836SJohn.Forte@Sun.COM 		    scf_strerror(scf_error()));
37857836SJohn.Forte@Sun.COM 		ret = STMF_PS_ERROR;
37867836SJohn.Forte@Sun.COM 		goto out;
37877836SJohn.Forte@Sun.COM 	}
37887836SJohn.Forte@Sun.COM 
37897836SJohn.Forte@Sun.COM 	if (scf_value_get_ustring(value, groupName,
37907836SJohn.Forte@Sun.COM 	    sizeof (groupName)) == -1) {
379111909SPeter.Gill@Sun.COM 		syslog(LOG_ERR, "get value %s/%s failed - %s",
379211909SPeter.Gill@Sun.COM 		    viewEntryPgName, STMF_VE_HOSTGROUP,
37937836SJohn.Forte@Sun.COM 		    scf_strerror(scf_error()));
37947836SJohn.Forte@Sun.COM 		ret = STMF_PS_ERROR;
37957836SJohn.Forte@Sun.COM 		goto out;
37967836SJohn.Forte@Sun.COM 	}
37977836SJohn.Forte@Sun.COM 	/* set hostGroup */
37987836SJohn.Forte@Sun.COM 	bcopy(groupName, viewEntry->hostGroup, strlen(groupName));
37997836SJohn.Forte@Sun.COM 
38007836SJohn.Forte@Sun.COM 	/* get allTargets property */
38017836SJohn.Forte@Sun.COM 	if (scf_pg_get_property(pg, STMF_VE_ALLTARGETS,
38027836SJohn.Forte@Sun.COM 	    prop) == -1) {
380311909SPeter.Gill@Sun.COM 		syslog(LOG_ERR, "get property %s/%s failed - %s",
380411909SPeter.Gill@Sun.COM 		    viewEntryPgName, STMF_VE_ALLTARGETS,
38057836SJohn.Forte@Sun.COM 		    scf_strerror(scf_error()));
38067836SJohn.Forte@Sun.COM 		ret = STMF_PS_ERROR;
38077836SJohn.Forte@Sun.COM 		goto out;
38087836SJohn.Forte@Sun.COM 	}
38097836SJohn.Forte@Sun.COM 
38107836SJohn.Forte@Sun.COM 	if (scf_property_get_value(prop, value) == -1) {
381111909SPeter.Gill@Sun.COM 		syslog(LOG_ERR, "get property value %s/%s failed - %s",
381211909SPeter.Gill@Sun.COM 		    viewEntryPgName, STMF_VE_ALLTARGETS,
38137836SJohn.Forte@Sun.COM 		    scf_strerror(scf_error()));
38147836SJohn.Forte@Sun.COM 		ret = STMF_PS_ERROR;
38157836SJohn.Forte@Sun.COM 		goto out;
38167836SJohn.Forte@Sun.COM 	}
38177836SJohn.Forte@Sun.COM 
38187836SJohn.Forte@Sun.COM 	/* set allTargets */
38197836SJohn.Forte@Sun.COM 	if (scf_value_get_boolean(value, (uint8_t *)&scfBool) == -1) {
382011909SPeter.Gill@Sun.COM 		syslog(LOG_ERR, "get value %s/%s failed - %s",
382111909SPeter.Gill@Sun.COM 		    viewEntryPgName, STMF_VE_ALLTARGETS,
38227836SJohn.Forte@Sun.COM 		    scf_strerror(scf_error()));
38237836SJohn.Forte@Sun.COM 		ret = STMF_PS_ERROR;
38247836SJohn.Forte@Sun.COM 		goto out;
38257836SJohn.Forte@Sun.COM 	}
38267836SJohn.Forte@Sun.COM 	viewEntry->allTargets = scfBool;
38277836SJohn.Forte@Sun.COM 
38287836SJohn.Forte@Sun.COM 	/* get targetGroup property */
38297836SJohn.Forte@Sun.COM 	if (scf_pg_get_property(pg, STMF_VE_TARGETGROUP, prop) == -1) {
383011909SPeter.Gill@Sun.COM 		syslog(LOG_ERR, "get property %s/%s failed - %s",
383111909SPeter.Gill@Sun.COM 		    viewEntryPgName, STMF_VE_TARGETGROUP,
38327836SJohn.Forte@Sun.COM 		    scf_strerror(scf_error()));
38337836SJohn.Forte@Sun.COM 		ret = STMF_PS_ERROR;
38347836SJohn.Forte@Sun.COM 		goto out;
38357836SJohn.Forte@Sun.COM 	}
38367836SJohn.Forte@Sun.COM 
38377836SJohn.Forte@Sun.COM 	if (scf_property_get_value(prop, value) == -1) {
383811909SPeter.Gill@Sun.COM 		syslog(LOG_ERR, "get property value %s/%s failed - %s",
383911909SPeter.Gill@Sun.COM 		    viewEntryPgName, STMF_VE_TARGETGROUP,
38407836SJohn.Forte@Sun.COM 		    scf_strerror(scf_error()));
38417836SJohn.Forte@Sun.COM 		ret = STMF_PS_ERROR;
38427836SJohn.Forte@Sun.COM 		goto out;
38437836SJohn.Forte@Sun.COM 	}
38447836SJohn.Forte@Sun.COM 
38457836SJohn.Forte@Sun.COM 	if (scf_value_get_ustring(value, groupName,
38467836SJohn.Forte@Sun.COM 	    sizeof (groupName)) == -1) {
384711909SPeter.Gill@Sun.COM 		syslog(LOG_ERR, "get value %s/%s failed - %s",
384811909SPeter.Gill@Sun.COM 		    viewEntryPgName, STMF_VE_TARGETGROUP,
38497836SJohn.Forte@Sun.COM 		    scf_strerror(scf_error()));
38507836SJohn.Forte@Sun.COM 		ret = STMF_PS_ERROR;
38517836SJohn.Forte@Sun.COM 		goto out;
38527836SJohn.Forte@Sun.COM 	}
38537836SJohn.Forte@Sun.COM 	/* set targetGroup */
38547836SJohn.Forte@Sun.COM 	bcopy(groupName, viewEntry->targetGroup, strlen(groupName));
38557836SJohn.Forte@Sun.COM 
38567836SJohn.Forte@Sun.COM 	/* get luNbr property */
38577836SJohn.Forte@Sun.COM 	if (scf_pg_get_property(pg, STMF_VE_LUNBR,
38587836SJohn.Forte@Sun.COM 	    prop) == -1) {
385911909SPeter.Gill@Sun.COM 		syslog(LOG_ERR, "get property %s/%s failed - %s",
386011909SPeter.Gill@Sun.COM 		    viewEntryPgName, STMF_VE_LUNBR,
38617836SJohn.Forte@Sun.COM 		    scf_strerror(scf_error()));
38627836SJohn.Forte@Sun.COM 		ret = STMF_PS_ERROR;
38637836SJohn.Forte@Sun.COM 		goto out;
38647836SJohn.Forte@Sun.COM 	}
38657836SJohn.Forte@Sun.COM 
38667836SJohn.Forte@Sun.COM 	if (scf_property_get_value(prop, value) == -1) {
386711909SPeter.Gill@Sun.COM 		syslog(LOG_ERR, "get property value %s/%s failed - %s",
386811909SPeter.Gill@Sun.COM 		    viewEntryPgName, STMF_VE_LUNBR,
38697836SJohn.Forte@Sun.COM 		    scf_strerror(scf_error()));
38707836SJohn.Forte@Sun.COM 		ret = STMF_PS_ERROR;
38717836SJohn.Forte@Sun.COM 		goto out;
38727836SJohn.Forte@Sun.COM 	}
38737836SJohn.Forte@Sun.COM 
38747836SJohn.Forte@Sun.COM 	/* set luNbr */
38757836SJohn.Forte@Sun.COM 	if (scf_value_get_opaque(value, (char *)viewEntry->luNbr,
38767836SJohn.Forte@Sun.COM 	    sizeof (viewEntry->luNbr)) == -1) {
387711909SPeter.Gill@Sun.COM 		syslog(LOG_ERR, "get opaque value %s/%s failed - %s",
387811909SPeter.Gill@Sun.COM 		    viewEntryPgName, STMF_VE_LUNBR,
38797836SJohn.Forte@Sun.COM 		    scf_strerror(scf_error()));
38807836SJohn.Forte@Sun.COM 		ret = STMF_PS_ERROR;
38817836SJohn.Forte@Sun.COM 		goto out;
38827836SJohn.Forte@Sun.COM 	}
38837836SJohn.Forte@Sun.COM 	/* set luNbrValid to true since we just got it */
38847836SJohn.Forte@Sun.COM 	viewEntry->luNbrValid = B_TRUE;
38857836SJohn.Forte@Sun.COM 
38867836SJohn.Forte@Sun.COM out:
38877836SJohn.Forte@Sun.COM 	/*
38887836SJohn.Forte@Sun.COM 	 * Free resources
38897836SJohn.Forte@Sun.COM 	 */
38907836SJohn.Forte@Sun.COM 	if (handle != NULL) {
38917836SJohn.Forte@Sun.COM 		scf_handle_destroy(handle);
38927836SJohn.Forte@Sun.COM 	}
38937836SJohn.Forte@Sun.COM 	if (svc != NULL) {
38947836SJohn.Forte@Sun.COM 		scf_service_destroy(svc);
38957836SJohn.Forte@Sun.COM 	}
38967836SJohn.Forte@Sun.COM 	if (pg != NULL) {
38977836SJohn.Forte@Sun.COM 		scf_pg_destroy(pg);
38987836SJohn.Forte@Sun.COM 	}
38997836SJohn.Forte@Sun.COM 	if (value != NULL) {
39007836SJohn.Forte@Sun.COM 		scf_value_destroy(value);
39017836SJohn.Forte@Sun.COM 	}
39027836SJohn.Forte@Sun.COM 	if (prop != NULL) {
39037836SJohn.Forte@Sun.COM 		scf_property_destroy(prop);
39047836SJohn.Forte@Sun.COM 	}
39057836SJohn.Forte@Sun.COM 
39067836SJohn.Forte@Sun.COM 	return (ret);
39077836SJohn.Forte@Sun.COM }
39087836SJohn.Forte@Sun.COM 
39097836SJohn.Forte@Sun.COM 
39107836SJohn.Forte@Sun.COM /*
39117836SJohn.Forte@Sun.COM  * psRemoveHostGroupMember
39127836SJohn.Forte@Sun.COM  *
39137836SJohn.Forte@Sun.COM  * Remove a host group member from a host group,
39147836SJohn.Forte@Sun.COM  *
39157836SJohn.Forte@Sun.COM  * groupName - name of group from which the member is removed
39167836SJohn.Forte@Sun.COM  * memberName - name of group member to remove
39177836SJohn.Forte@Sun.COM  *
39187836SJohn.Forte@Sun.COM  * returns:
39197836SJohn.Forte@Sun.COM  *  STMF_PS_SUCCESS on success
39207836SJohn.Forte@Sun.COM  *  STMF_PS_ERROR_* on failure
39217836SJohn.Forte@Sun.COM  */
39227836SJohn.Forte@Sun.COM int
psRemoveHostGroupMember(char * groupName,char * memberName)39237836SJohn.Forte@Sun.COM psRemoveHostGroupMember(char *groupName, char *memberName)
39247836SJohn.Forte@Sun.COM {
39257836SJohn.Forte@Sun.COM 	int ret;
39267836SJohn.Forte@Sun.COM 	char groupPropListName[MAXNAMELEN];
39277836SJohn.Forte@Sun.COM 	char groupPropName[MAXNAMELEN];
39287836SJohn.Forte@Sun.COM 
39297836SJohn.Forte@Sun.COM 	ret = iPsGetActualGroupName(STMF_HOST_GROUPS, groupName,
39307836SJohn.Forte@Sun.COM 	    groupPropName);
39317836SJohn.Forte@Sun.COM 	if (ret != STMF_PS_SUCCESS) {
39327836SJohn.Forte@Sun.COM 		return (ret);
39337836SJohn.Forte@Sun.COM 	}
39347836SJohn.Forte@Sun.COM 
39357836SJohn.Forte@Sun.COM 	if (snprintf(groupPropListName, sizeof (groupPropListName),
39367836SJohn.Forte@Sun.COM 	    "%s-%s", groupPropName, STMF_MEMBER_LIST_SUFFIX) >
39377836SJohn.Forte@Sun.COM 	    sizeof (groupPropListName)) {
39387836SJohn.Forte@Sun.COM 		syslog(LOG_ERR, "buffer overflow on property name %s",
39397836SJohn.Forte@Sun.COM 		    groupPropName);
39407836SJohn.Forte@Sun.COM 		return (STMF_PS_ERROR);
39417836SJohn.Forte@Sun.COM 	}
39427836SJohn.Forte@Sun.COM 
39437836SJohn.Forte@Sun.COM 	return (iPsAddRemoveGroupMember(STMF_HOST_GROUPS, groupPropListName,
39447836SJohn.Forte@Sun.COM 	    memberName, REMOVE));
39457836SJohn.Forte@Sun.COM }
39467836SJohn.Forte@Sun.COM 
39477836SJohn.Forte@Sun.COM /*
39487836SJohn.Forte@Sun.COM  * psRemoveTargetGroupMember
39497836SJohn.Forte@Sun.COM  *
39507836SJohn.Forte@Sun.COM  * Remove a target port group member from an target port group,
39517836SJohn.Forte@Sun.COM  *
39527836SJohn.Forte@Sun.COM  * groupName - name of group from which the member is removed
39537836SJohn.Forte@Sun.COM  * memberName - name of group member to remove
39547836SJohn.Forte@Sun.COM  *
39557836SJohn.Forte@Sun.COM  * returns:
39567836SJohn.Forte@Sun.COM  *  STMF_PS_SUCCESS on success
39577836SJohn.Forte@Sun.COM  *  STMF_PS_ERROR_* on failure
39587836SJohn.Forte@Sun.COM  */
39597836SJohn.Forte@Sun.COM int
psRemoveTargetGroupMember(char * groupName,char * memberName)39607836SJohn.Forte@Sun.COM psRemoveTargetGroupMember(char *groupName, char *memberName)
39617836SJohn.Forte@Sun.COM {
39627836SJohn.Forte@Sun.COM 	int ret;
39637836SJohn.Forte@Sun.COM 	char groupPropListName[MAXNAMELEN];
39647836SJohn.Forte@Sun.COM 	char groupPropName[MAXNAMELEN];
39657836SJohn.Forte@Sun.COM 
39667836SJohn.Forte@Sun.COM 	ret = iPsGetActualGroupName(STMF_TARGET_GROUPS, groupName,
39677836SJohn.Forte@Sun.COM 	    groupPropName);
39687836SJohn.Forte@Sun.COM 	if (ret != STMF_PS_SUCCESS) {
39697836SJohn.Forte@Sun.COM 		return (ret);
39707836SJohn.Forte@Sun.COM 	}
39717836SJohn.Forte@Sun.COM 
39727836SJohn.Forte@Sun.COM 	if (snprintf(groupPropListName, sizeof (groupPropListName),
39737836SJohn.Forte@Sun.COM 	    "%s-%s", groupPropName, STMF_MEMBER_LIST_SUFFIX) >
39747836SJohn.Forte@Sun.COM 	    sizeof (groupPropListName)) {
39757836SJohn.Forte@Sun.COM 		syslog(LOG_ERR, "buffer overflow on property name %s",
39767836SJohn.Forte@Sun.COM 		    groupPropName);
39777836SJohn.Forte@Sun.COM 		return (STMF_PS_ERROR);
39787836SJohn.Forte@Sun.COM 	}
39797836SJohn.Forte@Sun.COM 
39807836SJohn.Forte@Sun.COM 	return (iPsAddRemoveGroupMember(STMF_TARGET_GROUPS, groupPropListName,
39817836SJohn.Forte@Sun.COM 	    memberName, REMOVE));
39827836SJohn.Forte@Sun.COM }
39837836SJohn.Forte@Sun.COM 
39847836SJohn.Forte@Sun.COM /*
39857836SJohn.Forte@Sun.COM  * psGetProviderData
39867836SJohn.Forte@Sun.COM  *
39877836SJohn.Forte@Sun.COM  * Retrieves an nvlist on a per provider basis
39887836SJohn.Forte@Sun.COM  *
39897836SJohn.Forte@Sun.COM  * providerName - property group name to use
39907836SJohn.Forte@Sun.COM  * nvl - nvlist to retrieve
39917836SJohn.Forte@Sun.COM  *
39927836SJohn.Forte@Sun.COM  */
39937836SJohn.Forte@Sun.COM int
psGetProviderData(char * providerName,nvlist_t ** nvl,int providerType,uint64_t * setToken)39947836SJohn.Forte@Sun.COM psGetProviderData(char *providerName, nvlist_t **nvl, int providerType,
39957836SJohn.Forte@Sun.COM     uint64_t *setToken)
39967836SJohn.Forte@Sun.COM {
39977836SJohn.Forte@Sun.COM 	scf_handle_t	*handle = NULL;
39987836SJohn.Forte@Sun.COM 	scf_service_t	*svc = NULL;
39997836SJohn.Forte@Sun.COM 	scf_propertygroup_t	*pg = NULL;
40007836SJohn.Forte@Sun.COM 	scf_property_t	*prop = NULL;
40017836SJohn.Forte@Sun.COM 	scf_value_t	*value = NULL;
40027836SJohn.Forte@Sun.COM 	uint64_t blockCnt = 0;
40037836SJohn.Forte@Sun.COM 	ssize_t blockOffset = 0;
40047836SJohn.Forte@Sun.COM 	ssize_t actualBlockSize = 0;
40057836SJohn.Forte@Sun.COM 	char pgName[MAXPATHLEN];
40067836SJohn.Forte@Sun.COM 	char dataPropertyName[STMF_PROVIDER_DATA_PROP_NAME_SIZE];
40077836SJohn.Forte@Sun.COM 	char *nvlistEncoded = NULL;
40087836SJohn.Forte@Sun.COM 	ssize_t nvlistEncodedSize = 0;
40097836SJohn.Forte@Sun.COM 	boolean_t foundSetCnt = B_TRUE;
40107836SJohn.Forte@Sun.COM 	int i;
40117836SJohn.Forte@Sun.COM 	int ret = STMF_PS_SUCCESS;
40127836SJohn.Forte@Sun.COM 
40137836SJohn.Forte@Sun.COM 	if (providerName == NULL || (providerType != STMF_LU_PROVIDER_TYPE &&
40147836SJohn.Forte@Sun.COM 	    providerType != STMF_PORT_PROVIDER_TYPE)) {
40157836SJohn.Forte@Sun.COM 		ret = STMF_PS_ERROR_INVALID_ARG;
40167836SJohn.Forte@Sun.COM 		goto out;
40177836SJohn.Forte@Sun.COM 	}
40187836SJohn.Forte@Sun.COM 
40197836SJohn.Forte@Sun.COM 	ret = iPsInit(&handle, &svc);
40207836SJohn.Forte@Sun.COM 	if (ret != STMF_PS_SUCCESS) {
40217836SJohn.Forte@Sun.COM 		goto out;
40227836SJohn.Forte@Sun.COM 	}
40237836SJohn.Forte@Sun.COM 
40247836SJohn.Forte@Sun.COM 	/*
40257836SJohn.Forte@Sun.COM 	 * create the property group name
40267836SJohn.Forte@Sun.COM 	 */
40277836SJohn.Forte@Sun.COM 	(void) snprintf(pgName, sizeof (pgName), "%s%s",
40287836SJohn.Forte@Sun.COM 	    STMF_PROVIDER_DATA_PREFIX, providerName);
40297836SJohn.Forte@Sun.COM 
40307836SJohn.Forte@Sun.COM 	/*
40317836SJohn.Forte@Sun.COM 	 * Allocate scf resources
40327836SJohn.Forte@Sun.COM 	 */
40337836SJohn.Forte@Sun.COM 	if (((pg = scf_pg_create(handle)) == NULL) ||
40347836SJohn.Forte@Sun.COM 	    ((value = scf_value_create(handle)) == NULL) ||
40357836SJohn.Forte@Sun.COM 	    ((prop = scf_property_create(handle)) == NULL)) {
40367836SJohn.Forte@Sun.COM 		syslog(LOG_ERR, "scf alloc resource failed - %s",
40377836SJohn.Forte@Sun.COM 		    scf_strerror(scf_error()));
40387836SJohn.Forte@Sun.COM 		ret = STMF_PS_ERROR;
40397836SJohn.Forte@Sun.COM 		goto out;
40407836SJohn.Forte@Sun.COM 	}
40417836SJohn.Forte@Sun.COM 
40427836SJohn.Forte@Sun.COM 	/*
40437836SJohn.Forte@Sun.COM 	 * Retrieve the existing property group.
40447836SJohn.Forte@Sun.COM 	 */
40457836SJohn.Forte@Sun.COM 	if (scf_service_get_pg(svc, pgName, pg) == -1) {
40467836SJohn.Forte@Sun.COM 		if (scf_error() != SCF_ERROR_NOT_FOUND) {
404711909SPeter.Gill@Sun.COM 			syslog(LOG_ERR, "get pg %s failed - %s", pgName,
40487836SJohn.Forte@Sun.COM 			    scf_strerror(scf_error()));
40497836SJohn.Forte@Sun.COM 			ret = STMF_PS_ERROR;
40507836SJohn.Forte@Sun.COM 			goto out;
40517836SJohn.Forte@Sun.COM 		} else {
40527836SJohn.Forte@Sun.COM 			ret = STMF_PS_ERROR_NOT_FOUND;
40537836SJohn.Forte@Sun.COM 			goto out;
40547836SJohn.Forte@Sun.COM 		}
40557836SJohn.Forte@Sun.COM 	}
40567836SJohn.Forte@Sun.COM 
40577836SJohn.Forte@Sun.COM 	/*
40587836SJohn.Forte@Sun.COM 	 * Get the STMF_PROVIDER_DATA_PROP_COUNT property
40597836SJohn.Forte@Sun.COM 	 */
40607836SJohn.Forte@Sun.COM 	if (scf_pg_get_property(pg, STMF_PROVIDER_DATA_PROP_COUNT,
40617836SJohn.Forte@Sun.COM 	    prop) == -1) {
406211909SPeter.Gill@Sun.COM 		syslog(LOG_ERR, "get property %s/%s failed - %s",
406311909SPeter.Gill@Sun.COM 		    pgName, STMF_PROVIDER_DATA_PROP_COUNT,
40647836SJohn.Forte@Sun.COM 		    scf_strerror(scf_error()));
40657836SJohn.Forte@Sun.COM 		ret = STMF_PS_ERROR;
40667836SJohn.Forte@Sun.COM 		goto out;
40677836SJohn.Forte@Sun.COM 	}
40687836SJohn.Forte@Sun.COM 
40697836SJohn.Forte@Sun.COM 	/*
40707836SJohn.Forte@Sun.COM 	 * Get the STMF_PROVIDER_DATA_PROP_COUNT value
40717836SJohn.Forte@Sun.COM 	 */
40727836SJohn.Forte@Sun.COM 	if (scf_property_get_value(prop, value) == -1) {
407311909SPeter.Gill@Sun.COM 		syslog(LOG_ERR, "get property value %s/%s failed - %s",
407411909SPeter.Gill@Sun.COM 		    pgName, STMF_PROVIDER_DATA_PROP_COUNT,
40757836SJohn.Forte@Sun.COM 		    scf_strerror(scf_error()));
40767836SJohn.Forte@Sun.COM 		ret = STMF_PS_ERROR;
40777836SJohn.Forte@Sun.COM 		goto out;
40787836SJohn.Forte@Sun.COM 	}
40797836SJohn.Forte@Sun.COM 
40807836SJohn.Forte@Sun.COM 	/*
40817836SJohn.Forte@Sun.COM 	 * Now get the actual value from the value handle
40827836SJohn.Forte@Sun.COM 	 */
40837836SJohn.Forte@Sun.COM 	if (scf_value_get_count(value, &blockCnt) == -1) {
408411909SPeter.Gill@Sun.COM 		syslog(LOG_ERR, "get integer value %s/%s failed - %s",
408511909SPeter.Gill@Sun.COM 		    pgName, STMF_PROVIDER_DATA_PROP_COUNT,
40867836SJohn.Forte@Sun.COM 		    scf_strerror(scf_error()));
40877836SJohn.Forte@Sun.COM 		ret = STMF_PS_ERROR;
40887836SJohn.Forte@Sun.COM 		goto out;
40897836SJohn.Forte@Sun.COM 	}
40907836SJohn.Forte@Sun.COM 
40917836SJohn.Forte@Sun.COM 	/* Has the caller requested the token to be set? */
40927836SJohn.Forte@Sun.COM 	if (setToken) {
40937836SJohn.Forte@Sun.COM 		/*
40947836SJohn.Forte@Sun.COM 		 * Get the STMF_PROVIDER_DATA_PROP_SET_COUNT property
40957836SJohn.Forte@Sun.COM 		 * If it doesn't exist, we assume it to be zero.
40967836SJohn.Forte@Sun.COM 		 */
40977836SJohn.Forte@Sun.COM 		*setToken = 0;
40987836SJohn.Forte@Sun.COM 		if (scf_pg_get_property(pg, STMF_PROVIDER_DATA_PROP_SET_COUNT,
40997836SJohn.Forte@Sun.COM 		    prop) == -1) {
41007836SJohn.Forte@Sun.COM 			if (scf_error() == SCF_ERROR_NOT_FOUND) {
41017836SJohn.Forte@Sun.COM 				foundSetCnt = B_FALSE;
41027836SJohn.Forte@Sun.COM 			} else {
410311909SPeter.Gill@Sun.COM 				syslog(LOG_ERR, "get property %s/%s "
410411909SPeter.Gill@Sun.COM 				    "failed - %s", pgName,
410511909SPeter.Gill@Sun.COM 				    STMF_PROVIDER_DATA_PROP_SET_COUNT,
41067836SJohn.Forte@Sun.COM 				    scf_strerror(scf_error()));
41077836SJohn.Forte@Sun.COM 				ret = STMF_PS_ERROR;
41087836SJohn.Forte@Sun.COM 				goto out;
41097836SJohn.Forte@Sun.COM 			}
41107836SJohn.Forte@Sun.COM 		}
41117836SJohn.Forte@Sun.COM 
41127836SJohn.Forte@Sun.COM 		if (foundSetCnt) {
41137836SJohn.Forte@Sun.COM 			/*
41147836SJohn.Forte@Sun.COM 			 * Get the STMF_PROVIDER_DATA_PROP_SET_COUNT value
41157836SJohn.Forte@Sun.COM 			 */
41167836SJohn.Forte@Sun.COM 			if (scf_property_get_value(prop, value) == -1) {
41177836SJohn.Forte@Sun.COM 				syslog(LOG_ERR,
411811909SPeter.Gill@Sun.COM 				    "get property value %s/%s failed - %s",
411911909SPeter.Gill@Sun.COM 				    pgName, STMF_PROVIDER_DATA_PROP_SET_COUNT,
41207836SJohn.Forte@Sun.COM 				    scf_strerror(scf_error()));
41217836SJohn.Forte@Sun.COM 				ret = STMF_PS_ERROR;
41227836SJohn.Forte@Sun.COM 				goto out;
41237836SJohn.Forte@Sun.COM 			}
41247836SJohn.Forte@Sun.COM 
41257836SJohn.Forte@Sun.COM 			/*
41267836SJohn.Forte@Sun.COM 			 * Now get the actual value from the value handle
41277836SJohn.Forte@Sun.COM 			 * and set the caller's token
41287836SJohn.Forte@Sun.COM 			 */
41297836SJohn.Forte@Sun.COM 			if (scf_value_get_count(value, setToken) == -1) {
41307836SJohn.Forte@Sun.COM 				syslog(LOG_ERR,
413111909SPeter.Gill@Sun.COM 				    "get integer value %s/%s failed - %s",
413211909SPeter.Gill@Sun.COM 				    pgName, STMF_PROVIDER_DATA_PROP_SET_COUNT,
41337836SJohn.Forte@Sun.COM 				    scf_strerror(scf_error()));
41347836SJohn.Forte@Sun.COM 				ret = STMF_PS_ERROR;
41357836SJohn.Forte@Sun.COM 				goto out;
41367836SJohn.Forte@Sun.COM 			}
41377836SJohn.Forte@Sun.COM 		}
41387836SJohn.Forte@Sun.COM 	}
41397836SJohn.Forte@Sun.COM 
41407836SJohn.Forte@Sun.COM 	nvlistEncoded = (char *)calloc(1,
41417836SJohn.Forte@Sun.COM 	    blockCnt * STMF_PROVIDER_DATA_PROP_SIZE);
41427836SJohn.Forte@Sun.COM 	if (nvlistEncoded == NULL) {
41437836SJohn.Forte@Sun.COM 		syslog(LOG_ERR, "nvlistEncoded alloc failed");
41447836SJohn.Forte@Sun.COM 		ret = STMF_PS_ERROR_NOMEM;
41457836SJohn.Forte@Sun.COM 		goto out;
41467836SJohn.Forte@Sun.COM 	}
41477836SJohn.Forte@Sun.COM 
41487836SJohn.Forte@Sun.COM 	for (i = 0; i < blockCnt; i++) {
41497836SJohn.Forte@Sun.COM 		bzero(dataPropertyName, sizeof (dataPropertyName));
41507836SJohn.Forte@Sun.COM 		/*
41517836SJohn.Forte@Sun.COM 		 * create the name to use for the property
41527836SJohn.Forte@Sun.COM 		 */
41537836SJohn.Forte@Sun.COM 		(void) snprintf(dataPropertyName, sizeof (dataPropertyName),
41547836SJohn.Forte@Sun.COM 		    "%s-%d", STMF_PROVIDER_DATA_PROP_PREFIX, i);
41557836SJohn.Forte@Sun.COM 
41567836SJohn.Forte@Sun.COM 		if (scf_pg_get_property(pg, dataPropertyName, prop) == -1) {
415711909SPeter.Gill@Sun.COM 			syslog(LOG_ERR, "get property %s/%s failed - %s",
415811909SPeter.Gill@Sun.COM 			    pgName, dataPropertyName,
41597836SJohn.Forte@Sun.COM 			    scf_strerror(scf_error()));
41607836SJohn.Forte@Sun.COM 			ret = STMF_PS_ERROR;
41617836SJohn.Forte@Sun.COM 			goto out;
41627836SJohn.Forte@Sun.COM 		}
41637836SJohn.Forte@Sun.COM 
41647836SJohn.Forte@Sun.COM 		if (scf_property_get_value(prop, value) == -1) {
416511909SPeter.Gill@Sun.COM 			syslog(LOG_ERR, "get property value %s/%s failed - %s",
416611909SPeter.Gill@Sun.COM 			    pgName, dataPropertyName,
41677836SJohn.Forte@Sun.COM 			    scf_strerror(scf_error()));
41687836SJohn.Forte@Sun.COM 			ret = STMF_PS_ERROR;
41697836SJohn.Forte@Sun.COM 			goto out;
41707836SJohn.Forte@Sun.COM 		}
41717836SJohn.Forte@Sun.COM 
41727836SJohn.Forte@Sun.COM 		/*
41737836SJohn.Forte@Sun.COM 		 * Set the data block offset
41747836SJohn.Forte@Sun.COM 		 */
41757836SJohn.Forte@Sun.COM 		blockOffset = STMF_PROVIDER_DATA_PROP_SIZE * i;
41767836SJohn.Forte@Sun.COM 		actualBlockSize = scf_value_get_opaque(value,
41777836SJohn.Forte@Sun.COM 		    &nvlistEncoded[blockOffset], STMF_PROVIDER_DATA_PROP_SIZE);
41787836SJohn.Forte@Sun.COM 		if (actualBlockSize == -1) {
417911909SPeter.Gill@Sun.COM 			syslog(LOG_ERR, "get opaque property value %s/%s "
418011909SPeter.Gill@Sun.COM 			    "failed - %s", pgName, dataPropertyName,
41817836SJohn.Forte@Sun.COM 			    scf_strerror(scf_error()));
41827836SJohn.Forte@Sun.COM 			ret = STMF_PS_ERROR;
41837836SJohn.Forte@Sun.COM 			goto out;
41847836SJohn.Forte@Sun.COM 		}
41857836SJohn.Forte@Sun.COM 		nvlistEncodedSize += actualBlockSize;
41867836SJohn.Forte@Sun.COM 	}
41877836SJohn.Forte@Sun.COM 
41887836SJohn.Forte@Sun.COM 	if (nvlist_unpack(nvlistEncoded, nvlistEncodedSize, nvl, 0) != 0) {
41897836SJohn.Forte@Sun.COM 		syslog(LOG_ERR, "unable to unpack nvlist");
41907836SJohn.Forte@Sun.COM 		ret = STMF_PS_ERROR;
41917836SJohn.Forte@Sun.COM 		goto out;
41927836SJohn.Forte@Sun.COM 	}
41937836SJohn.Forte@Sun.COM 
41947836SJohn.Forte@Sun.COM 
41957836SJohn.Forte@Sun.COM out:
41967836SJohn.Forte@Sun.COM 	/*
41977836SJohn.Forte@Sun.COM 	 * Free resources
41987836SJohn.Forte@Sun.COM 	 */
41997836SJohn.Forte@Sun.COM 	if (handle != NULL) {
42007836SJohn.Forte@Sun.COM 		scf_handle_destroy(handle);
42017836SJohn.Forte@Sun.COM 	}
42027836SJohn.Forte@Sun.COM 	if (svc != NULL) {
42037836SJohn.Forte@Sun.COM 		scf_service_destroy(svc);
42047836SJohn.Forte@Sun.COM 	}
42057836SJohn.Forte@Sun.COM 	if (pg != NULL) {
42067836SJohn.Forte@Sun.COM 		scf_pg_destroy(pg);
42077836SJohn.Forte@Sun.COM 	}
42087836SJohn.Forte@Sun.COM 	if (prop != NULL) {
42097836SJohn.Forte@Sun.COM 		scf_property_destroy(prop);
42107836SJohn.Forte@Sun.COM 	}
42117836SJohn.Forte@Sun.COM 	if (value != NULL) {
42127836SJohn.Forte@Sun.COM 		scf_value_destroy(value);
42137836SJohn.Forte@Sun.COM 	}
42147836SJohn.Forte@Sun.COM 	if (nvlistEncoded != NULL) {
42157836SJohn.Forte@Sun.COM 		free(nvlistEncoded);
42167836SJohn.Forte@Sun.COM 	}
42177836SJohn.Forte@Sun.COM 
42187836SJohn.Forte@Sun.COM 	return (ret);
42197836SJohn.Forte@Sun.COM 
42207836SJohn.Forte@Sun.COM }
42217836SJohn.Forte@Sun.COM /*
42227836SJohn.Forte@Sun.COM  * psGetProviderDataList
42237836SJohn.Forte@Sun.COM  *
42247836SJohn.Forte@Sun.COM  * Retrieves the list of providers that currently store persistent data
42257836SJohn.Forte@Sun.COM  *
42267836SJohn.Forte@Sun.COM  * providerList - pointer to a pointer to an stmfProviderList structure
42277836SJohn.Forte@Sun.COM  *                On success, this will contain the list of providers
42287836SJohn.Forte@Sun.COM  *                currently storing persistent data.
42297836SJohn.Forte@Sun.COM  */
42307836SJohn.Forte@Sun.COM int
psGetProviderDataList(stmfProviderList ** providerList)42317836SJohn.Forte@Sun.COM psGetProviderDataList(stmfProviderList **providerList)
42327836SJohn.Forte@Sun.COM {
42337836SJohn.Forte@Sun.COM 	scf_handle_t *handle = NULL;
42347836SJohn.Forte@Sun.COM 	scf_service_t *svc = NULL;
42357836SJohn.Forte@Sun.COM 	scf_propertygroup_t *pg = NULL;
42367836SJohn.Forte@Sun.COM 	scf_property_t *prop = NULL;
42377836SJohn.Forte@Sun.COM 	scf_value_t *value = NULL;
42387836SJohn.Forte@Sun.COM 	scf_iter_t *pgIter = NULL;
42397836SJohn.Forte@Sun.COM 	char buf[MAXNAMELEN];
42407836SJohn.Forte@Sun.COM 	int providerCnt = 0;
42417836SJohn.Forte@Sun.COM 	int64_t providerType;
42427836SJohn.Forte@Sun.COM 	int i = 0, j;
42437836SJohn.Forte@Sun.COM 	int ret = STMF_PS_SUCCESS;
42447836SJohn.Forte@Sun.COM 
42457836SJohn.Forte@Sun.COM 	ret = iPsInit(&handle, &svc);
42467836SJohn.Forte@Sun.COM 	if (ret != STMF_PS_SUCCESS) {
42477836SJohn.Forte@Sun.COM 		goto out;
42487836SJohn.Forte@Sun.COM 	}
42497836SJohn.Forte@Sun.COM 
42507836SJohn.Forte@Sun.COM 	*providerList = NULL;
42517836SJohn.Forte@Sun.COM 
42527836SJohn.Forte@Sun.COM 	/*
42537836SJohn.Forte@Sun.COM 	 * Allocate scf resources
42547836SJohn.Forte@Sun.COM 	 */
42557836SJohn.Forte@Sun.COM 	if (((pg = scf_pg_create(handle)) == NULL) ||
42567836SJohn.Forte@Sun.COM 	    ((value = scf_value_create(handle)) == NULL) ||
42577836SJohn.Forte@Sun.COM 	    ((prop = scf_property_create(handle)) == NULL) ||
42587836SJohn.Forte@Sun.COM 	    ((pgIter = scf_iter_create(handle)) == NULL)) {
42597836SJohn.Forte@Sun.COM 		syslog(LOG_ERR, "scf alloc resource failed - %s",
42607836SJohn.Forte@Sun.COM 		    scf_strerror(scf_error()));
42617836SJohn.Forte@Sun.COM 		ret = STMF_PS_ERROR;
42627836SJohn.Forte@Sun.COM 		goto out;
42637836SJohn.Forte@Sun.COM 	}
42647836SJohn.Forte@Sun.COM 
42657836SJohn.Forte@Sun.COM 	/*
42667836SJohn.Forte@Sun.COM 	 * pgIter is the iterator handle
42677836SJohn.Forte@Sun.COM 	 */
42687836SJohn.Forte@Sun.COM 	if (scf_iter_service_pgs(pgIter, svc) == -1) {
42697836SJohn.Forte@Sun.COM 		syslog(LOG_ERR, "iter property groups failed - %s",
42707836SJohn.Forte@Sun.COM 		    scf_strerror(scf_error()));
42717836SJohn.Forte@Sun.COM 		ret = STMF_PS_ERROR;
42727836SJohn.Forte@Sun.COM 		goto out;
42737836SJohn.Forte@Sun.COM 	}
42747836SJohn.Forte@Sun.COM 
42757836SJohn.Forte@Sun.COM 	while (scf_iter_next_pg(pgIter, pg) == 1) {
42767836SJohn.Forte@Sun.COM 		if (scf_pg_get_name(pg, buf, sizeof (buf)) == -1) {
42777836SJohn.Forte@Sun.COM 			syslog(LOG_ERR, "get name failed - %s",
42787836SJohn.Forte@Sun.COM 			    scf_strerror(scf_error()));
42797836SJohn.Forte@Sun.COM 			ret = STMF_PS_ERROR;
42807836SJohn.Forte@Sun.COM 			break;
42817836SJohn.Forte@Sun.COM 		}
42827836SJohn.Forte@Sun.COM 		/*
42837836SJohn.Forte@Sun.COM 		 * Only count LU property groups
42847836SJohn.Forte@Sun.COM 		 */
42857836SJohn.Forte@Sun.COM 		if (strncmp(buf, STMF_PROVIDER_DATA_PREFIX,
42867836SJohn.Forte@Sun.COM 		    strlen(STMF_PROVIDER_DATA_PREFIX)) == 0) {
42877836SJohn.Forte@Sun.COM 			providerCnt++;
42887836SJohn.Forte@Sun.COM 		}
42897836SJohn.Forte@Sun.COM 	}
42907836SJohn.Forte@Sun.COM 
42917836SJohn.Forte@Sun.COM 	/*
42927836SJohn.Forte@Sun.COM 	 * pgIter is the iterator handle
42937836SJohn.Forte@Sun.COM 	 */
42947836SJohn.Forte@Sun.COM 	if (scf_iter_service_pgs(pgIter, svc) == -1) {
42957836SJohn.Forte@Sun.COM 		syslog(LOG_ERR, "iter property groups failed - %s",
42967836SJohn.Forte@Sun.COM 		    scf_strerror(scf_error()));
42977836SJohn.Forte@Sun.COM 		ret = STMF_PS_ERROR;
42987836SJohn.Forte@Sun.COM 		goto out;
42997836SJohn.Forte@Sun.COM 	}
43007836SJohn.Forte@Sun.COM 
43017836SJohn.Forte@Sun.COM 	*providerList = (stmfProviderList *)calloc(1,
43027836SJohn.Forte@Sun.COM 	    sizeof (stmfProviderList) + providerCnt * sizeof (stmfProvider));
43037836SJohn.Forte@Sun.COM 	if (*providerList == NULL) {
43047836SJohn.Forte@Sun.COM 		ret = STMF_PS_ERROR_NOMEM;
43057836SJohn.Forte@Sun.COM 		goto out;
43067836SJohn.Forte@Sun.COM 	}
43077836SJohn.Forte@Sun.COM 
43087836SJohn.Forte@Sun.COM 	/*
43097836SJohn.Forte@Sun.COM 	 * it's possible for entries to be added/removed while we're retrieving
43107836SJohn.Forte@Sun.COM 	 * the property groups. Just make sure we don't write beyond our
43117836SJohn.Forte@Sun.COM 	 * allocated buffer by checking to ensure i < providerCnt.
43127836SJohn.Forte@Sun.COM 	 */
43137836SJohn.Forte@Sun.COM 	while ((scf_iter_next_pg(pgIter, pg) == 1) && (i < providerCnt)) {
43147836SJohn.Forte@Sun.COM 		if (scf_pg_get_name(pg, buf, sizeof (buf)) == -1) {
43157836SJohn.Forte@Sun.COM 			syslog(LOG_ERR, "get name failed - %s",
43167836SJohn.Forte@Sun.COM 			    scf_strerror(scf_error()));
43177836SJohn.Forte@Sun.COM 			ret = STMF_PS_ERROR;
43187836SJohn.Forte@Sun.COM 			break;
43197836SJohn.Forte@Sun.COM 		}
43207836SJohn.Forte@Sun.COM 		/*
43217836SJohn.Forte@Sun.COM 		 * Only use provider data property groups
43227836SJohn.Forte@Sun.COM 		 */
43237836SJohn.Forte@Sun.COM 		if (strncmp(buf, STMF_PROVIDER_DATA_PREFIX,
43247836SJohn.Forte@Sun.COM 		    strlen(STMF_PROVIDER_DATA_PREFIX)) != 0) {
43257836SJohn.Forte@Sun.COM 			continue;
43267836SJohn.Forte@Sun.COM 		}
43277836SJohn.Forte@Sun.COM 
43287836SJohn.Forte@Sun.COM 		/*
43297836SJohn.Forte@Sun.COM 		 * Get the STMF_PROVIDER_DATA_PROP_TYPE property
43307836SJohn.Forte@Sun.COM 		 */
43317836SJohn.Forte@Sun.COM 		if (scf_pg_get_property(pg, STMF_PROVIDER_DATA_PROP_TYPE,
43327836SJohn.Forte@Sun.COM 		    prop) == -1) {
433311909SPeter.Gill@Sun.COM 			syslog(LOG_ERR, "get property %s/%s failed - %s",
433411909SPeter.Gill@Sun.COM 			    buf, STMF_PROVIDER_DATA_PROP_TYPE,
43357836SJohn.Forte@Sun.COM 			    scf_strerror(scf_error()));
43367836SJohn.Forte@Sun.COM 			ret = STMF_PS_ERROR;
43377836SJohn.Forte@Sun.COM 			break;
43387836SJohn.Forte@Sun.COM 		}
43397836SJohn.Forte@Sun.COM 
43407836SJohn.Forte@Sun.COM 		/*
43417836SJohn.Forte@Sun.COM 		 * Get the STMF_PROVIDER_DATA_PROP_TYPE value
43427836SJohn.Forte@Sun.COM 		 */
43437836SJohn.Forte@Sun.COM 		if (scf_property_get_value(prop, value) == -1) {
434411909SPeter.Gill@Sun.COM 			syslog(LOG_ERR, "get property value %s/%s failed - %s",
434511909SPeter.Gill@Sun.COM 			    buf, STMF_PROVIDER_DATA_PROP_TYPE,
43467836SJohn.Forte@Sun.COM 			    scf_strerror(scf_error()));
43477836SJohn.Forte@Sun.COM 			ret = STMF_PS_ERROR;
43487836SJohn.Forte@Sun.COM 			break;
43497836SJohn.Forte@Sun.COM 		}
43507836SJohn.Forte@Sun.COM 
43517836SJohn.Forte@Sun.COM 		/*
43527836SJohn.Forte@Sun.COM 		 * Now get the actual value from the value handle
43537836SJohn.Forte@Sun.COM 		 */
43547836SJohn.Forte@Sun.COM 		if (scf_value_get_integer(value, &providerType) == -1) {
435511909SPeter.Gill@Sun.COM 			syslog(LOG_ERR, "get integer value %s/%s failed - %s",
435611909SPeter.Gill@Sun.COM 			    buf, STMF_PROVIDER_DATA_PROP_TYPE,
43577836SJohn.Forte@Sun.COM 			    scf_strerror(scf_error()));
43587836SJohn.Forte@Sun.COM 			ret = STMF_PS_ERROR;
43597836SJohn.Forte@Sun.COM 			break;
43607836SJohn.Forte@Sun.COM 		}
43617836SJohn.Forte@Sun.COM 
43627836SJohn.Forte@Sun.COM 		(*providerList)->provider[i].providerType = providerType;
43637836SJohn.Forte@Sun.COM 
43647836SJohn.Forte@Sun.COM 		/* determine offset for copy of provider name */
43657836SJohn.Forte@Sun.COM 		j = strlen(STMF_PROVIDER_DATA_PREFIX);
43667836SJohn.Forte@Sun.COM 
43677836SJohn.Forte@Sun.COM 		/* copy provider name to caller's list */
43687836SJohn.Forte@Sun.COM 		(void) strncpy((*providerList)->provider[i].name, buf + j,
43697836SJohn.Forte@Sun.COM 		    sizeof ((*providerList)->provider[i].name));
43707836SJohn.Forte@Sun.COM 		i++;
43717836SJohn.Forte@Sun.COM 		(*providerList)->cnt++;
43727836SJohn.Forte@Sun.COM 	}
43737836SJohn.Forte@Sun.COM 
43747836SJohn.Forte@Sun.COM 	if (ret != STMF_PS_SUCCESS) {
43757836SJohn.Forte@Sun.COM 		free(*providerList);
43767836SJohn.Forte@Sun.COM 		goto out;
43777836SJohn.Forte@Sun.COM 	}
43787836SJohn.Forte@Sun.COM 
43797836SJohn.Forte@Sun.COM out:
43807836SJohn.Forte@Sun.COM 	/*
43817836SJohn.Forte@Sun.COM 	 * Free resources
43827836SJohn.Forte@Sun.COM 	 */
43837836SJohn.Forte@Sun.COM 	if (handle != NULL) {
43847836SJohn.Forte@Sun.COM 		scf_handle_destroy(handle);
43857836SJohn.Forte@Sun.COM 	}
43867836SJohn.Forte@Sun.COM 	if (svc != NULL) {
43877836SJohn.Forte@Sun.COM 		scf_service_destroy(svc);
43887836SJohn.Forte@Sun.COM 	}
43897836SJohn.Forte@Sun.COM 	if (pg != NULL) {
43907836SJohn.Forte@Sun.COM 		scf_pg_destroy(pg);
43917836SJohn.Forte@Sun.COM 	}
43927836SJohn.Forte@Sun.COM 	if (value != NULL) {
43937836SJohn.Forte@Sun.COM 		scf_value_destroy(value);
43947836SJohn.Forte@Sun.COM 	}
43957836SJohn.Forte@Sun.COM 	if (prop != NULL) {
43967836SJohn.Forte@Sun.COM 		scf_property_destroy(prop);
43977836SJohn.Forte@Sun.COM 	}
43987836SJohn.Forte@Sun.COM 	if (pgIter != NULL) {
43997836SJohn.Forte@Sun.COM 		scf_iter_destroy(pgIter);
44007836SJohn.Forte@Sun.COM 	}
44017836SJohn.Forte@Sun.COM 
44027836SJohn.Forte@Sun.COM 	return (ret);
44037836SJohn.Forte@Sun.COM }
44047836SJohn.Forte@Sun.COM 
44057836SJohn.Forte@Sun.COM 
44067836SJohn.Forte@Sun.COM /*
44077836SJohn.Forte@Sun.COM  * psSetProviderData
44087836SJohn.Forte@Sun.COM  *
44097836SJohn.Forte@Sun.COM  * Stores a packed nvlist on a per provider basis
44107836SJohn.Forte@Sun.COM  *
44117836SJohn.Forte@Sun.COM  * providerName - property group name to use
44127836SJohn.Forte@Sun.COM  * nvl - nvlist to store
44137836SJohn.Forte@Sun.COM  * providerType - type of provider (logical unit or port)
44147836SJohn.Forte@Sun.COM  *
44157836SJohn.Forte@Sun.COM  */
44167836SJohn.Forte@Sun.COM int
psSetProviderData(char * providerName,nvlist_t * nvl,int providerType,uint64_t * setToken)44177836SJohn.Forte@Sun.COM psSetProviderData(char *providerName, nvlist_t *nvl, int providerType,
44187836SJohn.Forte@Sun.COM     uint64_t *setToken)
44197836SJohn.Forte@Sun.COM {
44207836SJohn.Forte@Sun.COM 	scf_handle_t	*handle = NULL;
44217836SJohn.Forte@Sun.COM 	scf_service_t	*svc = NULL;
44227836SJohn.Forte@Sun.COM 	scf_propertygroup_t	*pg = NULL;
44237836SJohn.Forte@Sun.COM 	scf_property_t	*prop = NULL;
44247836SJohn.Forte@Sun.COM 	scf_transaction_t *tran = NULL;
44257836SJohn.Forte@Sun.COM 	/* represents arrays of entry and value pointers for scf */
44267836SJohn.Forte@Sun.COM 	scf_transaction_entry_t	**addEntry = NULL;
44277836SJohn.Forte@Sun.COM 	scf_transaction_entry_t	**deleteEntry = NULL;
44287836SJohn.Forte@Sun.COM 	scf_value_t **addValue = NULL;
44297836SJohn.Forte@Sun.COM 
44307836SJohn.Forte@Sun.COM 	/*
44317836SJohn.Forte@Sun.COM 	 * These declarations are for known entry and value set/get
44327836SJohn.Forte@Sun.COM 	 * operations
44337836SJohn.Forte@Sun.COM 	 */
44347836SJohn.Forte@Sun.COM 	scf_transaction_entry_t *entry1 = NULL;
44357836SJohn.Forte@Sun.COM 	scf_transaction_entry_t *entry2 = NULL;
44367836SJohn.Forte@Sun.COM 	scf_transaction_entry_t *entry3 = NULL;
44377836SJohn.Forte@Sun.COM 	scf_transaction_entry_t *entry5 = NULL;
44387836SJohn.Forte@Sun.COM 	scf_value_t *value1 = NULL;
44397836SJohn.Forte@Sun.COM 	scf_value_t *value2 = NULL;
44407836SJohn.Forte@Sun.COM 	scf_value_t *value3 = NULL;
44417836SJohn.Forte@Sun.COM 	scf_value_t *value4 = NULL;
44427836SJohn.Forte@Sun.COM 	scf_value_t *value5 = NULL;
44437836SJohn.Forte@Sun.COM 
44447836SJohn.Forte@Sun.COM 	boolean_t newPg = B_FALSE;
44457836SJohn.Forte@Sun.COM 	char pgName[MAXPATHLEN];
44467836SJohn.Forte@Sun.COM 	char dataPropertyName[STMF_PROVIDER_DATA_PROP_NAME_SIZE];
44477836SJohn.Forte@Sun.COM 	char *nvlistEncoded = NULL;
44487836SJohn.Forte@Sun.COM 	size_t nvlistEncodedSize;
44497836SJohn.Forte@Sun.COM 	size_t blockSize;
44507836SJohn.Forte@Sun.COM 	int i, j = 0;
44517836SJohn.Forte@Sun.COM 	int addEntryAlloc = 0, deleteEntryAlloc = 0, addValueAlloc = 0;
44527836SJohn.Forte@Sun.COM 	int blockOffset;
44537836SJohn.Forte@Sun.COM 	uint64_t oldBlockCnt = 0;
44547836SJohn.Forte@Sun.COM 	uint64_t blockCnt = 0;
44557836SJohn.Forte@Sun.COM 	uint64_t setCnt = 0;
44567836SJohn.Forte@Sun.COM 	boolean_t foundSetCnt = B_TRUE;
44577836SJohn.Forte@Sun.COM 	int ret = STMF_PS_SUCCESS;
44587836SJohn.Forte@Sun.COM 	int commitRet;
44597836SJohn.Forte@Sun.COM 
44607836SJohn.Forte@Sun.COM 	if (providerName == NULL || (providerType != STMF_LU_PROVIDER_TYPE &&
44617836SJohn.Forte@Sun.COM 	    providerType != STMF_PORT_PROVIDER_TYPE)) {
44627836SJohn.Forte@Sun.COM 		ret = STMF_PS_ERROR_INVALID_ARG;
44637836SJohn.Forte@Sun.COM 		goto out;
44647836SJohn.Forte@Sun.COM 	}
44657836SJohn.Forte@Sun.COM 
44667836SJohn.Forte@Sun.COM 	ret = iPsInit(&handle, &svc);
44677836SJohn.Forte@Sun.COM 	if (ret != STMF_PS_SUCCESS) {
44687836SJohn.Forte@Sun.COM 		goto out;
44697836SJohn.Forte@Sun.COM 	}
44707836SJohn.Forte@Sun.COM 
44717836SJohn.Forte@Sun.COM 	bzero(pgName, sizeof (pgName));
44727836SJohn.Forte@Sun.COM 	/*
44737836SJohn.Forte@Sun.COM 	 * create the property group name
44747836SJohn.Forte@Sun.COM 	 */
44757836SJohn.Forte@Sun.COM 	(void) snprintf(pgName, sizeof (pgName), "%s%s",
44767836SJohn.Forte@Sun.COM 	    STMF_PROVIDER_DATA_PREFIX, providerName);
44777836SJohn.Forte@Sun.COM 
44787836SJohn.Forte@Sun.COM 	/*
44797836SJohn.Forte@Sun.COM 	 * Allocate scf resources
44807836SJohn.Forte@Sun.COM 	 */
44817836SJohn.Forte@Sun.COM 	if (((pg = scf_pg_create(handle)) == NULL) ||
44827836SJohn.Forte@Sun.COM 	    ((entry1 = scf_entry_create(handle)) == NULL) ||
44837836SJohn.Forte@Sun.COM 	    ((entry2 = scf_entry_create(handle)) == NULL) ||
44847836SJohn.Forte@Sun.COM 	    ((entry3 = scf_entry_create(handle)) == NULL) ||
44857836SJohn.Forte@Sun.COM 	    ((entry5 = scf_entry_create(handle)) == NULL) ||
44867836SJohn.Forte@Sun.COM 	    ((value1 = scf_value_create(handle)) == NULL) ||
44877836SJohn.Forte@Sun.COM 	    ((value2 = scf_value_create(handle)) == NULL) ||
44887836SJohn.Forte@Sun.COM 	    ((value3 = scf_value_create(handle)) == NULL) ||
44897836SJohn.Forte@Sun.COM 	    ((value4 = scf_value_create(handle)) == NULL) ||
44907836SJohn.Forte@Sun.COM 	    ((value5 = scf_value_create(handle)) == NULL) ||
44917836SJohn.Forte@Sun.COM 	    ((prop = scf_property_create(handle)) == NULL) ||
44927836SJohn.Forte@Sun.COM 	    ((tran = scf_transaction_create(handle)) == NULL)) {
44937836SJohn.Forte@Sun.COM 		syslog(LOG_ERR, "scf alloc resource failed - %s",
44947836SJohn.Forte@Sun.COM 		    scf_strerror(scf_error()));
44957836SJohn.Forte@Sun.COM 		ret = STMF_PS_ERROR;
44967836SJohn.Forte@Sun.COM 		goto out;
44977836SJohn.Forte@Sun.COM 	}
44987836SJohn.Forte@Sun.COM 
44997836SJohn.Forte@Sun.COM 	/*
45007836SJohn.Forte@Sun.COM 	 * Get the existing property group
45017836SJohn.Forte@Sun.COM 	 */
45027836SJohn.Forte@Sun.COM 	if (scf_service_get_pg(svc, pgName, pg) == -1) {
45037836SJohn.Forte@Sun.COM 		if (scf_error() != SCF_ERROR_NOT_FOUND) {
450411909SPeter.Gill@Sun.COM 			syslog(LOG_ERR, "get pg %s failed - %s",
450511909SPeter.Gill@Sun.COM 			    pgName, scf_strerror(scf_error()));
45067836SJohn.Forte@Sun.COM 			ret = STMF_PS_ERROR;
45077836SJohn.Forte@Sun.COM 			goto out;
45087836SJohn.Forte@Sun.COM 		} else {
45097836SJohn.Forte@Sun.COM 			/*
45107836SJohn.Forte@Sun.COM 			 * create the property group.
45117836SJohn.Forte@Sun.COM 			 */
45127836SJohn.Forte@Sun.COM 			if (scf_service_add_pg(svc, pgName,
45137836SJohn.Forte@Sun.COM 			    SCF_GROUP_APPLICATION, 0, pg) == -1) {
451411909SPeter.Gill@Sun.COM 				syslog(LOG_ERR, "add pg %s failed - %s",
451511909SPeter.Gill@Sun.COM 				    pgName, scf_strerror(scf_error()));
45167836SJohn.Forte@Sun.COM 				ret = STMF_PS_ERROR;
45177836SJohn.Forte@Sun.COM 				goto out;
45187836SJohn.Forte@Sun.COM 			}
45197836SJohn.Forte@Sun.COM 			newPg = B_TRUE;
45207836SJohn.Forte@Sun.COM 		}
45217836SJohn.Forte@Sun.COM 	}
45227836SJohn.Forte@Sun.COM 
45237836SJohn.Forte@Sun.COM 	/*
45247836SJohn.Forte@Sun.COM 	 * Begin the transaction
45257836SJohn.Forte@Sun.COM 	 */
45267836SJohn.Forte@Sun.COM 	if (scf_transaction_start(tran, pg) == -1) {
452711909SPeter.Gill@Sun.COM 		syslog(LOG_ERR, "start transaction for %s failed - %s",
452811909SPeter.Gill@Sun.COM 		    pgName, scf_strerror(scf_error()));
45297836SJohn.Forte@Sun.COM 		ret = STMF_PS_ERROR;
45307836SJohn.Forte@Sun.COM 		goto out;
45317836SJohn.Forte@Sun.COM 	}
45327836SJohn.Forte@Sun.COM 
45337836SJohn.Forte@Sun.COM 	if (!newPg) {
45347836SJohn.Forte@Sun.COM 		/*
45357836SJohn.Forte@Sun.COM 		 * Get the STMF_PROVIDER_DATA_PROP_COUNT property
45367836SJohn.Forte@Sun.COM 		 */
45377836SJohn.Forte@Sun.COM 		if (scf_pg_get_property(pg, STMF_PROVIDER_DATA_PROP_COUNT,
45387836SJohn.Forte@Sun.COM 		    prop) == -1) {
453911909SPeter.Gill@Sun.COM 			syslog(LOG_ERR, "get property %s/%s failed - %s",
454011909SPeter.Gill@Sun.COM 			    pgName, STMF_PROVIDER_DATA_PROP_COUNT,
45417836SJohn.Forte@Sun.COM 			    scf_strerror(scf_error()));
45427836SJohn.Forte@Sun.COM 			ret = STMF_PS_ERROR;
45437836SJohn.Forte@Sun.COM 			goto out;
45447836SJohn.Forte@Sun.COM 		}
45457836SJohn.Forte@Sun.COM 
45467836SJohn.Forte@Sun.COM 		/*
45477836SJohn.Forte@Sun.COM 		 * Get the STMF_PROVIDER_DATA_PROP_COUNT value
45487836SJohn.Forte@Sun.COM 		 */
45497836SJohn.Forte@Sun.COM 		if (scf_property_get_value(prop, value4) == -1) {
455011909SPeter.Gill@Sun.COM 			syslog(LOG_ERR, "get property value %s/%s failed - %s",
455111909SPeter.Gill@Sun.COM 			    pgName, STMF_PROVIDER_DATA_PROP_COUNT,
45527836SJohn.Forte@Sun.COM 			    scf_strerror(scf_error()));
45537836SJohn.Forte@Sun.COM 			ret = STMF_PS_ERROR;
45547836SJohn.Forte@Sun.COM 			goto out;
45557836SJohn.Forte@Sun.COM 		}
45567836SJohn.Forte@Sun.COM 
45577836SJohn.Forte@Sun.COM 		/*
45587836SJohn.Forte@Sun.COM 		 * Now get the actual value from the value handle
45597836SJohn.Forte@Sun.COM 		 */
45607836SJohn.Forte@Sun.COM 		if (scf_value_get_count(value4, &oldBlockCnt) == -1) {
456111909SPeter.Gill@Sun.COM 			syslog(LOG_ERR, "get integer value %s/%s failed - %s",
456211909SPeter.Gill@Sun.COM 			    pgName, STMF_PROVIDER_DATA_PROP_COUNT,
45637836SJohn.Forte@Sun.COM 			    scf_strerror(scf_error()));
45647836SJohn.Forte@Sun.COM 			ret = STMF_PS_ERROR;
45657836SJohn.Forte@Sun.COM 			goto out;
45667836SJohn.Forte@Sun.COM 		}
45677836SJohn.Forte@Sun.COM 	}
45687836SJohn.Forte@Sun.COM 
45697836SJohn.Forte@Sun.COM 	/*
45707836SJohn.Forte@Sun.COM 	 * Get the STMF_PROVIDER_DATA_PROP_SET_COUNT property
45717836SJohn.Forte@Sun.COM 	 * If it doesn't exist, we'll create it later after successfully
45727836SJohn.Forte@Sun.COM 	 * setting the data.
45737836SJohn.Forte@Sun.COM 	 */
45747836SJohn.Forte@Sun.COM 	if (scf_pg_get_property(pg, STMF_PROVIDER_DATA_PROP_SET_COUNT,
45757836SJohn.Forte@Sun.COM 	    prop) == -1) {
45767836SJohn.Forte@Sun.COM 		if (scf_error() == SCF_ERROR_NOT_FOUND) {
45777836SJohn.Forte@Sun.COM 			foundSetCnt = B_FALSE;
45787836SJohn.Forte@Sun.COM 		} else {
457911909SPeter.Gill@Sun.COM 			syslog(LOG_ERR, "get property %s/%s failed - %s",
458011909SPeter.Gill@Sun.COM 			    pgName, STMF_PROVIDER_DATA_PROP_SET_COUNT,
45817836SJohn.Forte@Sun.COM 			    scf_strerror(scf_error()));
45827836SJohn.Forte@Sun.COM 			ret = STMF_PS_ERROR;
45837836SJohn.Forte@Sun.COM 			goto out;
45847836SJohn.Forte@Sun.COM 		}
45857836SJohn.Forte@Sun.COM 	}
45867836SJohn.Forte@Sun.COM 
45877836SJohn.Forte@Sun.COM 	if (foundSetCnt) {
45887836SJohn.Forte@Sun.COM 		/*
45897836SJohn.Forte@Sun.COM 		 * Get the STMF_PROVIDER_DATA_PROP_SET_COUNT value
45907836SJohn.Forte@Sun.COM 		 */
45917836SJohn.Forte@Sun.COM 		if (scf_property_get_value(prop, value5) == -1) {
459211909SPeter.Gill@Sun.COM 			syslog(LOG_ERR, "get property value %s/%s failed - %s",
459311909SPeter.Gill@Sun.COM 			    pgName, STMF_PROVIDER_DATA_PROP_SET_COUNT,
45947836SJohn.Forte@Sun.COM 			    scf_strerror(scf_error()));
45957836SJohn.Forte@Sun.COM 			ret = STMF_PS_ERROR;
45967836SJohn.Forte@Sun.COM 			goto out;
45977836SJohn.Forte@Sun.COM 		}
45987836SJohn.Forte@Sun.COM 
45997836SJohn.Forte@Sun.COM 		/*
46007836SJohn.Forte@Sun.COM 		 * Now get the actual value from the value handle
46017836SJohn.Forte@Sun.COM 		 */
46027836SJohn.Forte@Sun.COM 		if (scf_value_get_count(value5, &setCnt) == -1) {
460311909SPeter.Gill@Sun.COM 			syslog(LOG_ERR, "get integer value %s/%s failed - %s",
460411909SPeter.Gill@Sun.COM 			    pgName, STMF_PROVIDER_DATA_PROP_SET_COUNT,
46057836SJohn.Forte@Sun.COM 			    scf_strerror(scf_error()));
46067836SJohn.Forte@Sun.COM 			ret = STMF_PS_ERROR;
46077836SJohn.Forte@Sun.COM 			goto out;
46087836SJohn.Forte@Sun.COM 		}
46097836SJohn.Forte@Sun.COM 
46107836SJohn.Forte@Sun.COM 		/*
46117836SJohn.Forte@Sun.COM 		 * Compare the setCnt prop to the caller's.
46127836SJohn.Forte@Sun.COM 		 */
46137836SJohn.Forte@Sun.COM 		if (setToken && (*setToken != setCnt)) {
46147836SJohn.Forte@Sun.COM 			ret = STMF_PS_ERROR_PROV_DATA_STALE;
46157836SJohn.Forte@Sun.COM 			goto out;
46167836SJohn.Forte@Sun.COM 		}
46177836SJohn.Forte@Sun.COM 	}
46187836SJohn.Forte@Sun.COM 
46197836SJohn.Forte@Sun.COM 	setCnt++;
46207836SJohn.Forte@Sun.COM 
46217836SJohn.Forte@Sun.COM 	/*
46227836SJohn.Forte@Sun.COM 	 * prepare the list for writing
46237836SJohn.Forte@Sun.COM 	 */
46247836SJohn.Forte@Sun.COM 	if (nvlist_pack(nvl, &nvlistEncoded, &nvlistEncodedSize,
46257836SJohn.Forte@Sun.COM 	    NV_ENCODE_XDR, 0) != 0) {
462611909SPeter.Gill@Sun.COM 		syslog(LOG_ERR, "nvlist_pack for %s failed",
462711909SPeter.Gill@Sun.COM 		    pgName);
46287836SJohn.Forte@Sun.COM 		ret = STMF_PS_ERROR_NOMEM;
46297836SJohn.Forte@Sun.COM 		goto out;
46307836SJohn.Forte@Sun.COM 	}
46317836SJohn.Forte@Sun.COM 
46327836SJohn.Forte@Sun.COM 	/* Determine how many chunks we need to write */
46337836SJohn.Forte@Sun.COM 	blockCnt = nvlistEncodedSize/STMF_PROVIDER_DATA_PROP_SIZE;
46347836SJohn.Forte@Sun.COM 	if (nvlistEncodedSize % STMF_PROVIDER_DATA_PROP_SIZE)
46357836SJohn.Forte@Sun.COM 		blockCnt++;
46367836SJohn.Forte@Sun.COM 
46377836SJohn.Forte@Sun.COM 	/* allocate entry and value resources for writing those chunks */
46387836SJohn.Forte@Sun.COM 	addEntry = (scf_transaction_entry_t **)calloc(1, sizeof (*addEntry)
46397836SJohn.Forte@Sun.COM 	    * blockCnt);
46407836SJohn.Forte@Sun.COM 	if (addEntry == NULL) {
464111909SPeter.Gill@Sun.COM 		syslog(LOG_ERR, "addEntry alloc for %s failed", pgName);
46427836SJohn.Forte@Sun.COM 		ret = STMF_PS_ERROR_NOMEM;
46437836SJohn.Forte@Sun.COM 		goto out;
46447836SJohn.Forte@Sun.COM 	}
46457836SJohn.Forte@Sun.COM 
46467836SJohn.Forte@Sun.COM 	addValue = (scf_value_t **)calloc(1, sizeof (*addValue)
46477836SJohn.Forte@Sun.COM 	    * blockCnt);
46487836SJohn.Forte@Sun.COM 	if (addValue == NULL) {
464911909SPeter.Gill@Sun.COM 		syslog(LOG_ERR, "value alloc for %s failed", pgName);
46507836SJohn.Forte@Sun.COM 		ret = STMF_PS_ERROR_NOMEM;
46517836SJohn.Forte@Sun.COM 		goto out;
46527836SJohn.Forte@Sun.COM 	}
46537836SJohn.Forte@Sun.COM 
46547836SJohn.Forte@Sun.COM 	/*
46557836SJohn.Forte@Sun.COM 	 * allocate entry delete resources for deleting anything existing
46567836SJohn.Forte@Sun.COM 	 * that is more than the new block count. We could leave them around
46577836SJohn.Forte@Sun.COM 	 * without suffering any ill effects but it will be cleaner to look at
46587836SJohn.Forte@Sun.COM 	 * in smf tools if they are deleted.
46597836SJohn.Forte@Sun.COM 	 */
46607836SJohn.Forte@Sun.COM 	if (oldBlockCnt > blockCnt) {
46617836SJohn.Forte@Sun.COM 		deleteEntry = (scf_transaction_entry_t **)calloc(1,
46627836SJohn.Forte@Sun.COM 		    sizeof (*deleteEntry) * (oldBlockCnt - blockCnt));
46637836SJohn.Forte@Sun.COM 		if (deleteEntry == NULL) {
466411909SPeter.Gill@Sun.COM 			syslog(LOG_ERR, "deleteEntry alloc for %s failed",
466511909SPeter.Gill@Sun.COM 			    pgName);
46667836SJohn.Forte@Sun.COM 			ret = STMF_PS_ERROR_NOMEM;
46677836SJohn.Forte@Sun.COM 			goto out;
46687836SJohn.Forte@Sun.COM 		}
46697836SJohn.Forte@Sun.COM 		deleteEntryAlloc = oldBlockCnt - blockCnt;
46707836SJohn.Forte@Sun.COM 	}
46717836SJohn.Forte@Sun.COM 
46727836SJohn.Forte@Sun.COM 
46737836SJohn.Forte@Sun.COM 	for (i = 0; i < blockCnt; i++) {
46747836SJohn.Forte@Sun.COM 		/*
46757836SJohn.Forte@Sun.COM 		 * Create the entry resource for the prop
46767836SJohn.Forte@Sun.COM 		 */
46777836SJohn.Forte@Sun.COM 		addEntry[i] = scf_entry_create(handle);
46787836SJohn.Forte@Sun.COM 		if (addEntry[i] == NULL) {
467911909SPeter.Gill@Sun.COM 			syslog(LOG_ERR, "scf value alloc for %s failed - %s",
468011909SPeter.Gill@Sun.COM 			    pgName, scf_strerror(scf_error()));
46817836SJohn.Forte@Sun.COM 			ret = STMF_PS_ERROR;
46827836SJohn.Forte@Sun.COM 			goto out;
46837836SJohn.Forte@Sun.COM 		}
46847836SJohn.Forte@Sun.COM 
46857836SJohn.Forte@Sun.COM 		/* bump alloc count for addEntry allocation */
46867836SJohn.Forte@Sun.COM 		addEntryAlloc++;
46877836SJohn.Forte@Sun.COM 
46887836SJohn.Forte@Sun.COM 		/*
46897836SJohn.Forte@Sun.COM 		 * create the name to use for the property
46907836SJohn.Forte@Sun.COM 		 */
46917836SJohn.Forte@Sun.COM 		(void) snprintf(dataPropertyName, sizeof (dataPropertyName),
46927836SJohn.Forte@Sun.COM 		    "%s-%d", STMF_PROVIDER_DATA_PROP_PREFIX, i);
46937836SJohn.Forte@Sun.COM 
46947836SJohn.Forte@Sun.COM 		/*
46957836SJohn.Forte@Sun.COM 		 * Create the new property
46967836SJohn.Forte@Sun.COM 		 */
46977836SJohn.Forte@Sun.COM 		if (scf_transaction_property_new(tran, addEntry[i],
46987836SJohn.Forte@Sun.COM 		    dataPropertyName, SCF_TYPE_OPAQUE) == -1) {
46997836SJohn.Forte@Sun.COM 			if (scf_error() == SCF_ERROR_EXISTS) {
47007836SJohn.Forte@Sun.COM 				if (scf_transaction_property_change(tran,
47017836SJohn.Forte@Sun.COM 				    addEntry[i], dataPropertyName,
47027836SJohn.Forte@Sun.COM 				    SCF_TYPE_OPAQUE) == -1) {
470311909SPeter.Gill@Sun.COM 					syslog(LOG_ERR, "transaction property "
470411909SPeter.Gill@Sun.COM 					    "change %s/%s failed - %s",
470511909SPeter.Gill@Sun.COM 					    pgName, dataPropertyName,
47067836SJohn.Forte@Sun.COM 					    scf_strerror(scf_error()));
47077836SJohn.Forte@Sun.COM 					ret = STMF_PS_ERROR;
47087836SJohn.Forte@Sun.COM 					goto out;
47097836SJohn.Forte@Sun.COM 				}
47107836SJohn.Forte@Sun.COM 			} else {
47117836SJohn.Forte@Sun.COM 				syslog(LOG_ERR,
471211909SPeter.Gill@Sun.COM 				    "transaction property new %s/%s "
471311909SPeter.Gill@Sun.COM 				    "failed - %s", pgName, dataPropertyName,
47147836SJohn.Forte@Sun.COM 				    scf_strerror(scf_error()));
47157836SJohn.Forte@Sun.COM 				ret = STMF_PS_ERROR;
47167836SJohn.Forte@Sun.COM 				goto out;
47177836SJohn.Forte@Sun.COM 			}
47187836SJohn.Forte@Sun.COM 		}
47197836SJohn.Forte@Sun.COM 		/*
47207836SJohn.Forte@Sun.COM 		 * Create the value resource for the prop
47217836SJohn.Forte@Sun.COM 		 */
47227836SJohn.Forte@Sun.COM 		addValue[i] = scf_value_create(handle);
47237836SJohn.Forte@Sun.COM 		if (addValue[i] == NULL) {
472411909SPeter.Gill@Sun.COM 			syslog(LOG_ERR, "scf value alloc for %s failed - %s",
472511909SPeter.Gill@Sun.COM 			    pgName, scf_strerror(scf_error()));
47267836SJohn.Forte@Sun.COM 			ret = STMF_PS_ERROR;
47277836SJohn.Forte@Sun.COM 			goto out;
47287836SJohn.Forte@Sun.COM 		}
47297836SJohn.Forte@Sun.COM 
47307836SJohn.Forte@Sun.COM 		/* bump alloc count for addValue allocation */
47317836SJohn.Forte@Sun.COM 		addValueAlloc++;
47327836SJohn.Forte@Sun.COM 
47337836SJohn.Forte@Sun.COM 		/*
47347836SJohn.Forte@Sun.COM 		 * Set the data block offset and size
47357836SJohn.Forte@Sun.COM 		 */
47367836SJohn.Forte@Sun.COM 		if ((STMF_PROVIDER_DATA_PROP_SIZE * (i + 1))
47377836SJohn.Forte@Sun.COM 		    > nvlistEncodedSize) {
47387836SJohn.Forte@Sun.COM 			blockSize = nvlistEncodedSize
47397836SJohn.Forte@Sun.COM 			    - STMF_PROVIDER_DATA_PROP_SIZE * i;
47407836SJohn.Forte@Sun.COM 		} else {
47417836SJohn.Forte@Sun.COM 			blockSize = STMF_PROVIDER_DATA_PROP_SIZE;
47427836SJohn.Forte@Sun.COM 		}
47437836SJohn.Forte@Sun.COM 
47447836SJohn.Forte@Sun.COM 		blockOffset = STMF_PROVIDER_DATA_PROP_SIZE * i;
47457836SJohn.Forte@Sun.COM 		if (scf_value_set_opaque(addValue[i],
47467836SJohn.Forte@Sun.COM 		    &nvlistEncoded[blockOffset], blockSize) == -1) {
474711909SPeter.Gill@Sun.COM 			syslog(LOG_ERR, "set value for %s failed - %s",
474811909SPeter.Gill@Sun.COM 			    pgName, scf_strerror(scf_error()));
47497836SJohn.Forte@Sun.COM 			ret = STMF_PS_ERROR;
47507836SJohn.Forte@Sun.COM 			goto out;
47517836SJohn.Forte@Sun.COM 		}
47527836SJohn.Forte@Sun.COM 
47537836SJohn.Forte@Sun.COM 		/*
47547836SJohn.Forte@Sun.COM 		 * Add the data block to the transaction entry
47557836SJohn.Forte@Sun.COM 		 */
47567836SJohn.Forte@Sun.COM 		if (scf_entry_add_value(addEntry[i], addValue[i]) == -1) {
475711909SPeter.Gill@Sun.COM 			syslog(LOG_ERR, "add value for %s failed - %s",
475811909SPeter.Gill@Sun.COM 			    pgName, scf_strerror(scf_error()));
47597836SJohn.Forte@Sun.COM 			ret = STMF_PS_ERROR;
47607836SJohn.Forte@Sun.COM 			goto out;
47617836SJohn.Forte@Sun.COM 		}
47627836SJohn.Forte@Sun.COM 	}
47637836SJohn.Forte@Sun.COM 
47647836SJohn.Forte@Sun.COM 	/*
47657836SJohn.Forte@Sun.COM 	 * Now we need to delete any chunks (properties) that are no longer
47667836SJohn.Forte@Sun.COM 	 * needed. Iterate through the rest of the chunks deleting each.
47677836SJohn.Forte@Sun.COM 	 */
47687836SJohn.Forte@Sun.COM 	for (i = blockCnt; i < oldBlockCnt; i++) {
47697836SJohn.Forte@Sun.COM 		/*
47707836SJohn.Forte@Sun.COM 		 * Create the entry resource for the prop
47717836SJohn.Forte@Sun.COM 		 */
47727836SJohn.Forte@Sun.COM 		deleteEntry[j] = scf_entry_create(handle);
47737836SJohn.Forte@Sun.COM 		if (deleteEntry[j] == NULL) {
477411909SPeter.Gill@Sun.COM 			syslog(LOG_ERR, "scf value alloc for %s failed - %s",
477511909SPeter.Gill@Sun.COM 			    pgName, scf_strerror(scf_error()));
47767836SJohn.Forte@Sun.COM 			ret = STMF_PS_ERROR;
47777836SJohn.Forte@Sun.COM 			goto out;
47787836SJohn.Forte@Sun.COM 		}
47797836SJohn.Forte@Sun.COM 
47807836SJohn.Forte@Sun.COM 		/*
47817836SJohn.Forte@Sun.COM 		 * create the name to use for the property
47827836SJohn.Forte@Sun.COM 		 */
47837836SJohn.Forte@Sun.COM 		(void) snprintf(dataPropertyName, sizeof (dataPropertyName),
47847836SJohn.Forte@Sun.COM 		    "%s-%d", STMF_PROVIDER_DATA_PROP_PREFIX, i);
47857836SJohn.Forte@Sun.COM 
47867836SJohn.Forte@Sun.COM 		/*
47877836SJohn.Forte@Sun.COM 		 * Delete the existing property
47887836SJohn.Forte@Sun.COM 		 */
47897836SJohn.Forte@Sun.COM 		if (scf_transaction_property_delete(tran, deleteEntry[j++],
47907836SJohn.Forte@Sun.COM 		    dataPropertyName) == -1) {
479111909SPeter.Gill@Sun.COM 			syslog(LOG_ERR, "delete property %s/%s failed - %s",
479211909SPeter.Gill@Sun.COM 			    pgName, dataPropertyName,
47937836SJohn.Forte@Sun.COM 			    scf_strerror(scf_error()));
47947836SJohn.Forte@Sun.COM 			ret = STMF_PS_ERROR;
47957836SJohn.Forte@Sun.COM 			goto out;
47967836SJohn.Forte@Sun.COM 		}
47977836SJohn.Forte@Sun.COM 	}
47987836SJohn.Forte@Sun.COM 
47997836SJohn.Forte@Sun.COM 	if (newPg) {
48007836SJohn.Forte@Sun.COM 		/*
48017836SJohn.Forte@Sun.COM 		 * Ensure the read_authorization property is set
48027836SJohn.Forte@Sun.COM 		 * for the group
48037836SJohn.Forte@Sun.COM 		 */
48047836SJohn.Forte@Sun.COM 		if (scf_transaction_property_new(tran, entry1,
48057836SJohn.Forte@Sun.COM 		    "read_authorization", SCF_TYPE_ASTRING) == -1) {
480611909SPeter.Gill@Sun.COM 			syslog(LOG_ERR, "transaction property %s/%s new "
480711909SPeter.Gill@Sun.COM 			    "failed - %s", pgName, "read_authorization",
48087836SJohn.Forte@Sun.COM 			    scf_strerror(scf_error()));
48097836SJohn.Forte@Sun.COM 			ret = STMF_PS_ERROR;
48107836SJohn.Forte@Sun.COM 			goto out;
48117836SJohn.Forte@Sun.COM 		}
48127836SJohn.Forte@Sun.COM 
48137836SJohn.Forte@Sun.COM 		if (scf_value_set_astring(value1, STMF_SMF_READ_ATTR) == -1) {
481411909SPeter.Gill@Sun.COM 			syslog(LOG_ERR, "set value %s/%s failed - %s",
481511909SPeter.Gill@Sun.COM 			    pgName, "read_authorization",
48167836SJohn.Forte@Sun.COM 			    scf_strerror(scf_error()));
48177836SJohn.Forte@Sun.COM 			ret = STMF_PS_ERROR;
48187836SJohn.Forte@Sun.COM 			goto out;
48197836SJohn.Forte@Sun.COM 		}
48207836SJohn.Forte@Sun.COM 
48217836SJohn.Forte@Sun.COM 		if (scf_entry_add_value(entry1, value1) == -1) {
482211909SPeter.Gill@Sun.COM 			syslog(LOG_ERR, "add value %s/%s failed - %s",
482311909SPeter.Gill@Sun.COM 			    pgName, "read_authorization",
48247836SJohn.Forte@Sun.COM 			    scf_strerror(scf_error()));
48257836SJohn.Forte@Sun.COM 			ret = STMF_PS_ERROR;
48267836SJohn.Forte@Sun.COM 			goto out;
48277836SJohn.Forte@Sun.COM 		}
48287836SJohn.Forte@Sun.COM 	}
48297836SJohn.Forte@Sun.COM 
48307836SJohn.Forte@Sun.COM 	/* create or change the count property */
48317836SJohn.Forte@Sun.COM 	if (scf_transaction_property_new(tran, entry2,
48327836SJohn.Forte@Sun.COM 	    STMF_PROVIDER_DATA_PROP_COUNT, SCF_TYPE_COUNT) == -1) {
48337836SJohn.Forte@Sun.COM 		if (scf_error() == SCF_ERROR_EXISTS) {
48347836SJohn.Forte@Sun.COM 			if (scf_transaction_property_change(tran, entry2,
48357836SJohn.Forte@Sun.COM 			    STMF_PROVIDER_DATA_PROP_COUNT,
48367836SJohn.Forte@Sun.COM 			    SCF_TYPE_COUNT) == -1) {
483711909SPeter.Gill@Sun.COM 				syslog(LOG_ERR, "transaction property change "
483811909SPeter.Gill@Sun.COM 				    "%s/%s failed - %s", pgName,
483911909SPeter.Gill@Sun.COM 				    STMF_PROVIDER_DATA_PROP_COUNT,
48407836SJohn.Forte@Sun.COM 				    scf_strerror(scf_error()));
48417836SJohn.Forte@Sun.COM 				ret = STMF_PS_ERROR;
48427836SJohn.Forte@Sun.COM 				goto out;
48437836SJohn.Forte@Sun.COM 			}
48447836SJohn.Forte@Sun.COM 		} else {
484511909SPeter.Gill@Sun.COM 			syslog(LOG_ERR, "transaction property %s/%s new "
484611909SPeter.Gill@Sun.COM 			    "failed - %s", pgName,
484711909SPeter.Gill@Sun.COM 			    STMF_PROVIDER_DATA_PROP_COUNT,
48487836SJohn.Forte@Sun.COM 			    scf_strerror(scf_error()));
48497836SJohn.Forte@Sun.COM 			ret = STMF_PS_ERROR;
48507836SJohn.Forte@Sun.COM 			goto out;
48517836SJohn.Forte@Sun.COM 		}
48527836SJohn.Forte@Sun.COM 	}
48537836SJohn.Forte@Sun.COM 
48547836SJohn.Forte@Sun.COM 	scf_value_set_count(value2, blockCnt);
48557836SJohn.Forte@Sun.COM 
48567836SJohn.Forte@Sun.COM 	if (scf_entry_add_value(entry2, value2) == -1) {
485711909SPeter.Gill@Sun.COM 		syslog(LOG_ERR, "add value %s/%s failed - %s",
485811909SPeter.Gill@Sun.COM 		    pgName, STMF_PROVIDER_DATA_PROP_COUNT,
48597836SJohn.Forte@Sun.COM 		    scf_strerror(scf_error()));
48607836SJohn.Forte@Sun.COM 		ret = STMF_PS_ERROR;
48617836SJohn.Forte@Sun.COM 		goto out;
48627836SJohn.Forte@Sun.COM 	}
48637836SJohn.Forte@Sun.COM 
48647836SJohn.Forte@Sun.COM 	/* create or change the set count property */
48657836SJohn.Forte@Sun.COM 	if (scf_transaction_property_new(tran, entry5,
48667836SJohn.Forte@Sun.COM 	    STMF_PROVIDER_DATA_PROP_SET_COUNT, SCF_TYPE_COUNT) == -1) {
48677836SJohn.Forte@Sun.COM 		if (scf_error() == SCF_ERROR_EXISTS) {
48687836SJohn.Forte@Sun.COM 			if (scf_transaction_property_change(tran, entry5,
48697836SJohn.Forte@Sun.COM 			    STMF_PROVIDER_DATA_PROP_SET_COUNT,
48707836SJohn.Forte@Sun.COM 			    SCF_TYPE_COUNT) == -1) {
48717836SJohn.Forte@Sun.COM 				syslog(LOG_ERR,
487211909SPeter.Gill@Sun.COM 				    "transaction property change %s/%s "
487311909SPeter.Gill@Sun.COM 				    "failed - %s", pgName,
487411909SPeter.Gill@Sun.COM 				    STMF_PROVIDER_DATA_PROP_SET_COUNT,
48757836SJohn.Forte@Sun.COM 				    scf_strerror(scf_error()));
48767836SJohn.Forte@Sun.COM 				ret = STMF_PS_ERROR;
48777836SJohn.Forte@Sun.COM 				goto out;
48787836SJohn.Forte@Sun.COM 			}
48797836SJohn.Forte@Sun.COM 		} else {
488011909SPeter.Gill@Sun.COM 			syslog(LOG_ERR, "transaction property new %s/%s "
488111909SPeter.Gill@Sun.COM 			    "failed - %s", pgName,
488211909SPeter.Gill@Sun.COM 			    STMF_PROVIDER_DATA_PROP_SET_COUNT,
48837836SJohn.Forte@Sun.COM 			    scf_strerror(scf_error()));
48847836SJohn.Forte@Sun.COM 			ret = STMF_PS_ERROR;
48857836SJohn.Forte@Sun.COM 			goto out;
48867836SJohn.Forte@Sun.COM 		}
48877836SJohn.Forte@Sun.COM 	}
48887836SJohn.Forte@Sun.COM 
48897836SJohn.Forte@Sun.COM 
48907836SJohn.Forte@Sun.COM 
48917836SJohn.Forte@Sun.COM 	scf_value_set_count(value5, setCnt);
48927836SJohn.Forte@Sun.COM 
48937836SJohn.Forte@Sun.COM 	if (scf_entry_add_value(entry5, value5) == -1) {
489411909SPeter.Gill@Sun.COM 		syslog(LOG_ERR, "add value %s/%s failed - %s",
489511909SPeter.Gill@Sun.COM 		    pgName, STMF_PROVIDER_DATA_PROP_SET_COUNT,
48967836SJohn.Forte@Sun.COM 		    scf_strerror(scf_error()));
48977836SJohn.Forte@Sun.COM 		ret = STMF_PS_ERROR;
48987836SJohn.Forte@Sun.COM 		goto out;
48997836SJohn.Forte@Sun.COM 	}
49007836SJohn.Forte@Sun.COM 
49017836SJohn.Forte@Sun.COM 	/* create or change the provider type property */
49027836SJohn.Forte@Sun.COM 	if (scf_transaction_property_new(tran, entry3,
49037836SJohn.Forte@Sun.COM 	    STMF_PROVIDER_DATA_PROP_TYPE, SCF_TYPE_INTEGER) == -1) {
49047836SJohn.Forte@Sun.COM 		if (scf_error() == SCF_ERROR_EXISTS) {
49057836SJohn.Forte@Sun.COM 			if (scf_transaction_property_change(tran, entry3,
49067836SJohn.Forte@Sun.COM 			    STMF_PROVIDER_DATA_PROP_TYPE,
49077836SJohn.Forte@Sun.COM 			    SCF_TYPE_INTEGER) == -1) {
49087836SJohn.Forte@Sun.COM 				syslog(LOG_ERR,
490911909SPeter.Gill@Sun.COM 				    "transaction property change %s/%s "
491011909SPeter.Gill@Sun.COM 				    "failed - %s", pgName,
491111909SPeter.Gill@Sun.COM 				    STMF_PROVIDER_DATA_PROP_TYPE,
49127836SJohn.Forte@Sun.COM 				    scf_strerror(scf_error()));
49137836SJohn.Forte@Sun.COM 				ret = STMF_PS_ERROR;
49147836SJohn.Forte@Sun.COM 				goto out;
49157836SJohn.Forte@Sun.COM 			}
49167836SJohn.Forte@Sun.COM 		} else {
491711909SPeter.Gill@Sun.COM 			syslog(LOG_ERR, "transaction property new %s/%s "
491811909SPeter.Gill@Sun.COM 			    "failed - %s", pgName, STMF_PROVIDER_DATA_PROP_TYPE,
49197836SJohn.Forte@Sun.COM 			    scf_strerror(scf_error()));
49207836SJohn.Forte@Sun.COM 			ret = STMF_PS_ERROR;
49217836SJohn.Forte@Sun.COM 			goto out;
49227836SJohn.Forte@Sun.COM 		}
49237836SJohn.Forte@Sun.COM 	}
49247836SJohn.Forte@Sun.COM 
49257836SJohn.Forte@Sun.COM 	switch (providerType) {
49267836SJohn.Forte@Sun.COM 		case STMF_PORT_PROVIDER_TYPE:
49277836SJohn.Forte@Sun.COM 		case STMF_LU_PROVIDER_TYPE:
49287836SJohn.Forte@Sun.COM 			scf_value_set_integer(value3, providerType);
49297836SJohn.Forte@Sun.COM 			break;
49307836SJohn.Forte@Sun.COM 		default:
49317836SJohn.Forte@Sun.COM 			ret = STMF_PS_ERROR;
49327836SJohn.Forte@Sun.COM 			goto out;
49337836SJohn.Forte@Sun.COM 	}
49347836SJohn.Forte@Sun.COM 
49357836SJohn.Forte@Sun.COM 	if (scf_entry_add_value(entry3, value3) == -1) {
493611909SPeter.Gill@Sun.COM 		syslog(LOG_ERR, "add value %s/%s failed - %s", pgName,
493711909SPeter.Gill@Sun.COM 		    STMF_PROVIDER_DATA_PROP_TYPE, scf_strerror(scf_error()));
49387836SJohn.Forte@Sun.COM 		ret = STMF_PS_ERROR;
49397836SJohn.Forte@Sun.COM 		goto out;
49407836SJohn.Forte@Sun.COM 	}
49417836SJohn.Forte@Sun.COM 
49427836SJohn.Forte@Sun.COM 
49437836SJohn.Forte@Sun.COM 	if ((commitRet = scf_transaction_commit(tran)) != 1) {
494411909SPeter.Gill@Sun.COM 		syslog(LOG_ERR, "transaction commit for %s failed - %s",
494511909SPeter.Gill@Sun.COM 		    pgName, scf_strerror(scf_error()));
49467836SJohn.Forte@Sun.COM 		if (commitRet == 0) {
49477836SJohn.Forte@Sun.COM 			ret = STMF_PS_ERROR_BUSY;
49487836SJohn.Forte@Sun.COM 		} else {
49497836SJohn.Forte@Sun.COM 			ret = STMF_PS_ERROR;
49507836SJohn.Forte@Sun.COM 		}
49517836SJohn.Forte@Sun.COM 		goto out;
49527836SJohn.Forte@Sun.COM 	}
49537836SJohn.Forte@Sun.COM 
49547836SJohn.Forte@Sun.COM 	/* pass the new token back to the caller if requested */
49557836SJohn.Forte@Sun.COM 	if (ret == STMF_PS_SUCCESS && setToken) {
49567836SJohn.Forte@Sun.COM 		*setToken = setCnt;
49577836SJohn.Forte@Sun.COM 	}
49587836SJohn.Forte@Sun.COM 
49597836SJohn.Forte@Sun.COM out:
49607836SJohn.Forte@Sun.COM 	/*
49617836SJohn.Forte@Sun.COM 	 * Free resources
49627836SJohn.Forte@Sun.COM 	 */
49637836SJohn.Forte@Sun.COM 	if (handle != NULL) {
49647836SJohn.Forte@Sun.COM 		scf_handle_destroy(handle);
49657836SJohn.Forte@Sun.COM 	}
49667836SJohn.Forte@Sun.COM 	if (svc != NULL) {
49677836SJohn.Forte@Sun.COM 		scf_service_destroy(svc);
49687836SJohn.Forte@Sun.COM 	}
49697836SJohn.Forte@Sun.COM 	if (pg != NULL) {
49707836SJohn.Forte@Sun.COM 		scf_pg_destroy(pg);
49717836SJohn.Forte@Sun.COM 	}
49727836SJohn.Forte@Sun.COM 	if (prop != NULL) {
49737836SJohn.Forte@Sun.COM 		scf_property_destroy(prop);
49747836SJohn.Forte@Sun.COM 	}
49757836SJohn.Forte@Sun.COM 	if (tran != NULL) {
49767836SJohn.Forte@Sun.COM 		scf_transaction_destroy(tran);
49777836SJohn.Forte@Sun.COM 	}
49787836SJohn.Forte@Sun.COM 	for (i = 0; i < addEntryAlloc; i++) {
49797836SJohn.Forte@Sun.COM 		scf_entry_destroy(addEntry[i]);
49807836SJohn.Forte@Sun.COM 	}
49817836SJohn.Forte@Sun.COM 	for (i = 0; i < addValueAlloc; i++) {
49827836SJohn.Forte@Sun.COM 		scf_value_destroy(addValue[i]);
49837836SJohn.Forte@Sun.COM 	}
49847836SJohn.Forte@Sun.COM 	free(addValue);
49857836SJohn.Forte@Sun.COM 	free(addEntry);
49867836SJohn.Forte@Sun.COM 	for (i = 0; i < deleteEntryAlloc; i++) {
49877836SJohn.Forte@Sun.COM 		scf_entry_destroy(deleteEntry[i]);
49887836SJohn.Forte@Sun.COM 	}
49897836SJohn.Forte@Sun.COM 	free(deleteEntry);
49907836SJohn.Forte@Sun.COM 	if (entry1 != NULL) {
49917836SJohn.Forte@Sun.COM 		scf_entry_destroy(entry1);
49927836SJohn.Forte@Sun.COM 	}
49937836SJohn.Forte@Sun.COM 	if (entry2 != NULL) {
49947836SJohn.Forte@Sun.COM 		scf_entry_destroy(entry2);
49957836SJohn.Forte@Sun.COM 	}
49967836SJohn.Forte@Sun.COM 	if (entry3 != NULL) {
49977836SJohn.Forte@Sun.COM 		scf_entry_destroy(entry3);
49987836SJohn.Forte@Sun.COM 	}
49997836SJohn.Forte@Sun.COM 	if (entry5 != NULL) {
50007836SJohn.Forte@Sun.COM 		scf_entry_destroy(entry5);
50017836SJohn.Forte@Sun.COM 	}
50027836SJohn.Forte@Sun.COM 	if (value1 != NULL) {
50037836SJohn.Forte@Sun.COM 		scf_value_destroy(value1);
50047836SJohn.Forte@Sun.COM 	}
50057836SJohn.Forte@Sun.COM 	if (value2 != NULL) {
50067836SJohn.Forte@Sun.COM 		scf_value_destroy(value2);
50077836SJohn.Forte@Sun.COM 	}
50087836SJohn.Forte@Sun.COM 	if (value3 != NULL) {
50097836SJohn.Forte@Sun.COM 		scf_value_destroy(value3);
50107836SJohn.Forte@Sun.COM 	}
50117836SJohn.Forte@Sun.COM 	if (value4 != NULL) {
50127836SJohn.Forte@Sun.COM 		scf_value_destroy(value4);
50137836SJohn.Forte@Sun.COM 	}
50147836SJohn.Forte@Sun.COM 	if (value5 != NULL) {
50157836SJohn.Forte@Sun.COM 		scf_value_destroy(value5);
50167836SJohn.Forte@Sun.COM 	}
50177836SJohn.Forte@Sun.COM 	if (nvlistEncoded != NULL) {
50187836SJohn.Forte@Sun.COM 		free(nvlistEncoded);
50197836SJohn.Forte@Sun.COM 	}
50207836SJohn.Forte@Sun.COM 
50217836SJohn.Forte@Sun.COM 	return (ret);
50227836SJohn.Forte@Sun.COM }
50237836SJohn.Forte@Sun.COM 
50247836SJohn.Forte@Sun.COM /*
50257836SJohn.Forte@Sun.COM  * psGetViewEntry
50267836SJohn.Forte@Sun.COM  *
50277836SJohn.Forte@Sun.COM  * Purpose: Get a single view entry based on the logical unit identifier and
50287836SJohn.Forte@Sun.COM  *          view entry index
50297836SJohn.Forte@Sun.COM  *
50307836SJohn.Forte@Sun.COM  * lu - logical unit identifier
50317836SJohn.Forte@Sun.COM  * viewEntryIndex - index of view entry
50327836SJohn.Forte@Sun.COM  * ve - caller allocated stmfViewEntry structure. On success, this will
50337836SJohn.Forte@Sun.COM  *      contain the retrieved view entry
50347836SJohn.Forte@Sun.COM  */
50357836SJohn.Forte@Sun.COM int
psGetViewEntry(stmfGuid * lu,uint32_t viewEntryIndex,stmfViewEntry * ve)50367836SJohn.Forte@Sun.COM psGetViewEntry(stmfGuid *lu, uint32_t viewEntryIndex, stmfViewEntry *ve)
50377836SJohn.Forte@Sun.COM {
50387836SJohn.Forte@Sun.COM 	scf_handle_t	*handle = NULL;
50397836SJohn.Forte@Sun.COM 	scf_service_t	*svc = NULL;
50407836SJohn.Forte@Sun.COM 	scf_propertygroup_t	*pg = NULL;
50417836SJohn.Forte@Sun.COM 	char guidAsciiBuf[33]; /* size of ascii hex 16 byte guid with NULL */
50427836SJohn.Forte@Sun.COM 	char viewEntryPgName[VIEW_ENTRY_PG_SIZE];
50437836SJohn.Forte@Sun.COM 	char luPgName[LOGICAL_UNIT_PG_SIZE];
50447836SJohn.Forte@Sun.COM 	int ret = STMF_PS_SUCCESS;
50457836SJohn.Forte@Sun.COM 
50467836SJohn.Forte@Sun.COM 	ret = iPsInit(&handle, &svc);
50477836SJohn.Forte@Sun.COM 	if (ret != STMF_PS_SUCCESS) {
50487836SJohn.Forte@Sun.COM 		goto out;
50497836SJohn.Forte@Sun.COM 	}
50507836SJohn.Forte@Sun.COM 
50517836SJohn.Forte@Sun.COM 	pg = scf_pg_create(handle);
50527836SJohn.Forte@Sun.COM 	if (pg == NULL) {
50537836SJohn.Forte@Sun.COM 		syslog(LOG_ERR, "scf pg alloc failed - %s",
50547836SJohn.Forte@Sun.COM 		    scf_strerror(scf_error()));
50557836SJohn.Forte@Sun.COM 		ret = STMF_PS_ERROR;
50567836SJohn.Forte@Sun.COM 		goto out;
50577836SJohn.Forte@Sun.COM 	}
50587836SJohn.Forte@Sun.COM 
50597836SJohn.Forte@Sun.COM 	/* Convert to ASCII uppercase hexadecimal string */
50607836SJohn.Forte@Sun.COM 	(void) snprintf(guidAsciiBuf, sizeof (guidAsciiBuf),
50617836SJohn.Forte@Sun.COM 	    "%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X",
50627836SJohn.Forte@Sun.COM 	    lu->guid[0], lu->guid[1], lu->guid[2], lu->guid[3], lu->guid[4],
50637836SJohn.Forte@Sun.COM 	    lu->guid[5], lu->guid[6], lu->guid[7], lu->guid[8], lu->guid[9],
50647836SJohn.Forte@Sun.COM 	    lu->guid[10], lu->guid[11], lu->guid[12], lu->guid[13],
50657836SJohn.Forte@Sun.COM 	    lu->guid[14], lu->guid[15]);
50667836SJohn.Forte@Sun.COM 
50677836SJohn.Forte@Sun.COM 	(void) snprintf(luPgName, sizeof (luPgName), "%s-%s",
50687836SJohn.Forte@Sun.COM 	    STMF_LU_PREFIX, guidAsciiBuf);
50697836SJohn.Forte@Sun.COM 
50707836SJohn.Forte@Sun.COM 	/*
50717836SJohn.Forte@Sun.COM 	 * Format of view entry property group name:
50727836SJohn.Forte@Sun.COM 	 *	VE-<view_entry_index>-<lu_name>
50737836SJohn.Forte@Sun.COM 	 */
50747836SJohn.Forte@Sun.COM 	(void) snprintf(viewEntryPgName, sizeof (viewEntryPgName),
50757836SJohn.Forte@Sun.COM 	    "%s-%d-%s", STMF_VE_PREFIX, viewEntryIndex, guidAsciiBuf);
50767836SJohn.Forte@Sun.COM 
50777836SJohn.Forte@Sun.COM 	if (scf_service_get_pg(svc, viewEntryPgName, pg) == -1) {
50787836SJohn.Forte@Sun.COM 		if (scf_error() == SCF_ERROR_NOT_FOUND) {
50797836SJohn.Forte@Sun.COM 			ret = STMF_PS_ERROR_NOT_FOUND;
50807836SJohn.Forte@Sun.COM 		} else {
508111909SPeter.Gill@Sun.COM 			syslog(LOG_ERR, "get pg %s failed - %s",
508211909SPeter.Gill@Sun.COM 			    viewEntryPgName, scf_strerror(scf_error()));
50837836SJohn.Forte@Sun.COM 			ret = STMF_PS_ERROR;
50847836SJohn.Forte@Sun.COM 		}
50857836SJohn.Forte@Sun.COM 		goto out;
50867836SJohn.Forte@Sun.COM 	}
50877836SJohn.Forte@Sun.COM 
50887836SJohn.Forte@Sun.COM 
50897836SJohn.Forte@Sun.COM 	if ((ret = iPsGetViewEntry(viewEntryPgName, ve)) != STMF_PS_SUCCESS) {
50907836SJohn.Forte@Sun.COM 		ret = STMF_PS_ERROR;
50917836SJohn.Forte@Sun.COM 		goto out;
50927836SJohn.Forte@Sun.COM 	}
50937836SJohn.Forte@Sun.COM 
50947836SJohn.Forte@Sun.COM out:
50957836SJohn.Forte@Sun.COM 	/*
50967836SJohn.Forte@Sun.COM 	 * Free resources
50977836SJohn.Forte@Sun.COM 	 */
50987836SJohn.Forte@Sun.COM 	if (handle != NULL) {
50997836SJohn.Forte@Sun.COM 		scf_handle_destroy(handle);
51007836SJohn.Forte@Sun.COM 	}
51017836SJohn.Forte@Sun.COM 	if (svc != NULL) {
51027836SJohn.Forte@Sun.COM 		scf_service_destroy(svc);
51037836SJohn.Forte@Sun.COM 	}
51047836SJohn.Forte@Sun.COM 	if (pg != NULL) {
51057836SJohn.Forte@Sun.COM 		scf_pg_destroy(pg);
51067836SJohn.Forte@Sun.COM 	}
51077836SJohn.Forte@Sun.COM 
51087836SJohn.Forte@Sun.COM 	return (ret);
51097836SJohn.Forte@Sun.COM }
51107836SJohn.Forte@Sun.COM 
51117836SJohn.Forte@Sun.COM /*
51127836SJohn.Forte@Sun.COM  * psRemoveViewEntry
51137836SJohn.Forte@Sun.COM  *
51147836SJohn.Forte@Sun.COM  * Remove a view entry
51157836SJohn.Forte@Sun.COM  *
51167836SJohn.Forte@Sun.COM  * luGuid - identifier of logical unit from which to remove view entry
51177836SJohn.Forte@Sun.COM  * viewEntryIndex - view entry name to remove
51187836SJohn.Forte@Sun.COM  *
51197836SJohn.Forte@Sun.COM  * returns:
51207836SJohn.Forte@Sun.COM  *  STMF_PS_SUCCESS on success
51217836SJohn.Forte@Sun.COM  *  STMF_PS_ERROR_* on failure
51227836SJohn.Forte@Sun.COM  */
51237836SJohn.Forte@Sun.COM int
psRemoveViewEntry(stmfGuid * lu,uint32_t viewEntryIndex)51247836SJohn.Forte@Sun.COM psRemoveViewEntry(stmfGuid *lu, uint32_t viewEntryIndex)
51257836SJohn.Forte@Sun.COM {
51267836SJohn.Forte@Sun.COM 	scf_handle_t	*handle = NULL;
51277836SJohn.Forte@Sun.COM 	scf_service_t	*svc = NULL;
51287836SJohn.Forte@Sun.COM 	scf_propertygroup_t	*pg = NULL;
51297836SJohn.Forte@Sun.COM 	char guidAsciiBuf[33]; /* size of ascii hex 16 byte guid with NULL */
51307836SJohn.Forte@Sun.COM 	char viewEntryPgName[VIEW_ENTRY_PG_SIZE];
51317836SJohn.Forte@Sun.COM 	char luPgName[LOGICAL_UNIT_PG_SIZE];
51327836SJohn.Forte@Sun.COM 	int ret = STMF_PS_SUCCESS;
51337836SJohn.Forte@Sun.COM 	sigset_t sigmaskRestore;
51347836SJohn.Forte@Sun.COM 
51357836SJohn.Forte@Sun.COM 	/* grab the signal hold lock */
51367836SJohn.Forte@Sun.COM 	(void) pthread_mutex_lock(&sigSetLock);
51377836SJohn.Forte@Sun.COM 
51387836SJohn.Forte@Sun.COM 	/*
51397836SJohn.Forte@Sun.COM 	 * hold signals until we're done
51407836SJohn.Forte@Sun.COM 	 */
51417836SJohn.Forte@Sun.COM 	if (holdSignal(&sigmaskRestore) != 0) {
51427836SJohn.Forte@Sun.COM 		(void) pthread_mutex_unlock(&sigSetLock);
51437836SJohn.Forte@Sun.COM 		return (STMF_PS_ERROR);
51447836SJohn.Forte@Sun.COM 	}
51457836SJohn.Forte@Sun.COM 
51467836SJohn.Forte@Sun.COM 	ret = iPsInit(&handle, &svc);
51477836SJohn.Forte@Sun.COM 	if (ret != STMF_PS_SUCCESS) {
51487836SJohn.Forte@Sun.COM 		goto out;
51497836SJohn.Forte@Sun.COM 	}
51507836SJohn.Forte@Sun.COM 
51517836SJohn.Forte@Sun.COM 	pg = scf_pg_create(handle);
51527836SJohn.Forte@Sun.COM 	if (pg == NULL) {
51537836SJohn.Forte@Sun.COM 		syslog(LOG_ERR, "scf pg alloc failed - %s",
51547836SJohn.Forte@Sun.COM 		    scf_strerror(scf_error()));
51557836SJohn.Forte@Sun.COM 		ret = STMF_PS_ERROR;
51567836SJohn.Forte@Sun.COM 		goto out;
51577836SJohn.Forte@Sun.COM 	}
51587836SJohn.Forte@Sun.COM 
51597836SJohn.Forte@Sun.COM 	/* Convert to ASCII uppercase hexadecimal string */
51607836SJohn.Forte@Sun.COM 	(void) snprintf(guidAsciiBuf, sizeof (guidAsciiBuf),
51617836SJohn.Forte@Sun.COM 	    "%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X",
51627836SJohn.Forte@Sun.COM 	    lu->guid[0], lu->guid[1], lu->guid[2], lu->guid[3], lu->guid[4],
51637836SJohn.Forte@Sun.COM 	    lu->guid[5], lu->guid[6], lu->guid[7], lu->guid[8], lu->guid[9],
51647836SJohn.Forte@Sun.COM 	    lu->guid[10], lu->guid[11], lu->guid[12], lu->guid[13],
51657836SJohn.Forte@Sun.COM 	    lu->guid[14], lu->guid[15]);
51667836SJohn.Forte@Sun.COM 
51677836SJohn.Forte@Sun.COM 	(void) snprintf(luPgName, sizeof (luPgName), "%s-%s",
51687836SJohn.Forte@Sun.COM 	    STMF_LU_PREFIX, guidAsciiBuf);
51697836SJohn.Forte@Sun.COM 
51707836SJohn.Forte@Sun.COM 	/*
51717836SJohn.Forte@Sun.COM 	 * Format of view entry property group name:
51727836SJohn.Forte@Sun.COM 	 *	VE-<view_entry_index>-<lu_name>
51737836SJohn.Forte@Sun.COM 	 */
51747836SJohn.Forte@Sun.COM 	(void) snprintf(viewEntryPgName, sizeof (viewEntryPgName),
51757836SJohn.Forte@Sun.COM 	    "%s-%d-%s", STMF_VE_PREFIX, viewEntryIndex, guidAsciiBuf);
51767836SJohn.Forte@Sun.COM 
51777836SJohn.Forte@Sun.COM 	if (scf_service_get_pg(svc, viewEntryPgName, pg) == -1) {
51787836SJohn.Forte@Sun.COM 		if (scf_error() == SCF_ERROR_NOT_FOUND) {
51797836SJohn.Forte@Sun.COM 			ret = STMF_PS_ERROR_NOT_FOUND;
51807836SJohn.Forte@Sun.COM 		} else {
518111909SPeter.Gill@Sun.COM 			syslog(LOG_ERR, "get pg %s failed - %s",
518211909SPeter.Gill@Sun.COM 			    viewEntryPgName, scf_strerror(scf_error()));
51837836SJohn.Forte@Sun.COM 			ret = STMF_PS_ERROR;
51847836SJohn.Forte@Sun.COM 		}
51857836SJohn.Forte@Sun.COM 		goto out;
51867836SJohn.Forte@Sun.COM 	}
51877836SJohn.Forte@Sun.COM 
51887836SJohn.Forte@Sun.COM 	/*
51897836SJohn.Forte@Sun.COM 	 * update the logical unit property group to remove
51907836SJohn.Forte@Sun.COM 	 * the view entry and update the view entry count
51917836SJohn.Forte@Sun.COM 	 * If it fails, we won't delete the property group so that
51927836SJohn.Forte@Sun.COM 	 * we maintain consistency.
51937836SJohn.Forte@Sun.COM 	 */
51947836SJohn.Forte@Sun.COM 	if ((ret = iPsAddRemoveLuViewEntry(luPgName, viewEntryPgName,
51957836SJohn.Forte@Sun.COM 	    REMOVE)) != STMF_PS_SUCCESS) {
51967836SJohn.Forte@Sun.COM 		goto out;
51977836SJohn.Forte@Sun.COM 	}
51987836SJohn.Forte@Sun.COM 
51997836SJohn.Forte@Sun.COM 	/*
52007836SJohn.Forte@Sun.COM 	 * Delete the view entry. If this fails, we should try to add
52017836SJohn.Forte@Sun.COM 	 * the logical unit view entry property group back otherwise
52027836SJohn.Forte@Sun.COM 	 * we're inconsistent.
52037836SJohn.Forte@Sun.COM 	 */
52047836SJohn.Forte@Sun.COM 	if (scf_pg_delete(pg) == -1) {
520511909SPeter.Gill@Sun.COM 		syslog(LOG_ERR, "delete pg %s failed - %s", viewEntryPgName,
52067836SJohn.Forte@Sun.COM 		    scf_strerror(scf_error()));
52077836SJohn.Forte@Sun.COM 		if ((ret = iPsAddRemoveLuViewEntry(luPgName, viewEntryPgName,
52087836SJohn.Forte@Sun.COM 		    ADD)) != STMF_PS_SUCCESS) {
520911909SPeter.Gill@Sun.COM 			syslog(LOG_ERR, "add of view entry %s failed, possible"
521011909SPeter.Gill@Sun.COM 			    "inconsistency - %s", viewEntryPgName,
521111909SPeter.Gill@Sun.COM 			    scf_strerror(scf_error()));
52127836SJohn.Forte@Sun.COM 		}
52137836SJohn.Forte@Sun.COM 		ret = STMF_PS_ERROR;
52147836SJohn.Forte@Sun.COM 		goto out;
52157836SJohn.Forte@Sun.COM 	}
52167836SJohn.Forte@Sun.COM 
52177836SJohn.Forte@Sun.COM out:
52187836SJohn.Forte@Sun.COM 	/*
52197836SJohn.Forte@Sun.COM 	 * Okay, we're done. Release the signals
52207836SJohn.Forte@Sun.COM 	 */
52217836SJohn.Forte@Sun.COM 	if (releaseSignal(&sigmaskRestore) != 0) {
52227836SJohn.Forte@Sun.COM 		/*
52237836SJohn.Forte@Sun.COM 		 * Don't set this as an STMF_PS_ERROR_*. We succeeded
52247836SJohn.Forte@Sun.COM 		 * the requested operation. But we do need to log it.
52257836SJohn.Forte@Sun.COM 		 */
52267836SJohn.Forte@Sun.COM 		syslog(LOG_ERR, "Unable to release one or more signals - %s",
52277836SJohn.Forte@Sun.COM 		    strerror(errno));
52287836SJohn.Forte@Sun.COM 	}
52297836SJohn.Forte@Sun.COM 
52307836SJohn.Forte@Sun.COM 	/*
52317836SJohn.Forte@Sun.COM 	 * Free resources
52327836SJohn.Forte@Sun.COM 	 */
52337836SJohn.Forte@Sun.COM 	if (handle != NULL) {
52347836SJohn.Forte@Sun.COM 		scf_handle_destroy(handle);
52357836SJohn.Forte@Sun.COM 	}
52367836SJohn.Forte@Sun.COM 	if (svc != NULL) {
52377836SJohn.Forte@Sun.COM 		scf_service_destroy(svc);
52387836SJohn.Forte@Sun.COM 	}
52397836SJohn.Forte@Sun.COM 	if (pg != NULL) {
52407836SJohn.Forte@Sun.COM 		scf_pg_destroy(pg);
52417836SJohn.Forte@Sun.COM 	}
52427836SJohn.Forte@Sun.COM 
52437836SJohn.Forte@Sun.COM 	/* release the signal hold lock */
52447836SJohn.Forte@Sun.COM 	(void) pthread_mutex_unlock(&sigSetLock);
52457836SJohn.Forte@Sun.COM 
52467836SJohn.Forte@Sun.COM 	return (ret);
52477836SJohn.Forte@Sun.COM }
52487836SJohn.Forte@Sun.COM 
52497836SJohn.Forte@Sun.COM 
52507836SJohn.Forte@Sun.COM 
52517836SJohn.Forte@Sun.COM /*
52527836SJohn.Forte@Sun.COM  * holdSignal
52537836SJohn.Forte@Sun.COM  *
52547836SJohn.Forte@Sun.COM  * Hold SIGINT, SIGTERM, SIGQUIT until further notice.
52557836SJohn.Forte@Sun.COM  *
52567836SJohn.Forte@Sun.COM  * Saves old signal mask on a per thread basis
52577836SJohn.Forte@Sun.COM  * and saves action for the process.
52587836SJohn.Forte@Sun.COM  *
52597836SJohn.Forte@Sun.COM  * Installs action for above signals.
52607836SJohn.Forte@Sun.COM  *
52617836SJohn.Forte@Sun.COM  * locks held: sigSetLock
52627836SJohn.Forte@Sun.COM  *
52637836SJohn.Forte@Sun.COM  * returns:
52647836SJohn.Forte@Sun.COM  *  0 on success
52657836SJohn.Forte@Sun.COM  *  non-zero otherwise
52667836SJohn.Forte@Sun.COM  */
52677836SJohn.Forte@Sun.COM static int
holdSignal(sigset_t * sigmaskRestore)52687836SJohn.Forte@Sun.COM holdSignal(sigset_t *sigmaskRestore)
52697836SJohn.Forte@Sun.COM {
52707836SJohn.Forte@Sun.COM 	struct sigaction act;
52717836SJohn.Forte@Sun.COM 	sigset_t sigmask;
52727836SJohn.Forte@Sun.COM 
52737836SJohn.Forte@Sun.COM 	/*
52747836SJohn.Forte@Sun.COM 	 * Return existing signal mask for this thread
52757836SJohn.Forte@Sun.COM 	 */
52767836SJohn.Forte@Sun.COM 	if (pthread_sigmask(0, NULL, sigmaskRestore) != 0) {
52777836SJohn.Forte@Sun.COM 		return (1);
52787836SJohn.Forte@Sun.COM 	}
52797836SJohn.Forte@Sun.COM 
52807836SJohn.Forte@Sun.COM 	(void) sigemptyset(&act.sa_mask);
52817836SJohn.Forte@Sun.COM 	act.sa_handler = sigHandler;
52827836SJohn.Forte@Sun.COM 	act.sa_flags = 0;
52837836SJohn.Forte@Sun.COM 
52847836SJohn.Forte@Sun.COM 	/*
52857836SJohn.Forte@Sun.COM 	 * Have we set the actions for the signals we want to catch?
52867836SJohn.Forte@Sun.COM 	 */
52877836SJohn.Forte@Sun.COM 	if (!actionSet) {
52887836SJohn.Forte@Sun.COM 		if (sigaction(SIGQUIT, &act, &currentActionQuit) != 0) {
52897836SJohn.Forte@Sun.COM 			return (1);
52907836SJohn.Forte@Sun.COM 		}
52917836SJohn.Forte@Sun.COM 
52927836SJohn.Forte@Sun.COM 		if (sigaction(SIGINT, &act, &currentActionInt) != 0) {
52937836SJohn.Forte@Sun.COM 			return (1);
52947836SJohn.Forte@Sun.COM 		}
52957836SJohn.Forte@Sun.COM 
52967836SJohn.Forte@Sun.COM 		if (sigaction(SIGTERM, &act, &currentActionTerm) != 0) {
52977836SJohn.Forte@Sun.COM 			return (1);
52987836SJohn.Forte@Sun.COM 		}
52997836SJohn.Forte@Sun.COM 
53007836SJohn.Forte@Sun.COM 		actionSet = B_TRUE;
53017836SJohn.Forte@Sun.COM 	}
53027836SJohn.Forte@Sun.COM 
53037836SJohn.Forte@Sun.COM 	/*
53047836SJohn.Forte@Sun.COM 	 * We still need to change the mask for the current thread
53057836SJohn.Forte@Sun.COM 	 */
53067836SJohn.Forte@Sun.COM 	if (sigfillset(&sigmask) != 0) {
53077836SJohn.Forte@Sun.COM 		return (1);
53087836SJohn.Forte@Sun.COM 	}
53097836SJohn.Forte@Sun.COM 
53107836SJohn.Forte@Sun.COM 	(void) sigdelset(&sigmask, SIGQUIT);
53117836SJohn.Forte@Sun.COM 
53127836SJohn.Forte@Sun.COM 	(void) sigdelset(&sigmask, SIGINT);
53137836SJohn.Forte@Sun.COM 
53147836SJohn.Forte@Sun.COM 	(void) sigdelset(&sigmask, SIGTERM);
53157836SJohn.Forte@Sun.COM 
53167836SJohn.Forte@Sun.COM 	if (pthread_sigmask(SIG_SETMASK, &sigmask, NULL) != 0) {
53177836SJohn.Forte@Sun.COM 		return (1);
53187836SJohn.Forte@Sun.COM 	}
53197836SJohn.Forte@Sun.COM 
53207836SJohn.Forte@Sun.COM 	return (0);
53217836SJohn.Forte@Sun.COM }
53227836SJohn.Forte@Sun.COM 
53237836SJohn.Forte@Sun.COM /*
53247836SJohn.Forte@Sun.COM  * releaseSignal
53257836SJohn.Forte@Sun.COM  *
53267836SJohn.Forte@Sun.COM  * Re-install the original signal mask and signal actions
53277836SJohn.Forte@Sun.COM  *
53287836SJohn.Forte@Sun.COM  * Also, raise any signals that were caught during the hold period and clear
53297836SJohn.Forte@Sun.COM  * the signal from the caught set (signalsCaught).
53307836SJohn.Forte@Sun.COM  *
53317836SJohn.Forte@Sun.COM  * locks held: sigSetLock
53327836SJohn.Forte@Sun.COM  *
53337836SJohn.Forte@Sun.COM  * Returns
53347836SJohn.Forte@Sun.COM  *  0 on success
53357836SJohn.Forte@Sun.COM  *  non-zero otherwise
53367836SJohn.Forte@Sun.COM  */
53377836SJohn.Forte@Sun.COM static int
releaseSignal(sigset_t * sigmaskRestore)53387836SJohn.Forte@Sun.COM releaseSignal(sigset_t *sigmaskRestore)
53397836SJohn.Forte@Sun.COM {
53407836SJohn.Forte@Sun.COM 	int ret = 0;
53417836SJohn.Forte@Sun.COM 
53427836SJohn.Forte@Sun.COM 	if (sigaction(SIGQUIT, &currentActionQuit, NULL) != 0) {
53437836SJohn.Forte@Sun.COM 		ret = 1;
53447836SJohn.Forte@Sun.COM 	}
53457836SJohn.Forte@Sun.COM 
53467836SJohn.Forte@Sun.COM 	if (sigaction(SIGINT, &currentActionInt, NULL) != 0) {
53477836SJohn.Forte@Sun.COM 		ret = 1;
53487836SJohn.Forte@Sun.COM 	}
53497836SJohn.Forte@Sun.COM 
53507836SJohn.Forte@Sun.COM 	if (sigaction(SIGTERM, &currentActionTerm, NULL) != 0) {
53517836SJohn.Forte@Sun.COM 		ret = 1;
53527836SJohn.Forte@Sun.COM 	}
53537836SJohn.Forte@Sun.COM 
53547836SJohn.Forte@Sun.COM 	actionSet = B_FALSE;
53557836SJohn.Forte@Sun.COM 
53567836SJohn.Forte@Sun.COM 	/*
53577836SJohn.Forte@Sun.COM 	 * Restore previous signal mask for this thread
53587836SJohn.Forte@Sun.COM 	 */
53597836SJohn.Forte@Sun.COM 	if (pthread_sigmask(SIG_SETMASK, sigmaskRestore, NULL) != 0) {
53607836SJohn.Forte@Sun.COM 		syslog(LOG_ERR, "Unable to restore sigmask");
53617836SJohn.Forte@Sun.COM 	}
53627836SJohn.Forte@Sun.COM 
53637836SJohn.Forte@Sun.COM 	/*
53647836SJohn.Forte@Sun.COM 	 * Now raise signals that were raised while we were held
53657836SJohn.Forte@Sun.COM 	 */
53667836SJohn.Forte@Sun.COM 	if (sigismember(&signalsCaught, SIGTERM)) {
53677836SJohn.Forte@Sun.COM 		(void) sigdelset(&signalsCaught, SIGTERM);
53687836SJohn.Forte@Sun.COM 		(void) raise(SIGTERM);
53697836SJohn.Forte@Sun.COM 	}
53707836SJohn.Forte@Sun.COM 
53717836SJohn.Forte@Sun.COM 	if (sigismember(&signalsCaught, SIGINT)) {
53727836SJohn.Forte@Sun.COM 		(void) sigdelset(&signalsCaught, SIGINT);
53737836SJohn.Forte@Sun.COM 		(void) raise(SIGINT);
53747836SJohn.Forte@Sun.COM 	}
53757836SJohn.Forte@Sun.COM 
53767836SJohn.Forte@Sun.COM 	if (sigismember(&signalsCaught, SIGQUIT)) {
53777836SJohn.Forte@Sun.COM 		(void) sigdelset(&signalsCaught, SIGQUIT);
53787836SJohn.Forte@Sun.COM 		(void) raise(SIGQUIT);
53797836SJohn.Forte@Sun.COM 	}
53807836SJohn.Forte@Sun.COM 
53817836SJohn.Forte@Sun.COM 	return (ret);
53827836SJohn.Forte@Sun.COM }
5383