xref: /onnv-gate/usr/src/lib/libstmf/common/store.c (revision 11909)
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*11909SPeter.Gill@Sun.COM  * Copyright 2010 Sun Microsystems, Inc.  All rights reserved.
237836SJohn.Forte@Sun.COM  * Use is subject to license terms.
247836SJohn.Forte@Sun.COM  */
257836SJohn.Forte@Sun.COM 
267836SJohn.Forte@Sun.COM #include <libscf.h>
277836SJohn.Forte@Sun.COM #include <stdio.h>
287836SJohn.Forte@Sun.COM #include <stdlib.h>
297836SJohn.Forte@Sun.COM #include <errno.h>
307836SJohn.Forte@Sun.COM #include <assert.h>
317836SJohn.Forte@Sun.COM #include <strings.h>
327836SJohn.Forte@Sun.COM #include <libstmf.h>
337836SJohn.Forte@Sun.COM #include <store.h>
347836SJohn.Forte@Sun.COM #include <syslog.h>
357836SJohn.Forte@Sun.COM #include <signal.h>
367836SJohn.Forte@Sun.COM #include <pthread.h>
377836SJohn.Forte@Sun.COM #include <libnvpair.h>
387836SJohn.Forte@Sun.COM #include <limits.h>
397836SJohn.Forte@Sun.COM #include <unistd.h>
407836SJohn.Forte@Sun.COM 
417836SJohn.Forte@Sun.COM /*
427836SJohn.Forte@Sun.COM  * This file's functions are responsible for all store and retrieve operations
437836SJohn.Forte@Sun.COM  * against the STMF smf(5) database. The following shows the currently defined
447836SJohn.Forte@Sun.COM  * schema for the STMF database:
457836SJohn.Forte@Sun.COM  *
467836SJohn.Forte@Sun.COM  * Description of property groups for service: svc:/system/stmf
477836SJohn.Forte@Sun.COM  *
487836SJohn.Forte@Sun.COM  * Stability: Volatile
497836SJohn.Forte@Sun.COM  *
507836SJohn.Forte@Sun.COM  * 1. Property Group: host_groups
517836SJohn.Forte@Sun.COM  *        Properties: group_name-<N> where <N> is an unsigned integer
527836SJohn.Forte@Sun.COM  *                        type: ustring
537836SJohn.Forte@Sun.COM  *                        contains: group name
547836SJohn.Forte@Sun.COM  *                    group_name-<N>-member_list where <N> is an unsigned
557836SJohn.Forte@Sun.COM  *                            integer matching a group_name-<N> property.
567836SJohn.Forte@Sun.COM  *                        type: ustring
577836SJohn.Forte@Sun.COM  *                        contains: list of members
587836SJohn.Forte@Sun.COM  *
597836SJohn.Forte@Sun.COM  *        Description:
607836SJohn.Forte@Sun.COM  *             Contains the host group names as well as the host group members
617836SJohn.Forte@Sun.COM  *             for each host group.
627836SJohn.Forte@Sun.COM  *
637836SJohn.Forte@Sun.COM  * 2. Property Group: target_groups
647836SJohn.Forte@Sun.COM  *        Properties: group_name-<N> where <N> is an unsigned integer
657836SJohn.Forte@Sun.COM  *                        type: ustring
667836SJohn.Forte@Sun.COM  *                        contains: group name
677836SJohn.Forte@Sun.COM  *                    group_name-<N>-member_list where <N> is an unsigned
687836SJohn.Forte@Sun.COM  *                            integer matching a group_name-<N> property.
697836SJohn.Forte@Sun.COM  *                        type: ustring
707836SJohn.Forte@Sun.COM  *                        contains: list of members
717836SJohn.Forte@Sun.COM  *
727836SJohn.Forte@Sun.COM  *        Description:
737836SJohn.Forte@Sun.COM  *             Contains the target group names as well as the target group
747836SJohn.Forte@Sun.COM  *             members for each target group.
757836SJohn.Forte@Sun.COM  *
767836SJohn.Forte@Sun.COM  * 3. Property Group: lu-<GUID>
777836SJohn.Forte@Sun.COM  *                        where <GUID> is a 32 character hexadecimal string.
787836SJohn.Forte@Sun.COM  *        Properties: ve_cnt
797836SJohn.Forte@Sun.COM  *                        type: count
807836SJohn.Forte@Sun.COM  *                        contains: the number of current view entries
817836SJohn.Forte@Sun.COM  *                    view-entry-<N>-<GUID> where <N> is an unsigned integer
827836SJohn.Forte@Sun.COM  *                        type: ustring
837836SJohn.Forte@Sun.COM  *                        contains: nothing. Used as reference to the view
847836SJohn.Forte@Sun.COM  *                                  entry property group
857836SJohn.Forte@Sun.COM  *
867836SJohn.Forte@Sun.COM  *        Description:
877836SJohn.Forte@Sun.COM  *             Contains the references to each view entry. One lu-<GUID>
887836SJohn.Forte@Sun.COM  *             property group will exist for each logical unit with 1 or more
897836SJohn.Forte@Sun.COM  *             view entries.
907836SJohn.Forte@Sun.COM  *             Potentially can hold any other data that can be managed on a per
917836SJohn.Forte@Sun.COM  *             logical unit basis.
927836SJohn.Forte@Sun.COM  *
937836SJohn.Forte@Sun.COM  * 4. Property Group: view_entry-<N>-<GUID> (matches property in lu-<GUID>
947836SJohn.Forte@Sun.COM  *                    property group)
957836SJohn.Forte@Sun.COM  *        Properties: all_hosts
967836SJohn.Forte@Sun.COM  *                        type: boolean
977836SJohn.Forte@Sun.COM  *                        contains: when true, the value of host_group is
987836SJohn.Forte@Sun.COM  *                                  ignored
997836SJohn.Forte@Sun.COM  *                    all_targets
1007836SJohn.Forte@Sun.COM  *                        type: boolean
1017836SJohn.Forte@Sun.COM  *                        contains: when true, the value of target_group is
1027836SJohn.Forte@Sun.COM  *                                  ignored
1037836SJohn.Forte@Sun.COM  *                    host_group
1047836SJohn.Forte@Sun.COM  *                        type: ustring
1057836SJohn.Forte@Sun.COM  *                        contains: host group for logical unit mapping and
1067836SJohn.Forte@Sun.COM  *                                  masking purposes
1077836SJohn.Forte@Sun.COM  *                    target_group
1087836SJohn.Forte@Sun.COM  *                        type: ustring
1097836SJohn.Forte@Sun.COM  *                        contains: target group for logical unit mapping and
1107836SJohn.Forte@Sun.COM  *                                  masking purposes
1117836SJohn.Forte@Sun.COM  *                    lu_nbr
1127836SJohn.Forte@Sun.COM  *                        type: opaque
1137836SJohn.Forte@Sun.COM  *                        contains: the 8-byte SCSI logical unit number for
1147836SJohn.Forte@Sun.COM  *                                  mapping and masking purposes
1157836SJohn.Forte@Sun.COM  *        Description:
1167836SJohn.Forte@Sun.COM  *             One "view_entry-<N>-<GUID>" property group will exist for each
1177836SJohn.Forte@Sun.COM  *             view entry in the system. This property group name maps
1187836SJohn.Forte@Sun.COM  *             directly to the "lu-<GUID>" property group with a matching
1197836SJohn.Forte@Sun.COM  *             <GUID>.
1207836SJohn.Forte@Sun.COM  *
1217836SJohn.Forte@Sun.COM  * 5. Property Group: provider_data_pg_<provider-name>
1227836SJohn.Forte@Sun.COM  *                        where <provider-name> is the name of the provider
1237836SJohn.Forte@Sun.COM  *                           registered with stmf.
1247836SJohn.Forte@Sun.COM  *        Properties: provider_data_prop-<N>
1257836SJohn.Forte@Sun.COM  *                        where <N> is a sequential identifier for the data
1267836SJohn.Forte@Sun.COM  *                           chunk.
1277836SJohn.Forte@Sun.COM  *                        type: opaque
1287836SJohn.Forte@Sun.COM  *                        contains: up to STMF_PROVIDER_DATA_PROP_SIZE bytes
1297836SJohn.Forte@Sun.COM  *                                  of nvlist packed data.
1307836SJohn.Forte@Sun.COM  *                    provider_data_count
1317836SJohn.Forte@Sun.COM  *                        type: count
1327836SJohn.Forte@Sun.COM  *                        contains: the number of provider data chunks
1337836SJohn.Forte@Sun.COM  *                    provider_data_type
1347836SJohn.Forte@Sun.COM  *                        type: integer
1357836SJohn.Forte@Sun.COM  *                        contains: STMF_PORT_PROVIDER_TYPE or
1367836SJohn.Forte@Sun.COM  *                                  STMF_LU_PROVIDER_TYPE
1377836SJohn.Forte@Sun.COM  *
1387836SJohn.Forte@Sun.COM  *        Description:
1397836SJohn.Forte@Sun.COM  *             Holds the nvlist packed provider data set via
1407836SJohn.Forte@Sun.COM  *             stmfSetProviderData and retrieved via stmfGetProviderData. Data
1417836SJohn.Forte@Sun.COM  *             is stored in STMF_PROVIDER_DATA_PROP_SIZE chunks. On retrieve,
1427836SJohn.Forte@Sun.COM  *             these chunks are reassembled and unpacked.
1437836SJohn.Forte@Sun.COM  *
1447836SJohn.Forte@Sun.COM  */
1457836SJohn.Forte@Sun.COM 
1467836SJohn.Forte@Sun.COM static int iPsInit(scf_handle_t **, scf_service_t **);
1477836SJohn.Forte@Sun.COM static int iPsCreateDeleteGroup(char *, char *, int);
1487836SJohn.Forte@Sun.COM static int iPsAddRemoveGroupMember(char *, char *, char *, int);
1497836SJohn.Forte@Sun.COM static int iPsGetGroupList(char *, stmfGroupList **);
1507836SJohn.Forte@Sun.COM static int iPsGetGroupMemberList(char *, char *, stmfGroupProperties **);
1517836SJohn.Forte@Sun.COM static int iPsAddViewEntry(char *, char *, stmfViewEntry *);
1527836SJohn.Forte@Sun.COM static int iPsAddRemoveLuViewEntry(char *, char *, int);
1537836SJohn.Forte@Sun.COM static int iPsGetViewEntry(char *, stmfViewEntry *);
1547836SJohn.Forte@Sun.COM static int iPsGetActualGroupName(char *, char *, char *);
1557836SJohn.Forte@Sun.COM static int iPsGetServiceVersion(uint64_t *, scf_handle_t *, scf_service_t *);
1569585STim.Szeto@Sun.COM static int iPsGetSetPersistType(uint8_t *, scf_handle_t *, scf_service_t *,
1579585STim.Szeto@Sun.COM     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 
2067836SJohn.Forte@Sun.COM /*
2077836SJohn.Forte@Sun.COM  * Property names for view entry
2087836SJohn.Forte@Sun.COM  */
2097836SJohn.Forte@Sun.COM #define	STMF_VE_ALLHOSTS	    "all_hosts"
2107836SJohn.Forte@Sun.COM #define	STMF_VE_HOSTGROUP	    "host_group"
2117836SJohn.Forte@Sun.COM #define	STMF_VE_ALLTARGETS	    "all_targets"
2127836SJohn.Forte@Sun.COM #define	STMF_VE_TARGETGROUP	    "target_group"
2137836SJohn.Forte@Sun.COM #define	STMF_VE_LUNBR		    "lu_nbr"
2147836SJohn.Forte@Sun.COM 
2157836SJohn.Forte@Sun.COM /* Property group suffix for provider data */
2167836SJohn.Forte@Sun.COM #define	STMF_PROVIDER_DATA_PREFIX "provider_data_pg_"
2177836SJohn.Forte@Sun.COM #define	STMF_PROVIDER_DATA_PROP_PREFIX "provider_data_prop"
2187836SJohn.Forte@Sun.COM #define	STMF_PROVIDER_DATA_PROP_NAME_SIZE 256
2197836SJohn.Forte@Sun.COM #define	STMF_PROVIDER_DATA_PROP_TYPE "provider_type"
2207836SJohn.Forte@Sun.COM #define	STMF_PROVIDER_DATA_PROP_SET_COUNT "provider_data_set_cnt"
2217836SJohn.Forte@Sun.COM #define	STMF_PROVIDER_DATA_PROP_COUNT "provider_data_cnt"
2229585STim.Szeto@Sun.COM 
2237836SJohn.Forte@Sun.COM 
2247836SJohn.Forte@Sun.COM #define	STMF_SMF_READ_ATTR	"solaris.smf.read.stmf"
2257836SJohn.Forte@Sun.COM 
2269585STim.Szeto@Sun.COM #define	STMF_PS_PERSIST_NONE	"none"
2279585STim.Szeto@Sun.COM #define	STMF_PS_PERSIST_SMF	"smf"
2289585STim.Szeto@Sun.COM #define	STMF_PROVIDER_DATA_PROP_SIZE 4000
2299585STim.Szeto@Sun.COM /* END STORE PROPERTY DEFINITIONS */
2307836SJohn.Forte@Sun.COM 
2317836SJohn.Forte@Sun.COM /* service name */
2327836SJohn.Forte@Sun.COM #define	STMF_SERVICE	"system/stmf"
2337836SJohn.Forte@Sun.COM 
2347836SJohn.Forte@Sun.COM /* limits and flag values */
2357836SJohn.Forte@Sun.COM #define	GROUP_MEMBER_ALLOC 100
2367836SJohn.Forte@Sun.COM #define	VIEW_ENTRY_STRUCT_CNT 6
2377836SJohn.Forte@Sun.COM #define	VIEW_ENTRY_PG_SIZE 256
2387836SJohn.Forte@Sun.COM #define	LOGICAL_UNIT_PG_SIZE 256
2397836SJohn.Forte@Sun.COM #define	VIEW_ENTRY_MAX UINT32_MAX
2407836SJohn.Forte@Sun.COM #define	GROUP_MAX UINT64_MAX
2417836SJohn.Forte@Sun.COM #define	ADD 0
2427836SJohn.Forte@Sun.COM #define	REMOVE 1
2439585STim.Szeto@Sun.COM #define	GET 0
2449585STim.Szeto@Sun.COM #define	SET 1
2457836SJohn.Forte@Sun.COM 
2467836SJohn.Forte@Sun.COM /*
2477836SJohn.Forte@Sun.COM  * sigHandler
2487836SJohn.Forte@Sun.COM  *
2497836SJohn.Forte@Sun.COM  * Catch the signal and set the global signalsCaught to the signal received
2507836SJohn.Forte@Sun.COM  *
2517836SJohn.Forte@Sun.COM  * signalsCaught will be used by releaseSignal to raise this signal when
2527836SJohn.Forte@Sun.COM  * we're done processing our critical code.
2537836SJohn.Forte@Sun.COM  *
2547836SJohn.Forte@Sun.COM  */
2557836SJohn.Forte@Sun.COM static void
2567836SJohn.Forte@Sun.COM sigHandler(int sig)
2577836SJohn.Forte@Sun.COM {
2587836SJohn.Forte@Sun.COM 	(void) sigaddset(&signalsCaught, sig);
2597836SJohn.Forte@Sun.COM }
2607836SJohn.Forte@Sun.COM 
2617836SJohn.Forte@Sun.COM /*
2627836SJohn.Forte@Sun.COM  * iPsAddRemoveGroupMember
2637836SJohn.Forte@Sun.COM  *
2647836SJohn.Forte@Sun.COM  * Add or remove a member for a given group
2657836SJohn.Forte@Sun.COM  *
2667836SJohn.Forte@Sun.COM  * pgName - Property group name
2677836SJohn.Forte@Sun.COM  * groupName - group name to which the member is added/removed
2687836SJohn.Forte@Sun.COM  * memberName - member to be added/removed
2697836SJohn.Forte@Sun.COM  * addRemoveFlag - ADD/REMOVE
2707836SJohn.Forte@Sun.COM  *
2717836SJohn.Forte@Sun.COM  * returns:
2727836SJohn.Forte@Sun.COM  *  STMF_PS_SUCCESS on success
2737836SJohn.Forte@Sun.COM  *  STMF_PS_ERROR_* on failure
2747836SJohn.Forte@Sun.COM  */
2757836SJohn.Forte@Sun.COM static int
2767836SJohn.Forte@Sun.COM iPsAddRemoveGroupMember(char *pgName, char *groupName, char *memberName,
2777836SJohn.Forte@Sun.COM int addRemoveFlag)
2787836SJohn.Forte@Sun.COM {
2797836SJohn.Forte@Sun.COM 	scf_handle_t *handle = NULL;
2807836SJohn.Forte@Sun.COM 	scf_service_t *svc = NULL;
2817836SJohn.Forte@Sun.COM 	scf_propertygroup_t *pg = NULL;
2827836SJohn.Forte@Sun.COM 	scf_property_t *prop = NULL;
2837836SJohn.Forte@Sun.COM 	scf_value_t *valueLookup = NULL;
2847836SJohn.Forte@Sun.COM 	scf_value_t **valueSet = NULL;
2857836SJohn.Forte@Sun.COM 	scf_iter_t *valueIter = NULL;
2867836SJohn.Forte@Sun.COM 	scf_transaction_t *tran = NULL;
2877836SJohn.Forte@Sun.COM 	scf_transaction_entry_t *entry = NULL;
2887836SJohn.Forte@Sun.COM 	int i = 0;
2897836SJohn.Forte@Sun.COM 	int lastAlloc;
2907836SJohn.Forte@Sun.COM 	int valueArraySize = 0;
2917836SJohn.Forte@Sun.COM 	int ret = STMF_PS_SUCCESS;
2927836SJohn.Forte@Sun.COM 	char buf[STMF_IDENT_LENGTH];
2937836SJohn.Forte@Sun.COM 	int commitRet;
2947836SJohn.Forte@Sun.COM 	boolean_t found = B_FALSE;
2957836SJohn.Forte@Sun.COM 
2967836SJohn.Forte@Sun.COM 	assert(pgName != NULL && groupName != NULL && memberName != NULL);
2977836SJohn.Forte@Sun.COM 
2987836SJohn.Forte@Sun.COM 	/*
2997836SJohn.Forte@Sun.COM 	 * Init the service handle
3007836SJohn.Forte@Sun.COM 	 */
3017836SJohn.Forte@Sun.COM 	ret = iPsInit(&handle, &svc);
3027836SJohn.Forte@Sun.COM 	if (ret != STMF_PS_SUCCESS) {
3037836SJohn.Forte@Sun.COM 		goto out;
3047836SJohn.Forte@Sun.COM 	}
3057836SJohn.Forte@Sun.COM 
3067836SJohn.Forte@Sun.COM 	/*
3077836SJohn.Forte@Sun.COM 	 * Allocate scf resources
3087836SJohn.Forte@Sun.COM 	 */
3097836SJohn.Forte@Sun.COM 	if (((pg = scf_pg_create(handle)) == NULL) ||
3107836SJohn.Forte@Sun.COM 	    ((tran = scf_transaction_create(handle)) == NULL) ||
3117836SJohn.Forte@Sun.COM 	    ((entry = scf_entry_create(handle)) == NULL) ||
3127836SJohn.Forte@Sun.COM 	    ((prop = scf_property_create(handle)) == NULL) ||
3137836SJohn.Forte@Sun.COM 	    ((valueIter = scf_iter_create(handle)) == NULL)) {
3147836SJohn.Forte@Sun.COM 		syslog(LOG_ERR, "scf alloc resource failed - %s",
3157836SJohn.Forte@Sun.COM 		    scf_strerror(scf_error()));
3167836SJohn.Forte@Sun.COM 		ret = STMF_PS_ERROR;
3177836SJohn.Forte@Sun.COM 		goto out;
3187836SJohn.Forte@Sun.COM 	}
3197836SJohn.Forte@Sun.COM 
3207836SJohn.Forte@Sun.COM 	/*
3217836SJohn.Forte@Sun.COM 	 * Get the service property group handle
3227836SJohn.Forte@Sun.COM 	 */
3237836SJohn.Forte@Sun.COM 	if (scf_service_get_pg(svc, pgName, pg) == -1) {
3247836SJohn.Forte@Sun.COM 		if (scf_error() == SCF_ERROR_NOT_FOUND) {
3257836SJohn.Forte@Sun.COM 			ret = STMF_PS_ERROR_NOT_FOUND;
3267836SJohn.Forte@Sun.COM 		} else {
3277836SJohn.Forte@Sun.COM 			ret = STMF_PS_ERROR;
3287836SJohn.Forte@Sun.COM 		}
329*11909SPeter.Gill@Sun.COM 		syslog(LOG_ERR, "get pg %s failed - %s",
330*11909SPeter.Gill@Sun.COM 		    pgName, scf_strerror(scf_error()));
331*11909SPeter.Gill@Sun.COM 
3327836SJohn.Forte@Sun.COM 		goto out;
3337836SJohn.Forte@Sun.COM 	}
3347836SJohn.Forte@Sun.COM 
3357836SJohn.Forte@Sun.COM 	/*
3367836SJohn.Forte@Sun.COM 	 * Begin the transaction
3377836SJohn.Forte@Sun.COM 	 */
3387836SJohn.Forte@Sun.COM 	if (scf_transaction_start(tran, pg) == -1) {
339*11909SPeter.Gill@Sun.COM 		syslog(LOG_ERR, "start transaction for %s failed - %s",
340*11909SPeter.Gill@Sun.COM 		    pgName, scf_strerror(scf_error()));
3417836SJohn.Forte@Sun.COM 		ret = STMF_PS_ERROR;
3427836SJohn.Forte@Sun.COM 		goto out;
3437836SJohn.Forte@Sun.COM 	}
3447836SJohn.Forte@Sun.COM 
3457836SJohn.Forte@Sun.COM 	/*
3467836SJohn.Forte@Sun.COM 	 * We're changing an existing property by adding a propval
3477836SJohn.Forte@Sun.COM 	 * There are no add semantics in libscf for a property value. We'll
3487836SJohn.Forte@Sun.COM 	 * need to read in the current properties and apply them all to the
3497836SJohn.Forte@Sun.COM 	 * set and then add the one we were asked to add or omit the one
3507836SJohn.Forte@Sun.COM 	 * we were asked to remove.
3517836SJohn.Forte@Sun.COM 	 */
3527836SJohn.Forte@Sun.COM 	if (scf_transaction_property_change(tran, entry, groupName,
3537836SJohn.Forte@Sun.COM 	    SCF_TYPE_USTRING) == -1) {
3547836SJohn.Forte@Sun.COM 		if (scf_error() == SCF_ERROR_NOT_FOUND) {
3557836SJohn.Forte@Sun.COM 			ret = STMF_PS_ERROR_GROUP_NOT_FOUND;
3567836SJohn.Forte@Sun.COM 		} else {
3577836SJohn.Forte@Sun.COM 			ret = STMF_PS_ERROR;
358*11909SPeter.Gill@Sun.COM 			syslog(LOG_ERR, "tran property change %s/%s "
359*11909SPeter.Gill@Sun.COM 			    "failed - %s", pgName, groupName,
3607836SJohn.Forte@Sun.COM 			    scf_strerror(scf_error()));
3617836SJohn.Forte@Sun.COM 		}
3627836SJohn.Forte@Sun.COM 		goto out;
3637836SJohn.Forte@Sun.COM 	}
3647836SJohn.Forte@Sun.COM 
3657836SJohn.Forte@Sun.COM 	/*
3667836SJohn.Forte@Sun.COM 	 * Get the property handle
3677836SJohn.Forte@Sun.COM 	 */
3687836SJohn.Forte@Sun.COM 	if (scf_pg_get_property(pg, groupName, prop) == -1) {
369*11909SPeter.Gill@Sun.COM 		syslog(LOG_ERR, "get property %s/%s failed - %s",
370*11909SPeter.Gill@Sun.COM 		    pgName, groupName, scf_strerror(scf_error()));
3717836SJohn.Forte@Sun.COM 		ret = STMF_PS_ERROR;
3727836SJohn.Forte@Sun.COM 		goto out;
3737836SJohn.Forte@Sun.COM 	}
3747836SJohn.Forte@Sun.COM 
3757836SJohn.Forte@Sun.COM 	/*
3767836SJohn.Forte@Sun.COM 	 * Value lookup is used to lookup the existing values
3777836SJohn.Forte@Sun.COM 	 */
3787836SJohn.Forte@Sun.COM 	valueLookup = scf_value_create(handle);
3797836SJohn.Forte@Sun.COM 	if (valueLookup == NULL) {
380*11909SPeter.Gill@Sun.COM 		syslog(LOG_ERR, "scf value alloc for %s failed - %s",
381*11909SPeter.Gill@Sun.COM 		    pgName, 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 	 * valueIter is the iterator handle, create the resource
3887836SJohn.Forte@Sun.COM 	 */
3897836SJohn.Forte@Sun.COM 	if (scf_iter_property_values(valueIter, prop) == -1) {
390*11909SPeter.Gill@Sun.COM 		syslog(LOG_ERR, "iter values for %s/%s failed - %s",
391*11909SPeter.Gill@Sun.COM 		    pgName, groupName, scf_strerror(scf_error()));
3927836SJohn.Forte@Sun.COM 		ret = STMF_PS_ERROR;
3937836SJohn.Forte@Sun.COM 		goto out;
3947836SJohn.Forte@Sun.COM 	}
3957836SJohn.Forte@Sun.COM 
3967836SJohn.Forte@Sun.COM 	/*
3977836SJohn.Forte@Sun.COM 	 * Allocate value resource pointers.
3987836SJohn.Forte@Sun.COM 	 * We need a value resource for each value as value pointers passed
3997836SJohn.Forte@Sun.COM 	 * to libscf cannot be destroyed until the commit or destroy on the
4007836SJohn.Forte@Sun.COM 	 * transaction is done.
4017836SJohn.Forte@Sun.COM 	 *
4027836SJohn.Forte@Sun.COM 	 * We're using GROUP_MEMBER_ALLOC initially. If it's not large
4037836SJohn.Forte@Sun.COM 	 * enough, we'll realloc on the fly
4047836SJohn.Forte@Sun.COM 	 */
4057836SJohn.Forte@Sun.COM 	valueSet = (scf_value_t **)calloc(1, sizeof (*valueSet)
4067836SJohn.Forte@Sun.COM 	    * (lastAlloc = GROUP_MEMBER_ALLOC));
4077836SJohn.Forte@Sun.COM 	if (valueSet == NULL) {
4087836SJohn.Forte@Sun.COM 		ret = STMF_PS_ERROR_NOMEM;
4097836SJohn.Forte@Sun.COM 		goto out;
4107836SJohn.Forte@Sun.COM 	}
4117836SJohn.Forte@Sun.COM 
4127836SJohn.Forte@Sun.COM 	/*
4137836SJohn.Forte@Sun.COM 	 * Iterate through the existing values
4147836SJohn.Forte@Sun.COM 	 */
4157836SJohn.Forte@Sun.COM 	while (scf_iter_next_value(valueIter, valueLookup) == 1) {
4167836SJohn.Forte@Sun.COM 		bzero(buf, sizeof (buf));
4177836SJohn.Forte@Sun.COM 		if (scf_value_get_ustring(valueLookup, buf, MAXNAMELEN) == -1) {
418*11909SPeter.Gill@Sun.COM 			syslog(LOG_ERR, "iter %s/%s value failed - %s",
419*11909SPeter.Gill@Sun.COM 			    pgName, groupName, scf_strerror(scf_error()));
4207836SJohn.Forte@Sun.COM 			ret = STMF_PS_ERROR;
4217836SJohn.Forte@Sun.COM 			break;
4227836SJohn.Forte@Sun.COM 		}
4237836SJohn.Forte@Sun.COM 
4247836SJohn.Forte@Sun.COM 		/*
4257836SJohn.Forte@Sun.COM 		 * Check for existing
4267836SJohn.Forte@Sun.COM 		 * If we're adding, it's an error
4277836SJohn.Forte@Sun.COM 		 * If we're removing, we skip it and simply not
4287836SJohn.Forte@Sun.COM 		 * add it to the set. Subtraction by omission.
4297836SJohn.Forte@Sun.COM 		 */
4307836SJohn.Forte@Sun.COM 		if ((strlen(buf) == strlen(memberName)) &&
4317836SJohn.Forte@Sun.COM 		    bcmp(buf, memberName, strlen(buf)) == 0) {
4327836SJohn.Forte@Sun.COM 			if (addRemoveFlag == ADD) {
4337836SJohn.Forte@Sun.COM 				ret = STMF_PS_ERROR_EXISTS;
4347836SJohn.Forte@Sun.COM 				break;
4357836SJohn.Forte@Sun.COM 			} else {
4367836SJohn.Forte@Sun.COM 				found = B_TRUE;
4377836SJohn.Forte@Sun.COM 				continue;
4387836SJohn.Forte@Sun.COM 			}
4397836SJohn.Forte@Sun.COM 		}
4407836SJohn.Forte@Sun.COM 
4417836SJohn.Forte@Sun.COM 		/*
4427836SJohn.Forte@Sun.COM 		 * Create the value resource for this iteration
4437836SJohn.Forte@Sun.COM 		 */
4447836SJohn.Forte@Sun.COM 		valueSet[i] = scf_value_create(handle);
4457836SJohn.Forte@Sun.COM 		if (valueSet[i] == NULL) {
446*11909SPeter.Gill@Sun.COM 			syslog(LOG_ERR, "scf value alloc for %s failed - %s",
447*11909SPeter.Gill@Sun.COM 			    pgName, scf_strerror(scf_error()));
4487836SJohn.Forte@Sun.COM 			ret = STMF_PS_ERROR;
4497836SJohn.Forte@Sun.COM 			break;
4507836SJohn.Forte@Sun.COM 		}
4517836SJohn.Forte@Sun.COM 
4527836SJohn.Forte@Sun.COM 		/*
4537836SJohn.Forte@Sun.COM 		 * Set the value
4547836SJohn.Forte@Sun.COM 		 */
4557836SJohn.Forte@Sun.COM 		if (scf_value_set_ustring(valueSet[i], buf) == -1) {
456*11909SPeter.Gill@Sun.COM 			syslog(LOG_ERR, "set value for %s/%s failed - %s",
457*11909SPeter.Gill@Sun.COM 			    pgName, groupName, scf_strerror(scf_error()));
4587836SJohn.Forte@Sun.COM 			ret = STMF_PS_ERROR;
4597836SJohn.Forte@Sun.COM 			break;
4607836SJohn.Forte@Sun.COM 		}
4617836SJohn.Forte@Sun.COM 
4627836SJohn.Forte@Sun.COM 		/*
4637836SJohn.Forte@Sun.COM 		 * Now add the value
4647836SJohn.Forte@Sun.COM 		 */
4657836SJohn.Forte@Sun.COM 		if (scf_entry_add_value(entry, valueSet[i]) == -1) {
466*11909SPeter.Gill@Sun.COM 			syslog(LOG_ERR, "add value for %s/%s failed - %s",
467*11909SPeter.Gill@Sun.COM 			    pgName, groupName, scf_strerror(scf_error()));
4687836SJohn.Forte@Sun.COM 			ret = STMF_PS_ERROR;
4697836SJohn.Forte@Sun.COM 			break;
4707836SJohn.Forte@Sun.COM 		}
4717836SJohn.Forte@Sun.COM 
4727836SJohn.Forte@Sun.COM 		i++;
4737836SJohn.Forte@Sun.COM 
4747836SJohn.Forte@Sun.COM 		/*
4757836SJohn.Forte@Sun.COM 		 * realloc if we've hit the previous alloc size
4767836SJohn.Forte@Sun.COM 		 */
4777836SJohn.Forte@Sun.COM 		if (i >= lastAlloc) {
4787836SJohn.Forte@Sun.COM 			lastAlloc += GROUP_MEMBER_ALLOC;
4797836SJohn.Forte@Sun.COM 			valueSet = realloc(valueSet,
4807836SJohn.Forte@Sun.COM 			    sizeof (*valueSet) * lastAlloc);
4817836SJohn.Forte@Sun.COM 			if (valueSet == NULL) {
4827836SJohn.Forte@Sun.COM 				ret = STMF_PS_ERROR;
4837836SJohn.Forte@Sun.COM 				break;
4847836SJohn.Forte@Sun.COM 			}
4857836SJohn.Forte@Sun.COM 		}
4867836SJohn.Forte@Sun.COM 	}
4877836SJohn.Forte@Sun.COM 
4887836SJohn.Forte@Sun.COM 	/*
4897836SJohn.Forte@Sun.COM 	 * set valueArraySize to final allocated length
4907836SJohn.Forte@Sun.COM 	 * so we can use it to destroy the resources correctly
4917836SJohn.Forte@Sun.COM 	 */
4927836SJohn.Forte@Sun.COM 	valueArraySize = i;
4937836SJohn.Forte@Sun.COM 
4947836SJohn.Forte@Sun.COM 	if (!found && (addRemoveFlag == REMOVE)) {
4957836SJohn.Forte@Sun.COM 		ret = STMF_PS_ERROR_MEMBER_NOT_FOUND;
4967836SJohn.Forte@Sun.COM 	}
4977836SJohn.Forte@Sun.COM 
4987836SJohn.Forte@Sun.COM 	if (ret != STMF_PS_SUCCESS) {
4997836SJohn.Forte@Sun.COM 		goto out;
5007836SJohn.Forte@Sun.COM 	}
5017836SJohn.Forte@Sun.COM 
5027836SJohn.Forte@Sun.COM 	/*
5037836SJohn.Forte@Sun.COM 	 * If we're adding, we have one more step. Add the member to the
5047836SJohn.Forte@Sun.COM 	 * propval list
5057836SJohn.Forte@Sun.COM 	 */
5067836SJohn.Forte@Sun.COM 	if (addRemoveFlag == ADD) {
5077836SJohn.Forte@Sun.COM 		/*
5087836SJohn.Forte@Sun.COM 		 * Now create the new entry
5097836SJohn.Forte@Sun.COM 		 */
5107836SJohn.Forte@Sun.COM 		valueSet[i] = scf_value_create(handle);
5117836SJohn.Forte@Sun.COM 		if (valueSet[i] == NULL) {
512*11909SPeter.Gill@Sun.COM 			syslog(LOG_ERR, "scf value alloc for %s/%s failed - %s",
513*11909SPeter.Gill@Sun.COM 			    pgName, groupName, scf_strerror(scf_error()));
5147836SJohn.Forte@Sun.COM 			ret = STMF_PS_ERROR;
5157836SJohn.Forte@Sun.COM 			goto out;
5167836SJohn.Forte@Sun.COM 		} else {
5177836SJohn.Forte@Sun.COM 			valueArraySize++;
5187836SJohn.Forte@Sun.COM 		}
5197836SJohn.Forte@Sun.COM 
5207836SJohn.Forte@Sun.COM 		/*
5217836SJohn.Forte@Sun.COM 		 * Set the new member name
5227836SJohn.Forte@Sun.COM 		 */
5237836SJohn.Forte@Sun.COM 		if (scf_value_set_ustring(valueSet[i], memberName) == -1) {
524*11909SPeter.Gill@Sun.COM 			syslog(LOG_ERR, "set value for %s/%s failed - %s",
525*11909SPeter.Gill@Sun.COM 			    pgName, groupName, scf_strerror(scf_error()));
5267836SJohn.Forte@Sun.COM 			ret = STMF_PS_ERROR;
5277836SJohn.Forte@Sun.COM 			goto out;
5287836SJohn.Forte@Sun.COM 		}
5297836SJohn.Forte@Sun.COM 
5307836SJohn.Forte@Sun.COM 		/*
5317836SJohn.Forte@Sun.COM 		 * Add the new member
5327836SJohn.Forte@Sun.COM 		 */
5337836SJohn.Forte@Sun.COM 		if (scf_entry_add_value(entry, valueSet[i]) == -1) {
534*11909SPeter.Gill@Sun.COM 			syslog(LOG_ERR, "add value for %s/%s failed - %s",
535*11909SPeter.Gill@Sun.COM 			    pgName, groupName, scf_strerror(scf_error()));
5367836SJohn.Forte@Sun.COM 			ret = STMF_PS_ERROR;
5377836SJohn.Forte@Sun.COM 			goto out;
5387836SJohn.Forte@Sun.COM 		}
5397836SJohn.Forte@Sun.COM 	}
5407836SJohn.Forte@Sun.COM 
5417836SJohn.Forte@Sun.COM 	/*
5427836SJohn.Forte@Sun.COM 	 * Yes, we're finally done. We actually added or removed one entry
5437836SJohn.Forte@Sun.COM 	 * from the list.
5447836SJohn.Forte@Sun.COM 	 * Woohoo!
5457836SJohn.Forte@Sun.COM 	 */
5467836SJohn.Forte@Sun.COM 	if ((commitRet = scf_transaction_commit(tran)) != 1) {
547*11909SPeter.Gill@Sun.COM 		syslog(LOG_ERR, "transaction commit for %s failed - %s",
548*11909SPeter.Gill@Sun.COM 		    pgName, scf_strerror(scf_error()));
5497836SJohn.Forte@Sun.COM 		if (commitRet == 0) {
5507836SJohn.Forte@Sun.COM 			ret = STMF_PS_ERROR_BUSY;
5517836SJohn.Forte@Sun.COM 		} else {
5527836SJohn.Forte@Sun.COM 			ret = STMF_PS_ERROR;
5537836SJohn.Forte@Sun.COM 		}
5547836SJohn.Forte@Sun.COM 		goto out;
5557836SJohn.Forte@Sun.COM 	}
5567836SJohn.Forte@Sun.COM 
5577836SJohn.Forte@Sun.COM out:
5587836SJohn.Forte@Sun.COM 	/*
5597836SJohn.Forte@Sun.COM 	 * Free resources
5607836SJohn.Forte@Sun.COM 	 */
5617836SJohn.Forte@Sun.COM 	if (handle != NULL) {
5627836SJohn.Forte@Sun.COM 		scf_handle_destroy(handle);
5637836SJohn.Forte@Sun.COM 	}
5647836SJohn.Forte@Sun.COM 	if (svc != NULL) {
5657836SJohn.Forte@Sun.COM 		scf_service_destroy(svc);
5667836SJohn.Forte@Sun.COM 	}
5677836SJohn.Forte@Sun.COM 	if (pg != NULL) {
5687836SJohn.Forte@Sun.COM 		scf_pg_destroy(pg);
5697836SJohn.Forte@Sun.COM 	}
5707836SJohn.Forte@Sun.COM 	if (tran != NULL) {
5717836SJohn.Forte@Sun.COM 		scf_transaction_destroy(tran);
5727836SJohn.Forte@Sun.COM 	}
5737836SJohn.Forte@Sun.COM 	if (entry != NULL) {
5747836SJohn.Forte@Sun.COM 		scf_entry_destroy(entry);
5757836SJohn.Forte@Sun.COM 	}
5767836SJohn.Forte@Sun.COM 	if (prop != NULL) {
5777836SJohn.Forte@Sun.COM 		scf_property_destroy(prop);
5787836SJohn.Forte@Sun.COM 	}
5797836SJohn.Forte@Sun.COM 	if (valueLookup != NULL) {
5807836SJohn.Forte@Sun.COM 		scf_value_destroy(valueLookup);
5817836SJohn.Forte@Sun.COM 	}
5827836SJohn.Forte@Sun.COM 	if (valueIter != NULL) {
5837836SJohn.Forte@Sun.COM 		scf_iter_destroy(valueIter);
5847836SJohn.Forte@Sun.COM 	}
5857836SJohn.Forte@Sun.COM 
5867836SJohn.Forte@Sun.COM 	/*
5877836SJohn.Forte@Sun.COM 	 * Free valueSet scf resources
5887836SJohn.Forte@Sun.COM 	 */
5897836SJohn.Forte@Sun.COM 	if (valueArraySize > 0) {
5907836SJohn.Forte@Sun.COM 		for (i = 0; i < valueArraySize; i++) {
5917836SJohn.Forte@Sun.COM 			scf_value_destroy(valueSet[i]);
5927836SJohn.Forte@Sun.COM 		}
5937836SJohn.Forte@Sun.COM 	}
5947836SJohn.Forte@Sun.COM 	/*
5957836SJohn.Forte@Sun.COM 	 * Now free the pointer array to the resources
5967836SJohn.Forte@Sun.COM 	 */
5977836SJohn.Forte@Sun.COM 	if (valueSet != NULL) {
5987836SJohn.Forte@Sun.COM 		free(valueSet);
5997836SJohn.Forte@Sun.COM 	}
6007836SJohn.Forte@Sun.COM 
6017836SJohn.Forte@Sun.COM 	return (ret);
6027836SJohn.Forte@Sun.COM }
6037836SJohn.Forte@Sun.COM 
6047836SJohn.Forte@Sun.COM /*
6057836SJohn.Forte@Sun.COM  * iPsAddRemoveLuViewEntry
6067836SJohn.Forte@Sun.COM  *
6077836SJohn.Forte@Sun.COM  * Adds or removes a view entry name property for a given logical unit
6087836SJohn.Forte@Sun.COM  * property group. There is one logical unit property group for every logical
6097836SJohn.Forte@Sun.COM  * unit that has one or more associated view entries.
6107836SJohn.Forte@Sun.COM  *
6117836SJohn.Forte@Sun.COM  * luPgName - Property group name of logical unit
6127836SJohn.Forte@Sun.COM  * viewEntryPgName - Property group name of view entry
6137836SJohn.Forte@Sun.COM  * addRemoveFlag - ADD_VE/REMOVE_VE
6147836SJohn.Forte@Sun.COM  *
6157836SJohn.Forte@Sun.COM  * returns:
6167836SJohn.Forte@Sun.COM  *  STMF_PS_SUCCESS on success
6177836SJohn.Forte@Sun.COM  *  STMF_PS_ERROR_* on failure
6187836SJohn.Forte@Sun.COM  */
6197836SJohn.Forte@Sun.COM static int
6207836SJohn.Forte@Sun.COM iPsAddRemoveLuViewEntry(char *luPgName, char *viewEntryPgName,
6217836SJohn.Forte@Sun.COM     int addRemoveFlag)
6227836SJohn.Forte@Sun.COM {
6237836SJohn.Forte@Sun.COM 	scf_handle_t	*handle = NULL;
6247836SJohn.Forte@Sun.COM 	scf_service_t	*svc = NULL;
6257836SJohn.Forte@Sun.COM 	scf_propertygroup_t	*pg = NULL;
6267836SJohn.Forte@Sun.COM 	scf_property_t	*prop = NULL;
6277836SJohn.Forte@Sun.COM 	scf_value_t	*value = NULL;
6287836SJohn.Forte@Sun.COM 	scf_transaction_t   *tran = NULL;
6297836SJohn.Forte@Sun.COM 	scf_transaction_entry_t *entry = NULL;
6307836SJohn.Forte@Sun.COM 	scf_transaction_entry_t *entryVeName = NULL;
6317836SJohn.Forte@Sun.COM 	boolean_t createVeCnt = B_FALSE;
6327836SJohn.Forte@Sun.COM 	uint64_t veCnt = 0;
6337836SJohn.Forte@Sun.COM 	int ret = STMF_PS_SUCCESS;
6347836SJohn.Forte@Sun.COM 	int commitRet;
6357836SJohn.Forte@Sun.COM 
6367836SJohn.Forte@Sun.COM 	assert(luPgName != NULL || viewEntryPgName != NULL);
6377836SJohn.Forte@Sun.COM 	assert(!(addRemoveFlag != ADD && addRemoveFlag != REMOVE));
6387836SJohn.Forte@Sun.COM 
6397836SJohn.Forte@Sun.COM 	/*
6407836SJohn.Forte@Sun.COM 	 * Init the service handle
6417836SJohn.Forte@Sun.COM 	 */
6427836SJohn.Forte@Sun.COM 	ret = iPsInit(&handle, &svc);
6437836SJohn.Forte@Sun.COM 	if (ret != STMF_PS_SUCCESS) {
6447836SJohn.Forte@Sun.COM 		goto out;
6457836SJohn.Forte@Sun.COM 	}
6467836SJohn.Forte@Sun.COM 
6477836SJohn.Forte@Sun.COM 	/*
6487836SJohn.Forte@Sun.COM 	 * Allocate scf resources
6497836SJohn.Forte@Sun.COM 	 */
6507836SJohn.Forte@Sun.COM 	if (((pg = scf_pg_create(handle)) == NULL) ||
6517836SJohn.Forte@Sun.COM 	    ((tran = scf_transaction_create(handle)) == NULL) ||
6527836SJohn.Forte@Sun.COM 	    ((entry = scf_entry_create(handle)) == NULL) ||
6537836SJohn.Forte@Sun.COM 	    ((prop = scf_property_create(handle)) == NULL) ||
6547836SJohn.Forte@Sun.COM 	    ((value = scf_value_create(handle)) == NULL)) {
6557836SJohn.Forte@Sun.COM 		syslog(LOG_ERR, "scf alloc resource failed - %s",
6567836SJohn.Forte@Sun.COM 		    scf_strerror(scf_error()));
6577836SJohn.Forte@Sun.COM 		ret = STMF_PS_ERROR;
6587836SJohn.Forte@Sun.COM 		goto out;
6597836SJohn.Forte@Sun.COM 	}
6607836SJohn.Forte@Sun.COM 
6617836SJohn.Forte@Sun.COM 	/* get the LU property group */
6627836SJohn.Forte@Sun.COM 	if (scf_service_get_pg(svc, luPgName, pg) == -1) {
6637836SJohn.Forte@Sun.COM 		if (scf_error() == SCF_ERROR_NOT_FOUND &&
6647836SJohn.Forte@Sun.COM 		    addRemoveFlag == ADD) {
6657836SJohn.Forte@Sun.COM 			/* if it doesn't exist, create it */
6667836SJohn.Forte@Sun.COM 			if (scf_service_add_pg(svc, luPgName,
6677836SJohn.Forte@Sun.COM 			    SCF_GROUP_APPLICATION, 0, pg) == -1) {
668*11909SPeter.Gill@Sun.COM 				syslog(LOG_ERR, "add pg %s failed - %s",
669*11909SPeter.Gill@Sun.COM 				    luPgName, scf_strerror(scf_error()));
6707836SJohn.Forte@Sun.COM 				ret = STMF_PS_ERROR;
6717836SJohn.Forte@Sun.COM 			} else {
6727836SJohn.Forte@Sun.COM 				/* we need to create the VE_CNT property */
6737836SJohn.Forte@Sun.COM 				createVeCnt = B_TRUE;
6747836SJohn.Forte@Sun.COM 				ret = STMF_PS_SUCCESS;
6757836SJohn.Forte@Sun.COM 			}
6767836SJohn.Forte@Sun.COM 		} else if (scf_error() == SCF_ERROR_NOT_FOUND) {
6777836SJohn.Forte@Sun.COM 			ret = STMF_PS_ERROR_NOT_FOUND;
6787836SJohn.Forte@Sun.COM 		} else {
679*11909SPeter.Gill@Sun.COM 			syslog(LOG_ERR, "get lu pg %s failed - %s",
680*11909SPeter.Gill@Sun.COM 			    luPgName, scf_strerror(scf_error()));
6817836SJohn.Forte@Sun.COM 			ret = STMF_PS_ERROR;
6827836SJohn.Forte@Sun.COM 		}
6837836SJohn.Forte@Sun.COM 		if (ret != STMF_PS_SUCCESS) {
6847836SJohn.Forte@Sun.COM 			goto out;
6857836SJohn.Forte@Sun.COM 		}
6867836SJohn.Forte@Sun.COM 	}
6877836SJohn.Forte@Sun.COM 
6887836SJohn.Forte@Sun.COM 
6897836SJohn.Forte@Sun.COM 	/*
6907836SJohn.Forte@Sun.COM 	 * Begin the transaction
6917836SJohn.Forte@Sun.COM 	 */
6927836SJohn.Forte@Sun.COM 	if (scf_transaction_start(tran, pg) == -1) {
693*11909SPeter.Gill@Sun.COM 		syslog(LOG_ERR, "start transaction for %s failed - %s",
694*11909SPeter.Gill@Sun.COM 		    luPgName, scf_strerror(scf_error()));
6957836SJohn.Forte@Sun.COM 		ret = STMF_PS_ERROR;
6967836SJohn.Forte@Sun.COM 		goto out;
6977836SJohn.Forte@Sun.COM 	}
6987836SJohn.Forte@Sun.COM 
6997836SJohn.Forte@Sun.COM 
7007836SJohn.Forte@Sun.COM 	if (createVeCnt) {
7017836SJohn.Forte@Sun.COM 		/*
7027836SJohn.Forte@Sun.COM 		 * Create the STMF_VE_CNT property. This will keep the current
7037836SJohn.Forte@Sun.COM 		 * total view entries for this logical unit.
7047836SJohn.Forte@Sun.COM 		 */
7057836SJohn.Forte@Sun.COM 		if (scf_transaction_property_new(tran, entry, STMF_VE_CNT,
7067836SJohn.Forte@Sun.COM 		    SCF_TYPE_COUNT) == -1) {
7077836SJohn.Forte@Sun.COM 			if (scf_error() == SCF_ERROR_EXISTS) {
7087836SJohn.Forte@Sun.COM 				ret = STMF_PS_ERROR_EXISTS;
7097836SJohn.Forte@Sun.COM 			} else {
7107836SJohn.Forte@Sun.COM 				syslog(LOG_ERR,
711*11909SPeter.Gill@Sun.COM 				    "transaction property new %s/%s "
712*11909SPeter.Gill@Sun.COM 				    "failed - %s", luPgName, STMF_VE_CNT,
7137836SJohn.Forte@Sun.COM 				    scf_strerror(scf_error()));
7147836SJohn.Forte@Sun.COM 				ret = STMF_PS_ERROR;
7157836SJohn.Forte@Sun.COM 			}
7167836SJohn.Forte@Sun.COM 			goto out;
7177836SJohn.Forte@Sun.COM 		}
7187836SJohn.Forte@Sun.COM 	} else {
7197836SJohn.Forte@Sun.COM 		/*
7207836SJohn.Forte@Sun.COM 		 * The STMF_VE_CNT property already exists. Just update
7217836SJohn.Forte@Sun.COM 		 * it.
7227836SJohn.Forte@Sun.COM 		 */
7237836SJohn.Forte@Sun.COM 		if (scf_transaction_property_change(tran, entry,
7247836SJohn.Forte@Sun.COM 		    STMF_VE_CNT, SCF_TYPE_COUNT) == -1) {
725*11909SPeter.Gill@Sun.COM 			syslog(LOG_ERR, "transaction property %s/%s change "
726*11909SPeter.Gill@Sun.COM 			    "failed - %s", luPgName, STMF_VE_CNT,
7277836SJohn.Forte@Sun.COM 			    scf_strerror(scf_error()));
7287836SJohn.Forte@Sun.COM 			ret = STMF_PS_ERROR;
7297836SJohn.Forte@Sun.COM 			goto out;
7307836SJohn.Forte@Sun.COM 		}
7317836SJohn.Forte@Sun.COM 
7327836SJohn.Forte@Sun.COM 		/*
7337836SJohn.Forte@Sun.COM 		 * Get the STMF_VE_CNT property
7347836SJohn.Forte@Sun.COM 		 */
7357836SJohn.Forte@Sun.COM 		if (scf_pg_get_property(pg, STMF_VE_CNT, prop) == -1) {
736*11909SPeter.Gill@Sun.COM 			syslog(LOG_ERR, "get property %s/%s failed - %s",
737*11909SPeter.Gill@Sun.COM 			    luPgName, STMF_VE_CNT, scf_strerror(scf_error()));
7387836SJohn.Forte@Sun.COM 			ret = STMF_PS_ERROR;
7397836SJohn.Forte@Sun.COM 			goto out;
7407836SJohn.Forte@Sun.COM 		}
7417836SJohn.Forte@Sun.COM 
7427836SJohn.Forte@Sun.COM 		/*
7437836SJohn.Forte@Sun.COM 		 * Get the STMF_VE_CNT value
7447836SJohn.Forte@Sun.COM 		 */
7457836SJohn.Forte@Sun.COM 		if (scf_property_get_value(prop, value) == -1) {
746*11909SPeter.Gill@Sun.COM 			syslog(LOG_ERR, "get property %s/%s value failed - %s",
747*11909SPeter.Gill@Sun.COM 			    luPgName, STMF_VE_CNT, scf_strerror(scf_error()));
7487836SJohn.Forte@Sun.COM 			ret = STMF_PS_ERROR;
7497836SJohn.Forte@Sun.COM 			goto out;
7507836SJohn.Forte@Sun.COM 		}
7517836SJohn.Forte@Sun.COM 
7527836SJohn.Forte@Sun.COM 		/*
7537836SJohn.Forte@Sun.COM 		 * Now get the actual value from the value handle
7547836SJohn.Forte@Sun.COM 		 */
7557836SJohn.Forte@Sun.COM 		if (scf_value_get_count(value, &veCnt) == -1) {
756*11909SPeter.Gill@Sun.COM 			syslog(LOG_ERR, "get count value %s/%s failed - %s",
757*11909SPeter.Gill@Sun.COM 			    luPgName, STMF_VE_CNT, scf_strerror(scf_error()));
7587836SJohn.Forte@Sun.COM 			ret = STMF_PS_ERROR;
7597836SJohn.Forte@Sun.COM 			goto out;
7607836SJohn.Forte@Sun.COM 		}
7617836SJohn.Forte@Sun.COM 
7627836SJohn.Forte@Sun.COM 		/*
7637836SJohn.Forte@Sun.COM 		 * Reset the value resource as it is used below
7647836SJohn.Forte@Sun.COM 		 */
7657836SJohn.Forte@Sun.COM 		scf_value_reset(value);
7667836SJohn.Forte@Sun.COM 	}
7677836SJohn.Forte@Sun.COM 
7687836SJohn.Forte@Sun.COM 	if (addRemoveFlag == ADD) {
7697836SJohn.Forte@Sun.COM 		veCnt++;
7707836SJohn.Forte@Sun.COM 	} else {
7717836SJohn.Forte@Sun.COM 		/* Check if this is the last one being removed */
7727836SJohn.Forte@Sun.COM 		if (veCnt == 1) {
7737836SJohn.Forte@Sun.COM 			/*
7747836SJohn.Forte@Sun.COM 			 * Delete the pg and get out if this is the last
7757836SJohn.Forte@Sun.COM 			 * view entry
7767836SJohn.Forte@Sun.COM 			 */
7777836SJohn.Forte@Sun.COM 			if (scf_pg_delete(pg) == -1) {
778*11909SPeter.Gill@Sun.COM 				syslog(LOG_ERR, "delete pg %s failed - %s",
779*11909SPeter.Gill@Sun.COM 				    luPgName, scf_strerror(scf_error()));
780*11909SPeter.Gill@Sun.COM 
7817836SJohn.Forte@Sun.COM 				ret = STMF_PS_ERROR;
7827836SJohn.Forte@Sun.COM 			}
7837836SJohn.Forte@Sun.COM 			goto out;
7847836SJohn.Forte@Sun.COM 		} else {
7857836SJohn.Forte@Sun.COM 			veCnt--;
7867836SJohn.Forte@Sun.COM 		}
7877836SJohn.Forte@Sun.COM 	}
7887836SJohn.Forte@Sun.COM 
7897836SJohn.Forte@Sun.COM 
7907836SJohn.Forte@Sun.COM 	/*
7917836SJohn.Forte@Sun.COM 	 * Set the view entry count
7927836SJohn.Forte@Sun.COM 	 */
7937836SJohn.Forte@Sun.COM 	scf_value_set_count(value, veCnt);
7947836SJohn.Forte@Sun.COM 
7957836SJohn.Forte@Sun.COM 	/*
7967836SJohn.Forte@Sun.COM 	 * Add the value to the transaction entry
7977836SJohn.Forte@Sun.COM 	 */
7987836SJohn.Forte@Sun.COM 	if (scf_entry_add_value(entry, value) == -1) {
799*11909SPeter.Gill@Sun.COM 		syslog(LOG_ERR, "add value %s/%s failed - %s",
800*11909SPeter.Gill@Sun.COM 		    luPgName, STMF_VE_CNT, scf_strerror(scf_error()));
8017836SJohn.Forte@Sun.COM 		ret = STMF_PS_ERROR;
8027836SJohn.Forte@Sun.COM 		goto out;
8037836SJohn.Forte@Sun.COM 	}
8047836SJohn.Forte@Sun.COM 
8057836SJohn.Forte@Sun.COM 	/*
8067836SJohn.Forte@Sun.COM 	 * Create a transaction entry resource for the view entry name
8077836SJohn.Forte@Sun.COM 	 */
8087836SJohn.Forte@Sun.COM 	entryVeName = scf_entry_create(handle);
8097836SJohn.Forte@Sun.COM 	if (entryVeName == NULL) {
810*11909SPeter.Gill@Sun.COM 		syslog(LOG_ERR, "scf transaction entry alloc %s/%s failed - %s",
811*11909SPeter.Gill@Sun.COM 		    luPgName, viewEntryPgName, 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 	if (addRemoveFlag == ADD) {
8177836SJohn.Forte@Sun.COM 		/*
8187836SJohn.Forte@Sun.COM 		 * If adding, create a property with the view entry name
8197836SJohn.Forte@Sun.COM 		 */
8207836SJohn.Forte@Sun.COM 		if (scf_transaction_property_new(tran, entryVeName,
8217836SJohn.Forte@Sun.COM 		    viewEntryPgName, SCF_TYPE_USTRING) == -1) {
8227836SJohn.Forte@Sun.COM 			if (scf_error() == SCF_ERROR_EXISTS) {
8237836SJohn.Forte@Sun.COM 				ret = STMF_PS_ERROR_EXISTS;
8247836SJohn.Forte@Sun.COM 			} else {
8257836SJohn.Forte@Sun.COM 				syslog(LOG_ERR,
826*11909SPeter.Gill@Sun.COM 				    "transaction property new %s/%s "
827*11909SPeter.Gill@Sun.COM 				    "failed - %s", luPgName, viewEntryPgName,
8287836SJohn.Forte@Sun.COM 				    scf_strerror(scf_error()));
8297836SJohn.Forte@Sun.COM 				ret = STMF_PS_ERROR;
8307836SJohn.Forte@Sun.COM 			}
8317836SJohn.Forte@Sun.COM 			goto out;
8327836SJohn.Forte@Sun.COM 		}
8337836SJohn.Forte@Sun.COM 	} else {
8347836SJohn.Forte@Sun.COM 		/*
8357836SJohn.Forte@Sun.COM 		 * If removing, delete the existing property with the view
8367836SJohn.Forte@Sun.COM 		 * entry name
8377836SJohn.Forte@Sun.COM 		 */
8387836SJohn.Forte@Sun.COM 		if (scf_transaction_property_delete(tran, entryVeName,
8397836SJohn.Forte@Sun.COM 		    viewEntryPgName) == -1) {
8407836SJohn.Forte@Sun.COM 			if (scf_error() == SCF_ERROR_NOT_FOUND) {
8417836SJohn.Forte@Sun.COM 				ret = STMF_PS_ERROR_NOT_FOUND;
8427836SJohn.Forte@Sun.COM 			} else {
8437836SJohn.Forte@Sun.COM 				syslog(LOG_ERR,
844*11909SPeter.Gill@Sun.COM 				    "transaction property delete %s/%s "
845*11909SPeter.Gill@Sun.COM 				    "failed - %s", luPgName, viewEntryPgName,
8467836SJohn.Forte@Sun.COM 				    scf_strerror(scf_error()));
8477836SJohn.Forte@Sun.COM 				ret = STMF_PS_ERROR;
8487836SJohn.Forte@Sun.COM 			}
8497836SJohn.Forte@Sun.COM 			goto out;
8507836SJohn.Forte@Sun.COM 		}
8517836SJohn.Forte@Sun.COM 	}
8527836SJohn.Forte@Sun.COM 
8537836SJohn.Forte@Sun.COM 	/*
8547836SJohn.Forte@Sun.COM 	 * Commit property transaction
8557836SJohn.Forte@Sun.COM 	 */
8567836SJohn.Forte@Sun.COM 	if ((commitRet = scf_transaction_commit(tran)) != 1) {
857*11909SPeter.Gill@Sun.COM 		syslog(LOG_ERR, "transaction commit for %s failed - %s",
858*11909SPeter.Gill@Sun.COM 		    luPgName, scf_strerror(scf_error()));
8597836SJohn.Forte@Sun.COM 		if (commitRet == 0) {
8607836SJohn.Forte@Sun.COM 			ret = STMF_PS_ERROR_BUSY;
8617836SJohn.Forte@Sun.COM 		} else {
8627836SJohn.Forte@Sun.COM 			ret = STMF_PS_ERROR;
8637836SJohn.Forte@Sun.COM 		}
8647836SJohn.Forte@Sun.COM 		goto out;
8657836SJohn.Forte@Sun.COM 	}
8667836SJohn.Forte@Sun.COM 
8677836SJohn.Forte@Sun.COM out:
8687836SJohn.Forte@Sun.COM 	/*
8697836SJohn.Forte@Sun.COM 	 * Free resources
8707836SJohn.Forte@Sun.COM 	 */
8717836SJohn.Forte@Sun.COM 	if (handle != NULL) {
8727836SJohn.Forte@Sun.COM 		scf_handle_destroy(handle);
8737836SJohn.Forte@Sun.COM 	}
8747836SJohn.Forte@Sun.COM 	if (svc != NULL) {
8757836SJohn.Forte@Sun.COM 		scf_service_destroy(svc);
8767836SJohn.Forte@Sun.COM 	}
8777836SJohn.Forte@Sun.COM 	if (pg != NULL) {
8787836SJohn.Forte@Sun.COM 		scf_pg_destroy(pg);
8797836SJohn.Forte@Sun.COM 	}
8807836SJohn.Forte@Sun.COM 	if (tran != NULL) {
8817836SJohn.Forte@Sun.COM 		scf_transaction_destroy(tran);
8827836SJohn.Forte@Sun.COM 	}
8837836SJohn.Forte@Sun.COM 	if (entry != NULL) {
8847836SJohn.Forte@Sun.COM 		scf_entry_destroy(entry);
8857836SJohn.Forte@Sun.COM 	}
8867836SJohn.Forte@Sun.COM 	if (entryVeName != NULL) {
8877836SJohn.Forte@Sun.COM 		scf_entry_destroy(entryVeName);
8887836SJohn.Forte@Sun.COM 	}
8897836SJohn.Forte@Sun.COM 	if (prop != NULL) {
8907836SJohn.Forte@Sun.COM 		scf_property_destroy(prop);
8917836SJohn.Forte@Sun.COM 	}
8927836SJohn.Forte@Sun.COM 	if (value != NULL) {
8937836SJohn.Forte@Sun.COM 		scf_value_destroy(value);
8947836SJohn.Forte@Sun.COM 	}
8957836SJohn.Forte@Sun.COM 
8967836SJohn.Forte@Sun.COM 	return (ret);
8977836SJohn.Forte@Sun.COM }
8987836SJohn.Forte@Sun.COM 
8997836SJohn.Forte@Sun.COM /*
9007836SJohn.Forte@Sun.COM  * iPsAddViewEntry
9017836SJohn.Forte@Sun.COM  *
9027836SJohn.Forte@Sun.COM  * Add a view entry property group and optionally, a logical unit property
9037836SJohn.Forte@Sun.COM  * group if it does not exist.
9047836SJohn.Forte@Sun.COM  *
9057836SJohn.Forte@Sun.COM  * luName - ascii hexadecimal logical unit identifier
9067836SJohn.Forte@Sun.COM  * viewEntryName - name of view entry (VIEW_ENTRY_nn)
9077836SJohn.Forte@Sun.COM  * viewEntry - pointer to stmfViewEntry structure
9087836SJohn.Forte@Sun.COM  */
9097836SJohn.Forte@Sun.COM static int
9107836SJohn.Forte@Sun.COM iPsAddViewEntry(char *luPgName, char *viewEntryPgName, stmfViewEntry *viewEntry)
9117836SJohn.Forte@Sun.COM {
9127836SJohn.Forte@Sun.COM 	scf_handle_t	*handle = NULL;
9137836SJohn.Forte@Sun.COM 	scf_service_t	*svc = NULL;
9147836SJohn.Forte@Sun.COM 	scf_propertygroup_t	*pg = NULL;
9157836SJohn.Forte@Sun.COM 	scf_value_t	*value[VIEW_ENTRY_STRUCT_CNT];
9167836SJohn.Forte@Sun.COM 	scf_transaction_t   *tran = NULL;
9177836SJohn.Forte@Sun.COM 	scf_transaction_entry_t *entry[VIEW_ENTRY_STRUCT_CNT];
9187836SJohn.Forte@Sun.COM 	int i = 0;
9197836SJohn.Forte@Sun.COM 	int j = 0;
9207836SJohn.Forte@Sun.COM 	int ret;
9217836SJohn.Forte@Sun.COM 	uint8_t scfBool;
9227836SJohn.Forte@Sun.COM 	boolean_t createdVePg = B_FALSE;
9237836SJohn.Forte@Sun.COM 	int backoutRet;
9247836SJohn.Forte@Sun.COM 	int commitRet;
9257836SJohn.Forte@Sun.COM 
9267836SJohn.Forte@Sun.COM 	assert(luPgName != NULL || viewEntryPgName != NULL ||
9277836SJohn.Forte@Sun.COM 	    viewEntry == NULL);
9287836SJohn.Forte@Sun.COM 
9297836SJohn.Forte@Sun.COM 	bzero(value, sizeof (value));
9307836SJohn.Forte@Sun.COM 	bzero(entry, sizeof (entry));
9317836SJohn.Forte@Sun.COM 
9327836SJohn.Forte@Sun.COM 	/*
9337836SJohn.Forte@Sun.COM 	 * Init the service handle
9347836SJohn.Forte@Sun.COM 	 */
9357836SJohn.Forte@Sun.COM 	ret = iPsInit(&handle, &svc);
9367836SJohn.Forte@Sun.COM 	if (ret != STMF_PS_SUCCESS) {
9377836SJohn.Forte@Sun.COM 		goto out;
9387836SJohn.Forte@Sun.COM 	}
9397836SJohn.Forte@Sun.COM 
9407836SJohn.Forte@Sun.COM 	/*
9417836SJohn.Forte@Sun.COM 	 * Allocate scf resources
9427836SJohn.Forte@Sun.COM 	 */
9437836SJohn.Forte@Sun.COM 	if (((pg = scf_pg_create(handle)) == NULL) ||
9447836SJohn.Forte@Sun.COM 	    ((tran = scf_transaction_create(handle)) == NULL)) {
9457836SJohn.Forte@Sun.COM 		syslog(LOG_ERR, "scf alloc resource failed - %s",
9467836SJohn.Forte@Sun.COM 		    scf_strerror(scf_error()));
9477836SJohn.Forte@Sun.COM 		ret = STMF_PS_ERROR;
9487836SJohn.Forte@Sun.COM 		goto out;
9497836SJohn.Forte@Sun.COM 	}
9507836SJohn.Forte@Sun.COM 
9517836SJohn.Forte@Sun.COM 	/*
9527836SJohn.Forte@Sun.COM 	 * allocate value and entry resources for scf
9537836SJohn.Forte@Sun.COM 	 */
9547836SJohn.Forte@Sun.COM 	for (i = 0; i < VIEW_ENTRY_STRUCT_CNT; i++) {
9557836SJohn.Forte@Sun.COM 		if (((value[i] = scf_value_create(handle)) == NULL) ||
9567836SJohn.Forte@Sun.COM 		    ((entry[i] = scf_entry_create(handle)) == NULL)) {
9577836SJohn.Forte@Sun.COM 			syslog(LOG_ERR, "scf alloc resource failed - %s",
9587836SJohn.Forte@Sun.COM 			    scf_strerror(scf_error()));
9597836SJohn.Forte@Sun.COM 			ret = STMF_PS_ERROR;
9607836SJohn.Forte@Sun.COM 			goto out;
9617836SJohn.Forte@Sun.COM 		}
9627836SJohn.Forte@Sun.COM 	}
9637836SJohn.Forte@Sun.COM 
9647836SJohn.Forte@Sun.COM 	i = 0;
9657836SJohn.Forte@Sun.COM 
9667836SJohn.Forte@Sun.COM 	/*
9677836SJohn.Forte@Sun.COM 	 * Create the View Entry property group
9687836SJohn.Forte@Sun.COM 	 */
9697836SJohn.Forte@Sun.COM 	if (scf_service_add_pg(svc, viewEntryPgName, SCF_GROUP_APPLICATION,
9707836SJohn.Forte@Sun.COM 	    0, pg) == -1) {
9717836SJohn.Forte@Sun.COM 		if (scf_error() == SCF_ERROR_EXISTS) {
9727836SJohn.Forte@Sun.COM 			ret = STMF_PS_ERROR_EXISTS;
9737836SJohn.Forte@Sun.COM 		} else {
974*11909SPeter.Gill@Sun.COM 			syslog(LOG_ERR, "add pg %s failed - %s",
975*11909SPeter.Gill@Sun.COM 			    viewEntryPgName, scf_strerror(scf_error()));
9767836SJohn.Forte@Sun.COM 			ret = STMF_PS_ERROR;
9777836SJohn.Forte@Sun.COM 		}
9787836SJohn.Forte@Sun.COM 		goto out;
9797836SJohn.Forte@Sun.COM 	}
9807836SJohn.Forte@Sun.COM 
9817836SJohn.Forte@Sun.COM 	createdVePg = B_TRUE;
9827836SJohn.Forte@Sun.COM 
9837836SJohn.Forte@Sun.COM 	/*
9847836SJohn.Forte@Sun.COM 	 * Add the view entry as properties on the view entry group
9857836SJohn.Forte@Sun.COM 	 */
9867836SJohn.Forte@Sun.COM 
9877836SJohn.Forte@Sun.COM 	/*
9887836SJohn.Forte@Sun.COM 	 * Begin property update transaction
9897836SJohn.Forte@Sun.COM 	 */
9907836SJohn.Forte@Sun.COM 	if (scf_transaction_start(tran, pg) == -1) {
991*11909SPeter.Gill@Sun.COM 		syslog(LOG_ERR, "start transaction for add %s failed - %s",
992*11909SPeter.Gill@Sun.COM 		    viewEntryPgName, scf_strerror(scf_error()));
9937836SJohn.Forte@Sun.COM 		ret = STMF_PS_ERROR;
9947836SJohn.Forte@Sun.COM 		goto out;
9957836SJohn.Forte@Sun.COM 	}
9967836SJohn.Forte@Sun.COM 
9977836SJohn.Forte@Sun.COM 	/*
9987836SJohn.Forte@Sun.COM 	 * Add allHosts property
9997836SJohn.Forte@Sun.COM 	 */
10007836SJohn.Forte@Sun.COM 	if (scf_transaction_property_new(tran, entry[i],
10017836SJohn.Forte@Sun.COM 	    STMF_VE_ALLHOSTS, SCF_TYPE_BOOLEAN) == -1) {
10027836SJohn.Forte@Sun.COM 		if (scf_error() == SCF_ERROR_EXISTS) {
10037836SJohn.Forte@Sun.COM 			ret = STMF_PS_ERROR_EXISTS;
10047836SJohn.Forte@Sun.COM 		} else {
1005*11909SPeter.Gill@Sun.COM 			syslog(LOG_ERR, "transaction property new %s/%s "
1006*11909SPeter.Gill@Sun.COM 			    "failed - %s", viewEntryPgName, STMF_VE_ALLHOSTS,
10077836SJohn.Forte@Sun.COM 			    scf_strerror(scf_error()));
10087836SJohn.Forte@Sun.COM 			ret = STMF_PS_ERROR;
10097836SJohn.Forte@Sun.COM 		}
10107836SJohn.Forte@Sun.COM 		goto out;
10117836SJohn.Forte@Sun.COM 	}
10127836SJohn.Forte@Sun.COM 
10137836SJohn.Forte@Sun.COM 	/* Set the allHosts value */
10147836SJohn.Forte@Sun.COM 	scfBool = viewEntry->allHosts;
10157836SJohn.Forte@Sun.COM 	scf_value_set_boolean(value[i], scfBool);
10167836SJohn.Forte@Sun.COM 
10177836SJohn.Forte@Sun.COM 	/*
10187836SJohn.Forte@Sun.COM 	 * Add the allHosts value to the transaction
10197836SJohn.Forte@Sun.COM 	 */
10207836SJohn.Forte@Sun.COM 	if (scf_entry_add_value(entry[i], value[i]) == -1) {
1021*11909SPeter.Gill@Sun.COM 		syslog(LOG_ERR, "add value %s/%s failed - %s",
1022*11909SPeter.Gill@Sun.COM 		    viewEntryPgName, STMF_VE_ALLHOSTS,
10237836SJohn.Forte@Sun.COM 		    scf_strerror(scf_error()));
10247836SJohn.Forte@Sun.COM 		ret = STMF_PS_ERROR;
10257836SJohn.Forte@Sun.COM 		goto out;
10267836SJohn.Forte@Sun.COM 	}
10277836SJohn.Forte@Sun.COM 
10287836SJohn.Forte@Sun.COM 	i++;
10297836SJohn.Forte@Sun.COM 
10307836SJohn.Forte@Sun.COM 	/*
10317836SJohn.Forte@Sun.COM 	 * Create hostGroup property
10327836SJohn.Forte@Sun.COM 	 */
10337836SJohn.Forte@Sun.COM 	if (scf_transaction_property_new(tran, entry[i],
10347836SJohn.Forte@Sun.COM 	    STMF_VE_HOSTGROUP, SCF_TYPE_USTRING) == -1) {
10357836SJohn.Forte@Sun.COM 		if (scf_error() == SCF_ERROR_EXISTS) {
10367836SJohn.Forte@Sun.COM 			ret = STMF_PS_ERROR_EXISTS;
10377836SJohn.Forte@Sun.COM 		} else {
1038*11909SPeter.Gill@Sun.COM 			syslog(LOG_ERR, "transaction property new %s/%s "
1039*11909SPeter.Gill@Sun.COM 			    "failed - %s", viewEntryPgName, STMF_VE_HOSTGROUP,
10407836SJohn.Forte@Sun.COM 			    scf_strerror(scf_error()));
10417836SJohn.Forte@Sun.COM 			ret = STMF_PS_ERROR;
10427836SJohn.Forte@Sun.COM 		}
10437836SJohn.Forte@Sun.COM 		goto out;
10447836SJohn.Forte@Sun.COM 	}
10457836SJohn.Forte@Sun.COM 
10467836SJohn.Forte@Sun.COM 	/*
10477836SJohn.Forte@Sun.COM 	 * Set the value for hostGroup
10487836SJohn.Forte@Sun.COM 	 */
10497836SJohn.Forte@Sun.COM 	if (scf_value_set_ustring(value[i], viewEntry->hostGroup) == -1) {
1050*11909SPeter.Gill@Sun.COM 		syslog(LOG_ERR, "set value %s/%s failed - %s",
1051*11909SPeter.Gill@Sun.COM 		    viewEntryPgName, STMF_VE_HOSTGROUP,
10527836SJohn.Forte@Sun.COM 		    scf_strerror(scf_error()));
10537836SJohn.Forte@Sun.COM 		ret = STMF_PS_ERROR;
10547836SJohn.Forte@Sun.COM 		goto out;
10557836SJohn.Forte@Sun.COM 	}
10567836SJohn.Forte@Sun.COM 
10577836SJohn.Forte@Sun.COM 	/*
10587836SJohn.Forte@Sun.COM 	 * Add the hostGroup value to the transaction entry
10597836SJohn.Forte@Sun.COM 	 */
10607836SJohn.Forte@Sun.COM 	if (scf_entry_add_value(entry[i], value[i]) == -1) {
1061*11909SPeter.Gill@Sun.COM 		syslog(LOG_ERR, "add value %s/%s failed - %s",
1062*11909SPeter.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 	i++;
10697836SJohn.Forte@Sun.COM 
10707836SJohn.Forte@Sun.COM 	/*
10717836SJohn.Forte@Sun.COM 	 * Create the allTargets property
10727836SJohn.Forte@Sun.COM 	 */
10737836SJohn.Forte@Sun.COM 	if (scf_transaction_property_new(tran, entry[i],
10747836SJohn.Forte@Sun.COM 	    STMF_VE_ALLTARGETS, SCF_TYPE_BOOLEAN) == -1) {
10757836SJohn.Forte@Sun.COM 		if (scf_error() == SCF_ERROR_EXISTS) {
10767836SJohn.Forte@Sun.COM 			ret = STMF_PS_ERROR_EXISTS;
10777836SJohn.Forte@Sun.COM 		} else {
1078*11909SPeter.Gill@Sun.COM 			syslog(LOG_ERR, "transaction property new %s/%s "
1079*11909SPeter.Gill@Sun.COM 			    "failed - %s", viewEntryPgName, STMF_VE_ALLTARGETS,
10807836SJohn.Forte@Sun.COM 			    scf_strerror(scf_error()));
10817836SJohn.Forte@Sun.COM 			ret = STMF_PS_ERROR;
10827836SJohn.Forte@Sun.COM 		}
10837836SJohn.Forte@Sun.COM 		goto out;
10847836SJohn.Forte@Sun.COM 	}
10857836SJohn.Forte@Sun.COM 
10867836SJohn.Forte@Sun.COM 	/*
10877836SJohn.Forte@Sun.COM 	 * Set the allTargets value
10887836SJohn.Forte@Sun.COM 	 */
10897836SJohn.Forte@Sun.COM 	scfBool = viewEntry->allTargets;
10907836SJohn.Forte@Sun.COM 	scf_value_set_boolean(value[i], scfBool);
10917836SJohn.Forte@Sun.COM 
10927836SJohn.Forte@Sun.COM 	/*
10937836SJohn.Forte@Sun.COM 	 * Add the allTargets value to the transaction
10947836SJohn.Forte@Sun.COM 	 */
10957836SJohn.Forte@Sun.COM 	if (scf_entry_add_value(entry[i], value[i]) == -1) {
1096*11909SPeter.Gill@Sun.COM 		syslog(LOG_ERR, "add value %s/%s failed - %s",
1097*11909SPeter.Gill@Sun.COM 		    viewEntryPgName, STMF_VE_ALLTARGETS,
10987836SJohn.Forte@Sun.COM 		    scf_strerror(scf_error()));
10997836SJohn.Forte@Sun.COM 		ret = STMF_PS_ERROR;
11007836SJohn.Forte@Sun.COM 		goto out;
11017836SJohn.Forte@Sun.COM 	}
11027836SJohn.Forte@Sun.COM 
11037836SJohn.Forte@Sun.COM 	i++;
11047836SJohn.Forte@Sun.COM 
11057836SJohn.Forte@Sun.COM 	/*
11067836SJohn.Forte@Sun.COM 	 * Create targetGroup property
11077836SJohn.Forte@Sun.COM 	 */
11087836SJohn.Forte@Sun.COM 	if (scf_transaction_property_new(tran, entry[i],
11097836SJohn.Forte@Sun.COM 	    STMF_VE_TARGETGROUP, SCF_TYPE_USTRING) == -1) {
11107836SJohn.Forte@Sun.COM 		if (scf_error() == SCF_ERROR_EXISTS) {
11117836SJohn.Forte@Sun.COM 			ret = STMF_PS_ERROR_EXISTS;
11127836SJohn.Forte@Sun.COM 		} else {
1113*11909SPeter.Gill@Sun.COM 			syslog(LOG_ERR, "transaction property new %s/%s "
1114*11909SPeter.Gill@Sun.COM 			    "failed - %s", viewEntryPgName,
1115*11909SPeter.Gill@Sun.COM 			    STMF_VE_TARGETGROUP, scf_strerror(scf_error()));
11167836SJohn.Forte@Sun.COM 			ret = STMF_PS_ERROR;
11177836SJohn.Forte@Sun.COM 		}
11187836SJohn.Forte@Sun.COM 		goto out;
11197836SJohn.Forte@Sun.COM 	}
11207836SJohn.Forte@Sun.COM 
11217836SJohn.Forte@Sun.COM 	/*
11227836SJohn.Forte@Sun.COM 	 * Set the value for targetGroup
11237836SJohn.Forte@Sun.COM 	 */
11247836SJohn.Forte@Sun.COM 	if (scf_value_set_ustring(value[i], viewEntry->targetGroup) == -1) {
1125*11909SPeter.Gill@Sun.COM 		syslog(LOG_ERR, "set value %s/%s failed - %s",
1126*11909SPeter.Gill@Sun.COM 		    viewEntryPgName, STMF_VE_TARGETGROUP,
11277836SJohn.Forte@Sun.COM 		    scf_strerror(scf_error()));
11287836SJohn.Forte@Sun.COM 		ret = STMF_PS_ERROR;
11297836SJohn.Forte@Sun.COM 		goto out;
11307836SJohn.Forte@Sun.COM 	}
11317836SJohn.Forte@Sun.COM 
11327836SJohn.Forte@Sun.COM 	/*
11337836SJohn.Forte@Sun.COM 	 * Add targetGroup value to the transaction
11347836SJohn.Forte@Sun.COM 	 */
11357836SJohn.Forte@Sun.COM 	if (scf_entry_add_value(entry[i], value[i]) == -1) {
1136*11909SPeter.Gill@Sun.COM 		syslog(LOG_ERR, "add value %s/%s failed - %s",
1137*11909SPeter.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 	i++;
11447836SJohn.Forte@Sun.COM 
11457836SJohn.Forte@Sun.COM 	/*
11467836SJohn.Forte@Sun.COM 	 * Create the luNbr property
11477836SJohn.Forte@Sun.COM 	 */
11487836SJohn.Forte@Sun.COM 	if (scf_transaction_property_new(tran, entry[i], STMF_VE_LUNBR,
11497836SJohn.Forte@Sun.COM 	    SCF_TYPE_OPAQUE) == -1) {
11507836SJohn.Forte@Sun.COM 		if (scf_error() == SCF_ERROR_EXISTS) {
11517836SJohn.Forte@Sun.COM 			ret = STMF_PS_ERROR_EXISTS;
11527836SJohn.Forte@Sun.COM 		} else {
1153*11909SPeter.Gill@Sun.COM 			syslog(LOG_ERR, "transaction property new %s/%s "
1154*11909SPeter.Gill@Sun.COM 			    "failed - %s", viewEntryPgName, STMF_VE_LUNBR,
11557836SJohn.Forte@Sun.COM 			    scf_strerror(scf_error()));
11567836SJohn.Forte@Sun.COM 			ret = STMF_PS_ERROR;
11577836SJohn.Forte@Sun.COM 		}
11587836SJohn.Forte@Sun.COM 		goto out;
11597836SJohn.Forte@Sun.COM 	}
11607836SJohn.Forte@Sun.COM 
11617836SJohn.Forte@Sun.COM 	/*
11627836SJohn.Forte@Sun.COM 	 * Set the luNbr
11637836SJohn.Forte@Sun.COM 	 */
11647836SJohn.Forte@Sun.COM 	if (scf_value_set_opaque(value[i], (char *)viewEntry->luNbr,
11657836SJohn.Forte@Sun.COM 	    sizeof (viewEntry->luNbr)) == -1) {
1166*11909SPeter.Gill@Sun.COM 		syslog(LOG_ERR, "set value %s/%s failed - %s",
1167*11909SPeter.Gill@Sun.COM 		    viewEntryPgName, STMF_VE_LUNBR, scf_strerror(scf_error()));
11687836SJohn.Forte@Sun.COM 		ret = STMF_PS_ERROR;
11697836SJohn.Forte@Sun.COM 		goto out;
11707836SJohn.Forte@Sun.COM 	}
11717836SJohn.Forte@Sun.COM 
11727836SJohn.Forte@Sun.COM 	/*
11737836SJohn.Forte@Sun.COM 	 * Add luNbr to the transaction entry
11747836SJohn.Forte@Sun.COM 	 */
11757836SJohn.Forte@Sun.COM 	if (scf_entry_add_value(entry[i], value[i]) == -1) {
1176*11909SPeter.Gill@Sun.COM 		syslog(LOG_ERR, "add value %s/%s failed - %s",
1177*11909SPeter.Gill@Sun.COM 		    viewEntryPgName, STMF_VE_LUNBR, scf_strerror(scf_error()));
11787836SJohn.Forte@Sun.COM 		ret = STMF_PS_ERROR;
11797836SJohn.Forte@Sun.COM 		goto out;
11807836SJohn.Forte@Sun.COM 	}
11817836SJohn.Forte@Sun.COM 
11827836SJohn.Forte@Sun.COM 	/*
11837836SJohn.Forte@Sun.COM 	 * Now that we've successfully added the view entry,
11847836SJohn.Forte@Sun.COM 	 * update the logical unit property group or create
11857836SJohn.Forte@Sun.COM 	 * it if it does not exist
11867836SJohn.Forte@Sun.COM 	 */
11877836SJohn.Forte@Sun.COM 	ret = iPsAddRemoveLuViewEntry(luPgName, viewEntryPgName, ADD);
11887836SJohn.Forte@Sun.COM 
11897836SJohn.Forte@Sun.COM 	/*
11907836SJohn.Forte@Sun.COM 	 * If we did not add the view entry name to the logical unit,
11917836SJohn.Forte@Sun.COM 	 * make sure we do not commit the transaction
11927836SJohn.Forte@Sun.COM 	 */
11937836SJohn.Forte@Sun.COM 	if (ret != STMF_PS_SUCCESS) {
11947836SJohn.Forte@Sun.COM 		goto out;
11957836SJohn.Forte@Sun.COM 	}
11967836SJohn.Forte@Sun.COM 
11977836SJohn.Forte@Sun.COM 	/*
11987836SJohn.Forte@Sun.COM 	 * Commit property transaction
11997836SJohn.Forte@Sun.COM 	 */
12007836SJohn.Forte@Sun.COM 	if ((commitRet = scf_transaction_commit(tran)) != 1) {
1201*11909SPeter.Gill@Sun.COM 		syslog(LOG_ERR, "transaction commit for add %s failed - %s",
1202*11909SPeter.Gill@Sun.COM 		    viewEntryPgName, scf_strerror(scf_error()));
12037836SJohn.Forte@Sun.COM 		if (commitRet == 0) {
12047836SJohn.Forte@Sun.COM 			ret = STMF_PS_ERROR_BUSY;
12057836SJohn.Forte@Sun.COM 		} else {
12067836SJohn.Forte@Sun.COM 			ret = STMF_PS_ERROR;
12077836SJohn.Forte@Sun.COM 		}
12087836SJohn.Forte@Sun.COM 	}
12097836SJohn.Forte@Sun.COM 
12107836SJohn.Forte@Sun.COM 	if (ret != STMF_PS_SUCCESS) {
12117836SJohn.Forte@Sun.COM 		/*
12127836SJohn.Forte@Sun.COM 		 * If we did not commit, try to remove the view entry name
12137836SJohn.Forte@Sun.COM 		 * from the logical unit.
12147836SJohn.Forte@Sun.COM 		 * If that fails, we're now inconsistent.
12157836SJohn.Forte@Sun.COM 		 */
12167836SJohn.Forte@Sun.COM 		backoutRet = iPsAddRemoveLuViewEntry(luPgName, viewEntryPgName,
12177836SJohn.Forte@Sun.COM 		    REMOVE);
12187836SJohn.Forte@Sun.COM 
12197836SJohn.Forte@Sun.COM 		if (backoutRet != STMF_PS_SUCCESS) {
1220*11909SPeter.Gill@Sun.COM 			syslog(LOG_ERR, "remove lu view entry %s failed"
1221*11909SPeter.Gill@Sun.COM 			    "possible inconsistency - %s", luPgName,
12227836SJohn.Forte@Sun.COM 			    scf_strerror(scf_error()));
12237836SJohn.Forte@Sun.COM 		}
12247836SJohn.Forte@Sun.COM 		/*
12257836SJohn.Forte@Sun.COM 		 * We are still in an error scenario even though the remove
12267836SJohn.Forte@Sun.COM 		 * lu view entry succeeded.
12277836SJohn.Forte@Sun.COM 		 */
12287836SJohn.Forte@Sun.COM 		goto out;
12297836SJohn.Forte@Sun.COM 	}
12307836SJohn.Forte@Sun.COM 
12317836SJohn.Forte@Sun.COM out:
12327836SJohn.Forte@Sun.COM 	/*
12337836SJohn.Forte@Sun.COM 	 * Free resources
12347836SJohn.Forte@Sun.COM 	 */
12357836SJohn.Forte@Sun.COM 	if (handle != NULL) {
12367836SJohn.Forte@Sun.COM 		scf_handle_destroy(handle);
12377836SJohn.Forte@Sun.COM 	}
12387836SJohn.Forte@Sun.COM 	if (svc != NULL) {
12397836SJohn.Forte@Sun.COM 		scf_service_destroy(svc);
12407836SJohn.Forte@Sun.COM 	}
12417836SJohn.Forte@Sun.COM 	/* if there was an error, delete the created pg if one was created */
12427836SJohn.Forte@Sun.COM 	if ((ret != STMF_PS_SUCCESS) && createdVePg) {
12437836SJohn.Forte@Sun.COM 		if (scf_pg_delete(pg) == -1) {
1244*11909SPeter.Gill@Sun.COM 			syslog(LOG_ERR, "delete VE pg %s failed - %s",
1245*11909SPeter.Gill@Sun.COM 			    viewEntryPgName, scf_strerror(scf_error()));
12467836SJohn.Forte@Sun.COM 		}
12477836SJohn.Forte@Sun.COM 	}
12487836SJohn.Forte@Sun.COM 	if (pg != NULL) {
12497836SJohn.Forte@Sun.COM 		scf_pg_destroy(pg);
12507836SJohn.Forte@Sun.COM 	}
12517836SJohn.Forte@Sun.COM 	if (tran != NULL) {
12527836SJohn.Forte@Sun.COM 		scf_transaction_destroy(tran);
12537836SJohn.Forte@Sun.COM 	}
12547836SJohn.Forte@Sun.COM 	/*
12557836SJohn.Forte@Sun.COM 	 * Free value and entry scf resources
12567836SJohn.Forte@Sun.COM 	 */
12577836SJohn.Forte@Sun.COM 	if (i > 0) {
12587836SJohn.Forte@Sun.COM 		for (j = 0; j < VIEW_ENTRY_STRUCT_CNT; j++) {
12597836SJohn.Forte@Sun.COM 			if (value[j] != NULL)
12607836SJohn.Forte@Sun.COM 				scf_value_destroy(value[j]);
12617836SJohn.Forte@Sun.COM 			if (entry[j] != NULL)
12627836SJohn.Forte@Sun.COM 				scf_entry_destroy(entry[j]);
12637836SJohn.Forte@Sun.COM 		}
12647836SJohn.Forte@Sun.COM 	}
12657836SJohn.Forte@Sun.COM 
12667836SJohn.Forte@Sun.COM 	return (ret);
12677836SJohn.Forte@Sun.COM }
12687836SJohn.Forte@Sun.COM /*
12697836SJohn.Forte@Sun.COM  * psClearProviderData
12707836SJohn.Forte@Sun.COM  *
12717836SJohn.Forte@Sun.COM  * providerName - name of provider data to clear
12727836SJohn.Forte@Sun.COM  */
12737836SJohn.Forte@Sun.COM int
12747836SJohn.Forte@Sun.COM psClearProviderData(char *providerName, int providerType)
12757836SJohn.Forte@Sun.COM {
12767836SJohn.Forte@Sun.COM 	scf_handle_t	*handle = NULL;
12777836SJohn.Forte@Sun.COM 	scf_service_t	*svc = NULL;
12787836SJohn.Forte@Sun.COM 	scf_propertygroup_t	*pg = NULL;
12797836SJohn.Forte@Sun.COM 	char pgName[MAXPATHLEN];
12807836SJohn.Forte@Sun.COM 	int ret = STMF_PS_SUCCESS;
12817836SJohn.Forte@Sun.COM 	boolean_t pgNotFound = B_FALSE;
12827836SJohn.Forte@Sun.COM 
12837836SJohn.Forte@Sun.COM 	if (providerName == NULL || (providerType != STMF_LU_PROVIDER_TYPE &&
12847836SJohn.Forte@Sun.COM 	    providerType != STMF_PORT_PROVIDER_TYPE)) {
12857836SJohn.Forte@Sun.COM 		ret = STMF_PS_ERROR_INVALID_ARG;
12867836SJohn.Forte@Sun.COM 		goto out;
12877836SJohn.Forte@Sun.COM 	}
12887836SJohn.Forte@Sun.COM 
12897836SJohn.Forte@Sun.COM 	ret = iPsInit(&handle, &svc);
12907836SJohn.Forte@Sun.COM 	if (ret != STMF_PS_SUCCESS) {
12917836SJohn.Forte@Sun.COM 		goto out;
12927836SJohn.Forte@Sun.COM 	}
12937836SJohn.Forte@Sun.COM 
12947836SJohn.Forte@Sun.COM 	/*
12957836SJohn.Forte@Sun.COM 	 * Allocate scf resources
12967836SJohn.Forte@Sun.COM 	 */
12977836SJohn.Forte@Sun.COM 	if ((pg = scf_pg_create(handle)) == NULL) {
12987836SJohn.Forte@Sun.COM 		syslog(LOG_ERR, "scf alloc resource failed - %s",
12997836SJohn.Forte@Sun.COM 		    scf_strerror(scf_error()));
13007836SJohn.Forte@Sun.COM 		ret = STMF_PS_ERROR;
13017836SJohn.Forte@Sun.COM 		goto out;
13027836SJohn.Forte@Sun.COM 	}
13037836SJohn.Forte@Sun.COM 
13047836SJohn.Forte@Sun.COM 	/*
13057836SJohn.Forte@Sun.COM 	 * create the property group name
13067836SJohn.Forte@Sun.COM 	 */
13077836SJohn.Forte@Sun.COM 	(void) snprintf(pgName, sizeof (pgName), "%s%s",
13087836SJohn.Forte@Sun.COM 	    STMF_PROVIDER_DATA_PREFIX, providerName);
13097836SJohn.Forte@Sun.COM 
13107836SJohn.Forte@Sun.COM 	/*
13117836SJohn.Forte@Sun.COM 	 * delete provider property group
13127836SJohn.Forte@Sun.COM 	 */
13137836SJohn.Forte@Sun.COM 	if (scf_service_get_pg(svc, pgName, pg) == -1) {
13147836SJohn.Forte@Sun.COM 		if (scf_error() != SCF_ERROR_NOT_FOUND) {
1315*11909SPeter.Gill@Sun.COM 			syslog(LOG_ERR, "get pg %s failed - %s",
1316*11909SPeter.Gill@Sun.COM 			    pgName, scf_strerror(scf_error()));
13177836SJohn.Forte@Sun.COM 			ret = STMF_PS_ERROR;
13187836SJohn.Forte@Sun.COM 			goto out;
13197836SJohn.Forte@Sun.COM 		} else {
13207836SJohn.Forte@Sun.COM 			pgNotFound = B_TRUE;
13217836SJohn.Forte@Sun.COM 		}
13227836SJohn.Forte@Sun.COM 	}
13237836SJohn.Forte@Sun.COM 
13247836SJohn.Forte@Sun.COM 	if (!pgNotFound && (scf_pg_delete(pg) == -1)) {
1325*11909SPeter.Gill@Sun.COM 		syslog(LOG_ERR, "delete pg %s failed - %s",
1326*11909SPeter.Gill@Sun.COM 		    pgName, scf_strerror(scf_error()));
13277836SJohn.Forte@Sun.COM 		ret = STMF_PS_ERROR;
13287836SJohn.Forte@Sun.COM 		goto out;
13297836SJohn.Forte@Sun.COM 	}
13307836SJohn.Forte@Sun.COM 
13317836SJohn.Forte@Sun.COM 	if (pgNotFound) {
13327836SJohn.Forte@Sun.COM 		ret = STMF_PS_ERROR_NOT_FOUND;
13337836SJohn.Forte@Sun.COM 	}
13347836SJohn.Forte@Sun.COM 
13357836SJohn.Forte@Sun.COM out:
13367836SJohn.Forte@Sun.COM 	/*
13377836SJohn.Forte@Sun.COM 	 * Free resources
13387836SJohn.Forte@Sun.COM 	 */
13397836SJohn.Forte@Sun.COM 	if (handle != NULL) {
13407836SJohn.Forte@Sun.COM 		scf_handle_destroy(handle);
13417836SJohn.Forte@Sun.COM 	}
13427836SJohn.Forte@Sun.COM 	if (svc != NULL) {
13437836SJohn.Forte@Sun.COM 		scf_service_destroy(svc);
13447836SJohn.Forte@Sun.COM 	}
13457836SJohn.Forte@Sun.COM 	if (pg != NULL) {
13467836SJohn.Forte@Sun.COM 		scf_pg_destroy(pg);
13477836SJohn.Forte@Sun.COM 	}
13487836SJohn.Forte@Sun.COM 
13497836SJohn.Forte@Sun.COM 	return (ret);
13507836SJohn.Forte@Sun.COM }
13517836SJohn.Forte@Sun.COM 
13527836SJohn.Forte@Sun.COM /*
13537836SJohn.Forte@Sun.COM  * iPsCreateDeleteGroup
13547836SJohn.Forte@Sun.COM  *
13557836SJohn.Forte@Sun.COM  * Creates or deletes a group (target or host)
13567836SJohn.Forte@Sun.COM  *
13577836SJohn.Forte@Sun.COM  * When creating a group, two properties are created. One to hold the group
13587836SJohn.Forte@Sun.COM  * name and the other to hold the group members.
13597836SJohn.Forte@Sun.COM  *
13607836SJohn.Forte@Sun.COM  * pgName - Property group name
13617836SJohn.Forte@Sun.COM  * groupName - group name to create
13627836SJohn.Forte@Sun.COM  * addRemoveFlag - ADD_GROUP/REMOVE_GROUP
13637836SJohn.Forte@Sun.COM  *
13647836SJohn.Forte@Sun.COM  * returns:
13657836SJohn.Forte@Sun.COM  *  STMF_PS_SUCCESS on success
13667836SJohn.Forte@Sun.COM  *  STMF_PS_ERROR_* on failure
13677836SJohn.Forte@Sun.COM  */
13687836SJohn.Forte@Sun.COM static int
13697836SJohn.Forte@Sun.COM iPsCreateDeleteGroup(char *pgRefName, char *groupName, int addRemoveFlag)
13707836SJohn.Forte@Sun.COM {
13717836SJohn.Forte@Sun.COM 	scf_handle_t	*handle = NULL;
13727836SJohn.Forte@Sun.COM 	scf_service_t	*svc = NULL;
13737836SJohn.Forte@Sun.COM 	scf_propertygroup_t	*pg = NULL;
13747836SJohn.Forte@Sun.COM 	scf_property_t	*prop = NULL;
13757836SJohn.Forte@Sun.COM 	scf_iter_t	*propIter = NULL;
13767836SJohn.Forte@Sun.COM 	scf_transaction_t   *tran = NULL;
13777836SJohn.Forte@Sun.COM 	scf_transaction_entry_t *entry1 = NULL;
13787836SJohn.Forte@Sun.COM 	scf_transaction_entry_t *entry2 = NULL;
13797836SJohn.Forte@Sun.COM 	scf_value_t *value = NULL;
13807836SJohn.Forte@Sun.COM 	uint64_t groupIdx;
13817836SJohn.Forte@Sun.COM 	char buf1[MAXNAMELEN];
13827836SJohn.Forte@Sun.COM 	char buf2[MAXNAMELEN];
13837836SJohn.Forte@Sun.COM 	char tmpbuf[MAXNAMELEN];
13847836SJohn.Forte@Sun.COM 	boolean_t found = B_FALSE;
13857836SJohn.Forte@Sun.COM 	int ret = STMF_PS_SUCCESS;
13867836SJohn.Forte@Sun.COM 	int commitRet;
13877836SJohn.Forte@Sun.COM 
13887836SJohn.Forte@Sun.COM 	assert(groupName != NULL);
13897836SJohn.Forte@Sun.COM 
13907836SJohn.Forte@Sun.COM 	ret = iPsInit(&handle, &svc);
13917836SJohn.Forte@Sun.COM 	if (ret != STMF_PS_SUCCESS) {
13927836SJohn.Forte@Sun.COM 		goto out;
13937836SJohn.Forte@Sun.COM 	}
13947836SJohn.Forte@Sun.COM 
13957836SJohn.Forte@Sun.COM 	/*
13967836SJohn.Forte@Sun.COM 	 * Allocate scf resources
13977836SJohn.Forte@Sun.COM 	 */
13987836SJohn.Forte@Sun.COM 	if (((pg = scf_pg_create(handle)) == NULL) ||
13997836SJohn.Forte@Sun.COM 	    ((tran = scf_transaction_create(handle)) == NULL) ||
14007836SJohn.Forte@Sun.COM 	    ((entry1 = scf_entry_create(handle)) == NULL) ||
14017836SJohn.Forte@Sun.COM 	    ((entry2 = scf_entry_create(handle)) == NULL) ||
14027836SJohn.Forte@Sun.COM 	    ((prop = scf_property_create(handle)) == NULL) ||
14037836SJohn.Forte@Sun.COM 	    ((propIter = scf_iter_create(handle)) == NULL) ||
14047836SJohn.Forte@Sun.COM 	    ((value = scf_value_create(handle)) == NULL)) {
14057836SJohn.Forte@Sun.COM 		syslog(LOG_ERR, "scf alloc resource failed - %s",
14067836SJohn.Forte@Sun.COM 		    scf_strerror(scf_error()));
14077836SJohn.Forte@Sun.COM 		ret = STMF_PS_ERROR;
14087836SJohn.Forte@Sun.COM 		goto out;
14097836SJohn.Forte@Sun.COM 	}
14107836SJohn.Forte@Sun.COM 
14117836SJohn.Forte@Sun.COM 	/*
14127836SJohn.Forte@Sun.COM 	 * Get the property group being modified
14137836SJohn.Forte@Sun.COM 	 */
14147836SJohn.Forte@Sun.COM 	if (scf_service_get_pg(svc, pgRefName, pg) == -1) {
14157836SJohn.Forte@Sun.COM 		if (scf_error() == SCF_ERROR_NOT_FOUND &&
14167836SJohn.Forte@Sun.COM 		    addRemoveFlag == ADD) {
14177836SJohn.Forte@Sun.COM 			if (scf_service_add_pg(svc, pgRefName,
14187836SJohn.Forte@Sun.COM 			    SCF_GROUP_APPLICATION, 0, pg) == -1) {
1419*11909SPeter.Gill@Sun.COM 				syslog(LOG_ERR, "add pg %s failed - %s",
1420*11909SPeter.Gill@Sun.COM 				    pgRefName, scf_strerror(scf_error()));
14217836SJohn.Forte@Sun.COM 				ret = STMF_PS_ERROR;
14227836SJohn.Forte@Sun.COM 			}
14237836SJohn.Forte@Sun.COM 		} else if (scf_error() == SCF_ERROR_NOT_FOUND) {
1424*11909SPeter.Gill@Sun.COM 			syslog(LOG_ERR, "get pg %s failed - %s",
1425*11909SPeter.Gill@Sun.COM 			    pgRefName, scf_strerror(scf_error()));
14267836SJohn.Forte@Sun.COM 			ret = STMF_PS_ERROR_NOT_FOUND;
14277836SJohn.Forte@Sun.COM 		} else {
1428*11909SPeter.Gill@Sun.COM 			syslog(LOG_ERR, "get pg %s failed - %s",
1429*11909SPeter.Gill@Sun.COM 			    pgRefName, scf_strerror(scf_error()));
14307836SJohn.Forte@Sun.COM 			ret = STMF_PS_ERROR;
14317836SJohn.Forte@Sun.COM 		}
14327836SJohn.Forte@Sun.COM 		if (ret != STMF_PS_SUCCESS) {
14337836SJohn.Forte@Sun.COM 			goto out;
14347836SJohn.Forte@Sun.COM 		}
14357836SJohn.Forte@Sun.COM 	}
14367836SJohn.Forte@Sun.COM 
14377836SJohn.Forte@Sun.COM 	/*
14387836SJohn.Forte@Sun.COM 	 * propIter is the iterator handle
14397836SJohn.Forte@Sun.COM 	 */
14407836SJohn.Forte@Sun.COM 	if (scf_iter_pg_properties(propIter, pg) == -1) {
1441*11909SPeter.Gill@Sun.COM 		syslog(LOG_ERR, "iter properties for %s failed - %s",
1442*11909SPeter.Gill@Sun.COM 		    pgRefName, scf_strerror(scf_error()));
14437836SJohn.Forte@Sun.COM 		ret = STMF_PS_ERROR;
14447836SJohn.Forte@Sun.COM 		goto out;
14457836SJohn.Forte@Sun.COM 	}
14467836SJohn.Forte@Sun.COM 
14477836SJohn.Forte@Sun.COM 	/*
14487836SJohn.Forte@Sun.COM 	 * Iterate through the group names.
14497836SJohn.Forte@Sun.COM 	 * If we find it in the list, it's an error when addRemoveFlag == ADD.
14507836SJohn.Forte@Sun.COM 	 */
14517836SJohn.Forte@Sun.COM 	while (scf_iter_next_property(propIter, prop) == 1) {
14527836SJohn.Forte@Sun.COM 		if (scf_property_get_name(prop, buf1, sizeof (buf1)) == -1) {
1453*11909SPeter.Gill@Sun.COM 			syslog(LOG_ERR, "get name from %s iter failed - %s",
1454*11909SPeter.Gill@Sun.COM 			    pgRefName, scf_strerror(scf_error()));
14557836SJohn.Forte@Sun.COM 			ret = STMF_PS_ERROR;
14567836SJohn.Forte@Sun.COM 			break;
14577836SJohn.Forte@Sun.COM 		}
14587836SJohn.Forte@Sun.COM 		/*
14597836SJohn.Forte@Sun.COM 		 * Skip over member list properties
14607836SJohn.Forte@Sun.COM 		 */
14617836SJohn.Forte@Sun.COM 		if (strstr(buf1, STMF_MEMBER_LIST_SUFFIX)) {
14627836SJohn.Forte@Sun.COM 			continue;
14637836SJohn.Forte@Sun.COM 		}
14647836SJohn.Forte@Sun.COM 		if (scf_property_get_value(prop, value) == -1) {
1465*11909SPeter.Gill@Sun.COM 			syslog(LOG_ERR, "get property value %s/%s failed - %s",
1466*11909SPeter.Gill@Sun.COM 			    pgRefName, buf1, scf_strerror(scf_error()));
14677836SJohn.Forte@Sun.COM 			ret = STMF_PS_ERROR;
14687836SJohn.Forte@Sun.COM 			break;
14697836SJohn.Forte@Sun.COM 		}
14707836SJohn.Forte@Sun.COM 		if (scf_value_get_ustring(value, tmpbuf,
14717836SJohn.Forte@Sun.COM 		    sizeof (tmpbuf)) == -1) {
1472*11909SPeter.Gill@Sun.COM 			syslog(LOG_ERR, "get ustring %s/%s failed - %s",
1473*11909SPeter.Gill@Sun.COM 			    pgRefName, buf1, scf_strerror(scf_error()));
14747836SJohn.Forte@Sun.COM 			ret = STMF_PS_ERROR;
14757836SJohn.Forte@Sun.COM 			break;
14767836SJohn.Forte@Sun.COM 		}
14777836SJohn.Forte@Sun.COM 
14787836SJohn.Forte@Sun.COM 		if ((strlen(tmpbuf) == strlen(groupName)) &&
14797836SJohn.Forte@Sun.COM 		    bcmp(tmpbuf, groupName, strlen(tmpbuf)) == 0) {
14807836SJohn.Forte@Sun.COM 			if (addRemoveFlag == ADD) {
14817836SJohn.Forte@Sun.COM 				ret = STMF_PS_ERROR_EXISTS;
14827836SJohn.Forte@Sun.COM 			}
14837836SJohn.Forte@Sun.COM 			found = B_TRUE;
14847836SJohn.Forte@Sun.COM 			/*
14857836SJohn.Forte@Sun.COM 			 * buf1 contains the name for REMOVE
14867836SJohn.Forte@Sun.COM 			 */
14877836SJohn.Forte@Sun.COM 			break;
14887836SJohn.Forte@Sun.COM 		}
14897836SJohn.Forte@Sun.COM 	}
14907836SJohn.Forte@Sun.COM 
14917836SJohn.Forte@Sun.COM 	if (ret != STMF_PS_SUCCESS) {
14927836SJohn.Forte@Sun.COM 		goto out;
14937836SJohn.Forte@Sun.COM 	}
14947836SJohn.Forte@Sun.COM 
14957836SJohn.Forte@Sun.COM 	scf_value_reset(value);
14967836SJohn.Forte@Sun.COM 
14977836SJohn.Forte@Sun.COM 	if (!found && addRemoveFlag == REMOVE) {
14987836SJohn.Forte@Sun.COM 		ret = STMF_PS_ERROR_NOT_FOUND;
14997836SJohn.Forte@Sun.COM 		goto out;
15007836SJohn.Forte@Sun.COM 	}
15017836SJohn.Forte@Sun.COM 
15027836SJohn.Forte@Sun.COM 	/*
15037836SJohn.Forte@Sun.COM 	 * If we're adding, we need to create a new property name for the
15047836SJohn.Forte@Sun.COM 	 * new group
15057836SJohn.Forte@Sun.COM 	 */
15067836SJohn.Forte@Sun.COM 	if (addRemoveFlag == ADD) {
15077836SJohn.Forte@Sun.COM 		for (groupIdx = 0; groupIdx < GROUP_MAX; groupIdx++) {
15087836SJohn.Forte@Sun.COM 			if (snprintf(buf1, sizeof (buf1), "%s-%lld",
15097836SJohn.Forte@Sun.COM 			    STMF_GROUP_PREFIX, groupIdx) > sizeof (buf1)) {
15107836SJohn.Forte@Sun.COM 				syslog(LOG_ERR,
15117836SJohn.Forte@Sun.COM 				    "buffer overflow on property name %s",
15127836SJohn.Forte@Sun.COM 				    buf1);
15137836SJohn.Forte@Sun.COM 				ret = STMF_PS_ERROR;
15147836SJohn.Forte@Sun.COM 				break;
15157836SJohn.Forte@Sun.COM 			}
15167836SJohn.Forte@Sun.COM 			if (scf_pg_get_property(pg, buf1, prop) == -1) {
15177836SJohn.Forte@Sun.COM 				if (scf_error() != SCF_ERROR_NOT_FOUND) {
1518*11909SPeter.Gill@Sun.COM 					syslog(LOG_ERR, "get property %s/%s "
1519*11909SPeter.Gill@Sun.COM 					    "failed - %s", pgRefName, buf1,
15207836SJohn.Forte@Sun.COM 					    scf_strerror(scf_error()));
15217836SJohn.Forte@Sun.COM 					ret = STMF_PS_ERROR;
15227836SJohn.Forte@Sun.COM 				}
15237836SJohn.Forte@Sun.COM 				break;
15247836SJohn.Forte@Sun.COM 			}
15257836SJohn.Forte@Sun.COM 		}
15267836SJohn.Forte@Sun.COM 	}
15277836SJohn.Forte@Sun.COM 
15287836SJohn.Forte@Sun.COM 	/*
15297836SJohn.Forte@Sun.COM 	 * Now create the new member list property for the new group
15307836SJohn.Forte@Sun.COM 	 */
15317836SJohn.Forte@Sun.COM 	if (snprintf(buf2, sizeof (buf2), "%s-%s", buf1,
15327836SJohn.Forte@Sun.COM 	    STMF_MEMBER_LIST_SUFFIX) > sizeof (buf2)) {
15337836SJohn.Forte@Sun.COM 		syslog(LOG_ERR, "buffer overflow on property name %s",
15347836SJohn.Forte@Sun.COM 		    buf1);
15357836SJohn.Forte@Sun.COM 		ret = STMF_PS_ERROR;
15367836SJohn.Forte@Sun.COM 		goto out;
15377836SJohn.Forte@Sun.COM 	}
15387836SJohn.Forte@Sun.COM 
15397836SJohn.Forte@Sun.COM 	/*
15407836SJohn.Forte@Sun.COM 	 * buf1 now contains the name of the property if it was found in the
15417836SJohn.Forte@Sun.COM 	 * list in the case of delete or the next available property name
15427836SJohn.Forte@Sun.COM 	 * in the case of create
15437836SJohn.Forte@Sun.COM 	 *
15447836SJohn.Forte@Sun.COM 	 * buf2 now contains the member list property name
15457836SJohn.Forte@Sun.COM 	 */
15467836SJohn.Forte@Sun.COM 	if (scf_transaction_start(tran, pg) == -1) {
1547*11909SPeter.Gill@Sun.COM 		syslog(LOG_ERR, "start transaction for %s failed - %s",
1548*11909SPeter.Gill@Sun.COM 		    pgRefName, scf_strerror(scf_error()));
15497836SJohn.Forte@Sun.COM 		ret = STMF_PS_ERROR;
15507836SJohn.Forte@Sun.COM 		goto out;
15517836SJohn.Forte@Sun.COM 	}
15527836SJohn.Forte@Sun.COM 
15537836SJohn.Forte@Sun.COM 	if (addRemoveFlag == ADD) {
15547836SJohn.Forte@Sun.COM 		/*
15557836SJohn.Forte@Sun.COM 		 * Create the property 'group name'
15567836SJohn.Forte@Sun.COM 		 * This is the container for the group name
15577836SJohn.Forte@Sun.COM 		 */
15587836SJohn.Forte@Sun.COM 		if (scf_transaction_property_new(tran, entry1, buf1,
15597836SJohn.Forte@Sun.COM 		    SCF_TYPE_USTRING) == -1) {
1560*11909SPeter.Gill@Sun.COM 			syslog(LOG_ERR, "transaction property new %s/%s "
1561*11909SPeter.Gill@Sun.COM 			    "failed - %s", pgRefName, buf1,
15627836SJohn.Forte@Sun.COM 			    scf_strerror(scf_error()));
15637836SJohn.Forte@Sun.COM 			ret = STMF_PS_ERROR;
15647836SJohn.Forte@Sun.COM 			goto out;
15657836SJohn.Forte@Sun.COM 		}
15667836SJohn.Forte@Sun.COM 		if (scf_value_set_ustring(value, groupName) == -1) {
1567*11909SPeter.Gill@Sun.COM 			syslog(LOG_ERR, "set ustring %s/%s failed - %s",
1568*11909SPeter.Gill@Sun.COM 			    pgRefName, buf1, scf_strerror(scf_error()));
15697836SJohn.Forte@Sun.COM 			ret = STMF_PS_ERROR;
15707836SJohn.Forte@Sun.COM 			goto out;
15717836SJohn.Forte@Sun.COM 		}
15727836SJohn.Forte@Sun.COM 		if (scf_entry_add_value(entry1, value) == -1) {
1573*11909SPeter.Gill@Sun.COM 			syslog(LOG_ERR, "add value %s/%s failed - %s",
1574*11909SPeter.Gill@Sun.COM 			    pgRefName, buf1, scf_strerror(scf_error()));
15757836SJohn.Forte@Sun.COM 			ret = STMF_PS_ERROR;
15767836SJohn.Forte@Sun.COM 			goto out;
15777836SJohn.Forte@Sun.COM 		}
15787836SJohn.Forte@Sun.COM 		/*
15797836SJohn.Forte@Sun.COM 		 * Create the property 'group list'
15807836SJohn.Forte@Sun.COM 		 * This is the container for the group members
15817836SJohn.Forte@Sun.COM 		 */
15827836SJohn.Forte@Sun.COM 		if (scf_transaction_property_new(tran, entry2, buf2,
15837836SJohn.Forte@Sun.COM 		    SCF_TYPE_USTRING) == -1) {
1584*11909SPeter.Gill@Sun.COM 			syslog(LOG_ERR, "transaction property new %s/%s "
1585*11909SPeter.Gill@Sun.COM 			    "failed - %s", pgRefName, buf2,
15867836SJohn.Forte@Sun.COM 			    scf_strerror(scf_error()));
15877836SJohn.Forte@Sun.COM 			ret = STMF_PS_ERROR;
15887836SJohn.Forte@Sun.COM 			goto out;
15897836SJohn.Forte@Sun.COM 		}
15907836SJohn.Forte@Sun.COM 	} else {
15917836SJohn.Forte@Sun.COM 		/*
15927836SJohn.Forte@Sun.COM 		 * Delete the property 'group name'
15937836SJohn.Forte@Sun.COM 		 */
15947836SJohn.Forte@Sun.COM 		if (scf_transaction_property_delete(tran, entry1, buf1)
15957836SJohn.Forte@Sun.COM 		    == -1) {
15967836SJohn.Forte@Sun.COM 			syslog(LOG_ERR,
1597*11909SPeter.Gill@Sun.COM 			    "transaction property delete %s/%s failed - %s",
1598*11909SPeter.Gill@Sun.COM 			    pgRefName, buf1, scf_strerror(scf_error()));
15997836SJohn.Forte@Sun.COM 			ret = STMF_PS_ERROR;
16007836SJohn.Forte@Sun.COM 			goto out;
16017836SJohn.Forte@Sun.COM 		}
16027836SJohn.Forte@Sun.COM 		/*
16037836SJohn.Forte@Sun.COM 		 * Delete the property 'group list'
16047836SJohn.Forte@Sun.COM 		 */
16057836SJohn.Forte@Sun.COM 		if (scf_transaction_property_delete(tran, entry2, buf2)
16067836SJohn.Forte@Sun.COM 		    == -1) {
1607*11909SPeter.Gill@Sun.COM 			syslog(LOG_ERR, "transaction property delete %s/%s "
1608*11909SPeter.Gill@Sun.COM 			    "failed - %s", pgRefName, buf2,
16097836SJohn.Forte@Sun.COM 			    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 
16157836SJohn.Forte@Sun.COM 	if (ret != STMF_PS_SUCCESS) {
16167836SJohn.Forte@Sun.COM 		goto out;
16177836SJohn.Forte@Sun.COM 	}
16187836SJohn.Forte@Sun.COM 
16197836SJohn.Forte@Sun.COM 	if ((commitRet = scf_transaction_commit(tran)) != 1) {
1620*11909SPeter.Gill@Sun.COM 		syslog(LOG_ERR, "transaction commit for %s failed - %s",
1621*11909SPeter.Gill@Sun.COM 		    pgRefName, scf_strerror(scf_error()));
16227836SJohn.Forte@Sun.COM 		if (commitRet == 0) {
16237836SJohn.Forte@Sun.COM 			ret = STMF_PS_ERROR_BUSY;
16247836SJohn.Forte@Sun.COM 		} else {
16257836SJohn.Forte@Sun.COM 			ret = STMF_PS_ERROR;
16267836SJohn.Forte@Sun.COM 		}
16277836SJohn.Forte@Sun.COM 	}
16287836SJohn.Forte@Sun.COM 
16297836SJohn.Forte@Sun.COM out:
16307836SJohn.Forte@Sun.COM 	/*
16317836SJohn.Forte@Sun.COM 	 * Free resources
16327836SJohn.Forte@Sun.COM 	 */
16337836SJohn.Forte@Sun.COM 	if (handle != NULL) {
16347836SJohn.Forte@Sun.COM 		scf_handle_destroy(handle);
16357836SJohn.Forte@Sun.COM 	}
16367836SJohn.Forte@Sun.COM 	if (svc != NULL) {
16377836SJohn.Forte@Sun.COM 		scf_service_destroy(svc);
16387836SJohn.Forte@Sun.COM 	}
16397836SJohn.Forte@Sun.COM 	if (pg != NULL) {
16407836SJohn.Forte@Sun.COM 		scf_pg_destroy(pg);
16417836SJohn.Forte@Sun.COM 	}
16427836SJohn.Forte@Sun.COM 	if (tran != NULL) {
16437836SJohn.Forte@Sun.COM 		scf_transaction_destroy(tran);
16447836SJohn.Forte@Sun.COM 	}
16457836SJohn.Forte@Sun.COM 	if (entry1 != NULL) {
16467836SJohn.Forte@Sun.COM 		scf_entry_destroy(entry1);
16477836SJohn.Forte@Sun.COM 	}
16487836SJohn.Forte@Sun.COM 	if (entry2 != NULL) {
16497836SJohn.Forte@Sun.COM 		scf_entry_destroy(entry2);
16507836SJohn.Forte@Sun.COM 	}
16517836SJohn.Forte@Sun.COM 	if (prop != NULL) {
16527836SJohn.Forte@Sun.COM 		scf_property_destroy(prop);
16537836SJohn.Forte@Sun.COM 	}
16547836SJohn.Forte@Sun.COM 	if (propIter != NULL) {
16557836SJohn.Forte@Sun.COM 		scf_iter_destroy(propIter);
16567836SJohn.Forte@Sun.COM 	}
16577836SJohn.Forte@Sun.COM 	if (value != NULL) {
16587836SJohn.Forte@Sun.COM 		scf_value_destroy(value);
16597836SJohn.Forte@Sun.COM 	}
16607836SJohn.Forte@Sun.COM 
16617836SJohn.Forte@Sun.COM 	return (ret);
16627836SJohn.Forte@Sun.COM }
16637836SJohn.Forte@Sun.COM 
16647836SJohn.Forte@Sun.COM /*
16657836SJohn.Forte@Sun.COM  * iPsGetGroupList
16667836SJohn.Forte@Sun.COM  *
16677836SJohn.Forte@Sun.COM  * pgName - Property group name
16687836SJohn.Forte@Sun.COM  * groupList - pointer to pointer to stmfGroupList structure. On success,
16697836SJohn.Forte@Sun.COM  * contains the list of groups
16707836SJohn.Forte@Sun.COM  *
16717836SJohn.Forte@Sun.COM  * returns:
16727836SJohn.Forte@Sun.COM  *  STMF_PS_SUCCESS on success
16737836SJohn.Forte@Sun.COM  *  STMF_PS_ERROR_* on failure
16747836SJohn.Forte@Sun.COM  */
16757836SJohn.Forte@Sun.COM static int
16767836SJohn.Forte@Sun.COM iPsGetGroupList(char *pgName, stmfGroupList **groupList)
16777836SJohn.Forte@Sun.COM {
16787836SJohn.Forte@Sun.COM 	scf_handle_t	*handle = NULL;
16797836SJohn.Forte@Sun.COM 	scf_service_t	*svc = NULL;
16807836SJohn.Forte@Sun.COM 	scf_propertygroup_t	*pg = NULL;
16817836SJohn.Forte@Sun.COM 	scf_property_t	*prop = NULL;
16827836SJohn.Forte@Sun.COM 	scf_iter_t	*propIter = NULL;
16837836SJohn.Forte@Sun.COM 	scf_value_t	*value = NULL;
16847836SJohn.Forte@Sun.COM 	char buf[MAXNAMELEN];
16857836SJohn.Forte@Sun.COM 	int memberCnt = 0;
16867836SJohn.Forte@Sun.COM 	int i = 0;
16877836SJohn.Forte@Sun.COM 	int ret = STMF_PS_SUCCESS;
16887836SJohn.Forte@Sun.COM 
16897836SJohn.Forte@Sun.COM 	assert(groupList != NULL);
16907836SJohn.Forte@Sun.COM 
16917836SJohn.Forte@Sun.COM 	ret = iPsInit(&handle, &svc);
16927836SJohn.Forte@Sun.COM 	if (ret != STMF_PS_SUCCESS) {
16937836SJohn.Forte@Sun.COM 		goto out;
16947836SJohn.Forte@Sun.COM 	}
16957836SJohn.Forte@Sun.COM 
16967836SJohn.Forte@Sun.COM 	/*
16977836SJohn.Forte@Sun.COM 	 * Allocate scf resources
16987836SJohn.Forte@Sun.COM 	 */
16997836SJohn.Forte@Sun.COM 	if (((pg = scf_pg_create(handle)) == NULL) ||
17007836SJohn.Forte@Sun.COM 	    ((prop = scf_property_create(handle)) == NULL) ||
17017836SJohn.Forte@Sun.COM 	    ((propIter = scf_iter_create(handle)) == NULL) ||
17027836SJohn.Forte@Sun.COM 	    ((value = scf_value_create(handle)) == NULL)) {
17037836SJohn.Forte@Sun.COM 		syslog(LOG_ERR, "scf alloc resource failed - %s",
17047836SJohn.Forte@Sun.COM 		    scf_strerror(scf_error()));
17057836SJohn.Forte@Sun.COM 		ret = STMF_PS_ERROR;
17067836SJohn.Forte@Sun.COM 		goto out;
17077836SJohn.Forte@Sun.COM 	}
17087836SJohn.Forte@Sun.COM 
17097836SJohn.Forte@Sun.COM 	if (scf_service_get_pg(svc, pgName, pg) == -1) {
17107836SJohn.Forte@Sun.COM 		if (scf_error() == SCF_ERROR_NOT_FOUND) {
1711*11909SPeter.Gill@Sun.COM 			syslog(LOG_ERR, "get pg %s failed - %s",
1712*11909SPeter.Gill@Sun.COM 			    pgName, scf_strerror(scf_error()));
17137836SJohn.Forte@Sun.COM 			ret = STMF_PS_ERROR_NOT_FOUND;
17147836SJohn.Forte@Sun.COM 		} else {
1715*11909SPeter.Gill@Sun.COM 			syslog(LOG_ERR, "get pg %s failed - %s",
1716*11909SPeter.Gill@Sun.COM 			    pgName, scf_strerror(scf_error()));
17177836SJohn.Forte@Sun.COM 			ret = STMF_PS_ERROR;
17187836SJohn.Forte@Sun.COM 		}
17197836SJohn.Forte@Sun.COM 		goto out;
17207836SJohn.Forte@Sun.COM 	}
17217836SJohn.Forte@Sun.COM 
17227836SJohn.Forte@Sun.COM 	/*
17237836SJohn.Forte@Sun.COM 	 * propIter is the iterator handle
17247836SJohn.Forte@Sun.COM 	 */
17257836SJohn.Forte@Sun.COM 	if (scf_iter_pg_properties(propIter, pg) == -1) {
1726*11909SPeter.Gill@Sun.COM 		syslog(LOG_ERR, "iter properties for %s failed - %s",
1727*11909SPeter.Gill@Sun.COM 		    pgName, scf_strerror(scf_error()));
17287836SJohn.Forte@Sun.COM 		ret = STMF_PS_ERROR;
17297836SJohn.Forte@Sun.COM 		goto out;
17307836SJohn.Forte@Sun.COM 	}
17317836SJohn.Forte@Sun.COM 
17327836SJohn.Forte@Sun.COM 	while (scf_iter_next_property(propIter, prop) == 1) {
17337836SJohn.Forte@Sun.COM 		if (scf_property_get_name(prop, buf, sizeof (buf)) == -1) {
1734*11909SPeter.Gill@Sun.COM 			syslog(LOG_ERR, "get name from %s iter failed - %s",
1735*11909SPeter.Gill@Sun.COM 			    pgName, scf_strerror(scf_error()));
17367836SJohn.Forte@Sun.COM 			ret = STMF_PS_ERROR;
17377836SJohn.Forte@Sun.COM 			break;
17387836SJohn.Forte@Sun.COM 		}
17397836SJohn.Forte@Sun.COM 		/*
17407836SJohn.Forte@Sun.COM 		 * Skip over member list properties
17417836SJohn.Forte@Sun.COM 		 */
17427836SJohn.Forte@Sun.COM 		if (strstr(buf, STMF_MEMBER_LIST_SUFFIX)) {
17437836SJohn.Forte@Sun.COM 			continue;
17447836SJohn.Forte@Sun.COM 		}
17457836SJohn.Forte@Sun.COM 		memberCnt++;
17467836SJohn.Forte@Sun.COM 	}
17477836SJohn.Forte@Sun.COM 
17487836SJohn.Forte@Sun.COM 	/*
17497836SJohn.Forte@Sun.COM 	 * propIter is the iterator handle
17507836SJohn.Forte@Sun.COM 	 */
17517836SJohn.Forte@Sun.COM 	if (scf_iter_pg_properties(propIter, pg) == -1) {
1752*11909SPeter.Gill@Sun.COM 		syslog(LOG_ERR, "iter properties for %s failed - %s",
1753*11909SPeter.Gill@Sun.COM 		    pgName, scf_strerror(scf_error()));
17547836SJohn.Forte@Sun.COM 		ret = STMF_PS_ERROR;
17557836SJohn.Forte@Sun.COM 		goto out;
17567836SJohn.Forte@Sun.COM 	}
17577836SJohn.Forte@Sun.COM 
17587836SJohn.Forte@Sun.COM 	*groupList = (stmfGroupList *)calloc(1, sizeof (stmfGroupList) +
17597836SJohn.Forte@Sun.COM 	    memberCnt * sizeof (stmfGroupName));
17607836SJohn.Forte@Sun.COM 
17617836SJohn.Forte@Sun.COM 	if (*groupList == NULL) {
17627836SJohn.Forte@Sun.COM 		ret = STMF_PS_ERROR_NOMEM;
17637836SJohn.Forte@Sun.COM 		goto out;
17647836SJohn.Forte@Sun.COM 	}
17657836SJohn.Forte@Sun.COM 
17667836SJohn.Forte@Sun.COM 	/*
17677836SJohn.Forte@Sun.COM 	 * In order to get a list of groups, simply get all of the
17687836SJohn.Forte@Sun.COM 	 * properties that are not member list properties, i.e. the group
17697836SJohn.Forte@Sun.COM 	 * name properties.
17707836SJohn.Forte@Sun.COM 	 * It's possible for this list to grow beyond what was originally
17717836SJohn.Forte@Sun.COM 	 * read so just ensure we're not writing beyond our allocated buffer
17727836SJohn.Forte@Sun.COM 	 * by ensuring i < memberCnt
17737836SJohn.Forte@Sun.COM 	 */
17747836SJohn.Forte@Sun.COM 	while ((scf_iter_next_property(propIter, prop) == 1) &&
17757836SJohn.Forte@Sun.COM 	    (i < memberCnt)) {
17767836SJohn.Forte@Sun.COM 		if (scf_property_get_name(prop, buf, sizeof (buf)) == -1) {
1777*11909SPeter.Gill@Sun.COM 			syslog(LOG_ERR, "get name from %s iter failed - %s",
1778*11909SPeter.Gill@Sun.COM 			    pgName, scf_strerror(scf_error()));
17797836SJohn.Forte@Sun.COM 			ret = STMF_PS_ERROR;
17807836SJohn.Forte@Sun.COM 			break;
17817836SJohn.Forte@Sun.COM 		}
17827836SJohn.Forte@Sun.COM 		/*
17837836SJohn.Forte@Sun.COM 		 * Skip over member list properties
17847836SJohn.Forte@Sun.COM 		 */
17857836SJohn.Forte@Sun.COM 		if (strstr(buf, STMF_MEMBER_LIST_SUFFIX)) {
17867836SJohn.Forte@Sun.COM 			continue;
17877836SJohn.Forte@Sun.COM 		}
17887836SJohn.Forte@Sun.COM 		if (scf_property_get_value(prop, value) == -1) {
1789*11909SPeter.Gill@Sun.COM 			syslog(LOG_ERR, "get property value %s/%s failed - %s",
1790*11909SPeter.Gill@Sun.COM 			    pgName, buf, scf_strerror(scf_error()));
17917836SJohn.Forte@Sun.COM 			ret = STMF_PS_ERROR;
17927836SJohn.Forte@Sun.COM 			break;
17937836SJohn.Forte@Sun.COM 		}
17947836SJohn.Forte@Sun.COM 		if (scf_value_get_ustring(value, buf, sizeof (buf)) == -1) {
1795*11909SPeter.Gill@Sun.COM 			syslog(LOG_ERR, "get ustring %s/%s failed - %s",
1796*11909SPeter.Gill@Sun.COM 			    pgName, buf, scf_strerror(scf_error()));
17977836SJohn.Forte@Sun.COM 			ret = STMF_PS_ERROR;
17987836SJohn.Forte@Sun.COM 			break;
17997836SJohn.Forte@Sun.COM 		}
18007836SJohn.Forte@Sun.COM 		bcopy(buf, (*groupList)->name[i++], strlen(buf));
18017836SJohn.Forte@Sun.COM 		(*groupList)->cnt++;
18027836SJohn.Forte@Sun.COM 	}
18037836SJohn.Forte@Sun.COM 
18047836SJohn.Forte@Sun.COM 	if (ret != STMF_PS_SUCCESS) {
18057836SJohn.Forte@Sun.COM 		free(*groupList);
18067836SJohn.Forte@Sun.COM 		goto out;
18077836SJohn.Forte@Sun.COM 	}
18087836SJohn.Forte@Sun.COM 
18097836SJohn.Forte@Sun.COM out:
18107836SJohn.Forte@Sun.COM 	/*
18117836SJohn.Forte@Sun.COM 	 * Free resources
18127836SJohn.Forte@Sun.COM 	 */
18137836SJohn.Forte@Sun.COM 	if (handle != NULL) {
18147836SJohn.Forte@Sun.COM 		scf_handle_destroy(handle);
18157836SJohn.Forte@Sun.COM 	}
18167836SJohn.Forte@Sun.COM 	if (svc != NULL) {
18177836SJohn.Forte@Sun.COM 		scf_service_destroy(svc);
18187836SJohn.Forte@Sun.COM 	}
18197836SJohn.Forte@Sun.COM 	if (pg != NULL) {
18207836SJohn.Forte@Sun.COM 		scf_pg_destroy(pg);
18217836SJohn.Forte@Sun.COM 	}
18227836SJohn.Forte@Sun.COM 	if (propIter != NULL) {
18237836SJohn.Forte@Sun.COM 		scf_iter_destroy(propIter);
18247836SJohn.Forte@Sun.COM 	}
18257836SJohn.Forte@Sun.COM 	if (prop != NULL) {
18267836SJohn.Forte@Sun.COM 		scf_property_destroy(prop);
18277836SJohn.Forte@Sun.COM 	}
18287836SJohn.Forte@Sun.COM 	if (value != NULL) {
18297836SJohn.Forte@Sun.COM 		scf_value_destroy(value);
18307836SJohn.Forte@Sun.COM 	}
18317836SJohn.Forte@Sun.COM 
18327836SJohn.Forte@Sun.COM 	return (ret);
18337836SJohn.Forte@Sun.COM }
18347836SJohn.Forte@Sun.COM 
18357836SJohn.Forte@Sun.COM /*
18367836SJohn.Forte@Sun.COM  * iPsGetGroupMemberList
18377836SJohn.Forte@Sun.COM  *
18387836SJohn.Forte@Sun.COM  * pgName - Property group name
18397836SJohn.Forte@Sun.COM  * groupName - group name (host group or target group)
18407836SJohn.Forte@Sun.COM  * groupMemberList - pointer to pointer to stmfGroupProperties structure. On
18417836SJohn.Forte@Sun.COM  * success, contains the list of group members
18427836SJohn.Forte@Sun.COM  *
18437836SJohn.Forte@Sun.COM  * returns:
18447836SJohn.Forte@Sun.COM  *  STMF_PS_SUCCESS on success
18457836SJohn.Forte@Sun.COM  *  STMF_PS_ERROR_* on failure
18467836SJohn.Forte@Sun.COM  */
18477836SJohn.Forte@Sun.COM static int
18487836SJohn.Forte@Sun.COM iPsGetGroupMemberList(char *pgName, char *groupName,
18497836SJohn.Forte@Sun.COM     stmfGroupProperties **groupMemberList)
18507836SJohn.Forte@Sun.COM {
18517836SJohn.Forte@Sun.COM 	scf_handle_t	*handle = NULL;
18527836SJohn.Forte@Sun.COM 	scf_service_t	*svc = NULL;
18537836SJohn.Forte@Sun.COM 	scf_propertygroup_t	*pg = NULL;
18547836SJohn.Forte@Sun.COM 	scf_property_t	*prop = NULL;
18557836SJohn.Forte@Sun.COM 	scf_value_t	*valueLookup = NULL;
18567836SJohn.Forte@Sun.COM 	scf_iter_t	*valueIter = NULL;
18577836SJohn.Forte@Sun.COM 	int i = 0;
18587836SJohn.Forte@Sun.COM 	int memberCnt;
18597836SJohn.Forte@Sun.COM 	int len;
18607836SJohn.Forte@Sun.COM 	int ret = STMF_PS_SUCCESS;
18617836SJohn.Forte@Sun.COM 	char buf[MAXNAMELEN];
18627836SJohn.Forte@Sun.COM 
18637836SJohn.Forte@Sun.COM 	assert(pgName != NULL && groupName != NULL);
18647836SJohn.Forte@Sun.COM 
18657836SJohn.Forte@Sun.COM 	/*
18667836SJohn.Forte@Sun.COM 	 * init the service handle
18677836SJohn.Forte@Sun.COM 	 */
18687836SJohn.Forte@Sun.COM 	ret = iPsInit(&handle, &svc);
18697836SJohn.Forte@Sun.COM 	if (ret != STMF_PS_SUCCESS) {
18707836SJohn.Forte@Sun.COM 		goto out;
18717836SJohn.Forte@Sun.COM 	}
18727836SJohn.Forte@Sun.COM 
18737836SJohn.Forte@Sun.COM 	/*
18747836SJohn.Forte@Sun.COM 	 * Allocate scf resources
18757836SJohn.Forte@Sun.COM 	 */
18767836SJohn.Forte@Sun.COM 	if (((pg = scf_pg_create(handle)) == NULL) ||
18777836SJohn.Forte@Sun.COM 	    ((prop = scf_property_create(handle)) == NULL) ||
18787836SJohn.Forte@Sun.COM 	    ((valueIter = scf_iter_create(handle)) == NULL) ||
18797836SJohn.Forte@Sun.COM 	    ((valueLookup = scf_value_create(handle)) == NULL)) {
18807836SJohn.Forte@Sun.COM 		syslog(LOG_ERR, "scf alloc resource failed - %s",
18817836SJohn.Forte@Sun.COM 		    scf_strerror(scf_error()));
18827836SJohn.Forte@Sun.COM 		ret = STMF_PS_ERROR;
18837836SJohn.Forte@Sun.COM 		goto out;
18847836SJohn.Forte@Sun.COM 	}
18857836SJohn.Forte@Sun.COM 
18867836SJohn.Forte@Sun.COM 	/*
18877836SJohn.Forte@Sun.COM 	 * get the service property group handle
18887836SJohn.Forte@Sun.COM 	 */
18897836SJohn.Forte@Sun.COM 	if (scf_service_get_pg(svc, pgName, pg) == -1) {
18907836SJohn.Forte@Sun.COM 		if (scf_error() == SCF_ERROR_NOT_FOUND) {
18917836SJohn.Forte@Sun.COM 			ret = STMF_PS_ERROR_NOT_FOUND;
18927836SJohn.Forte@Sun.COM 		} else {
18937836SJohn.Forte@Sun.COM 			ret = STMF_PS_ERROR;
18947836SJohn.Forte@Sun.COM 		}
1895*11909SPeter.Gill@Sun.COM 		syslog(LOG_ERR, "get pg %s failed - %s",
1896*11909SPeter.Gill@Sun.COM 		    pgName, scf_strerror(scf_error()));
18977836SJohn.Forte@Sun.COM 		goto out;
18987836SJohn.Forte@Sun.COM 	}
18997836SJohn.Forte@Sun.COM 
19007836SJohn.Forte@Sun.COM 	/*
19017836SJohn.Forte@Sun.COM 	 * Get the property handle
19027836SJohn.Forte@Sun.COM 	 * based on the target or host group name
19037836SJohn.Forte@Sun.COM 	 */
19047836SJohn.Forte@Sun.COM 	if (scf_pg_get_property(pg, groupName, prop) == -1) {
1905*11909SPeter.Gill@Sun.COM 		syslog(LOG_ERR, "get property %s/%s failed - %s",
1906*11909SPeter.Gill@Sun.COM 		    pgName, groupName, scf_strerror(scf_error()));
19077836SJohn.Forte@Sun.COM 		ret = STMF_PS_ERROR;
19087836SJohn.Forte@Sun.COM 		goto out;
19097836SJohn.Forte@Sun.COM 	}
19107836SJohn.Forte@Sun.COM 
19117836SJohn.Forte@Sun.COM 	/*
19127836SJohn.Forte@Sun.COM 	 * valueIter is the iterator handle
19137836SJohn.Forte@Sun.COM 	 */
19147836SJohn.Forte@Sun.COM 	if (scf_iter_property_values(valueIter, prop) == -1) {
1915*11909SPeter.Gill@Sun.COM 		syslog(LOG_ERR, "iter value %s/%s failed - %s",
1916*11909SPeter.Gill@Sun.COM 		    pgName, groupName, scf_strerror(scf_error()));
19177836SJohn.Forte@Sun.COM 		ret = STMF_PS_ERROR;
19187836SJohn.Forte@Sun.COM 		goto out;
19197836SJohn.Forte@Sun.COM 	}
19207836SJohn.Forte@Sun.COM 
19217836SJohn.Forte@Sun.COM 	while (scf_iter_next_value(valueIter, valueLookup) == 1) {
19227836SJohn.Forte@Sun.COM 		if (scf_value_get_ustring(valueLookup, buf, MAXNAMELEN) == -1) {
1923*11909SPeter.Gill@Sun.COM 			syslog(LOG_ERR, "iter value %s/%s failed - %s",
1924*11909SPeter.Gill@Sun.COM 			    pgName, groupName, scf_strerror(scf_error()));
19257836SJohn.Forte@Sun.COM 			ret = STMF_PS_ERROR;
19267836SJohn.Forte@Sun.COM 			break;
19277836SJohn.Forte@Sun.COM 		}
19287836SJohn.Forte@Sun.COM 		i++;
19297836SJohn.Forte@Sun.COM 	}
19307836SJohn.Forte@Sun.COM 
19317836SJohn.Forte@Sun.COM 	/*
19327836SJohn.Forte@Sun.COM 	 * valueIter is the iterator handle
19337836SJohn.Forte@Sun.COM 	 */
19347836SJohn.Forte@Sun.COM 	if (scf_iter_property_values(valueIter, prop) == -1) {
1935*11909SPeter.Gill@Sun.COM 		syslog(LOG_ERR, "iter value %s/%s failed - %s",
1936*11909SPeter.Gill@Sun.COM 		    pgName, groupName, scf_strerror(scf_error()));
19377836SJohn.Forte@Sun.COM 		ret = STMF_PS_ERROR;
19387836SJohn.Forte@Sun.COM 		goto out;
19397836SJohn.Forte@Sun.COM 	}
19407836SJohn.Forte@Sun.COM 
19417836SJohn.Forte@Sun.COM 	memberCnt = i;
19427836SJohn.Forte@Sun.COM 
19437836SJohn.Forte@Sun.COM 	*groupMemberList = (stmfGroupProperties *)calloc(1,
19447836SJohn.Forte@Sun.COM 	    sizeof (stmfGroupProperties) + memberCnt * sizeof (stmfDevid));
19457836SJohn.Forte@Sun.COM 	if (*groupMemberList == NULL) {
19467836SJohn.Forte@Sun.COM 		ret = STMF_PS_ERROR_NOMEM;
19477836SJohn.Forte@Sun.COM 		goto out;
19487836SJohn.Forte@Sun.COM 	}
19497836SJohn.Forte@Sun.COM 
19507836SJohn.Forte@Sun.COM 	i = 0;
19517836SJohn.Forte@Sun.COM 	while ((scf_iter_next_value(valueIter, valueLookup) == 1) &&
19527836SJohn.Forte@Sun.COM 	    (i < memberCnt)) {
19537836SJohn.Forte@Sun.COM 		if ((len = scf_value_get_ustring(valueLookup, buf, MAXNAMELEN))
19547836SJohn.Forte@Sun.COM 		    == -1) {
1955*11909SPeter.Gill@Sun.COM 			syslog(LOG_ERR, "iter value %s/%s failed - %s",
1956*11909SPeter.Gill@Sun.COM 			    pgName, groupName, scf_strerror(scf_error()));
19577836SJohn.Forte@Sun.COM 			ret = STMF_PS_ERROR;
19587836SJohn.Forte@Sun.COM 			break;
19597836SJohn.Forte@Sun.COM 		}
19607836SJohn.Forte@Sun.COM 		if (len < sizeof (stmfDevid) - 1) {
19617836SJohn.Forte@Sun.COM 			(*groupMemberList)->name[i].identLength = len;
19627836SJohn.Forte@Sun.COM 			bcopy(buf,
19637836SJohn.Forte@Sun.COM 			    (*groupMemberList)->name[i++].ident, len);
19647836SJohn.Forte@Sun.COM 			(*groupMemberList)->cnt++;
19657836SJohn.Forte@Sun.COM 		} else {
19667836SJohn.Forte@Sun.COM 			ret = STMF_PS_ERROR;
19677836SJohn.Forte@Sun.COM 			break;
19687836SJohn.Forte@Sun.COM 		}
19697836SJohn.Forte@Sun.COM 	}
19707836SJohn.Forte@Sun.COM 
19717836SJohn.Forte@Sun.COM 	if (ret != STMF_PS_SUCCESS) {
19727836SJohn.Forte@Sun.COM 		free(*groupMemberList);
19737836SJohn.Forte@Sun.COM 		goto out;
19747836SJohn.Forte@Sun.COM 	}
19757836SJohn.Forte@Sun.COM 
19767836SJohn.Forte@Sun.COM out:
19777836SJohn.Forte@Sun.COM 	/*
19787836SJohn.Forte@Sun.COM 	 * Free resources
19797836SJohn.Forte@Sun.COM 	 */
19807836SJohn.Forte@Sun.COM 	if (handle != NULL) {
19817836SJohn.Forte@Sun.COM 		scf_handle_destroy(handle);
19827836SJohn.Forte@Sun.COM 	}
19837836SJohn.Forte@Sun.COM 	if (svc != NULL) {
19847836SJohn.Forte@Sun.COM 		scf_service_destroy(svc);
19857836SJohn.Forte@Sun.COM 	}
19867836SJohn.Forte@Sun.COM 	if (pg != NULL) {
19877836SJohn.Forte@Sun.COM 		scf_pg_destroy(pg);
19887836SJohn.Forte@Sun.COM 	}
19897836SJohn.Forte@Sun.COM 	if (prop != NULL) {
19907836SJohn.Forte@Sun.COM 		scf_property_destroy(prop);
19917836SJohn.Forte@Sun.COM 	}
19927836SJohn.Forte@Sun.COM 	if (valueLookup != NULL) {
19937836SJohn.Forte@Sun.COM 		scf_value_destroy(valueLookup);
19947836SJohn.Forte@Sun.COM 	}
19957836SJohn.Forte@Sun.COM 	if (valueIter != NULL) {
19967836SJohn.Forte@Sun.COM 		scf_iter_destroy(valueIter);
19977836SJohn.Forte@Sun.COM 	}
19987836SJohn.Forte@Sun.COM 
19997836SJohn.Forte@Sun.COM 	return (ret);
20007836SJohn.Forte@Sun.COM }
20017836SJohn.Forte@Sun.COM 
20029585STim.Szeto@Sun.COM int
20039585STim.Szeto@Sun.COM psGetServicePersist(uint8_t *persistType)
20049585STim.Szeto@Sun.COM {
20059585STim.Szeto@Sun.COM 	scf_handle_t	*handle = NULL;
20069585STim.Szeto@Sun.COM 	scf_service_t	*svc = NULL;
20079585STim.Szeto@Sun.COM 	int ret;
20089585STim.Szeto@Sun.COM 
20099585STim.Szeto@Sun.COM 
20109585STim.Szeto@Sun.COM 	ret = iPsInit(&handle, &svc);
20119585STim.Szeto@Sun.COM 	if (ret != STMF_PS_SUCCESS) {
20129585STim.Szeto@Sun.COM 		return (STMF_PS_ERROR);
20139585STim.Szeto@Sun.COM 	}
20149585STim.Szeto@Sun.COM 
20159585STim.Szeto@Sun.COM 	ret = iPsGetSetPersistType(persistType, handle, svc, GET);
20169585STim.Szeto@Sun.COM 
20179585STim.Szeto@Sun.COM 	/*
20189585STim.Szeto@Sun.COM 	 * Free resources
20199585STim.Szeto@Sun.COM 	 */
20209585STim.Szeto@Sun.COM 	if (handle != NULL) {
20219585STim.Szeto@Sun.COM 		scf_handle_destroy(handle);
20229585STim.Szeto@Sun.COM 	}
20239585STim.Szeto@Sun.COM 	if (svc != NULL) {
20249585STim.Szeto@Sun.COM 		scf_service_destroy(svc);
20259585STim.Szeto@Sun.COM 	}
20269585STim.Szeto@Sun.COM 	return (ret);
20279585STim.Szeto@Sun.COM }
20289585STim.Szeto@Sun.COM 
20299585STim.Szeto@Sun.COM int
20309585STim.Szeto@Sun.COM psSetServicePersist(uint8_t persistType)
20319585STim.Szeto@Sun.COM {
20329585STim.Szeto@Sun.COM 	scf_handle_t	*handle = NULL;
20339585STim.Szeto@Sun.COM 	scf_service_t	*svc = NULL;
20349585STim.Szeto@Sun.COM 	int ret;
20359585STim.Szeto@Sun.COM 
20369585STim.Szeto@Sun.COM 
20379585STim.Szeto@Sun.COM 	ret = iPsInit(&handle, &svc);
20389585STim.Szeto@Sun.COM 	if (ret != STMF_PS_SUCCESS) {
20399585STim.Szeto@Sun.COM 		return (STMF_PS_ERROR);
20409585STim.Szeto@Sun.COM 	}
20419585STim.Szeto@Sun.COM 
20429585STim.Szeto@Sun.COM 	ret = iPsGetSetPersistType(&persistType, handle, svc, SET);
20439585STim.Szeto@Sun.COM 
20449585STim.Szeto@Sun.COM 	/*
20459585STim.Szeto@Sun.COM 	 * Free resources
20469585STim.Szeto@Sun.COM 	 */
20479585STim.Szeto@Sun.COM 	if (handle != NULL) {
20489585STim.Szeto@Sun.COM 		scf_handle_destroy(handle);
20499585STim.Szeto@Sun.COM 	}
20509585STim.Szeto@Sun.COM 	if (svc != NULL) {
20519585STim.Szeto@Sun.COM 		scf_service_destroy(svc);
20529585STim.Szeto@Sun.COM 	}
20539585STim.Szeto@Sun.COM 	return (ret);
20549585STim.Szeto@Sun.COM }
20559585STim.Szeto@Sun.COM 
20569585STim.Szeto@Sun.COM static int
20579585STim.Szeto@Sun.COM iPsGetSetPersistType(uint8_t *persistType, scf_handle_t *handle,
20589585STim.Szeto@Sun.COM scf_service_t *svc, int getSet)
20599585STim.Szeto@Sun.COM {
20609585STim.Szeto@Sun.COM 	scf_propertygroup_t	*pg = NULL;
20619585STim.Szeto@Sun.COM 	scf_property_t	*prop = NULL;
20629585STim.Szeto@Sun.COM 	scf_value_t	*value = NULL;
20639585STim.Szeto@Sun.COM 	scf_transaction_t *tran = NULL;
20649585STim.Szeto@Sun.COM 	scf_transaction_entry_t *entry = NULL;
20659585STim.Szeto@Sun.COM 	char iPersistTypeGet[MAXNAMELEN] = {0};
20669585STim.Szeto@Sun.COM 	char *iPersistType;
20679585STim.Szeto@Sun.COM 	int ret = STMF_PS_SUCCESS;
20689585STim.Szeto@Sun.COM 	int commitRet;
20699585STim.Szeto@Sun.COM 
20709585STim.Szeto@Sun.COM 	if (((pg = scf_pg_create(handle)) == NULL) ||
20719585STim.Szeto@Sun.COM 	    ((prop = scf_property_create(handle)) == NULL) ||
20729585STim.Szeto@Sun.COM 	    ((entry = scf_entry_create(handle)) == NULL) ||
20739585STim.Szeto@Sun.COM 	    ((tran = scf_transaction_create(handle)) == NULL) ||
20749585STim.Szeto@Sun.COM 	    ((value = scf_value_create(handle)) == NULL)) {
20759585STim.Szeto@Sun.COM 		syslog(LOG_ERR, "scf alloc resource failed - %s",
20769585STim.Szeto@Sun.COM 		    scf_strerror(scf_error()));
20779585STim.Szeto@Sun.COM 		ret = STMF_PS_ERROR;
20789585STim.Szeto@Sun.COM 		goto out;
20799585STim.Szeto@Sun.COM 	}
20809585STim.Szeto@Sun.COM 
20819585STim.Szeto@Sun.COM 	if (getSet == GET) {
20829585STim.Szeto@Sun.COM 		/* set to default */
20839585STim.Szeto@Sun.COM 		*persistType = STMF_PERSIST_SMF;
20849585STim.Szeto@Sun.COM 		iPersistType = STMF_PS_PERSIST_SMF;
20859585STim.Szeto@Sun.COM 	}
20869585STim.Szeto@Sun.COM 
20879585STim.Szeto@Sun.COM 	if (getSet == SET) {
20889585STim.Szeto@Sun.COM 		if (*persistType == STMF_PERSIST_SMF) {
20899585STim.Szeto@Sun.COM 			iPersistType = STMF_PS_PERSIST_SMF;
20909585STim.Szeto@Sun.COM 		} else if (*persistType == STMF_PERSIST_NONE) {
20919585STim.Szeto@Sun.COM 			iPersistType = STMF_PS_PERSIST_NONE;
20929585STim.Szeto@Sun.COM 		} else {
20939585STim.Szeto@Sun.COM 			ret = STMF_PS_ERROR;
20949585STim.Szeto@Sun.COM 			goto out;
20959585STim.Szeto@Sun.COM 		}
20969585STim.Szeto@Sun.COM 	}
20979585STim.Szeto@Sun.COM 
20989585STim.Szeto@Sun.COM 	/*
20999585STim.Szeto@Sun.COM 	 * get stmf data property group
21009585STim.Szeto@Sun.COM 	 */
21019585STim.Szeto@Sun.COM 	if (scf_service_get_pg(svc, STMF_DATA_GROUP, pg) == -1) {
21029585STim.Szeto@Sun.COM 		if (scf_error() == SCF_ERROR_NOT_FOUND) {
21039585STim.Szeto@Sun.COM 			ret = STMF_PS_ERROR_NOT_FOUND;
21049585STim.Szeto@Sun.COM 		} else {
21059585STim.Szeto@Sun.COM 			ret = STMF_PS_ERROR;
21069585STim.Szeto@Sun.COM 		}
2107*11909SPeter.Gill@Sun.COM 		syslog(LOG_ERR, "get pg %s failed - %s",
2108*11909SPeter.Gill@Sun.COM 		    STMF_DATA_GROUP, scf_strerror(scf_error()));
2109*11909SPeter.Gill@Sun.COM 
21109585STim.Szeto@Sun.COM 		goto out;
21119585STim.Szeto@Sun.COM 	}
21129585STim.Szeto@Sun.COM 
21139585STim.Szeto@Sun.COM 	/* find persistence property */
21149585STim.Szeto@Sun.COM 	/*
21159585STim.Szeto@Sun.COM 	 * Get the persistence property
21169585STim.Szeto@Sun.COM 	 */
21179585STim.Szeto@Sun.COM 	if (scf_pg_get_property(pg, STMF_PERSIST_TYPE, prop) == -1) {
21189585STim.Szeto@Sun.COM 		if (scf_error() == SCF_ERROR_NOT_FOUND) {
21199585STim.Szeto@Sun.COM 			ret = STMF_PS_ERROR_NOT_FOUND;
21209585STim.Szeto@Sun.COM 		} else {
2121*11909SPeter.Gill@Sun.COM 			syslog(LOG_ERR, "get property %s/%s failed - %s",
2122*11909SPeter.Gill@Sun.COM 			    STMF_DATA_GROUP, STMF_PERSIST_TYPE,
21239585STim.Szeto@Sun.COM 			    scf_strerror(scf_error()));
21249585STim.Szeto@Sun.COM 			ret = STMF_PS_ERROR;
21259585STim.Szeto@Sun.COM 			goto out;
21269585STim.Szeto@Sun.COM 		}
21279585STim.Szeto@Sun.COM 	}
21289585STim.Szeto@Sun.COM 
21299585STim.Szeto@Sun.COM 	/* no persist property found */
21309585STim.Szeto@Sun.COM 	if (ret == STMF_PS_ERROR_NOT_FOUND || getSet == SET) {
21319585STim.Szeto@Sun.COM 		/*
21329585STim.Szeto@Sun.COM 		 * If we have no persistType property, go ahead
21339585STim.Szeto@Sun.COM 		 * and create it with the user specified value or
21349585STim.Szeto@Sun.COM 		 * the default value.
21359585STim.Szeto@Sun.COM 		 */
21369585STim.Szeto@Sun.COM 		/*
21379585STim.Szeto@Sun.COM 		 * Begin the transaction
21389585STim.Szeto@Sun.COM 		 */
21399585STim.Szeto@Sun.COM 		if (scf_transaction_start(tran, pg) == -1) {
2140*11909SPeter.Gill@Sun.COM 			syslog(LOG_ERR, "start transaction for %s failed - %s",
2141*11909SPeter.Gill@Sun.COM 			    STMF_DATA_GROUP, scf_strerror(scf_error()));
21429585STim.Szeto@Sun.COM 			ret = STMF_PS_ERROR;
21439585STim.Szeto@Sun.COM 			goto out;
21449585STim.Szeto@Sun.COM 		}
21459585STim.Szeto@Sun.COM 
21469585STim.Szeto@Sun.COM 		/* is this a SET or GET w/error? */
21479585STim.Szeto@Sun.COM 		if (ret) {
21489585STim.Szeto@Sun.COM 			if (scf_transaction_property_new(tran, entry,
21499585STim.Szeto@Sun.COM 			    STMF_PERSIST_TYPE, SCF_TYPE_ASTRING) == -1) {
2150*11909SPeter.Gill@Sun.COM 				syslog(LOG_ERR, "transaction property new "
2151*11909SPeter.Gill@Sun.COM 				    "%s/%s failed - %s", STMF_DATA_GROUP,
2152*11909SPeter.Gill@Sun.COM 				    STMF_PERSIST_TYPE,
21539585STim.Szeto@Sun.COM 				    scf_strerror(scf_error()));
21549585STim.Szeto@Sun.COM 				ret = STMF_PS_ERROR;
21559585STim.Szeto@Sun.COM 				goto out;
21569585STim.Szeto@Sun.COM 			}
21579585STim.Szeto@Sun.COM 		} else {
21589585STim.Szeto@Sun.COM 			if (scf_transaction_property_change(tran, entry,
21599585STim.Szeto@Sun.COM 			    STMF_PERSIST_TYPE, SCF_TYPE_ASTRING) == -1) {
2160*11909SPeter.Gill@Sun.COM 				syslog(LOG_ERR, "transaction property change "
2161*11909SPeter.Gill@Sun.COM 				    "%s/%s failed - %s", STMF_DATA_GROUP,
2162*11909SPeter.Gill@Sun.COM 				    STMF_PERSIST_TYPE,
21639585STim.Szeto@Sun.COM 				    scf_strerror(scf_error()));
21649585STim.Szeto@Sun.COM 				ret = STMF_PS_ERROR;
21659585STim.Szeto@Sun.COM 				goto out;
21669585STim.Szeto@Sun.COM 			}
21679585STim.Szeto@Sun.COM 		}
21689585STim.Szeto@Sun.COM 
21699585STim.Szeto@Sun.COM 		/*
21709585STim.Szeto@Sun.COM 		 * set the persist type
21719585STim.Szeto@Sun.COM 		 */
21729585STim.Szeto@Sun.COM 		if (scf_value_set_astring(value, iPersistType) == -1) {
2173*11909SPeter.Gill@Sun.COM 			syslog(LOG_ERR, "set value %s/%s failed - %s",
2174*11909SPeter.Gill@Sun.COM 			    STMF_DATA_GROUP, STMF_PERSIST_TYPE,
21759585STim.Szeto@Sun.COM 			    scf_strerror(scf_error()));
21769585STim.Szeto@Sun.COM 			ret = STMF_PS_ERROR;
21779585STim.Szeto@Sun.COM 			goto out;
21789585STim.Szeto@Sun.COM 		}
21799585STim.Szeto@Sun.COM 
21809585STim.Szeto@Sun.COM 		/*
21819585STim.Szeto@Sun.COM 		 * add the value to the transaction
21829585STim.Szeto@Sun.COM 		 */
21839585STim.Szeto@Sun.COM 		if (scf_entry_add_value(entry, value) == -1) {
2184*11909SPeter.Gill@Sun.COM 			syslog(LOG_ERR, "add value %s/%s failed - %s",
2185*11909SPeter.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 		if ((commitRet = scf_transaction_commit(tran)) != 1) {
2191*11909SPeter.Gill@Sun.COM 			syslog(LOG_ERR, "transaction commit for %s failed - %s",
2192*11909SPeter.Gill@Sun.COM 			    STMF_DATA_GROUP, scf_strerror(scf_error()));
21939585STim.Szeto@Sun.COM 			if (commitRet == 0) {
21949585STim.Szeto@Sun.COM 				ret = STMF_PS_ERROR_BUSY;
21959585STim.Szeto@Sun.COM 			} else {
21969585STim.Szeto@Sun.COM 				ret = STMF_PS_ERROR;
21979585STim.Szeto@Sun.COM 			}
21989585STim.Szeto@Sun.COM 			goto out;
21999585STim.Szeto@Sun.COM 		}
22009585STim.Szeto@Sun.COM 		/* reset return value */
22019585STim.Szeto@Sun.COM 		ret = STMF_PS_SUCCESS;
22029585STim.Szeto@Sun.COM 	} else if (getSet == GET) {
22039585STim.Szeto@Sun.COM 		/* get the persist property */
22049585STim.Szeto@Sun.COM 		if (scf_property_get_value(prop, value) == -1) {
2205*11909SPeter.Gill@Sun.COM 			syslog(LOG_ERR, "get property value %s/%s failed - %s",
2206*11909SPeter.Gill@Sun.COM 			    STMF_DATA_GROUP, STMF_PERSIST_TYPE,
22079585STim.Szeto@Sun.COM 			    scf_strerror(scf_error()));
22089585STim.Szeto@Sun.COM 			ret = STMF_PS_ERROR;
22099585STim.Szeto@Sun.COM 			goto out;
22109585STim.Szeto@Sun.COM 		}
22119585STim.Szeto@Sun.COM 
22129585STim.Szeto@Sun.COM 		/*
22139585STim.Szeto@Sun.COM 		 * Get the value of the persist property
22149585STim.Szeto@Sun.COM 		 */
22159585STim.Szeto@Sun.COM 		if (scf_value_get_astring(value, iPersistTypeGet, MAXNAMELEN)
22169585STim.Szeto@Sun.COM 		    == -1) {
2217*11909SPeter.Gill@Sun.COM 			syslog(LOG_ERR, "get string value %s/%s failed - %s",
2218*11909SPeter.Gill@Sun.COM 			    STMF_DATA_GROUP, STMF_PERSIST_TYPE,
22199585STim.Szeto@Sun.COM 			    scf_strerror(scf_error()));
22209585STim.Szeto@Sun.COM 			ret = STMF_PS_ERROR;
22219585STim.Szeto@Sun.COM 			goto out;
22229585STim.Szeto@Sun.COM 		}
22239585STim.Szeto@Sun.COM 	}
22249585STim.Szeto@Sun.COM 
22259585STim.Szeto@Sun.COM 	if (getSet == GET) {
22269585STim.Szeto@Sun.COM 		if (strcmp(iPersistTypeGet, STMF_PS_PERSIST_NONE) == 0) {
22279585STim.Szeto@Sun.COM 			*persistType = STMF_PERSIST_NONE;
22289585STim.Szeto@Sun.COM 		} else if (strcmp(iPersistTypeGet, STMF_PS_PERSIST_SMF) == 0) {
22299585STim.Szeto@Sun.COM 			*persistType = STMF_PERSIST_SMF;
22309585STim.Szeto@Sun.COM 		} else {
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 out:
22369585STim.Szeto@Sun.COM 	/*
22379585STim.Szeto@Sun.COM 	 * Free resources.
22389585STim.Szeto@Sun.COM 	 * handle and svc should not be free'd here. They're
22399585STim.Szeto@Sun.COM 	 * free'd elsewhere
22409585STim.Szeto@Sun.COM 	 */
22419585STim.Szeto@Sun.COM 	if (pg != NULL) {
22429585STim.Szeto@Sun.COM 		scf_pg_destroy(pg);
22439585STim.Szeto@Sun.COM 	}
22449585STim.Szeto@Sun.COM 	if (prop != NULL) {
22459585STim.Szeto@Sun.COM 		scf_property_destroy(prop);
22469585STim.Szeto@Sun.COM 	}
22479585STim.Szeto@Sun.COM 	if (entry != NULL) {
22489585STim.Szeto@Sun.COM 		scf_entry_destroy(entry);
22499585STim.Szeto@Sun.COM 	}
22509585STim.Szeto@Sun.COM 	if (tran != NULL) {
22519585STim.Szeto@Sun.COM 		scf_transaction_destroy(tran);
22529585STim.Szeto@Sun.COM 	}
22539585STim.Szeto@Sun.COM 	if (value != NULL) {
22549585STim.Szeto@Sun.COM 		scf_value_destroy(value);
22559585STim.Szeto@Sun.COM 	}
22569585STim.Szeto@Sun.COM 	return (ret);
22579585STim.Szeto@Sun.COM }
22589585STim.Szeto@Sun.COM 
22597836SJohn.Forte@Sun.COM /*
22607836SJohn.Forte@Sun.COM  * Initialize scf stmf service access
22617836SJohn.Forte@Sun.COM  * handle - returned handle
22627836SJohn.Forte@Sun.COM  * service - returned service handle
22637836SJohn.Forte@Sun.COM  *
22647836SJohn.Forte@Sun.COM  * Both handle and service must be destroyed by the caller
22657836SJohn.Forte@Sun.COM  */
22667836SJohn.Forte@Sun.COM static int
22677836SJohn.Forte@Sun.COM iPsInit(scf_handle_t **handle, scf_service_t **service)
22687836SJohn.Forte@Sun.COM {
22697836SJohn.Forte@Sun.COM 	scf_scope_t	*scope = NULL;
22707836SJohn.Forte@Sun.COM 	uint64_t version;
22717836SJohn.Forte@Sun.COM 	int ret;
22727836SJohn.Forte@Sun.COM 
22737836SJohn.Forte@Sun.COM 	assert(handle != NULL && service != NULL);
22747836SJohn.Forte@Sun.COM 
22757836SJohn.Forte@Sun.COM 	if ((*handle = scf_handle_create(SCF_VERSION)) == NULL) {
22767836SJohn.Forte@Sun.COM 		syslog(LOG_ERR, "scf_handle_create failed - %s",
22777836SJohn.Forte@Sun.COM 		    scf_strerror(scf_error()));
22787836SJohn.Forte@Sun.COM 		ret = STMF_PS_ERROR;
22797836SJohn.Forte@Sun.COM 		goto err;
22807836SJohn.Forte@Sun.COM 	}
22817836SJohn.Forte@Sun.COM 
22827836SJohn.Forte@Sun.COM 	if (scf_handle_bind(*handle) == -1) {
22837836SJohn.Forte@Sun.COM 		syslog(LOG_ERR, "scf_handle_bind failed - %s",
22847836SJohn.Forte@Sun.COM 		    scf_strerror(scf_error()));
22857836SJohn.Forte@Sun.COM 		ret = STMF_PS_ERROR;
22867836SJohn.Forte@Sun.COM 		goto err;
22877836SJohn.Forte@Sun.COM 	}
22887836SJohn.Forte@Sun.COM 
22897836SJohn.Forte@Sun.COM 	if ((*service = scf_service_create(*handle)) == NULL) {
22907836SJohn.Forte@Sun.COM 		syslog(LOG_ERR, "scf_service_create failed - %s",
22917836SJohn.Forte@Sun.COM 		    scf_strerror(scf_error()));
22927836SJohn.Forte@Sun.COM 		ret = STMF_PS_ERROR;
22937836SJohn.Forte@Sun.COM 		goto err;
22947836SJohn.Forte@Sun.COM 	}
22957836SJohn.Forte@Sun.COM 
22967836SJohn.Forte@Sun.COM 	if ((scope = scf_scope_create(*handle)) == NULL) {
22977836SJohn.Forte@Sun.COM 		syslog(LOG_ERR, "scf_scope_create failed - %s",
22987836SJohn.Forte@Sun.COM 		    scf_strerror(scf_error()));
22997836SJohn.Forte@Sun.COM 		ret = STMF_PS_ERROR;
23007836SJohn.Forte@Sun.COM 		goto err;
23017836SJohn.Forte@Sun.COM 	}
23027836SJohn.Forte@Sun.COM 
23037836SJohn.Forte@Sun.COM 	if (scf_handle_get_scope(*handle, SCF_SCOPE_LOCAL, scope) == -1) {
23047836SJohn.Forte@Sun.COM 		syslog(LOG_ERR, "scf_handle_get_scope failed - %s",
23057836SJohn.Forte@Sun.COM 		    scf_strerror(scf_error()));
23067836SJohn.Forte@Sun.COM 		ret = STMF_PS_ERROR;
23077836SJohn.Forte@Sun.COM 		goto err;
23087836SJohn.Forte@Sun.COM 	}
23097836SJohn.Forte@Sun.COM 
23107836SJohn.Forte@Sun.COM 	if (scf_scope_get_service(scope, STMF_SERVICE, *service) == -1) {
23117836SJohn.Forte@Sun.COM 		syslog(LOG_ERR, "scf_scope_get_service failed - %s",
23127836SJohn.Forte@Sun.COM 		    scf_strerror(scf_error()));
23137836SJohn.Forte@Sun.COM 		ret = STMF_PS_ERROR_SERVICE_NOT_FOUND;
23147836SJohn.Forte@Sun.COM 		goto err;
23157836SJohn.Forte@Sun.COM 	}
23167836SJohn.Forte@Sun.COM 
23177836SJohn.Forte@Sun.COM 
23187836SJohn.Forte@Sun.COM 	/*
23197836SJohn.Forte@Sun.COM 	 * Get and check the version number
23207836SJohn.Forte@Sun.COM 	 */
23217836SJohn.Forte@Sun.COM 	ret = iPsGetServiceVersion(&version, *handle, *service);
23227836SJohn.Forte@Sun.COM 	if (ret != STMF_PS_SUCCESS) {
23237836SJohn.Forte@Sun.COM 		goto err;
23247836SJohn.Forte@Sun.COM 	}
23257836SJohn.Forte@Sun.COM 
23267836SJohn.Forte@Sun.COM 	if (version != STMF_SMF_VERSION) {
23277836SJohn.Forte@Sun.COM 		ret = STMF_PS_ERROR_VERSION_MISMATCH;
23287836SJohn.Forte@Sun.COM 		goto err;
23297836SJohn.Forte@Sun.COM 	}
23307836SJohn.Forte@Sun.COM 
23317836SJohn.Forte@Sun.COM 	/* we only need destroy the scope here */
23327836SJohn.Forte@Sun.COM 	scf_scope_destroy(scope);
23337836SJohn.Forte@Sun.COM 
23347836SJohn.Forte@Sun.COM 	return (STMF_PS_SUCCESS);
23357836SJohn.Forte@Sun.COM 
23367836SJohn.Forte@Sun.COM err:
23377836SJohn.Forte@Sun.COM 	if (*handle != NULL) {
23387836SJohn.Forte@Sun.COM 		scf_handle_destroy(*handle);
23397836SJohn.Forte@Sun.COM 	}
23407836SJohn.Forte@Sun.COM 	if (*service != NULL) {
23417836SJohn.Forte@Sun.COM 		scf_service_destroy(*service);
23427836SJohn.Forte@Sun.COM 		*service = NULL;
23437836SJohn.Forte@Sun.COM 	}
23447836SJohn.Forte@Sun.COM 	if (scope != NULL) {
23457836SJohn.Forte@Sun.COM 		scf_scope_destroy(scope);
23467836SJohn.Forte@Sun.COM 	}
23477836SJohn.Forte@Sun.COM 	return (ret);
23487836SJohn.Forte@Sun.COM }
23497836SJohn.Forte@Sun.COM 
23509585STim.Szeto@Sun.COM 
23517836SJohn.Forte@Sun.COM /*
23527836SJohn.Forte@Sun.COM  * called by iPsInit only
23537836SJohn.Forte@Sun.COM  * iPsGetServiceVersion
23547836SJohn.Forte@Sun.COM  */
23557836SJohn.Forte@Sun.COM static int
23567836SJohn.Forte@Sun.COM iPsGetServiceVersion(uint64_t *version, scf_handle_t *handle,
23577836SJohn.Forte@Sun.COM scf_service_t *svc)
23587836SJohn.Forte@Sun.COM {
23597836SJohn.Forte@Sun.COM 	scf_propertygroup_t	*pg = NULL;
23607836SJohn.Forte@Sun.COM 	scf_property_t	*prop = NULL;
23617836SJohn.Forte@Sun.COM 	scf_value_t	*value = NULL;
23627836SJohn.Forte@Sun.COM 	scf_transaction_t *tran = NULL;
23637836SJohn.Forte@Sun.COM 	scf_transaction_entry_t *entry = NULL;
23647836SJohn.Forte@Sun.COM 	int ret = STMF_PS_SUCCESS;
23657836SJohn.Forte@Sun.COM 	int commitRet;
23667836SJohn.Forte@Sun.COM 
23677836SJohn.Forte@Sun.COM 	if (((pg = scf_pg_create(handle)) == NULL) ||
23687836SJohn.Forte@Sun.COM 	    ((prop = scf_property_create(handle)) == NULL) ||
23697836SJohn.Forte@Sun.COM 	    ((entry = scf_entry_create(handle)) == NULL) ||
23707836SJohn.Forte@Sun.COM 	    ((tran = scf_transaction_create(handle)) == NULL) ||
23717836SJohn.Forte@Sun.COM 	    ((value = scf_value_create(handle)) == NULL)) {
23727836SJohn.Forte@Sun.COM 		syslog(LOG_ERR, "scf alloc resource failed - %s",
23737836SJohn.Forte@Sun.COM 		    scf_strerror(scf_error()));
23747836SJohn.Forte@Sun.COM 		ret = STMF_PS_ERROR;
23757836SJohn.Forte@Sun.COM 		goto out;
23767836SJohn.Forte@Sun.COM 	}
23777836SJohn.Forte@Sun.COM 
23787836SJohn.Forte@Sun.COM 	*version = STMF_SMF_VERSION;
23797836SJohn.Forte@Sun.COM 
23807836SJohn.Forte@Sun.COM 	/*
23817836SJohn.Forte@Sun.COM 	 * get stmf data property group
23827836SJohn.Forte@Sun.COM 	 */
23837836SJohn.Forte@Sun.COM 	if (scf_service_get_pg(svc, STMF_DATA_GROUP, pg) == -1) {
23847836SJohn.Forte@Sun.COM 		if (scf_error() == SCF_ERROR_NOT_FOUND) {
23857836SJohn.Forte@Sun.COM 			ret = STMF_PS_ERROR_NOT_FOUND;
23867836SJohn.Forte@Sun.COM 		} else {
2387*11909SPeter.Gill@Sun.COM 			syslog(LOG_ERR, "get pg %s failed - %s",
2388*11909SPeter.Gill@Sun.COM 			    STMF_DATA_GROUP, scf_strerror(scf_error()));
23897836SJohn.Forte@Sun.COM 			ret = STMF_PS_ERROR;
23907836SJohn.Forte@Sun.COM 			goto out;
23917836SJohn.Forte@Sun.COM 		}
23927836SJohn.Forte@Sun.COM 	}
23937836SJohn.Forte@Sun.COM 
23947836SJohn.Forte@Sun.COM 	/* create the group */
23957836SJohn.Forte@Sun.COM 	if (ret == STMF_PS_ERROR_NOT_FOUND) {
23967836SJohn.Forte@Sun.COM 		/*
23977836SJohn.Forte@Sun.COM 		 * create the property group.
23987836SJohn.Forte@Sun.COM 		 */
23997836SJohn.Forte@Sun.COM 		if (scf_service_add_pg(svc, STMF_DATA_GROUP,
24007836SJohn.Forte@Sun.COM 		    SCF_GROUP_APPLICATION, 0, pg) == -1) {
2401*11909SPeter.Gill@Sun.COM 			syslog(LOG_ERR, "add pg %s failed - %s",
2402*11909SPeter.Gill@Sun.COM 			    STMF_DATA_GROUP, scf_strerror(scf_error()));
24037836SJohn.Forte@Sun.COM 			ret = STMF_PS_ERROR;
24047836SJohn.Forte@Sun.COM 			goto out;
24057836SJohn.Forte@Sun.COM 		}
24067836SJohn.Forte@Sun.COM 		/* reset return value */
24077836SJohn.Forte@Sun.COM 		ret = STMF_PS_SUCCESS;
24087836SJohn.Forte@Sun.COM 	}
24097836SJohn.Forte@Sun.COM 
24107836SJohn.Forte@Sun.COM 	/* find version property */
24117836SJohn.Forte@Sun.COM 	/*
24127836SJohn.Forte@Sun.COM 	 * Get the version property
24137836SJohn.Forte@Sun.COM 	 */
24147836SJohn.Forte@Sun.COM 	if (scf_pg_get_property(pg, STMF_VERSION_NAME, prop) == -1) {
24157836SJohn.Forte@Sun.COM 		if (scf_error() == SCF_ERROR_NOT_FOUND) {
24167836SJohn.Forte@Sun.COM 			ret = STMF_PS_ERROR_NOT_FOUND;
24177836SJohn.Forte@Sun.COM 		} else {
2418*11909SPeter.Gill@Sun.COM 			syslog(LOG_ERR, "get property %s/%s failed - %s",
2419*11909SPeter.Gill@Sun.COM 			    STMF_DATA_GROUP, STMF_VERSION_NAME,
24207836SJohn.Forte@Sun.COM 			    scf_strerror(scf_error()));
24217836SJohn.Forte@Sun.COM 			ret = STMF_PS_ERROR;
24227836SJohn.Forte@Sun.COM 			goto out;
24237836SJohn.Forte@Sun.COM 		}
24247836SJohn.Forte@Sun.COM 	}
24257836SJohn.Forte@Sun.COM 
24267836SJohn.Forte@Sun.COM 	/* no version property found */
24277836SJohn.Forte@Sun.COM 	if (ret == STMF_PS_ERROR_NOT_FOUND) {
24287836SJohn.Forte@Sun.COM 		/*
24297836SJohn.Forte@Sun.COM 		 * If we have no version property, go ahead
24307836SJohn.Forte@Sun.COM 		 * and create it. We're obviously making an assumption
24317836SJohn.Forte@Sun.COM 		 * here that someone did not delete the existing property
24327836SJohn.Forte@Sun.COM 		 * and that this is the initial set and the initial call
24337836SJohn.Forte@Sun.COM 		 * to iPsInit.
24347836SJohn.Forte@Sun.COM 		 * If they did delete it, this will simply plant this
24357836SJohn.Forte@Sun.COM 		 * library's version on this service. That may or may not be
24367836SJohn.Forte@Sun.COM 		 * correct and we have no way of determining that.
24377836SJohn.Forte@Sun.COM 		 */
24387836SJohn.Forte@Sun.COM 		/*
24397836SJohn.Forte@Sun.COM 		 * Begin the transaction
24407836SJohn.Forte@Sun.COM 		 */
24417836SJohn.Forte@Sun.COM 		if (scf_transaction_start(tran, pg) == -1) {
2442*11909SPeter.Gill@Sun.COM 			syslog(LOG_ERR, "start transaction for %s failed - %s",
2443*11909SPeter.Gill@Sun.COM 			    STMF_DATA_GROUP, scf_strerror(scf_error()));
24447836SJohn.Forte@Sun.COM 			ret = STMF_PS_ERROR;
24457836SJohn.Forte@Sun.COM 			goto out;
24467836SJohn.Forte@Sun.COM 		}
24477836SJohn.Forte@Sun.COM 
24487836SJohn.Forte@Sun.COM 		if (scf_transaction_property_new(tran, entry,
24497836SJohn.Forte@Sun.COM 		    STMF_VERSION_NAME, SCF_TYPE_COUNT) == -1) {
24507836SJohn.Forte@Sun.COM 			syslog(LOG_ERR,
2451*11909SPeter.Gill@Sun.COM 			    "transaction property new %s/%s failed - %s",
2452*11909SPeter.Gill@Sun.COM 			    STMF_DATA_GROUP, STMF_VERSION_NAME,
24537836SJohn.Forte@Sun.COM 			    scf_strerror(scf_error()));
24547836SJohn.Forte@Sun.COM 			ret = STMF_PS_ERROR;
24557836SJohn.Forte@Sun.COM 			goto out;
24567836SJohn.Forte@Sun.COM 		}
24577836SJohn.Forte@Sun.COM 
24587836SJohn.Forte@Sun.COM 		/*
24597836SJohn.Forte@Sun.COM 		 * set the version number
24607836SJohn.Forte@Sun.COM 		 */
24617836SJohn.Forte@Sun.COM 		scf_value_set_count(value, *version);
24627836SJohn.Forte@Sun.COM 
24637836SJohn.Forte@Sun.COM 		/*
24647836SJohn.Forte@Sun.COM 		 * add the value to the transaction
24657836SJohn.Forte@Sun.COM 		 */
24667836SJohn.Forte@Sun.COM 		if (scf_entry_add_value(entry, value) == -1) {
2467*11909SPeter.Gill@Sun.COM 			syslog(LOG_ERR, "add value %s/%s failed - %s",
2468*11909SPeter.Gill@Sun.COM 			    STMF_DATA_GROUP, STMF_VERSION_NAME,
24697836SJohn.Forte@Sun.COM 			    scf_strerror(scf_error()));
24707836SJohn.Forte@Sun.COM 			ret = STMF_PS_ERROR;
24717836SJohn.Forte@Sun.COM 			goto out;
24727836SJohn.Forte@Sun.COM 		}
24737836SJohn.Forte@Sun.COM 		if ((commitRet = scf_transaction_commit(tran)) != 1) {
2474*11909SPeter.Gill@Sun.COM 			syslog(LOG_ERR, "transaction commit for %s failed - %s",
2475*11909SPeter.Gill@Sun.COM 			    STMF_DATA_GROUP, scf_strerror(scf_error()));
24767836SJohn.Forte@Sun.COM 			if (commitRet == 0) {
24777836SJohn.Forte@Sun.COM 				ret = STMF_PS_ERROR_BUSY;
24787836SJohn.Forte@Sun.COM 			} else {
24797836SJohn.Forte@Sun.COM 				ret = STMF_PS_ERROR;
24807836SJohn.Forte@Sun.COM 			}
24817836SJohn.Forte@Sun.COM 			goto out;
24827836SJohn.Forte@Sun.COM 		}
24837836SJohn.Forte@Sun.COM 		/* reset return value */
24847836SJohn.Forte@Sun.COM 		ret = STMF_PS_SUCCESS;
24857836SJohn.Forte@Sun.COM 	} else {
24867836SJohn.Forte@Sun.COM 		/* get the version property */
24877836SJohn.Forte@Sun.COM 		if (scf_pg_get_property(pg, STMF_VERSION_NAME, prop) == -1) {
2488*11909SPeter.Gill@Sun.COM 			syslog(LOG_ERR, "get property %s/%s failed - %s",
2489*11909SPeter.Gill@Sun.COM 			    STMF_DATA_GROUP, STMF_VERSION_NAME,
24907836SJohn.Forte@Sun.COM 			    scf_strerror(scf_error()));
24917836SJohn.Forte@Sun.COM 			ret = STMF_PS_ERROR;
24927836SJohn.Forte@Sun.COM 			goto out;
24937836SJohn.Forte@Sun.COM 		}
24947836SJohn.Forte@Sun.COM 
24957836SJohn.Forte@Sun.COM 		if (scf_property_get_value(prop, value) == -1) {
2496*11909SPeter.Gill@Sun.COM 			syslog(LOG_ERR, "get property value %s/%s failed - %s",
2497*11909SPeter.Gill@Sun.COM 			    STMF_DATA_GROUP, STMF_VERSION_NAME,
24987836SJohn.Forte@Sun.COM 			    scf_strerror(scf_error()));
24997836SJohn.Forte@Sun.COM 			ret = STMF_PS_ERROR;
25007836SJohn.Forte@Sun.COM 			goto out;
25017836SJohn.Forte@Sun.COM 		}
25027836SJohn.Forte@Sun.COM 
25037836SJohn.Forte@Sun.COM 		/*
25047836SJohn.Forte@Sun.COM 		 * Get the actual value of the view entry count property
25057836SJohn.Forte@Sun.COM 		 */
25067836SJohn.Forte@Sun.COM 		if (scf_value_get_count(value, version) == -1) {
2507*11909SPeter.Gill@Sun.COM 			syslog(LOG_ERR, "get count value %s/%s failed - %s",
2508*11909SPeter.Gill@Sun.COM 			    STMF_DATA_GROUP, STMF_VERSION_NAME,
25097836SJohn.Forte@Sun.COM 			    scf_strerror(scf_error()));
25107836SJohn.Forte@Sun.COM 			ret = STMF_PS_ERROR;
25117836SJohn.Forte@Sun.COM 			goto out;
25127836SJohn.Forte@Sun.COM 		}
25137836SJohn.Forte@Sun.COM 	}
25147836SJohn.Forte@Sun.COM 
25157836SJohn.Forte@Sun.COM out:
25167836SJohn.Forte@Sun.COM 	/*
25177836SJohn.Forte@Sun.COM 	 * Free resources.
25187836SJohn.Forte@Sun.COM 	 * handle and svc should not be free'd here. They're
25197836SJohn.Forte@Sun.COM 	 * free'd elsewhere
25207836SJohn.Forte@Sun.COM 	 */
25217836SJohn.Forte@Sun.COM 	if (pg != NULL) {
25227836SJohn.Forte@Sun.COM 		scf_pg_destroy(pg);
25237836SJohn.Forte@Sun.COM 	}
25247836SJohn.Forte@Sun.COM 	if (prop != NULL) {
25257836SJohn.Forte@Sun.COM 		scf_property_destroy(prop);
25267836SJohn.Forte@Sun.COM 	}
25277836SJohn.Forte@Sun.COM 	if (entry != NULL) {
25287836SJohn.Forte@Sun.COM 		scf_entry_destroy(entry);
25297836SJohn.Forte@Sun.COM 	}
25307836SJohn.Forte@Sun.COM 	if (tran != NULL) {
25317836SJohn.Forte@Sun.COM 		scf_transaction_destroy(tran);
25327836SJohn.Forte@Sun.COM 	}
25337836SJohn.Forte@Sun.COM 	if (value != NULL) {
25347836SJohn.Forte@Sun.COM 		scf_value_destroy(value);
25357836SJohn.Forte@Sun.COM 	}
25367836SJohn.Forte@Sun.COM 	return (ret);
25377836SJohn.Forte@Sun.COM }
25387836SJohn.Forte@Sun.COM 
25397836SJohn.Forte@Sun.COM 
25407836SJohn.Forte@Sun.COM 
25417836SJohn.Forte@Sun.COM /*
25427836SJohn.Forte@Sun.COM  * iPsGetActualGroupName
25437836SJohn.Forte@Sun.COM  *
25447836SJohn.Forte@Sun.COM  * pgName - Property group name
25457836SJohn.Forte@Sun.COM  * groupName - requested group name
25467836SJohn.Forte@Sun.COM  * actualName - actual group name to reference (len must be >= MAXNAMELEN)
25477836SJohn.Forte@Sun.COM  *
25487836SJohn.Forte@Sun.COM  * returns:
25497836SJohn.Forte@Sun.COM  *  STMF_PS_SUCCESS on success
25507836SJohn.Forte@Sun.COM  *  STMF_PS_ERROR_* on failure
25517836SJohn.Forte@Sun.COM  */
25527836SJohn.Forte@Sun.COM static int
25537836SJohn.Forte@Sun.COM iPsGetActualGroupName(char *pgName, char *groupName, char *actualName)
25547836SJohn.Forte@Sun.COM {
25557836SJohn.Forte@Sun.COM 	scf_handle_t	*handle = NULL;
25567836SJohn.Forte@Sun.COM 	scf_service_t	*svc = NULL;
25577836SJohn.Forte@Sun.COM 	scf_propertygroup_t	*pg = NULL;
25587836SJohn.Forte@Sun.COM 	scf_property_t	*prop = NULL;
25597836SJohn.Forte@Sun.COM 	scf_iter_t	*propIter = NULL;
25607836SJohn.Forte@Sun.COM 	scf_value_t	*value = NULL;
25617836SJohn.Forte@Sun.COM 	char buf[MAXNAMELEN];
25627836SJohn.Forte@Sun.COM 	int ret;
25637836SJohn.Forte@Sun.COM 
25647836SJohn.Forte@Sun.COM 	ret = iPsInit(&handle, &svc);
25657836SJohn.Forte@Sun.COM 	if (ret != STMF_PS_SUCCESS) {
25667836SJohn.Forte@Sun.COM 		goto out;
25677836SJohn.Forte@Sun.COM 	}
25687836SJohn.Forte@Sun.COM 
25697836SJohn.Forte@Sun.COM 	/*
25707836SJohn.Forte@Sun.COM 	 * Allocate scf resources
25717836SJohn.Forte@Sun.COM 	 */
25727836SJohn.Forte@Sun.COM 	if (((pg = scf_pg_create(handle)) == NULL) ||
25737836SJohn.Forte@Sun.COM 	    ((prop = scf_property_create(handle)) == NULL) ||
25747836SJohn.Forte@Sun.COM 	    ((propIter = scf_iter_create(handle)) == NULL) ||
25757836SJohn.Forte@Sun.COM 	    ((value = scf_value_create(handle)) == NULL)) {
25767836SJohn.Forte@Sun.COM 		syslog(LOG_ERR, "scf alloc resource failed - %s",
25777836SJohn.Forte@Sun.COM 		    scf_strerror(scf_error()));
25787836SJohn.Forte@Sun.COM 		ret = STMF_PS_ERROR;
25797836SJohn.Forte@Sun.COM 		goto out;
25807836SJohn.Forte@Sun.COM 	}
25817836SJohn.Forte@Sun.COM 
25827836SJohn.Forte@Sun.COM 	/*
25837836SJohn.Forte@Sun.COM 	 * get group list property group
25847836SJohn.Forte@Sun.COM 	 */
25857836SJohn.Forte@Sun.COM 	if (scf_service_get_pg(svc, pgName, pg) == -1) {
25867836SJohn.Forte@Sun.COM 		if (scf_error() == SCF_ERROR_NOT_FOUND) {
25877836SJohn.Forte@Sun.COM 			ret = STMF_PS_ERROR_GROUP_NOT_FOUND;
25887836SJohn.Forte@Sun.COM 		} else {
2589*11909SPeter.Gill@Sun.COM 			syslog(LOG_ERR, "get pg %s failed - %s",
2590*11909SPeter.Gill@Sun.COM 			    pgName, scf_strerror(scf_error()));
25917836SJohn.Forte@Sun.COM 			ret = STMF_PS_ERROR;
25927836SJohn.Forte@Sun.COM 		}
25937836SJohn.Forte@Sun.COM 		goto out;
25947836SJohn.Forte@Sun.COM 	}
25957836SJohn.Forte@Sun.COM 
25967836SJohn.Forte@Sun.COM 	/*
25977836SJohn.Forte@Sun.COM 	 * propIter is the iterator handle
25987836SJohn.Forte@Sun.COM 	 */
25997836SJohn.Forte@Sun.COM 	if (scf_iter_pg_properties(propIter, pg) == -1) {
2600*11909SPeter.Gill@Sun.COM 		syslog(LOG_ERR, "iter properties for %s failed - %s",
2601*11909SPeter.Gill@Sun.COM 		    pgName, scf_strerror(scf_error()));
26027836SJohn.Forte@Sun.COM 		ret = STMF_PS_ERROR;
26037836SJohn.Forte@Sun.COM 		goto out;
26047836SJohn.Forte@Sun.COM 	}
26057836SJohn.Forte@Sun.COM 
26067836SJohn.Forte@Sun.COM 	/*
26077836SJohn.Forte@Sun.COM 	 * Iterate through group properties searching for the requested
26087836SJohn.Forte@Sun.COM 	 * group name. When we find it, we need to get the property name
26097836SJohn.Forte@Sun.COM 	 * since it refers to the actual group name.
26107836SJohn.Forte@Sun.COM 	 */
26117836SJohn.Forte@Sun.COM 
26127836SJohn.Forte@Sun.COM 	/* initialize to not found */
26137836SJohn.Forte@Sun.COM 	ret = STMF_PS_ERROR_GROUP_NOT_FOUND;
26147836SJohn.Forte@Sun.COM 	while (scf_iter_next_property(propIter, prop) == 1) {
26157836SJohn.Forte@Sun.COM 		if (scf_property_get_name(prop, actualName, MAXNAMELEN) == -1) {
2616*11909SPeter.Gill@Sun.COM 			syslog(LOG_ERR, "get name from %s iter failed - %s",
2617*11909SPeter.Gill@Sun.COM 			    pgName, scf_strerror(scf_error()));
26187836SJohn.Forte@Sun.COM 			ret = STMF_PS_ERROR;
26197836SJohn.Forte@Sun.COM 			break;
26207836SJohn.Forte@Sun.COM 		}
26217836SJohn.Forte@Sun.COM 		/*
26227836SJohn.Forte@Sun.COM 		 * Skip over non-member list properties
26237836SJohn.Forte@Sun.COM 		 */
26247836SJohn.Forte@Sun.COM 		if (strstr(actualName, STMF_MEMBER_LIST_SUFFIX)) {
26257836SJohn.Forte@Sun.COM 			continue;
26267836SJohn.Forte@Sun.COM 		}
26277836SJohn.Forte@Sun.COM 		if (scf_property_get_value(prop, value) == -1) {
2628*11909SPeter.Gill@Sun.COM 			syslog(LOG_ERR, "get property value %s/%s failed - %s",
2629*11909SPeter.Gill@Sun.COM 			    pgName, actualName, scf_strerror(scf_error()));
26307836SJohn.Forte@Sun.COM 			ret = STMF_PS_ERROR;
26317836SJohn.Forte@Sun.COM 			break;
26327836SJohn.Forte@Sun.COM 		}
26337836SJohn.Forte@Sun.COM 		if (scf_value_get_ustring(value, buf, sizeof (buf)) == -1) {
2634*11909SPeter.Gill@Sun.COM 			syslog(LOG_ERR, "get ustring %s/%s failed - %s",
2635*11909SPeter.Gill@Sun.COM 			    pgName, actualName, scf_strerror(scf_error()));
26367836SJohn.Forte@Sun.COM 			ret = STMF_PS_ERROR;
26377836SJohn.Forte@Sun.COM 			break;
26387836SJohn.Forte@Sun.COM 		}
26397836SJohn.Forte@Sun.COM 
26407836SJohn.Forte@Sun.COM 		/*
26417836SJohn.Forte@Sun.COM 		 * When we find a match, set success and break
26427836SJohn.Forte@Sun.COM 		 */
26437836SJohn.Forte@Sun.COM 		if ((strlen(buf) == strlen(groupName)) &&
26447836SJohn.Forte@Sun.COM 		    bcmp(buf, groupName, strlen(buf)) == 0) {
26457836SJohn.Forte@Sun.COM 			ret = STMF_PS_SUCCESS;
26467836SJohn.Forte@Sun.COM 			break;
26477836SJohn.Forte@Sun.COM 		}
26487836SJohn.Forte@Sun.COM 	}
26497836SJohn.Forte@Sun.COM 
26507836SJohn.Forte@Sun.COM 	/*
26517836SJohn.Forte@Sun.COM 	 * if we didn't find it, ret is set to STMF_PS_ERROR_GROUP_NOT_FOUND
26527836SJohn.Forte@Sun.COM 	 */
26537836SJohn.Forte@Sun.COM 
26547836SJohn.Forte@Sun.COM out:
26557836SJohn.Forte@Sun.COM 	/*
26567836SJohn.Forte@Sun.COM 	 * Free resources
26577836SJohn.Forte@Sun.COM 	 */
26587836SJohn.Forte@Sun.COM 	if (handle != NULL) {
26597836SJohn.Forte@Sun.COM 		scf_handle_destroy(handle);
26607836SJohn.Forte@Sun.COM 	}
26617836SJohn.Forte@Sun.COM 	if (svc != NULL) {
26627836SJohn.Forte@Sun.COM 		scf_service_destroy(svc);
26637836SJohn.Forte@Sun.COM 	}
26647836SJohn.Forte@Sun.COM 	if (pg != NULL) {
26657836SJohn.Forte@Sun.COM 		scf_pg_destroy(pg);
26667836SJohn.Forte@Sun.COM 	}
26677836SJohn.Forte@Sun.COM 	if (propIter != NULL) {
26687836SJohn.Forte@Sun.COM 		scf_iter_destroy(propIter);
26697836SJohn.Forte@Sun.COM 	}
26707836SJohn.Forte@Sun.COM 	if (prop != NULL) {
26717836SJohn.Forte@Sun.COM 		scf_property_destroy(prop);
26727836SJohn.Forte@Sun.COM 	}
26737836SJohn.Forte@Sun.COM 	if (value != NULL) {
26747836SJohn.Forte@Sun.COM 		scf_value_destroy(value);
26757836SJohn.Forte@Sun.COM 	}
26767836SJohn.Forte@Sun.COM 
26777836SJohn.Forte@Sun.COM 	return (ret);
26787836SJohn.Forte@Sun.COM }
26797836SJohn.Forte@Sun.COM 
26807836SJohn.Forte@Sun.COM /*
26817836SJohn.Forte@Sun.COM  * psAddHostGroupMember
26827836SJohn.Forte@Sun.COM  *
26837836SJohn.Forte@Sun.COM  * Add a host group member to a host group,
26847836SJohn.Forte@Sun.COM  *
26857836SJohn.Forte@Sun.COM  * Input: groupName - name of group to which the member is added
26867836SJohn.Forte@Sun.COM  *        memberName - name of group member to add
26877836SJohn.Forte@Sun.COM  */
26887836SJohn.Forte@Sun.COM int
26897836SJohn.Forte@Sun.COM psAddHostGroupMember(char *groupName, char *memberName)
26907836SJohn.Forte@Sun.COM {
26917836SJohn.Forte@Sun.COM 	int ret;
26927836SJohn.Forte@Sun.COM 	char groupPropListName[MAXNAMELEN];
26937836SJohn.Forte@Sun.COM 	char groupPropName[MAXNAMELEN];
26947836SJohn.Forte@Sun.COM 
26957836SJohn.Forte@Sun.COM 	ret = iPsGetActualGroupName(STMF_HOST_GROUPS, groupName,
26967836SJohn.Forte@Sun.COM 	    groupPropName);
26977836SJohn.Forte@Sun.COM 	if (ret != STMF_PS_SUCCESS) {
26987836SJohn.Forte@Sun.COM 		return (ret);
26997836SJohn.Forte@Sun.COM 	}
27007836SJohn.Forte@Sun.COM 
27017836SJohn.Forte@Sun.COM 	if (snprintf(groupPropListName, sizeof (groupPropListName),
27027836SJohn.Forte@Sun.COM 	    "%s-%s", groupPropName, STMF_MEMBER_LIST_SUFFIX) >
27037836SJohn.Forte@Sun.COM 	    sizeof (groupPropListName)) {
27047836SJohn.Forte@Sun.COM 		syslog(LOG_ERR, "buffer overflow on property name %s",
27057836SJohn.Forte@Sun.COM 		    groupPropName);
27067836SJohn.Forte@Sun.COM 		return (STMF_PS_ERROR);
27077836SJohn.Forte@Sun.COM 	}
27087836SJohn.Forte@Sun.COM 
27097836SJohn.Forte@Sun.COM 	return (iPsAddRemoveGroupMember(STMF_HOST_GROUPS, groupPropListName,
27107836SJohn.Forte@Sun.COM 	    memberName, ADD));
27117836SJohn.Forte@Sun.COM }
27127836SJohn.Forte@Sun.COM 
27137836SJohn.Forte@Sun.COM /*
27147836SJohn.Forte@Sun.COM  * psAddTargetGroupMember
27157836SJohn.Forte@Sun.COM  *
27167836SJohn.Forte@Sun.COM  * Add a target port group member to a target group
27177836SJohn.Forte@Sun.COM  *
27187836SJohn.Forte@Sun.COM  * Input: groupName - name of group to which the member is added
27197836SJohn.Forte@Sun.COM  *        memberName - name of group member to add. Must be nul terminated.
27207836SJohn.Forte@Sun.COM  */
27217836SJohn.Forte@Sun.COM int
27227836SJohn.Forte@Sun.COM psAddTargetGroupMember(char *groupName, char *memberName)
27237836SJohn.Forte@Sun.COM {
27247836SJohn.Forte@Sun.COM 	int ret;
27257836SJohn.Forte@Sun.COM 	char groupPropListName[MAXNAMELEN];
27267836SJohn.Forte@Sun.COM 	char groupPropName[MAXNAMELEN];
27277836SJohn.Forte@Sun.COM 
27287836SJohn.Forte@Sun.COM 	ret = iPsGetActualGroupName(STMF_TARGET_GROUPS, groupName,
27297836SJohn.Forte@Sun.COM 	    groupPropName);
27307836SJohn.Forte@Sun.COM 	if (ret != STMF_PS_SUCCESS) {
27317836SJohn.Forte@Sun.COM 		return (ret);
27327836SJohn.Forte@Sun.COM 	}
27337836SJohn.Forte@Sun.COM 
27347836SJohn.Forte@Sun.COM 	if (snprintf(groupPropListName, sizeof (groupPropListName),
27357836SJohn.Forte@Sun.COM 	    "%s-%s", groupPropName, STMF_MEMBER_LIST_SUFFIX) >
27367836SJohn.Forte@Sun.COM 	    sizeof (groupPropListName)) {
27377836SJohn.Forte@Sun.COM 		syslog(LOG_ERR, "buffer overflow on property name %s",
27387836SJohn.Forte@Sun.COM 		    groupPropName);
27397836SJohn.Forte@Sun.COM 		return (STMF_PS_ERROR);
27407836SJohn.Forte@Sun.COM 	}
27417836SJohn.Forte@Sun.COM 
27427836SJohn.Forte@Sun.COM 	return (iPsAddRemoveGroupMember(STMF_TARGET_GROUPS, groupPropListName,
27437836SJohn.Forte@Sun.COM 	    memberName, ADD));
27447836SJohn.Forte@Sun.COM }
27457836SJohn.Forte@Sun.COM 
27467836SJohn.Forte@Sun.COM 
27477836SJohn.Forte@Sun.COM /*
27487836SJohn.Forte@Sun.COM  * psAddViewEntry
27497836SJohn.Forte@Sun.COM  *
27507836SJohn.Forte@Sun.COM  * luGuid - logical unit identifier
27517836SJohn.Forte@Sun.COM  * viewEntry - pointer to viewEntry allocated by the caller that contains
27527836SJohn.Forte@Sun.COM  *             the values to set for this view entry
27537836SJohn.Forte@Sun.COM  *
27547836SJohn.Forte@Sun.COM  * returns:
27557836SJohn.Forte@Sun.COM  *  STMF_PS_SUCCESS on success
27567836SJohn.Forte@Sun.COM  *  STMF_PS_ERROR_* on failure
27577836SJohn.Forte@Sun.COM  */
27587836SJohn.Forte@Sun.COM int
27597836SJohn.Forte@Sun.COM psAddViewEntry(stmfGuid *lu, stmfViewEntry *viewEntry)
27607836SJohn.Forte@Sun.COM {
27617836SJohn.Forte@Sun.COM 	scf_handle_t	*handle = NULL;
27627836SJohn.Forte@Sun.COM 	scf_service_t	*svc = NULL;
27637836SJohn.Forte@Sun.COM 	scf_propertygroup_t	*pg = NULL;
27647836SJohn.Forte@Sun.COM 	char guidAsciiBuf[33]; /* size of ascii hex 16 byte guid with NULL */
27657836SJohn.Forte@Sun.COM 	char viewEntryPgName[VIEW_ENTRY_PG_SIZE];
27667836SJohn.Forte@Sun.COM 	char scfLuPgName[LOGICAL_UNIT_PG_SIZE];
27677836SJohn.Forte@Sun.COM 	int ret = STMF_PS_SUCCESS;
27687836SJohn.Forte@Sun.COM 	sigset_t sigmaskRestore;
27697836SJohn.Forte@Sun.COM 
27707836SJohn.Forte@Sun.COM 	/* grab the signal hold lock */
27717836SJohn.Forte@Sun.COM 	(void) pthread_mutex_lock(&sigSetLock);
27727836SJohn.Forte@Sun.COM 
27737836SJohn.Forte@Sun.COM 	/*
27747836SJohn.Forte@Sun.COM 	 * hold signals until we're done
27757836SJohn.Forte@Sun.COM 	 */
27767836SJohn.Forte@Sun.COM 	if (holdSignal(&sigmaskRestore) != 0) {
27777836SJohn.Forte@Sun.COM 		(void) pthread_mutex_unlock(&sigSetLock);
27787836SJohn.Forte@Sun.COM 		return (STMF_PS_ERROR);
27797836SJohn.Forte@Sun.COM 	}
27807836SJohn.Forte@Sun.COM 
27817836SJohn.Forte@Sun.COM 	ret = iPsInit(&handle, &svc);
27827836SJohn.Forte@Sun.COM 	if (ret != STMF_PS_SUCCESS) {
27837836SJohn.Forte@Sun.COM 		goto out;
27847836SJohn.Forte@Sun.COM 	}
27857836SJohn.Forte@Sun.COM 
27867836SJohn.Forte@Sun.COM 	pg = scf_pg_create(handle);
27877836SJohn.Forte@Sun.COM 	if (pg == NULL) {
27887836SJohn.Forte@Sun.COM 		syslog(LOG_ERR, "scf pg alloc failed - %s",
27897836SJohn.Forte@Sun.COM 		    scf_strerror(scf_error()));
27907836SJohn.Forte@Sun.COM 		ret = STMF_PS_ERROR;
27917836SJohn.Forte@Sun.COM 		goto out;
27927836SJohn.Forte@Sun.COM 	}
27937836SJohn.Forte@Sun.COM 
27947836SJohn.Forte@Sun.COM 	/* Convert to ASCII uppercase hexadecimal string */
27957836SJohn.Forte@Sun.COM 	(void) snprintf(guidAsciiBuf, sizeof (guidAsciiBuf),
27967836SJohn.Forte@Sun.COM 	    "%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X",
27977836SJohn.Forte@Sun.COM 	    lu->guid[0], lu->guid[1], lu->guid[2], lu->guid[3], lu->guid[4],
27987836SJohn.Forte@Sun.COM 	    lu->guid[5], lu->guid[6], lu->guid[7], lu->guid[8], lu->guid[9],
27997836SJohn.Forte@Sun.COM 	    lu->guid[10], lu->guid[11], lu->guid[12], lu->guid[13],
28007836SJohn.Forte@Sun.COM 	    lu->guid[14], lu->guid[15]);
28017836SJohn.Forte@Sun.COM 
28027836SJohn.Forte@Sun.COM 	(void) snprintf(scfLuPgName, sizeof (scfLuPgName), "%s-%s",
28037836SJohn.Forte@Sun.COM 	    STMF_LU_PREFIX, guidAsciiBuf);
28047836SJohn.Forte@Sun.COM 
28057836SJohn.Forte@Sun.COM 	bzero(viewEntryPgName, sizeof (viewEntryPgName));
28067836SJohn.Forte@Sun.COM 	/*
28077836SJohn.Forte@Sun.COM 	 * Format of view entry property group name:
28087836SJohn.Forte@Sun.COM 	 *	VE-<view_entry_name>-<lu_name>
28097836SJohn.Forte@Sun.COM 	 */
28107836SJohn.Forte@Sun.COM 	(void) snprintf(viewEntryPgName, sizeof (viewEntryPgName),
28117836SJohn.Forte@Sun.COM 	    "%s-%d-%s", STMF_VE_PREFIX, viewEntry->veIndex, guidAsciiBuf);
28127836SJohn.Forte@Sun.COM 
28137836SJohn.Forte@Sun.COM 	ret = iPsAddViewEntry(scfLuPgName, viewEntryPgName, viewEntry);
28147836SJohn.Forte@Sun.COM 
28157836SJohn.Forte@Sun.COM out:
28167836SJohn.Forte@Sun.COM 	/*
28177836SJohn.Forte@Sun.COM 	 * Okay, we're done. Release the signals
28187836SJohn.Forte@Sun.COM 	 */
28197836SJohn.Forte@Sun.COM 	if (releaseSignal(&sigmaskRestore) != 0) {
28207836SJohn.Forte@Sun.COM 		/*
28217836SJohn.Forte@Sun.COM 		 * Don't set this as an STMF_PS_ERROR_*. We succeeded
28227836SJohn.Forte@Sun.COM 		 * the requested operation. But we do need to log it.
28237836SJohn.Forte@Sun.COM 		 */
28247836SJohn.Forte@Sun.COM 		syslog(LOG_ERR, "Unable to release one or more signals - %s",
28257836SJohn.Forte@Sun.COM 		    strerror(errno));
28267836SJohn.Forte@Sun.COM 	}
28277836SJohn.Forte@Sun.COM 
28287836SJohn.Forte@Sun.COM 	/*
28297836SJohn.Forte@Sun.COM 	 * Free resources
28307836SJohn.Forte@Sun.COM 	 */
28317836SJohn.Forte@Sun.COM 	if (handle != NULL) {
28327836SJohn.Forte@Sun.COM 		scf_handle_destroy(handle);
28337836SJohn.Forte@Sun.COM 	}
28347836SJohn.Forte@Sun.COM 	if (svc != NULL) {
28357836SJohn.Forte@Sun.COM 		scf_service_destroy(svc);
28367836SJohn.Forte@Sun.COM 	}
28377836SJohn.Forte@Sun.COM 	if (pg != NULL) {
28387836SJohn.Forte@Sun.COM 		scf_pg_destroy(pg);
28397836SJohn.Forte@Sun.COM 	}
28407836SJohn.Forte@Sun.COM 
28417836SJohn.Forte@Sun.COM 	/* release the signal hold lock */
28427836SJohn.Forte@Sun.COM 	(void) pthread_mutex_unlock(&sigSetLock);
28437836SJohn.Forte@Sun.COM 
28447836SJohn.Forte@Sun.COM 	return (ret);
28457836SJohn.Forte@Sun.COM }
28467836SJohn.Forte@Sun.COM 
28477836SJohn.Forte@Sun.COM /*
28487836SJohn.Forte@Sun.COM  * psCheckService
28497836SJohn.Forte@Sun.COM  *
28507836SJohn.Forte@Sun.COM  * Purpose: Checks whether service exists
28517836SJohn.Forte@Sun.COM  *
28527836SJohn.Forte@Sun.COM  */
28537836SJohn.Forte@Sun.COM int
28547836SJohn.Forte@Sun.COM psCheckService()
28557836SJohn.Forte@Sun.COM {
28567836SJohn.Forte@Sun.COM 	int ret;
28577836SJohn.Forte@Sun.COM 	scf_handle_t	*handle = NULL;
28587836SJohn.Forte@Sun.COM 	scf_service_t	*svc = NULL;
28597836SJohn.Forte@Sun.COM 
28607836SJohn.Forte@Sun.COM 	ret = iPsInit(&handle, &svc);
28617836SJohn.Forte@Sun.COM 
28627836SJohn.Forte@Sun.COM 	/*
28637836SJohn.Forte@Sun.COM 	 * Free resources
28647836SJohn.Forte@Sun.COM 	 */
28657836SJohn.Forte@Sun.COM 	if (handle != NULL) {
28667836SJohn.Forte@Sun.COM 		scf_handle_destroy(handle);
28677836SJohn.Forte@Sun.COM 	}
28687836SJohn.Forte@Sun.COM 	if (svc != NULL) {
28697836SJohn.Forte@Sun.COM 		scf_service_destroy(svc);
28707836SJohn.Forte@Sun.COM 	}
28717836SJohn.Forte@Sun.COM 
28727836SJohn.Forte@Sun.COM 	return (ret);
28737836SJohn.Forte@Sun.COM }
28747836SJohn.Forte@Sun.COM 
28757836SJohn.Forte@Sun.COM /*
28767836SJohn.Forte@Sun.COM  * psCreateHostGroup
28777836SJohn.Forte@Sun.COM  *
28787836SJohn.Forte@Sun.COM  * groupName - name of group to create
28797836SJohn.Forte@Sun.COM  *
28807836SJohn.Forte@Sun.COM  * returns:
28817836SJohn.Forte@Sun.COM  *  STMF_PS_SUCCESS on success
28827836SJohn.Forte@Sun.COM  *  STMF_PS_ERROR_* on failure
28837836SJohn.Forte@Sun.COM  */
28847836SJohn.Forte@Sun.COM int
28857836SJohn.Forte@Sun.COM psCreateHostGroup(char *groupName)
28867836SJohn.Forte@Sun.COM {
28877836SJohn.Forte@Sun.COM 	return (iPsCreateDeleteGroup(STMF_HOST_GROUPS, groupName, ADD));
28887836SJohn.Forte@Sun.COM }
28897836SJohn.Forte@Sun.COM 
28907836SJohn.Forte@Sun.COM /*
28917836SJohn.Forte@Sun.COM  * psCreateTargetGroup
28927836SJohn.Forte@Sun.COM  *
28937836SJohn.Forte@Sun.COM  * groupName - name of group to create
28947836SJohn.Forte@Sun.COM  *
28957836SJohn.Forte@Sun.COM  * returns:
28967836SJohn.Forte@Sun.COM  *  STMF_PS_SUCCESS on success
28977836SJohn.Forte@Sun.COM  *  STMF_PS_ERROR_* on failure
28987836SJohn.Forte@Sun.COM  */
28997836SJohn.Forte@Sun.COM int
29007836SJohn.Forte@Sun.COM psCreateTargetGroup(char *groupName)
29017836SJohn.Forte@Sun.COM {
29027836SJohn.Forte@Sun.COM 	return (iPsCreateDeleteGroup(STMF_TARGET_GROUPS, groupName, ADD));
29037836SJohn.Forte@Sun.COM }
29047836SJohn.Forte@Sun.COM 
29057836SJohn.Forte@Sun.COM /*
29067836SJohn.Forte@Sun.COM  * psDeleteHostGroup
29077836SJohn.Forte@Sun.COM  *
29087836SJohn.Forte@Sun.COM  * groupName - name of group to delete
29097836SJohn.Forte@Sun.COM  *
29107836SJohn.Forte@Sun.COM  * returns:
29117836SJohn.Forte@Sun.COM  *  STMF_PS_SUCCESS on success
29127836SJohn.Forte@Sun.COM  *  STMF_PS_ERROR_* on failure
29137836SJohn.Forte@Sun.COM  */
29147836SJohn.Forte@Sun.COM int
29157836SJohn.Forte@Sun.COM psDeleteHostGroup(char *groupName)
29167836SJohn.Forte@Sun.COM {
29177836SJohn.Forte@Sun.COM 	return (iPsCreateDeleteGroup(STMF_HOST_GROUPS, groupName, REMOVE));
29187836SJohn.Forte@Sun.COM }
29197836SJohn.Forte@Sun.COM 
29207836SJohn.Forte@Sun.COM /*
29217836SJohn.Forte@Sun.COM  * psDeleteTargetGroup
29227836SJohn.Forte@Sun.COM  *
29237836SJohn.Forte@Sun.COM  * groupName - name of group to delete
29247836SJohn.Forte@Sun.COM  *
29257836SJohn.Forte@Sun.COM  * returns:
29267836SJohn.Forte@Sun.COM  *  STMF_PS_SUCCESS on success
29277836SJohn.Forte@Sun.COM  *  STMF_PS_ERROR_* on failure
29287836SJohn.Forte@Sun.COM  */
29297836SJohn.Forte@Sun.COM int
29307836SJohn.Forte@Sun.COM psDeleteTargetGroup(char *groupName)
29317836SJohn.Forte@Sun.COM {
29327836SJohn.Forte@Sun.COM 	return (iPsCreateDeleteGroup(STMF_TARGET_GROUPS, groupName,
29337836SJohn.Forte@Sun.COM 	    REMOVE));
29347836SJohn.Forte@Sun.COM }
29357836SJohn.Forte@Sun.COM 
29367836SJohn.Forte@Sun.COM /*
29377836SJohn.Forte@Sun.COM  * psGetHostGroupList
29387836SJohn.Forte@Sun.COM  *
29397836SJohn.Forte@Sun.COM  * groupList - pointer to pointer to stmfGroupList. Contains the list
29407836SJohn.Forte@Sun.COM  *             of host groups on successful return.
29417836SJohn.Forte@Sun.COM  *
29427836SJohn.Forte@Sun.COM  * returns:
29437836SJohn.Forte@Sun.COM  *  STMF_PS_SUCCESS on success
29447836SJohn.Forte@Sun.COM  *  STMF_PS_ERROR_* on failure
29457836SJohn.Forte@Sun.COM  */
29467836SJohn.Forte@Sun.COM int
29477836SJohn.Forte@Sun.COM psGetHostGroupList(stmfGroupList **groupList)
29487836SJohn.Forte@Sun.COM {
29497836SJohn.Forte@Sun.COM 	return (iPsGetGroupList(STMF_HOST_GROUPS, groupList));
29507836SJohn.Forte@Sun.COM }
29517836SJohn.Forte@Sun.COM 
29527836SJohn.Forte@Sun.COM /*
29537836SJohn.Forte@Sun.COM  * psGetLogicalUnitList
29547836SJohn.Forte@Sun.COM  *
29557836SJohn.Forte@Sun.COM  *
29567836SJohn.Forte@Sun.COM  */
29577836SJohn.Forte@Sun.COM int
29587836SJohn.Forte@Sun.COM psGetLogicalUnitList(stmfGuidList **guidList)
29597836SJohn.Forte@Sun.COM {
29607836SJohn.Forte@Sun.COM 	scf_handle_t	*handle = NULL;
29617836SJohn.Forte@Sun.COM 	scf_service_t	*svc = NULL;
29627836SJohn.Forte@Sun.COM 	scf_propertygroup_t	*pg = NULL;
29637836SJohn.Forte@Sun.COM 	scf_iter_t	*pgIter = NULL;
29647836SJohn.Forte@Sun.COM 	char buf[MAXNAMELEN];
29657836SJohn.Forte@Sun.COM 	int guidCnt = 0;
29667836SJohn.Forte@Sun.COM 	int i = 0, j;
29677836SJohn.Forte@Sun.COM 	int ret = STMF_PS_SUCCESS;
29687836SJohn.Forte@Sun.COM 	unsigned int guid[sizeof (stmfGuid)];
29697836SJohn.Forte@Sun.COM 	stmfGuid outGuid;
29707836SJohn.Forte@Sun.COM 
29717836SJohn.Forte@Sun.COM 	assert(guidList != NULL);
29727836SJohn.Forte@Sun.COM 
29737836SJohn.Forte@Sun.COM 	ret = iPsInit(&handle, &svc);
29747836SJohn.Forte@Sun.COM 	if (ret != STMF_PS_SUCCESS) {
29757836SJohn.Forte@Sun.COM 		goto out;
29767836SJohn.Forte@Sun.COM 	}
29777836SJohn.Forte@Sun.COM 
29787836SJohn.Forte@Sun.COM 	/*
29797836SJohn.Forte@Sun.COM 	 * Allocate scf resources
29807836SJohn.Forte@Sun.COM 	 */
29817836SJohn.Forte@Sun.COM 	if (((pg = scf_pg_create(handle)) == NULL) ||
29827836SJohn.Forte@Sun.COM 	    ((pgIter = scf_iter_create(handle)) == NULL)) {
29837836SJohn.Forte@Sun.COM 		syslog(LOG_ERR, "scf alloc resource failed - %s",
29847836SJohn.Forte@Sun.COM 		    scf_strerror(scf_error()));
29857836SJohn.Forte@Sun.COM 		ret = STMF_PS_ERROR;
29867836SJohn.Forte@Sun.COM 		goto out;
29877836SJohn.Forte@Sun.COM 	}
29887836SJohn.Forte@Sun.COM 
29897836SJohn.Forte@Sun.COM 	/*
29907836SJohn.Forte@Sun.COM 	 * pgIter is the iterator handle
29917836SJohn.Forte@Sun.COM 	 */
29927836SJohn.Forte@Sun.COM 	if (scf_iter_service_pgs(pgIter, svc) == -1) {
29937836SJohn.Forte@Sun.COM 		syslog(LOG_ERR, "iter property groups failed - %s",
29947836SJohn.Forte@Sun.COM 		    scf_strerror(scf_error()));
29957836SJohn.Forte@Sun.COM 		ret = STMF_PS_ERROR;
29967836SJohn.Forte@Sun.COM 		goto out;
29977836SJohn.Forte@Sun.COM 	}
29987836SJohn.Forte@Sun.COM 
29997836SJohn.Forte@Sun.COM 	while (scf_iter_next_pg(pgIter, pg) == 1) {
30007836SJohn.Forte@Sun.COM 		if (scf_pg_get_name(pg, buf, sizeof (buf)) == -1) {
3001*11909SPeter.Gill@Sun.COM 			syslog(LOG_ERR, "get pg name failed - %s",
30027836SJohn.Forte@Sun.COM 			    scf_strerror(scf_error()));
30037836SJohn.Forte@Sun.COM 			ret = STMF_PS_ERROR;
30047836SJohn.Forte@Sun.COM 			break;
30057836SJohn.Forte@Sun.COM 		}
30067836SJohn.Forte@Sun.COM 		/*
30077836SJohn.Forte@Sun.COM 		 * Only count LU property groups
30087836SJohn.Forte@Sun.COM 		 */
30097836SJohn.Forte@Sun.COM 		if (strncmp(buf, STMF_LU_PREFIX, strlen(STMF_LU_PREFIX)) == 0) {
30107836SJohn.Forte@Sun.COM 			guidCnt++;
30117836SJohn.Forte@Sun.COM 		}
30127836SJohn.Forte@Sun.COM 	}
30137836SJohn.Forte@Sun.COM 
30147836SJohn.Forte@Sun.COM 	/*
30157836SJohn.Forte@Sun.COM 	 * pgIter is the iterator handle
30167836SJohn.Forte@Sun.COM 	 */
30177836SJohn.Forte@Sun.COM 	if (scf_iter_service_pgs(pgIter, svc) == -1) {
30187836SJohn.Forte@Sun.COM 		syslog(LOG_ERR, "iter property groups failed - %s",
30197836SJohn.Forte@Sun.COM 		    scf_strerror(scf_error()));
30207836SJohn.Forte@Sun.COM 		ret = STMF_PS_ERROR;
30217836SJohn.Forte@Sun.COM 		goto out;
30227836SJohn.Forte@Sun.COM 	}
30237836SJohn.Forte@Sun.COM 
30247836SJohn.Forte@Sun.COM 	*guidList = (stmfGuidList *)calloc(1, sizeof (stmfGuidList) +
30257836SJohn.Forte@Sun.COM 	    guidCnt * sizeof (stmfGuid));
30267836SJohn.Forte@Sun.COM 	if (*guidList == NULL) {
30277836SJohn.Forte@Sun.COM 		ret = STMF_PS_ERROR_NOMEM;
30287836SJohn.Forte@Sun.COM 		goto out;
30297836SJohn.Forte@Sun.COM 	}
30307836SJohn.Forte@Sun.COM 
30317836SJohn.Forte@Sun.COM 	/*
30327836SJohn.Forte@Sun.COM 	 * it's possible for entries to be added/removed while we're retrieving
30337836SJohn.Forte@Sun.COM 	 * the property groups. Just make sure we don't write beyond our
30347836SJohn.Forte@Sun.COM 	 * allocated buffer by checking to ensure i < guidCnt.
30357836SJohn.Forte@Sun.COM 	 */
30367836SJohn.Forte@Sun.COM 	while ((scf_iter_next_pg(pgIter, pg) == 1) && (i < guidCnt)) {
30377836SJohn.Forte@Sun.COM 		if (scf_pg_get_name(pg, buf, sizeof (buf)) == -1) {
3038*11909SPeter.Gill@Sun.COM 			syslog(LOG_ERR, "get pg name failed - %s",
30397836SJohn.Forte@Sun.COM 			    scf_strerror(scf_error()));
30407836SJohn.Forte@Sun.COM 			ret = STMF_PS_ERROR;
30417836SJohn.Forte@Sun.COM 			break;
30427836SJohn.Forte@Sun.COM 		}
30437836SJohn.Forte@Sun.COM 		/*
30447836SJohn.Forte@Sun.COM 		 * Only use LU property groups
30457836SJohn.Forte@Sun.COM 		 */
30467836SJohn.Forte@Sun.COM 		if (strncmp(buf, STMF_LU_PREFIX, strlen(STMF_LU_PREFIX)) != 0) {
30477836SJohn.Forte@Sun.COM 			continue;
30487836SJohn.Forte@Sun.COM 		}
30497836SJohn.Forte@Sun.COM 
30507836SJohn.Forte@Sun.COM 		j = strlen(STMF_LU_PREFIX) + strlen("-");
30517836SJohn.Forte@Sun.COM 
30527836SJohn.Forte@Sun.COM 		(void) sscanf(buf + j,
30537836SJohn.Forte@Sun.COM 		    "%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x",
30547836SJohn.Forte@Sun.COM 		    &guid[0], &guid[1], &guid[2], &guid[3], &guid[4], &guid[5],
30557836SJohn.Forte@Sun.COM 		    &guid[6], &guid[7], &guid[8], &guid[9], &guid[10],
30567836SJohn.Forte@Sun.COM 		    &guid[11], &guid[12], &guid[13], &guid[14], &guid[15]);
30577836SJohn.Forte@Sun.COM 
30587836SJohn.Forte@Sun.COM 		for (j = 0; j < sizeof (stmfGuid); j++) {
30597836SJohn.Forte@Sun.COM 			outGuid.guid[j] = guid[j];
30607836SJohn.Forte@Sun.COM 		}
30617836SJohn.Forte@Sun.COM 
30627836SJohn.Forte@Sun.COM 		bcopy(&outGuid, (*guidList)->guid[i++].guid, sizeof (stmfGuid));
30637836SJohn.Forte@Sun.COM 		(*guidList)->cnt++;
30647836SJohn.Forte@Sun.COM 	}
30657836SJohn.Forte@Sun.COM 
30667836SJohn.Forte@Sun.COM 	if (ret != STMF_PS_SUCCESS) {
30677836SJohn.Forte@Sun.COM 		free(*guidList);
30687836SJohn.Forte@Sun.COM 		goto out;
30697836SJohn.Forte@Sun.COM 	}
30707836SJohn.Forte@Sun.COM 
30717836SJohn.Forte@Sun.COM out:
30727836SJohn.Forte@Sun.COM 	/*
30737836SJohn.Forte@Sun.COM 	 * Free resources
30747836SJohn.Forte@Sun.COM 	 */
30757836SJohn.Forte@Sun.COM 	if (handle != NULL) {
30767836SJohn.Forte@Sun.COM 		scf_handle_destroy(handle);
30777836SJohn.Forte@Sun.COM 	}
30787836SJohn.Forte@Sun.COM 	if (svc != NULL) {
30797836SJohn.Forte@Sun.COM 		scf_service_destroy(svc);
30807836SJohn.Forte@Sun.COM 	}
30817836SJohn.Forte@Sun.COM 	if (pg != NULL) {
30827836SJohn.Forte@Sun.COM 		scf_pg_destroy(pg);
30837836SJohn.Forte@Sun.COM 	}
30847836SJohn.Forte@Sun.COM 	if (pgIter != NULL) {
30857836SJohn.Forte@Sun.COM 		scf_iter_destroy(pgIter);
30867836SJohn.Forte@Sun.COM 	}
30877836SJohn.Forte@Sun.COM 
30887836SJohn.Forte@Sun.COM 	return (ret);
30897836SJohn.Forte@Sun.COM }
30907836SJohn.Forte@Sun.COM 
30917836SJohn.Forte@Sun.COM /*
30927836SJohn.Forte@Sun.COM  * psGetTargetGroupList
30937836SJohn.Forte@Sun.COM  *
30947836SJohn.Forte@Sun.COM  * groupList - pointer to pointer to stmfGroupList. Contains the list
30957836SJohn.Forte@Sun.COM  *             of target groups on successful return.
30967836SJohn.Forte@Sun.COM  *
30977836SJohn.Forte@Sun.COM  * returns:
30987836SJohn.Forte@Sun.COM  *  STMF_PS_SUCCESS on success
30997836SJohn.Forte@Sun.COM  *  STMF_PS_ERROR_* on failure
31007836SJohn.Forte@Sun.COM  */
31017836SJohn.Forte@Sun.COM int
31027836SJohn.Forte@Sun.COM psGetTargetGroupList(stmfGroupList **groupList)
31037836SJohn.Forte@Sun.COM {
31047836SJohn.Forte@Sun.COM 	return (iPsGetGroupList(STMF_TARGET_GROUPS, groupList));
31057836SJohn.Forte@Sun.COM }
31067836SJohn.Forte@Sun.COM 
31077836SJohn.Forte@Sun.COM /*
31087836SJohn.Forte@Sun.COM  * psGetHostGroupMemberList
31097836SJohn.Forte@Sun.COM  *
31107836SJohn.Forte@Sun.COM  * groupName - group name for which to retrieve a member list
31117836SJohn.Forte@Sun.COM  * groupMemberList - pointer to pointer to stmfGroupProperties list
31127836SJohn.Forte@Sun.COM  *
31137836SJohn.Forte@Sun.COM  * returns:
31147836SJohn.Forte@Sun.COM  *  STMF_PS_SUCCESS on success
31157836SJohn.Forte@Sun.COM  *  STMF_PS_ERROR_* on failure
31167836SJohn.Forte@Sun.COM  */
31177836SJohn.Forte@Sun.COM int
31187836SJohn.Forte@Sun.COM psGetHostGroupMemberList(char *groupName, stmfGroupProperties **groupMemberList)
31197836SJohn.Forte@Sun.COM {
31207836SJohn.Forte@Sun.COM 	int ret;
31217836SJohn.Forte@Sun.COM 	char groupPropListName[MAXNAMELEN];
31227836SJohn.Forte@Sun.COM 	char groupPropName[MAXNAMELEN];
31237836SJohn.Forte@Sun.COM 
31247836SJohn.Forte@Sun.COM 	ret = iPsGetActualGroupName(STMF_HOST_GROUPS, groupName,
31257836SJohn.Forte@Sun.COM 	    groupPropName);
31267836SJohn.Forte@Sun.COM 	if (ret != STMF_PS_SUCCESS) {
31277836SJohn.Forte@Sun.COM 		return (ret);
31287836SJohn.Forte@Sun.COM 	}
31297836SJohn.Forte@Sun.COM 
31307836SJohn.Forte@Sun.COM 	if (snprintf(groupPropListName, sizeof (groupPropListName),
31317836SJohn.Forte@Sun.COM 	    "%s-%s", groupPropName, STMF_MEMBER_LIST_SUFFIX) >
31327836SJohn.Forte@Sun.COM 	    sizeof (groupPropListName)) {
31337836SJohn.Forte@Sun.COM 		syslog(LOG_ERR, "buffer overflow on property name %s",
31347836SJohn.Forte@Sun.COM 		    groupPropName);
31357836SJohn.Forte@Sun.COM 		return (STMF_PS_ERROR);
31367836SJohn.Forte@Sun.COM 	}
31377836SJohn.Forte@Sun.COM 
31387836SJohn.Forte@Sun.COM 	return (iPsGetGroupMemberList(STMF_HOST_GROUPS, groupPropListName,
31397836SJohn.Forte@Sun.COM 	    groupMemberList));
31407836SJohn.Forte@Sun.COM }
31417836SJohn.Forte@Sun.COM 
31427836SJohn.Forte@Sun.COM /*
31437836SJohn.Forte@Sun.COM  * psGetTargetGroupMemberList
31447836SJohn.Forte@Sun.COM  *
31457836SJohn.Forte@Sun.COM  * groupName - group name for which to retrieve a member list
31467836SJohn.Forte@Sun.COM  * groupMemberList - pointer to pointer to stmfGroupProperties list
31477836SJohn.Forte@Sun.COM  *
31487836SJohn.Forte@Sun.COM  * returns:
31497836SJohn.Forte@Sun.COM  *  STMF_PS_SUCCESS on success
31507836SJohn.Forte@Sun.COM  *  STMF_PS_ERROR_* on failure
31517836SJohn.Forte@Sun.COM  */
31527836SJohn.Forte@Sun.COM int
31537836SJohn.Forte@Sun.COM psGetTargetGroupMemberList(char *groupName,
31547836SJohn.Forte@Sun.COM     stmfGroupProperties **groupMemberList)
31557836SJohn.Forte@Sun.COM {
31567836SJohn.Forte@Sun.COM 	int ret;
31577836SJohn.Forte@Sun.COM 	char groupPropListName[MAXNAMELEN];
31587836SJohn.Forte@Sun.COM 	char groupPropName[MAXNAMELEN];
31597836SJohn.Forte@Sun.COM 
31607836SJohn.Forte@Sun.COM 	ret = iPsGetActualGroupName(STMF_TARGET_GROUPS, groupName,
31617836SJohn.Forte@Sun.COM 	    groupPropName);
31627836SJohn.Forte@Sun.COM 	if (ret != STMF_PS_SUCCESS) {
31637836SJohn.Forte@Sun.COM 		return (ret);
31647836SJohn.Forte@Sun.COM 	}
31657836SJohn.Forte@Sun.COM 
31667836SJohn.Forte@Sun.COM 	if (snprintf(groupPropListName, sizeof (groupPropListName),
31677836SJohn.Forte@Sun.COM 	    "%s-%s", groupPropName, STMF_MEMBER_LIST_SUFFIX) >
31687836SJohn.Forte@Sun.COM 	    sizeof (groupPropListName)) {
31697836SJohn.Forte@Sun.COM 		syslog(LOG_ERR, "buffer overflow on property name %s",
31707836SJohn.Forte@Sun.COM 		    groupPropName);
31717836SJohn.Forte@Sun.COM 		return (STMF_PS_ERROR);
31727836SJohn.Forte@Sun.COM 	}
31737836SJohn.Forte@Sun.COM 
31747836SJohn.Forte@Sun.COM 	return (iPsGetGroupMemberList(STMF_TARGET_GROUPS,
31757836SJohn.Forte@Sun.COM 	    groupPropListName, groupMemberList));
31767836SJohn.Forte@Sun.COM }
31777836SJohn.Forte@Sun.COM 
31787836SJohn.Forte@Sun.COM /*
31797836SJohn.Forte@Sun.COM  * qsort function
31807836SJohn.Forte@Sun.COM  * sort on veIndex
31817836SJohn.Forte@Sun.COM  */
31827836SJohn.Forte@Sun.COM static int
31837836SJohn.Forte@Sun.COM viewEntryCompare(const void *p1, const void *p2)
31847836SJohn.Forte@Sun.COM {
31857836SJohn.Forte@Sun.COM 
31867836SJohn.Forte@Sun.COM 	stmfViewEntry *v1 = (stmfViewEntry *)p1, *v2 = (stmfViewEntry *)p2;
31877836SJohn.Forte@Sun.COM 	if (v1->veIndex > v2->veIndex)
31887836SJohn.Forte@Sun.COM 		return (1);
31897836SJohn.Forte@Sun.COM 	if (v1->veIndex < v2->veIndex)
31907836SJohn.Forte@Sun.COM 		return (-1);
31917836SJohn.Forte@Sun.COM 	return (0);
31927836SJohn.Forte@Sun.COM }
31937836SJohn.Forte@Sun.COM 
31947836SJohn.Forte@Sun.COM /*
31957836SJohn.Forte@Sun.COM  * psGetViewEntryList
31967836SJohn.Forte@Sun.COM  *
31977836SJohn.Forte@Sun.COM  * luGuid - identifier of logical unit for which to retrieve a view entry list
31987836SJohn.Forte@Sun.COM  * viewEntryList - pointer to pointer to stmfViewEntryList. It will be allocated
31997836SJohn.Forte@Sun.COM  *                 on successful return.
32007836SJohn.Forte@Sun.COM  *
32017836SJohn.Forte@Sun.COM  * returns:
32027836SJohn.Forte@Sun.COM  *  STMF_PS_SUCCESS on success
32037836SJohn.Forte@Sun.COM  *  STMF_PS_ERROR_* on failure
32047836SJohn.Forte@Sun.COM  */
32057836SJohn.Forte@Sun.COM int
32067836SJohn.Forte@Sun.COM psGetViewEntryList(stmfGuid *lu, stmfViewEntryList **viewEntryList)
32077836SJohn.Forte@Sun.COM {
32087836SJohn.Forte@Sun.COM 	scf_handle_t	*handle = NULL;
32097836SJohn.Forte@Sun.COM 	scf_service_t	*svc = NULL;
32107836SJohn.Forte@Sun.COM 	scf_propertygroup_t	*pg = NULL;
32117836SJohn.Forte@Sun.COM 	scf_property_t	*prop = NULL;
32127836SJohn.Forte@Sun.COM 	scf_value_t *value = NULL;
32137836SJohn.Forte@Sun.COM 	scf_iter_t  *propIter = NULL;
32147836SJohn.Forte@Sun.COM 	char guidAsciiBuf[33]; /* size of ascii hex 16 byte guid with NULL */
32157836SJohn.Forte@Sun.COM 	char viewEntryPgName[VIEW_ENTRY_PG_SIZE];
32167836SJohn.Forte@Sun.COM 	char luPgName[LOGICAL_UNIT_PG_SIZE];
32177836SJohn.Forte@Sun.COM 	int ret = STMF_PS_SUCCESS;
32187836SJohn.Forte@Sun.COM 	uint64_t i = 0;
32197836SJohn.Forte@Sun.COM 	uint64_t veCnt;
32207836SJohn.Forte@Sun.COM 
32217836SJohn.Forte@Sun.COM 
32227836SJohn.Forte@Sun.COM 	ret = iPsInit(&handle, &svc);
32237836SJohn.Forte@Sun.COM 	if (ret != STMF_PS_SUCCESS) {
32247836SJohn.Forte@Sun.COM 		goto out;
32257836SJohn.Forte@Sun.COM 	}
32267836SJohn.Forte@Sun.COM 
32277836SJohn.Forte@Sun.COM 	/*
32287836SJohn.Forte@Sun.COM 	 * Allocate scf resources
32297836SJohn.Forte@Sun.COM 	 */
32307836SJohn.Forte@Sun.COM 	if (((pg = scf_pg_create(handle)) == NULL) ||
32317836SJohn.Forte@Sun.COM 	    ((prop = scf_property_create(handle)) == NULL) ||
32327836SJohn.Forte@Sun.COM 	    ((propIter = scf_iter_create(handle)) == NULL) ||
32337836SJohn.Forte@Sun.COM 	    ((value = scf_value_create(handle)) == NULL)) {
32347836SJohn.Forte@Sun.COM 		syslog(LOG_ERR, "scf alloc resource failed - %s",
32357836SJohn.Forte@Sun.COM 		    scf_strerror(scf_error()));
32367836SJohn.Forte@Sun.COM 		ret = STMF_PS_ERROR;
32377836SJohn.Forte@Sun.COM 		goto out;
32387836SJohn.Forte@Sun.COM 	}
32397836SJohn.Forte@Sun.COM 
32407836SJohn.Forte@Sun.COM 	/* Convert to ASCII uppercase hexadecimal string */
32417836SJohn.Forte@Sun.COM 	(void) snprintf(guidAsciiBuf, sizeof (guidAsciiBuf),
32427836SJohn.Forte@Sun.COM 	    "%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X",
32437836SJohn.Forte@Sun.COM 	    lu->guid[0], lu->guid[1], lu->guid[2], lu->guid[3], lu->guid[4],
32447836SJohn.Forte@Sun.COM 	    lu->guid[5], lu->guid[6], lu->guid[7], lu->guid[8], lu->guid[9],
32457836SJohn.Forte@Sun.COM 	    lu->guid[10], lu->guid[11], lu->guid[12], lu->guid[13],
32467836SJohn.Forte@Sun.COM 	    lu->guid[14], lu->guid[15]);
32477836SJohn.Forte@Sun.COM 
32487836SJohn.Forte@Sun.COM 	/* form the LU property group name (LU-<guid>) */
32497836SJohn.Forte@Sun.COM 	(void) snprintf(luPgName, sizeof (luPgName), "%s-%s",
32507836SJohn.Forte@Sun.COM 	    STMF_LU_PREFIX, guidAsciiBuf);
32517836SJohn.Forte@Sun.COM 
32527836SJohn.Forte@Sun.COM 	/* get the property group associated with this LU */
32537836SJohn.Forte@Sun.COM 	if (scf_service_get_pg(svc, luPgName, pg) == -1) {
32547836SJohn.Forte@Sun.COM 		if (scf_error() == SCF_ERROR_NOT_FOUND) {
32557836SJohn.Forte@Sun.COM 			ret = STMF_PS_ERROR_NOT_FOUND;
32567836SJohn.Forte@Sun.COM 		} else {
3257*11909SPeter.Gill@Sun.COM 			syslog(LOG_ERR, "get pg %s failed - %s",
3258*11909SPeter.Gill@Sun.COM 			    luPgName, scf_strerror(scf_error()));
32597836SJohn.Forte@Sun.COM 			ret = STMF_PS_ERROR;
32607836SJohn.Forte@Sun.COM 		}
32617836SJohn.Forte@Sun.COM 		goto out;
32627836SJohn.Forte@Sun.COM 	}
32637836SJohn.Forte@Sun.COM 
32647836SJohn.Forte@Sun.COM 	/* get the view entry count property */
32657836SJohn.Forte@Sun.COM 	if (scf_pg_get_property(pg, STMF_VE_CNT, prop) == -1) {
3266*11909SPeter.Gill@Sun.COM 		syslog(LOG_ERR, "get property %s/%s failed - %s",
3267*11909SPeter.Gill@Sun.COM 		    luPgName, STMF_VE_CNT, scf_strerror(scf_error()));
32687836SJohn.Forte@Sun.COM 		ret = STMF_PS_ERROR;
32697836SJohn.Forte@Sun.COM 		goto out;
32707836SJohn.Forte@Sun.COM 	}
32717836SJohn.Forte@Sun.COM 
32727836SJohn.Forte@Sun.COM 	if (scf_property_get_value(prop, value) == -1) {
3273*11909SPeter.Gill@Sun.COM 		syslog(LOG_ERR, "get property value %s/%s failed - %s",
3274*11909SPeter.Gill@Sun.COM 		    luPgName, STMF_VE_CNT, scf_strerror(scf_error()));
32757836SJohn.Forte@Sun.COM 		ret = STMF_PS_ERROR;
32767836SJohn.Forte@Sun.COM 		goto out;
32777836SJohn.Forte@Sun.COM 	}
32787836SJohn.Forte@Sun.COM 
32797836SJohn.Forte@Sun.COM 	/*
32807836SJohn.Forte@Sun.COM 	 * Get the actual value of the view entry count property
32817836SJohn.Forte@Sun.COM 	 */
32827836SJohn.Forte@Sun.COM 	if (scf_value_get_count(value, &veCnt) == -1) {
3283*11909SPeter.Gill@Sun.COM 		syslog(LOG_ERR, "get integer value %s/%s failed - %s",
3284*11909SPeter.Gill@Sun.COM 		    luPgName, STMF_VE_CNT, scf_strerror(scf_error()));
32857836SJohn.Forte@Sun.COM 		ret = STMF_PS_ERROR;
32867836SJohn.Forte@Sun.COM 		goto out;
32877836SJohn.Forte@Sun.COM 	}
32887836SJohn.Forte@Sun.COM 
32897836SJohn.Forte@Sun.COM 	/*
32907836SJohn.Forte@Sun.COM 	 * propIter is the iterator handle
32917836SJohn.Forte@Sun.COM 	 */
32927836SJohn.Forte@Sun.COM 	if (scf_iter_pg_properties(propIter, pg) == -1) {
3293*11909SPeter.Gill@Sun.COM 		syslog(LOG_ERR, "iter properties for %s failed - %s",
3294*11909SPeter.Gill@Sun.COM 		    luPgName, scf_strerror(scf_error()));
32957836SJohn.Forte@Sun.COM 		ret = STMF_PS_ERROR;
32967836SJohn.Forte@Sun.COM 		goto out;
32977836SJohn.Forte@Sun.COM 	}
32987836SJohn.Forte@Sun.COM 
32997836SJohn.Forte@Sun.COM 	/*
33007836SJohn.Forte@Sun.COM 	 * alloc the list based on the view entry count
33017836SJohn.Forte@Sun.COM 	 */
33027836SJohn.Forte@Sun.COM 	*viewEntryList = (stmfViewEntryList *)calloc(1,
33037836SJohn.Forte@Sun.COM 	    sizeof (stmfViewEntryList) + veCnt * sizeof (stmfViewEntry));
33047836SJohn.Forte@Sun.COM 	if (*viewEntryList == NULL) {
33057836SJohn.Forte@Sun.COM 		ret = STMF_PS_ERROR_NOMEM;
33067836SJohn.Forte@Sun.COM 		goto out;
33077836SJohn.Forte@Sun.COM 	}
33087836SJohn.Forte@Sun.COM 
33097836SJohn.Forte@Sun.COM 	i = 0;
33107836SJohn.Forte@Sun.COM 	/*
33117836SJohn.Forte@Sun.COM 	 * iterate through the view entry properties to find the
33127836SJohn.Forte@Sun.COM 	 * view entries
33137836SJohn.Forte@Sun.COM 	 */
33147836SJohn.Forte@Sun.COM 	while (scf_iter_next_property(propIter, prop) == 1) {
33157836SJohn.Forte@Sun.COM 		/* find match for view entry property */
33167836SJohn.Forte@Sun.COM 		if (scf_property_get_name(prop, viewEntryPgName,
33177836SJohn.Forte@Sun.COM 		    sizeof (viewEntryPgName)) != -1) {
33187836SJohn.Forte@Sun.COM 			if (strncmp(viewEntryPgName, STMF_VE_PREFIX,
33197836SJohn.Forte@Sun.COM 			    strlen(STMF_VE_PREFIX)) != 0) {
33207836SJohn.Forte@Sun.COM 				continue;
33217836SJohn.Forte@Sun.COM 			}
33227836SJohn.Forte@Sun.COM 			/*
33237836SJohn.Forte@Sun.COM 			 * We've exceeded our alloc limit
33247836SJohn.Forte@Sun.COM 			 * break with error
33257836SJohn.Forte@Sun.COM 			 */
33267836SJohn.Forte@Sun.COM 			if (i == veCnt) {
33277836SJohn.Forte@Sun.COM 				ret = STMF_PS_ERROR;
33287836SJohn.Forte@Sun.COM 				break;
33297836SJohn.Forte@Sun.COM 			}
33307836SJohn.Forte@Sun.COM 
33317836SJohn.Forte@Sun.COM 			if ((ret = iPsGetViewEntry(viewEntryPgName,
33327836SJohn.Forte@Sun.COM 			    &((*viewEntryList)->ve[i]))) != STMF_PS_SUCCESS) {
33337836SJohn.Forte@Sun.COM 				break;
33347836SJohn.Forte@Sun.COM 			}
33357836SJohn.Forte@Sun.COM 
33367836SJohn.Forte@Sun.COM 			i++;
33377836SJohn.Forte@Sun.COM 
33387836SJohn.Forte@Sun.COM 			/* set the list count */
33397836SJohn.Forte@Sun.COM 			(*viewEntryList)->cnt++;
33407836SJohn.Forte@Sun.COM 		} else {
3341*11909SPeter.Gill@Sun.COM 			syslog(LOG_ERR, "scf iter %s properties failed - %s",
3342*11909SPeter.Gill@Sun.COM 			    luPgName, scf_strerror(scf_error()));
33437836SJohn.Forte@Sun.COM 			ret = STMF_PS_ERROR;
33447836SJohn.Forte@Sun.COM 			break;
33457836SJohn.Forte@Sun.COM 		}
33467836SJohn.Forte@Sun.COM 
33477836SJohn.Forte@Sun.COM 	}
33487836SJohn.Forte@Sun.COM 
33497836SJohn.Forte@Sun.COM 	if (ret != STMF_PS_SUCCESS) {
33507836SJohn.Forte@Sun.COM 		free(*viewEntryList);
33517836SJohn.Forte@Sun.COM 		goto out;
33527836SJohn.Forte@Sun.COM 	}
33537836SJohn.Forte@Sun.COM 
33547836SJohn.Forte@Sun.COM 	/*
33557836SJohn.Forte@Sun.COM 	 * We're sorting the final list here based on the veIndex
33567836SJohn.Forte@Sun.COM 	 * If we don't, the caller is going to have to do it to reap
33577836SJohn.Forte@Sun.COM 	 * some intelligent output.
33587836SJohn.Forte@Sun.COM 	 */
33597836SJohn.Forte@Sun.COM 	qsort((void *)&((*viewEntryList)->ve[0]), (*viewEntryList)->cnt,
33607836SJohn.Forte@Sun.COM 	    sizeof (stmfViewEntry), viewEntryCompare);
33617836SJohn.Forte@Sun.COM 
33627836SJohn.Forte@Sun.COM out:
33637836SJohn.Forte@Sun.COM 	/*
33647836SJohn.Forte@Sun.COM 	 * Free resources
33657836SJohn.Forte@Sun.COM 	 */
33667836SJohn.Forte@Sun.COM 	if (handle != NULL) {
33677836SJohn.Forte@Sun.COM 		scf_handle_destroy(handle);
33687836SJohn.Forte@Sun.COM 	}
33697836SJohn.Forte@Sun.COM 	if (svc != NULL) {
33707836SJohn.Forte@Sun.COM 		scf_service_destroy(svc);
33717836SJohn.Forte@Sun.COM 	}
33727836SJohn.Forte@Sun.COM 	if (pg != NULL) {
33737836SJohn.Forte@Sun.COM 		scf_pg_destroy(pg);
33747836SJohn.Forte@Sun.COM 	}
33757836SJohn.Forte@Sun.COM 	if (prop != NULL) {
33767836SJohn.Forte@Sun.COM 		scf_property_destroy(prop);
33777836SJohn.Forte@Sun.COM 	}
33787836SJohn.Forte@Sun.COM 	if (value != NULL) {
33797836SJohn.Forte@Sun.COM 		scf_value_destroy(value);
33807836SJohn.Forte@Sun.COM 	}
33817836SJohn.Forte@Sun.COM 	if (propIter != NULL) {
33827836SJohn.Forte@Sun.COM 		scf_iter_destroy(propIter);
33837836SJohn.Forte@Sun.COM 	}
33847836SJohn.Forte@Sun.COM 
33857836SJohn.Forte@Sun.COM 	return (ret);
33867836SJohn.Forte@Sun.COM }
33877836SJohn.Forte@Sun.COM 
33887836SJohn.Forte@Sun.COM /*
33897836SJohn.Forte@Sun.COM  * iPsGetViewEntry
33907836SJohn.Forte@Sun.COM  *
33917836SJohn.Forte@Sun.COM  * viewEntryPgName - view entry property group name to retrieve
33927836SJohn.Forte@Sun.COM  * viewEntry - pointer to stmfViewEntry structure allocated by the caller
33937836SJohn.Forte@Sun.COM  *
33947836SJohn.Forte@Sun.COM  * returns:
33957836SJohn.Forte@Sun.COM  *  STMF_PS_SUCCESS on success
33967836SJohn.Forte@Sun.COM  *  STMF_PS_ERROR_* on failure
33977836SJohn.Forte@Sun.COM  */
33987836SJohn.Forte@Sun.COM static int
33997836SJohn.Forte@Sun.COM iPsGetViewEntry(char *viewEntryPgName, stmfViewEntry *viewEntry)
34007836SJohn.Forte@Sun.COM {
34017836SJohn.Forte@Sun.COM 	scf_handle_t	*handle = NULL;
34027836SJohn.Forte@Sun.COM 	scf_service_t	*svc = NULL;
34037836SJohn.Forte@Sun.COM 	scf_propertygroup_t	*pg = NULL;
34047836SJohn.Forte@Sun.COM 	scf_property_t	*prop = NULL;
34057836SJohn.Forte@Sun.COM 	scf_value_t *value = NULL;
34067836SJohn.Forte@Sun.COM 	uint8_t scfBool;
34077836SJohn.Forte@Sun.COM 	char *indexPtr;
34087836SJohn.Forte@Sun.COM 	char groupName[sizeof (stmfGroupName)];
34097836SJohn.Forte@Sun.COM 	int ret = STMF_PS_SUCCESS;
34107836SJohn.Forte@Sun.COM 
34117836SJohn.Forte@Sun.COM 
34127836SJohn.Forte@Sun.COM 	ret = iPsInit(&handle, &svc);
34137836SJohn.Forte@Sun.COM 	if (ret != STMF_PS_SUCCESS) {
34147836SJohn.Forte@Sun.COM 		goto out;
34157836SJohn.Forte@Sun.COM 	}
34167836SJohn.Forte@Sun.COM 
34177836SJohn.Forte@Sun.COM 	/*
34187836SJohn.Forte@Sun.COM 	 * Allocate scf resources
34197836SJohn.Forte@Sun.COM 	 */
34207836SJohn.Forte@Sun.COM 	if (((pg = scf_pg_create(handle)) == NULL) ||
34217836SJohn.Forte@Sun.COM 	    ((prop = scf_property_create(handle)) == NULL) ||
34227836SJohn.Forte@Sun.COM 	    ((value = scf_value_create(handle)) == NULL)) {
34237836SJohn.Forte@Sun.COM 		syslog(LOG_ERR, "scf alloc resource failed - %s",
34247836SJohn.Forte@Sun.COM 		    scf_strerror(scf_error()));
34257836SJohn.Forte@Sun.COM 		ret = STMF_PS_ERROR;
34267836SJohn.Forte@Sun.COM 		goto out;
34277836SJohn.Forte@Sun.COM 	}
34287836SJohn.Forte@Sun.COM 
34297836SJohn.Forte@Sun.COM 	bzero(viewEntry, sizeof (stmfViewEntry));
34307836SJohn.Forte@Sun.COM 
34317836SJohn.Forte@Sun.COM 	/*
34327836SJohn.Forte@Sun.COM 	 * get the service property group view entry handle
34337836SJohn.Forte@Sun.COM 	 */
34347836SJohn.Forte@Sun.COM 	if (scf_service_get_pg(svc, viewEntryPgName, pg) == -1) {
34357836SJohn.Forte@Sun.COM 		if (scf_error() == SCF_ERROR_NOT_FOUND) {
34367836SJohn.Forte@Sun.COM 			ret = STMF_PS_ERROR_NOT_FOUND;
34377836SJohn.Forte@Sun.COM 		} else {
3438*11909SPeter.Gill@Sun.COM 			syslog(LOG_ERR, "get pg %s failed - %s",
3439*11909SPeter.Gill@Sun.COM 			    viewEntryPgName, scf_strerror(scf_error()));
34407836SJohn.Forte@Sun.COM 			ret = STMF_PS_ERROR;
34417836SJohn.Forte@Sun.COM 		}
34427836SJohn.Forte@Sun.COM 		goto out;
34437836SJohn.Forte@Sun.COM 	}
34447836SJohn.Forte@Sun.COM 
34457836SJohn.Forte@Sun.COM 
34467836SJohn.Forte@Sun.COM 	/*
34477836SJohn.Forte@Sun.COM 	 * get index
34487836SJohn.Forte@Sun.COM 	 * format is: VE-<veIndex>-GUID
34497836SJohn.Forte@Sun.COM 	 */
34507836SJohn.Forte@Sun.COM 	indexPtr = strchr(viewEntryPgName, '-');
34517836SJohn.Forte@Sun.COM 	if (!indexPtr) {
34527836SJohn.Forte@Sun.COM 		ret = STMF_PS_ERROR;
34537836SJohn.Forte@Sun.COM 		goto out;
34547836SJohn.Forte@Sun.COM 	}
34557836SJohn.Forte@Sun.COM 
34567836SJohn.Forte@Sun.COM 	/* Set the index */
34577836SJohn.Forte@Sun.COM 	viewEntry->veIndex = atoi(strtok(++indexPtr, "-"));
34587836SJohn.Forte@Sun.COM 
34597836SJohn.Forte@Sun.COM 	viewEntry->veIndexValid = B_TRUE;
34607836SJohn.Forte@Sun.COM 
34617836SJohn.Forte@Sun.COM 	/* get allHosts property */
34627836SJohn.Forte@Sun.COM 	if (scf_pg_get_property(pg, STMF_VE_ALLHOSTS,
34637836SJohn.Forte@Sun.COM 	    prop) == -1) {
3464*11909SPeter.Gill@Sun.COM 		syslog(LOG_ERR, "get property %s/%s failed - %s",
3465*11909SPeter.Gill@Sun.COM 		    viewEntryPgName, STMF_VE_ALLHOSTS,
34667836SJohn.Forte@Sun.COM 		    scf_strerror(scf_error()));
34677836SJohn.Forte@Sun.COM 		ret = STMF_PS_ERROR;
34687836SJohn.Forte@Sun.COM 		goto out;
34697836SJohn.Forte@Sun.COM 	}
34707836SJohn.Forte@Sun.COM 
34717836SJohn.Forte@Sun.COM 	if (scf_property_get_value(prop, value) == -1) {
3472*11909SPeter.Gill@Sun.COM 		syslog(LOG_ERR, "get property %s/%s failed - %s",
3473*11909SPeter.Gill@Sun.COM 		    viewEntryPgName, STMF_VE_ALLHOSTS,
34747836SJohn.Forte@Sun.COM 		    scf_strerror(scf_error()));
34757836SJohn.Forte@Sun.COM 		ret = STMF_PS_ERROR;
34767836SJohn.Forte@Sun.COM 		goto out;
34777836SJohn.Forte@Sun.COM 	}
34787836SJohn.Forte@Sun.COM 
34797836SJohn.Forte@Sun.COM 	/* set allHosts */
34807836SJohn.Forte@Sun.COM 	if (scf_value_get_boolean(value, (uint8_t *)&scfBool) == -1) {
3481*11909SPeter.Gill@Sun.COM 		syslog(LOG_ERR, "get property %s/%s failed - %s",
3482*11909SPeter.Gill@Sun.COM 		    viewEntryPgName, STMF_VE_ALLHOSTS,
34837836SJohn.Forte@Sun.COM 		    scf_strerror(scf_error()));
34847836SJohn.Forte@Sun.COM 		ret = STMF_PS_ERROR;
34857836SJohn.Forte@Sun.COM 		goto out;
34867836SJohn.Forte@Sun.COM 	}
34877836SJohn.Forte@Sun.COM 	viewEntry->allHosts = scfBool;
34887836SJohn.Forte@Sun.COM 
34897836SJohn.Forte@Sun.COM 	/* get hostGroup property */
34907836SJohn.Forte@Sun.COM 	if (scf_pg_get_property(pg, STMF_VE_HOSTGROUP,
34917836SJohn.Forte@Sun.COM 	    prop) == -1) {
3492*11909SPeter.Gill@Sun.COM 		syslog(LOG_ERR, "get property %s/%s failed - %s",
3493*11909SPeter.Gill@Sun.COM 		    viewEntryPgName, STMF_VE_HOSTGROUP,
34947836SJohn.Forte@Sun.COM 		    scf_strerror(scf_error()));
34957836SJohn.Forte@Sun.COM 		ret = STMF_PS_ERROR;
34967836SJohn.Forte@Sun.COM 		goto out;
34977836SJohn.Forte@Sun.COM 	}
34987836SJohn.Forte@Sun.COM 
34997836SJohn.Forte@Sun.COM 	if (scf_property_get_value(prop, value) == -1) {
3500*11909SPeter.Gill@Sun.COM 		syslog(LOG_ERR, "get property %s/%s failed - %s",
3501*11909SPeter.Gill@Sun.COM 		    viewEntryPgName, STMF_VE_HOSTGROUP,
35027836SJohn.Forte@Sun.COM 		    scf_strerror(scf_error()));
35037836SJohn.Forte@Sun.COM 		ret = STMF_PS_ERROR;
35047836SJohn.Forte@Sun.COM 		goto out;
35057836SJohn.Forte@Sun.COM 	}
35067836SJohn.Forte@Sun.COM 
35077836SJohn.Forte@Sun.COM 	if (scf_value_get_ustring(value, groupName,
35087836SJohn.Forte@Sun.COM 	    sizeof (groupName)) == -1) {
3509*11909SPeter.Gill@Sun.COM 		syslog(LOG_ERR, "get value %s/%s failed - %s",
3510*11909SPeter.Gill@Sun.COM 		    viewEntryPgName, STMF_VE_HOSTGROUP,
35117836SJohn.Forte@Sun.COM 		    scf_strerror(scf_error()));
35127836SJohn.Forte@Sun.COM 		ret = STMF_PS_ERROR;
35137836SJohn.Forte@Sun.COM 		goto out;
35147836SJohn.Forte@Sun.COM 	}
35157836SJohn.Forte@Sun.COM 	/* set hostGroup */
35167836SJohn.Forte@Sun.COM 	bcopy(groupName, viewEntry->hostGroup, strlen(groupName));
35177836SJohn.Forte@Sun.COM 
35187836SJohn.Forte@Sun.COM 	/* get allTargets property */
35197836SJohn.Forte@Sun.COM 	if (scf_pg_get_property(pg, STMF_VE_ALLTARGETS,
35207836SJohn.Forte@Sun.COM 	    prop) == -1) {
3521*11909SPeter.Gill@Sun.COM 		syslog(LOG_ERR, "get property %s/%s failed - %s",
3522*11909SPeter.Gill@Sun.COM 		    viewEntryPgName, STMF_VE_ALLTARGETS,
35237836SJohn.Forte@Sun.COM 		    scf_strerror(scf_error()));
35247836SJohn.Forte@Sun.COM 		ret = STMF_PS_ERROR;
35257836SJohn.Forte@Sun.COM 		goto out;
35267836SJohn.Forte@Sun.COM 	}
35277836SJohn.Forte@Sun.COM 
35287836SJohn.Forte@Sun.COM 	if (scf_property_get_value(prop, value) == -1) {
3529*11909SPeter.Gill@Sun.COM 		syslog(LOG_ERR, "get property value %s/%s failed - %s",
3530*11909SPeter.Gill@Sun.COM 		    viewEntryPgName, STMF_VE_ALLTARGETS,
35317836SJohn.Forte@Sun.COM 		    scf_strerror(scf_error()));
35327836SJohn.Forte@Sun.COM 		ret = STMF_PS_ERROR;
35337836SJohn.Forte@Sun.COM 		goto out;
35347836SJohn.Forte@Sun.COM 	}
35357836SJohn.Forte@Sun.COM 
35367836SJohn.Forte@Sun.COM 	/* set allTargets */
35377836SJohn.Forte@Sun.COM 	if (scf_value_get_boolean(value, (uint8_t *)&scfBool) == -1) {
3538*11909SPeter.Gill@Sun.COM 		syslog(LOG_ERR, "get value %s/%s failed - %s",
3539*11909SPeter.Gill@Sun.COM 		    viewEntryPgName, STMF_VE_ALLTARGETS,
35407836SJohn.Forte@Sun.COM 		    scf_strerror(scf_error()));
35417836SJohn.Forte@Sun.COM 		ret = STMF_PS_ERROR;
35427836SJohn.Forte@Sun.COM 		goto out;
35437836SJohn.Forte@Sun.COM 	}
35447836SJohn.Forte@Sun.COM 	viewEntry->allTargets = scfBool;
35457836SJohn.Forte@Sun.COM 
35467836SJohn.Forte@Sun.COM 	/* get targetGroup property */
35477836SJohn.Forte@Sun.COM 	if (scf_pg_get_property(pg, STMF_VE_TARGETGROUP, prop) == -1) {
3548*11909SPeter.Gill@Sun.COM 		syslog(LOG_ERR, "get property %s/%s failed - %s",
3549*11909SPeter.Gill@Sun.COM 		    viewEntryPgName, STMF_VE_TARGETGROUP,
35507836SJohn.Forte@Sun.COM 		    scf_strerror(scf_error()));
35517836SJohn.Forte@Sun.COM 		ret = STMF_PS_ERROR;
35527836SJohn.Forte@Sun.COM 		goto out;
35537836SJohn.Forte@Sun.COM 	}
35547836SJohn.Forte@Sun.COM 
35557836SJohn.Forte@Sun.COM 	if (scf_property_get_value(prop, value) == -1) {
3556*11909SPeter.Gill@Sun.COM 		syslog(LOG_ERR, "get property value %s/%s failed - %s",
3557*11909SPeter.Gill@Sun.COM 		    viewEntryPgName, STMF_VE_TARGETGROUP,
35587836SJohn.Forte@Sun.COM 		    scf_strerror(scf_error()));
35597836SJohn.Forte@Sun.COM 		ret = STMF_PS_ERROR;
35607836SJohn.Forte@Sun.COM 		goto out;
35617836SJohn.Forte@Sun.COM 	}
35627836SJohn.Forte@Sun.COM 
35637836SJohn.Forte@Sun.COM 	if (scf_value_get_ustring(value, groupName,
35647836SJohn.Forte@Sun.COM 	    sizeof (groupName)) == -1) {
3565*11909SPeter.Gill@Sun.COM 		syslog(LOG_ERR, "get value %s/%s failed - %s",
3566*11909SPeter.Gill@Sun.COM 		    viewEntryPgName, STMF_VE_TARGETGROUP,
35677836SJohn.Forte@Sun.COM 		    scf_strerror(scf_error()));
35687836SJohn.Forte@Sun.COM 		ret = STMF_PS_ERROR;
35697836SJohn.Forte@Sun.COM 		goto out;
35707836SJohn.Forte@Sun.COM 	}
35717836SJohn.Forte@Sun.COM 	/* set targetGroup */
35727836SJohn.Forte@Sun.COM 	bcopy(groupName, viewEntry->targetGroup, strlen(groupName));
35737836SJohn.Forte@Sun.COM 
35747836SJohn.Forte@Sun.COM 	/* get luNbr property */
35757836SJohn.Forte@Sun.COM 	if (scf_pg_get_property(pg, STMF_VE_LUNBR,
35767836SJohn.Forte@Sun.COM 	    prop) == -1) {
3577*11909SPeter.Gill@Sun.COM 		syslog(LOG_ERR, "get property %s/%s failed - %s",
3578*11909SPeter.Gill@Sun.COM 		    viewEntryPgName, STMF_VE_LUNBR,
35797836SJohn.Forte@Sun.COM 		    scf_strerror(scf_error()));
35807836SJohn.Forte@Sun.COM 		ret = STMF_PS_ERROR;
35817836SJohn.Forte@Sun.COM 		goto out;
35827836SJohn.Forte@Sun.COM 	}
35837836SJohn.Forte@Sun.COM 
35847836SJohn.Forte@Sun.COM 	if (scf_property_get_value(prop, value) == -1) {
3585*11909SPeter.Gill@Sun.COM 		syslog(LOG_ERR, "get property value %s/%s failed - %s",
3586*11909SPeter.Gill@Sun.COM 		    viewEntryPgName, STMF_VE_LUNBR,
35877836SJohn.Forte@Sun.COM 		    scf_strerror(scf_error()));
35887836SJohn.Forte@Sun.COM 		ret = STMF_PS_ERROR;
35897836SJohn.Forte@Sun.COM 		goto out;
35907836SJohn.Forte@Sun.COM 	}
35917836SJohn.Forte@Sun.COM 
35927836SJohn.Forte@Sun.COM 	/* set luNbr */
35937836SJohn.Forte@Sun.COM 	if (scf_value_get_opaque(value, (char *)viewEntry->luNbr,
35947836SJohn.Forte@Sun.COM 	    sizeof (viewEntry->luNbr)) == -1) {
3595*11909SPeter.Gill@Sun.COM 		syslog(LOG_ERR, "get opaque value %s/%s failed - %s",
3596*11909SPeter.Gill@Sun.COM 		    viewEntryPgName, STMF_VE_LUNBR,
35977836SJohn.Forte@Sun.COM 		    scf_strerror(scf_error()));
35987836SJohn.Forte@Sun.COM 		ret = STMF_PS_ERROR;
35997836SJohn.Forte@Sun.COM 		goto out;
36007836SJohn.Forte@Sun.COM 	}
36017836SJohn.Forte@Sun.COM 	/* set luNbrValid to true since we just got it */
36027836SJohn.Forte@Sun.COM 	viewEntry->luNbrValid = B_TRUE;
36037836SJohn.Forte@Sun.COM 
36047836SJohn.Forte@Sun.COM out:
36057836SJohn.Forte@Sun.COM 	/*
36067836SJohn.Forte@Sun.COM 	 * Free resources
36077836SJohn.Forte@Sun.COM 	 */
36087836SJohn.Forte@Sun.COM 	if (handle != NULL) {
36097836SJohn.Forte@Sun.COM 		scf_handle_destroy(handle);
36107836SJohn.Forte@Sun.COM 	}
36117836SJohn.Forte@Sun.COM 	if (svc != NULL) {
36127836SJohn.Forte@Sun.COM 		scf_service_destroy(svc);
36137836SJohn.Forte@Sun.COM 	}
36147836SJohn.Forte@Sun.COM 	if (pg != NULL) {
36157836SJohn.Forte@Sun.COM 		scf_pg_destroy(pg);
36167836SJohn.Forte@Sun.COM 	}
36177836SJohn.Forte@Sun.COM 	if (value != NULL) {
36187836SJohn.Forte@Sun.COM 		scf_value_destroy(value);
36197836SJohn.Forte@Sun.COM 	}
36207836SJohn.Forte@Sun.COM 	if (prop != NULL) {
36217836SJohn.Forte@Sun.COM 		scf_property_destroy(prop);
36227836SJohn.Forte@Sun.COM 	}
36237836SJohn.Forte@Sun.COM 
36247836SJohn.Forte@Sun.COM 	return (ret);
36257836SJohn.Forte@Sun.COM }
36267836SJohn.Forte@Sun.COM 
36277836SJohn.Forte@Sun.COM 
36287836SJohn.Forte@Sun.COM /*
36297836SJohn.Forte@Sun.COM  * psRemoveHostGroupMember
36307836SJohn.Forte@Sun.COM  *
36317836SJohn.Forte@Sun.COM  * Remove a host group member from a host group,
36327836SJohn.Forte@Sun.COM  *
36337836SJohn.Forte@Sun.COM  * groupName - name of group from which the member is removed
36347836SJohn.Forte@Sun.COM  * memberName - name of group member to remove
36357836SJohn.Forte@Sun.COM  *
36367836SJohn.Forte@Sun.COM  * returns:
36377836SJohn.Forte@Sun.COM  *  STMF_PS_SUCCESS on success
36387836SJohn.Forte@Sun.COM  *  STMF_PS_ERROR_* on failure
36397836SJohn.Forte@Sun.COM  */
36407836SJohn.Forte@Sun.COM int
36417836SJohn.Forte@Sun.COM psRemoveHostGroupMember(char *groupName, char *memberName)
36427836SJohn.Forte@Sun.COM {
36437836SJohn.Forte@Sun.COM 	int ret;
36447836SJohn.Forte@Sun.COM 	char groupPropListName[MAXNAMELEN];
36457836SJohn.Forte@Sun.COM 	char groupPropName[MAXNAMELEN];
36467836SJohn.Forte@Sun.COM 
36477836SJohn.Forte@Sun.COM 	ret = iPsGetActualGroupName(STMF_HOST_GROUPS, groupName,
36487836SJohn.Forte@Sun.COM 	    groupPropName);
36497836SJohn.Forte@Sun.COM 	if (ret != STMF_PS_SUCCESS) {
36507836SJohn.Forte@Sun.COM 		return (ret);
36517836SJohn.Forte@Sun.COM 	}
36527836SJohn.Forte@Sun.COM 
36537836SJohn.Forte@Sun.COM 	if (snprintf(groupPropListName, sizeof (groupPropListName),
36547836SJohn.Forte@Sun.COM 	    "%s-%s", groupPropName, STMF_MEMBER_LIST_SUFFIX) >
36557836SJohn.Forte@Sun.COM 	    sizeof (groupPropListName)) {
36567836SJohn.Forte@Sun.COM 		syslog(LOG_ERR, "buffer overflow on property name %s",
36577836SJohn.Forte@Sun.COM 		    groupPropName);
36587836SJohn.Forte@Sun.COM 		return (STMF_PS_ERROR);
36597836SJohn.Forte@Sun.COM 	}
36607836SJohn.Forte@Sun.COM 
36617836SJohn.Forte@Sun.COM 	return (iPsAddRemoveGroupMember(STMF_HOST_GROUPS, groupPropListName,
36627836SJohn.Forte@Sun.COM 	    memberName, REMOVE));
36637836SJohn.Forte@Sun.COM }
36647836SJohn.Forte@Sun.COM 
36657836SJohn.Forte@Sun.COM /*
36667836SJohn.Forte@Sun.COM  * psRemoveTargetGroupMember
36677836SJohn.Forte@Sun.COM  *
36687836SJohn.Forte@Sun.COM  * Remove a target port group member from an target port group,
36697836SJohn.Forte@Sun.COM  *
36707836SJohn.Forte@Sun.COM  * groupName - name of group from which the member is removed
36717836SJohn.Forte@Sun.COM  * memberName - name of group member to remove
36727836SJohn.Forte@Sun.COM  *
36737836SJohn.Forte@Sun.COM  * returns:
36747836SJohn.Forte@Sun.COM  *  STMF_PS_SUCCESS on success
36757836SJohn.Forte@Sun.COM  *  STMF_PS_ERROR_* on failure
36767836SJohn.Forte@Sun.COM  */
36777836SJohn.Forte@Sun.COM int
36787836SJohn.Forte@Sun.COM psRemoveTargetGroupMember(char *groupName, char *memberName)
36797836SJohn.Forte@Sun.COM {
36807836SJohn.Forte@Sun.COM 	int ret;
36817836SJohn.Forte@Sun.COM 	char groupPropListName[MAXNAMELEN];
36827836SJohn.Forte@Sun.COM 	char groupPropName[MAXNAMELEN];
36837836SJohn.Forte@Sun.COM 
36847836SJohn.Forte@Sun.COM 	ret = iPsGetActualGroupName(STMF_TARGET_GROUPS, groupName,
36857836SJohn.Forte@Sun.COM 	    groupPropName);
36867836SJohn.Forte@Sun.COM 	if (ret != STMF_PS_SUCCESS) {
36877836SJohn.Forte@Sun.COM 		return (ret);
36887836SJohn.Forte@Sun.COM 	}
36897836SJohn.Forte@Sun.COM 
36907836SJohn.Forte@Sun.COM 	if (snprintf(groupPropListName, sizeof (groupPropListName),
36917836SJohn.Forte@Sun.COM 	    "%s-%s", groupPropName, STMF_MEMBER_LIST_SUFFIX) >
36927836SJohn.Forte@Sun.COM 	    sizeof (groupPropListName)) {
36937836SJohn.Forte@Sun.COM 		syslog(LOG_ERR, "buffer overflow on property name %s",
36947836SJohn.Forte@Sun.COM 		    groupPropName);
36957836SJohn.Forte@Sun.COM 		return (STMF_PS_ERROR);
36967836SJohn.Forte@Sun.COM 	}
36977836SJohn.Forte@Sun.COM 
36987836SJohn.Forte@Sun.COM 	return (iPsAddRemoveGroupMember(STMF_TARGET_GROUPS, groupPropListName,
36997836SJohn.Forte@Sun.COM 	    memberName, REMOVE));
37007836SJohn.Forte@Sun.COM }
37017836SJohn.Forte@Sun.COM 
37027836SJohn.Forte@Sun.COM /*
37037836SJohn.Forte@Sun.COM  * psGetProviderData
37047836SJohn.Forte@Sun.COM  *
37057836SJohn.Forte@Sun.COM  * Retrieves an nvlist on a per provider basis
37067836SJohn.Forte@Sun.COM  *
37077836SJohn.Forte@Sun.COM  * providerName - property group name to use
37087836SJohn.Forte@Sun.COM  * nvl - nvlist to retrieve
37097836SJohn.Forte@Sun.COM  *
37107836SJohn.Forte@Sun.COM  */
37117836SJohn.Forte@Sun.COM int
37127836SJohn.Forte@Sun.COM psGetProviderData(char *providerName, nvlist_t **nvl, int providerType,
37137836SJohn.Forte@Sun.COM     uint64_t *setToken)
37147836SJohn.Forte@Sun.COM {
37157836SJohn.Forte@Sun.COM 	scf_handle_t	*handle = NULL;
37167836SJohn.Forte@Sun.COM 	scf_service_t	*svc = NULL;
37177836SJohn.Forte@Sun.COM 	scf_propertygroup_t	*pg = NULL;
37187836SJohn.Forte@Sun.COM 	scf_property_t	*prop = NULL;
37197836SJohn.Forte@Sun.COM 	scf_value_t	*value = NULL;
37207836SJohn.Forte@Sun.COM 	uint64_t blockCnt = 0;
37217836SJohn.Forte@Sun.COM 	ssize_t blockOffset = 0;
37227836SJohn.Forte@Sun.COM 	ssize_t actualBlockSize = 0;
37237836SJohn.Forte@Sun.COM 	char pgName[MAXPATHLEN];
37247836SJohn.Forte@Sun.COM 	char dataPropertyName[STMF_PROVIDER_DATA_PROP_NAME_SIZE];
37257836SJohn.Forte@Sun.COM 	char *nvlistEncoded = NULL;
37267836SJohn.Forte@Sun.COM 	ssize_t nvlistEncodedSize = 0;
37277836SJohn.Forte@Sun.COM 	boolean_t foundSetCnt = B_TRUE;
37287836SJohn.Forte@Sun.COM 	int i;
37297836SJohn.Forte@Sun.COM 	int ret = STMF_PS_SUCCESS;
37307836SJohn.Forte@Sun.COM 
37317836SJohn.Forte@Sun.COM 	if (providerName == NULL || (providerType != STMF_LU_PROVIDER_TYPE &&
37327836SJohn.Forte@Sun.COM 	    providerType != STMF_PORT_PROVIDER_TYPE)) {
37337836SJohn.Forte@Sun.COM 		ret = STMF_PS_ERROR_INVALID_ARG;
37347836SJohn.Forte@Sun.COM 		goto out;
37357836SJohn.Forte@Sun.COM 	}
37367836SJohn.Forte@Sun.COM 
37377836SJohn.Forte@Sun.COM 	ret = iPsInit(&handle, &svc);
37387836SJohn.Forte@Sun.COM 	if (ret != STMF_PS_SUCCESS) {
37397836SJohn.Forte@Sun.COM 		goto out;
37407836SJohn.Forte@Sun.COM 	}
37417836SJohn.Forte@Sun.COM 
37427836SJohn.Forte@Sun.COM 	/*
37437836SJohn.Forte@Sun.COM 	 * create the property group name
37447836SJohn.Forte@Sun.COM 	 */
37457836SJohn.Forte@Sun.COM 	(void) snprintf(pgName, sizeof (pgName), "%s%s",
37467836SJohn.Forte@Sun.COM 	    STMF_PROVIDER_DATA_PREFIX, providerName);
37477836SJohn.Forte@Sun.COM 
37487836SJohn.Forte@Sun.COM 	/*
37497836SJohn.Forte@Sun.COM 	 * Allocate scf resources
37507836SJohn.Forte@Sun.COM 	 */
37517836SJohn.Forte@Sun.COM 	if (((pg = scf_pg_create(handle)) == NULL) ||
37527836SJohn.Forte@Sun.COM 	    ((value = scf_value_create(handle)) == NULL) ||
37537836SJohn.Forte@Sun.COM 	    ((prop = scf_property_create(handle)) == NULL)) {
37547836SJohn.Forte@Sun.COM 		syslog(LOG_ERR, "scf alloc resource failed - %s",
37557836SJohn.Forte@Sun.COM 		    scf_strerror(scf_error()));
37567836SJohn.Forte@Sun.COM 		ret = STMF_PS_ERROR;
37577836SJohn.Forte@Sun.COM 		goto out;
37587836SJohn.Forte@Sun.COM 	}
37597836SJohn.Forte@Sun.COM 
37607836SJohn.Forte@Sun.COM 	/*
37617836SJohn.Forte@Sun.COM 	 * Retrieve the existing property group.
37627836SJohn.Forte@Sun.COM 	 */
37637836SJohn.Forte@Sun.COM 	if (scf_service_get_pg(svc, pgName, pg) == -1) {
37647836SJohn.Forte@Sun.COM 		if (scf_error() != SCF_ERROR_NOT_FOUND) {
3765*11909SPeter.Gill@Sun.COM 			syslog(LOG_ERR, "get pg %s failed - %s", pgName,
37667836SJohn.Forte@Sun.COM 			    scf_strerror(scf_error()));
37677836SJohn.Forte@Sun.COM 			ret = STMF_PS_ERROR;
37687836SJohn.Forte@Sun.COM 			goto out;
37697836SJohn.Forte@Sun.COM 		} else {
37707836SJohn.Forte@Sun.COM 			ret = STMF_PS_ERROR_NOT_FOUND;
37717836SJohn.Forte@Sun.COM 			goto out;
37727836SJohn.Forte@Sun.COM 		}
37737836SJohn.Forte@Sun.COM 	}
37747836SJohn.Forte@Sun.COM 
37757836SJohn.Forte@Sun.COM 	/*
37767836SJohn.Forte@Sun.COM 	 * Get the STMF_PROVIDER_DATA_PROP_COUNT property
37777836SJohn.Forte@Sun.COM 	 */
37787836SJohn.Forte@Sun.COM 	if (scf_pg_get_property(pg, STMF_PROVIDER_DATA_PROP_COUNT,
37797836SJohn.Forte@Sun.COM 	    prop) == -1) {
3780*11909SPeter.Gill@Sun.COM 		syslog(LOG_ERR, "get property %s/%s failed - %s",
3781*11909SPeter.Gill@Sun.COM 		    pgName, STMF_PROVIDER_DATA_PROP_COUNT,
37827836SJohn.Forte@Sun.COM 		    scf_strerror(scf_error()));
37837836SJohn.Forte@Sun.COM 		ret = STMF_PS_ERROR;
37847836SJohn.Forte@Sun.COM 		goto out;
37857836SJohn.Forte@Sun.COM 	}
37867836SJohn.Forte@Sun.COM 
37877836SJohn.Forte@Sun.COM 	/*
37887836SJohn.Forte@Sun.COM 	 * Get the STMF_PROVIDER_DATA_PROP_COUNT value
37897836SJohn.Forte@Sun.COM 	 */
37907836SJohn.Forte@Sun.COM 	if (scf_property_get_value(prop, value) == -1) {
3791*11909SPeter.Gill@Sun.COM 		syslog(LOG_ERR, "get property value %s/%s failed - %s",
3792*11909SPeter.Gill@Sun.COM 		    pgName, STMF_PROVIDER_DATA_PROP_COUNT,
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 
37987836SJohn.Forte@Sun.COM 	/*
37997836SJohn.Forte@Sun.COM 	 * Now get the actual value from the value handle
38007836SJohn.Forte@Sun.COM 	 */
38017836SJohn.Forte@Sun.COM 	if (scf_value_get_count(value, &blockCnt) == -1) {
3802*11909SPeter.Gill@Sun.COM 		syslog(LOG_ERR, "get integer value %s/%s failed - %s",
3803*11909SPeter.Gill@Sun.COM 		    pgName, STMF_PROVIDER_DATA_PROP_COUNT,
38047836SJohn.Forte@Sun.COM 		    scf_strerror(scf_error()));
38057836SJohn.Forte@Sun.COM 		ret = STMF_PS_ERROR;
38067836SJohn.Forte@Sun.COM 		goto out;
38077836SJohn.Forte@Sun.COM 	}
38087836SJohn.Forte@Sun.COM 
38097836SJohn.Forte@Sun.COM 	/* Has the caller requested the token to be set? */
38107836SJohn.Forte@Sun.COM 	if (setToken) {
38117836SJohn.Forte@Sun.COM 		/*
38127836SJohn.Forte@Sun.COM 		 * Get the STMF_PROVIDER_DATA_PROP_SET_COUNT property
38137836SJohn.Forte@Sun.COM 		 * If it doesn't exist, we assume it to be zero.
38147836SJohn.Forte@Sun.COM 		 */
38157836SJohn.Forte@Sun.COM 		*setToken = 0;
38167836SJohn.Forte@Sun.COM 		if (scf_pg_get_property(pg, STMF_PROVIDER_DATA_PROP_SET_COUNT,
38177836SJohn.Forte@Sun.COM 		    prop) == -1) {
38187836SJohn.Forte@Sun.COM 			if (scf_error() == SCF_ERROR_NOT_FOUND) {
38197836SJohn.Forte@Sun.COM 				foundSetCnt = B_FALSE;
38207836SJohn.Forte@Sun.COM 			} else {
3821*11909SPeter.Gill@Sun.COM 				syslog(LOG_ERR, "get property %s/%s "
3822*11909SPeter.Gill@Sun.COM 				    "failed - %s", pgName,
3823*11909SPeter.Gill@Sun.COM 				    STMF_PROVIDER_DATA_PROP_SET_COUNT,
38247836SJohn.Forte@Sun.COM 				    scf_strerror(scf_error()));
38257836SJohn.Forte@Sun.COM 				ret = STMF_PS_ERROR;
38267836SJohn.Forte@Sun.COM 				goto out;
38277836SJohn.Forte@Sun.COM 			}
38287836SJohn.Forte@Sun.COM 		}
38297836SJohn.Forte@Sun.COM 
38307836SJohn.Forte@Sun.COM 		if (foundSetCnt) {
38317836SJohn.Forte@Sun.COM 			/*
38327836SJohn.Forte@Sun.COM 			 * Get the STMF_PROVIDER_DATA_PROP_SET_COUNT value
38337836SJohn.Forte@Sun.COM 			 */
38347836SJohn.Forte@Sun.COM 			if (scf_property_get_value(prop, value) == -1) {
38357836SJohn.Forte@Sun.COM 				syslog(LOG_ERR,
3836*11909SPeter.Gill@Sun.COM 				    "get property value %s/%s failed - %s",
3837*11909SPeter.Gill@Sun.COM 				    pgName, STMF_PROVIDER_DATA_PROP_SET_COUNT,
38387836SJohn.Forte@Sun.COM 				    scf_strerror(scf_error()));
38397836SJohn.Forte@Sun.COM 				ret = STMF_PS_ERROR;
38407836SJohn.Forte@Sun.COM 				goto out;
38417836SJohn.Forte@Sun.COM 			}
38427836SJohn.Forte@Sun.COM 
38437836SJohn.Forte@Sun.COM 			/*
38447836SJohn.Forte@Sun.COM 			 * Now get the actual value from the value handle
38457836SJohn.Forte@Sun.COM 			 * and set the caller's token
38467836SJohn.Forte@Sun.COM 			 */
38477836SJohn.Forte@Sun.COM 			if (scf_value_get_count(value, setToken) == -1) {
38487836SJohn.Forte@Sun.COM 				syslog(LOG_ERR,
3849*11909SPeter.Gill@Sun.COM 				    "get integer value %s/%s failed - %s",
3850*11909SPeter.Gill@Sun.COM 				    pgName, STMF_PROVIDER_DATA_PROP_SET_COUNT,
38517836SJohn.Forte@Sun.COM 				    scf_strerror(scf_error()));
38527836SJohn.Forte@Sun.COM 				ret = STMF_PS_ERROR;
38537836SJohn.Forte@Sun.COM 				goto out;
38547836SJohn.Forte@Sun.COM 			}
38557836SJohn.Forte@Sun.COM 		}
38567836SJohn.Forte@Sun.COM 	}
38577836SJohn.Forte@Sun.COM 
38587836SJohn.Forte@Sun.COM 	nvlistEncoded = (char *)calloc(1,
38597836SJohn.Forte@Sun.COM 	    blockCnt * STMF_PROVIDER_DATA_PROP_SIZE);
38607836SJohn.Forte@Sun.COM 	if (nvlistEncoded == NULL) {
38617836SJohn.Forte@Sun.COM 		syslog(LOG_ERR, "nvlistEncoded alloc failed");
38627836SJohn.Forte@Sun.COM 		ret = STMF_PS_ERROR_NOMEM;
38637836SJohn.Forte@Sun.COM 		goto out;
38647836SJohn.Forte@Sun.COM 	}
38657836SJohn.Forte@Sun.COM 
38667836SJohn.Forte@Sun.COM 	for (i = 0; i < blockCnt; i++) {
38677836SJohn.Forte@Sun.COM 		bzero(dataPropertyName, sizeof (dataPropertyName));
38687836SJohn.Forte@Sun.COM 		/*
38697836SJohn.Forte@Sun.COM 		 * create the name to use for the property
38707836SJohn.Forte@Sun.COM 		 */
38717836SJohn.Forte@Sun.COM 		(void) snprintf(dataPropertyName, sizeof (dataPropertyName),
38727836SJohn.Forte@Sun.COM 		    "%s-%d", STMF_PROVIDER_DATA_PROP_PREFIX, i);
38737836SJohn.Forte@Sun.COM 
38747836SJohn.Forte@Sun.COM 		if (scf_pg_get_property(pg, dataPropertyName, prop) == -1) {
3875*11909SPeter.Gill@Sun.COM 			syslog(LOG_ERR, "get property %s/%s failed - %s",
3876*11909SPeter.Gill@Sun.COM 			    pgName, dataPropertyName,
38777836SJohn.Forte@Sun.COM 			    scf_strerror(scf_error()));
38787836SJohn.Forte@Sun.COM 			ret = STMF_PS_ERROR;
38797836SJohn.Forte@Sun.COM 			goto out;
38807836SJohn.Forte@Sun.COM 		}
38817836SJohn.Forte@Sun.COM 
38827836SJohn.Forte@Sun.COM 		if (scf_property_get_value(prop, value) == -1) {
3883*11909SPeter.Gill@Sun.COM 			syslog(LOG_ERR, "get property value %s/%s failed - %s",
3884*11909SPeter.Gill@Sun.COM 			    pgName, dataPropertyName,
38857836SJohn.Forte@Sun.COM 			    scf_strerror(scf_error()));
38867836SJohn.Forte@Sun.COM 			ret = STMF_PS_ERROR;
38877836SJohn.Forte@Sun.COM 			goto out;
38887836SJohn.Forte@Sun.COM 		}
38897836SJohn.Forte@Sun.COM 
38907836SJohn.Forte@Sun.COM 		/*
38917836SJohn.Forte@Sun.COM 		 * Set the data block offset
38927836SJohn.Forte@Sun.COM 		 */
38937836SJohn.Forte@Sun.COM 		blockOffset = STMF_PROVIDER_DATA_PROP_SIZE * i;
38947836SJohn.Forte@Sun.COM 		actualBlockSize = scf_value_get_opaque(value,
38957836SJohn.Forte@Sun.COM 		    &nvlistEncoded[blockOffset], STMF_PROVIDER_DATA_PROP_SIZE);
38967836SJohn.Forte@Sun.COM 		if (actualBlockSize == -1) {
3897*11909SPeter.Gill@Sun.COM 			syslog(LOG_ERR, "get opaque property value %s/%s "
3898*11909SPeter.Gill@Sun.COM 			    "failed - %s", pgName, dataPropertyName,
38997836SJohn.Forte@Sun.COM 			    scf_strerror(scf_error()));
39007836SJohn.Forte@Sun.COM 			ret = STMF_PS_ERROR;
39017836SJohn.Forte@Sun.COM 			goto out;
39027836SJohn.Forte@Sun.COM 		}
39037836SJohn.Forte@Sun.COM 		nvlistEncodedSize += actualBlockSize;
39047836SJohn.Forte@Sun.COM 	}
39057836SJohn.Forte@Sun.COM 
39067836SJohn.Forte@Sun.COM 	if (nvlist_unpack(nvlistEncoded, nvlistEncodedSize, nvl, 0) != 0) {
39077836SJohn.Forte@Sun.COM 		syslog(LOG_ERR, "unable to unpack nvlist");
39087836SJohn.Forte@Sun.COM 		ret = STMF_PS_ERROR;
39097836SJohn.Forte@Sun.COM 		goto out;
39107836SJohn.Forte@Sun.COM 	}
39117836SJohn.Forte@Sun.COM 
39127836SJohn.Forte@Sun.COM 
39137836SJohn.Forte@Sun.COM out:
39147836SJohn.Forte@Sun.COM 	/*
39157836SJohn.Forte@Sun.COM 	 * Free resources
39167836SJohn.Forte@Sun.COM 	 */
39177836SJohn.Forte@Sun.COM 	if (handle != NULL) {
39187836SJohn.Forte@Sun.COM 		scf_handle_destroy(handle);
39197836SJohn.Forte@Sun.COM 	}
39207836SJohn.Forte@Sun.COM 	if (svc != NULL) {
39217836SJohn.Forte@Sun.COM 		scf_service_destroy(svc);
39227836SJohn.Forte@Sun.COM 	}
39237836SJohn.Forte@Sun.COM 	if (pg != NULL) {
39247836SJohn.Forte@Sun.COM 		scf_pg_destroy(pg);
39257836SJohn.Forte@Sun.COM 	}
39267836SJohn.Forte@Sun.COM 	if (prop != NULL) {
39277836SJohn.Forte@Sun.COM 		scf_property_destroy(prop);
39287836SJohn.Forte@Sun.COM 	}
39297836SJohn.Forte@Sun.COM 	if (value != NULL) {
39307836SJohn.Forte@Sun.COM 		scf_value_destroy(value);
39317836SJohn.Forte@Sun.COM 	}
39327836SJohn.Forte@Sun.COM 	if (nvlistEncoded != NULL) {
39337836SJohn.Forte@Sun.COM 		free(nvlistEncoded);
39347836SJohn.Forte@Sun.COM 	}
39357836SJohn.Forte@Sun.COM 
39367836SJohn.Forte@Sun.COM 	return (ret);
39377836SJohn.Forte@Sun.COM 
39387836SJohn.Forte@Sun.COM }
39397836SJohn.Forte@Sun.COM /*
39407836SJohn.Forte@Sun.COM  * psGetProviderDataList
39417836SJohn.Forte@Sun.COM  *
39427836SJohn.Forte@Sun.COM  * Retrieves the list of providers that currently store persistent data
39437836SJohn.Forte@Sun.COM  *
39447836SJohn.Forte@Sun.COM  * providerList - pointer to a pointer to an stmfProviderList structure
39457836SJohn.Forte@Sun.COM  *                On success, this will contain the list of providers
39467836SJohn.Forte@Sun.COM  *                currently storing persistent data.
39477836SJohn.Forte@Sun.COM  */
39487836SJohn.Forte@Sun.COM int
39497836SJohn.Forte@Sun.COM psGetProviderDataList(stmfProviderList **providerList)
39507836SJohn.Forte@Sun.COM {
39517836SJohn.Forte@Sun.COM 	scf_handle_t *handle = NULL;
39527836SJohn.Forte@Sun.COM 	scf_service_t *svc = NULL;
39537836SJohn.Forte@Sun.COM 	scf_propertygroup_t *pg = NULL;
39547836SJohn.Forte@Sun.COM 	scf_property_t *prop = NULL;
39557836SJohn.Forte@Sun.COM 	scf_value_t *value = NULL;
39567836SJohn.Forte@Sun.COM 	scf_iter_t *pgIter = NULL;
39577836SJohn.Forte@Sun.COM 	char buf[MAXNAMELEN];
39587836SJohn.Forte@Sun.COM 	int providerCnt = 0;
39597836SJohn.Forte@Sun.COM 	int64_t providerType;
39607836SJohn.Forte@Sun.COM 	int i = 0, j;
39617836SJohn.Forte@Sun.COM 	int ret = STMF_PS_SUCCESS;
39627836SJohn.Forte@Sun.COM 
39637836SJohn.Forte@Sun.COM 	ret = iPsInit(&handle, &svc);
39647836SJohn.Forte@Sun.COM 	if (ret != STMF_PS_SUCCESS) {
39657836SJohn.Forte@Sun.COM 		goto out;
39667836SJohn.Forte@Sun.COM 	}
39677836SJohn.Forte@Sun.COM 
39687836SJohn.Forte@Sun.COM 	*providerList = NULL;
39697836SJohn.Forte@Sun.COM 
39707836SJohn.Forte@Sun.COM 	/*
39717836SJohn.Forte@Sun.COM 	 * Allocate scf resources
39727836SJohn.Forte@Sun.COM 	 */
39737836SJohn.Forte@Sun.COM 	if (((pg = scf_pg_create(handle)) == NULL) ||
39747836SJohn.Forte@Sun.COM 	    ((value = scf_value_create(handle)) == NULL) ||
39757836SJohn.Forte@Sun.COM 	    ((prop = scf_property_create(handle)) == NULL) ||
39767836SJohn.Forte@Sun.COM 	    ((pgIter = scf_iter_create(handle)) == NULL)) {
39777836SJohn.Forte@Sun.COM 		syslog(LOG_ERR, "scf alloc resource failed - %s",
39787836SJohn.Forte@Sun.COM 		    scf_strerror(scf_error()));
39797836SJohn.Forte@Sun.COM 		ret = STMF_PS_ERROR;
39807836SJohn.Forte@Sun.COM 		goto out;
39817836SJohn.Forte@Sun.COM 	}
39827836SJohn.Forte@Sun.COM 
39837836SJohn.Forte@Sun.COM 	/*
39847836SJohn.Forte@Sun.COM 	 * pgIter is the iterator handle
39857836SJohn.Forte@Sun.COM 	 */
39867836SJohn.Forte@Sun.COM 	if (scf_iter_service_pgs(pgIter, svc) == -1) {
39877836SJohn.Forte@Sun.COM 		syslog(LOG_ERR, "iter property groups failed - %s",
39887836SJohn.Forte@Sun.COM 		    scf_strerror(scf_error()));
39897836SJohn.Forte@Sun.COM 		ret = STMF_PS_ERROR;
39907836SJohn.Forte@Sun.COM 		goto out;
39917836SJohn.Forte@Sun.COM 	}
39927836SJohn.Forte@Sun.COM 
39937836SJohn.Forte@Sun.COM 	while (scf_iter_next_pg(pgIter, pg) == 1) {
39947836SJohn.Forte@Sun.COM 		if (scf_pg_get_name(pg, buf, sizeof (buf)) == -1) {
39957836SJohn.Forte@Sun.COM 			syslog(LOG_ERR, "get name failed - %s",
39967836SJohn.Forte@Sun.COM 			    scf_strerror(scf_error()));
39977836SJohn.Forte@Sun.COM 			ret = STMF_PS_ERROR;
39987836SJohn.Forte@Sun.COM 			break;
39997836SJohn.Forte@Sun.COM 		}
40007836SJohn.Forte@Sun.COM 		/*
40017836SJohn.Forte@Sun.COM 		 * Only count LU property groups
40027836SJohn.Forte@Sun.COM 		 */
40037836SJohn.Forte@Sun.COM 		if (strncmp(buf, STMF_PROVIDER_DATA_PREFIX,
40047836SJohn.Forte@Sun.COM 		    strlen(STMF_PROVIDER_DATA_PREFIX)) == 0) {
40057836SJohn.Forte@Sun.COM 			providerCnt++;
40067836SJohn.Forte@Sun.COM 		}
40077836SJohn.Forte@Sun.COM 	}
40087836SJohn.Forte@Sun.COM 
40097836SJohn.Forte@Sun.COM 	/*
40107836SJohn.Forte@Sun.COM 	 * pgIter is the iterator handle
40117836SJohn.Forte@Sun.COM 	 */
40127836SJohn.Forte@Sun.COM 	if (scf_iter_service_pgs(pgIter, svc) == -1) {
40137836SJohn.Forte@Sun.COM 		syslog(LOG_ERR, "iter property groups failed - %s",
40147836SJohn.Forte@Sun.COM 		    scf_strerror(scf_error()));
40157836SJohn.Forte@Sun.COM 		ret = STMF_PS_ERROR;
40167836SJohn.Forte@Sun.COM 		goto out;
40177836SJohn.Forte@Sun.COM 	}
40187836SJohn.Forte@Sun.COM 
40197836SJohn.Forte@Sun.COM 	*providerList = (stmfProviderList *)calloc(1,
40207836SJohn.Forte@Sun.COM 	    sizeof (stmfProviderList) + providerCnt * sizeof (stmfProvider));
40217836SJohn.Forte@Sun.COM 	if (*providerList == NULL) {
40227836SJohn.Forte@Sun.COM 		ret = STMF_PS_ERROR_NOMEM;
40237836SJohn.Forte@Sun.COM 		goto out;
40247836SJohn.Forte@Sun.COM 	}
40257836SJohn.Forte@Sun.COM 
40267836SJohn.Forte@Sun.COM 	/*
40277836SJohn.Forte@Sun.COM 	 * it's possible for entries to be added/removed while we're retrieving
40287836SJohn.Forte@Sun.COM 	 * the property groups. Just make sure we don't write beyond our
40297836SJohn.Forte@Sun.COM 	 * allocated buffer by checking to ensure i < providerCnt.
40307836SJohn.Forte@Sun.COM 	 */
40317836SJohn.Forte@Sun.COM 	while ((scf_iter_next_pg(pgIter, pg) == 1) && (i < providerCnt)) {
40327836SJohn.Forte@Sun.COM 		if (scf_pg_get_name(pg, buf, sizeof (buf)) == -1) {
40337836SJohn.Forte@Sun.COM 			syslog(LOG_ERR, "get name failed - %s",
40347836SJohn.Forte@Sun.COM 			    scf_strerror(scf_error()));
40357836SJohn.Forte@Sun.COM 			ret = STMF_PS_ERROR;
40367836SJohn.Forte@Sun.COM 			break;
40377836SJohn.Forte@Sun.COM 		}
40387836SJohn.Forte@Sun.COM 		/*
40397836SJohn.Forte@Sun.COM 		 * Only use provider data property groups
40407836SJohn.Forte@Sun.COM 		 */
40417836SJohn.Forte@Sun.COM 		if (strncmp(buf, STMF_PROVIDER_DATA_PREFIX,
40427836SJohn.Forte@Sun.COM 		    strlen(STMF_PROVIDER_DATA_PREFIX)) != 0) {
40437836SJohn.Forte@Sun.COM 			continue;
40447836SJohn.Forte@Sun.COM 		}
40457836SJohn.Forte@Sun.COM 
40467836SJohn.Forte@Sun.COM 		/*
40477836SJohn.Forte@Sun.COM 		 * Get the STMF_PROVIDER_DATA_PROP_TYPE property
40487836SJohn.Forte@Sun.COM 		 */
40497836SJohn.Forte@Sun.COM 		if (scf_pg_get_property(pg, STMF_PROVIDER_DATA_PROP_TYPE,
40507836SJohn.Forte@Sun.COM 		    prop) == -1) {
4051*11909SPeter.Gill@Sun.COM 			syslog(LOG_ERR, "get property %s/%s failed - %s",
4052*11909SPeter.Gill@Sun.COM 			    buf, STMF_PROVIDER_DATA_PROP_TYPE,
40537836SJohn.Forte@Sun.COM 			    scf_strerror(scf_error()));
40547836SJohn.Forte@Sun.COM 			ret = STMF_PS_ERROR;
40557836SJohn.Forte@Sun.COM 			break;
40567836SJohn.Forte@Sun.COM 		}
40577836SJohn.Forte@Sun.COM 
40587836SJohn.Forte@Sun.COM 		/*
40597836SJohn.Forte@Sun.COM 		 * Get the STMF_PROVIDER_DATA_PROP_TYPE value
40607836SJohn.Forte@Sun.COM 		 */
40617836SJohn.Forte@Sun.COM 		if (scf_property_get_value(prop, value) == -1) {
4062*11909SPeter.Gill@Sun.COM 			syslog(LOG_ERR, "get property value %s/%s failed - %s",
4063*11909SPeter.Gill@Sun.COM 			    buf, STMF_PROVIDER_DATA_PROP_TYPE,
40647836SJohn.Forte@Sun.COM 			    scf_strerror(scf_error()));
40657836SJohn.Forte@Sun.COM 			ret = STMF_PS_ERROR;
40667836SJohn.Forte@Sun.COM 			break;
40677836SJohn.Forte@Sun.COM 		}
40687836SJohn.Forte@Sun.COM 
40697836SJohn.Forte@Sun.COM 		/*
40707836SJohn.Forte@Sun.COM 		 * Now get the actual value from the value handle
40717836SJohn.Forte@Sun.COM 		 */
40727836SJohn.Forte@Sun.COM 		if (scf_value_get_integer(value, &providerType) == -1) {
4073*11909SPeter.Gill@Sun.COM 			syslog(LOG_ERR, "get integer value %s/%s failed - %s",
4074*11909SPeter.Gill@Sun.COM 			    buf, STMF_PROVIDER_DATA_PROP_TYPE,
40757836SJohn.Forte@Sun.COM 			    scf_strerror(scf_error()));
40767836SJohn.Forte@Sun.COM 			ret = STMF_PS_ERROR;
40777836SJohn.Forte@Sun.COM 			break;
40787836SJohn.Forte@Sun.COM 		}
40797836SJohn.Forte@Sun.COM 
40807836SJohn.Forte@Sun.COM 		(*providerList)->provider[i].providerType = providerType;
40817836SJohn.Forte@Sun.COM 
40827836SJohn.Forte@Sun.COM 		/* determine offset for copy of provider name */
40837836SJohn.Forte@Sun.COM 		j = strlen(STMF_PROVIDER_DATA_PREFIX);
40847836SJohn.Forte@Sun.COM 
40857836SJohn.Forte@Sun.COM 		/* copy provider name to caller's list */
40867836SJohn.Forte@Sun.COM 		(void) strncpy((*providerList)->provider[i].name, buf + j,
40877836SJohn.Forte@Sun.COM 		    sizeof ((*providerList)->provider[i].name));
40887836SJohn.Forte@Sun.COM 		i++;
40897836SJohn.Forte@Sun.COM 		(*providerList)->cnt++;
40907836SJohn.Forte@Sun.COM 	}
40917836SJohn.Forte@Sun.COM 
40927836SJohn.Forte@Sun.COM 	if (ret != STMF_PS_SUCCESS) {
40937836SJohn.Forte@Sun.COM 		free(*providerList);
40947836SJohn.Forte@Sun.COM 		goto out;
40957836SJohn.Forte@Sun.COM 	}
40967836SJohn.Forte@Sun.COM 
40977836SJohn.Forte@Sun.COM out:
40987836SJohn.Forte@Sun.COM 	/*
40997836SJohn.Forte@Sun.COM 	 * Free resources
41007836SJohn.Forte@Sun.COM 	 */
41017836SJohn.Forte@Sun.COM 	if (handle != NULL) {
41027836SJohn.Forte@Sun.COM 		scf_handle_destroy(handle);
41037836SJohn.Forte@Sun.COM 	}
41047836SJohn.Forte@Sun.COM 	if (svc != NULL) {
41057836SJohn.Forte@Sun.COM 		scf_service_destroy(svc);
41067836SJohn.Forte@Sun.COM 	}
41077836SJohn.Forte@Sun.COM 	if (pg != NULL) {
41087836SJohn.Forte@Sun.COM 		scf_pg_destroy(pg);
41097836SJohn.Forte@Sun.COM 	}
41107836SJohn.Forte@Sun.COM 	if (value != NULL) {
41117836SJohn.Forte@Sun.COM 		scf_value_destroy(value);
41127836SJohn.Forte@Sun.COM 	}
41137836SJohn.Forte@Sun.COM 	if (prop != NULL) {
41147836SJohn.Forte@Sun.COM 		scf_property_destroy(prop);
41157836SJohn.Forte@Sun.COM 	}
41167836SJohn.Forte@Sun.COM 	if (pgIter != NULL) {
41177836SJohn.Forte@Sun.COM 		scf_iter_destroy(pgIter);
41187836SJohn.Forte@Sun.COM 	}
41197836SJohn.Forte@Sun.COM 
41207836SJohn.Forte@Sun.COM 	return (ret);
41217836SJohn.Forte@Sun.COM }
41227836SJohn.Forte@Sun.COM 
41237836SJohn.Forte@Sun.COM 
41247836SJohn.Forte@Sun.COM /*
41257836SJohn.Forte@Sun.COM  * psSetProviderData
41267836SJohn.Forte@Sun.COM  *
41277836SJohn.Forte@Sun.COM  * Stores a packed nvlist on a per provider basis
41287836SJohn.Forte@Sun.COM  *
41297836SJohn.Forte@Sun.COM  * providerName - property group name to use
41307836SJohn.Forte@Sun.COM  * nvl - nvlist to store
41317836SJohn.Forte@Sun.COM  * providerType - type of provider (logical unit or port)
41327836SJohn.Forte@Sun.COM  *
41337836SJohn.Forte@Sun.COM  */
41347836SJohn.Forte@Sun.COM int
41357836SJohn.Forte@Sun.COM psSetProviderData(char *providerName, nvlist_t *nvl, int providerType,
41367836SJohn.Forte@Sun.COM     uint64_t *setToken)
41377836SJohn.Forte@Sun.COM {
41387836SJohn.Forte@Sun.COM 	scf_handle_t	*handle = NULL;
41397836SJohn.Forte@Sun.COM 	scf_service_t	*svc = NULL;
41407836SJohn.Forte@Sun.COM 	scf_propertygroup_t	*pg = NULL;
41417836SJohn.Forte@Sun.COM 	scf_property_t	*prop = NULL;
41427836SJohn.Forte@Sun.COM 	scf_transaction_t *tran = NULL;
41437836SJohn.Forte@Sun.COM 	/* represents arrays of entry and value pointers for scf */
41447836SJohn.Forte@Sun.COM 	scf_transaction_entry_t	**addEntry = NULL;
41457836SJohn.Forte@Sun.COM 	scf_transaction_entry_t	**deleteEntry = NULL;
41467836SJohn.Forte@Sun.COM 	scf_value_t **addValue = NULL;
41477836SJohn.Forte@Sun.COM 
41487836SJohn.Forte@Sun.COM 	/*
41497836SJohn.Forte@Sun.COM 	 * These declarations are for known entry and value set/get
41507836SJohn.Forte@Sun.COM 	 * operations
41517836SJohn.Forte@Sun.COM 	 */
41527836SJohn.Forte@Sun.COM 	scf_transaction_entry_t *entry1 = NULL;
41537836SJohn.Forte@Sun.COM 	scf_transaction_entry_t *entry2 = NULL;
41547836SJohn.Forte@Sun.COM 	scf_transaction_entry_t *entry3 = NULL;
41557836SJohn.Forte@Sun.COM 	scf_transaction_entry_t *entry5 = NULL;
41567836SJohn.Forte@Sun.COM 	scf_value_t *value1 = NULL;
41577836SJohn.Forte@Sun.COM 	scf_value_t *value2 = NULL;
41587836SJohn.Forte@Sun.COM 	scf_value_t *value3 = NULL;
41597836SJohn.Forte@Sun.COM 	scf_value_t *value4 = NULL;
41607836SJohn.Forte@Sun.COM 	scf_value_t *value5 = NULL;
41617836SJohn.Forte@Sun.COM 
41627836SJohn.Forte@Sun.COM 	boolean_t newPg = B_FALSE;
41637836SJohn.Forte@Sun.COM 	char pgName[MAXPATHLEN];
41647836SJohn.Forte@Sun.COM 	char dataPropertyName[STMF_PROVIDER_DATA_PROP_NAME_SIZE];
41657836SJohn.Forte@Sun.COM 	char *nvlistEncoded = NULL;
41667836SJohn.Forte@Sun.COM 	size_t nvlistEncodedSize;
41677836SJohn.Forte@Sun.COM 	size_t blockSize;
41687836SJohn.Forte@Sun.COM 	int i, j = 0;
41697836SJohn.Forte@Sun.COM 	int addEntryAlloc = 0, deleteEntryAlloc = 0, addValueAlloc = 0;
41707836SJohn.Forte@Sun.COM 	int blockOffset;
41717836SJohn.Forte@Sun.COM 	uint64_t oldBlockCnt = 0;
41727836SJohn.Forte@Sun.COM 	uint64_t blockCnt = 0;
41737836SJohn.Forte@Sun.COM 	uint64_t setCnt = 0;
41747836SJohn.Forte@Sun.COM 	boolean_t foundSetCnt = B_TRUE;
41757836SJohn.Forte@Sun.COM 	int ret = STMF_PS_SUCCESS;
41767836SJohn.Forte@Sun.COM 	int commitRet;
41777836SJohn.Forte@Sun.COM 
41787836SJohn.Forte@Sun.COM 	if (providerName == NULL || (providerType != STMF_LU_PROVIDER_TYPE &&
41797836SJohn.Forte@Sun.COM 	    providerType != STMF_PORT_PROVIDER_TYPE)) {
41807836SJohn.Forte@Sun.COM 		ret = STMF_PS_ERROR_INVALID_ARG;
41817836SJohn.Forte@Sun.COM 		goto out;
41827836SJohn.Forte@Sun.COM 	}
41837836SJohn.Forte@Sun.COM 
41847836SJohn.Forte@Sun.COM 	ret = iPsInit(&handle, &svc);
41857836SJohn.Forte@Sun.COM 	if (ret != STMF_PS_SUCCESS) {
41867836SJohn.Forte@Sun.COM 		goto out;
41877836SJohn.Forte@Sun.COM 	}
41887836SJohn.Forte@Sun.COM 
41897836SJohn.Forte@Sun.COM 	bzero(pgName, sizeof (pgName));
41907836SJohn.Forte@Sun.COM 	/*
41917836SJohn.Forte@Sun.COM 	 * create the property group name
41927836SJohn.Forte@Sun.COM 	 */
41937836SJohn.Forte@Sun.COM 	(void) snprintf(pgName, sizeof (pgName), "%s%s",
41947836SJohn.Forte@Sun.COM 	    STMF_PROVIDER_DATA_PREFIX, providerName);
41957836SJohn.Forte@Sun.COM 
41967836SJohn.Forte@Sun.COM 	/*
41977836SJohn.Forte@Sun.COM 	 * Allocate scf resources
41987836SJohn.Forte@Sun.COM 	 */
41997836SJohn.Forte@Sun.COM 	if (((pg = scf_pg_create(handle)) == NULL) ||
42007836SJohn.Forte@Sun.COM 	    ((entry1 = scf_entry_create(handle)) == NULL) ||
42017836SJohn.Forte@Sun.COM 	    ((entry2 = scf_entry_create(handle)) == NULL) ||
42027836SJohn.Forte@Sun.COM 	    ((entry3 = scf_entry_create(handle)) == NULL) ||
42037836SJohn.Forte@Sun.COM 	    ((entry5 = scf_entry_create(handle)) == NULL) ||
42047836SJohn.Forte@Sun.COM 	    ((value1 = scf_value_create(handle)) == NULL) ||
42057836SJohn.Forte@Sun.COM 	    ((value2 = scf_value_create(handle)) == NULL) ||
42067836SJohn.Forte@Sun.COM 	    ((value3 = scf_value_create(handle)) == NULL) ||
42077836SJohn.Forte@Sun.COM 	    ((value4 = scf_value_create(handle)) == NULL) ||
42087836SJohn.Forte@Sun.COM 	    ((value5 = scf_value_create(handle)) == NULL) ||
42097836SJohn.Forte@Sun.COM 	    ((prop = scf_property_create(handle)) == NULL) ||
42107836SJohn.Forte@Sun.COM 	    ((tran = scf_transaction_create(handle)) == NULL)) {
42117836SJohn.Forte@Sun.COM 		syslog(LOG_ERR, "scf alloc resource failed - %s",
42127836SJohn.Forte@Sun.COM 		    scf_strerror(scf_error()));
42137836SJohn.Forte@Sun.COM 		ret = STMF_PS_ERROR;
42147836SJohn.Forte@Sun.COM 		goto out;
42157836SJohn.Forte@Sun.COM 	}
42167836SJohn.Forte@Sun.COM 
42177836SJohn.Forte@Sun.COM 	/*
42187836SJohn.Forte@Sun.COM 	 * Get the existing property group
42197836SJohn.Forte@Sun.COM 	 */
42207836SJohn.Forte@Sun.COM 	if (scf_service_get_pg(svc, pgName, pg) == -1) {
42217836SJohn.Forte@Sun.COM 		if (scf_error() != SCF_ERROR_NOT_FOUND) {
4222*11909SPeter.Gill@Sun.COM 			syslog(LOG_ERR, "get pg %s failed - %s",
4223*11909SPeter.Gill@Sun.COM 			    pgName, scf_strerror(scf_error()));
42247836SJohn.Forte@Sun.COM 			ret = STMF_PS_ERROR;
42257836SJohn.Forte@Sun.COM 			goto out;
42267836SJohn.Forte@Sun.COM 		} else {
42277836SJohn.Forte@Sun.COM 			/*
42287836SJohn.Forte@Sun.COM 			 * create the property group.
42297836SJohn.Forte@Sun.COM 			 */
42307836SJohn.Forte@Sun.COM 			if (scf_service_add_pg(svc, pgName,
42317836SJohn.Forte@Sun.COM 			    SCF_GROUP_APPLICATION, 0, pg) == -1) {
4232*11909SPeter.Gill@Sun.COM 				syslog(LOG_ERR, "add pg %s failed - %s",
4233*11909SPeter.Gill@Sun.COM 				    pgName, scf_strerror(scf_error()));
42347836SJohn.Forte@Sun.COM 				ret = STMF_PS_ERROR;
42357836SJohn.Forte@Sun.COM 				goto out;
42367836SJohn.Forte@Sun.COM 			}
42377836SJohn.Forte@Sun.COM 			newPg = B_TRUE;
42387836SJohn.Forte@Sun.COM 		}
42397836SJohn.Forte@Sun.COM 	}
42407836SJohn.Forte@Sun.COM 
42417836SJohn.Forte@Sun.COM 	/*
42427836SJohn.Forte@Sun.COM 	 * Begin the transaction
42437836SJohn.Forte@Sun.COM 	 */
42447836SJohn.Forte@Sun.COM 	if (scf_transaction_start(tran, pg) == -1) {
4245*11909SPeter.Gill@Sun.COM 		syslog(LOG_ERR, "start transaction for %s failed - %s",
4246*11909SPeter.Gill@Sun.COM 		    pgName, scf_strerror(scf_error()));
42477836SJohn.Forte@Sun.COM 		ret = STMF_PS_ERROR;
42487836SJohn.Forte@Sun.COM 		goto out;
42497836SJohn.Forte@Sun.COM 	}
42507836SJohn.Forte@Sun.COM 
42517836SJohn.Forte@Sun.COM 	if (!newPg) {
42527836SJohn.Forte@Sun.COM 		/*
42537836SJohn.Forte@Sun.COM 		 * Get the STMF_PROVIDER_DATA_PROP_COUNT property
42547836SJohn.Forte@Sun.COM 		 */
42557836SJohn.Forte@Sun.COM 		if (scf_pg_get_property(pg, STMF_PROVIDER_DATA_PROP_COUNT,
42567836SJohn.Forte@Sun.COM 		    prop) == -1) {
4257*11909SPeter.Gill@Sun.COM 			syslog(LOG_ERR, "get property %s/%s failed - %s",
4258*11909SPeter.Gill@Sun.COM 			    pgName, STMF_PROVIDER_DATA_PROP_COUNT,
42597836SJohn.Forte@Sun.COM 			    scf_strerror(scf_error()));
42607836SJohn.Forte@Sun.COM 			ret = STMF_PS_ERROR;
42617836SJohn.Forte@Sun.COM 			goto out;
42627836SJohn.Forte@Sun.COM 		}
42637836SJohn.Forte@Sun.COM 
42647836SJohn.Forte@Sun.COM 		/*
42657836SJohn.Forte@Sun.COM 		 * Get the STMF_PROVIDER_DATA_PROP_COUNT value
42667836SJohn.Forte@Sun.COM 		 */
42677836SJohn.Forte@Sun.COM 		if (scf_property_get_value(prop, value4) == -1) {
4268*11909SPeter.Gill@Sun.COM 			syslog(LOG_ERR, "get property value %s/%s failed - %s",
4269*11909SPeter.Gill@Sun.COM 			    pgName, STMF_PROVIDER_DATA_PROP_COUNT,
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 		/*
42767836SJohn.Forte@Sun.COM 		 * Now get the actual value from the value handle
42777836SJohn.Forte@Sun.COM 		 */
42787836SJohn.Forte@Sun.COM 		if (scf_value_get_count(value4, &oldBlockCnt) == -1) {
4279*11909SPeter.Gill@Sun.COM 			syslog(LOG_ERR, "get integer value %s/%s failed - %s",
4280*11909SPeter.Gill@Sun.COM 			    pgName, STMF_PROVIDER_DATA_PROP_COUNT,
42817836SJohn.Forte@Sun.COM 			    scf_strerror(scf_error()));
42827836SJohn.Forte@Sun.COM 			ret = STMF_PS_ERROR;
42837836SJohn.Forte@Sun.COM 			goto out;
42847836SJohn.Forte@Sun.COM 		}
42857836SJohn.Forte@Sun.COM 	}
42867836SJohn.Forte@Sun.COM 
42877836SJohn.Forte@Sun.COM 	/*
42887836SJohn.Forte@Sun.COM 	 * Get the STMF_PROVIDER_DATA_PROP_SET_COUNT property
42897836SJohn.Forte@Sun.COM 	 * If it doesn't exist, we'll create it later after successfully
42907836SJohn.Forte@Sun.COM 	 * setting the data.
42917836SJohn.Forte@Sun.COM 	 */
42927836SJohn.Forte@Sun.COM 	if (scf_pg_get_property(pg, STMF_PROVIDER_DATA_PROP_SET_COUNT,
42937836SJohn.Forte@Sun.COM 	    prop) == -1) {
42947836SJohn.Forte@Sun.COM 		if (scf_error() == SCF_ERROR_NOT_FOUND) {
42957836SJohn.Forte@Sun.COM 			foundSetCnt = B_FALSE;
42967836SJohn.Forte@Sun.COM 		} else {
4297*11909SPeter.Gill@Sun.COM 			syslog(LOG_ERR, "get property %s/%s failed - %s",
4298*11909SPeter.Gill@Sun.COM 			    pgName, STMF_PROVIDER_DATA_PROP_SET_COUNT,
42997836SJohn.Forte@Sun.COM 			    scf_strerror(scf_error()));
43007836SJohn.Forte@Sun.COM 			ret = STMF_PS_ERROR;
43017836SJohn.Forte@Sun.COM 			goto out;
43027836SJohn.Forte@Sun.COM 		}
43037836SJohn.Forte@Sun.COM 	}
43047836SJohn.Forte@Sun.COM 
43057836SJohn.Forte@Sun.COM 	if (foundSetCnt) {
43067836SJohn.Forte@Sun.COM 		/*
43077836SJohn.Forte@Sun.COM 		 * Get the STMF_PROVIDER_DATA_PROP_SET_COUNT value
43087836SJohn.Forte@Sun.COM 		 */
43097836SJohn.Forte@Sun.COM 		if (scf_property_get_value(prop, value5) == -1) {
4310*11909SPeter.Gill@Sun.COM 			syslog(LOG_ERR, "get property value %s/%s failed - %s",
4311*11909SPeter.Gill@Sun.COM 			    pgName, STMF_PROVIDER_DATA_PROP_SET_COUNT,
43127836SJohn.Forte@Sun.COM 			    scf_strerror(scf_error()));
43137836SJohn.Forte@Sun.COM 			ret = STMF_PS_ERROR;
43147836SJohn.Forte@Sun.COM 			goto out;
43157836SJohn.Forte@Sun.COM 		}
43167836SJohn.Forte@Sun.COM 
43177836SJohn.Forte@Sun.COM 		/*
43187836SJohn.Forte@Sun.COM 		 * Now get the actual value from the value handle
43197836SJohn.Forte@Sun.COM 		 */
43207836SJohn.Forte@Sun.COM 		if (scf_value_get_count(value5, &setCnt) == -1) {
4321*11909SPeter.Gill@Sun.COM 			syslog(LOG_ERR, "get integer value %s/%s failed - %s",
4322*11909SPeter.Gill@Sun.COM 			    pgName, STMF_PROVIDER_DATA_PROP_SET_COUNT,
43237836SJohn.Forte@Sun.COM 			    scf_strerror(scf_error()));
43247836SJohn.Forte@Sun.COM 			ret = STMF_PS_ERROR;
43257836SJohn.Forte@Sun.COM 			goto out;
43267836SJohn.Forte@Sun.COM 		}
43277836SJohn.Forte@Sun.COM 
43287836SJohn.Forte@Sun.COM 		/*
43297836SJohn.Forte@Sun.COM 		 * Compare the setCnt prop to the caller's.
43307836SJohn.Forte@Sun.COM 		 */
43317836SJohn.Forte@Sun.COM 		if (setToken && (*setToken != setCnt)) {
43327836SJohn.Forte@Sun.COM 			ret = STMF_PS_ERROR_PROV_DATA_STALE;
43337836SJohn.Forte@Sun.COM 			goto out;
43347836SJohn.Forte@Sun.COM 		}
43357836SJohn.Forte@Sun.COM 	}
43367836SJohn.Forte@Sun.COM 
43377836SJohn.Forte@Sun.COM 	setCnt++;
43387836SJohn.Forte@Sun.COM 
43397836SJohn.Forte@Sun.COM 	/*
43407836SJohn.Forte@Sun.COM 	 * prepare the list for writing
43417836SJohn.Forte@Sun.COM 	 */
43427836SJohn.Forte@Sun.COM 	if (nvlist_pack(nvl, &nvlistEncoded, &nvlistEncodedSize,
43437836SJohn.Forte@Sun.COM 	    NV_ENCODE_XDR, 0) != 0) {
4344*11909SPeter.Gill@Sun.COM 		syslog(LOG_ERR, "nvlist_pack for %s failed",
4345*11909SPeter.Gill@Sun.COM 		    pgName);
43467836SJohn.Forte@Sun.COM 		ret = STMF_PS_ERROR_NOMEM;
43477836SJohn.Forte@Sun.COM 		goto out;
43487836SJohn.Forte@Sun.COM 	}
43497836SJohn.Forte@Sun.COM 
43507836SJohn.Forte@Sun.COM 	/* Determine how many chunks we need to write */
43517836SJohn.Forte@Sun.COM 	blockCnt = nvlistEncodedSize/STMF_PROVIDER_DATA_PROP_SIZE;
43527836SJohn.Forte@Sun.COM 	if (nvlistEncodedSize % STMF_PROVIDER_DATA_PROP_SIZE)
43537836SJohn.Forte@Sun.COM 		blockCnt++;
43547836SJohn.Forte@Sun.COM 
43557836SJohn.Forte@Sun.COM 	/* allocate entry and value resources for writing those chunks */
43567836SJohn.Forte@Sun.COM 	addEntry = (scf_transaction_entry_t **)calloc(1, sizeof (*addEntry)
43577836SJohn.Forte@Sun.COM 	    * blockCnt);
43587836SJohn.Forte@Sun.COM 	if (addEntry == NULL) {
4359*11909SPeter.Gill@Sun.COM 		syslog(LOG_ERR, "addEntry alloc for %s failed", pgName);
43607836SJohn.Forte@Sun.COM 		ret = STMF_PS_ERROR_NOMEM;
43617836SJohn.Forte@Sun.COM 		goto out;
43627836SJohn.Forte@Sun.COM 	}
43637836SJohn.Forte@Sun.COM 
43647836SJohn.Forte@Sun.COM 	addValue = (scf_value_t **)calloc(1, sizeof (*addValue)
43657836SJohn.Forte@Sun.COM 	    * blockCnt);
43667836SJohn.Forte@Sun.COM 	if (addValue == NULL) {
4367*11909SPeter.Gill@Sun.COM 		syslog(LOG_ERR, "value alloc for %s failed", pgName);
43687836SJohn.Forte@Sun.COM 		ret = STMF_PS_ERROR_NOMEM;
43697836SJohn.Forte@Sun.COM 		goto out;
43707836SJohn.Forte@Sun.COM 	}
43717836SJohn.Forte@Sun.COM 
43727836SJohn.Forte@Sun.COM 	/*
43737836SJohn.Forte@Sun.COM 	 * allocate entry delete resources for deleting anything existing
43747836SJohn.Forte@Sun.COM 	 * that is more than the new block count. We could leave them around
43757836SJohn.Forte@Sun.COM 	 * without suffering any ill effects but it will be cleaner to look at
43767836SJohn.Forte@Sun.COM 	 * in smf tools if they are deleted.
43777836SJohn.Forte@Sun.COM 	 */
43787836SJohn.Forte@Sun.COM 	if (oldBlockCnt > blockCnt) {
43797836SJohn.Forte@Sun.COM 		deleteEntry = (scf_transaction_entry_t **)calloc(1,
43807836SJohn.Forte@Sun.COM 		    sizeof (*deleteEntry) * (oldBlockCnt - blockCnt));
43817836SJohn.Forte@Sun.COM 		if (deleteEntry == NULL) {
4382*11909SPeter.Gill@Sun.COM 			syslog(LOG_ERR, "deleteEntry alloc for %s failed",
4383*11909SPeter.Gill@Sun.COM 			    pgName);
43847836SJohn.Forte@Sun.COM 			ret = STMF_PS_ERROR_NOMEM;
43857836SJohn.Forte@Sun.COM 			goto out;
43867836SJohn.Forte@Sun.COM 		}
43877836SJohn.Forte@Sun.COM 		deleteEntryAlloc = oldBlockCnt - blockCnt;
43887836SJohn.Forte@Sun.COM 	}
43897836SJohn.Forte@Sun.COM 
43907836SJohn.Forte@Sun.COM 
43917836SJohn.Forte@Sun.COM 	for (i = 0; i < blockCnt; i++) {
43927836SJohn.Forte@Sun.COM 		/*
43937836SJohn.Forte@Sun.COM 		 * Create the entry resource for the prop
43947836SJohn.Forte@Sun.COM 		 */
43957836SJohn.Forte@Sun.COM 		addEntry[i] = scf_entry_create(handle);
43967836SJohn.Forte@Sun.COM 		if (addEntry[i] == NULL) {
4397*11909SPeter.Gill@Sun.COM 			syslog(LOG_ERR, "scf value alloc for %s failed - %s",
4398*11909SPeter.Gill@Sun.COM 			    pgName, scf_strerror(scf_error()));
43997836SJohn.Forte@Sun.COM 			ret = STMF_PS_ERROR;
44007836SJohn.Forte@Sun.COM 			goto out;
44017836SJohn.Forte@Sun.COM 		}
44027836SJohn.Forte@Sun.COM 
44037836SJohn.Forte@Sun.COM 		/* bump alloc count for addEntry allocation */
44047836SJohn.Forte@Sun.COM 		addEntryAlloc++;
44057836SJohn.Forte@Sun.COM 
44067836SJohn.Forte@Sun.COM 		/*
44077836SJohn.Forte@Sun.COM 		 * create the name to use for the property
44087836SJohn.Forte@Sun.COM 		 */
44097836SJohn.Forte@Sun.COM 		(void) snprintf(dataPropertyName, sizeof (dataPropertyName),
44107836SJohn.Forte@Sun.COM 		    "%s-%d", STMF_PROVIDER_DATA_PROP_PREFIX, i);
44117836SJohn.Forte@Sun.COM 
44127836SJohn.Forte@Sun.COM 		/*
44137836SJohn.Forte@Sun.COM 		 * Create the new property
44147836SJohn.Forte@Sun.COM 		 */
44157836SJohn.Forte@Sun.COM 		if (scf_transaction_property_new(tran, addEntry[i],
44167836SJohn.Forte@Sun.COM 		    dataPropertyName, SCF_TYPE_OPAQUE) == -1) {
44177836SJohn.Forte@Sun.COM 			if (scf_error() == SCF_ERROR_EXISTS) {
44187836SJohn.Forte@Sun.COM 				if (scf_transaction_property_change(tran,
44197836SJohn.Forte@Sun.COM 				    addEntry[i], dataPropertyName,
44207836SJohn.Forte@Sun.COM 				    SCF_TYPE_OPAQUE) == -1) {
4421*11909SPeter.Gill@Sun.COM 					syslog(LOG_ERR, "transaction property "
4422*11909SPeter.Gill@Sun.COM 					    "change %s/%s failed - %s",
4423*11909SPeter.Gill@Sun.COM 					    pgName, dataPropertyName,
44247836SJohn.Forte@Sun.COM 					    scf_strerror(scf_error()));
44257836SJohn.Forte@Sun.COM 					ret = STMF_PS_ERROR;
44267836SJohn.Forte@Sun.COM 					goto out;
44277836SJohn.Forte@Sun.COM 				}
44287836SJohn.Forte@Sun.COM 			} else {
44297836SJohn.Forte@Sun.COM 				syslog(LOG_ERR,
4430*11909SPeter.Gill@Sun.COM 				    "transaction property new %s/%s "
4431*11909SPeter.Gill@Sun.COM 				    "failed - %s", pgName, dataPropertyName,
44327836SJohn.Forte@Sun.COM 				    scf_strerror(scf_error()));
44337836SJohn.Forte@Sun.COM 				ret = STMF_PS_ERROR;
44347836SJohn.Forte@Sun.COM 				goto out;
44357836SJohn.Forte@Sun.COM 			}
44367836SJohn.Forte@Sun.COM 		}
44377836SJohn.Forte@Sun.COM 		/*
44387836SJohn.Forte@Sun.COM 		 * Create the value resource for the prop
44397836SJohn.Forte@Sun.COM 		 */
44407836SJohn.Forte@Sun.COM 		addValue[i] = scf_value_create(handle);
44417836SJohn.Forte@Sun.COM 		if (addValue[i] == NULL) {
4442*11909SPeter.Gill@Sun.COM 			syslog(LOG_ERR, "scf value alloc for %s failed - %s",
4443*11909SPeter.Gill@Sun.COM 			    pgName, scf_strerror(scf_error()));
44447836SJohn.Forte@Sun.COM 			ret = STMF_PS_ERROR;
44457836SJohn.Forte@Sun.COM 			goto out;
44467836SJohn.Forte@Sun.COM 		}
44477836SJohn.Forte@Sun.COM 
44487836SJohn.Forte@Sun.COM 		/* bump alloc count for addValue allocation */
44497836SJohn.Forte@Sun.COM 		addValueAlloc++;
44507836SJohn.Forte@Sun.COM 
44517836SJohn.Forte@Sun.COM 		/*
44527836SJohn.Forte@Sun.COM 		 * Set the data block offset and size
44537836SJohn.Forte@Sun.COM 		 */
44547836SJohn.Forte@Sun.COM 		if ((STMF_PROVIDER_DATA_PROP_SIZE * (i + 1))
44557836SJohn.Forte@Sun.COM 		    > nvlistEncodedSize) {
44567836SJohn.Forte@Sun.COM 			blockSize = nvlistEncodedSize
44577836SJohn.Forte@Sun.COM 			    - STMF_PROVIDER_DATA_PROP_SIZE * i;
44587836SJohn.Forte@Sun.COM 		} else {
44597836SJohn.Forte@Sun.COM 			blockSize = STMF_PROVIDER_DATA_PROP_SIZE;
44607836SJohn.Forte@Sun.COM 		}
44617836SJohn.Forte@Sun.COM 
44627836SJohn.Forte@Sun.COM 		blockOffset = STMF_PROVIDER_DATA_PROP_SIZE * i;
44637836SJohn.Forte@Sun.COM 		if (scf_value_set_opaque(addValue[i],
44647836SJohn.Forte@Sun.COM 		    &nvlistEncoded[blockOffset], blockSize) == -1) {
4465*11909SPeter.Gill@Sun.COM 			syslog(LOG_ERR, "set value for %s failed - %s",
4466*11909SPeter.Gill@Sun.COM 			    pgName, scf_strerror(scf_error()));
44677836SJohn.Forte@Sun.COM 			ret = STMF_PS_ERROR;
44687836SJohn.Forte@Sun.COM 			goto out;
44697836SJohn.Forte@Sun.COM 		}
44707836SJohn.Forte@Sun.COM 
44717836SJohn.Forte@Sun.COM 		/*
44727836SJohn.Forte@Sun.COM 		 * Add the data block to the transaction entry
44737836SJohn.Forte@Sun.COM 		 */
44747836SJohn.Forte@Sun.COM 		if (scf_entry_add_value(addEntry[i], addValue[i]) == -1) {
4475*11909SPeter.Gill@Sun.COM 			syslog(LOG_ERR, "add value for %s failed - %s",
4476*11909SPeter.Gill@Sun.COM 			    pgName, scf_strerror(scf_error()));
44777836SJohn.Forte@Sun.COM 			ret = STMF_PS_ERROR;
44787836SJohn.Forte@Sun.COM 			goto out;
44797836SJohn.Forte@Sun.COM 		}
44807836SJohn.Forte@Sun.COM 	}
44817836SJohn.Forte@Sun.COM 
44827836SJohn.Forte@Sun.COM 	/*
44837836SJohn.Forte@Sun.COM 	 * Now we need to delete any chunks (properties) that are no longer
44847836SJohn.Forte@Sun.COM 	 * needed. Iterate through the rest of the chunks deleting each.
44857836SJohn.Forte@Sun.COM 	 */
44867836SJohn.Forte@Sun.COM 	for (i = blockCnt; i < oldBlockCnt; i++) {
44877836SJohn.Forte@Sun.COM 		/*
44887836SJohn.Forte@Sun.COM 		 * Create the entry resource for the prop
44897836SJohn.Forte@Sun.COM 		 */
44907836SJohn.Forte@Sun.COM 		deleteEntry[j] = scf_entry_create(handle);
44917836SJohn.Forte@Sun.COM 		if (deleteEntry[j] == NULL) {
4492*11909SPeter.Gill@Sun.COM 			syslog(LOG_ERR, "scf value alloc for %s failed - %s",
4493*11909SPeter.Gill@Sun.COM 			    pgName, scf_strerror(scf_error()));
44947836SJohn.Forte@Sun.COM 			ret = STMF_PS_ERROR;
44957836SJohn.Forte@Sun.COM 			goto out;
44967836SJohn.Forte@Sun.COM 		}
44977836SJohn.Forte@Sun.COM 
44987836SJohn.Forte@Sun.COM 		/*
44997836SJohn.Forte@Sun.COM 		 * create the name to use for the property
45007836SJohn.Forte@Sun.COM 		 */
45017836SJohn.Forte@Sun.COM 		(void) snprintf(dataPropertyName, sizeof (dataPropertyName),
45027836SJohn.Forte@Sun.COM 		    "%s-%d", STMF_PROVIDER_DATA_PROP_PREFIX, i);
45037836SJohn.Forte@Sun.COM 
45047836SJohn.Forte@Sun.COM 		/*
45057836SJohn.Forte@Sun.COM 		 * Delete the existing property
45067836SJohn.Forte@Sun.COM 		 */
45077836SJohn.Forte@Sun.COM 		if (scf_transaction_property_delete(tran, deleteEntry[j++],
45087836SJohn.Forte@Sun.COM 		    dataPropertyName) == -1) {
4509*11909SPeter.Gill@Sun.COM 			syslog(LOG_ERR, "delete property %s/%s failed - %s",
4510*11909SPeter.Gill@Sun.COM 			    pgName, dataPropertyName,
45117836SJohn.Forte@Sun.COM 			    scf_strerror(scf_error()));
45127836SJohn.Forte@Sun.COM 			ret = STMF_PS_ERROR;
45137836SJohn.Forte@Sun.COM 			goto out;
45147836SJohn.Forte@Sun.COM 		}
45157836SJohn.Forte@Sun.COM 	}
45167836SJohn.Forte@Sun.COM 
45177836SJohn.Forte@Sun.COM 	if (newPg) {
45187836SJohn.Forte@Sun.COM 		/*
45197836SJohn.Forte@Sun.COM 		 * Ensure the read_authorization property is set
45207836SJohn.Forte@Sun.COM 		 * for the group
45217836SJohn.Forte@Sun.COM 		 */
45227836SJohn.Forte@Sun.COM 		if (scf_transaction_property_new(tran, entry1,
45237836SJohn.Forte@Sun.COM 		    "read_authorization", SCF_TYPE_ASTRING) == -1) {
4524*11909SPeter.Gill@Sun.COM 			syslog(LOG_ERR, "transaction property %s/%s new "
4525*11909SPeter.Gill@Sun.COM 			    "failed - %s", pgName, "read_authorization",
45267836SJohn.Forte@Sun.COM 			    scf_strerror(scf_error()));
45277836SJohn.Forte@Sun.COM 			ret = STMF_PS_ERROR;
45287836SJohn.Forte@Sun.COM 			goto out;
45297836SJohn.Forte@Sun.COM 		}
45307836SJohn.Forte@Sun.COM 
45317836SJohn.Forte@Sun.COM 		if (scf_value_set_astring(value1, STMF_SMF_READ_ATTR) == -1) {
4532*11909SPeter.Gill@Sun.COM 			syslog(LOG_ERR, "set value %s/%s failed - %s",
4533*11909SPeter.Gill@Sun.COM 			    pgName, "read_authorization",
45347836SJohn.Forte@Sun.COM 			    scf_strerror(scf_error()));
45357836SJohn.Forte@Sun.COM 			ret = STMF_PS_ERROR;
45367836SJohn.Forte@Sun.COM 			goto out;
45377836SJohn.Forte@Sun.COM 		}
45387836SJohn.Forte@Sun.COM 
45397836SJohn.Forte@Sun.COM 		if (scf_entry_add_value(entry1, value1) == -1) {
4540*11909SPeter.Gill@Sun.COM 			syslog(LOG_ERR, "add value %s/%s failed - %s",
4541*11909SPeter.Gill@Sun.COM 			    pgName, "read_authorization",
45427836SJohn.Forte@Sun.COM 			    scf_strerror(scf_error()));
45437836SJohn.Forte@Sun.COM 			ret = STMF_PS_ERROR;
45447836SJohn.Forte@Sun.COM 			goto out;
45457836SJohn.Forte@Sun.COM 		}
45467836SJohn.Forte@Sun.COM 	}
45477836SJohn.Forte@Sun.COM 
45487836SJohn.Forte@Sun.COM 	/* create or change the count property */
45497836SJohn.Forte@Sun.COM 	if (scf_transaction_property_new(tran, entry2,
45507836SJohn.Forte@Sun.COM 	    STMF_PROVIDER_DATA_PROP_COUNT, SCF_TYPE_COUNT) == -1) {
45517836SJohn.Forte@Sun.COM 		if (scf_error() == SCF_ERROR_EXISTS) {
45527836SJohn.Forte@Sun.COM 			if (scf_transaction_property_change(tran, entry2,
45537836SJohn.Forte@Sun.COM 			    STMF_PROVIDER_DATA_PROP_COUNT,
45547836SJohn.Forte@Sun.COM 			    SCF_TYPE_COUNT) == -1) {
4555*11909SPeter.Gill@Sun.COM 				syslog(LOG_ERR, "transaction property change "
4556*11909SPeter.Gill@Sun.COM 				    "%s/%s failed - %s", pgName,
4557*11909SPeter.Gill@Sun.COM 				    STMF_PROVIDER_DATA_PROP_COUNT,
45587836SJohn.Forte@Sun.COM 				    scf_strerror(scf_error()));
45597836SJohn.Forte@Sun.COM 				ret = STMF_PS_ERROR;
45607836SJohn.Forte@Sun.COM 				goto out;
45617836SJohn.Forte@Sun.COM 			}
45627836SJohn.Forte@Sun.COM 		} else {
4563*11909SPeter.Gill@Sun.COM 			syslog(LOG_ERR, "transaction property %s/%s new "
4564*11909SPeter.Gill@Sun.COM 			    "failed - %s", pgName,
4565*11909SPeter.Gill@Sun.COM 			    STMF_PROVIDER_DATA_PROP_COUNT,
45667836SJohn.Forte@Sun.COM 			    scf_strerror(scf_error()));
45677836SJohn.Forte@Sun.COM 			ret = STMF_PS_ERROR;
45687836SJohn.Forte@Sun.COM 			goto out;
45697836SJohn.Forte@Sun.COM 		}
45707836SJohn.Forte@Sun.COM 	}
45717836SJohn.Forte@Sun.COM 
45727836SJohn.Forte@Sun.COM 	scf_value_set_count(value2, blockCnt);
45737836SJohn.Forte@Sun.COM 
45747836SJohn.Forte@Sun.COM 	if (scf_entry_add_value(entry2, value2) == -1) {
4575*11909SPeter.Gill@Sun.COM 		syslog(LOG_ERR, "add value %s/%s failed - %s",
4576*11909SPeter.Gill@Sun.COM 		    pgName, STMF_PROVIDER_DATA_PROP_COUNT,
45777836SJohn.Forte@Sun.COM 		    scf_strerror(scf_error()));
45787836SJohn.Forte@Sun.COM 		ret = STMF_PS_ERROR;
45797836SJohn.Forte@Sun.COM 		goto out;
45807836SJohn.Forte@Sun.COM 	}
45817836SJohn.Forte@Sun.COM 
45827836SJohn.Forte@Sun.COM 	/* create or change the set count property */
45837836SJohn.Forte@Sun.COM 	if (scf_transaction_property_new(tran, entry5,
45847836SJohn.Forte@Sun.COM 	    STMF_PROVIDER_DATA_PROP_SET_COUNT, SCF_TYPE_COUNT) == -1) {
45857836SJohn.Forte@Sun.COM 		if (scf_error() == SCF_ERROR_EXISTS) {
45867836SJohn.Forte@Sun.COM 			if (scf_transaction_property_change(tran, entry5,
45877836SJohn.Forte@Sun.COM 			    STMF_PROVIDER_DATA_PROP_SET_COUNT,
45887836SJohn.Forte@Sun.COM 			    SCF_TYPE_COUNT) == -1) {
45897836SJohn.Forte@Sun.COM 				syslog(LOG_ERR,
4590*11909SPeter.Gill@Sun.COM 				    "transaction property change %s/%s "
4591*11909SPeter.Gill@Sun.COM 				    "failed - %s", pgName,
4592*11909SPeter.Gill@Sun.COM 				    STMF_PROVIDER_DATA_PROP_SET_COUNT,
45937836SJohn.Forte@Sun.COM 				    scf_strerror(scf_error()));
45947836SJohn.Forte@Sun.COM 				ret = STMF_PS_ERROR;
45957836SJohn.Forte@Sun.COM 				goto out;
45967836SJohn.Forte@Sun.COM 			}
45977836SJohn.Forte@Sun.COM 		} else {
4598*11909SPeter.Gill@Sun.COM 			syslog(LOG_ERR, "transaction property new %s/%s "
4599*11909SPeter.Gill@Sun.COM 			    "failed - %s", pgName,
4600*11909SPeter.Gill@Sun.COM 			    STMF_PROVIDER_DATA_PROP_SET_COUNT,
46017836SJohn.Forte@Sun.COM 			    scf_strerror(scf_error()));
46027836SJohn.Forte@Sun.COM 			ret = STMF_PS_ERROR;
46037836SJohn.Forte@Sun.COM 			goto out;
46047836SJohn.Forte@Sun.COM 		}
46057836SJohn.Forte@Sun.COM 	}
46067836SJohn.Forte@Sun.COM 
46077836SJohn.Forte@Sun.COM 
46087836SJohn.Forte@Sun.COM 
46097836SJohn.Forte@Sun.COM 	scf_value_set_count(value5, setCnt);
46107836SJohn.Forte@Sun.COM 
46117836SJohn.Forte@Sun.COM 	if (scf_entry_add_value(entry5, value5) == -1) {
4612*11909SPeter.Gill@Sun.COM 		syslog(LOG_ERR, "add value %s/%s failed - %s",
4613*11909SPeter.Gill@Sun.COM 		    pgName, STMF_PROVIDER_DATA_PROP_SET_COUNT,
46147836SJohn.Forte@Sun.COM 		    scf_strerror(scf_error()));
46157836SJohn.Forte@Sun.COM 		ret = STMF_PS_ERROR;
46167836SJohn.Forte@Sun.COM 		goto out;
46177836SJohn.Forte@Sun.COM 	}
46187836SJohn.Forte@Sun.COM 
46197836SJohn.Forte@Sun.COM 	/* create or change the provider type property */
46207836SJohn.Forte@Sun.COM 	if (scf_transaction_property_new(tran, entry3,
46217836SJohn.Forte@Sun.COM 	    STMF_PROVIDER_DATA_PROP_TYPE, SCF_TYPE_INTEGER) == -1) {
46227836SJohn.Forte@Sun.COM 		if (scf_error() == SCF_ERROR_EXISTS) {
46237836SJohn.Forte@Sun.COM 			if (scf_transaction_property_change(tran, entry3,
46247836SJohn.Forte@Sun.COM 			    STMF_PROVIDER_DATA_PROP_TYPE,
46257836SJohn.Forte@Sun.COM 			    SCF_TYPE_INTEGER) == -1) {
46267836SJohn.Forte@Sun.COM 				syslog(LOG_ERR,
4627*11909SPeter.Gill@Sun.COM 				    "transaction property change %s/%s "
4628*11909SPeter.Gill@Sun.COM 				    "failed - %s", pgName,
4629*11909SPeter.Gill@Sun.COM 				    STMF_PROVIDER_DATA_PROP_TYPE,
46307836SJohn.Forte@Sun.COM 				    scf_strerror(scf_error()));
46317836SJohn.Forte@Sun.COM 				ret = STMF_PS_ERROR;
46327836SJohn.Forte@Sun.COM 				goto out;
46337836SJohn.Forte@Sun.COM 			}
46347836SJohn.Forte@Sun.COM 		} else {
4635*11909SPeter.Gill@Sun.COM 			syslog(LOG_ERR, "transaction property new %s/%s "
4636*11909SPeter.Gill@Sun.COM 			    "failed - %s", pgName, STMF_PROVIDER_DATA_PROP_TYPE,
46377836SJohn.Forte@Sun.COM 			    scf_strerror(scf_error()));
46387836SJohn.Forte@Sun.COM 			ret = STMF_PS_ERROR;
46397836SJohn.Forte@Sun.COM 			goto out;
46407836SJohn.Forte@Sun.COM 		}
46417836SJohn.Forte@Sun.COM 	}
46427836SJohn.Forte@Sun.COM 
46437836SJohn.Forte@Sun.COM 	switch (providerType) {
46447836SJohn.Forte@Sun.COM 		case STMF_PORT_PROVIDER_TYPE:
46457836SJohn.Forte@Sun.COM 		case STMF_LU_PROVIDER_TYPE:
46467836SJohn.Forte@Sun.COM 			scf_value_set_integer(value3, providerType);
46477836SJohn.Forte@Sun.COM 			break;
46487836SJohn.Forte@Sun.COM 		default:
46497836SJohn.Forte@Sun.COM 			ret = STMF_PS_ERROR;
46507836SJohn.Forte@Sun.COM 			goto out;
46517836SJohn.Forte@Sun.COM 	}
46527836SJohn.Forte@Sun.COM 
46537836SJohn.Forte@Sun.COM 	if (scf_entry_add_value(entry3, value3) == -1) {
4654*11909SPeter.Gill@Sun.COM 		syslog(LOG_ERR, "add value %s/%s failed - %s", pgName,
4655*11909SPeter.Gill@Sun.COM 		    STMF_PROVIDER_DATA_PROP_TYPE, scf_strerror(scf_error()));
46567836SJohn.Forte@Sun.COM 		ret = STMF_PS_ERROR;
46577836SJohn.Forte@Sun.COM 		goto out;
46587836SJohn.Forte@Sun.COM 	}
46597836SJohn.Forte@Sun.COM 
46607836SJohn.Forte@Sun.COM 
46617836SJohn.Forte@Sun.COM 	if ((commitRet = scf_transaction_commit(tran)) != 1) {
4662*11909SPeter.Gill@Sun.COM 		syslog(LOG_ERR, "transaction commit for %s failed - %s",
4663*11909SPeter.Gill@Sun.COM 		    pgName, scf_strerror(scf_error()));
46647836SJohn.Forte@Sun.COM 		if (commitRet == 0) {
46657836SJohn.Forte@Sun.COM 			ret = STMF_PS_ERROR_BUSY;
46667836SJohn.Forte@Sun.COM 		} else {
46677836SJohn.Forte@Sun.COM 			ret = STMF_PS_ERROR;
46687836SJohn.Forte@Sun.COM 		}
46697836SJohn.Forte@Sun.COM 		goto out;
46707836SJohn.Forte@Sun.COM 	}
46717836SJohn.Forte@Sun.COM 
46727836SJohn.Forte@Sun.COM 	/* pass the new token back to the caller if requested */
46737836SJohn.Forte@Sun.COM 	if (ret == STMF_PS_SUCCESS && setToken) {
46747836SJohn.Forte@Sun.COM 		*setToken = setCnt;
46757836SJohn.Forte@Sun.COM 	}
46767836SJohn.Forte@Sun.COM 
46777836SJohn.Forte@Sun.COM out:
46787836SJohn.Forte@Sun.COM 	/*
46797836SJohn.Forte@Sun.COM 	 * Free resources
46807836SJohn.Forte@Sun.COM 	 */
46817836SJohn.Forte@Sun.COM 	if (handle != NULL) {
46827836SJohn.Forte@Sun.COM 		scf_handle_destroy(handle);
46837836SJohn.Forte@Sun.COM 	}
46847836SJohn.Forte@Sun.COM 	if (svc != NULL) {
46857836SJohn.Forte@Sun.COM 		scf_service_destroy(svc);
46867836SJohn.Forte@Sun.COM 	}
46877836SJohn.Forte@Sun.COM 	if (pg != NULL) {
46887836SJohn.Forte@Sun.COM 		scf_pg_destroy(pg);
46897836SJohn.Forte@Sun.COM 	}
46907836SJohn.Forte@Sun.COM 	if (prop != NULL) {
46917836SJohn.Forte@Sun.COM 		scf_property_destroy(prop);
46927836SJohn.Forte@Sun.COM 	}
46937836SJohn.Forte@Sun.COM 	if (tran != NULL) {
46947836SJohn.Forte@Sun.COM 		scf_transaction_destroy(tran);
46957836SJohn.Forte@Sun.COM 	}
46967836SJohn.Forte@Sun.COM 	for (i = 0; i < addEntryAlloc; i++) {
46977836SJohn.Forte@Sun.COM 		scf_entry_destroy(addEntry[i]);
46987836SJohn.Forte@Sun.COM 	}
46997836SJohn.Forte@Sun.COM 	for (i = 0; i < addValueAlloc; i++) {
47007836SJohn.Forte@Sun.COM 		scf_value_destroy(addValue[i]);
47017836SJohn.Forte@Sun.COM 	}
47027836SJohn.Forte@Sun.COM 	free(addValue);
47037836SJohn.Forte@Sun.COM 	free(addEntry);
47047836SJohn.Forte@Sun.COM 	for (i = 0; i < deleteEntryAlloc; i++) {
47057836SJohn.Forte@Sun.COM 		scf_entry_destroy(deleteEntry[i]);
47067836SJohn.Forte@Sun.COM 	}
47077836SJohn.Forte@Sun.COM 	free(deleteEntry);
47087836SJohn.Forte@Sun.COM 	if (entry1 != NULL) {
47097836SJohn.Forte@Sun.COM 		scf_entry_destroy(entry1);
47107836SJohn.Forte@Sun.COM 	}
47117836SJohn.Forte@Sun.COM 	if (entry2 != NULL) {
47127836SJohn.Forte@Sun.COM 		scf_entry_destroy(entry2);
47137836SJohn.Forte@Sun.COM 	}
47147836SJohn.Forte@Sun.COM 	if (entry3 != NULL) {
47157836SJohn.Forte@Sun.COM 		scf_entry_destroy(entry3);
47167836SJohn.Forte@Sun.COM 	}
47177836SJohn.Forte@Sun.COM 	if (entry5 != NULL) {
47187836SJohn.Forte@Sun.COM 		scf_entry_destroy(entry5);
47197836SJohn.Forte@Sun.COM 	}
47207836SJohn.Forte@Sun.COM 	if (value1 != NULL) {
47217836SJohn.Forte@Sun.COM 		scf_value_destroy(value1);
47227836SJohn.Forte@Sun.COM 	}
47237836SJohn.Forte@Sun.COM 	if (value2 != NULL) {
47247836SJohn.Forte@Sun.COM 		scf_value_destroy(value2);
47257836SJohn.Forte@Sun.COM 	}
47267836SJohn.Forte@Sun.COM 	if (value3 != NULL) {
47277836SJohn.Forte@Sun.COM 		scf_value_destroy(value3);
47287836SJohn.Forte@Sun.COM 	}
47297836SJohn.Forte@Sun.COM 	if (value4 != NULL) {
47307836SJohn.Forte@Sun.COM 		scf_value_destroy(value4);
47317836SJohn.Forte@Sun.COM 	}
47327836SJohn.Forte@Sun.COM 	if (value5 != NULL) {
47337836SJohn.Forte@Sun.COM 		scf_value_destroy(value5);
47347836SJohn.Forte@Sun.COM 	}
47357836SJohn.Forte@Sun.COM 	if (nvlistEncoded != NULL) {
47367836SJohn.Forte@Sun.COM 		free(nvlistEncoded);
47377836SJohn.Forte@Sun.COM 	}
47387836SJohn.Forte@Sun.COM 
47397836SJohn.Forte@Sun.COM 	return (ret);
47407836SJohn.Forte@Sun.COM }
47417836SJohn.Forte@Sun.COM 
47427836SJohn.Forte@Sun.COM /*
47437836SJohn.Forte@Sun.COM  * psGetViewEntry
47447836SJohn.Forte@Sun.COM  *
47457836SJohn.Forte@Sun.COM  * Purpose: Get a single view entry based on the logical unit identifier and
47467836SJohn.Forte@Sun.COM  *          view entry index
47477836SJohn.Forte@Sun.COM  *
47487836SJohn.Forte@Sun.COM  * lu - logical unit identifier
47497836SJohn.Forte@Sun.COM  * viewEntryIndex - index of view entry
47507836SJohn.Forte@Sun.COM  * ve - caller allocated stmfViewEntry structure. On success, this will
47517836SJohn.Forte@Sun.COM  *      contain the retrieved view entry
47527836SJohn.Forte@Sun.COM  */
47537836SJohn.Forte@Sun.COM int
47547836SJohn.Forte@Sun.COM psGetViewEntry(stmfGuid *lu, uint32_t viewEntryIndex, stmfViewEntry *ve)
47557836SJohn.Forte@Sun.COM {
47567836SJohn.Forte@Sun.COM 	scf_handle_t	*handle = NULL;
47577836SJohn.Forte@Sun.COM 	scf_service_t	*svc = NULL;
47587836SJohn.Forte@Sun.COM 	scf_propertygroup_t	*pg = NULL;
47597836SJohn.Forte@Sun.COM 	char guidAsciiBuf[33]; /* size of ascii hex 16 byte guid with NULL */
47607836SJohn.Forte@Sun.COM 	char viewEntryPgName[VIEW_ENTRY_PG_SIZE];
47617836SJohn.Forte@Sun.COM 	char luPgName[LOGICAL_UNIT_PG_SIZE];
47627836SJohn.Forte@Sun.COM 	int ret = STMF_PS_SUCCESS;
47637836SJohn.Forte@Sun.COM 
47647836SJohn.Forte@Sun.COM 	ret = iPsInit(&handle, &svc);
47657836SJohn.Forte@Sun.COM 	if (ret != STMF_PS_SUCCESS) {
47667836SJohn.Forte@Sun.COM 		goto out;
47677836SJohn.Forte@Sun.COM 	}
47687836SJohn.Forte@Sun.COM 
47697836SJohn.Forte@Sun.COM 	pg = scf_pg_create(handle);
47707836SJohn.Forte@Sun.COM 	if (pg == NULL) {
47717836SJohn.Forte@Sun.COM 		syslog(LOG_ERR, "scf pg alloc failed - %s",
47727836SJohn.Forte@Sun.COM 		    scf_strerror(scf_error()));
47737836SJohn.Forte@Sun.COM 		ret = STMF_PS_ERROR;
47747836SJohn.Forte@Sun.COM 		goto out;
47757836SJohn.Forte@Sun.COM 	}
47767836SJohn.Forte@Sun.COM 
47777836SJohn.Forte@Sun.COM 	/* Convert to ASCII uppercase hexadecimal string */
47787836SJohn.Forte@Sun.COM 	(void) snprintf(guidAsciiBuf, sizeof (guidAsciiBuf),
47797836SJohn.Forte@Sun.COM 	    "%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X",
47807836SJohn.Forte@Sun.COM 	    lu->guid[0], lu->guid[1], lu->guid[2], lu->guid[3], lu->guid[4],
47817836SJohn.Forte@Sun.COM 	    lu->guid[5], lu->guid[6], lu->guid[7], lu->guid[8], lu->guid[9],
47827836SJohn.Forte@Sun.COM 	    lu->guid[10], lu->guid[11], lu->guid[12], lu->guid[13],
47837836SJohn.Forte@Sun.COM 	    lu->guid[14], lu->guid[15]);
47847836SJohn.Forte@Sun.COM 
47857836SJohn.Forte@Sun.COM 	(void) snprintf(luPgName, sizeof (luPgName), "%s-%s",
47867836SJohn.Forte@Sun.COM 	    STMF_LU_PREFIX, guidAsciiBuf);
47877836SJohn.Forte@Sun.COM 
47887836SJohn.Forte@Sun.COM 	/*
47897836SJohn.Forte@Sun.COM 	 * Format of view entry property group name:
47907836SJohn.Forte@Sun.COM 	 *	VE-<view_entry_index>-<lu_name>
47917836SJohn.Forte@Sun.COM 	 */
47927836SJohn.Forte@Sun.COM 	(void) snprintf(viewEntryPgName, sizeof (viewEntryPgName),
47937836SJohn.Forte@Sun.COM 	    "%s-%d-%s", STMF_VE_PREFIX, viewEntryIndex, guidAsciiBuf);
47947836SJohn.Forte@Sun.COM 
47957836SJohn.Forte@Sun.COM 	if (scf_service_get_pg(svc, viewEntryPgName, pg) == -1) {
47967836SJohn.Forte@Sun.COM 		if (scf_error() == SCF_ERROR_NOT_FOUND) {
47977836SJohn.Forte@Sun.COM 			ret = STMF_PS_ERROR_NOT_FOUND;
47987836SJohn.Forte@Sun.COM 		} else {
4799*11909SPeter.Gill@Sun.COM 			syslog(LOG_ERR, "get pg %s failed - %s",
4800*11909SPeter.Gill@Sun.COM 			    viewEntryPgName, scf_strerror(scf_error()));
48017836SJohn.Forte@Sun.COM 			ret = STMF_PS_ERROR;
48027836SJohn.Forte@Sun.COM 		}
48037836SJohn.Forte@Sun.COM 		goto out;
48047836SJohn.Forte@Sun.COM 	}
48057836SJohn.Forte@Sun.COM 
48067836SJohn.Forte@Sun.COM 
48077836SJohn.Forte@Sun.COM 	if ((ret = iPsGetViewEntry(viewEntryPgName, ve)) != STMF_PS_SUCCESS) {
48087836SJohn.Forte@Sun.COM 		ret = STMF_PS_ERROR;
48097836SJohn.Forte@Sun.COM 		goto out;
48107836SJohn.Forte@Sun.COM 	}
48117836SJohn.Forte@Sun.COM 
48127836SJohn.Forte@Sun.COM out:
48137836SJohn.Forte@Sun.COM 	/*
48147836SJohn.Forte@Sun.COM 	 * Free resources
48157836SJohn.Forte@Sun.COM 	 */
48167836SJohn.Forte@Sun.COM 	if (handle != NULL) {
48177836SJohn.Forte@Sun.COM 		scf_handle_destroy(handle);
48187836SJohn.Forte@Sun.COM 	}
48197836SJohn.Forte@Sun.COM 	if (svc != NULL) {
48207836SJohn.Forte@Sun.COM 		scf_service_destroy(svc);
48217836SJohn.Forte@Sun.COM 	}
48227836SJohn.Forte@Sun.COM 	if (pg != NULL) {
48237836SJohn.Forte@Sun.COM 		scf_pg_destroy(pg);
48247836SJohn.Forte@Sun.COM 	}
48257836SJohn.Forte@Sun.COM 
48267836SJohn.Forte@Sun.COM 	return (ret);
48277836SJohn.Forte@Sun.COM }
48287836SJohn.Forte@Sun.COM 
48297836SJohn.Forte@Sun.COM /*
48307836SJohn.Forte@Sun.COM  * psRemoveViewEntry
48317836SJohn.Forte@Sun.COM  *
48327836SJohn.Forte@Sun.COM  * Remove a view entry
48337836SJohn.Forte@Sun.COM  *
48347836SJohn.Forte@Sun.COM  * luGuid - identifier of logical unit from which to remove view entry
48357836SJohn.Forte@Sun.COM  * viewEntryIndex - view entry name to remove
48367836SJohn.Forte@Sun.COM  *
48377836SJohn.Forte@Sun.COM  * returns:
48387836SJohn.Forte@Sun.COM  *  STMF_PS_SUCCESS on success
48397836SJohn.Forte@Sun.COM  *  STMF_PS_ERROR_* on failure
48407836SJohn.Forte@Sun.COM  */
48417836SJohn.Forte@Sun.COM int
48427836SJohn.Forte@Sun.COM psRemoveViewEntry(stmfGuid *lu, uint32_t viewEntryIndex)
48437836SJohn.Forte@Sun.COM {
48447836SJohn.Forte@Sun.COM 	scf_handle_t	*handle = NULL;
48457836SJohn.Forte@Sun.COM 	scf_service_t	*svc = NULL;
48467836SJohn.Forte@Sun.COM 	scf_propertygroup_t	*pg = NULL;
48477836SJohn.Forte@Sun.COM 	char guidAsciiBuf[33]; /* size of ascii hex 16 byte guid with NULL */
48487836SJohn.Forte@Sun.COM 	char viewEntryPgName[VIEW_ENTRY_PG_SIZE];
48497836SJohn.Forte@Sun.COM 	char luPgName[LOGICAL_UNIT_PG_SIZE];
48507836SJohn.Forte@Sun.COM 	int ret = STMF_PS_SUCCESS;
48517836SJohn.Forte@Sun.COM 	sigset_t sigmaskRestore;
48527836SJohn.Forte@Sun.COM 
48537836SJohn.Forte@Sun.COM 	/* grab the signal hold lock */
48547836SJohn.Forte@Sun.COM 	(void) pthread_mutex_lock(&sigSetLock);
48557836SJohn.Forte@Sun.COM 
48567836SJohn.Forte@Sun.COM 	/*
48577836SJohn.Forte@Sun.COM 	 * hold signals until we're done
48587836SJohn.Forte@Sun.COM 	 */
48597836SJohn.Forte@Sun.COM 	if (holdSignal(&sigmaskRestore) != 0) {
48607836SJohn.Forte@Sun.COM 		(void) pthread_mutex_unlock(&sigSetLock);
48617836SJohn.Forte@Sun.COM 		return (STMF_PS_ERROR);
48627836SJohn.Forte@Sun.COM 	}
48637836SJohn.Forte@Sun.COM 
48647836SJohn.Forte@Sun.COM 	ret = iPsInit(&handle, &svc);
48657836SJohn.Forte@Sun.COM 	if (ret != STMF_PS_SUCCESS) {
48667836SJohn.Forte@Sun.COM 		goto out;
48677836SJohn.Forte@Sun.COM 	}
48687836SJohn.Forte@Sun.COM 
48697836SJohn.Forte@Sun.COM 	pg = scf_pg_create(handle);
48707836SJohn.Forte@Sun.COM 	if (pg == NULL) {
48717836SJohn.Forte@Sun.COM 		syslog(LOG_ERR, "scf pg alloc failed - %s",
48727836SJohn.Forte@Sun.COM 		    scf_strerror(scf_error()));
48737836SJohn.Forte@Sun.COM 		ret = STMF_PS_ERROR;
48747836SJohn.Forte@Sun.COM 		goto out;
48757836SJohn.Forte@Sun.COM 	}
48767836SJohn.Forte@Sun.COM 
48777836SJohn.Forte@Sun.COM 	/* Convert to ASCII uppercase hexadecimal string */
48787836SJohn.Forte@Sun.COM 	(void) snprintf(guidAsciiBuf, sizeof (guidAsciiBuf),
48797836SJohn.Forte@Sun.COM 	    "%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X",
48807836SJohn.Forte@Sun.COM 	    lu->guid[0], lu->guid[1], lu->guid[2], lu->guid[3], lu->guid[4],
48817836SJohn.Forte@Sun.COM 	    lu->guid[5], lu->guid[6], lu->guid[7], lu->guid[8], lu->guid[9],
48827836SJohn.Forte@Sun.COM 	    lu->guid[10], lu->guid[11], lu->guid[12], lu->guid[13],
48837836SJohn.Forte@Sun.COM 	    lu->guid[14], lu->guid[15]);
48847836SJohn.Forte@Sun.COM 
48857836SJohn.Forte@Sun.COM 	(void) snprintf(luPgName, sizeof (luPgName), "%s-%s",
48867836SJohn.Forte@Sun.COM 	    STMF_LU_PREFIX, guidAsciiBuf);
48877836SJohn.Forte@Sun.COM 
48887836SJohn.Forte@Sun.COM 	/*
48897836SJohn.Forte@Sun.COM 	 * Format of view entry property group name:
48907836SJohn.Forte@Sun.COM 	 *	VE-<view_entry_index>-<lu_name>
48917836SJohn.Forte@Sun.COM 	 */
48927836SJohn.Forte@Sun.COM 	(void) snprintf(viewEntryPgName, sizeof (viewEntryPgName),
48937836SJohn.Forte@Sun.COM 	    "%s-%d-%s", STMF_VE_PREFIX, viewEntryIndex, guidAsciiBuf);
48947836SJohn.Forte@Sun.COM 
48957836SJohn.Forte@Sun.COM 	if (scf_service_get_pg(svc, viewEntryPgName, pg) == -1) {
48967836SJohn.Forte@Sun.COM 		if (scf_error() == SCF_ERROR_NOT_FOUND) {
48977836SJohn.Forte@Sun.COM 			ret = STMF_PS_ERROR_NOT_FOUND;
48987836SJohn.Forte@Sun.COM 		} else {
4899*11909SPeter.Gill@Sun.COM 			syslog(LOG_ERR, "get pg %s failed - %s",
4900*11909SPeter.Gill@Sun.COM 			    viewEntryPgName, scf_strerror(scf_error()));
49017836SJohn.Forte@Sun.COM 			ret = STMF_PS_ERROR;
49027836SJohn.Forte@Sun.COM 		}
49037836SJohn.Forte@Sun.COM 		goto out;
49047836SJohn.Forte@Sun.COM 	}
49057836SJohn.Forte@Sun.COM 
49067836SJohn.Forte@Sun.COM 	/*
49077836SJohn.Forte@Sun.COM 	 * update the logical unit property group to remove
49087836SJohn.Forte@Sun.COM 	 * the view entry and update the view entry count
49097836SJohn.Forte@Sun.COM 	 * If it fails, we won't delete the property group so that
49107836SJohn.Forte@Sun.COM 	 * we maintain consistency.
49117836SJohn.Forte@Sun.COM 	 */
49127836SJohn.Forte@Sun.COM 	if ((ret = iPsAddRemoveLuViewEntry(luPgName, viewEntryPgName,
49137836SJohn.Forte@Sun.COM 	    REMOVE)) != STMF_PS_SUCCESS) {
49147836SJohn.Forte@Sun.COM 		goto out;
49157836SJohn.Forte@Sun.COM 	}
49167836SJohn.Forte@Sun.COM 
49177836SJohn.Forte@Sun.COM 	/*
49187836SJohn.Forte@Sun.COM 	 * Delete the view entry. If this fails, we should try to add
49197836SJohn.Forte@Sun.COM 	 * the logical unit view entry property group back otherwise
49207836SJohn.Forte@Sun.COM 	 * we're inconsistent.
49217836SJohn.Forte@Sun.COM 	 */
49227836SJohn.Forte@Sun.COM 	if (scf_pg_delete(pg) == -1) {
4923*11909SPeter.Gill@Sun.COM 		syslog(LOG_ERR, "delete pg %s failed - %s", viewEntryPgName,
49247836SJohn.Forte@Sun.COM 		    scf_strerror(scf_error()));
49257836SJohn.Forte@Sun.COM 		if ((ret = iPsAddRemoveLuViewEntry(luPgName, viewEntryPgName,
49267836SJohn.Forte@Sun.COM 		    ADD)) != STMF_PS_SUCCESS) {
4927*11909SPeter.Gill@Sun.COM 			syslog(LOG_ERR, "add of view entry %s failed, possible"
4928*11909SPeter.Gill@Sun.COM 			    "inconsistency - %s", viewEntryPgName,
4929*11909SPeter.Gill@Sun.COM 			    scf_strerror(scf_error()));
49307836SJohn.Forte@Sun.COM 		}
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 out:
49367836SJohn.Forte@Sun.COM 	/*
49377836SJohn.Forte@Sun.COM 	 * Okay, we're done. Release the signals
49387836SJohn.Forte@Sun.COM 	 */
49397836SJohn.Forte@Sun.COM 	if (releaseSignal(&sigmaskRestore) != 0) {
49407836SJohn.Forte@Sun.COM 		/*
49417836SJohn.Forte@Sun.COM 		 * Don't set this as an STMF_PS_ERROR_*. We succeeded
49427836SJohn.Forte@Sun.COM 		 * the requested operation. But we do need to log it.
49437836SJohn.Forte@Sun.COM 		 */
49447836SJohn.Forte@Sun.COM 		syslog(LOG_ERR, "Unable to release one or more signals - %s",
49457836SJohn.Forte@Sun.COM 		    strerror(errno));
49467836SJohn.Forte@Sun.COM 	}
49477836SJohn.Forte@Sun.COM 
49487836SJohn.Forte@Sun.COM 	/*
49497836SJohn.Forte@Sun.COM 	 * Free resources
49507836SJohn.Forte@Sun.COM 	 */
49517836SJohn.Forte@Sun.COM 	if (handle != NULL) {
49527836SJohn.Forte@Sun.COM 		scf_handle_destroy(handle);
49537836SJohn.Forte@Sun.COM 	}
49547836SJohn.Forte@Sun.COM 	if (svc != NULL) {
49557836SJohn.Forte@Sun.COM 		scf_service_destroy(svc);
49567836SJohn.Forte@Sun.COM 	}
49577836SJohn.Forte@Sun.COM 	if (pg != NULL) {
49587836SJohn.Forte@Sun.COM 		scf_pg_destroy(pg);
49597836SJohn.Forte@Sun.COM 	}
49607836SJohn.Forte@Sun.COM 
49617836SJohn.Forte@Sun.COM 	/* release the signal hold lock */
49627836SJohn.Forte@Sun.COM 	(void) pthread_mutex_unlock(&sigSetLock);
49637836SJohn.Forte@Sun.COM 
49647836SJohn.Forte@Sun.COM 	return (ret);
49657836SJohn.Forte@Sun.COM }
49667836SJohn.Forte@Sun.COM 
49677836SJohn.Forte@Sun.COM 
49687836SJohn.Forte@Sun.COM 
49697836SJohn.Forte@Sun.COM /*
49707836SJohn.Forte@Sun.COM  * holdSignal
49717836SJohn.Forte@Sun.COM  *
49727836SJohn.Forte@Sun.COM  * Hold SIGINT, SIGTERM, SIGQUIT until further notice.
49737836SJohn.Forte@Sun.COM  *
49747836SJohn.Forte@Sun.COM  * Saves old signal mask on a per thread basis
49757836SJohn.Forte@Sun.COM  * and saves action for the process.
49767836SJohn.Forte@Sun.COM  *
49777836SJohn.Forte@Sun.COM  * Installs action for above signals.
49787836SJohn.Forte@Sun.COM  *
49797836SJohn.Forte@Sun.COM  * locks held: sigSetLock
49807836SJohn.Forte@Sun.COM  *
49817836SJohn.Forte@Sun.COM  * returns:
49827836SJohn.Forte@Sun.COM  *  0 on success
49837836SJohn.Forte@Sun.COM  *  non-zero otherwise
49847836SJohn.Forte@Sun.COM  */
49857836SJohn.Forte@Sun.COM static int
49867836SJohn.Forte@Sun.COM holdSignal(sigset_t *sigmaskRestore)
49877836SJohn.Forte@Sun.COM {
49887836SJohn.Forte@Sun.COM 	struct sigaction act;
49897836SJohn.Forte@Sun.COM 	sigset_t sigmask;
49907836SJohn.Forte@Sun.COM 
49917836SJohn.Forte@Sun.COM 	/*
49927836SJohn.Forte@Sun.COM 	 * Return existing signal mask for this thread
49937836SJohn.Forte@Sun.COM 	 */
49947836SJohn.Forte@Sun.COM 	if (pthread_sigmask(0, NULL, sigmaskRestore) != 0) {
49957836SJohn.Forte@Sun.COM 		return (1);
49967836SJohn.Forte@Sun.COM 	}
49977836SJohn.Forte@Sun.COM 
49987836SJohn.Forte@Sun.COM 	(void) sigemptyset(&act.sa_mask);
49997836SJohn.Forte@Sun.COM 	act.sa_handler = sigHandler;
50007836SJohn.Forte@Sun.COM 	act.sa_flags = 0;
50017836SJohn.Forte@Sun.COM 
50027836SJohn.Forte@Sun.COM 	/*
50037836SJohn.Forte@Sun.COM 	 * Have we set the actions for the signals we want to catch?
50047836SJohn.Forte@Sun.COM 	 */
50057836SJohn.Forte@Sun.COM 	if (!actionSet) {
50067836SJohn.Forte@Sun.COM 		if (sigaction(SIGQUIT, &act, &currentActionQuit) != 0) {
50077836SJohn.Forte@Sun.COM 			return (1);
50087836SJohn.Forte@Sun.COM 		}
50097836SJohn.Forte@Sun.COM 
50107836SJohn.Forte@Sun.COM 		if (sigaction(SIGINT, &act, &currentActionInt) != 0) {
50117836SJohn.Forte@Sun.COM 			return (1);
50127836SJohn.Forte@Sun.COM 		}
50137836SJohn.Forte@Sun.COM 
50147836SJohn.Forte@Sun.COM 		if (sigaction(SIGTERM, &act, &currentActionTerm) != 0) {
50157836SJohn.Forte@Sun.COM 			return (1);
50167836SJohn.Forte@Sun.COM 		}
50177836SJohn.Forte@Sun.COM 
50187836SJohn.Forte@Sun.COM 		actionSet = B_TRUE;
50197836SJohn.Forte@Sun.COM 	}
50207836SJohn.Forte@Sun.COM 
50217836SJohn.Forte@Sun.COM 	/*
50227836SJohn.Forte@Sun.COM 	 * We still need to change the mask for the current thread
50237836SJohn.Forte@Sun.COM 	 */
50247836SJohn.Forte@Sun.COM 	if (sigfillset(&sigmask) != 0) {
50257836SJohn.Forte@Sun.COM 		return (1);
50267836SJohn.Forte@Sun.COM 	}
50277836SJohn.Forte@Sun.COM 
50287836SJohn.Forte@Sun.COM 	(void) sigdelset(&sigmask, SIGQUIT);
50297836SJohn.Forte@Sun.COM 
50307836SJohn.Forte@Sun.COM 	(void) sigdelset(&sigmask, SIGINT);
50317836SJohn.Forte@Sun.COM 
50327836SJohn.Forte@Sun.COM 	(void) sigdelset(&sigmask, SIGTERM);
50337836SJohn.Forte@Sun.COM 
50347836SJohn.Forte@Sun.COM 	if (pthread_sigmask(SIG_SETMASK, &sigmask, NULL) != 0) {
50357836SJohn.Forte@Sun.COM 		return (1);
50367836SJohn.Forte@Sun.COM 	}
50377836SJohn.Forte@Sun.COM 
50387836SJohn.Forte@Sun.COM 	return (0);
50397836SJohn.Forte@Sun.COM }
50407836SJohn.Forte@Sun.COM 
50417836SJohn.Forte@Sun.COM /*
50427836SJohn.Forte@Sun.COM  * releaseSignal
50437836SJohn.Forte@Sun.COM  *
50447836SJohn.Forte@Sun.COM  * Re-install the original signal mask and signal actions
50457836SJohn.Forte@Sun.COM  *
50467836SJohn.Forte@Sun.COM  * Also, raise any signals that were caught during the hold period and clear
50477836SJohn.Forte@Sun.COM  * the signal from the caught set (signalsCaught).
50487836SJohn.Forte@Sun.COM  *
50497836SJohn.Forte@Sun.COM  * locks held: sigSetLock
50507836SJohn.Forte@Sun.COM  *
50517836SJohn.Forte@Sun.COM  * Returns
50527836SJohn.Forte@Sun.COM  *  0 on success
50537836SJohn.Forte@Sun.COM  *  non-zero otherwise
50547836SJohn.Forte@Sun.COM  */
50557836SJohn.Forte@Sun.COM static int
50567836SJohn.Forte@Sun.COM releaseSignal(sigset_t *sigmaskRestore)
50577836SJohn.Forte@Sun.COM {
50587836SJohn.Forte@Sun.COM 	int ret = 0;
50597836SJohn.Forte@Sun.COM 
50607836SJohn.Forte@Sun.COM 	if (sigaction(SIGQUIT, &currentActionQuit, NULL) != 0) {
50617836SJohn.Forte@Sun.COM 		ret = 1;
50627836SJohn.Forte@Sun.COM 	}
50637836SJohn.Forte@Sun.COM 
50647836SJohn.Forte@Sun.COM 	if (sigaction(SIGINT, &currentActionInt, NULL) != 0) {
50657836SJohn.Forte@Sun.COM 		ret = 1;
50667836SJohn.Forte@Sun.COM 	}
50677836SJohn.Forte@Sun.COM 
50687836SJohn.Forte@Sun.COM 	if (sigaction(SIGTERM, &currentActionTerm, NULL) != 0) {
50697836SJohn.Forte@Sun.COM 		ret = 1;
50707836SJohn.Forte@Sun.COM 	}
50717836SJohn.Forte@Sun.COM 
50727836SJohn.Forte@Sun.COM 	actionSet = B_FALSE;
50737836SJohn.Forte@Sun.COM 
50747836SJohn.Forte@Sun.COM 	/*
50757836SJohn.Forte@Sun.COM 	 * Restore previous signal mask for this thread
50767836SJohn.Forte@Sun.COM 	 */
50777836SJohn.Forte@Sun.COM 	if (pthread_sigmask(SIG_SETMASK, sigmaskRestore, NULL) != 0) {
50787836SJohn.Forte@Sun.COM 		syslog(LOG_ERR, "Unable to restore sigmask");
50797836SJohn.Forte@Sun.COM 	}
50807836SJohn.Forte@Sun.COM 
50817836SJohn.Forte@Sun.COM 	/*
50827836SJohn.Forte@Sun.COM 	 * Now raise signals that were raised while we were held
50837836SJohn.Forte@Sun.COM 	 */
50847836SJohn.Forte@Sun.COM 	if (sigismember(&signalsCaught, SIGTERM)) {
50857836SJohn.Forte@Sun.COM 		(void) sigdelset(&signalsCaught, SIGTERM);
50867836SJohn.Forte@Sun.COM 		(void) raise(SIGTERM);
50877836SJohn.Forte@Sun.COM 	}
50887836SJohn.Forte@Sun.COM 
50897836SJohn.Forte@Sun.COM 	if (sigismember(&signalsCaught, SIGINT)) {
50907836SJohn.Forte@Sun.COM 		(void) sigdelset(&signalsCaught, SIGINT);
50917836SJohn.Forte@Sun.COM 		(void) raise(SIGINT);
50927836SJohn.Forte@Sun.COM 	}
50937836SJohn.Forte@Sun.COM 
50947836SJohn.Forte@Sun.COM 	if (sigismember(&signalsCaught, SIGQUIT)) {
50957836SJohn.Forte@Sun.COM 		(void) sigdelset(&signalsCaught, SIGQUIT);
50967836SJohn.Forte@Sun.COM 		(void) raise(SIGQUIT);
50977836SJohn.Forte@Sun.COM 	}
50987836SJohn.Forte@Sun.COM 
50997836SJohn.Forte@Sun.COM 	return (ret);
51007836SJohn.Forte@Sun.COM }
5101