#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>
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;
#define STMF_SMF_VERSION 1
#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"
#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"
#define DEFAULT_LU_STATE "default_lu_state"
#define DEFAULT_TARGET_PORT_STATE "default_target_state"
#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"
#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"
#define STMF_SERVICE "system/stmf"
#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
static void
sigHandler(int sig)
{
(void) sigaddset(&signalsCaught, sig);
}
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);
ret = iPsInit(&handle, &svc);
if (ret != STMF_PS_SUCCESS) {
goto out;
}
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;
}
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;
}
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;
}
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;
}
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;
}
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;
}
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;
}
valueSet = (scf_value_t **)calloc(1, sizeof (*valueSet)
* (lastAlloc = GROUP_MEMBER_ALLOC));
if (valueSet == NULL) {
ret = STMF_PS_ERROR_NOMEM;
goto out;
}
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;
}
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;
}
}
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;
}
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;
}
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++;
if (i >= lastAlloc) {
lastAlloc += GROUP_MEMBER_ALLOC;
valueSet = realloc(valueSet,
sizeof (*valueSet) * lastAlloc);
if (valueSet == NULL) {
ret = STMF_PS_ERROR;
break;
}
}
}
valueArraySize = i;
if (!found && (addRemoveFlag == REMOVE)) {
ret = STMF_PS_ERROR_MEMBER_NOT_FOUND;
}
if (ret != STMF_PS_SUCCESS) {
goto out;
}
if (addRemoveFlag == ADD) {
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++;
}
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;
}
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;
}
}
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:
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);
}
if (valueArraySize > 0) {
for (i = 0; i < valueArraySize; i++) {
scf_value_destroy(valueSet[i]);
}
}
if (valueSet != NULL) {
free(valueSet);
}
return (ret);
}
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));
ret = iPsInit(&handle, &svc);
if (ret != STMF_PS_SUCCESS) {
goto out;
}
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;
}
if (scf_service_get_pg(svc, luPgName, pg) == -1) {
if (scf_error() == SCF_ERROR_NOT_FOUND &&
addRemoveFlag == ADD) {
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 {
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;
}
}
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) {
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 {
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;
}
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;
}
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;
}
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;
}
scf_value_reset(value);
}
if (addRemoveFlag == ADD) {
veCnt++;
} else {
if (veCnt == 1) {
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--;
}
}
scf_value_set_count(value, veCnt);
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;
}
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 (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 (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;
}
}
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:
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);
}
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));
ret = iPsInit(&handle, &svc);
if (ret != STMF_PS_SUCCESS) {
goto out;
}
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;
}
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;
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;
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;
}
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;
}
scfBool = viewEntry->allHosts;
scf_value_set_boolean(value[i], scfBool);
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++;
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;
}
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;
}
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++;
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;
}
scfBool = viewEntry->allTargets;
scf_value_set_boolean(value[i], scfBool);
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++;
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;
}
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;
}
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++;
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;
}
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;
}
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;
}
ret = iPsAddRemoveLuViewEntry(luPgName, viewEntryPgName, ADD);
if (ret != STMF_PS_SUCCESS) {
goto out;
}
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) {
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()));
}
goto out;
}
out:
if (handle != NULL) {
scf_handle_destroy(handle);
}
if (svc != NULL) {
scf_service_destroy(svc);
}
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);
}
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);
}
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;
}
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;
}
(void) snprintf(pgName, sizeof (pgName), "%s%s",
STMF_PROVIDER_DATA_PREFIX, providerName);
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:
if (handle != NULL) {
scf_handle_destroy(handle);
}
if (svc != NULL) {
scf_service_destroy(svc);
}
if (pg != NULL) {
scf_pg_destroy(pg);
}
return (ret);
}
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;
}
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;
}
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;
}
}
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;
}
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;
}
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;
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 (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;
}
}
}
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;
}
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) {
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;
}
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 {
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;
}
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:
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);
}
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;
}
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;
}
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;
}
if (strstr(buf, STMF_MEMBER_LIST_SUFFIX)) {
continue;
}
memberCnt++;
}
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;
}
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;
}
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:
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);
}
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);
ret = iPsInit(&handle, &svc);
if (ret != STMF_PS_SUCCESS) {
goto out;
}
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;
}
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;
}
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;
}
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++;
}
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;
}
memberCnt = i;
*groupMemberList = (stmfGroupProperties *)calloc(1,
sizeof (stmfGroupProperties) + memberCnt * sizeof (stmfDevid));
if (*groupMemberList == NULL) {
ret = STMF_PS_ERROR_NOMEM;
goto out;
}
i = 0;
while ((scf_iter_next_value(valueIter, valueLookup) == 1) &&
(i < memberCnt)) {
if ((len = 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;
}
if (len < sizeof (stmfDevid) - 1) {
(*groupMemberList)->name[i].identLength = len;
bcopy(buf,
(*groupMemberList)->name[i++].ident, len);
(*groupMemberList)->cnt++;
} else {
ret = STMF_PS_ERROR;
break;
}
}
if (ret != STMF_PS_SUCCESS) {
free(*groupMemberList);
goto out;
}
out:
if (handle != NULL) {
scf_handle_destroy(handle);
}
if (svc != NULL) {
scf_service_destroy(svc);
}
if (pg != NULL) {
scf_pg_destroy(pg);
}
if (prop != NULL) {
scf_property_destroy(prop);
}
if (valueLookup != NULL) {
scf_value_destroy(valueLookup);
}
if (valueIter != NULL) {
scf_iter_destroy(valueIter);
}
return (ret);
}
int
psGetServicePersist(uint8_t *persistType)
{
scf_handle_t *handle = NULL;
scf_service_t *svc = NULL;
int ret;
ret = iPsInit(&handle, &svc);
if (ret != STMF_PS_SUCCESS) {
return (STMF_PS_ERROR);
}
ret = iPsGetSetPersistType(persistType, handle, svc, GET);
if (handle != NULL) {
scf_handle_destroy(handle);
}
if (svc != NULL) {
scf_service_destroy(svc);
}
return (ret);
}
int
psSetServicePersist(uint8_t persistType)
{
scf_handle_t *handle = NULL;
scf_service_t *svc = NULL;
int ret;
ret = iPsInit(&handle, &svc);
if (ret != STMF_PS_SUCCESS) {
return (STMF_PS_ERROR);
}
ret = iPsGetSetPersistType(&persistType, handle, svc, SET);
if (handle != NULL) {
scf_handle_destroy(handle);
}
if (svc != NULL) {
scf_service_destroy(svc);
}
return (ret);
}
static int
iPsGetSetPersistType(uint8_t *persistType, scf_handle_t *handle,
scf_service_t *svc, int getSet)
{
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;
char iPersistTypeGet[MAXNAMELEN] = {0};
char *iPersistType;
int ret = STMF_PS_SUCCESS;
int commitRet;
if (((pg = scf_pg_create(handle)) == NULL) ||
((prop = scf_property_create(handle)) == NULL) ||
((entry = scf_entry_create(handle)) == NULL) ||
((tran = scf_transaction_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 (getSet == GET) {
*persistType = STMF_PERSIST_SMF;
iPersistType = STMF_PS_PERSIST_SMF;
}
if (getSet == SET) {
if (*persistType == STMF_PERSIST_SMF) {
iPersistType = STMF_PS_PERSIST_SMF;
} else if (*persistType == STMF_PERSIST_NONE) {
iPersistType = STMF_PS_PERSIST_NONE;
} else {
ret = STMF_PS_ERROR;
goto out;
}
}
if (scf_service_get_pg(svc, STMF_DATA_GROUP, 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",
STMF_DATA_GROUP, scf_strerror(scf_error()));
goto out;
}
if (scf_pg_get_property(pg, STMF_PERSIST_TYPE, prop) == -1) {
if (scf_error() == SCF_ERROR_NOT_FOUND) {
ret = STMF_PS_ERROR_NOT_FOUND;
} else {
syslog(LOG_ERR, "get property %s/%s failed - %s",
STMF_DATA_GROUP, STMF_PERSIST_TYPE,
scf_strerror(scf_error()));
ret = STMF_PS_ERROR;
goto out;
}
}
if (ret == STMF_PS_ERROR_NOT_FOUND || getSet == SET) {
if (scf_transaction_start(tran, pg) == -1) {
syslog(LOG_ERR, "start transaction for %s failed - %s",
STMF_DATA_GROUP, scf_strerror(scf_error()));
ret = STMF_PS_ERROR;
goto out;
}
if (ret) {
if (scf_transaction_property_new(tran, entry,
STMF_PERSIST_TYPE, SCF_TYPE_ASTRING) == -1) {
syslog(LOG_ERR, "transaction property new "
"%s/%s failed - %s", STMF_DATA_GROUP,
STMF_PERSIST_TYPE,
scf_strerror(scf_error()));
ret = STMF_PS_ERROR;
goto out;
}
} else {
if (scf_transaction_property_change(tran, entry,
STMF_PERSIST_TYPE, SCF_TYPE_ASTRING) == -1) {
syslog(LOG_ERR, "transaction property change "
"%s/%s failed - %s", STMF_DATA_GROUP,
STMF_PERSIST_TYPE,
scf_strerror(scf_error()));
ret = STMF_PS_ERROR;
goto out;
}
}
if (scf_value_set_astring(value, iPersistType) == -1) {
syslog(LOG_ERR, "set value %s/%s failed - %s",
STMF_DATA_GROUP, STMF_PERSIST_TYPE,
scf_strerror(scf_error()));
ret = STMF_PS_ERROR;
goto out;
}
if (scf_entry_add_value(entry, value) == -1) {
syslog(LOG_ERR, "add value %s/%s failed - %s",
STMF_DATA_GROUP, STMF_PERSIST_TYPE,
scf_strerror(scf_error()));
ret = STMF_PS_ERROR;
goto out;
}
if ((commitRet = scf_transaction_commit(tran)) != 1) {
syslog(LOG_ERR, "transaction commit for %s failed - %s",
STMF_DATA_GROUP, scf_strerror(scf_error()));
if (commitRet == 0) {
ret = STMF_PS_ERROR_BUSY;
} else {
ret = STMF_PS_ERROR;
}
goto out;
}
ret = STMF_PS_SUCCESS;
} else if (getSet == GET) {
if (scf_property_get_value(prop, value) == -1) {
syslog(LOG_ERR, "get property value %s/%s failed - %s",
STMF_DATA_GROUP, STMF_PERSIST_TYPE,
scf_strerror(scf_error()));
ret = STMF_PS_ERROR;
goto out;
}
if (scf_value_get_astring(value, iPersistTypeGet, MAXNAMELEN)
== -1) {
syslog(LOG_ERR, "get string value %s/%s failed - %s",
STMF_DATA_GROUP, STMF_PERSIST_TYPE,
scf_strerror(scf_error()));
ret = STMF_PS_ERROR;
goto out;
}
}
if (getSet == GET) {
if (strcmp(iPersistTypeGet, STMF_PS_PERSIST_NONE) == 0) {
*persistType = STMF_PERSIST_NONE;
} else if (strcmp(iPersistTypeGet, STMF_PS_PERSIST_SMF) == 0) {
*persistType = STMF_PERSIST_SMF;
} else {
ret = STMF_PS_ERROR;
goto out;
}
}
out:
if (pg != NULL) {
scf_pg_destroy(pg);
}
if (prop != NULL) {
scf_property_destroy(prop);
}
if (entry != NULL) {
scf_entry_destroy(entry);
}
if (tran != NULL) {
scf_transaction_destroy(tran);
}
if (value != NULL) {
scf_value_destroy(value);
}
return (ret);
}
int
psSetStmfProp(int propType, char *propVal)
{
return (iPsGetSetStmfProp(propType, propVal, SET));
}
int
psGetStmfProp(int propType, char *propVal)
{
return (iPsGetSetStmfProp(propType, propVal, GET));
}
static int
iPsGetSetStmfProp(int propType, char *propVal, int getSet)
{
scf_handle_t *handle = NULL;
scf_service_t *svc = NULL;
scf_property_t *prop = NULL;
scf_propertygroup_t *pg = NULL;
scf_transaction_t *tran = NULL;
scf_transaction_entry_t *entry = NULL;
scf_value_t *value = NULL;
char *psStmfPropVal = NULL;
char *psStmfProp = NULL;
char stmfPropGet[MAXNAMELEN] = {0};
int ret = STMF_PS_SUCCESS;
int commitRet;
if (propVal == NULL || (getSet != GET && getSet != SET)) {
ret = STMF_PS_ERROR;
goto out;
}
ret = iPsInit(&handle, &svc);
if (ret != STMF_PS_SUCCESS) {
goto out;
}
if (((pg = scf_pg_create(handle)) == NULL) ||
((prop = scf_property_create(handle)) == NULL) ||
((entry = scf_entry_create(handle)) == NULL) ||
((tran = scf_transaction_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 (getSet == GET) {
switch (propType) {
case STMF_DEFAULT_LU_STATE :
psStmfProp = DEFAULT_LU_STATE;
psStmfPropVal = STMF_PS_LU_ONLINE;
(void) strcpy(stmfPropGet, psStmfPropVal);
break;
case STMF_DEFAULT_TARGET_PORT_STATE :
psStmfProp = DEFAULT_TARGET_PORT_STATE;
psStmfPropVal = STMF_PS_TARGET_PORT_ONLINE;
(void) strcpy(stmfPropGet, psStmfPropVal);
break;
default :
ret = STMF_PS_ERROR;
goto out;
}
}
if (getSet == SET) {
switch (propType) {
case STMF_DEFAULT_LU_STATE :
psStmfProp = DEFAULT_LU_STATE;
if (strcasecmp(propVal, "online") == 0) {
psStmfPropVal = STMF_PS_LU_ONLINE;
} else if (strcasecmp(propVal,
"offline") == 0) {
psStmfPropVal = STMF_PS_LU_OFFLINE;
} else {
ret = STMF_PS_ERROR;
goto out;
}
break;
case STMF_DEFAULT_TARGET_PORT_STATE :
psStmfProp = DEFAULT_TARGET_PORT_STATE;
if (strcasecmp(propVal, "online") == 0) {
psStmfPropVal =
STMF_PS_TARGET_PORT_ONLINE;
} else if (strcasecmp(propVal,
"offline") == 0) {
psStmfPropVal =
STMF_PS_TARGET_PORT_OFFLINE;
} else {
ret = STMF_PS_ERROR;
goto out;
}
break;
default :
ret = STMF_PS_ERROR;
goto out;
}
}
if (scf_service_get_pg(svc, STMF_DATA_GROUP, 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",
STMF_DATA_GROUP, scf_strerror(scf_error()));
goto out;
}
if (scf_pg_get_property(pg, psStmfProp, prop) == -1) {
if (scf_error() == SCF_ERROR_NOT_FOUND) {
ret = STMF_PS_ERROR_NOT_FOUND;
} else {
syslog(LOG_ERR, "start transaction for %s/%s "
"failed - %s", STMF_DATA_GROUP, psStmfProp,
scf_strerror(scf_error()));
ret = STMF_PS_ERROR;
goto out;
}
}
if (ret == STMF_PS_ERROR_NOT_FOUND || getSet == SET) {
if (scf_transaction_start(tran, pg) == -1) {
syslog(LOG_ERR, "start transaction for %s failed - %s",
STMF_DATA_GROUP, scf_strerror(scf_error()));
ret = STMF_PS_ERROR;
goto out;
}
if (ret) {
if (scf_transaction_property_new(tran, entry,
psStmfProp, SCF_TYPE_ASTRING) == -1) {
syslog(LOG_ERR, "transaction property new "
"%s/%s failed - %s", STMF_DATA_GROUP,
psStmfProp, scf_strerror(scf_error()));
ret = STMF_PS_ERROR;
goto out;
}
} else {
if (scf_transaction_property_change(tran, entry,
psStmfProp, SCF_TYPE_ASTRING) == -1) {
syslog(LOG_ERR,
"transaction property change "
"%s/%s failed - %s",
STMF_DATA_GROUP, psStmfProp,
scf_strerror(scf_error()));
ret = STMF_PS_ERROR;
goto out;
}
}
if (scf_value_set_astring(value, psStmfPropVal) == -1) {
syslog(LOG_ERR, "set value %s/%s failed - %s",
STMF_DATA_GROUP, psStmfProp,
scf_strerror(scf_error()));
ret = STMF_PS_ERROR;
goto out;
}
if (scf_entry_add_value(entry, value) == -1) {
syslog(LOG_ERR, "add value %s/%s failed - %s",
STMF_DATA_GROUP, psStmfProp,
scf_strerror(scf_error()));
ret = STMF_PS_ERROR;
goto out;
}
if ((commitRet = scf_transaction_commit(tran)) != 1) {
syslog(LOG_ERR, "transaction commit for %s"
"failed - %s", STMF_DATA_GROUP,
scf_strerror(scf_error()));
if (commitRet == 0) {
ret = STMF_PS_ERROR_BUSY;
} else {
ret = STMF_PS_ERROR;
}
goto out;
}
ret = STMF_PS_SUCCESS;
} else if (getSet == GET) {
if (scf_property_get_value(prop, value) == -1) {
syslog(LOG_ERR, "get property value "
"%s/%s failed - %s",
STMF_DATA_GROUP, psStmfProp,
scf_strerror(scf_error()));
ret = STMF_PS_ERROR;
goto out;
}
if (scf_value_get_astring(value, stmfPropGet, MAXNAMELEN)
== -1) {
syslog(LOG_ERR, "get string value %s/%s failed - %s",
STMF_DATA_GROUP, psStmfProp,
scf_strerror(scf_error()));
ret = STMF_PS_ERROR;
goto out;
}
}
if (getSet == GET) {
if (strcmp(stmfPropGet, STMF_PS_LU_ONLINE) == 0) {
(void) strcpy(propVal, "online");
} else if (strcmp(stmfPropGet, STMF_PS_LU_OFFLINE) == 0) {
(void) strcpy(propVal, "offline");
} else if (strcmp(stmfPropGet, STMF_PS_TARGET_PORT_ONLINE)
== 0) {
(void) strcpy(propVal, "online");
} else if (strcmp(stmfPropGet, STMF_PS_TARGET_PORT_OFFLINE)
== 0) {
(void) strcpy(propVal, "offline");
} else {
ret = STMF_PS_ERROR;
goto out;
}
}
out:
if (handle != NULL) {
scf_handle_destroy(handle);
}
if (svc != NULL) {
scf_service_destroy(svc);
}
if (pg != NULL) {
scf_pg_destroy(pg);
}
if (prop != NULL) {
scf_property_destroy(prop);
}
if (entry != NULL) {
scf_entry_destroy(entry);
}
if (tran != NULL) {
scf_transaction_destroy(tran);
}
if (value != NULL) {
scf_value_destroy(value);
}
return (ret);
}
static int
iPsInit(scf_handle_t **handle, scf_service_t **service)
{
scf_scope_t *scope = NULL;
uint64_t version;
int ret;
assert(handle != NULL && service != NULL);
if ((*handle = scf_handle_create(SCF_VERSION)) == NULL) {
syslog(LOG_ERR, "scf_handle_create failed - %s",
scf_strerror(scf_error()));
ret = STMF_PS_ERROR;
goto err;
}
if (scf_handle_bind(*handle) == -1) {
syslog(LOG_ERR, "scf_handle_bind failed - %s",
scf_strerror(scf_error()));
ret = STMF_PS_ERROR;
goto err;
}
if ((*service = scf_service_create(*handle)) == NULL) {
syslog(LOG_ERR, "scf_service_create failed - %s",
scf_strerror(scf_error()));
ret = STMF_PS_ERROR;
goto err;
}
if ((scope = scf_scope_create(*handle)) == NULL) {
syslog(LOG_ERR, "scf_scope_create failed - %s",
scf_strerror(scf_error()));
ret = STMF_PS_ERROR;
goto err;
}
if (scf_handle_get_scope(*handle, SCF_SCOPE_LOCAL, scope) == -1) {
syslog(LOG_ERR, "scf_handle_get_scope failed - %s",
scf_strerror(scf_error()));
ret = STMF_PS_ERROR;
goto err;
}
if (scf_scope_get_service(scope, STMF_SERVICE, *service) == -1) {
syslog(LOG_ERR, "scf_scope_get_service failed - %s",
scf_strerror(scf_error()));
ret = STMF_PS_ERROR_SERVICE_NOT_FOUND;
goto err;
}
ret = iPsGetServiceVersion(&version, *handle, *service);
if (ret != STMF_PS_SUCCESS) {
goto err;
}
if (version != STMF_SMF_VERSION) {
ret = STMF_PS_ERROR_VERSION_MISMATCH;
goto err;
}
scf_scope_destroy(scope);
return (STMF_PS_SUCCESS);
err:
if (*handle != NULL) {
scf_handle_destroy(*handle);
}
if (*service != NULL) {
scf_service_destroy(*service);
*service = NULL;
}
if (scope != NULL) {
scf_scope_destroy(scope);
}
return (ret);
}
static int
iPsGetServiceVersion(uint64_t *version, scf_handle_t *handle,
scf_service_t *svc)
{
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;
int ret = STMF_PS_SUCCESS;
int commitRet;
if (((pg = scf_pg_create(handle)) == NULL) ||
((prop = scf_property_create(handle)) == NULL) ||
((entry = scf_entry_create(handle)) == NULL) ||
((tran = scf_transaction_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;
}
*version = STMF_SMF_VERSION;
if (scf_service_get_pg(svc, STMF_DATA_GROUP, pg) == -1) {
if (scf_error() == SCF_ERROR_NOT_FOUND) {
ret = STMF_PS_ERROR_NOT_FOUND;
} else {
syslog(LOG_ERR, "get pg %s failed - %s",
STMF_DATA_GROUP, scf_strerror(scf_error()));
ret = STMF_PS_ERROR;
goto out;
}
}
if (ret == STMF_PS_ERROR_NOT_FOUND) {
if (scf_service_add_pg(svc, STMF_DATA_GROUP,
SCF_GROUP_APPLICATION, 0, pg) == -1) {
syslog(LOG_ERR, "add pg %s failed - %s",
STMF_DATA_GROUP, scf_strerror(scf_error()));
ret = STMF_PS_ERROR;
goto out;
}
ret = STMF_PS_SUCCESS;
}
if (scf_pg_get_property(pg, STMF_VERSION_NAME, prop) == -1) {
if (scf_error() == SCF_ERROR_NOT_FOUND) {
ret = STMF_PS_ERROR_NOT_FOUND;
} else {
syslog(LOG_ERR, "get property %s/%s failed - %s",
STMF_DATA_GROUP, STMF_VERSION_NAME,
scf_strerror(scf_error()));
ret = STMF_PS_ERROR;
goto out;
}
}
if (ret == STMF_PS_ERROR_NOT_FOUND) {
if (scf_transaction_start(tran, pg) == -1) {
syslog(LOG_ERR, "start transaction for %s failed - %s",
STMF_DATA_GROUP, scf_strerror(scf_error()));
ret = STMF_PS_ERROR;
goto out;
}
if (scf_transaction_property_new(tran, entry,
STMF_VERSION_NAME, SCF_TYPE_COUNT) == -1) {
syslog(LOG_ERR,
"transaction property new %s/%s failed - %s",
STMF_DATA_GROUP, STMF_VERSION_NAME,
scf_strerror(scf_error()));
ret = STMF_PS_ERROR;
goto out;
}
scf_value_set_count(value, *version);
if (scf_entry_add_value(entry, value) == -1) {
syslog(LOG_ERR, "add value %s/%s failed - %s",
STMF_DATA_GROUP, STMF_VERSION_NAME,
scf_strerror(scf_error()));
ret = STMF_PS_ERROR;
goto out;
}
if ((commitRet = scf_transaction_commit(tran)) != 1) {
syslog(LOG_ERR, "transaction commit for %s failed - %s",
STMF_DATA_GROUP, scf_strerror(scf_error()));
if (commitRet == 0) {
ret = STMF_PS_ERROR_BUSY;
} else {
ret = STMF_PS_ERROR;
}
goto out;
}
ret = STMF_PS_SUCCESS;
} else {
if (scf_pg_get_property(pg, STMF_VERSION_NAME, prop) == -1) {
syslog(LOG_ERR, "get property %s/%s failed - %s",
STMF_DATA_GROUP, STMF_VERSION_NAME,
scf_strerror(scf_error()));
ret = STMF_PS_ERROR;
goto out;
}
if (scf_property_get_value(prop, value) == -1) {
syslog(LOG_ERR, "get property value %s/%s failed - %s",
STMF_DATA_GROUP, STMF_VERSION_NAME,
scf_strerror(scf_error()));
ret = STMF_PS_ERROR;
goto out;
}
if (scf_value_get_count(value, version) == -1) {
syslog(LOG_ERR, "get count value %s/%s failed - %s",
STMF_DATA_GROUP, STMF_VERSION_NAME,
scf_strerror(scf_error()));
ret = STMF_PS_ERROR;
goto out;
}
}
out:
if (pg != NULL) {
scf_pg_destroy(pg);
}
if (prop != NULL) {
scf_property_destroy(prop);
}
if (entry != NULL) {
scf_entry_destroy(entry);
}
if (tran != NULL) {
scf_transaction_destroy(tran);
}
if (value != NULL) {
scf_value_destroy(value);
}
return (ret);
}
static int
iPsGetActualGroupName(char *pgName, char *groupName, char *actualName)
{
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 ret;
ret = iPsInit(&handle, &svc);
if (ret != STMF_PS_SUCCESS) {
goto out;
}
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) {
ret = STMF_PS_ERROR_GROUP_NOT_FOUND;
} else {
syslog(LOG_ERR, "get pg %s failed - %s",
pgName, scf_strerror(scf_error()));
ret = STMF_PS_ERROR;
}
goto out;
}
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;
}
ret = STMF_PS_ERROR_GROUP_NOT_FOUND;
while (scf_iter_next_property(propIter, prop) == 1) {
if (scf_property_get_name(prop, actualName, MAXNAMELEN) == -1) {
syslog(LOG_ERR, "get name from %s iter failed - %s",
pgName, scf_strerror(scf_error()));
ret = STMF_PS_ERROR;
break;
}
if (strstr(actualName, STMF_MEMBER_LIST_SUFFIX)) {
continue;
}
if (scf_property_get_value(prop, value) == -1) {
syslog(LOG_ERR, "get property value %s/%s failed - %s",
pgName, actualName, 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, actualName, scf_strerror(scf_error()));
ret = STMF_PS_ERROR;
break;
}
if ((strlen(buf) == strlen(groupName)) &&
bcmp(buf, groupName, strlen(buf)) == 0) {
ret = STMF_PS_SUCCESS;
break;
}
}
out:
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);
}
int
psAddHostGroupMember(char *groupName, char *memberName)
{
int ret;
char groupPropListName[MAXNAMELEN];
char groupPropName[MAXNAMELEN];
ret = iPsGetActualGroupName(STMF_HOST_GROUPS, groupName,
groupPropName);
if (ret != STMF_PS_SUCCESS) {
return (ret);
}
if (snprintf(groupPropListName, sizeof (groupPropListName),
"%s-%s", groupPropName, STMF_MEMBER_LIST_SUFFIX) >
sizeof (groupPropListName)) {
syslog(LOG_ERR, "buffer overflow on property name %s",
groupPropName);
return (STMF_PS_ERROR);
}
return (iPsAddRemoveGroupMember(STMF_HOST_GROUPS, groupPropListName,
memberName, ADD));
}
int
psAddTargetGroupMember(char *groupName, char *memberName)
{
int ret;
char groupPropListName[MAXNAMELEN];
char groupPropName[MAXNAMELEN];
ret = iPsGetActualGroupName(STMF_TARGET_GROUPS, groupName,
groupPropName);
if (ret != STMF_PS_SUCCESS) {
return (ret);
}
if (snprintf(groupPropListName, sizeof (groupPropListName),
"%s-%s", groupPropName, STMF_MEMBER_LIST_SUFFIX) >
sizeof (groupPropListName)) {
syslog(LOG_ERR, "buffer overflow on property name %s",
groupPropName);
return (STMF_PS_ERROR);
}
return (iPsAddRemoveGroupMember(STMF_TARGET_GROUPS, groupPropListName,
memberName, ADD));
}
int
psAddViewEntry(stmfGuid *lu, stmfViewEntry *viewEntry)
{
scf_handle_t *handle = NULL;
scf_service_t *svc = NULL;
scf_propertygroup_t *pg = NULL;
char guidAsciiBuf[33];
char viewEntryPgName[VIEW_ENTRY_PG_SIZE];
char scfLuPgName[LOGICAL_UNIT_PG_SIZE];
int ret = STMF_PS_SUCCESS;
sigset_t sigmaskRestore;
(void) pthread_mutex_lock(&sigSetLock);
if (holdSignal(&sigmaskRestore) != 0) {
(void) pthread_mutex_unlock(&sigSetLock);
return (STMF_PS_ERROR);
}
ret = iPsInit(&handle, &svc);
if (ret != STMF_PS_SUCCESS) {
goto out;
}
pg = scf_pg_create(handle);
if (pg == NULL) {
syslog(LOG_ERR, "scf pg alloc failed - %s",
scf_strerror(scf_error()));
ret = STMF_PS_ERROR;
goto out;
}
(void) snprintf(guidAsciiBuf, sizeof (guidAsciiBuf),
"%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X",
lu->guid[0], lu->guid[1], lu->guid[2], lu->guid[3], lu->guid[4],
lu->guid[5], lu->guid[6], lu->guid[7], lu->guid[8], lu->guid[9],
lu->guid[10], lu->guid[11], lu->guid[12], lu->guid[13],
lu->guid[14], lu->guid[15]);
(void) snprintf(scfLuPgName, sizeof (scfLuPgName), "%s-%s",
STMF_LU_PREFIX, guidAsciiBuf);
bzero(viewEntryPgName, sizeof (viewEntryPgName));
(void) snprintf(viewEntryPgName, sizeof (viewEntryPgName),
"%s-%d-%s", STMF_VE_PREFIX, viewEntry->veIndex, guidAsciiBuf);
ret = iPsAddViewEntry(scfLuPgName, viewEntryPgName, viewEntry);
out:
if (releaseSignal(&sigmaskRestore) != 0) {
syslog(LOG_ERR, "Unable to release one or more signals - %s",
strerror(errno));
}
if (handle != NULL) {
scf_handle_destroy(handle);
}
if (svc != NULL) {
scf_service_destroy(svc);
}
if (pg != NULL) {
scf_pg_destroy(pg);
}
(void) pthread_mutex_unlock(&sigSetLock);
return (ret);
}
int
psCheckService()
{
int ret;
scf_handle_t *handle = NULL;
scf_service_t *svc = NULL;
ret = iPsInit(&handle, &svc);
if (handle != NULL) {
scf_handle_destroy(handle);
}
if (svc != NULL) {
scf_service_destroy(svc);
}
return (ret);
}
int
psCreateHostGroup(char *groupName)
{
return (iPsCreateDeleteGroup(STMF_HOST_GROUPS, groupName, ADD));
}
int
psCreateTargetGroup(char *groupName)
{
return (iPsCreateDeleteGroup(STMF_TARGET_GROUPS, groupName, ADD));
}
int
psDeleteHostGroup(char *groupName)
{
return (iPsCreateDeleteGroup(STMF_HOST_GROUPS, groupName, REMOVE));
}
int
psDeleteTargetGroup(char *groupName)
{
return (iPsCreateDeleteGroup(STMF_TARGET_GROUPS, groupName,
REMOVE));
}
int
psGetHostGroupList(stmfGroupList **groupList)
{
return (iPsGetGroupList(STMF_HOST_GROUPS, groupList));
}
int
psGetLogicalUnitList(stmfGuidList **guidList)
{
scf_handle_t *handle = NULL;
scf_service_t *svc = NULL;
scf_propertygroup_t *pg = NULL;
scf_iter_t *pgIter = NULL;
char buf[MAXNAMELEN];
int guidCnt = 0;
int i = 0, j;
int ret = STMF_PS_SUCCESS;
unsigned int guid[sizeof (stmfGuid)];
stmfGuid outGuid;
assert(guidList != NULL);
ret = iPsInit(&handle, &svc);
if (ret != STMF_PS_SUCCESS) {
goto out;
}
if (((pg = scf_pg_create(handle)) == NULL) ||
((pgIter = scf_iter_create(handle)) == NULL)) {
syslog(LOG_ERR, "scf alloc resource failed - %s",
scf_strerror(scf_error()));
ret = STMF_PS_ERROR;
goto out;
}
if (scf_iter_service_pgs(pgIter, svc) == -1) {
syslog(LOG_ERR, "iter property groups failed - %s",
scf_strerror(scf_error()));
ret = STMF_PS_ERROR;
goto out;
}
while (scf_iter_next_pg(pgIter, pg) == 1) {
if (scf_pg_get_name(pg, buf, sizeof (buf)) == -1) {
syslog(LOG_ERR, "get pg name failed - %s",
scf_strerror(scf_error()));
ret = STMF_PS_ERROR;
break;
}
if (strncmp(buf, STMF_LU_PREFIX, strlen(STMF_LU_PREFIX)) == 0) {
guidCnt++;
}
}
if (scf_iter_service_pgs(pgIter, svc) == -1) {
syslog(LOG_ERR, "iter property groups failed - %s",
scf_strerror(scf_error()));
ret = STMF_PS_ERROR;
goto out;
}
*guidList = (stmfGuidList *)calloc(1, sizeof (stmfGuidList) +
guidCnt * sizeof (stmfGuid));
if (*guidList == NULL) {
ret = STMF_PS_ERROR_NOMEM;
goto out;
}
while ((scf_iter_next_pg(pgIter, pg) == 1) && (i < guidCnt)) {
if (scf_pg_get_name(pg, buf, sizeof (buf)) == -1) {
syslog(LOG_ERR, "get pg name failed - %s",
scf_strerror(scf_error()));
ret = STMF_PS_ERROR;
break;
}
if (strncmp(buf, STMF_LU_PREFIX, strlen(STMF_LU_PREFIX)) != 0) {
continue;
}
j = strlen(STMF_LU_PREFIX) + strlen("-");
(void) sscanf(buf + j,
"%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x",
&guid[0], &guid[1], &guid[2], &guid[3], &guid[4], &guid[5],
&guid[6], &guid[7], &guid[8], &guid[9], &guid[10],
&guid[11], &guid[12], &guid[13], &guid[14], &guid[15]);
for (j = 0; j < sizeof (stmfGuid); j++) {
outGuid.guid[j] = guid[j];
}
bcopy(&outGuid, (*guidList)->guid[i++].guid, sizeof (stmfGuid));
(*guidList)->cnt++;
}
if (ret != STMF_PS_SUCCESS) {
free(*guidList);
goto out;
}
out:
if (handle != NULL) {
scf_handle_destroy(handle);
}
if (svc != NULL) {
scf_service_destroy(svc);
}
if (pg != NULL) {
scf_pg_destroy(pg);
}
if (pgIter != NULL) {
scf_iter_destroy(pgIter);
}
return (ret);
}
int
psGetTargetGroupList(stmfGroupList **groupList)
{
return (iPsGetGroupList(STMF_TARGET_GROUPS, groupList));
}
int
psGetHostGroupMemberList(char *groupName, stmfGroupProperties **groupMemberList)
{
int ret;
char groupPropListName[MAXNAMELEN];
char groupPropName[MAXNAMELEN];
ret = iPsGetActualGroupName(STMF_HOST_GROUPS, groupName,
groupPropName);
if (ret != STMF_PS_SUCCESS) {
return (ret);
}
if (snprintf(groupPropListName, sizeof (groupPropListName),
"%s-%s", groupPropName, STMF_MEMBER_LIST_SUFFIX) >
sizeof (groupPropListName)) {
syslog(LOG_ERR, "buffer overflow on property name %s",
groupPropName);
return (STMF_PS_ERROR);
}
return (iPsGetGroupMemberList(STMF_HOST_GROUPS, groupPropListName,
groupMemberList));
}
int
psGetTargetGroupMemberList(char *groupName,
stmfGroupProperties **groupMemberList)
{
int ret;
char groupPropListName[MAXNAMELEN];
char groupPropName[MAXNAMELEN];
ret = iPsGetActualGroupName(STMF_TARGET_GROUPS, groupName,
groupPropName);
if (ret != STMF_PS_SUCCESS) {
return (ret);
}
if (snprintf(groupPropListName, sizeof (groupPropListName),
"%s-%s", groupPropName, STMF_MEMBER_LIST_SUFFIX) >
sizeof (groupPropListName)) {
syslog(LOG_ERR, "buffer overflow on property name %s",
groupPropName);
return (STMF_PS_ERROR);
}
return (iPsGetGroupMemberList(STMF_TARGET_GROUPS,
groupPropListName, groupMemberList));
}
static int
viewEntryCompare(const void *p1, const void *p2)
{
stmfViewEntry *v1 = (stmfViewEntry *)p1, *v2 = (stmfViewEntry *)p2;
if (v1->veIndex > v2->veIndex)
return (1);
if (v1->veIndex < v2->veIndex)
return (-1);
return (0);
}
int
psGetViewEntryList(stmfGuid *lu, stmfViewEntryList **viewEntryList)
{
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_iter_t *propIter = NULL;
char guidAsciiBuf[33];
char viewEntryPgName[VIEW_ENTRY_PG_SIZE];
char luPgName[LOGICAL_UNIT_PG_SIZE];
int ret = STMF_PS_SUCCESS;
uint64_t i = 0;
uint64_t veCnt;
ret = iPsInit(&handle, &svc);
if (ret != STMF_PS_SUCCESS) {
goto out;
}
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;
}
(void) snprintf(guidAsciiBuf, sizeof (guidAsciiBuf),
"%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X",
lu->guid[0], lu->guid[1], lu->guid[2], lu->guid[3], lu->guid[4],
lu->guid[5], lu->guid[6], lu->guid[7], lu->guid[8], lu->guid[9],
lu->guid[10], lu->guid[11], lu->guid[12], lu->guid[13],
lu->guid[14], lu->guid[15]);
(void) snprintf(luPgName, sizeof (luPgName), "%s-%s",
STMF_LU_PREFIX, guidAsciiBuf);
if (scf_service_get_pg(svc, luPgName, pg) == -1) {
if (scf_error() == SCF_ERROR_NOT_FOUND) {
ret = STMF_PS_ERROR_NOT_FOUND;
} else {
syslog(LOG_ERR, "get pg %s failed - %s",
luPgName, scf_strerror(scf_error()));
ret = STMF_PS_ERROR;
}
goto out;
}
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;
}
if (scf_property_get_value(prop, value) == -1) {
syslog(LOG_ERR, "get property value %s/%s failed - %s",
luPgName, STMF_VE_CNT, scf_strerror(scf_error()));
ret = STMF_PS_ERROR;
goto out;
}
if (scf_value_get_count(value, &veCnt) == -1) {
syslog(LOG_ERR, "get integer value %s/%s failed - %s",
luPgName, STMF_VE_CNT, scf_strerror(scf_error()));
ret = STMF_PS_ERROR;
goto out;
}
if (scf_iter_pg_properties(propIter, pg) == -1) {
syslog(LOG_ERR, "iter properties for %s failed - %s",
luPgName, scf_strerror(scf_error()));
ret = STMF_PS_ERROR;
goto out;
}
*viewEntryList = (stmfViewEntryList *)calloc(1,
sizeof (stmfViewEntryList) + veCnt * sizeof (stmfViewEntry));
if (*viewEntryList == NULL) {
ret = STMF_PS_ERROR_NOMEM;
goto out;
}
i = 0;
while (scf_iter_next_property(propIter, prop) == 1) {
if (scf_property_get_name(prop, viewEntryPgName,
sizeof (viewEntryPgName)) != -1) {
if (strncmp(viewEntryPgName, STMF_VE_PREFIX,
strlen(STMF_VE_PREFIX)) != 0) {
continue;
}
if (i == veCnt) {
ret = STMF_PS_ERROR;
break;
}
if ((ret = iPsGetViewEntry(viewEntryPgName,
&((*viewEntryList)->ve[i]))) != STMF_PS_SUCCESS) {
break;
}
i++;
(*viewEntryList)->cnt++;
} else {
syslog(LOG_ERR, "scf iter %s properties failed - %s",
luPgName, scf_strerror(scf_error()));
ret = STMF_PS_ERROR;
break;
}
}
if (ret != STMF_PS_SUCCESS) {
free(*viewEntryList);
goto out;
}
qsort((void *)&((*viewEntryList)->ve[0]), (*viewEntryList)->cnt,
sizeof (stmfViewEntry), viewEntryCompare);
out:
if (handle != NULL) {
scf_handle_destroy(handle);
}
if (svc != NULL) {
scf_service_destroy(svc);
}
if (pg != NULL) {
scf_pg_destroy(pg);
}
if (prop != NULL) {
scf_property_destroy(prop);
}
if (value != NULL) {
scf_value_destroy(value);
}
if (propIter != NULL) {
scf_iter_destroy(propIter);
}
return (ret);
}
static int
iPsGetViewEntry(char *viewEntryPgName, stmfViewEntry *viewEntry)
{
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;
uint8_t scfBool;
char *indexPtr;
char groupName[sizeof (stmfGroupName)];
int ret = STMF_PS_SUCCESS;
ret = iPsInit(&handle, &svc);
if (ret != STMF_PS_SUCCESS) {
goto out;
}
if (((pg = scf_pg_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;
}
bzero(viewEntry, sizeof (stmfViewEntry));
if (scf_service_get_pg(svc, viewEntryPgName, pg) == -1) {
if (scf_error() == SCF_ERROR_NOT_FOUND) {
ret = STMF_PS_ERROR_NOT_FOUND;
} else {
syslog(LOG_ERR, "get pg %s failed - %s",
viewEntryPgName, scf_strerror(scf_error()));
ret = STMF_PS_ERROR;
}
goto out;
}
indexPtr = strchr(viewEntryPgName, '-');
if (!indexPtr) {
ret = STMF_PS_ERROR;
goto out;
}
viewEntry->veIndex = atoi(strtok(++indexPtr, "-"));
viewEntry->veIndexValid = B_TRUE;
if (scf_pg_get_property(pg, STMF_VE_ALLHOSTS,
prop) == -1) {
syslog(LOG_ERR, "get property %s/%s failed - %s",
viewEntryPgName, STMF_VE_ALLHOSTS,
scf_strerror(scf_error()));
ret = STMF_PS_ERROR;
goto out;
}
if (scf_property_get_value(prop, value) == -1) {
syslog(LOG_ERR, "get property %s/%s failed - %s",
viewEntryPgName, STMF_VE_ALLHOSTS,
scf_strerror(scf_error()));
ret = STMF_PS_ERROR;
goto out;
}
if (scf_value_get_boolean(value, (uint8_t *)&scfBool) == -1) {
syslog(LOG_ERR, "get property %s/%s failed - %s",
viewEntryPgName, STMF_VE_ALLHOSTS,
scf_strerror(scf_error()));
ret = STMF_PS_ERROR;
goto out;
}
viewEntry->allHosts = scfBool;
if (scf_pg_get_property(pg, STMF_VE_HOSTGROUP,
prop) == -1) {
syslog(LOG_ERR, "get property %s/%s failed - %s",
viewEntryPgName, STMF_VE_HOSTGROUP,
scf_strerror(scf_error()));
ret = STMF_PS_ERROR;
goto out;
}
if (scf_property_get_value(prop, value) == -1) {
syslog(LOG_ERR, "get property %s/%s failed - %s",
viewEntryPgName, STMF_VE_HOSTGROUP,
scf_strerror(scf_error()));
ret = STMF_PS_ERROR;
goto out;
}
if (scf_value_get_ustring(value, groupName,
sizeof (groupName)) == -1) {
syslog(LOG_ERR, "get value %s/%s failed - %s",
viewEntryPgName, STMF_VE_HOSTGROUP,
scf_strerror(scf_error()));
ret = STMF_PS_ERROR;
goto out;
}
bcopy(groupName, viewEntry->hostGroup, strlen(groupName));
if (scf_pg_get_property(pg, STMF_VE_ALLTARGETS,
prop) == -1) {
syslog(LOG_ERR, "get property %s/%s failed - %s",
viewEntryPgName, STMF_VE_ALLTARGETS,
scf_strerror(scf_error()));
ret = STMF_PS_ERROR;
goto out;
}
if (scf_property_get_value(prop, value) == -1) {
syslog(LOG_ERR, "get property value %s/%s failed - %s",
viewEntryPgName, STMF_VE_ALLTARGETS,
scf_strerror(scf_error()));
ret = STMF_PS_ERROR;
goto out;
}
if (scf_value_get_boolean(value, (uint8_t *)&scfBool) == -1) {
syslog(LOG_ERR, "get value %s/%s failed - %s",
viewEntryPgName, STMF_VE_ALLTARGETS,
scf_strerror(scf_error()));
ret = STMF_PS_ERROR;
goto out;
}
viewEntry->allTargets = scfBool;
if (scf_pg_get_property(pg, STMF_VE_TARGETGROUP, prop) == -1) {
syslog(LOG_ERR, "get property %s/%s failed - %s",
viewEntryPgName, STMF_VE_TARGETGROUP,
scf_strerror(scf_error()));
ret = STMF_PS_ERROR;
goto out;
}
if (scf_property_get_value(prop, value) == -1) {
syslog(LOG_ERR, "get property value %s/%s failed - %s",
viewEntryPgName, STMF_VE_TARGETGROUP,
scf_strerror(scf_error()));
ret = STMF_PS_ERROR;
goto out;
}
if (scf_value_get_ustring(value, groupName,
sizeof (groupName)) == -1) {
syslog(LOG_ERR, "get value %s/%s failed - %s",
viewEntryPgName, STMF_VE_TARGETGROUP,
scf_strerror(scf_error()));
ret = STMF_PS_ERROR;
goto out;
}
bcopy(groupName, viewEntry->targetGroup, strlen(groupName));
if (scf_pg_get_property(pg, STMF_VE_LUNBR,
prop) == -1) {
syslog(LOG_ERR, "get property %s/%s failed - %s",
viewEntryPgName, STMF_VE_LUNBR,
scf_strerror(scf_error()));
ret = STMF_PS_ERROR;
goto out;
}
if (scf_property_get_value(prop, value) == -1) {
syslog(LOG_ERR, "get property value %s/%s failed - %s",
viewEntryPgName, STMF_VE_LUNBR,
scf_strerror(scf_error()));
ret = STMF_PS_ERROR;
goto out;
}
if (scf_value_get_opaque(value, (char *)viewEntry->luNbr,
sizeof (viewEntry->luNbr)) == -1) {
syslog(LOG_ERR, "get opaque value %s/%s failed - %s",
viewEntryPgName, STMF_VE_LUNBR,
scf_strerror(scf_error()));
ret = STMF_PS_ERROR;
goto out;
}
viewEntry->luNbrValid = B_TRUE;
out:
if (handle != NULL) {
scf_handle_destroy(handle);
}
if (svc != NULL) {
scf_service_destroy(svc);
}
if (pg != NULL) {
scf_pg_destroy(pg);
}
if (value != NULL) {
scf_value_destroy(value);
}
if (prop != NULL) {
scf_property_destroy(prop);
}
return (ret);
}
int
psRemoveHostGroupMember(char *groupName, char *memberName)
{
int ret;
char groupPropListName[MAXNAMELEN];
char groupPropName[MAXNAMELEN];
ret = iPsGetActualGroupName(STMF_HOST_GROUPS, groupName,
groupPropName);
if (ret != STMF_PS_SUCCESS) {
return (ret);
}
if (snprintf(groupPropListName, sizeof (groupPropListName),
"%s-%s", groupPropName, STMF_MEMBER_LIST_SUFFIX) >
sizeof (groupPropListName)) {
syslog(LOG_ERR, "buffer overflow on property name %s",
groupPropName);
return (STMF_PS_ERROR);
}
return (iPsAddRemoveGroupMember(STMF_HOST_GROUPS, groupPropListName,
memberName, REMOVE));
}
int
psRemoveTargetGroupMember(char *groupName, char *memberName)
{
int ret;
char groupPropListName[MAXNAMELEN];
char groupPropName[MAXNAMELEN];
ret = iPsGetActualGroupName(STMF_TARGET_GROUPS, groupName,
groupPropName);
if (ret != STMF_PS_SUCCESS) {
return (ret);
}
if (snprintf(groupPropListName, sizeof (groupPropListName),
"%s-%s", groupPropName, STMF_MEMBER_LIST_SUFFIX) >
sizeof (groupPropListName)) {
syslog(LOG_ERR, "buffer overflow on property name %s",
groupPropName);
return (STMF_PS_ERROR);
}
return (iPsAddRemoveGroupMember(STMF_TARGET_GROUPS, groupPropListName,
memberName, REMOVE));
}
int
psGetProviderData(char *providerName, nvlist_t **nvl, int providerType,
uint64_t *setToken)
{
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;
uint64_t blockCnt = 0;
ssize_t blockOffset = 0;
ssize_t actualBlockSize = 0;
char pgName[MAXPATHLEN];
char dataPropertyName[STMF_PROVIDER_DATA_PROP_NAME_SIZE];
char *nvlistEncoded = NULL;
ssize_t nvlistEncodedSize = 0;
boolean_t foundSetCnt = B_TRUE;
int i;
int ret = STMF_PS_SUCCESS;
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;
}
(void) snprintf(pgName, sizeof (pgName), "%s%s",
STMF_PROVIDER_DATA_PREFIX, providerName);
if (((pg = scf_pg_create(handle)) == NULL) ||
((value = scf_value_create(handle)) == NULL) ||
((prop = scf_property_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;
goto out;
} else {
ret = STMF_PS_ERROR_NOT_FOUND;
goto out;
}
}
if (scf_pg_get_property(pg, STMF_PROVIDER_DATA_PROP_COUNT,
prop) == -1) {
syslog(LOG_ERR, "get property %s/%s failed - %s",
pgName, STMF_PROVIDER_DATA_PROP_COUNT,
scf_strerror(scf_error()));
ret = STMF_PS_ERROR;
goto out;
}
if (scf_property_get_value(prop, value) == -1) {
syslog(LOG_ERR, "get property value %s/%s failed - %s",
pgName, STMF_PROVIDER_DATA_PROP_COUNT,
scf_strerror(scf_error()));
ret = STMF_PS_ERROR;
goto out;
}
if (scf_value_get_count(value, &blockCnt) == -1) {
syslog(LOG_ERR, "get integer value %s/%s failed - %s",
pgName, STMF_PROVIDER_DATA_PROP_COUNT,
scf_strerror(scf_error()));
ret = STMF_PS_ERROR;
goto out;
}
if (setToken) {
*setToken = 0;
if (scf_pg_get_property(pg, STMF_PROVIDER_DATA_PROP_SET_COUNT,
prop) == -1) {
if (scf_error() == SCF_ERROR_NOT_FOUND) {
foundSetCnt = B_FALSE;
} else {
syslog(LOG_ERR, "get property %s/%s "
"failed - %s", pgName,
STMF_PROVIDER_DATA_PROP_SET_COUNT,
scf_strerror(scf_error()));
ret = STMF_PS_ERROR;
goto out;
}
}
if (foundSetCnt) {
if (scf_property_get_value(prop, value) == -1) {
syslog(LOG_ERR,
"get property value %s/%s failed - %s",
pgName, STMF_PROVIDER_DATA_PROP_SET_COUNT,
scf_strerror(scf_error()));
ret = STMF_PS_ERROR;
goto out;
}
if (scf_value_get_count(value, setToken) == -1) {
syslog(LOG_ERR,
"get integer value %s/%s failed - %s",
pgName, STMF_PROVIDER_DATA_PROP_SET_COUNT,
scf_strerror(scf_error()));
ret = STMF_PS_ERROR;
goto out;
}
}
}
nvlistEncoded = (char *)calloc(1,
blockCnt * STMF_PROVIDER_DATA_PROP_SIZE);
if (nvlistEncoded == NULL) {
syslog(LOG_ERR, "nvlistEncoded alloc failed");
ret = STMF_PS_ERROR_NOMEM;
goto out;
}
for (i = 0; i < blockCnt; i++) {
bzero(dataPropertyName, sizeof (dataPropertyName));
(void) snprintf(dataPropertyName, sizeof (dataPropertyName),
"%s-%d", STMF_PROVIDER_DATA_PROP_PREFIX, i);
if (scf_pg_get_property(pg, dataPropertyName, prop) == -1) {
syslog(LOG_ERR, "get property %s/%s failed - %s",
pgName, dataPropertyName,
scf_strerror(scf_error()));
ret = STMF_PS_ERROR;
goto out;
}
if (scf_property_get_value(prop, value) == -1) {
syslog(LOG_ERR, "get property value %s/%s failed - %s",
pgName, dataPropertyName,
scf_strerror(scf_error()));
ret = STMF_PS_ERROR;
goto out;
}
blockOffset = STMF_PROVIDER_DATA_PROP_SIZE * i;
actualBlockSize = scf_value_get_opaque(value,
&nvlistEncoded[blockOffset], STMF_PROVIDER_DATA_PROP_SIZE);
if (actualBlockSize == -1) {
syslog(LOG_ERR, "get opaque property value %s/%s "
"failed - %s", pgName, dataPropertyName,
scf_strerror(scf_error()));
ret = STMF_PS_ERROR;
goto out;
}
nvlistEncodedSize += actualBlockSize;
}
if (nvlist_unpack(nvlistEncoded, nvlistEncodedSize, nvl, 0) != 0) {
syslog(LOG_ERR, "unable to unpack nvlist");
ret = STMF_PS_ERROR;
goto out;
}
out:
if (handle != NULL) {
scf_handle_destroy(handle);
}
if (svc != NULL) {
scf_service_destroy(svc);
}
if (pg != NULL) {
scf_pg_destroy(pg);
}
if (prop != NULL) {
scf_property_destroy(prop);
}
if (value != NULL) {
scf_value_destroy(value);
}
if (nvlistEncoded != NULL) {
free(nvlistEncoded);
}
return (ret);
}
int
psGetProviderDataList(stmfProviderList **providerList)
{
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_iter_t *pgIter = NULL;
char buf[MAXNAMELEN];
int providerCnt = 0;
int64_t providerType;
int i = 0, j;
int ret = STMF_PS_SUCCESS;
ret = iPsInit(&handle, &svc);
if (ret != STMF_PS_SUCCESS) {
goto out;
}
*providerList = NULL;
if (((pg = scf_pg_create(handle)) == NULL) ||
((value = scf_value_create(handle)) == NULL) ||
((prop = scf_property_create(handle)) == NULL) ||
((pgIter = scf_iter_create(handle)) == NULL)) {
syslog(LOG_ERR, "scf alloc resource failed - %s",
scf_strerror(scf_error()));
ret = STMF_PS_ERROR;
goto out;
}
if (scf_iter_service_pgs(pgIter, svc) == -1) {
syslog(LOG_ERR, "iter property groups failed - %s",
scf_strerror(scf_error()));
ret = STMF_PS_ERROR;
goto out;
}
while (scf_iter_next_pg(pgIter, pg) == 1) {
if (scf_pg_get_name(pg, buf, sizeof (buf)) == -1) {
syslog(LOG_ERR, "get name failed - %s",
scf_strerror(scf_error()));
ret = STMF_PS_ERROR;
break;
}
if (strncmp(buf, STMF_PROVIDER_DATA_PREFIX,
strlen(STMF_PROVIDER_DATA_PREFIX)) == 0) {
providerCnt++;
}
}
if (scf_iter_service_pgs(pgIter, svc) == -1) {
syslog(LOG_ERR, "iter property groups failed - %s",
scf_strerror(scf_error()));
ret = STMF_PS_ERROR;
goto out;
}
*providerList = (stmfProviderList *)calloc(1,
sizeof (stmfProviderList) + providerCnt * sizeof (stmfProvider));
if (*providerList == NULL) {
ret = STMF_PS_ERROR_NOMEM;
goto out;
}
while ((scf_iter_next_pg(pgIter, pg) == 1) && (i < providerCnt)) {
if (scf_pg_get_name(pg, buf, sizeof (buf)) == -1) {
syslog(LOG_ERR, "get name failed - %s",
scf_strerror(scf_error()));
ret = STMF_PS_ERROR;
break;
}
if (strncmp(buf, STMF_PROVIDER_DATA_PREFIX,
strlen(STMF_PROVIDER_DATA_PREFIX)) != 0) {
continue;
}
if (scf_pg_get_property(pg, STMF_PROVIDER_DATA_PROP_TYPE,
prop) == -1) {
syslog(LOG_ERR, "get property %s/%s failed - %s",
buf, STMF_PROVIDER_DATA_PROP_TYPE,
scf_strerror(scf_error()));
ret = STMF_PS_ERROR;
break;
}
if (scf_property_get_value(prop, value) == -1) {
syslog(LOG_ERR, "get property value %s/%s failed - %s",
buf, STMF_PROVIDER_DATA_PROP_TYPE,
scf_strerror(scf_error()));
ret = STMF_PS_ERROR;
break;
}
if (scf_value_get_integer(value, &providerType) == -1) {
syslog(LOG_ERR, "get integer value %s/%s failed - %s",
buf, STMF_PROVIDER_DATA_PROP_TYPE,
scf_strerror(scf_error()));
ret = STMF_PS_ERROR;
break;
}
(*providerList)->provider[i].providerType = providerType;
j = strlen(STMF_PROVIDER_DATA_PREFIX);
(void) strncpy((*providerList)->provider[i].name, buf + j,
sizeof ((*providerList)->provider[i].name));
i++;
(*providerList)->cnt++;
}
if (ret != STMF_PS_SUCCESS) {
free(*providerList);
goto out;
}
out:
if (handle != NULL) {
scf_handle_destroy(handle);
}
if (svc != NULL) {
scf_service_destroy(svc);
}
if (pg != NULL) {
scf_pg_destroy(pg);
}
if (value != NULL) {
scf_value_destroy(value);
}
if (prop != NULL) {
scf_property_destroy(prop);
}
if (pgIter != NULL) {
scf_iter_destroy(pgIter);
}
return (ret);
}
int
psSetProviderData(char *providerName, nvlist_t *nvl, int providerType,
uint64_t *setToken)
{
scf_handle_t *handle = NULL;
scf_service_t *svc = NULL;
scf_propertygroup_t *pg = NULL;
scf_property_t *prop = NULL;
scf_transaction_t *tran = NULL;
scf_transaction_entry_t **addEntry = NULL;
scf_transaction_entry_t **deleteEntry = NULL;
scf_value_t **addValue = NULL;
scf_transaction_entry_t *entry1 = NULL;
scf_transaction_entry_t *entry2 = NULL;
scf_transaction_entry_t *entry3 = NULL;
scf_transaction_entry_t *entry5 = NULL;
scf_value_t *value1 = NULL;
scf_value_t *value2 = NULL;
scf_value_t *value3 = NULL;
scf_value_t *value4 = NULL;
scf_value_t *value5 = NULL;
boolean_t newPg = B_FALSE;
char pgName[MAXPATHLEN];
char dataPropertyName[STMF_PROVIDER_DATA_PROP_NAME_SIZE];
char *nvlistEncoded = NULL;
size_t nvlistEncodedSize;
size_t blockSize;
int i, j = 0;
int addEntryAlloc = 0, deleteEntryAlloc = 0, addValueAlloc = 0;
int blockOffset;
uint64_t oldBlockCnt = 0;
uint64_t blockCnt = 0;
uint64_t setCnt = 0;
boolean_t foundSetCnt = B_TRUE;
int ret = STMF_PS_SUCCESS;
int commitRet;
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;
}
bzero(pgName, sizeof (pgName));
(void) snprintf(pgName, sizeof (pgName), "%s%s",
STMF_PROVIDER_DATA_PREFIX, providerName);
if (((pg = scf_pg_create(handle)) == NULL) ||
((entry1 = scf_entry_create(handle)) == NULL) ||
((entry2 = scf_entry_create(handle)) == NULL) ||
((entry3 = scf_entry_create(handle)) == NULL) ||
((entry5 = scf_entry_create(handle)) == NULL) ||
((value1 = scf_value_create(handle)) == NULL) ||
((value2 = scf_value_create(handle)) == NULL) ||
((value3 = scf_value_create(handle)) == NULL) ||
((value4 = scf_value_create(handle)) == NULL) ||
((value5 = scf_value_create(handle)) == NULL) ||
((prop = scf_property_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;
}
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 {
if (scf_service_add_pg(svc, pgName,
SCF_GROUP_APPLICATION, 0, pg) == -1) {
syslog(LOG_ERR, "add pg %s failed - %s",
pgName, scf_strerror(scf_error()));
ret = STMF_PS_ERROR;
goto out;
}
newPg = B_TRUE;
}
}
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;
}
if (!newPg) {
if (scf_pg_get_property(pg, STMF_PROVIDER_DATA_PROP_COUNT,
prop) == -1) {
syslog(LOG_ERR, "get property %s/%s failed - %s",
pgName, STMF_PROVIDER_DATA_PROP_COUNT,
scf_strerror(scf_error()));
ret = STMF_PS_ERROR;
goto out;
}
if (scf_property_get_value(prop, value4) == -1) {
syslog(LOG_ERR, "get property value %s/%s failed - %s",
pgName, STMF_PROVIDER_DATA_PROP_COUNT,
scf_strerror(scf_error()));
ret = STMF_PS_ERROR;
goto out;
}
if (scf_value_get_count(value4, &oldBlockCnt) == -1) {
syslog(LOG_ERR, "get integer value %s/%s failed - %s",
pgName, STMF_PROVIDER_DATA_PROP_COUNT,
scf_strerror(scf_error()));
ret = STMF_PS_ERROR;
goto out;
}
}
if (scf_pg_get_property(pg, STMF_PROVIDER_DATA_PROP_SET_COUNT,
prop) == -1) {
if (scf_error() == SCF_ERROR_NOT_FOUND) {
foundSetCnt = B_FALSE;
} else {
syslog(LOG_ERR, "get property %s/%s failed - %s",
pgName, STMF_PROVIDER_DATA_PROP_SET_COUNT,
scf_strerror(scf_error()));
ret = STMF_PS_ERROR;
goto out;
}
}
if (foundSetCnt) {
if (scf_property_get_value(prop, value5) == -1) {
syslog(LOG_ERR, "get property value %s/%s failed - %s",
pgName, STMF_PROVIDER_DATA_PROP_SET_COUNT,
scf_strerror(scf_error()));
ret = STMF_PS_ERROR;
goto out;
}
if (scf_value_get_count(value5, &setCnt) == -1) {
syslog(LOG_ERR, "get integer value %s/%s failed - %s",
pgName, STMF_PROVIDER_DATA_PROP_SET_COUNT,
scf_strerror(scf_error()));
ret = STMF_PS_ERROR;
goto out;
}
if (setToken && (*setToken != setCnt)) {
ret = STMF_PS_ERROR_PROV_DATA_STALE;
goto out;
}
}
setCnt++;
if (nvlist_pack(nvl, &nvlistEncoded, &nvlistEncodedSize,
NV_ENCODE_XDR, 0) != 0) {
syslog(LOG_ERR, "nvlist_pack for %s failed",
pgName);
ret = STMF_PS_ERROR_NOMEM;
goto out;
}
blockCnt = nvlistEncodedSize/STMF_PROVIDER_DATA_PROP_SIZE;
if (nvlistEncodedSize % STMF_PROVIDER_DATA_PROP_SIZE)
blockCnt++;
addEntry = (scf_transaction_entry_t **)calloc(1, sizeof (*addEntry)
* blockCnt);
if (addEntry == NULL) {
syslog(LOG_ERR, "addEntry alloc for %s failed", pgName);
ret = STMF_PS_ERROR_NOMEM;
goto out;
}
addValue = (scf_value_t **)calloc(1, sizeof (*addValue)
* blockCnt);
if (addValue == NULL) {
syslog(LOG_ERR, "value alloc for %s failed", pgName);
ret = STMF_PS_ERROR_NOMEM;
goto out;
}
if (oldBlockCnt > blockCnt) {
deleteEntry = (scf_transaction_entry_t **)calloc(1,
sizeof (*deleteEntry) * (oldBlockCnt - blockCnt));
if (deleteEntry == NULL) {
syslog(LOG_ERR, "deleteEntry alloc for %s failed",
pgName);
ret = STMF_PS_ERROR_NOMEM;
goto out;
}
deleteEntryAlloc = oldBlockCnt - blockCnt;
}
for (i = 0; i < blockCnt; i++) {
addEntry[i] = scf_entry_create(handle);
if (addEntry[i] == NULL) {
syslog(LOG_ERR, "scf value alloc for %s failed - %s",
pgName, scf_strerror(scf_error()));
ret = STMF_PS_ERROR;
goto out;
}
addEntryAlloc++;
(void) snprintf(dataPropertyName, sizeof (dataPropertyName),
"%s-%d", STMF_PROVIDER_DATA_PROP_PREFIX, i);
if (scf_transaction_property_new(tran, addEntry[i],
dataPropertyName, SCF_TYPE_OPAQUE) == -1) {
if (scf_error() == SCF_ERROR_EXISTS) {
if (scf_transaction_property_change(tran,
addEntry[i], dataPropertyName,
SCF_TYPE_OPAQUE) == -1) {
syslog(LOG_ERR, "transaction property "
"change %s/%s failed - %s",
pgName, dataPropertyName,
scf_strerror(scf_error()));
ret = STMF_PS_ERROR;
goto out;
}
} else {
syslog(LOG_ERR,
"transaction property new %s/%s "
"failed - %s", pgName, dataPropertyName,
scf_strerror(scf_error()));
ret = STMF_PS_ERROR;
goto out;
}
}
addValue[i] = scf_value_create(handle);
if (addValue[i] == NULL) {
syslog(LOG_ERR, "scf value alloc for %s failed - %s",
pgName, scf_strerror(scf_error()));
ret = STMF_PS_ERROR;
goto out;
}
addValueAlloc++;
if ((STMF_PROVIDER_DATA_PROP_SIZE * (i + 1))
> nvlistEncodedSize) {
blockSize = nvlistEncodedSize
- STMF_PROVIDER_DATA_PROP_SIZE * i;
} else {
blockSize = STMF_PROVIDER_DATA_PROP_SIZE;
}
blockOffset = STMF_PROVIDER_DATA_PROP_SIZE * i;
if (scf_value_set_opaque(addValue[i],
&nvlistEncoded[blockOffset], blockSize) == -1) {
syslog(LOG_ERR, "set value for %s failed - %s",
pgName, scf_strerror(scf_error()));
ret = STMF_PS_ERROR;
goto out;
}
if (scf_entry_add_value(addEntry[i], addValue[i]) == -1) {
syslog(LOG_ERR, "add value for %s failed - %s",
pgName, scf_strerror(scf_error()));
ret = STMF_PS_ERROR;
goto out;
}
}
for (i = blockCnt; i < oldBlockCnt; i++) {
deleteEntry[j] = scf_entry_create(handle);
if (deleteEntry[j] == NULL) {
syslog(LOG_ERR, "scf value alloc for %s failed - %s",
pgName, scf_strerror(scf_error()));
ret = STMF_PS_ERROR;
goto out;
}
(void) snprintf(dataPropertyName, sizeof (dataPropertyName),
"%s-%d", STMF_PROVIDER_DATA_PROP_PREFIX, i);
if (scf_transaction_property_delete(tran, deleteEntry[j++],
dataPropertyName) == -1) {
syslog(LOG_ERR, "delete property %s/%s failed - %s",
pgName, dataPropertyName,
scf_strerror(scf_error()));
ret = STMF_PS_ERROR;
goto out;
}
}
if (newPg) {
if (scf_transaction_property_new(tran, entry1,
"read_authorization", SCF_TYPE_ASTRING) == -1) {
syslog(LOG_ERR, "transaction property %s/%s new "
"failed - %s", pgName, "read_authorization",
scf_strerror(scf_error()));
ret = STMF_PS_ERROR;
goto out;
}
if (scf_value_set_astring(value1, STMF_SMF_READ_ATTR) == -1) {
syslog(LOG_ERR, "set value %s/%s failed - %s",
pgName, "read_authorization",
scf_strerror(scf_error()));
ret = STMF_PS_ERROR;
goto out;
}
if (scf_entry_add_value(entry1, value1) == -1) {
syslog(LOG_ERR, "add value %s/%s failed - %s",
pgName, "read_authorization",
scf_strerror(scf_error()));
ret = STMF_PS_ERROR;
goto out;
}
}
if (scf_transaction_property_new(tran, entry2,
STMF_PROVIDER_DATA_PROP_COUNT, SCF_TYPE_COUNT) == -1) {
if (scf_error() == SCF_ERROR_EXISTS) {
if (scf_transaction_property_change(tran, entry2,
STMF_PROVIDER_DATA_PROP_COUNT,
SCF_TYPE_COUNT) == -1) {
syslog(LOG_ERR, "transaction property change "
"%s/%s failed - %s", pgName,
STMF_PROVIDER_DATA_PROP_COUNT,
scf_strerror(scf_error()));
ret = STMF_PS_ERROR;
goto out;
}
} else {
syslog(LOG_ERR, "transaction property %s/%s new "
"failed - %s", pgName,
STMF_PROVIDER_DATA_PROP_COUNT,
scf_strerror(scf_error()));
ret = STMF_PS_ERROR;
goto out;
}
}
scf_value_set_count(value2, blockCnt);
if (scf_entry_add_value(entry2, value2) == -1) {
syslog(LOG_ERR, "add value %s/%s failed - %s",
pgName, STMF_PROVIDER_DATA_PROP_COUNT,
scf_strerror(scf_error()));
ret = STMF_PS_ERROR;
goto out;
}
if (scf_transaction_property_new(tran, entry5,
STMF_PROVIDER_DATA_PROP_SET_COUNT, SCF_TYPE_COUNT) == -1) {
if (scf_error() == SCF_ERROR_EXISTS) {
if (scf_transaction_property_change(tran, entry5,
STMF_PROVIDER_DATA_PROP_SET_COUNT,
SCF_TYPE_COUNT) == -1) {
syslog(LOG_ERR,
"transaction property change %s/%s "
"failed - %s", pgName,
STMF_PROVIDER_DATA_PROP_SET_COUNT,
scf_strerror(scf_error()));
ret = STMF_PS_ERROR;
goto out;
}
} else {
syslog(LOG_ERR, "transaction property new %s/%s "
"failed - %s", pgName,
STMF_PROVIDER_DATA_PROP_SET_COUNT,
scf_strerror(scf_error()));
ret = STMF_PS_ERROR;
goto out;
}
}
scf_value_set_count(value5, setCnt);
if (scf_entry_add_value(entry5, value5) == -1) {
syslog(LOG_ERR, "add value %s/%s failed - %s",
pgName, STMF_PROVIDER_DATA_PROP_SET_COUNT,
scf_strerror(scf_error()));
ret = STMF_PS_ERROR;
goto out;
}
if (scf_transaction_property_new(tran, entry3,
STMF_PROVIDER_DATA_PROP_TYPE, SCF_TYPE_INTEGER) == -1) {
if (scf_error() == SCF_ERROR_EXISTS) {
if (scf_transaction_property_change(tran, entry3,
STMF_PROVIDER_DATA_PROP_TYPE,
SCF_TYPE_INTEGER) == -1) {
syslog(LOG_ERR,
"transaction property change %s/%s "
"failed - %s", pgName,
STMF_PROVIDER_DATA_PROP_TYPE,
scf_strerror(scf_error()));
ret = STMF_PS_ERROR;
goto out;
}
} else {
syslog(LOG_ERR, "transaction property new %s/%s "
"failed - %s", pgName, STMF_PROVIDER_DATA_PROP_TYPE,
scf_strerror(scf_error()));
ret = STMF_PS_ERROR;
goto out;
}
}
switch (providerType) {
case STMF_PORT_PROVIDER_TYPE:
case STMF_LU_PROVIDER_TYPE:
scf_value_set_integer(value3, providerType);
break;
default:
ret = STMF_PS_ERROR;
goto out;
}
if (scf_entry_add_value(entry3, value3) == -1) {
syslog(LOG_ERR, "add value %s/%s failed - %s", pgName,
STMF_PROVIDER_DATA_PROP_TYPE, scf_strerror(scf_error()));
ret = STMF_PS_ERROR;
goto out;
}
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;
}
if (ret == STMF_PS_SUCCESS && setToken) {
*setToken = setCnt;
}
out:
if (handle != NULL) {
scf_handle_destroy(handle);
}
if (svc != NULL) {
scf_service_destroy(svc);
}
if (pg != NULL) {
scf_pg_destroy(pg);
}
if (prop != NULL) {
scf_property_destroy(prop);
}
if (tran != NULL) {
scf_transaction_destroy(tran);
}
for (i = 0; i < addEntryAlloc; i++) {
scf_entry_destroy(addEntry[i]);
}
for (i = 0; i < addValueAlloc; i++) {
scf_value_destroy(addValue[i]);
}
free(addValue);
free(addEntry);
for (i = 0; i < deleteEntryAlloc; i++) {
scf_entry_destroy(deleteEntry[i]);
}
free(deleteEntry);
if (entry1 != NULL) {
scf_entry_destroy(entry1);
}
if (entry2 != NULL) {
scf_entry_destroy(entry2);
}
if (entry3 != NULL) {
scf_entry_destroy(entry3);
}
if (entry5 != NULL) {
scf_entry_destroy(entry5);
}
if (value1 != NULL) {
scf_value_destroy(value1);
}
if (value2 != NULL) {
scf_value_destroy(value2);
}
if (value3 != NULL) {
scf_value_destroy(value3);
}
if (value4 != NULL) {
scf_value_destroy(value4);
}
if (value5 != NULL) {
scf_value_destroy(value5);
}
if (nvlistEncoded != NULL) {
free(nvlistEncoded);
}
return (ret);
}
int
psGetViewEntry(stmfGuid *lu, uint32_t viewEntryIndex, stmfViewEntry *ve)
{
scf_handle_t *handle = NULL;
scf_service_t *svc = NULL;
scf_propertygroup_t *pg = NULL;
char guidAsciiBuf[33];
char viewEntryPgName[VIEW_ENTRY_PG_SIZE];
char luPgName[LOGICAL_UNIT_PG_SIZE];
int ret = STMF_PS_SUCCESS;
ret = iPsInit(&handle, &svc);
if (ret != STMF_PS_SUCCESS) {
goto out;
}
pg = scf_pg_create(handle);
if (pg == NULL) {
syslog(LOG_ERR, "scf pg alloc failed - %s",
scf_strerror(scf_error()));
ret = STMF_PS_ERROR;
goto out;
}
(void) snprintf(guidAsciiBuf, sizeof (guidAsciiBuf),
"%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X",
lu->guid[0], lu->guid[1], lu->guid[2], lu->guid[3], lu->guid[4],
lu->guid[5], lu->guid[6], lu->guid[7], lu->guid[8], lu->guid[9],
lu->guid[10], lu->guid[11], lu->guid[12], lu->guid[13],
lu->guid[14], lu->guid[15]);
(void) snprintf(luPgName, sizeof (luPgName), "%s-%s",
STMF_LU_PREFIX, guidAsciiBuf);
(void) snprintf(viewEntryPgName, sizeof (viewEntryPgName),
"%s-%d-%s", STMF_VE_PREFIX, viewEntryIndex, guidAsciiBuf);
if (scf_service_get_pg(svc, viewEntryPgName, pg) == -1) {
if (scf_error() == SCF_ERROR_NOT_FOUND) {
ret = STMF_PS_ERROR_NOT_FOUND;
} else {
syslog(LOG_ERR, "get pg %s failed - %s",
viewEntryPgName, scf_strerror(scf_error()));
ret = STMF_PS_ERROR;
}
goto out;
}
if ((ret = iPsGetViewEntry(viewEntryPgName, ve)) != STMF_PS_SUCCESS) {
ret = STMF_PS_ERROR;
goto out;
}
out:
if (handle != NULL) {
scf_handle_destroy(handle);
}
if (svc != NULL) {
scf_service_destroy(svc);
}
if (pg != NULL) {
scf_pg_destroy(pg);
}
return (ret);
}
int
psRemoveViewEntry(stmfGuid *lu, uint32_t viewEntryIndex)
{
scf_handle_t *handle = NULL;
scf_service_t *svc = NULL;
scf_propertygroup_t *pg = NULL;
char guidAsciiBuf[33];
char viewEntryPgName[VIEW_ENTRY_PG_SIZE];
char luPgName[LOGICAL_UNIT_PG_SIZE];
int ret = STMF_PS_SUCCESS;
sigset_t sigmaskRestore;
(void) pthread_mutex_lock(&sigSetLock);
if (holdSignal(&sigmaskRestore) != 0) {
(void) pthread_mutex_unlock(&sigSetLock);
return (STMF_PS_ERROR);
}
ret = iPsInit(&handle, &svc);
if (ret != STMF_PS_SUCCESS) {
goto out;
}
pg = scf_pg_create(handle);
if (pg == NULL) {
syslog(LOG_ERR, "scf pg alloc failed - %s",
scf_strerror(scf_error()));
ret = STMF_PS_ERROR;
goto out;
}
(void) snprintf(guidAsciiBuf, sizeof (guidAsciiBuf),
"%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X",
lu->guid[0], lu->guid[1], lu->guid[2], lu->guid[3], lu->guid[4],
lu->guid[5], lu->guid[6], lu->guid[7], lu->guid[8], lu->guid[9],
lu->guid[10], lu->guid[11], lu->guid[12], lu->guid[13],
lu->guid[14], lu->guid[15]);
(void) snprintf(luPgName, sizeof (luPgName), "%s-%s",
STMF_LU_PREFIX, guidAsciiBuf);
(void) snprintf(viewEntryPgName, sizeof (viewEntryPgName),
"%s-%d-%s", STMF_VE_PREFIX, viewEntryIndex, guidAsciiBuf);
if (scf_service_get_pg(svc, viewEntryPgName, pg) == -1) {
if (scf_error() == SCF_ERROR_NOT_FOUND) {
ret = STMF_PS_ERROR_NOT_FOUND;
} else {
syslog(LOG_ERR, "get pg %s failed - %s",
viewEntryPgName, scf_strerror(scf_error()));
ret = STMF_PS_ERROR;
}
goto out;
}
if ((ret = iPsAddRemoveLuViewEntry(luPgName, viewEntryPgName,
REMOVE)) != STMF_PS_SUCCESS) {
goto out;
}
if (scf_pg_delete(pg) == -1) {
syslog(LOG_ERR, "delete pg %s failed - %s", viewEntryPgName,
scf_strerror(scf_error()));
if ((ret = iPsAddRemoveLuViewEntry(luPgName, viewEntryPgName,
ADD)) != STMF_PS_SUCCESS) {
syslog(LOG_ERR, "add of view entry %s failed, possible"
"inconsistency - %s", viewEntryPgName,
scf_strerror(scf_error()));
}
ret = STMF_PS_ERROR;
goto out;
}
out:
if (releaseSignal(&sigmaskRestore) != 0) {
syslog(LOG_ERR, "Unable to release one or more signals - %s",
strerror(errno));
}
if (handle != NULL) {
scf_handle_destroy(handle);
}
if (svc != NULL) {
scf_service_destroy(svc);
}
if (pg != NULL) {
scf_pg_destroy(pg);
}
(void) pthread_mutex_unlock(&sigSetLock);
return (ret);
}
static int
holdSignal(sigset_t *sigmaskRestore)
{
struct sigaction act;
sigset_t sigmask;
if (pthread_sigmask(0, NULL, sigmaskRestore) != 0) {
return (1);
}
(void) sigemptyset(&act.sa_mask);
act.sa_handler = sigHandler;
act.sa_flags = 0;
if (!actionSet) {
if (sigaction(SIGQUIT, &act, ¤tActionQuit) != 0) {
return (1);
}
if (sigaction(SIGINT, &act, ¤tActionInt) != 0) {
return (1);
}
if (sigaction(SIGTERM, &act, ¤tActionTerm) != 0) {
return (1);
}
actionSet = B_TRUE;
}
if (sigfillset(&sigmask) != 0) {
return (1);
}
(void) sigdelset(&sigmask, SIGQUIT);
(void) sigdelset(&sigmask, SIGINT);
(void) sigdelset(&sigmask, SIGTERM);
if (pthread_sigmask(SIG_SETMASK, &sigmask, NULL) != 0) {
return (1);
}
return (0);
}
static int
releaseSignal(sigset_t *sigmaskRestore)
{
int ret = 0;
if (sigaction(SIGQUIT, ¤tActionQuit, NULL) != 0) {
ret = 1;
}
if (sigaction(SIGINT, ¤tActionInt, NULL) != 0) {
ret = 1;
}
if (sigaction(SIGTERM, ¤tActionTerm, NULL) != 0) {
ret = 1;
}
actionSet = B_FALSE;
if (pthread_sigmask(SIG_SETMASK, sigmaskRestore, NULL) != 0) {
syslog(LOG_ERR, "Unable to restore sigmask");
}
if (sigismember(&signalsCaught, SIGTERM)) {
(void) sigdelset(&signalsCaught, SIGTERM);
(void) raise(SIGTERM);
}
if (sigismember(&signalsCaught, SIGINT)) {
(void) sigdelset(&signalsCaught, SIGINT);
(void) raise(SIGINT);
}
if (sigismember(&signalsCaught, SIGQUIT)) {
(void) sigdelset(&signalsCaught, SIGQUIT);
(void) raise(SIGQUIT);
}
return (ret);
}