components/visual-panels/smf/src/cmd/rad/mod/smf/instance.c
branchs11-update
changeset 2805 4888f6212f94
parent 2804 7546c836fd87
child 2806 8ac3cbf66125
equal deleted inserted replaced
2804:7546c836fd87 2805:4888f6212f94
     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, 2012, Oracle and/or its affiliates. All rights reserved.
       
    24  */
       
    25 
       
    26 #include <sys/stat.h>
       
    27 #include <fcntl.h>
       
    28 #include <unistd.h>
       
    29 #include <rad/adr.h>
       
    30 #include <rad/adr_object.h>
       
    31 #include <rad/rad_modapi.h>
       
    32 #include <stdio.h>
       
    33 #include <errno.h>
       
    34 #include <libscf.h>
       
    35 #include <libscf_priv.h>
       
    36 #include "api_smf.h"
       
    37 #include "rhandle.h"
       
    38 #include "smfutil.h"
       
    39 #include "datatype.h"
       
    40 
       
    41 /*ARGSUSED*/
       
    42 conerr_t
       
    43 interface_Instance_read_instance(rad_instance_t *inst, adr_attribute_t *attr,
       
    44     adr_data_t **data, adr_data_t **error)
       
    45 {
       
    46 	smfobj_t *smfo = instance_getdata(inst);
       
    47 	*data = adr_data_new_string(smfo->iname, LT_COPY);
       
    48 	return (*data == NULL ? ce_nomem : ce_ok);
       
    49 }
       
    50 
       
    51 
       
    52 /*ARGSUSED*/
       
    53 static svcerr_t
       
    54 rt_read_restarter(scf_handle_t *h, void *arg, adr_data_t **ret,
       
    55     adr_data_t **error)
       
    56 {
       
    57 	smfobj_t *smfo = arg;
       
    58 	smfu_entity_t entity = SMFU_ENTITY_INIT;
       
    59 	svcerr_t se = SE_OK;
       
    60 	char fmri[max_fmri + 1];
       
    61 
       
    62 	scf_propertygroup_t *pg = scf_pg_create(h);
       
    63 	scf_property_t *prop = scf_property_create(h);
       
    64 	scf_value_t *value = scf_value_create(h);
       
    65 
       
    66 	if (pg == NULL || prop == NULL || value == NULL) {
       
    67 		se = SE_FATAL;
       
    68 		goto done;
       
    69 	}
       
    70 
       
    71 	if ((se = smfu_lookup(h, smfo->sname, smfo->iname, &entity)) != SE_OK)
       
    72 		goto done;
       
    73 	se = smfu_get_pg_r(h, &entity, SCF_PG_GENERAL, pg);
       
    74 	if (se != SE_OK)
       
    75 		goto done;
       
    76 
       
    77 	if (scf_pg_get_property(pg, SCF_PROPERTY_RESTARTER, prop) == -1) {
       
    78 		if (scf_error() == SCF_ERROR_NOT_FOUND)
       
    79 			*ret = adr_data_new_string(SCF_SERVICE_STARTD,
       
    80 			    LT_CONST);
       
    81 		else
       
    82 			se = smfu_maperr(scf_error());
       
    83 		goto done;
       
    84 	}
       
    85 
       
    86 	if (scf_property_get_value(prop, value) == -1 ||
       
    87 	    scf_value_get_as_string(value, fmri, sizeof (fmri)) == -1) {
       
    88 		se = smfu_maperr(scf_error());
       
    89 		goto done;
       
    90 	}
       
    91 
       
    92 	*ret = adr_data_new_string(fmri, LT_COPY);
       
    93 
       
    94 done:
       
    95 	scf_value_destroy(value);
       
    96 	scf_property_destroy(prop);
       
    97 	scf_pg_destroy(pg);
       
    98 	smfu_entity_destroy(&entity);
       
    99 
       
   100 	return (se);
       
   101 }
       
   102 
       
   103 /*ARGSUSED*/
       
   104 conerr_t
       
   105 interface_Instance_read_restarter(rad_instance_t *inst, adr_attribute_t *attr,
       
   106     adr_data_t **data, adr_data_t **error)
       
   107 {
       
   108 	return (smfu_rtrun(rt_read_restarter, instance_getdata(inst), data,
       
   109 	    error));
       
   110 }
       
   111 
       
   112 
       
   113 /*ARGSUSED*/
       
   114 static svcerr_t
       
   115 rt_read_enabled(scf_handle_t *h, void *arg, adr_data_t **ret,
       
   116     adr_data_t **error)
       
   117 {
       
   118 	smfobj_t *smfo = arg;
       
   119 	smfu_entity_t entity = SMFU_ENTITY_INIT;
       
   120 	svcerr_t se = SE_OK;
       
   121 
       
   122 	scf_propertygroup_t *pg = scf_pg_create(h);
       
   123 	scf_property_t *prop = scf_property_create(h);
       
   124 	scf_value_t *value = scf_value_create(h);
       
   125 
       
   126 	if (pg == NULL || prop == NULL || value == NULL) {
       
   127 		se = SE_FATAL;
       
   128 		goto done;
       
   129 	}
       
   130 
       
   131 	if ((se = smfu_lookup(h, smfo->sname, smfo->iname, &entity)) != SE_OK)
       
   132 		goto done;
       
   133 
       
   134 	uint8_t bool;
       
   135 	scf_error_t serr = smfu_read_enabled(entity.instance, pg, prop,
       
   136 	    value, SCF_PG_GENERAL_OVR, &bool);
       
   137 	if (serr == SCF_ERROR_NOT_FOUND)
       
   138 		serr = smfu_read_enabled(entity.instance, pg, prop,
       
   139 		    value, SCF_PG_GENERAL, &bool);
       
   140 
       
   141 	if (serr == 0)
       
   142 		*ret = adr_data_new_boolean(bool > 0);
       
   143 	else
       
   144 		se = smfu_maperr(serr);
       
   145 
       
   146 done:
       
   147 	scf_value_destroy(value);
       
   148 	scf_property_destroy(prop);
       
   149 	scf_pg_destroy(pg);
       
   150 	smfu_entity_destroy(&entity);
       
   151 
       
   152 	return (se);
       
   153 }
       
   154 
       
   155 /*ARGSUSED*/
       
   156 conerr_t
       
   157 interface_Instance_read_enabled(rad_instance_t *inst, adr_attribute_t *attr,
       
   158     adr_data_t **data, adr_data_t **error)
       
   159 {
       
   160 	return (smfu_rtrun(rt_read_enabled, instance_getdata(inst), data,
       
   161 	    error));
       
   162 }
       
   163 
       
   164 
       
   165 /*ARGSUSED*/
       
   166 static svcerr_t
       
   167 rt_read_state(scf_handle_t *h, void *arg, adr_data_t **ret, adr_data_t **error)
       
   168 {
       
   169 	smfobj_t *smfo = arg;
       
   170 	smfu_entity_t entity = SMFU_ENTITY_INIT;
       
   171 	svcerr_t se = SE_OK;
       
   172 	char statestr[MAX_SCF_STATE_STRING_SZ];
       
   173 
       
   174 	scf_propertygroup_t *pg = scf_pg_create(h);
       
   175 	scf_property_t *prop = scf_property_create(h);
       
   176 	scf_value_t *value = scf_value_create(h);
       
   177 
       
   178 	if (pg == NULL || prop == NULL || value == NULL) {
       
   179 		se = SE_FATAL;
       
   180 		goto done;
       
   181 	}
       
   182 
       
   183 	if ((se = smfu_lookup(h, smfo->sname, smfo->iname, &entity)) != SE_OK)
       
   184 		goto done;
       
   185 
       
   186 	if (scf_instance_get_pg(entity.instance, SCF_PG_RESTARTER, pg) == -1 ||
       
   187 	    scf_pg_get_property(pg, SCF_PROPERTY_STATE, prop) == -1 ||
       
   188 	    scf_property_get_value(prop, value) == -1 ||
       
   189 	    scf_value_get_as_string(value, statestr, sizeof (statestr)) == -1) {
       
   190 		se = smfu_maperr(scf_error());
       
   191 		goto done;
       
   192 	}
       
   193 
       
   194 	*ret = create_SMFState(statestr);
       
   195 done:
       
   196 	scf_value_destroy(value);
       
   197 	scf_property_destroy(prop);
       
   198 	scf_pg_destroy(pg);
       
   199 	smfu_entity_destroy(&entity);
       
   200 	return (se);
       
   201 }
       
   202 
       
   203 /*ARGSUSED*/
       
   204 conerr_t
       
   205 interface_Instance_read_state(rad_instance_t *inst, adr_attribute_t *attr,
       
   206     adr_data_t **data, adr_data_t **error)
       
   207 {
       
   208 	return (smfu_rtrun(rt_read_state, instance_getdata(inst), data, error));
       
   209 }
       
   210 
       
   211 
       
   212 /*ARGSUSED*/
       
   213 static svcerr_t
       
   214 rt_read_ex_state(scf_handle_t *h, void *arg, adr_data_t **ret,
       
   215     adr_data_t **error)
       
   216 {
       
   217 	smfobj_t *smfo = arg;
       
   218 	smfu_entity_t entity = SMFU_ENTITY_INIT;
       
   219 	svcerr_t se = SE_OK;
       
   220 
       
   221 	if ((se = smfu_lookup(h, smfo->sname, smfo->iname, &entity)) != SE_OK)
       
   222 		return (SE_FATAL);
       
   223 
       
   224 	se = create_ExtendedState(h, entity.instance, ret);
       
   225 	smfu_entity_destroy(&entity);
       
   226 	return (se);
       
   227 }
       
   228 
       
   229 /*ARGSUSED*/
       
   230 conerr_t
       
   231 interface_Instance_read_ex_state(rad_instance_t *inst, adr_attribute_t *attr,
       
   232     adr_data_t **data, adr_data_t **error)
       
   233 {
       
   234 	return (smfu_rtrun(rt_read_ex_state, instance_getdata(inst), data,
       
   235 	    error));
       
   236 }
       
   237 
       
   238 
       
   239 /*ARGSUSED*/
       
   240 static svcerr_t
       
   241 rt_read_snapshots(scf_handle_t *h, void *arg, adr_data_t **ret,
       
   242     adr_data_t **error)
       
   243 {
       
   244 	smfobj_t *smfo = arg;
       
   245 	smfu_entity_t entity = SMFU_ENTITY_INIT;
       
   246 	svcerr_t se = SE_OK;
       
   247 	char sname[max_name + 1];
       
   248 
       
   249 	scf_snapshot_t *snap = scf_snapshot_create(h);
       
   250 	scf_iter_t *iter = scf_iter_create(h);
       
   251 	adr_data_t *rdata = adr_data_new_array(&adr_t_array_string, 6);
       
   252 
       
   253 	if (snap == NULL || iter == NULL) {
       
   254 		se = SE_FATAL;
       
   255 		goto done;
       
   256 	}
       
   257 
       
   258 	if ((se = smfu_lookup(h, smfo->sname, smfo->iname, &entity)) != SE_OK)
       
   259 		goto done;
       
   260 
       
   261 	if (scf_iter_instance_snapshots(iter, entity.instance) == -1) {
       
   262 		se = smfu_maperr(scf_error());
       
   263 		goto done;
       
   264 	}
       
   265 
       
   266 	int e;
       
   267 	while ((e = scf_iter_next_snapshot(iter, snap)) > 0) {
       
   268 		if (scf_snapshot_get_name(snap, sname, sizeof (sname)) == -1) {
       
   269 			se = smfu_maperr(scf_error());
       
   270 			goto done;
       
   271 		}
       
   272 		(void) adr_array_add(rdata,
       
   273 		    adr_data_new_string(sname, LT_COPY));
       
   274 	}
       
   275 	if (e != 0)
       
   276 		se = smfu_maperr(scf_error());
       
   277 
       
   278 done:
       
   279 	smfu_entity_destroy(&entity);
       
   280 	scf_iter_destroy(iter);
       
   281 	scf_snapshot_destroy(snap);
       
   282 	*ret = rdata;
       
   283 
       
   284 	return (se);
       
   285 }
       
   286 
       
   287 /*ARGSUSED*/
       
   288 conerr_t
       
   289 interface_Instance_read_snapshots(rad_instance_t *inst, adr_attribute_t *attr,
       
   290     adr_data_t **data, adr_data_t **error)
       
   291 {
       
   292 	return (smfu_rtrun(rt_read_snapshots, instance_getdata(inst), data,
       
   293 	    error));
       
   294 }
       
   295 
       
   296 
       
   297 static svcerr_t
       
   298 rt_invoke_readSnapshotPGs(scf_handle_t *h, void *arg, adr_data_t **ret,
       
   299     adr_data_t **error)
       
   300 {
       
   301 	radarg_t *ra = arg;
       
   302 	smfobj_t *smfo = instance_getdata(ra->inst);
       
   303 	const char *snapname =
       
   304 	    ra->args[0] == NULL ? NULL : adr_data_to_string(ra->args[0]);
       
   305 	smfu_entity_t entity = SMFU_ENTITY_INIT;
       
   306 	svcerr_t se = SE_OK;
       
   307 	scf_error_t serr;
       
   308 
       
   309 	scf_propertygroup_t *pg = scf_pg_create(h);
       
   310 	scf_iter_t *iter = scf_iter_create(h);
       
   311 	adr_data_t *result = adr_data_new_array(&t_array__PropertyGroup, 5);
       
   312 
       
   313 	if (pg == NULL || iter == NULL) {
       
   314 		se = SE_FATAL;
       
   315 		goto done;
       
   316 	}
       
   317 
       
   318 	if ((se = smfu_lookup(h, smfo->sname, smfo->iname, &entity)) != SE_OK)
       
   319 		goto done;
       
   320 
       
   321 	if ((serr = smfu_instance_iter_composed_pgs(h, entity.instance,
       
   322 	    snapname, NULL, iter)) != 0) {
       
   323 		if (serr == SCF_ERROR_NOT_FOUND)
       
   324 			se = error_scf(error, &e__ErrorCode_NOTFOUND,
       
   325 			    &e__ErrorTarget_SNAPSHOT, NULL, NULL);
       
   326 		else
       
   327 			se = smfu_maperr(serr);
       
   328 		goto done;
       
   329 	}
       
   330 
       
   331 	int e;
       
   332 	while ((e = scf_iter_next_pg(iter, pg)) > 0) {
       
   333 		adr_data_t *dep;
       
   334 		if ((se = create_PropertyGroup(pg, &dep)) != SE_OK)
       
   335 			goto done;
       
   336 		(void) adr_array_add(result, dep);
       
   337 	}
       
   338 	if (e != 0)
       
   339 		se = smfu_maperr(scf_error());
       
   340 
       
   341 done:
       
   342 	*ret = result;
       
   343 	scf_iter_destroy(iter);
       
   344 	scf_pg_destroy(pg);
       
   345 	smfu_entity_destroy(&entity);
       
   346 	return (se);
       
   347 }
       
   348 
       
   349 /*ARGSUSED*/
       
   350 conerr_t
       
   351 interface_Instance_invoke_readSnapshotPGs(rad_instance_t *inst,
       
   352     adr_method_t *meth, adr_data_t **ret, adr_data_t **args, int count,
       
   353     adr_data_t **error)
       
   354 {
       
   355 	radarg_t ra = { .inst = inst, .args = args };
       
   356 	return (smfu_rtrun(rt_invoke_readSnapshotPGs, &ra, ret, error));
       
   357 }
       
   358 
       
   359 
       
   360 static svcerr_t
       
   361 rt_invoke_readSnapshotProperties(scf_handle_t *h, void *arg, adr_data_t **ret,
       
   362     adr_data_t **error)
       
   363 {
       
   364 	radarg_t *ra = arg;
       
   365 	smfobj_t *smfo = instance_getdata(ra->inst);
       
   366 	const char *snapname =
       
   367 	    ra->args[0] == NULL ? NULL : adr_data_to_string(ra->args[0]);
       
   368 	const char *pgname = adr_data_to_string(ra->args[1]);
       
   369 	smfu_entity_t entity = SMFU_ENTITY_INIT;
       
   370 	svcerr_t se = SE_OK;
       
   371 
       
   372 	scf_propertygroup_t *pg = scf_pg_create(h);
       
   373 
       
   374 	if (pg == NULL) {
       
   375 		se = SE_FATAL;
       
   376 		goto done;
       
   377 	}
       
   378 
       
   379 	if ((se = smfu_lookup(h, smfo->sname, smfo->iname, &entity)) != SE_OK)
       
   380 		goto done;
       
   381 
       
   382 	if ((se = smfu_instance_get_composed_pg(h, entity.instance, snapname,
       
   383 	    pgname, pg, error)) != SE_OK)
       
   384 		goto done;
       
   385 
       
   386 	se = create_Properties(h, pg, ret, error);
       
   387 done:
       
   388 	scf_pg_destroy(pg);
       
   389 	smfu_entity_destroy(&entity);
       
   390 	return (se);
       
   391 }
       
   392 
       
   393 /*ARGSUSED*/
       
   394 conerr_t
       
   395 interface_Instance_invoke_readSnapshotProperties(rad_instance_t *inst,
       
   396     adr_method_t *meth, adr_data_t **ret, adr_data_t **args, int count,
       
   397     adr_data_t **error)
       
   398 {
       
   399 	radarg_t ra = { .inst = inst, .args = args };
       
   400 	return (smfu_rtrun(rt_invoke_readSnapshotProperties, &ra, ret, error));
       
   401 }
       
   402 
       
   403 
       
   404 static svcerr_t
       
   405 rt_invoke_readSnapshotProperty(scf_handle_t *h, void *arg, adr_data_t **ret,
       
   406     adr_data_t **error)
       
   407 {
       
   408 	radarg_t *ra = arg;
       
   409 	smfobj_t *smfo = instance_getdata(ra->inst);
       
   410 	const char *snapname =
       
   411 	    ra->args[0] == NULL ? NULL : adr_data_to_string(ra->args[0]);
       
   412 	const char *pgname = adr_data_to_string(ra->args[1]);
       
   413 	const char *propname = adr_data_to_string(ra->args[2]);
       
   414 	smfu_entity_t entity = SMFU_ENTITY_INIT;
       
   415 	svcerr_t se = SE_OK;
       
   416 
       
   417 	scf_propertygroup_t *pg = scf_pg_create(h);
       
   418 	scf_property_t *prop = scf_property_create(h);
       
   419 	scf_iter_t *iter = scf_iter_create(h);
       
   420 	scf_value_t *value = scf_value_create(h);
       
   421 
       
   422 	if (pg == NULL || prop == NULL || iter == NULL || value == NULL) {
       
   423 		se = SE_FATAL;
       
   424 		goto done;
       
   425 	}
       
   426 
       
   427 	if ((se = smfu_lookup(h, smfo->sname, smfo->iname, &entity)) != SE_OK)
       
   428 		goto done;
       
   429 
       
   430 	if ((se = smfu_instance_get_composed_pg(h, entity.instance, snapname,
       
   431 	    pgname, pg, error)) != SE_OK)
       
   432 		goto done;
       
   433 
       
   434 	if (scf_pg_get_property(pg, propname, prop) == -1) {
       
   435 		if (scf_error() == SCF_ERROR_NOT_FOUND)
       
   436 			se = error_scf(error, &e__ErrorCode_NOTFOUND,
       
   437 			    &e__ErrorTarget_PROPERTY, propname, NULL);
       
   438 		else
       
   439 			se = smfu_maperr(scf_error());
       
   440 		goto done;
       
   441 	}
       
   442 
       
   443 	se = create_Property(prop, iter, value, ret, error);
       
   444 
       
   445 done:
       
   446 	scf_value_destroy(value);
       
   447 	scf_iter_destroy(iter);
       
   448 	scf_property_destroy(prop);
       
   449 	scf_pg_destroy(pg);
       
   450 	smfu_entity_destroy(&entity);
       
   451 	return (se);
       
   452 }
       
   453 
       
   454 /*ARGSUSED*/
       
   455 conerr_t
       
   456 interface_Instance_invoke_readSnapshotProperty(rad_instance_t *inst,
       
   457     adr_method_t *meth, adr_data_t **ret, adr_data_t **args, int count,
       
   458     adr_data_t **error)
       
   459 {
       
   460 	radarg_t ra = { .inst = inst, .args = args };
       
   461 	return (smfu_rtrun(rt_invoke_readSnapshotProperty, &ra, ret, error));
       
   462 }
       
   463 
       
   464 
       
   465 /*
       
   466  * Custom retry implementation for smf_*_instance() routines.
       
   467  */
       
   468 static boolean_t
       
   469 smf_action(conerr_t *result, adr_data_t **error, int rval)
       
   470 {
       
   471 	if (rval == 0) {
       
   472 		*result = ce_ok;
       
   473 		return (B_FALSE);
       
   474 	}
       
   475 
       
   476 	svcerr_t se = SE_OK;
       
   477 	switch (scf_error()) {
       
   478 	case SCF_ERROR_BACKEND_READONLY:
       
   479 		se = error_scf(error, &e__ErrorCode_READONLY, NULL, NULL, NULL);
       
   480 		break;
       
   481 	case SCF_ERROR_PERMISSION_DENIED:
       
   482 		se = error_scf(error, &e__ErrorCode_DENIED, NULL, NULL, NULL);
       
   483 		break;
       
   484 	case SCF_ERROR_CONSTRAINT_VIOLATED:
       
   485 		se = error_scf(error, &e__ErrorCode_INVALID, NULL, NULL, NULL);
       
   486 		break;
       
   487 	default:
       
   488 		se = smfu_maperr(scf_error());
       
   489 	}
       
   490 
       
   491 	if (se == SE_NOTFOUND) {
       
   492 		*result = ce_notfound;
       
   493 		return (B_FALSE);
       
   494 	}
       
   495 
       
   496 	if (se == SE_FATAL) {
       
   497 		(void) internal_error(error, NULL);
       
   498 		*result = ce_object;
       
   499 		return (B_FALSE);
       
   500 	}
       
   501 
       
   502 	return (B_TRUE);
       
   503 }
       
   504 
       
   505 /*ARGSUSED*/
       
   506 conerr_t
       
   507 interface_Instance_invoke_clear(rad_instance_t *inst, adr_method_t *meth,
       
   508     adr_data_t **ret, adr_data_t **args, int count, adr_data_t **error)
       
   509 {
       
   510 	smfobj_t *smfo = instance_getdata(inst);
       
   511 	/* boolean_t sync = adr_data_to_boolean(args[0]); */
       
   512 
       
   513 	conerr_t res;
       
   514 	while (smf_action(&res, error, smf_restore_instance(smfo->fmri)))
       
   515 		;
       
   516 	return (res);
       
   517 }
       
   518 
       
   519 /*ARGSUSED*/
       
   520 conerr_t
       
   521 interface_Instance_invoke_restart(rad_instance_t *inst, adr_method_t *meth,
       
   522     adr_data_t **ret, adr_data_t **args, int count, adr_data_t **error)
       
   523 {
       
   524 	smfobj_t *smfo = instance_getdata(inst);
       
   525 	/* boolean_t sync = adr_data_to_boolean(args[0]); */
       
   526 
       
   527 	conerr_t res;
       
   528 	while (smf_action(&res, error, smf_restart_instance(smfo->fmri)))
       
   529 		;
       
   530 	return (res);
       
   531 }
       
   532 
       
   533 /*ARGSUSED*/
       
   534 conerr_t
       
   535 interface_Instance_invoke_refresh(rad_instance_t *inst, adr_method_t *meth,
       
   536     adr_data_t **ret, adr_data_t **args, int count, adr_data_t **error)
       
   537 {
       
   538 	smfobj_t *smfo = instance_getdata(inst);
       
   539 	/* boolean_t sync = adr_data_to_boolean(args[0]); */
       
   540 
       
   541 	conerr_t res;
       
   542 	while (smf_action(&res, error, smf_refresh_instance(smfo->fmri)))
       
   543 		;
       
   544 	return (res);
       
   545 }
       
   546 
       
   547 /*ARGSUSED*/
       
   548 conerr_t
       
   549 interface_Instance_invoke_maintain(rad_instance_t *inst, adr_method_t *meth,
       
   550     adr_data_t **ret, adr_data_t **args, int count, adr_data_t **error)
       
   551 {
       
   552 	smfobj_t *smfo = instance_getdata(inst);
       
   553 	boolean_t imm = adr_data_to_boolean(args[0]);
       
   554 	boolean_t temp = adr_data_to_boolean(args[1]);
       
   555 	/* boolean_t sync = adr_data_to_boolean(args[2]); */
       
   556 
       
   557 	int flags = 0;
       
   558 	if (imm)
       
   559 		flags |= SMF_IMMEDIATE;
       
   560 	if (temp)
       
   561 		flags |= SMF_TEMPORARY;
       
   562 
       
   563 	conerr_t res;
       
   564 	while (smf_action(&res, error,
       
   565 	    smf_maintain_instance(smfo->fmri, flags)))
       
   566 		;
       
   567 	return (res);
       
   568 }
       
   569 
       
   570 /*ARGSUSED*/
       
   571 conerr_t
       
   572 interface_Instance_invoke_enable(rad_instance_t *inst, adr_method_t *meth,
       
   573     adr_data_t **ret, adr_data_t **args, int count, adr_data_t **error)
       
   574 {
       
   575 	smfobj_t *smfo = instance_getdata(inst);
       
   576 	boolean_t temp = adr_data_to_boolean(args[0]);
       
   577 	/* boolean_t sync = adr_data_to_boolean(args[1]); */
       
   578 
       
   579 	int flags = 0;
       
   580 	if (temp)
       
   581 		flags |= SMF_TEMPORARY;
       
   582 
       
   583 	conerr_t res;
       
   584 	while (smf_action(&res, error, smf_enable_instance(smfo->fmri, flags)))
       
   585 		;
       
   586 	return (res);
       
   587 }
       
   588 
       
   589 /*ARGSUSED*/
       
   590 conerr_t
       
   591 interface_Instance_invoke_disable(rad_instance_t *inst, adr_method_t *meth,
       
   592     adr_data_t **ret, adr_data_t **args, int count, adr_data_t **error)
       
   593 {
       
   594 	smfobj_t *smfo = instance_getdata(inst);
       
   595 	boolean_t temp = adr_data_to_boolean(args[0]);
       
   596 	/* boolean_t sync = adr_data_to_boolean(args[1]); */
       
   597 
       
   598 	int flags = 0;
       
   599 	if (temp)
       
   600 		flags |= SMF_TEMPORARY;
       
   601 
       
   602 	conerr_t res;
       
   603 	while (smf_action(&res, error, smf_disable_instance(smfo->fmri, flags)))
       
   604 		;
       
   605 	return (res);
       
   606 }
       
   607 
       
   608 
       
   609 static svcerr_t
       
   610 rt_get_logfile(scf_handle_t *h, void *arg, adr_data_t **ret, adr_data_t **error)
       
   611 {
       
   612 	smfobj_t *smfo = arg;
       
   613 	smfu_entity_t entity = SMFU_ENTITY_INIT;
       
   614 	svcerr_t se = SE_OK;
       
   615 
       
   616 	scf_propertygroup_t *pg = scf_pg_create(h);
       
   617 	scf_property_t *prop = scf_property_create(h);
       
   618 	scf_value_t *value = scf_value_create(h);
       
   619 	char *logfile;
       
   620 
       
   621 	if (pg == NULL || prop == NULL || value == NULL) {
       
   622 		se = SE_FATAL;
       
   623 		goto done;
       
   624 	}
       
   625 
       
   626 	if ((se = smfu_lookup(h, smfo->sname, smfo->iname, &entity)) != SE_OK)
       
   627 		goto done;
       
   628 
       
   629 	if (scf_instance_get_pg(entity.instance, SCF_PG_RESTARTER, pg) == -1 ||
       
   630 	    scf_pg_get_property(pg, SCF_PROPERTY_LOGFILE, prop) == -1 ||
       
   631 	    scf_property_get_value(prop, value) == -1) {
       
   632 		if (scf_error() == SCF_ERROR_NOT_FOUND) {
       
   633 			se = error_scf(error, &e__ErrorCode_NOTFOUND, NULL,
       
   634 			    NULL, NULL);
       
   635 		} else {
       
   636 			se = smfu_maperr(scf_error());
       
   637 		}
       
   638 		goto done;
       
   639 	}
       
   640 
       
   641 	scf_error_t serr = smfu_value_get_string(value, &logfile);
       
   642 	if (serr != 0) {
       
   643 		se = smfu_maperr(serr);
       
   644 		goto done;
       
   645 	}
       
   646 
       
   647 	*ret = adr_data_new_string(logfile, LT_FREE);
       
   648 done:
       
   649 	scf_pg_destroy(pg);
       
   650 	scf_property_destroy(prop);
       
   651 	scf_value_destroy(value);
       
   652 	smfu_entity_destroy(&entity);
       
   653 	return (se);
       
   654 }
       
   655 
       
   656 /*ARGSUSED*/
       
   657 conerr_t
       
   658 interface_Instance_invoke_getLogInfo(rad_instance_t *inst, adr_method_t *meth,
       
   659     adr_data_t **ret, adr_data_t **args, int count, adr_data_t **error)
       
   660 {
       
   661 	adr_data_t *logfile = NULL;
       
   662 	conerr_t ce = smfu_rtrun(rt_get_logfile, instance_getdata(inst),
       
   663 	    &logfile, error);
       
   664 	if (ce != ce_ok)
       
   665 		return (ce);
       
   666 
       
   667 	struct stat st;
       
   668 	if (stat(adr_data_to_string(logfile), &st) != 0) {
       
   669 		adr_data_free(logfile);
       
   670 		(void) error_scf(error, &e__ErrorCode_NOTFOUND, NULL, NULL,
       
   671 		    NULL);
       
   672 		return (ce_object);
       
   673 	}
       
   674 
       
   675 	int max_size = adr_data_to_integer(args[0]);
       
   676 	int bsize = max_size >= 0 && max_size < st.st_size ?
       
   677 	    max_size : st.st_size;
       
   678 
       
   679 	char *buffer = malloc(bsize);
       
   680 	if (buffer == NULL) {
       
   681 		(void) internal_error(error, NULL);
       
   682 		adr_data_free(logfile);
       
   683 		return (ce_object);
       
   684 	}
       
   685 
       
   686 	int fd;
       
   687 	if ((fd = open(adr_data_to_string(logfile), O_RDONLY)) == -1) {
       
   688 		(void) error_scf(error, (errno == EACCES) ?
       
   689 		    &e__ErrorCode_DENIED : &e__ErrorCode_INTERNAL,
       
   690 		    NULL, NULL, NULL);
       
   691 		adr_data_free(logfile);
       
   692 		free(buffer);
       
   693 		return (ce_object);
       
   694 	}
       
   695 
       
   696 	if (pread(fd, buffer, bsize, st.st_size - bsize) != bsize) {
       
   697 		(void) internal_error(error, NULL);
       
   698 		adr_data_free(logfile);
       
   699 		free(buffer);
       
   700 		(void) close(fd);
       
   701 		return (ce_object);
       
   702 	}
       
   703 
       
   704 	(void) close(fd);
       
   705 
       
   706 	adr_data_t *result = adr_data_new_struct(&t__LogInfo);
       
   707 	adr_struct_set(result, "name", logfile);
       
   708 	adr_struct_set(result, "size", adr_data_new_integer(st.st_size));
       
   709 	adr_struct_set(result, "MTime", adr_data_new_time_ts(&st.st_mtim));
       
   710 	adr_struct_set(result, "contents",
       
   711 	    adr_data_new_opaque(buffer, bsize, LT_FREE));
       
   712 
       
   713 	if ((*ret = adr_data_purify(result)) == NULL) {
       
   714 		(void) internal_error(error, NULL);
       
   715 		return (ce_object);
       
   716 	}
       
   717 
       
   718 	return (ce_ok);
       
   719 }