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 } |
|