usr/src/cmd/fs.d/nfs/lib/smfcfg.c
changeset 13092 fcc1e406c13f
child 14144 85a6c280af72
equal deleted inserted replaced
13091:9116acef0349 13092:fcc1e406c13f
       
     1 /*
       
     2  * CDDL HEADER START
       
     3  *
       
     4  * The contents of this file are subject to the terms of the
       
     5  * Common Development and Distribution License (the "License").
       
     6  * You may not use this file except in compliance with the License.
       
     7  *
       
     8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
       
     9  * or http://www.opensolaris.org/os/licensing.
       
    10  * See the License for the specific language governing permissions
       
    11  * and limitations under the License.
       
    12  *
       
    13  * When distributing Covered Code, include this CDDL HEADER in each
       
    14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
       
    15  * If applicable, add the following below this CDDL HEADER, with the
       
    16  * fields enclosed by brackets "[]" replaced with your own identifying
       
    17  * information: Portions Copyright [yyyy] [name of copyright owner]
       
    18  *
       
    19  * CDDL HEADER END
       
    20  */
       
    21 /*
       
    22  * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
       
    23  */
       
    24 #include <stdio.h>
       
    25 #include <stdlib.h>
       
    26 #include <syslog.h>
       
    27 #include <stdarg.h>
       
    28 #include "smfcfg.h"
       
    29 
       
    30 fs_smfhandle_t *
       
    31 fs_smf_init(char *fmri, char *instance)
       
    32 {
       
    33 	fs_smfhandle_t *handle = NULL;
       
    34 	char *svcname, srv[MAXPATHLEN];
       
    35 
       
    36 	/*
       
    37 	 * svc name is of the form svc://network/fs/server:instance1
       
    38 	 * FMRI portion is /network/fs/server
       
    39 	 */
       
    40 	snprintf(srv, MAXPATHLEN, "%s", fmri + strlen("svc:/"));
       
    41 	svcname = strrchr(srv, ':');
       
    42 	if (svcname != NULL)
       
    43 		*svcname = '\0';
       
    44 	svcname = srv;
       
    45 
       
    46 	handle = calloc(1, sizeof (fs_smfhandle_t));
       
    47 	if (handle != NULL) {
       
    48 		handle->fs_handle = scf_handle_create(SCF_VERSION);
       
    49 		if (handle->fs_handle == NULL)
       
    50 			goto out;
       
    51 		if (scf_handle_bind(handle->fs_handle) != 0)
       
    52 			goto out;
       
    53 		handle->fs_service =
       
    54 		    scf_service_create(handle->fs_handle);
       
    55 		handle->fs_scope =
       
    56 		    scf_scope_create(handle->fs_handle);
       
    57 		if (scf_handle_get_local_scope(handle->fs_handle,
       
    58 		    handle->fs_scope) != 0)
       
    59 			goto out;
       
    60 		if (scf_scope_get_service(handle->fs_scope,
       
    61 		    svcname, handle->fs_service)  != SCF_SUCCESS) {
       
    62 			goto out;
       
    63 		}
       
    64 		handle->fs_pg =
       
    65 		    scf_pg_create(handle->fs_handle);
       
    66 		handle->fs_instance =
       
    67 		    scf_instance_create(handle->fs_handle);
       
    68 		handle->fs_property =
       
    69 		    scf_property_create(handle->fs_handle);
       
    70 		handle->fs_value =
       
    71 		    scf_value_create(handle->fs_handle);
       
    72 	} else {
       
    73 		fprintf(stderr,
       
    74 		    gettext("Cannot access SMF repository: %s\n"), fmri);
       
    75 	}
       
    76 	return (handle);
       
    77 
       
    78 out:
       
    79 	fs_smf_fini(handle);
       
    80 	fprintf(stderr, gettext("SMF Initialization problems..%s\n"), fmri);
       
    81 	return (NULL);
       
    82 }
       
    83 
       
    84 
       
    85 void
       
    86 fs_smf_fini(fs_smfhandle_t *handle)
       
    87 {
       
    88 	if (handle != NULL) {
       
    89 		scf_scope_destroy(handle->fs_scope);
       
    90 		scf_instance_destroy(handle->fs_instance);
       
    91 		scf_service_destroy(handle->fs_service);
       
    92 		scf_pg_destroy(handle->fs_pg);
       
    93 		scf_property_destroy(handle->fs_property);
       
    94 		scf_value_destroy(handle->fs_value);
       
    95 		if (handle->fs_handle != NULL) {
       
    96 			scf_handle_unbind(handle->fs_handle);
       
    97 			scf_handle_destroy(handle->fs_handle);
       
    98 		}
       
    99 		free(handle);
       
   100 	}
       
   101 }
       
   102 
       
   103 int
       
   104 fs_smf_set_prop(smf_fstype_t fstype, char *prop_name, char *valbuf,
       
   105     char *instance, scf_type_t sctype, char *fmri)
       
   106 {
       
   107 	fs_smfhandle_t *phandle;
       
   108 	scf_handle_t *handle;
       
   109 	scf_propertygroup_t *pg;
       
   110 	scf_property_t *prop;
       
   111 	scf_transaction_t *tran;
       
   112 	scf_transaction_entry_t *entry;
       
   113 	scf_instance_t *inst;
       
   114 	scf_value_t *val;
       
   115 	int valint;
       
   116 	int index = 0;
       
   117 	int ret = 0;
       
   118 	char *p = NULL;
       
   119 	char *svcname, srv[MAXPATHLEN];
       
   120 	const char *pgname;
       
   121 
       
   122 	/*
       
   123 	 * The SVC names we are using currently are already
       
   124 	 * appended by default. Fix this for instances project.
       
   125 	 */
       
   126 	snprintf(srv, MAXPATHLEN, "%s", fmri);
       
   127 	p = strstr(fmri, ":default");
       
   128 	if (p == NULL) {
       
   129 		strcat(srv, ":");
       
   130 		if (instance == NULL)
       
   131 			instance = "default";
       
   132 		if (strlen(srv) + strlen(instance) > MAXPATHLEN)
       
   133 			goto out;
       
   134 		strncat(srv, instance, strlen(instance));
       
   135 	}
       
   136 	svcname = srv;
       
   137 	phandle = fs_smf_init(fmri, instance);
       
   138 	if (phandle == NULL) {
       
   139 		return (SMF_SYSTEM_ERR);
       
   140 	}
       
   141 	handle = phandle->fs_handle;
       
   142 	pg = phandle->fs_pg;
       
   143 	prop = phandle->fs_property;
       
   144 	inst = phandle->fs_instance;
       
   145 	val = phandle->fs_value;
       
   146 	tran = scf_transaction_create(handle);
       
   147 	entry = scf_entry_create(handle);
       
   148 
       
   149 	if (handle == NULL || pg == NULL || prop == NULL ||
       
   150 	    val == NULL|| tran == NULL || entry == NULL || inst == NULL) {
       
   151 		ret = SMF_SYSTEM_ERR;
       
   152 		goto out;
       
   153 	}
       
   154 
       
   155 	if (scf_handle_decode_fmri(handle, svcname, phandle->fs_scope,
       
   156 	    phandle->fs_service, inst, NULL, NULL, 0) != 0) {
       
   157 		ret = scf_error();
       
   158 		goto out;
       
   159 	}
       
   160 	if (fstype == AUTOFS_SMF)
       
   161 		pgname = AUTOFS_PROPS_PGNAME;
       
   162 	else
       
   163 		pgname = NFS_PROPS_PGNAME;
       
   164 
       
   165 	if (scf_instance_get_pg(inst, pgname,
       
   166 	    pg) != -1) {
       
   167 		uint8_t	vint;
       
   168 		if (scf_transaction_start(tran, pg) == -1) {
       
   169 			ret = scf_error();
       
   170 			goto out;
       
   171 		}
       
   172 		switch (sctype) {
       
   173 		case SCF_TYPE_INTEGER:
       
   174 			errno = 0;
       
   175 			valint = strtoul(valbuf, NULL, 0);
       
   176 			if (errno != 0) {
       
   177 				ret = SMF_SYSTEM_ERR;
       
   178 				goto out;
       
   179 			}
       
   180 			if (scf_transaction_property_change(tran,
       
   181 			    entry, prop_name, SCF_TYPE_INTEGER) == 0) {
       
   182 				scf_value_set_integer(val, valint);
       
   183 				if (scf_entry_add_value(entry, val) < 0) {
       
   184 					ret = scf_error();
       
   185 					goto out;
       
   186 				}
       
   187 			}
       
   188 			break;
       
   189 		case SCF_TYPE_ASTRING:
       
   190 			if (scf_transaction_property_change(tran, entry,
       
   191 			    prop_name, SCF_TYPE_ASTRING) == 0) {
       
   192 				if (scf_value_set_astring(val,
       
   193 				    valbuf) == 0) {
       
   194 					if (scf_entry_add_value(entry,
       
   195 					    val) != 0) {
       
   196 						ret = scf_error();
       
   197 						goto out;
       
   198 					}
       
   199 				} else
       
   200 					ret = SMF_SYSTEM_ERR;
       
   201 			} else
       
   202 				ret = SMF_SYSTEM_ERR;
       
   203 			break;
       
   204 		case SCF_TYPE_BOOLEAN:
       
   205 			if (strcmp(valbuf, "1") == 0) {
       
   206 				vint = 1;
       
   207 			} else if (strcmp(valbuf, "0") == 0) {
       
   208 				vint = 0;
       
   209 			} else  {
       
   210 				ret = SMF_SYSTEM_ERR;
       
   211 				break;
       
   212 			}
       
   213 			if (scf_transaction_property_change(tran, entry,
       
   214 			    prop_name, SCF_TYPE_BOOLEAN) == 0) {
       
   215 				scf_value_set_boolean(val, (uint8_t)vint);
       
   216 				if (scf_entry_add_value(entry, val) != 0) {
       
   217 					ret = scf_error();
       
   218 					goto out;
       
   219 				}
       
   220 			} else {
       
   221 				ret = SMF_SYSTEM_ERR;
       
   222 			}
       
   223 			break;
       
   224 		}
       
   225 		if (ret != SMF_SYSTEM_ERR)
       
   226 			scf_transaction_commit(tran);
       
   227 	}
       
   228 out:
       
   229 	if (tran != NULL)
       
   230 		scf_transaction_destroy(tran);
       
   231 	if (entry != NULL)
       
   232 		scf_entry_destroy(entry);
       
   233 	fs_smf_fini(phandle);
       
   234 	return (ret);
       
   235 }
       
   236 
       
   237 int
       
   238 fs_smf_get_prop(smf_fstype_t fstype, char *prop_name, char *cbuf,
       
   239     char *instance, scf_type_t sctype, char *fmri, int *bufsz)
       
   240 {
       
   241 	fs_smfhandle_t *phandle;
       
   242 	scf_handle_t *handle;
       
   243 	scf_propertygroup_t *pg;
       
   244 	scf_property_t *prop;
       
   245 	scf_value_t *val;
       
   246 	scf_instance_t *inst;
       
   247 	int ret = 0, len = 0, length;
       
   248 	int64_t valint = 0;
       
   249 	char srv[MAXPATHLEN], *p, *svcname;
       
   250 	const char *pgname;
       
   251 	uint8_t bval;
       
   252 
       
   253 	/*
       
   254 	 * The SVC names we are using currently are already
       
   255 	 * appended by default. Fix this for instances project.
       
   256 	 */
       
   257 	snprintf(srv, MAXPATHLEN, "%s", fmri);
       
   258 	p = strstr(fmri, ":default");
       
   259 	if (p == NULL) {
       
   260 		strcat(srv, ":");
       
   261 		if (instance == NULL)
       
   262 			instance = "default";
       
   263 		if (strlen(srv) + strlen(instance) > MAXPATHLEN)
       
   264 			goto out;
       
   265 		strncat(srv, instance, strlen(instance));
       
   266 	}
       
   267 	svcname = srv;
       
   268 	phandle = fs_smf_init(fmri, instance);
       
   269 	if (phandle == NULL)
       
   270 		return (SMF_SYSTEM_ERR);
       
   271 	handle = phandle->fs_handle;
       
   272 	pg = phandle->fs_pg;
       
   273 	inst = phandle->fs_instance;
       
   274 	prop = phandle->fs_property;
       
   275 	val = phandle->fs_value;
       
   276 
       
   277 	if (handle == NULL || pg == NULL || prop == NULL || val == NULL ||
       
   278 	    inst == NULL)  {
       
   279 		return (SMF_SYSTEM_ERR);
       
   280 	}
       
   281 
       
   282 
       
   283 	if (scf_handle_decode_fmri(handle, svcname, phandle->fs_scope,
       
   284 	    phandle->fs_service, inst, NULL, NULL, 0) != 0) {
       
   285 		ret = scf_error();
       
   286 		goto out;
       
   287 	}
       
   288 
       
   289 	if (fstype == AUTOFS_SMF)
       
   290 		pgname = AUTOFS_PROPS_PGNAME;
       
   291 	else
       
   292 		pgname = NFS_PROPS_PGNAME;
       
   293 
       
   294 	if (scf_instance_get_pg(inst, pgname, pg) != -1) {
       
   295 		if (scf_pg_get_property(pg, prop_name,
       
   296 		    prop) != SCF_SUCCESS) {
       
   297 			ret = scf_error();
       
   298 			goto out;
       
   299 		}
       
   300 		if (scf_property_get_value(prop, val) != SCF_SUCCESS) {
       
   301 			ret = scf_error();
       
   302 			goto out;
       
   303 		}
       
   304 		switch (sctype) {
       
   305 		case SCF_TYPE_ASTRING:
       
   306 			len = scf_value_get_astring(val, cbuf, *bufsz);
       
   307 			if (len < 0 || len > *bufsz) {
       
   308 				ret = scf_error();
       
   309 				goto out;
       
   310 			}
       
   311 			ret = 0;
       
   312 			*bufsz = len;
       
   313 		break;
       
   314 		case SCF_TYPE_INTEGER:
       
   315 			if (scf_value_get_integer(val, &valint) != 0) {
       
   316 				ret = scf_error();
       
   317 				goto out;
       
   318 			}
       
   319 			length =  snprintf(cbuf, *bufsz, "%lld", valint);
       
   320 			if (length < 0 || length > *bufsz) {
       
   321 				ret = SA_BAD_VALUE;
       
   322 				goto out;
       
   323 			}
       
   324 			ret = 0;
       
   325 		break;
       
   326 		case SCF_TYPE_BOOLEAN:
       
   327 			if (scf_value_get_boolean(val, &bval) != 0) {
       
   328 				ret = scf_error();
       
   329 				goto out;
       
   330 			}
       
   331 			if (bval == 1) {
       
   332 				length = snprintf(cbuf, *bufsz, "%s", "true");
       
   333 			} else {
       
   334 				length = snprintf(cbuf, *bufsz, "%s", "false");
       
   335 			}
       
   336 			if (length < 0 || length > *bufsz) {
       
   337 				ret = SA_BAD_VALUE;
       
   338 				goto out;
       
   339 			}
       
   340 		break;
       
   341 		}
       
   342 	} else {
       
   343 		ret = scf_error();
       
   344 	}
       
   345 	if ((ret != 0) && scf_error() != SCF_ERROR_NONE)
       
   346 		fprintf(stdout, gettext("%s\n"), scf_strerror(ret));
       
   347 out:
       
   348 	fs_smf_fini(phandle);
       
   349 	return (ret);
       
   350 }
       
   351 
       
   352 
       
   353 int
       
   354 nfs_smf_get_prop(char *prop_name, char *propbuf, char *instance,
       
   355     scf_type_t sctype, char *svc_name, int *bufsz)
       
   356 {
       
   357 	return (fs_smf_get_prop(NFS_SMF, prop_name, propbuf,
       
   358 	    instance, sctype, svc_name, bufsz));
       
   359 }
       
   360 
       
   361 int
       
   362 nfs_smf_set_prop(char *prop_name, char *value, char *instance,
       
   363     scf_type_t type, char *svc_name)
       
   364 {
       
   365 	return (fs_smf_set_prop(NFS_SMF, prop_name, value, instance,
       
   366 	    type, svc_name));
       
   367 }
       
   368 
       
   369 int
       
   370 autofs_smf_set_prop(char *prop_name, char *value, char *instance,
       
   371     scf_type_t type, char *svc_name)
       
   372 {
       
   373 	return (fs_smf_set_prop(AUTOFS_SMF, prop_name, value, instance,
       
   374 	    type, svc_name));
       
   375 }
       
   376 
       
   377 int
       
   378 autofs_smf_get_prop(char *prop_name, char *propbuf, char *instance,
       
   379     scf_type_t sctype, char *svc_name, int *bufsz)
       
   380 {
       
   381 	return (fs_smf_get_prop(AUTOFS_SMF, prop_name, propbuf,
       
   382 	    instance, sctype, svc_name, bufsz));
       
   383 }
       
   384 
       
   385 boolean_t
       
   386 string_to_boolean(const char *str)
       
   387 {
       
   388 	if (strcasecmp(str, "true") == 0 || atoi(str) == 1 ||
       
   389 	    strcasecmp(str, "on") == 0 || strcasecmp(str, "yes") == 0) {
       
   390 		return (B_TRUE);
       
   391 	} else
       
   392 		return (B_FALSE);
       
   393 }