/usr/src/lib/libstmf/common/store.c
C | 5385 lines | 3545 code | 513 blank | 1327 comment | 1281 complexity | 72cecf98ef8b788f39a4e83302e0ed76 MD5 | raw file
Possible License(s): BSD-3-Clause-No-Nuclear-License-2014, MPL-2.0-no-copyleft-exception, AGPL-3.0, GPL-2.0, GPL-3.0, LGPL-3.0, 0BSD, AGPL-1.0, BSD-3-Clause, LGPL-2.1, LGPL-2.0, BSD-2-Clause
Large files files are truncated, but you can click here to view the full file
- /*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms of the
- * Common Development and Distribution License (the "License").
- * You may not use this file except in compliance with the License.
- *
- * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
- * See the License for the specific language governing permissions
- * and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL HEADER in each
- * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
- * If applicable, add the following below this CDDL HEADER, with the
- * fields enclosed by brackets "[]" replaced with your own identifying
- * information: Portions Copyright [yyyy] [name of copyright owner]
- *
- * CDDL HEADER END
- */
- /*
- * Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved.
- * Copyright 2012 Milan Jurik. All rights reserved.
- */
- #include <libscf.h>
- #include <stdio.h>
- #include <stdlib.h>
- #include <errno.h>
- #include <assert.h>
- #include <strings.h>
- #include <libstmf.h>
- #include <store.h>
- #include <syslog.h>
- #include <signal.h>
- #include <pthread.h>
- #include <libnvpair.h>
- #include <limits.h>
- #include <unistd.h>
- /*
- * This file's functions are responsible for all store and retrieve operations
- * against the STMF smf(5) database. The following shows the currently defined
- * schema for the STMF database:
- *
- * Description of property groups for service: svc:/system/stmf
- *
- * Stability: Volatile
- *
- * 1. Property Group: host_groups
- * Properties: group_name-<N> where <N> is an unsigned integer
- * type: ustring
- * contains: group name
- * group_name-<N>-member_list where <N> is an unsigned
- * integer matching a group_name-<N> property.
- * type: ustring
- * contains: list of members
- *
- * Description:
- * Contains the host group names as well as the host group members
- * for each host group.
- *
- * 2. Property Group: target_groups
- * Properties: group_name-<N> where <N> is an unsigned integer
- * type: ustring
- * contains: group name
- * group_name-<N>-member_list where <N> is an unsigned
- * integer matching a group_name-<N> property.
- * type: ustring
- * contains: list of members
- *
- * Description:
- * Contains the target group names as well as the target group
- * members for each target group.
- *
- * 3. Property Group: lu-<GUID>
- * where <GUID> is a 32 character hexadecimal string.
- * Properties: ve_cnt
- * type: count
- * contains: the number of current view entries
- * view-entry-<N>-<GUID> where <N> is an unsigned integer
- * type: ustring
- * contains: nothing. Used as reference to the view
- * entry property group
- *
- * Description:
- * Contains the references to each view entry. One lu-<GUID>
- * property group will exist for each logical unit with 1 or more
- * view entries.
- * Potentially can hold any other data that can be managed on a per
- * logical unit basis.
- *
- * 4. Property Group: view_entry-<N>-<GUID> (matches property in lu-<GUID>
- * property group)
- * Properties: all_hosts
- * type: boolean
- * contains: when true, the value of host_group is
- * ignored
- * all_targets
- * type: boolean
- * contains: when true, the value of target_group is
- * ignored
- * host_group
- * type: ustring
- * contains: host group for logical unit mapping and
- * masking purposes
- * target_group
- * type: ustring
- * contains: target group for logical unit mapping and
- * masking purposes
- * lu_nbr
- * type: opaque
- * contains: the 8-byte SCSI logical unit number for
- * mapping and masking purposes
- * Description:
- * One "view_entry-<N>-<GUID>" property group will exist for each
- * view entry in the system. This property group name maps
- * directly to the "lu-<GUID>" property group with a matching
- * <GUID>.
- *
- * 5. Property Group: provider_data_pg_<provider-name>
- * where <provider-name> is the name of the provider
- * registered with stmf.
- * Properties: provider_data_prop-<N>
- * where <N> is a sequential identifier for the data
- * chunk.
- * type: opaque
- * contains: up to STMF_PROVIDER_DATA_PROP_SIZE bytes
- * of nvlist packed data.
- * provider_data_count
- * type: count
- * contains: the number of provider data chunks
- * provider_data_type
- * type: integer
- * contains: STMF_PORT_PROVIDER_TYPE or
- * STMF_LU_PROVIDER_TYPE
- *
- * Description:
- * Holds the nvlist packed provider data set via
- * stmfSetProviderData and retrieved via stmfGetProviderData. Data
- * is stored in STMF_PROVIDER_DATA_PROP_SIZE chunks. On retrieve,
- * these chunks are reassembled and unpacked.
- *
- */
- static int iPsInit(scf_handle_t **, scf_service_t **);
- static int iPsCreateDeleteGroup(char *, char *, int);
- static int iPsAddRemoveGroupMember(char *, char *, char *, int);
- static int iPsGetGroupList(char *, stmfGroupList **);
- static int iPsGetGroupMemberList(char *, char *, stmfGroupProperties **);
- static int iPsAddViewEntry(char *, char *, stmfViewEntry *);
- static int iPsAddRemoveLuViewEntry(char *, char *, int);
- static int iPsGetViewEntry(char *, stmfViewEntry *);
- static int iPsGetActualGroupName(char *, char *, char *);
- static int iPsGetServiceVersion(uint64_t *, scf_handle_t *, scf_service_t *);
- static int iPsGetSetPersistType(uint8_t *, scf_handle_t *, scf_service_t *,
- int);
- static int iPsGetSetStmfProp(int, char *, int);
- static int viewEntryCompare(const void *, const void *);
- static int holdSignal(sigset_t *);
- static int releaseSignal(sigset_t *);
- static void sigHandler();
- static pthread_mutex_t sigSetLock = PTHREAD_MUTEX_INITIALIZER;
- sigset_t sigSet;
- sigset_t signalsCaught;
- struct sigaction currentActionQuit;
- struct sigaction currentActionTerm;
- struct sigaction currentActionInt;
- boolean_t actionSet = B_FALSE;
- /*
- * Version info for the SMF schema
- */
- #define STMF_SMF_VERSION 1
- /*
- * Note: Do not change these property names and size values.
- * They represent fields in the persistent config and once modified
- * will have a nasty side effect of invalidating the existing store.
- * If you do need to change them, you'll need to use the versioning above
- * to retain backward compatiblity with the previous configuration schema.
- */
- /* BEGIN STORE PROPERTY DEFINITIONS */
- /*
- * Property Group Names and prefixes
- */
- #define STMF_HOST_GROUPS "host_groups"
- #define STMF_TARGET_GROUPS "target_groups"
- #define STMF_VE_PREFIX "view_entry"
- #define STMF_LU_PREFIX "lu"
- #define STMF_DATA_GROUP "stmf_data"
- /*
- * Property names and prefix for logical unit property group
- */
- #define STMF_VE_CNT "ve_cnt"
- #define STMF_GROUP_PREFIX "group_name"
- #define STMF_MEMBER_LIST_SUFFIX "member_list"
- #define STMF_VERSION_NAME "version_name"
- #define STMF_PERSIST_TYPE "persist_method"
- /* Property names for stmf properties */
- #define DEFAULT_LU_STATE "default_lu_state"
- #define DEFAULT_TARGET_PORT_STATE "default_target_state"
- /*
- * Property names for view entry
- */
- #define STMF_VE_ALLHOSTS "all_hosts"
- #define STMF_VE_HOSTGROUP "host_group"
- #define STMF_VE_ALLTARGETS "all_targets"
- #define STMF_VE_TARGETGROUP "target_group"
- #define STMF_VE_LUNBR "lu_nbr"
- /* Property group suffix for provider data */
- #define STMF_PROVIDER_DATA_PREFIX "provider_data_pg_"
- #define STMF_PROVIDER_DATA_PROP_PREFIX "provider_data_prop"
- #define STMF_PROVIDER_DATA_PROP_NAME_SIZE 256
- #define STMF_PROVIDER_DATA_PROP_TYPE "provider_type"
- #define STMF_PROVIDER_DATA_PROP_SET_COUNT "provider_data_set_cnt"
- #define STMF_PROVIDER_DATA_PROP_COUNT "provider_data_cnt"
- #define STMF_SMF_READ_ATTR "solaris.smf.read.stmf"
- #define STMF_PS_PERSIST_NONE "none"
- #define STMF_PS_PERSIST_SMF "smf"
- #define STMF_PROVIDER_DATA_PROP_SIZE 4000
- #define STMF_PS_LU_ONLINE "default_lu_online"
- #define STMF_PS_LU_OFFLINE "default_lu_offline"
- #define STMF_PS_TARGET_PORT_ONLINE "default_target_online"
- #define STMF_PS_TARGET_PORT_OFFLINE "default_target_offline"
- /* END STORE PROPERTY DEFINITIONS */
- /* service name */
- #define STMF_SERVICE "system/stmf"
- /* limits and flag values */
- #define GROUP_MEMBER_ALLOC 100
- #define VIEW_ENTRY_STRUCT_CNT 6
- #define VIEW_ENTRY_PG_SIZE 256
- #define LOGICAL_UNIT_PG_SIZE 256
- #define VIEW_ENTRY_MAX UINT32_MAX
- #define GROUP_MAX UINT64_MAX
- #define ADD 0
- #define REMOVE 1
- #define GET 0
- #define SET 1
- /*
- * sigHandler
- *
- * Catch the signal and set the global signalsCaught to the signal received
- *
- * signalsCaught will be used by releaseSignal to raise this signal when
- * we're done processing our critical code.
- *
- */
- static void
- sigHandler(int sig)
- {
- (void) sigaddset(&signalsCaught, sig);
- }
- /*
- * iPsAddRemoveGroupMember
- *
- * Add or remove a member for a given group
- *
- * pgName - Property group name
- * groupName - group name to which the member is added/removed
- * memberName - member to be added/removed
- * addRemoveFlag - ADD/REMOVE
- *
- * returns:
- * STMF_PS_SUCCESS on success
- * STMF_PS_ERROR_* on failure
- */
- static int
- iPsAddRemoveGroupMember(char *pgName, char *groupName, char *memberName,
- int addRemoveFlag)
- {
- scf_handle_t *handle = NULL;
- scf_service_t *svc = NULL;
- scf_propertygroup_t *pg = NULL;
- scf_property_t *prop = NULL;
- scf_value_t *valueLookup = NULL;
- scf_value_t **valueSet = NULL;
- scf_iter_t *valueIter = NULL;
- scf_transaction_t *tran = NULL;
- scf_transaction_entry_t *entry = NULL;
- int i = 0;
- int lastAlloc;
- int valueArraySize = 0;
- int ret = STMF_PS_SUCCESS;
- char buf[STMF_IDENT_LENGTH];
- int commitRet;
- boolean_t found = B_FALSE;
- assert(pgName != NULL && groupName != NULL && memberName != NULL);
- /*
- * Init the service handle
- */
- ret = iPsInit(&handle, &svc);
- if (ret != STMF_PS_SUCCESS) {
- goto out;
- }
- /*
- * Allocate scf resources
- */
- if (((pg = scf_pg_create(handle)) == NULL) ||
- ((tran = scf_transaction_create(handle)) == NULL) ||
- ((entry = scf_entry_create(handle)) == NULL) ||
- ((prop = scf_property_create(handle)) == NULL) ||
- ((valueIter = scf_iter_create(handle)) == NULL)) {
- syslog(LOG_ERR, "scf alloc resource failed - %s",
- scf_strerror(scf_error()));
- ret = STMF_PS_ERROR;
- goto out;
- }
- /*
- * Get the service property group handle
- */
- if (scf_service_get_pg(svc, pgName, pg) == -1) {
- if (scf_error() == SCF_ERROR_NOT_FOUND) {
- ret = STMF_PS_ERROR_NOT_FOUND;
- } else {
- ret = STMF_PS_ERROR;
- }
- syslog(LOG_ERR, "get pg %s failed - %s",
- pgName, scf_strerror(scf_error()));
- goto out;
- }
- /*
- * Begin the transaction
- */
- if (scf_transaction_start(tran, pg) == -1) {
- syslog(LOG_ERR, "start transaction for %s failed - %s",
- pgName, scf_strerror(scf_error()));
- ret = STMF_PS_ERROR;
- goto out;
- }
- /*
- * We're changing an existing property by adding a propval
- * There are no add semantics in libscf for a property value. We'll
- * need to read in the current properties and apply them all to the
- * set and then add the one we were asked to add or omit the one
- * we were asked to remove.
- */
- if (scf_transaction_property_change(tran, entry, groupName,
- SCF_TYPE_USTRING) == -1) {
- if (scf_error() == SCF_ERROR_NOT_FOUND) {
- ret = STMF_PS_ERROR_GROUP_NOT_FOUND;
- } else {
- ret = STMF_PS_ERROR;
- syslog(LOG_ERR, "tran property change %s/%s "
- "failed - %s", pgName, groupName,
- scf_strerror(scf_error()));
- }
- goto out;
- }
- /*
- * Get the property handle
- */
- if (scf_pg_get_property(pg, groupName, prop) == -1) {
- syslog(LOG_ERR, "get property %s/%s failed - %s",
- pgName, groupName, scf_strerror(scf_error()));
- ret = STMF_PS_ERROR;
- goto out;
- }
- /*
- * Value lookup is used to lookup the existing values
- */
- valueLookup = scf_value_create(handle);
- if (valueLookup == NULL) {
- syslog(LOG_ERR, "scf value alloc for %s failed - %s",
- pgName, scf_strerror(scf_error()));
- ret = STMF_PS_ERROR;
- goto out;
- }
- /*
- * valueIter is the iterator handle, create the resource
- */
- if (scf_iter_property_values(valueIter, prop) == -1) {
- syslog(LOG_ERR, "iter values for %s/%s failed - %s",
- pgName, groupName, scf_strerror(scf_error()));
- ret = STMF_PS_ERROR;
- goto out;
- }
- /*
- * Allocate value resource pointers.
- * We need a value resource for each value as value pointers passed
- * to libscf cannot be destroyed until the commit or destroy on the
- * transaction is done.
- *
- * We're using GROUP_MEMBER_ALLOC initially. If it's not large
- * enough, we'll realloc on the fly
- */
- valueSet = (scf_value_t **)calloc(1, sizeof (*valueSet)
- * (lastAlloc = GROUP_MEMBER_ALLOC));
- if (valueSet == NULL) {
- ret = STMF_PS_ERROR_NOMEM;
- goto out;
- }
- /*
- * Iterate through the existing values
- */
- while (scf_iter_next_value(valueIter, valueLookup) == 1) {
- bzero(buf, sizeof (buf));
- if (scf_value_get_ustring(valueLookup, buf, MAXNAMELEN) == -1) {
- syslog(LOG_ERR, "iter %s/%s value failed - %s",
- pgName, groupName, scf_strerror(scf_error()));
- ret = STMF_PS_ERROR;
- break;
- }
- /*
- * Check for existing
- * If we're adding, it's an error
- * If we're removing, we skip it and simply not
- * add it to the set. Subtraction by omission.
- */
- if ((strlen(buf) == strlen(memberName)) &&
- bcmp(buf, memberName, strlen(buf)) == 0) {
- if (addRemoveFlag == ADD) {
- ret = STMF_PS_ERROR_EXISTS;
- break;
- } else {
- found = B_TRUE;
- continue;
- }
- }
- /*
- * Create the value resource for this iteration
- */
- valueSet[i] = scf_value_create(handle);
- if (valueSet[i] == NULL) {
- syslog(LOG_ERR, "scf value alloc for %s failed - %s",
- pgName, scf_strerror(scf_error()));
- ret = STMF_PS_ERROR;
- break;
- }
- /*
- * Set the value
- */
- if (scf_value_set_ustring(valueSet[i], buf) == -1) {
- syslog(LOG_ERR, "set value for %s/%s failed - %s",
- pgName, groupName, scf_strerror(scf_error()));
- ret = STMF_PS_ERROR;
- break;
- }
- /*
- * Now add the value
- */
- if (scf_entry_add_value(entry, valueSet[i]) == -1) {
- syslog(LOG_ERR, "add value for %s/%s failed - %s",
- pgName, groupName, scf_strerror(scf_error()));
- ret = STMF_PS_ERROR;
- break;
- }
- i++;
- /*
- * realloc if we've hit the previous alloc size
- */
- if (i >= lastAlloc) {
- lastAlloc += GROUP_MEMBER_ALLOC;
- valueSet = realloc(valueSet,
- sizeof (*valueSet) * lastAlloc);
- if (valueSet == NULL) {
- ret = STMF_PS_ERROR;
- break;
- }
- }
- }
- /*
- * set valueArraySize to final allocated length
- * so we can use it to destroy the resources correctly
- */
- valueArraySize = i;
- if (!found && (addRemoveFlag == REMOVE)) {
- ret = STMF_PS_ERROR_MEMBER_NOT_FOUND;
- }
- if (ret != STMF_PS_SUCCESS) {
- goto out;
- }
- /*
- * If we're adding, we have one more step. Add the member to the
- * propval list
- */
- if (addRemoveFlag == ADD) {
- /*
- * Now create the new entry
- */
- valueSet[i] = scf_value_create(handle);
- if (valueSet[i] == NULL) {
- syslog(LOG_ERR, "scf value alloc for %s/%s failed - %s",
- pgName, groupName, scf_strerror(scf_error()));
- ret = STMF_PS_ERROR;
- goto out;
- } else {
- valueArraySize++;
- }
- /*
- * Set the new member name
- */
- if (scf_value_set_ustring(valueSet[i], memberName) == -1) {
- syslog(LOG_ERR, "set value for %s/%s failed - %s",
- pgName, groupName, scf_strerror(scf_error()));
- ret = STMF_PS_ERROR;
- goto out;
- }
- /*
- * Add the new member
- */
- if (scf_entry_add_value(entry, valueSet[i]) == -1) {
- syslog(LOG_ERR, "add value for %s/%s failed - %s",
- pgName, groupName, scf_strerror(scf_error()));
- ret = STMF_PS_ERROR;
- goto out;
- }
- }
- /*
- * Yes, we're finally done. We actually added or removed one entry
- * from the list.
- * Woohoo!
- */
- if ((commitRet = scf_transaction_commit(tran)) != 1) {
- syslog(LOG_ERR, "transaction commit for %s failed - %s",
- pgName, scf_strerror(scf_error()));
- if (commitRet == 0) {
- ret = STMF_PS_ERROR_BUSY;
- } else {
- ret = STMF_PS_ERROR;
- }
- goto out;
- }
- out:
- /*
- * Free resources
- */
- if (handle != NULL) {
- scf_handle_destroy(handle);
- }
- if (svc != NULL) {
- scf_service_destroy(svc);
- }
- if (pg != NULL) {
- scf_pg_destroy(pg);
- }
- if (tran != NULL) {
- scf_transaction_destroy(tran);
- }
- if (entry != NULL) {
- scf_entry_destroy(entry);
- }
- if (prop != NULL) {
- scf_property_destroy(prop);
- }
- if (valueLookup != NULL) {
- scf_value_destroy(valueLookup);
- }
- if (valueIter != NULL) {
- scf_iter_destroy(valueIter);
- }
- /*
- * Free valueSet scf resources
- */
- if (valueArraySize > 0) {
- for (i = 0; i < valueArraySize; i++) {
- scf_value_destroy(valueSet[i]);
- }
- }
- /*
- * Now free the pointer array to the resources
- */
- if (valueSet != NULL) {
- free(valueSet);
- }
- return (ret);
- }
- /*
- * iPsAddRemoveLuViewEntry
- *
- * Adds or removes a view entry name property for a given logical unit
- * property group. There is one logical unit property group for every logical
- * unit that has one or more associated view entries.
- *
- * luPgName - Property group name of logical unit
- * viewEntryPgName - Property group name of view entry
- * addRemoveFlag - ADD_VE/REMOVE_VE
- *
- * returns:
- * STMF_PS_SUCCESS on success
- * STMF_PS_ERROR_* on failure
- */
- static int
- iPsAddRemoveLuViewEntry(char *luPgName, char *viewEntryPgName,
- int addRemoveFlag)
- {
- scf_handle_t *handle = NULL;
- scf_service_t *svc = NULL;
- scf_propertygroup_t *pg = NULL;
- scf_property_t *prop = NULL;
- scf_value_t *value = NULL;
- scf_transaction_t *tran = NULL;
- scf_transaction_entry_t *entry = NULL;
- scf_transaction_entry_t *entryVeName = NULL;
- boolean_t createVeCnt = B_FALSE;
- uint64_t veCnt = 0;
- int ret = STMF_PS_SUCCESS;
- int commitRet;
- assert(luPgName != NULL || viewEntryPgName != NULL);
- assert(!(addRemoveFlag != ADD && addRemoveFlag != REMOVE));
- /*
- * Init the service handle
- */
- ret = iPsInit(&handle, &svc);
- if (ret != STMF_PS_SUCCESS) {
- goto out;
- }
- /*
- * Allocate scf resources
- */
- if (((pg = scf_pg_create(handle)) == NULL) ||
- ((tran = scf_transaction_create(handle)) == NULL) ||
- ((entry = scf_entry_create(handle)) == NULL) ||
- ((prop = scf_property_create(handle)) == NULL) ||
- ((value = scf_value_create(handle)) == NULL)) {
- syslog(LOG_ERR, "scf alloc resource failed - %s",
- scf_strerror(scf_error()));
- ret = STMF_PS_ERROR;
- goto out;
- }
- /* get the LU property group */
- if (scf_service_get_pg(svc, luPgName, pg) == -1) {
- if (scf_error() == SCF_ERROR_NOT_FOUND &&
- addRemoveFlag == ADD) {
- /* if it doesn't exist, create it */
- if (scf_service_add_pg(svc, luPgName,
- SCF_GROUP_APPLICATION, 0, pg) == -1) {
- syslog(LOG_ERR, "add pg %s failed - %s",
- luPgName, scf_strerror(scf_error()));
- ret = STMF_PS_ERROR;
- } else {
- /* we need to create the VE_CNT property */
- createVeCnt = B_TRUE;
- ret = STMF_PS_SUCCESS;
- }
- } else if (scf_error() == SCF_ERROR_NOT_FOUND) {
- ret = STMF_PS_ERROR_NOT_FOUND;
- } else {
- syslog(LOG_ERR, "get lu pg %s failed - %s",
- luPgName, scf_strerror(scf_error()));
- ret = STMF_PS_ERROR;
- }
- if (ret != STMF_PS_SUCCESS) {
- goto out;
- }
- }
- /*
- * Begin the transaction
- */
- if (scf_transaction_start(tran, pg) == -1) {
- syslog(LOG_ERR, "start transaction for %s failed - %s",
- luPgName, scf_strerror(scf_error()));
- ret = STMF_PS_ERROR;
- goto out;
- }
- if (createVeCnt) {
- /*
- * Create the STMF_VE_CNT property. This will keep the current
- * total view entries for this logical unit.
- */
- if (scf_transaction_property_new(tran, entry, STMF_VE_CNT,
- SCF_TYPE_COUNT) == -1) {
- if (scf_error() == SCF_ERROR_EXISTS) {
- ret = STMF_PS_ERROR_EXISTS;
- } else {
- syslog(LOG_ERR,
- "transaction property new %s/%s "
- "failed - %s", luPgName, STMF_VE_CNT,
- scf_strerror(scf_error()));
- ret = STMF_PS_ERROR;
- }
- goto out;
- }
- } else {
- /*
- * The STMF_VE_CNT property already exists. Just update
- * it.
- */
- if (scf_transaction_property_change(tran, entry,
- STMF_VE_CNT, SCF_TYPE_COUNT) == -1) {
- syslog(LOG_ERR, "transaction property %s/%s change "
- "failed - %s", luPgName, STMF_VE_CNT,
- scf_strerror(scf_error()));
- ret = STMF_PS_ERROR;
- goto out;
- }
- /*
- * Get the STMF_VE_CNT property
- */
- if (scf_pg_get_property(pg, STMF_VE_CNT, prop) == -1) {
- syslog(LOG_ERR, "get property %s/%s failed - %s",
- luPgName, STMF_VE_CNT, scf_strerror(scf_error()));
- ret = STMF_PS_ERROR;
- goto out;
- }
- /*
- * Get the STMF_VE_CNT value
- */
- if (scf_property_get_value(prop, value) == -1) {
- syslog(LOG_ERR, "get property %s/%s value failed - %s",
- luPgName, STMF_VE_CNT, scf_strerror(scf_error()));
- ret = STMF_PS_ERROR;
- goto out;
- }
- /*
- * Now get the actual value from the value handle
- */
- if (scf_value_get_count(value, &veCnt) == -1) {
- syslog(LOG_ERR, "get count value %s/%s failed - %s",
- luPgName, STMF_VE_CNT, scf_strerror(scf_error()));
- ret = STMF_PS_ERROR;
- goto out;
- }
- /*
- * Reset the value resource as it is used below
- */
- scf_value_reset(value);
- }
- if (addRemoveFlag == ADD) {
- veCnt++;
- } else {
- /* Check if this is the last one being removed */
- if (veCnt == 1) {
- /*
- * Delete the pg and get out if this is the last
- * view entry
- */
- if (scf_pg_delete(pg) == -1) {
- syslog(LOG_ERR, "delete pg %s failed - %s",
- luPgName, scf_strerror(scf_error()));
- ret = STMF_PS_ERROR;
- }
- goto out;
- } else {
- veCnt--;
- }
- }
- /*
- * Set the view entry count
- */
- scf_value_set_count(value, veCnt);
- /*
- * Add the value to the transaction entry
- */
- if (scf_entry_add_value(entry, value) == -1) {
- syslog(LOG_ERR, "add value %s/%s failed - %s",
- luPgName, STMF_VE_CNT, scf_strerror(scf_error()));
- ret = STMF_PS_ERROR;
- goto out;
- }
- /*
- * Create a transaction entry resource for the view entry name
- */
- entryVeName = scf_entry_create(handle);
- if (entryVeName == NULL) {
- syslog(LOG_ERR, "scf transaction entry alloc %s/%s failed - %s",
- luPgName, viewEntryPgName, scf_strerror(scf_error()));
- ret = STMF_PS_ERROR;
- goto out;
- }
- if (addRemoveFlag == ADD) {
- /*
- * If adding, create a property with the view entry name
- */
- if (scf_transaction_property_new(tran, entryVeName,
- viewEntryPgName, SCF_TYPE_USTRING) == -1) {
- if (scf_error() == SCF_ERROR_EXISTS) {
- ret = STMF_PS_ERROR_EXISTS;
- } else {
- syslog(LOG_ERR,
- "transaction property new %s/%s "
- "failed - %s", luPgName, viewEntryPgName,
- scf_strerror(scf_error()));
- ret = STMF_PS_ERROR;
- }
- goto out;
- }
- } else {
- /*
- * If removing, delete the existing property with the view
- * entry name
- */
- if (scf_transaction_property_delete(tran, entryVeName,
- viewEntryPgName) == -1) {
- if (scf_error() == SCF_ERROR_NOT_FOUND) {
- ret = STMF_PS_ERROR_NOT_FOUND;
- } else {
- syslog(LOG_ERR,
- "transaction property delete %s/%s "
- "failed - %s", luPgName, viewEntryPgName,
- scf_strerror(scf_error()));
- ret = STMF_PS_ERROR;
- }
- goto out;
- }
- }
- /*
- * Commit property transaction
- */
- if ((commitRet = scf_transaction_commit(tran)) != 1) {
- syslog(LOG_ERR, "transaction commit for %s failed - %s",
- luPgName, scf_strerror(scf_error()));
- if (commitRet == 0) {
- ret = STMF_PS_ERROR_BUSY;
- } else {
- ret = STMF_PS_ERROR;
- }
- goto out;
- }
- out:
- /*
- * Free resources
- */
- if (handle != NULL) {
- scf_handle_destroy(handle);
- }
- if (svc != NULL) {
- scf_service_destroy(svc);
- }
- if (pg != NULL) {
- scf_pg_destroy(pg);
- }
- if (tran != NULL) {
- scf_transaction_destroy(tran);
- }
- if (entry != NULL) {
- scf_entry_destroy(entry);
- }
- if (entryVeName != NULL) {
- scf_entry_destroy(entryVeName);
- }
- if (prop != NULL) {
- scf_property_destroy(prop);
- }
- if (value != NULL) {
- scf_value_destroy(value);
- }
- return (ret);
- }
- /*
- * iPsAddViewEntry
- *
- * Add a view entry property group and optionally, a logical unit property
- * group if it does not exist.
- *
- * luName - ascii hexadecimal logical unit identifier
- * viewEntryName - name of view entry (VIEW_ENTRY_nn)
- * viewEntry - pointer to stmfViewEntry structure
- */
- static int
- iPsAddViewEntry(char *luPgName, char *viewEntryPgName, stmfViewEntry *viewEntry)
- {
- scf_handle_t *handle = NULL;
- scf_service_t *svc = NULL;
- scf_propertygroup_t *pg = NULL;
- scf_value_t *value[VIEW_ENTRY_STRUCT_CNT];
- scf_transaction_t *tran = NULL;
- scf_transaction_entry_t *entry[VIEW_ENTRY_STRUCT_CNT];
- int i = 0;
- int j = 0;
- int ret;
- uint8_t scfBool;
- boolean_t createdVePg = B_FALSE;
- int backoutRet;
- int commitRet;
- assert(luPgName != NULL || viewEntryPgName != NULL ||
- viewEntry == NULL);
- bzero(value, sizeof (value));
- bzero(entry, sizeof (entry));
- /*
- * Init the service handle
- */
- ret = iPsInit(&handle, &svc);
- if (ret != STMF_PS_SUCCESS) {
- goto out;
- }
- /*
- * Allocate scf resources
- */
- if (((pg = scf_pg_create(handle)) == NULL) ||
- ((tran = scf_transaction_create(handle)) == NULL)) {
- syslog(LOG_ERR, "scf alloc resource failed - %s",
- scf_strerror(scf_error()));
- ret = STMF_PS_ERROR;
- goto out;
- }
- /*
- * allocate value and entry resources for scf
- */
- for (i = 0; i < VIEW_ENTRY_STRUCT_CNT; i++) {
- if (((value[i] = scf_value_create(handle)) == NULL) ||
- ((entry[i] = scf_entry_create(handle)) == NULL)) {
- syslog(LOG_ERR, "scf alloc resource failed - %s",
- scf_strerror(scf_error()));
- ret = STMF_PS_ERROR;
- goto out;
- }
- }
- i = 0;
- /*
- * Create the View Entry property group
- */
- if (scf_service_add_pg(svc, viewEntryPgName, SCF_GROUP_APPLICATION,
- 0, pg) == -1) {
- if (scf_error() == SCF_ERROR_EXISTS) {
- ret = STMF_PS_ERROR_EXISTS;
- } else {
- syslog(LOG_ERR, "add pg %s failed - %s",
- viewEntryPgName, scf_strerror(scf_error()));
- ret = STMF_PS_ERROR;
- }
- goto out;
- }
- createdVePg = B_TRUE;
- /*
- * Add the view entry as properties on the view entry group
- */
- /*
- * Begin property update transaction
- */
- if (scf_transaction_start(tran, pg) == -1) {
- syslog(LOG_ERR, "start transaction for add %s failed - %s",
- viewEntryPgName, scf_strerror(scf_error()));
- ret = STMF_PS_ERROR;
- goto out;
- }
- /*
- * Add allHosts property
- */
- if (scf_transaction_property_new(tran, entry[i],
- STMF_VE_ALLHOSTS, SCF_TYPE_BOOLEAN) == -1) {
- if (scf_error() == SCF_ERROR_EXISTS) {
- ret = STMF_PS_ERROR_EXISTS;
- } else {
- syslog(LOG_ERR, "transaction property new %s/%s "
- "failed - %s", viewEntryPgName, STMF_VE_ALLHOSTS,
- scf_strerror(scf_error()));
- ret = STMF_PS_ERROR;
- }
- goto out;
- }
- /* Set the allHosts value */
- scfBool = viewEntry->allHosts;
- scf_value_set_boolean(value[i], scfBool);
- /*
- * Add the allHosts value to the transaction
- */
- if (scf_entry_add_value(entry[i], value[i]) == -1) {
- syslog(LOG_ERR, "add value %s/%s failed - %s",
- viewEntryPgName, STMF_VE_ALLHOSTS,
- scf_strerror(scf_error()));
- ret = STMF_PS_ERROR;
- goto out;
- }
- i++;
- /*
- * Create hostGroup property
- */
- if (scf_transaction_property_new(tran, entry[i],
- STMF_VE_HOSTGROUP, SCF_TYPE_USTRING) == -1) {
- if (scf_error() == SCF_ERROR_EXISTS) {
- ret = STMF_PS_ERROR_EXISTS;
- } else {
- syslog(LOG_ERR, "transaction property new %s/%s "
- "failed - %s", viewEntryPgName, STMF_VE_HOSTGROUP,
- scf_strerror(scf_error()));
- ret = STMF_PS_ERROR;
- }
- goto out;
- }
- /*
- * Set the value for hostGroup
- */
- if (scf_value_set_ustring(value[i], viewEntry->hostGroup) == -1) {
- syslog(LOG_ERR, "set value %s/%s failed - %s",
- viewEntryPgName, STMF_VE_HOSTGROUP,
- scf_strerror(scf_error()));
- ret = STMF_PS_ERROR;
- goto out;
- }
- /*
- * Add the hostGroup value to the transaction entry
- */
- if (scf_entry_add_value(entry[i], value[i]) == -1) {
- syslog(LOG_ERR, "add value %s/%s failed - %s",
- viewEntryPgName, STMF_VE_HOSTGROUP,
- scf_strerror(scf_error()));
- ret = STMF_PS_ERROR;
- goto out;
- }
- i++;
- /*
- * Create the allTargets property
- */
- if (scf_transaction_property_new(tran, entry[i],
- STMF_VE_ALLTARGETS, SCF_TYPE_BOOLEAN) == -1) {
- if (scf_error() == SCF_ERROR_EXISTS) {
- ret = STMF_PS_ERROR_EXISTS;
- } else {
- syslog(LOG_ERR, "transaction property new %s/%s "
- "failed - %s", viewEntryPgName, STMF_VE_ALLTARGETS,
- scf_strerror(scf_error()));
- ret = STMF_PS_ERROR;
- }
- goto out;
- }
- /*
- * Set the allTargets value
- */
- scfBool = viewEntry->allTargets;
- scf_value_set_boolean(value[i], scfBool);
- /*
- * Add the allTargets value to the transaction
- */
- if (scf_entry_add_value(entry[i], value[i]) == -1) {
- syslog(LOG_ERR, "add value %s/%s failed - %s",
- viewEntryPgName, STMF_VE_ALLTARGETS,
- scf_strerror(scf_error()));
- ret = STMF_PS_ERROR;
- goto out;
- }
- i++;
- /*
- * Create targetGroup property
- */
- if (scf_transaction_property_new(tran, entry[i],
- STMF_VE_TARGETGROUP, SCF_TYPE_USTRING) == -1) {
- if (scf_error() == SCF_ERROR_EXISTS) {
- ret = STMF_PS_ERROR_EXISTS;
- } else {
- syslog(LOG_ERR, "transaction property new %s/%s "
- "failed - %s", viewEntryPgName,
- STMF_VE_TARGETGROUP, scf_strerror(scf_error()));
- ret = STMF_PS_ERROR;
- }
- goto out;
- }
- /*
- * Set the value for targetGroup
- */
- if (scf_value_set_ustring(value[i], viewEntry->targetGroup) == -1) {
- syslog(LOG_ERR, "set value %s/%s failed - %s",
- viewEntryPgName, STMF_VE_TARGETGROUP,
- scf_strerror(scf_error()));
- ret = STMF_PS_ERROR;
- goto out;
- }
- /*
- * Add targetGroup value to the transaction
- */
- if (scf_entry_add_value(entry[i], value[i]) == -1) {
- syslog(LOG_ERR, "add value %s/%s failed - %s",
- viewEntryPgName, STMF_VE_TARGETGROUP,
- scf_strerror(scf_error()));
- ret = STMF_PS_ERROR;
- goto out;
- }
- i++;
- /*
- * Create the luNbr property
- */
- if (scf_transaction_property_new(tran, entry[i], STMF_VE_LUNBR,
- SCF_TYPE_OPAQUE) == -1) {
- if (scf_error() == SCF_ERROR_EXISTS) {
- ret = STMF_PS_ERROR_EXISTS;
- } else {
- syslog(LOG_ERR, "transaction property new %s/%s "
- "failed - %s", viewEntryPgName, STMF_VE_LUNBR,
- scf_strerror(scf_error()));
- ret = STMF_PS_ERROR;
- }
- goto out;
- }
- /*
- * Set the luNbr
- */
- if (scf_value_set_opaque(value[i], (char *)viewEntry->luNbr,
- sizeof (viewEntry->luNbr)) == -1) {
- syslog(LOG_ERR, "set value %s/%s failed - %s",
- viewEntryPgName, STMF_VE_LUNBR, scf_strerror(scf_error()));
- ret = STMF_PS_ERROR;
- goto out;
- }
- /*
- * Add luNbr to the transaction entry
- */
- if (scf_entry_add_value(entry[i], value[i]) == -1) {
- syslog(LOG_ERR, "add value %s/%s failed - %s",
- viewEntryPgName, STMF_VE_LUNBR, scf_strerror(scf_error()));
- ret = STMF_PS_ERROR;
- goto out;
- }
- /*
- * Now that we've successfully added the view entry,
- * update the logical unit property group or create
- * it if it does not exist
- */
- ret = iPsAddRemoveLuViewEntry(luPgName, viewEntryPgName, ADD);
- /*
- * If we did not add the view entry name to the logical unit,
- * make sure we do not commit the transaction
- */
- if (ret != STMF_PS_SUCCESS) {
- goto out;
- }
- /*
- * Commit property transaction
- */
- if ((commitRet = scf_transaction_commit(tran)) != 1) {
- syslog(LOG_ERR, "transaction commit for add %s failed - %s",
- viewEntryPgName, scf_strerror(scf_error()));
- if (commitRet == 0) {
- ret = STMF_PS_ERROR_BUSY;
- } else {
- ret = STMF_PS_ERROR;
- }
- }
- if (ret != STMF_PS_SUCCESS) {
- /*
- * If we did not commit, try to remove the view entry name
- * from the logical unit.
- * If that fails, we're now inconsistent.
- */
- backoutRet = iPsAddRemoveLuViewEntry(luPgName, viewEntryPgName,
- REMOVE);
- if (backoutRet != STMF_PS_SUCCESS) {
- syslog(LOG_ERR, "remove lu view entry %s failed"
- "possible inconsistency - %s", luPgName,
- scf_strerror(scf_error()));
- }
- /*
- * We are still in an error scenario even though the remove
- * lu view entry succeeded.
- */
- goto out;
- }
- out:
- /*
- * Free resources
- */
- if (handle != NULL) {
- scf_handle_destroy(handle);
- }
- if (svc != NULL) {
- scf_service_destroy(svc);
- }
- /* if there was an error, delete the created pg if one was created */
- if ((ret != STMF_PS_SUCCESS) && createdVePg) {
- if (scf_pg_delete(pg) == -1) {
- syslog(LOG_ERR, "delete VE pg %s failed - %s",
- viewEntryPgName, scf_strerror(scf_error()));
- }
- }
- if (pg != NULL) {
- scf_pg_destroy(pg);
- }
- if (tran != NULL) {
- scf_transaction_destroy(tran);
- }
- /*
- * Free value and entry scf resources
- */
- if (i > 0) {
- for (j = 0; j < VIEW_ENTRY_STRUCT_CNT; j++) {
- if (value[j] != NULL)
- scf_value_destroy(value[j]);
- if (entry[j] != NULL)
- scf_entry_destroy(entry[j]);
- }
- }
- return (ret);
- }
- /*
- * psClearProviderData
- *
- * providerName - name of provider data to clear
- */
- int
- psClearProviderData(char *providerName, int providerType)
- {
- scf_handle_t *handle = NULL;
- scf_service_t *svc = NULL;
- scf_propertygroup_t *pg = NULL;
- char pgName[MAXPATHLEN];
- int ret = STMF_PS_SUCCESS;
- boolean_t pgNotFound = B_FALSE;
- if (providerName == NULL || (providerType != STMF_LU_PROVIDER_TYPE &&
- providerType != STMF_PORT_PROVIDER_TYPE)) {
- ret = STMF_PS_ERROR_INVALID_ARG;
- goto out;
- }
- ret = iPsInit(&handle, &svc);
- if (ret != STMF_PS_SUCCESS) {
- goto out;
- }
- /*
- * Allocate scf resources
- */
- if ((pg = scf_pg_create(handle)) == NULL) {
- syslog(LOG_ERR, "scf alloc resource failed - %s",
- scf_strerror(scf_error()));
- ret = STMF_PS_ERROR;
- goto out;
- }
- /*
- * create the property group name
- */
- (void) snprintf(pgName, sizeof (pgName), "%s%s",
- STMF_PROVIDER_DATA_PREFIX, providerName);
- /*
- * delete provider property group
- */
- if (scf_service_get_pg(svc, pgName, pg) == -1) {
- if (scf_error() != SCF_ERROR_NOT_FOUND) {
- syslog(LOG_ERR, "get pg %s failed - %s",
- pgName, scf_strerror(scf_error()));
- ret = STMF_PS_ERROR;
- goto out;
- } else {
- pgNotFound = B_TRUE;
- }
- }
- if (!pgNotFound && (scf_pg_delete(pg) == -1)) {
- syslog(LOG_ERR, "delete pg %s failed - %s",
- pgName, scf_strerror(scf_error()));
- ret = STMF_PS_ERROR;
- goto out;
- }
- if (pgNotFound) {
- ret = STMF_PS_ERROR_NOT_FOUND;
- }
- out:
- /*
- * Free resources
- */
- if (handle != NULL) {
- scf_handle_destroy(handle);
- }
- if (svc != NULL) {
- scf_service_destroy(svc);
- }
- if (pg != NULL) {
- scf_pg_destroy(pg);
- }
- return (ret);
- }
- /*
- * iPsCreateDeleteGroup
- *
- * Creates or deletes a group (target or host)
- *
- * When creating a group, two properties are created. One to hold the group
- * name and the other to hold the group members.
- *
- * pgName - Property group name
- * groupName - group name to create
- * addRemoveFlag - ADD_GROUP/REMOVE_GROUP
- *
- * returns:
- * STMF_PS_SUCCESS on success
- * STMF_PS_ERROR_* on failure
- */
- static int
- iPsCreateDeleteGroup(char *pgRefName, char *groupName, int addRemoveFlag)
- {
- scf_handle_t *handle = NULL;
- scf_service_t *svc = NULL;
- scf_propertygroup_t *pg = NULL;
- scf_property_t *prop = NULL;
- scf_iter_t *propIter = NULL;
- scf_transaction_t *tran = NULL;
- scf_transaction_entry_t *entry1 = NULL;
- scf_transaction_entry_t *entry2 = NULL;
- scf_value_t *value = NULL;
- uint64_t groupIdx;
- char buf1[MAXNAMELEN];
- char buf2[MAXNAMELEN];
- char tmpbuf[MAXNAMELEN];
- boolean_t found = B_FALSE;
- int ret = STMF_PS_SUCCESS;
- int commitRet;
- assert(groupName != NULL);
- ret = iPsInit(&handle, &svc);
- if (ret != STMF_PS_SUCCESS) {
- goto out;
- }
- /*
- * Allocate scf resources
- */
- if (((pg = scf_pg_create(handle)) == NULL) ||
- ((tran = scf_transaction_create(handle)) == NULL) ||
- ((entry1 = scf_entry_create(handle)) == NULL) ||
- ((entry2 = scf_entry_create(handle)) == NULL) ||
- ((prop = scf_property_create(handle)) == NULL) ||
- ((propIter = scf_iter_create(handle)) == NULL) ||
- ((value = scf_value_create(handle)) == NULL)) {
- syslog(LOG_ERR, "scf alloc resource failed - %s",
- scf_strerror(scf_error()));
- ret = STMF_PS_ERROR;
- goto out;
- }
- /*
- * Get the property group being modified
- */
- if (scf_service_get_pg(svc, pgRefName, pg) == -1) {
- if (scf_error() == SCF_ERROR_NOT_FOUND &&
- addRemoveFlag == ADD) {
- if (scf_service_add_pg(svc, pgRefName,
- SCF_GROUP_APPLICATION, 0, pg) == -1) {
- syslog(LOG_ERR, "add pg %s failed - %s",
- pgRefName, scf_strerror(scf_error()));
- ret = STMF_PS_ERROR;
- }
- } else if (scf_error() == SCF_ERROR_NOT_FOUND) {
- syslog(LOG_ERR, "get pg %s failed - %s",
- pgRefName, scf_strerror(scf_error()));
- ret = STMF_PS_ERROR_NOT_FOUND;
- } else {
- syslog(LOG_ERR, "get pg %s failed - %s",
- pgRefName, scf_strerror(scf_error()));
- ret = STMF_PS_ERROR;
- }
- if (ret != STMF_PS_SUCCESS) {
- goto out;
- }
- }
- /*
- * propIter is the iterator handle
- */
- if (scf_iter_pg_properties(propIter, pg) == -1) {
- syslog(LOG_ERR, "iter properties for %s failed - %s",
- pgRefName, scf_strerror(scf_error()));
- ret = STMF_PS_ERROR;
- goto out;
- }
- /*
- * Iterate through the group names.
- * If we find it in the list, it's an error when addRemoveFlag == ADD.
- */
- while (scf_iter_next_property(propIter, prop) == 1) {
- if (scf_property_get_name(prop, buf1, sizeof (buf1)) == -1) {
- syslog(LOG_ERR, "get name from %s iter failed - %s",
- pgRefName, scf_strerror(scf_error()));
- ret = STMF_PS_ERROR;
- break;
- }
- /*
- * Skip over member list properties
- */
- if (strstr(buf1, STMF_MEMBER_LIST_SUFFIX)) {
- continue;
- }
- if (scf_property_get_value(prop, value) == -1) {
- syslog(LOG_ERR, "get property value %s/%s failed - %s",
- pgRefName, buf1, scf_strerror(scf_error()));
- ret = STMF_PS_ERROR;
- break;
- }
- if (scf_value_get_ustring(value, tmpbuf,
- sizeof (tmpbuf)) == -1) {
- syslog(LOG_ERR, "get ustring %s/%s failed - %s",
- pgRefName, buf1, scf_strerror(scf_error()));
- ret = STMF_PS_ERROR;
- break;
- }
- if ((strlen(tmpbuf) == strlen(groupName)) &&
- bcmp(tmpbuf, groupName, strlen(tmpbuf)) == 0) {
- if (addRemoveFlag == ADD) {
- ret = STMF_PS_ERROR_EXISTS;
- }
- found = B_TRUE;
- /*
- * buf1 contains the name for REMOVE
- */
- break;
- }
- }
- if (ret != STMF_PS_SUCCESS) {
- goto out;
- }
- scf_value_reset(value);
- if (!found && addRemoveFlag == REMOVE) {
- ret = STMF_PS_ERROR_NOT_FOUND;
- goto out;
- }
- /*
- * If we're adding, we need to create a new property name for the
- * new group
- */
- if (addRemoveFlag == ADD) {
- for (groupIdx = 0; groupIdx < GROUP_MAX; groupIdx++) {
- if (snprintf(buf1, sizeof (buf1), "%s-%lld",
- STMF_GROUP_PREFIX, groupIdx) > sizeof (buf1)) {
- syslog(LOG_ERR,
- "buffer overflow on property name %s",
- buf1);
- ret = STMF_PS_ERROR;
- break;
- }
- if (scf_pg_get_property(pg, buf1, prop) == -1) {
- if (scf_error() != SCF_ERROR_NOT_FOUND) {
- syslog(LOG_ERR, "get property %s/%s "
- "failed - %s", pgRefName, buf1,
- scf_strerror(scf_error()));
- ret = STMF_PS_ERROR;
- }
- break;
- }
- }
- }
- /*
- * Now create the new member list property for the new group
- */
- if (snprintf(buf2, sizeof (buf2), "%s-%s", buf1,
- STMF_MEMBER_LIST_SUFFIX) > sizeof (buf2)) {
- syslog(LOG_ERR, "buffer overflow on property name %s",
- buf1);
- ret = STMF_PS_ERROR;
- goto out;
- }
- /*
- * buf1 now contains the name of the property if it was found in the
- * list in the case of delete or the next available property name
- * in the case of create
- *
- * buf2 now contains the member list property name
- */
- if (scf_transaction_start(tran, pg) == -1) {
- syslog(LOG_ERR, "start transaction for %s failed - %s",
- pgRefName, scf_strerror(scf_error()));
- ret = STMF_PS_ERROR;
- goto out;
- }
- if (addRemoveFlag == ADD) {
- /*
- * Create the property 'group name'
- * This is the container for the group name
- */
- if (scf_transaction_property_new(tran, entry1, buf1,
- SCF_TYPE_USTRING) == -1) {
- syslog(LOG_ERR, "transaction property new %s/%s "
- "failed - %s", pgRefName, buf1,
- scf_strerror(scf_error()));
- ret = STMF_PS_ERROR;
- goto out;
- }
- if (scf_value_set_ustring(value, groupName) == -1) {
- syslog(LOG_ERR, "set ustring %s/%s failed - %s",
- pgRefName, buf1, scf_strerror(scf_error()));
- ret = STMF_PS_ERROR;
- goto out;
- }
- if (scf_entry_add_value(entry1, value) == -1) {
- syslog(LOG_ERR, "add value %s/%s failed - %s",
- pgRefName, buf1, scf_strerror(scf_error()));
- ret = STMF_PS_ERROR;
- goto out;
- }
- /*
- * Create the property 'group list'
- * This is the container for the group members
- */
- if (scf_transaction_property_new(tran, entry2, buf2,
- SCF_TYPE_USTRING) == -1) {
- syslog(LOG_ERR, "transaction property new %s/%s "
- "failed - %s", pgRefName, buf2,
- scf_strerror(scf_error()));
- ret = STMF_PS_ERROR;
- goto out;
- }
- } else {
- /*
- * Delete the property 'group name'
- */
- if (scf_transaction_property_delete(tran, entry1, buf1)
- == -1) {
- syslog(LOG_ERR,
- "transaction property delete %s/%s failed - %s",
- pgRefName, buf1, scf_strerror(scf_error()));
- ret = STMF_PS_ERROR;
- goto out;
- }
- /*
- * Delete the property 'group list'
- */
- if (scf_transaction_property_delete(tran, entry2, buf2)
- == -1) {
- syslog(LOG_ERR, "transaction property delete %s/%s "
- "failed - %s", pgRefName, buf2,
- scf_strerror(scf_error()));
- ret = STMF_PS_ERROR;
- goto out;
- }
- }
- if (ret != STMF_PS_SUCCESS) {
- goto out;
- }
- if ((commitRet = scf_transaction_commit(tran)) != 1) {
- syslog(LOG_ERR, "transaction commit for %s failed - %s",
- pgRefName, scf_strerror(scf_error()));
- if (commitRet == 0) {
- ret = STMF_PS_ERROR_BUSY;
- } else {
- ret = STMF_PS_ERROR;
- }
- }
- out:
- /*
- * Free resources
- */
- if (handle != NULL) {
- scf_handle_destroy(handle);
- }
- if (svc != NULL) {
- scf_service_destroy(svc);
- }
- if (pg != NULL) {
- scf_pg_destroy(pg);
- }
- if (tran != NULL) {
- scf_transaction_destroy(tran);
- }
- if (entry1 != NULL) {
- scf_entry_destroy(entry1);
- }
- if (entry2 != NULL) {
- scf_entry_destroy(entry2);
- }
- if (prop != NULL) {
- scf_property_destroy(prop);
- }
- if (propIter != NULL) {
- scf_iter_destroy(propIter);
- }
- if (value != NULL) {
- scf_value_destroy(value);
- }
- return (ret);
- }
- /*
- * iPsGetGroupList
- *
- * pgName - Property group name
- * groupList - pointer to pointer to stmfGroupList structure. On success,
- * contains the list of groups
- *
- * returns:
- * STMF_PS_SUCCESS on success
- * STMF_PS_ERROR_* on failure
- */
- static int
- iPsGetGroupList(char *pgName, stmfGroupList **groupList)
- {
- scf_handle_t *handle = NULL;
- scf_service_t *svc = NULL;
- scf_propertygroup_t *pg = NULL;
- scf_property_t *prop = NULL;
- scf_iter_t *propIter = NULL;
- scf_value_t *value = NULL;
- char buf[MAXNAMELEN];
- int memberCnt = 0;
- int i = 0;
- int ret = STMF_PS_SUCCESS;
- assert(groupList != NULL);
- ret = iPsInit(&handle, &svc);
- if (ret != STMF_PS_SUCCESS) {
- goto out;
- }
- /*
- * Allocate scf resources
- */
- if (((pg = scf_pg_create(handle)) == NULL) ||
- ((prop = scf_property_create(handle)) == NULL) ||
- ((propIter = scf_iter_create(handle)) == NULL) ||
- ((value = scf_value_create(handle)) == NULL)) {
- syslog(LOG_ERR, "scf alloc resource failed - %s",
- scf_strerror(scf_error()));
- ret = STMF_PS_ERROR;
- goto out;
- }
- if (scf_service_get_pg(svc, pgName, pg) == -1) {
- if (scf_error() == SCF_ERROR_NOT_FOUND) {
- syslog(LOG_ERR, "get pg %s failed - %s",
- pgName, scf_strerror(scf_error()));
- ret = STMF_PS_ERROR_NOT_FOUND;
- } else {
- syslog(LOG_ERR, "get pg %s failed - %s",
- pgName, scf_strerror(scf_error()));
- ret = STMF_PS_ERROR;
- }
- goto out;
- }
- /*
- * propIter is the iterator handle
- */
- if (scf_iter_pg_properties(propIter, pg) == -1) {
- syslog(LOG_ERR, "iter properties for %s failed - %s",
- pgName, scf_strerror(scf_error()));
- ret = STMF_PS_ERROR;
- goto out;
- }
- while (scf_iter_next_property(propIter, prop) == 1) {
- if (scf_property_get_name(prop, buf, sizeof (buf)) == -1) {
- syslog(LOG_ERR, "get name from %s iter failed - %s",
- pgName, scf_strerror(scf_error()));
- ret = STMF_PS_ERROR;
- break;
- }
- /*
- * Skip over member list properties
- */
- if (strstr(buf, STMF_MEMBER_LIST_SUFFIX)) {
- continue;
- }
- memberCnt++;
- }
- /*
- * propIter is the iterator handle
- */
- if (scf_iter_pg_properties(propIter, pg) == -1) {
- syslog(LOG_ERR, "iter properties for %s failed - %s",
- pgName, scf_strerror(scf_error()));
- ret = STMF_PS_ERROR;
- goto out;
- }
- *groupList = (stmfGroupList *)calloc(1, sizeof (stmfGroupList) +
- memberCnt * sizeof (stmfGroupName));
- if (*groupList == NULL) {
- ret = STMF_PS_ERROR_NOMEM;
- goto out;
- }
- /*
- * In order to get a list of groups, simply get all of the
- * properties that are not member list properties, i.e. the group
- * name properties.
- * It's possible for this list to grow beyond what was originally
- * read so just ensure we're not writing beyond our allocated buffer
- * by ensuring i < memberCnt
- */
- while ((scf_iter_next_property(propIter, prop) == 1) &&
- (i < memberCnt)) {
- if (scf_property_get_name(prop, buf, sizeof (buf)) == -1) {
- syslog(LOG_ERR, "get name from %s iter failed - %s",
- pgName, scf_strerror(scf_error()));
- ret = STMF_PS_ERROR;
- break;
- }
- /*
- * Skip over member list properties
- */
- if (strstr(buf, STMF_MEMBER_LIST_SUFFIX)) {
- continue;
- }
- if (scf_property_get_value(prop, value) == -1) {
- syslog(LOG_ERR, "get property value %s/%s failed - %s",
- pgName, buf, scf_strerror(scf_error()));
- ret = STMF_PS_ERROR;
- break;
- }
- if (scf_value_get_ustring(value, buf, sizeof (buf)) == -1) {
- syslog(LOG_ERR, "get ustring %s/%s failed - %s",
- pgName, buf, scf_strerror(scf_error()));
- ret = STMF_PS_ERROR;
- break;
- }
- bcopy(buf, (*groupList)->name[i++], strlen(buf));
- (*groupList)->cnt++;
- }
- if (ret != STMF_PS_SUCCESS) {
- free(*groupList);
- goto out;
- }
- out:
- /*
- * Free resources
- */
- if (handle != NULL) {
- scf_handle_destroy(handle);
- }
- if (svc != NULL) {
- scf_service_destroy(svc);
- }
- if (pg != NULL) {
- scf_pg_destroy(pg);
- }
- if (propIter != NULL) {
- scf_iter_destroy(propIter);
- }
- if (prop != NULL) {
- scf_property_destroy(prop);
- }
- if (value != NULL) {
- scf_value_destroy(value);
- }
- return (ret);
- }
- /*
- * iPsGetGroupMemberList
- *
- * pgName - Property group name
- * groupName - group name (host group or target group)
- * groupMemberList - pointer to pointer to stmfGroupProperties structure. On
- * success, contains the list of group members
- *
- * returns:
- * STMF_PS_SUCCESS on success
- * STMF_PS_ERROR_* on failure
- */
- static int
- iPsGetGroupMemberList(char *pgName, char *groupName,
- stmfGroupProperties **groupMemberList)
- {
- scf_handle_t *handle = NULL;
- scf_service_t *svc = NULL;
- scf_propertygroup_t *pg = NULL;
- scf_property_t *prop = NULL;
- scf_value_t *valueLookup = NULL;
- scf_iter_t *valueIter = NULL;
- int i = 0;
- int memberCnt;
- int len;
- int ret = STMF_PS_SUCCESS;
- char buf[MAXNAMELEN];
- assert(pgName != NULL && groupName != NULL);
- /*
- * init the service handle
- */
- ret = iPsInit(&handle, &svc);
- if (ret != STMF_PS_SUCCESS) {
- goto out;
- }
- /*
- * Allocate scf resources
- */
- if (((pg = scf_pg_create(handle)) == NULL) ||
- ((prop = scf_property_create(handle)) == NULL) ||
- ((valueIter = scf_iter_create(handle)) == NULL) ||
- ((valueLookup = scf_value_create(handle)) == NULL)) {
- syslog(LOG_ERR, "scf alloc resource failed - %s",
- scf_strerror(scf_error()));
- ret = STMF_PS_ERROR;
- goto out;
- }
- /*
- * get the service property group handle
- */
- if (scf_service_get_pg(svc, pgName, pg) == -1) {
- if (scf_error() == SCF_ERROR_NOT_FOUND) {
- ret = STMF_PS_ERROR_NOT_FOUND;
- } else {
- ret = STMF_PS_ERROR;
- }
- syslog(LOG_ERR, "get pg %s failed - %s",
- pgName, scf_strerror(scf_error()));
- goto out;
- }
- /*
- * Get the property handle
- * based on the target or host group name
- */
- if (scf_pg_get_property(pg, groupName, prop) == -1) {
- syslog(LOG_ERR, "get property %s/%s failed - %s",
- pgName, groupName, scf_strerror(scf_error()));
- ret = STMF_PS_ERROR;
- goto out;
- }
- /*
- * valueIter is the iterator handle
- */
- if (scf_iter_property_values(valueIter, prop) == -1) {
- syslog(LOG_ERR, "iter value %s/%s failed - %s",
- pgName, groupName, scf_strerror(scf_error()));
- ret = STMF_PS_ERROR;
- goto out;
- }
- while (scf_iter_next_value(valueIter, valueLookup) == 1) {
- if (scf_value_get_ustring(valueLookup, buf, MAXNAMELEN) == -1) {
- syslog(LOG_ERR, "iter value %s/%s failed - %s",
- pgName, groupName, scf_strerror(scf_error()));
- ret = STMF_PS_ERROR;
- break;
- }
- i++;
- }
- /*
- * valueIter is the iterator handle
- */
- if (scf_iter_…
Large files files are truncated, but you can click here to view the full file