summaryrefslogtreecommitdiff
path: root/usr/src/cmd/fs.d/nfs/lib/smfcfg.c
diff options
context:
space:
mode:
Diffstat (limited to 'usr/src/cmd/fs.d/nfs/lib/smfcfg.c')
-rw-r--r--usr/src/cmd/fs.d/nfs/lib/smfcfg.c393
1 files changed, 393 insertions, 0 deletions
diff --git a/usr/src/cmd/fs.d/nfs/lib/smfcfg.c b/usr/src/cmd/fs.d/nfs/lib/smfcfg.c
new file mode 100644
index 0000000000..78b34389a5
--- /dev/null
+++ b/usr/src/cmd/fs.d/nfs/lib/smfcfg.c
@@ -0,0 +1,393 @@
+/*
+ * 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) 2010, Oracle and/or its affiliates. All rights reserved.
+ */
+#include <stdio.h>
+#include <stdlib.h>
+#include <syslog.h>
+#include <stdarg.h>
+#include "smfcfg.h"
+
+fs_smfhandle_t *
+fs_smf_init(char *fmri, char *instance)
+{
+ fs_smfhandle_t *handle = NULL;
+ char *svcname, srv[MAXPATHLEN];
+
+ /*
+ * svc name is of the form svc://network/fs/server:instance1
+ * FMRI portion is /network/fs/server
+ */
+ snprintf(srv, MAXPATHLEN, "%s", fmri + strlen("svc:/"));
+ svcname = strrchr(srv, ':');
+ if (svcname != NULL)
+ *svcname = '\0';
+ svcname = srv;
+
+ handle = calloc(1, sizeof (fs_smfhandle_t));
+ if (handle != NULL) {
+ handle->fs_handle = scf_handle_create(SCF_VERSION);
+ if (handle->fs_handle == NULL)
+ goto out;
+ if (scf_handle_bind(handle->fs_handle) != 0)
+ goto out;
+ handle->fs_service =
+ scf_service_create(handle->fs_handle);
+ handle->fs_scope =
+ scf_scope_create(handle->fs_handle);
+ if (scf_handle_get_local_scope(handle->fs_handle,
+ handle->fs_scope) != 0)
+ goto out;
+ if (scf_scope_get_service(handle->fs_scope,
+ svcname, handle->fs_service) != SCF_SUCCESS) {
+ goto out;
+ }
+ handle->fs_pg =
+ scf_pg_create(handle->fs_handle);
+ handle->fs_instance =
+ scf_instance_create(handle->fs_handle);
+ handle->fs_property =
+ scf_property_create(handle->fs_handle);
+ handle->fs_value =
+ scf_value_create(handle->fs_handle);
+ } else {
+ fprintf(stderr,
+ gettext("Cannot access SMF repository: %s\n"), fmri);
+ }
+ return (handle);
+
+out:
+ fs_smf_fini(handle);
+ fprintf(stderr, gettext("SMF Initialization problems..%s\n"), fmri);
+ return (NULL);
+}
+
+
+void
+fs_smf_fini(fs_smfhandle_t *handle)
+{
+ if (handle != NULL) {
+ scf_scope_destroy(handle->fs_scope);
+ scf_instance_destroy(handle->fs_instance);
+ scf_service_destroy(handle->fs_service);
+ scf_pg_destroy(handle->fs_pg);
+ scf_property_destroy(handle->fs_property);
+ scf_value_destroy(handle->fs_value);
+ if (handle->fs_handle != NULL) {
+ scf_handle_unbind(handle->fs_handle);
+ scf_handle_destroy(handle->fs_handle);
+ }
+ free(handle);
+ }
+}
+
+int
+fs_smf_set_prop(smf_fstype_t fstype, char *prop_name, char *valbuf,
+ char *instance, scf_type_t sctype, char *fmri)
+{
+ fs_smfhandle_t *phandle;
+ scf_handle_t *handle;
+ scf_propertygroup_t *pg;
+ scf_property_t *prop;
+ scf_transaction_t *tran;
+ scf_transaction_entry_t *entry;
+ scf_instance_t *inst;
+ scf_value_t *val;
+ int valint;
+ int index = 0;
+ int ret = 0;
+ char *p = NULL;
+ char *svcname, srv[MAXPATHLEN];
+ const char *pgname;
+
+ /*
+ * The SVC names we are using currently are already
+ * appended by default. Fix this for instances project.
+ */
+ snprintf(srv, MAXPATHLEN, "%s", fmri);
+ p = strstr(fmri, ":default");
+ if (p == NULL) {
+ strcat(srv, ":");
+ if (instance == NULL)
+ instance = "default";
+ if (strlen(srv) + strlen(instance) > MAXPATHLEN)
+ goto out;
+ strncat(srv, instance, strlen(instance));
+ }
+ svcname = srv;
+ phandle = fs_smf_init(fmri, instance);
+ if (phandle == NULL) {
+ return (SMF_SYSTEM_ERR);
+ }
+ handle = phandle->fs_handle;
+ pg = phandle->fs_pg;
+ prop = phandle->fs_property;
+ inst = phandle->fs_instance;
+ val = phandle->fs_value;
+ tran = scf_transaction_create(handle);
+ entry = scf_entry_create(handle);
+
+ if (handle == NULL || pg == NULL || prop == NULL ||
+ val == NULL|| tran == NULL || entry == NULL || inst == NULL) {
+ ret = SMF_SYSTEM_ERR;
+ goto out;
+ }
+
+ if (scf_handle_decode_fmri(handle, svcname, phandle->fs_scope,
+ phandle->fs_service, inst, NULL, NULL, 0) != 0) {
+ ret = scf_error();
+ goto out;
+ }
+ if (fstype == AUTOFS_SMF)
+ pgname = AUTOFS_PROPS_PGNAME;
+ else
+ pgname = NFS_PROPS_PGNAME;
+
+ if (scf_instance_get_pg(inst, pgname,
+ pg) != -1) {
+ uint8_t vint;
+ if (scf_transaction_start(tran, pg) == -1) {
+ ret = scf_error();
+ goto out;
+ }
+ switch (sctype) {
+ case SCF_TYPE_INTEGER:
+ errno = 0;
+ valint = strtoul(valbuf, NULL, 0);
+ if (errno != 0) {
+ ret = SMF_SYSTEM_ERR;
+ goto out;
+ }
+ if (scf_transaction_property_change(tran,
+ entry, prop_name, SCF_TYPE_INTEGER) == 0) {
+ scf_value_set_integer(val, valint);
+ if (scf_entry_add_value(entry, val) < 0) {
+ ret = scf_error();
+ goto out;
+ }
+ }
+ break;
+ case SCF_TYPE_ASTRING:
+ if (scf_transaction_property_change(tran, entry,
+ prop_name, SCF_TYPE_ASTRING) == 0) {
+ if (scf_value_set_astring(val,
+ valbuf) == 0) {
+ if (scf_entry_add_value(entry,
+ val) != 0) {
+ ret = scf_error();
+ goto out;
+ }
+ } else
+ ret = SMF_SYSTEM_ERR;
+ } else
+ ret = SMF_SYSTEM_ERR;
+ break;
+ case SCF_TYPE_BOOLEAN:
+ if (strcmp(valbuf, "1") == 0) {
+ vint = 1;
+ } else if (strcmp(valbuf, "0") == 0) {
+ vint = 0;
+ } else {
+ ret = SMF_SYSTEM_ERR;
+ break;
+ }
+ if (scf_transaction_property_change(tran, entry,
+ prop_name, SCF_TYPE_BOOLEAN) == 0) {
+ scf_value_set_boolean(val, (uint8_t)vint);
+ if (scf_entry_add_value(entry, val) != 0) {
+ ret = scf_error();
+ goto out;
+ }
+ } else {
+ ret = SMF_SYSTEM_ERR;
+ }
+ break;
+ }
+ if (ret != SMF_SYSTEM_ERR)
+ scf_transaction_commit(tran);
+ }
+out:
+ if (tran != NULL)
+ scf_transaction_destroy(tran);
+ if (entry != NULL)
+ scf_entry_destroy(entry);
+ fs_smf_fini(phandle);
+ return (ret);
+}
+
+int
+fs_smf_get_prop(smf_fstype_t fstype, char *prop_name, char *cbuf,
+ char *instance, scf_type_t sctype, char *fmri, int *bufsz)
+{
+ fs_smfhandle_t *phandle;
+ scf_handle_t *handle;
+ scf_propertygroup_t *pg;
+ scf_property_t *prop;
+ scf_value_t *val;
+ scf_instance_t *inst;
+ int ret = 0, len = 0, length;
+ int64_t valint = 0;
+ char srv[MAXPATHLEN], *p, *svcname;
+ const char *pgname;
+ uint8_t bval;
+
+ /*
+ * The SVC names we are using currently are already
+ * appended by default. Fix this for instances project.
+ */
+ snprintf(srv, MAXPATHLEN, "%s", fmri);
+ p = strstr(fmri, ":default");
+ if (p == NULL) {
+ strcat(srv, ":");
+ if (instance == NULL)
+ instance = "default";
+ if (strlen(srv) + strlen(instance) > MAXPATHLEN)
+ goto out;
+ strncat(srv, instance, strlen(instance));
+ }
+ svcname = srv;
+ phandle = fs_smf_init(fmri, instance);
+ if (phandle == NULL)
+ return (SMF_SYSTEM_ERR);
+ handle = phandle->fs_handle;
+ pg = phandle->fs_pg;
+ inst = phandle->fs_instance;
+ prop = phandle->fs_property;
+ val = phandle->fs_value;
+
+ if (handle == NULL || pg == NULL || prop == NULL || val == NULL ||
+ inst == NULL) {
+ return (SMF_SYSTEM_ERR);
+ }
+
+
+ if (scf_handle_decode_fmri(handle, svcname, phandle->fs_scope,
+ phandle->fs_service, inst, NULL, NULL, 0) != 0) {
+ ret = scf_error();
+ goto out;
+ }
+
+ if (fstype == AUTOFS_SMF)
+ pgname = AUTOFS_PROPS_PGNAME;
+ else
+ pgname = NFS_PROPS_PGNAME;
+
+ if (scf_instance_get_pg(inst, pgname, pg) != -1) {
+ if (scf_pg_get_property(pg, prop_name,
+ prop) != SCF_SUCCESS) {
+ ret = scf_error();
+ goto out;
+ }
+ if (scf_property_get_value(prop, val) != SCF_SUCCESS) {
+ ret = scf_error();
+ goto out;
+ }
+ switch (sctype) {
+ case SCF_TYPE_ASTRING:
+ len = scf_value_get_astring(val, cbuf, *bufsz);
+ if (len < 0 || len > *bufsz) {
+ ret = scf_error();
+ goto out;
+ }
+ ret = 0;
+ *bufsz = len;
+ break;
+ case SCF_TYPE_INTEGER:
+ if (scf_value_get_integer(val, &valint) != 0) {
+ ret = scf_error();
+ goto out;
+ }
+ length = snprintf(cbuf, *bufsz, "%lld", valint);
+ if (length < 0 || length > *bufsz) {
+ ret = SA_BAD_VALUE;
+ goto out;
+ }
+ ret = 0;
+ break;
+ case SCF_TYPE_BOOLEAN:
+ if (scf_value_get_boolean(val, &bval) != 0) {
+ ret = scf_error();
+ goto out;
+ }
+ if (bval == 1) {
+ length = snprintf(cbuf, *bufsz, "%s", "true");
+ } else {
+ length = snprintf(cbuf, *bufsz, "%s", "false");
+ }
+ if (length < 0 || length > *bufsz) {
+ ret = SA_BAD_VALUE;
+ goto out;
+ }
+ break;
+ }
+ } else {
+ ret = scf_error();
+ }
+ if ((ret != 0) && scf_error() != SCF_ERROR_NONE)
+ fprintf(stdout, gettext("%s\n"), scf_strerror(ret));
+out:
+ fs_smf_fini(phandle);
+ return (ret);
+}
+
+
+int
+nfs_smf_get_prop(char *prop_name, char *propbuf, char *instance,
+ scf_type_t sctype, char *svc_name, int *bufsz)
+{
+ return (fs_smf_get_prop(NFS_SMF, prop_name, propbuf,
+ instance, sctype, svc_name, bufsz));
+}
+
+int
+nfs_smf_set_prop(char *prop_name, char *value, char *instance,
+ scf_type_t type, char *svc_name)
+{
+ return (fs_smf_set_prop(NFS_SMF, prop_name, value, instance,
+ type, svc_name));
+}
+
+int
+autofs_smf_set_prop(char *prop_name, char *value, char *instance,
+ scf_type_t type, char *svc_name)
+{
+ return (fs_smf_set_prop(AUTOFS_SMF, prop_name, value, instance,
+ type, svc_name));
+}
+
+int
+autofs_smf_get_prop(char *prop_name, char *propbuf, char *instance,
+ scf_type_t sctype, char *svc_name, int *bufsz)
+{
+ return (fs_smf_get_prop(AUTOFS_SMF, prop_name, propbuf,
+ instance, sctype, svc_name, bufsz));
+}
+
+boolean_t
+string_to_boolean(const char *str)
+{
+ if (strcasecmp(str, "true") == 0 || atoi(str) == 1 ||
+ strcasecmp(str, "on") == 0 || strcasecmp(str, "yes") == 0) {
+ return (B_TRUE);
+ } else
+ return (B_FALSE);
+}