components/visual-panels/time/src/cmd/rad/mod/time/smfutil.c
changeset 1700 d04a7bb15a5b
parent 1699 152cafe6cd99
child 1701 279ed2832e3f
equal deleted inserted replaced
1699:152cafe6cd99 1700:d04a7bb15a5b
     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 /*
       
    23  * Copyright (c) 2011, 2013, Oracle and/or its affiliates. All rights reserved.
       
    24  */
       
    25 
       
    26 #include <rad/rad_modapi.h>
       
    27 #include <libscf.h>
       
    28 
       
    29 #include "smfutil.h"
       
    30 
       
    31 static scf_handle_t *
       
    32 handle_create(void)
       
    33 {
       
    34 	scf_handle_t *h = scf_handle_create(SCF_VERSION);
       
    35 	if (h == NULL)
       
    36 		return (NULL);
       
    37 
       
    38 	if (scf_handle_bind(h) == -1) {
       
    39 		scf_handle_destroy(h);
       
    40 		return (NULL);
       
    41 	}
       
    42 	return (h);
       
    43 }
       
    44 
       
    45 static conerr_t
       
    46 maperr(scf_error_t e)
       
    47 {
       
    48 	switch (e) {
       
    49 	case SCF_ERROR_NONE:
       
    50 		return (CE_OK);
       
    51 	case SCF_ERROR_PERMISSION_DENIED:
       
    52 		return (CE_PRIV);
       
    53 	default:
       
    54 		return (CE_SYSTEM);
       
    55 	}
       
    56 }
       
    57 
       
    58 conerr_t
       
    59 smfu_get_property(char *fmri, char *pgname, char *propname, char *value,
       
    60     size_t n)
       
    61 {
       
    62 	conerr_t err = CE_OK;
       
    63 	scf_handle_t *scfhandle = handle_create();
       
    64 	scf_service_t *service = scf_service_create(scfhandle);
       
    65 	scf_instance_t *instance = scf_instance_create(scfhandle);
       
    66 	scf_propertygroup_t *pg = scf_pg_create(scfhandle);
       
    67 	scf_property_t *prop = scf_property_create(scfhandle);
       
    68 	scf_iter_t *iter = scf_iter_create(scfhandle);
       
    69 	scf_value_t *val = scf_value_create(scfhandle);
       
    70 
       
    71 	if (scfhandle == NULL || service == NULL || instance == NULL ||
       
    72 	    pg == NULL || prop == NULL || iter == NULL || val == NULL) {
       
    73 		err = CE_NOMEM;
       
    74 		goto out;
       
    75 	}
       
    76 
       
    77 	if (scf_handle_decode_fmri(scfhandle, fmri, NULL, service, instance,
       
    78 	    NULL, NULL, 0) != SCF_SUCCESS) {
       
    79 		rad_log(RL_ERROR, "couldn't decode '%s': %s\n", fmri,
       
    80 		    scf_strerror(scf_error()));
       
    81 		err = maperr(scf_error());
       
    82 		goto out;
       
    83 	}
       
    84 
       
    85 	if (scf_instance_get_pg(instance, pgname, pg) != 0 ||
       
    86 	    scf_pg_get_property(pg, propname, prop) != 0 ||
       
    87 	    scf_iter_property_values(iter, prop) != 0) {
       
    88 		rad_log(RL_ERROR, "couldn't get property: '%s/%s/%s': %s\n",
       
    89 		    fmri, pgname, propname, scf_strerror(scf_error()));
       
    90 		err = maperr(scf_error());
       
    91 		goto out;
       
    92 	}
       
    93 
       
    94 	if (scf_iter_next_value(iter, val) > 0 &&
       
    95 	    scf_value_get_as_string(val, value, n) == -1) {
       
    96 		rad_log(RL_ERROR,
       
    97 		    "couldn't get property value: '%s/%s/%s': %s\n", fmri,
       
    98 		    pgname, propname, scf_strerror(scf_error()));
       
    99 		err = maperr(scf_error());
       
   100 		goto out;
       
   101 	}
       
   102 out:
       
   103 	scf_value_destroy(val);
       
   104 	scf_property_destroy(prop);
       
   105 	scf_pg_destroy(pg);
       
   106 	scf_iter_destroy(iter);
       
   107 	scf_instance_destroy(instance);
       
   108 	scf_service_destroy(service);
       
   109 	scf_handle_destroy(scfhandle);
       
   110 
       
   111 	return (err);
       
   112 }
       
   113 
       
   114 conerr_t
       
   115 smfu_set_property(char *fmri, char *pgname, char *propname, char *value)
       
   116 {
       
   117 	conerr_t err = CE_OK;
       
   118 	scf_handle_t *scfhandle = handle_create();
       
   119 	scf_service_t *service = scf_service_create(scfhandle);
       
   120 	scf_instance_t *instance = scf_instance_create(scfhandle);
       
   121 	scf_propertygroup_t *pg = scf_pg_create(scfhandle);
       
   122 	scf_property_t *prop = scf_property_create(scfhandle);
       
   123 	scf_value_t *val = scf_value_create(scfhandle);
       
   124 	scf_transaction_t *tx = scf_transaction_create(scfhandle);
       
   125 	scf_transaction_entry_t *ent = scf_entry_create(scfhandle);
       
   126 	scf_type_t type;
       
   127 
       
   128 	if (scfhandle == NULL || service == NULL || instance == NULL ||
       
   129 	    pg == NULL || prop == NULL || tx == NULL || ent == NULL ||
       
   130 	    val == NULL) {
       
   131 		err = CE_NOMEM;
       
   132 		goto out;
       
   133 	}
       
   134 
       
   135 	if (scf_handle_decode_fmri(scfhandle, fmri, NULL, service, instance,
       
   136 	    NULL, NULL, 0) != SCF_SUCCESS) {
       
   137 		rad_log(RL_ERROR, "couldn't decode '%s': %s\n", fmri,
       
   138 		    scf_strerror(scf_error()));
       
   139 		err = maperr(scf_error());
       
   140 		goto out;
       
   141 	}
       
   142 
       
   143 	if (scf_instance_get_pg(instance, pgname, pg) != 0 ||
       
   144 	    scf_pg_get_property(pg, propname, prop) != 0 ||
       
   145 	    scf_property_type(prop, &type) != 0) {
       
   146 		rad_log(RL_ERROR, "couldn't get property: '%s/%s/%s': %s\n",
       
   147 		    fmri, pgname, propname, scf_strerror(scf_error()));
       
   148 		err = maperr(scf_error());
       
   149 		goto out;
       
   150 	}
       
   151 
       
   152 top:
       
   153 	if (scf_transaction_start(tx, pg) == -1 ||
       
   154 	    scf_transaction_property_change(tx, ent, propname, type) != 0 ||
       
   155 	    scf_value_set_from_string(val, type, value) != 0 ||
       
   156 	    scf_entry_add_value(ent, val) != 0) {
       
   157 		rad_log(RL_ERROR, "couldn't set property: '%s/%s/%s': %s\n",
       
   158 		    fmri, pgname, propname, scf_strerror(scf_error()));
       
   159 		err = maperr(scf_error());
       
   160 		goto out;
       
   161 	}
       
   162 
       
   163 	switch (scf_transaction_commit(tx)) {
       
   164 	/* success */
       
   165 	case 1:
       
   166 		if (smf_refresh_instance(fmri) != 0) {
       
   167 			err = maperr(scf_error());
       
   168 			goto out;
       
   169 		}
       
   170 		break;
       
   171 	/* retry */
       
   172 	case 0:
       
   173 		if (scf_pg_update(pg) != 0) {
       
   174 			err = maperr(scf_error());
       
   175 			goto out;
       
   176 		}
       
   177 		scf_transaction_reset(tx);
       
   178 		goto top;
       
   179 	default:
       
   180 		err = maperr(scf_error());
       
   181 		goto out;
       
   182 	}
       
   183 out:
       
   184 	scf_entry_destroy(ent);
       
   185 	scf_transaction_destroy(tx);
       
   186 	scf_value_destroy(val);
       
   187 	scf_property_destroy(prop);
       
   188 	scf_pg_destroy(pg);
       
   189 	scf_instance_destroy(instance);
       
   190 	scf_service_destroy(service);
       
   191 	scf_handle_destroy(scfhandle);
       
   192 
       
   193 	return (err);
       
   194 }