1*12967Sgavin.maltby@oracle.com /*
2*12967Sgavin.maltby@oracle.com * CDDL HEADER START
3*12967Sgavin.maltby@oracle.com *
4*12967Sgavin.maltby@oracle.com * The contents of this file are subject to the terms of the
5*12967Sgavin.maltby@oracle.com * Common Development and Distribution License (the "License").
6*12967Sgavin.maltby@oracle.com * You may not use this file except in compliance with the License.
7*12967Sgavin.maltby@oracle.com *
8*12967Sgavin.maltby@oracle.com * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9*12967Sgavin.maltby@oracle.com * or http://www.opensolaris.org/os/licensing.
10*12967Sgavin.maltby@oracle.com * See the License for the specific language governing permissions
11*12967Sgavin.maltby@oracle.com * and limitations under the License.
12*12967Sgavin.maltby@oracle.com *
13*12967Sgavin.maltby@oracle.com * When distributing Covered Code, include this CDDL HEADER in each
14*12967Sgavin.maltby@oracle.com * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15*12967Sgavin.maltby@oracle.com * If applicable, add the following below this CDDL HEADER, with the
16*12967Sgavin.maltby@oracle.com * fields enclosed by brackets "[]" replaced with your own identifying
17*12967Sgavin.maltby@oracle.com * information: Portions Copyright [yyyy] [name of copyright owner]
18*12967Sgavin.maltby@oracle.com *
19*12967Sgavin.maltby@oracle.com * CDDL HEADER END
20*12967Sgavin.maltby@oracle.com */
21*12967Sgavin.maltby@oracle.com
22*12967Sgavin.maltby@oracle.com /*
23*12967Sgavin.maltby@oracle.com * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
24*12967Sgavin.maltby@oracle.com */
25*12967Sgavin.maltby@oracle.com
26*12967Sgavin.maltby@oracle.com #include "libscf_impl.h"
27*12967Sgavin.maltby@oracle.com
28*12967Sgavin.maltby@oracle.com #include <assert.h>
29*12967Sgavin.maltby@oracle.com #include <strings.h>
30*12967Sgavin.maltby@oracle.com
31*12967Sgavin.maltby@oracle.com /*
32*12967Sgavin.maltby@oracle.com * Errors returned by smf_notify_{del|get|set}_params()
33*12967Sgavin.maltby@oracle.com */
34*12967Sgavin.maltby@oracle.com static const scf_error_t errs_1[] = {
35*12967Sgavin.maltby@oracle.com SCF_ERROR_BACKEND_ACCESS,
36*12967Sgavin.maltby@oracle.com SCF_ERROR_BACKEND_READONLY,
37*12967Sgavin.maltby@oracle.com SCF_ERROR_CONNECTION_BROKEN,
38*12967Sgavin.maltby@oracle.com SCF_ERROR_DELETED,
39*12967Sgavin.maltby@oracle.com SCF_ERROR_INTERNAL,
40*12967Sgavin.maltby@oracle.com SCF_ERROR_INVALID_ARGUMENT,
41*12967Sgavin.maltby@oracle.com SCF_ERROR_NO_MEMORY,
42*12967Sgavin.maltby@oracle.com SCF_ERROR_NO_RESOURCES,
43*12967Sgavin.maltby@oracle.com SCF_ERROR_NOT_FOUND,
44*12967Sgavin.maltby@oracle.com SCF_ERROR_PERMISSION_DENIED,
45*12967Sgavin.maltby@oracle.com 0
46*12967Sgavin.maltby@oracle.com };
47*12967Sgavin.maltby@oracle.com
48*12967Sgavin.maltby@oracle.com /*
49*12967Sgavin.maltby@oracle.com * Errors returned by smf_notify_{del|get|set}_params()
50*12967Sgavin.maltby@oracle.com * Except SCF_ERROR_INVALID_ARGUMENT
51*12967Sgavin.maltby@oracle.com */
52*12967Sgavin.maltby@oracle.com static const scf_error_t errs_2[] = {
53*12967Sgavin.maltby@oracle.com SCF_ERROR_BACKEND_ACCESS,
54*12967Sgavin.maltby@oracle.com SCF_ERROR_BACKEND_READONLY,
55*12967Sgavin.maltby@oracle.com SCF_ERROR_CONNECTION_BROKEN,
56*12967Sgavin.maltby@oracle.com SCF_ERROR_DELETED,
57*12967Sgavin.maltby@oracle.com SCF_ERROR_INTERNAL,
58*12967Sgavin.maltby@oracle.com SCF_ERROR_NO_MEMORY,
59*12967Sgavin.maltby@oracle.com SCF_ERROR_NO_RESOURCES,
60*12967Sgavin.maltby@oracle.com SCF_ERROR_NOT_FOUND,
61*12967Sgavin.maltby@oracle.com SCF_ERROR_PERMISSION_DENIED,
62*12967Sgavin.maltby@oracle.com 0
63*12967Sgavin.maltby@oracle.com };
64*12967Sgavin.maltby@oracle.com
65*12967Sgavin.maltby@oracle.com /*
66*12967Sgavin.maltby@oracle.com * Helper function that abort() on unexpected errors.
67*12967Sgavin.maltby@oracle.com * The expected error set is a zero-terminated array of scf_error_t
68*12967Sgavin.maltby@oracle.com */
69*12967Sgavin.maltby@oracle.com static int
check_scf_error(scf_error_t e,const scf_error_t * errs)70*12967Sgavin.maltby@oracle.com check_scf_error(scf_error_t e, const scf_error_t *errs)
71*12967Sgavin.maltby@oracle.com {
72*12967Sgavin.maltby@oracle.com if (ismember(e, errs))
73*12967Sgavin.maltby@oracle.com return (1);
74*12967Sgavin.maltby@oracle.com
75*12967Sgavin.maltby@oracle.com assert(0);
76*12967Sgavin.maltby@oracle.com abort();
77*12967Sgavin.maltby@oracle.com
78*12967Sgavin.maltby@oracle.com /*NOTREACHED*/
79*12967Sgavin.maltby@oracle.com }
80*12967Sgavin.maltby@oracle.com
81*12967Sgavin.maltby@oracle.com /*
82*12967Sgavin.maltby@oracle.com * Mapping of state transition to pgname.
83*12967Sgavin.maltby@oracle.com */
84*12967Sgavin.maltby@oracle.com static struct st_pgname {
85*12967Sgavin.maltby@oracle.com const char *st_pgname;
86*12967Sgavin.maltby@oracle.com int32_t st_state;
87*12967Sgavin.maltby@oracle.com } st_pgnames[] = {
88*12967Sgavin.maltby@oracle.com { "to-uninitialized", SCF_TRANS(0, SCF_STATE_UNINIT) },
89*12967Sgavin.maltby@oracle.com { "from-uninitialized", SCF_TRANS(SCF_STATE_UNINIT, 0) },
90*12967Sgavin.maltby@oracle.com { "to-maintenance", SCF_TRANS(0, SCF_STATE_MAINT) },
91*12967Sgavin.maltby@oracle.com { "from-maintenance", SCF_TRANS(SCF_STATE_MAINT, 0) },
92*12967Sgavin.maltby@oracle.com { "to-offline", SCF_TRANS(0, SCF_STATE_OFFLINE) },
93*12967Sgavin.maltby@oracle.com { "from-offline", SCF_TRANS(SCF_STATE_OFFLINE, 0) },
94*12967Sgavin.maltby@oracle.com { "to-disabled", SCF_TRANS(0, SCF_STATE_DISABLED) },
95*12967Sgavin.maltby@oracle.com { "from-disabled", SCF_TRANS(SCF_STATE_DISABLED, 0) },
96*12967Sgavin.maltby@oracle.com { "to-online", SCF_TRANS(0, SCF_STATE_ONLINE) },
97*12967Sgavin.maltby@oracle.com { "from-online", SCF_TRANS(SCF_STATE_ONLINE, 0) },
98*12967Sgavin.maltby@oracle.com { "to-degraded", SCF_TRANS(0, SCF_STATE_DEGRADED) },
99*12967Sgavin.maltby@oracle.com { "from-degraded", SCF_TRANS(SCF_STATE_DEGRADED, 0) },
100*12967Sgavin.maltby@oracle.com { NULL, 0 }
101*12967Sgavin.maltby@oracle.com };
102*12967Sgavin.maltby@oracle.com
103*12967Sgavin.maltby@oracle.com /*
104*12967Sgavin.maltby@oracle.com * Check if class matches or is a subclass of SCF_SVC_TRANSITION_CLASS
105*12967Sgavin.maltby@oracle.com *
106*12967Sgavin.maltby@oracle.com * returns 1, otherwise return 0
107*12967Sgavin.maltby@oracle.com */
108*12967Sgavin.maltby@oracle.com static boolean_t
is_svc_stn(const char * class)109*12967Sgavin.maltby@oracle.com is_svc_stn(const char *class)
110*12967Sgavin.maltby@oracle.com {
111*12967Sgavin.maltby@oracle.com int n = strlen(SCF_SVC_TRANSITION_CLASS);
112*12967Sgavin.maltby@oracle.com
113*12967Sgavin.maltby@oracle.com if (class && strncmp(class, SCF_SVC_TRANSITION_CLASS, n) == 0)
114*12967Sgavin.maltby@oracle.com if (class[n] == '\0' || class[n] == '.')
115*12967Sgavin.maltby@oracle.com return (1);
116*12967Sgavin.maltby@oracle.com return (0);
117*12967Sgavin.maltby@oracle.com }
118*12967Sgavin.maltby@oracle.com
119*12967Sgavin.maltby@oracle.com /*
120*12967Sgavin.maltby@oracle.com * Return the len of the base class. For instance, "class.class1.class2.*"
121*12967Sgavin.maltby@oracle.com * will return the length of "class.class1.class2"
122*12967Sgavin.maltby@oracle.com * This function does not check if the class or base class is valid.
123*12967Sgavin.maltby@oracle.com * A class such as "class.class1....****" is not valid but will return the
124*12967Sgavin.maltby@oracle.com * length of "class.class1....***"
125*12967Sgavin.maltby@oracle.com */
126*12967Sgavin.maltby@oracle.com static size_t
base_class_len(const char * c)127*12967Sgavin.maltby@oracle.com base_class_len(const char *c)
128*12967Sgavin.maltby@oracle.com {
129*12967Sgavin.maltby@oracle.com const char *p;
130*12967Sgavin.maltby@oracle.com size_t n;
131*12967Sgavin.maltby@oracle.com
132*12967Sgavin.maltby@oracle.com if ((n = strlen(c)) == 0)
133*12967Sgavin.maltby@oracle.com return (0);
134*12967Sgavin.maltby@oracle.com
135*12967Sgavin.maltby@oracle.com p = c + n;
136*12967Sgavin.maltby@oracle.com
137*12967Sgavin.maltby@oracle.com /* get rid of any trailing asterisk */
138*12967Sgavin.maltby@oracle.com if (*--p == '*')
139*12967Sgavin.maltby@oracle.com n--;
140*12967Sgavin.maltby@oracle.com
141*12967Sgavin.maltby@oracle.com /* make sure the class doesn't end in '.' */
142*12967Sgavin.maltby@oracle.com while (p >= c && *--p == '.')
143*12967Sgavin.maltby@oracle.com n--;
144*12967Sgavin.maltby@oracle.com
145*12967Sgavin.maltby@oracle.com return (n);
146*12967Sgavin.maltby@oracle.com }
147*12967Sgavin.maltby@oracle.com
148*12967Sgavin.maltby@oracle.com /*
149*12967Sgavin.maltby@oracle.com * Allocates and builds the pgname for an FMA dotted class.
150*12967Sgavin.maltby@oracle.com * The pgname will be of the form "class.class1.class2,SCF_NOTIFY_PG_POSTFIX"
151*12967Sgavin.maltby@oracle.com *
152*12967Sgavin.maltby@oracle.com * NULL on error
153*12967Sgavin.maltby@oracle.com */
154*12967Sgavin.maltby@oracle.com static char *
class_to_pgname(const char * class)155*12967Sgavin.maltby@oracle.com class_to_pgname(const char *class)
156*12967Sgavin.maltby@oracle.com {
157*12967Sgavin.maltby@oracle.com size_t n;
158*12967Sgavin.maltby@oracle.com ssize_t sz = scf_limit(SCF_LIMIT_MAX_NAME_LENGTH) + 1;
159*12967Sgavin.maltby@oracle.com char *pgname = NULL;
160*12967Sgavin.maltby@oracle.com
161*12967Sgavin.maltby@oracle.com n = base_class_len(class);
162*12967Sgavin.maltby@oracle.com
163*12967Sgavin.maltby@oracle.com if (n == 0) {
164*12967Sgavin.maltby@oracle.com (void) scf_set_error(SCF_ERROR_INVALID_ARGUMENT);
165*12967Sgavin.maltby@oracle.com return (NULL);
166*12967Sgavin.maltby@oracle.com }
167*12967Sgavin.maltby@oracle.com
168*12967Sgavin.maltby@oracle.com if ((pgname = malloc(sz)) == NULL) {
169*12967Sgavin.maltby@oracle.com (void) scf_set_error(SCF_ERROR_NO_MEMORY);
170*12967Sgavin.maltby@oracle.com goto error;
171*12967Sgavin.maltby@oracle.com }
172*12967Sgavin.maltby@oracle.com
173*12967Sgavin.maltby@oracle.com if (snprintf(pgname, sz, "%.*s,%s", (int)n, class,
174*12967Sgavin.maltby@oracle.com SCF_NOTIFY_PG_POSTFIX) >= sz) {
175*12967Sgavin.maltby@oracle.com (void) scf_set_error(SCF_ERROR_INVALID_ARGUMENT);
176*12967Sgavin.maltby@oracle.com goto error;
177*12967Sgavin.maltby@oracle.com }
178*12967Sgavin.maltby@oracle.com return (pgname);
179*12967Sgavin.maltby@oracle.com
180*12967Sgavin.maltby@oracle.com error:
181*12967Sgavin.maltby@oracle.com free(pgname);
182*12967Sgavin.maltby@oracle.com pgname = NULL;
183*12967Sgavin.maltby@oracle.com
184*12967Sgavin.maltby@oracle.com return (pgname);
185*12967Sgavin.maltby@oracle.com }
186*12967Sgavin.maltby@oracle.com
187*12967Sgavin.maltby@oracle.com /*
188*12967Sgavin.maltby@oracle.com * Get the pg from the running snapshot of the instance (composed or not)
189*12967Sgavin.maltby@oracle.com */
190*12967Sgavin.maltby@oracle.com static int
get_pg(scf_service_t * s,scf_instance_t * i,const char * n,scf_propertygroup_t * pg,int composed)191*12967Sgavin.maltby@oracle.com get_pg(scf_service_t *s, scf_instance_t *i, const char *n,
192*12967Sgavin.maltby@oracle.com scf_propertygroup_t *pg, int composed)
193*12967Sgavin.maltby@oracle.com {
194*12967Sgavin.maltby@oracle.com scf_handle_t *h = scf_instance_handle(i);
195*12967Sgavin.maltby@oracle.com scf_error_t scf_e = scf_error();
196*12967Sgavin.maltby@oracle.com scf_snapshot_t *snap = scf_snapshot_create(h);
197*12967Sgavin.maltby@oracle.com scf_snaplevel_t *slvl = scf_snaplevel_create(h);
198*12967Sgavin.maltby@oracle.com int r = -1;
199*12967Sgavin.maltby@oracle.com
200*12967Sgavin.maltby@oracle.com if (h == NULL) {
201*12967Sgavin.maltby@oracle.com /*
202*12967Sgavin.maltby@oracle.com * Use the error stored in scf_e
203*12967Sgavin.maltby@oracle.com */
204*12967Sgavin.maltby@oracle.com (void) scf_set_error(scf_e);
205*12967Sgavin.maltby@oracle.com goto out;
206*12967Sgavin.maltby@oracle.com }
207*12967Sgavin.maltby@oracle.com if (s == NULL) {
208*12967Sgavin.maltby@oracle.com if (snap == NULL || slvl == NULL)
209*12967Sgavin.maltby@oracle.com goto out;
210*12967Sgavin.maltby@oracle.com if (scf_instance_get_snapshot(i, "running", snap) != 0)
211*12967Sgavin.maltby@oracle.com goto out;
212*12967Sgavin.maltby@oracle.com
213*12967Sgavin.maltby@oracle.com if (composed) {
214*12967Sgavin.maltby@oracle.com if (scf_instance_get_pg_composed(i, snap, n, pg) != 0)
215*12967Sgavin.maltby@oracle.com goto out;
216*12967Sgavin.maltby@oracle.com } else {
217*12967Sgavin.maltby@oracle.com if (scf_snapshot_get_base_snaplevel(snap, slvl) != 0 ||
218*12967Sgavin.maltby@oracle.com scf_snaplevel_get_pg(slvl, n, pg) != 0)
219*12967Sgavin.maltby@oracle.com goto out;
220*12967Sgavin.maltby@oracle.com }
221*12967Sgavin.maltby@oracle.com } else {
222*12967Sgavin.maltby@oracle.com if (scf_service_get_pg(s, n, pg) != 0)
223*12967Sgavin.maltby@oracle.com goto out;
224*12967Sgavin.maltby@oracle.com }
225*12967Sgavin.maltby@oracle.com
226*12967Sgavin.maltby@oracle.com r = 0;
227*12967Sgavin.maltby@oracle.com out:
228*12967Sgavin.maltby@oracle.com scf_snaplevel_destroy(slvl);
229*12967Sgavin.maltby@oracle.com scf_snapshot_destroy(snap);
230*12967Sgavin.maltby@oracle.com
231*12967Sgavin.maltby@oracle.com return (r);
232*12967Sgavin.maltby@oracle.com }
233*12967Sgavin.maltby@oracle.com
234*12967Sgavin.maltby@oracle.com /*
235*12967Sgavin.maltby@oracle.com * Add a pg if it does not exist, or get it if it exists.
236*12967Sgavin.maltby@oracle.com * It operates on the instance if the service parameter is NULL.
237*12967Sgavin.maltby@oracle.com *
238*12967Sgavin.maltby@oracle.com * returns 0 on success or -1 on failure
239*12967Sgavin.maltby@oracle.com */
240*12967Sgavin.maltby@oracle.com static int
get_or_add_pg(scf_service_t * s,scf_instance_t * i,const char * n,const char * t,uint32_t flags,scf_propertygroup_t * pg)241*12967Sgavin.maltby@oracle.com get_or_add_pg(scf_service_t *s, scf_instance_t *i, const char *n, const char *t,
242*12967Sgavin.maltby@oracle.com uint32_t flags, scf_propertygroup_t *pg)
243*12967Sgavin.maltby@oracle.com {
244*12967Sgavin.maltby@oracle.com int r;
245*12967Sgavin.maltby@oracle.com
246*12967Sgavin.maltby@oracle.com if (s == NULL)
247*12967Sgavin.maltby@oracle.com r = scf_instance_add_pg(i, n, t, flags, pg);
248*12967Sgavin.maltby@oracle.com else
249*12967Sgavin.maltby@oracle.com r = scf_service_add_pg(s, n, t, flags, pg);
250*12967Sgavin.maltby@oracle.com
251*12967Sgavin.maltby@oracle.com if (r == 0)
252*12967Sgavin.maltby@oracle.com return (0);
253*12967Sgavin.maltby@oracle.com else if (scf_error() != SCF_ERROR_EXISTS)
254*12967Sgavin.maltby@oracle.com return (-1);
255*12967Sgavin.maltby@oracle.com
256*12967Sgavin.maltby@oracle.com if (s == NULL)
257*12967Sgavin.maltby@oracle.com r = scf_instance_get_pg(i, n, pg);
258*12967Sgavin.maltby@oracle.com else
259*12967Sgavin.maltby@oracle.com r = scf_service_get_pg(s, n, pg);
260*12967Sgavin.maltby@oracle.com
261*12967Sgavin.maltby@oracle.com return (r);
262*12967Sgavin.maltby@oracle.com }
263*12967Sgavin.maltby@oracle.com
264*12967Sgavin.maltby@oracle.com /*
265*12967Sgavin.maltby@oracle.com * Delete the property group form the instance or service.
266*12967Sgavin.maltby@oracle.com * If service is NULL, use instance, otherwise use only the service.
267*12967Sgavin.maltby@oracle.com *
268*12967Sgavin.maltby@oracle.com * Return SCF_SUCCESS or SCF_FAILED on
269*12967Sgavin.maltby@oracle.com * SCF_ERROR_BACKEND_ACCESS
270*12967Sgavin.maltby@oracle.com * SCF_ERROR_BACKEND_READONLY
271*12967Sgavin.maltby@oracle.com * SCF_ERROR_CONNECTION_BROKEN
272*12967Sgavin.maltby@oracle.com * SCF_ERROR_DELETED
273*12967Sgavin.maltby@oracle.com * SCF_ERROR_HANDLE_MISMATCH
274*12967Sgavin.maltby@oracle.com * SCF_ERROR_INTERNAL
275*12967Sgavin.maltby@oracle.com * SCF_ERROR_INVALID_ARGUMENT
276*12967Sgavin.maltby@oracle.com * SCF_ERROR_NO_RESOURCES
277*12967Sgavin.maltby@oracle.com * SCF_ERROR_NOT_BOUND
278*12967Sgavin.maltby@oracle.com * SCF_ERROR_NOT_FOUND
279*12967Sgavin.maltby@oracle.com * SCF_ERROR_NOT_SET
280*12967Sgavin.maltby@oracle.com * SCF_ERROR_PERMISSION_DENIED
281*12967Sgavin.maltby@oracle.com */
282*12967Sgavin.maltby@oracle.com static int
del_pg(scf_service_t * s,scf_instance_t * i,const char * n,scf_propertygroup_t * pg)283*12967Sgavin.maltby@oracle.com del_pg(scf_service_t *s, scf_instance_t *i, const char *n,
284*12967Sgavin.maltby@oracle.com scf_propertygroup_t *pg)
285*12967Sgavin.maltby@oracle.com {
286*12967Sgavin.maltby@oracle.com if ((s == NULL ? scf_instance_get_pg(i, n, pg) :
287*12967Sgavin.maltby@oracle.com scf_service_get_pg(s, n, pg)) != SCF_SUCCESS)
288*12967Sgavin.maltby@oracle.com if (scf_error() == SCF_ERROR_NOT_FOUND)
289*12967Sgavin.maltby@oracle.com return (SCF_SUCCESS);
290*12967Sgavin.maltby@oracle.com else
291*12967Sgavin.maltby@oracle.com return (SCF_FAILED);
292*12967Sgavin.maltby@oracle.com
293*12967Sgavin.maltby@oracle.com if (scf_pg_delete(pg) != SCF_SUCCESS)
294*12967Sgavin.maltby@oracle.com if (scf_error() == SCF_ERROR_DELETED)
295*12967Sgavin.maltby@oracle.com return (SCF_SUCCESS);
296*12967Sgavin.maltby@oracle.com else
297*12967Sgavin.maltby@oracle.com return (SCF_FAILED);
298*12967Sgavin.maltby@oracle.com
299*12967Sgavin.maltby@oracle.com return (SCF_SUCCESS);
300*12967Sgavin.maltby@oracle.com }
301*12967Sgavin.maltby@oracle.com
302*12967Sgavin.maltby@oracle.com static scf_type_t
get_scf_type(nvpair_t * p)303*12967Sgavin.maltby@oracle.com get_scf_type(nvpair_t *p)
304*12967Sgavin.maltby@oracle.com {
305*12967Sgavin.maltby@oracle.com switch (nvpair_type(p)) {
306*12967Sgavin.maltby@oracle.com case DATA_TYPE_BOOLEAN:
307*12967Sgavin.maltby@oracle.com case DATA_TYPE_BOOLEAN_VALUE:
308*12967Sgavin.maltby@oracle.com case DATA_TYPE_BOOLEAN_ARRAY:
309*12967Sgavin.maltby@oracle.com return (SCF_TYPE_BOOLEAN);
310*12967Sgavin.maltby@oracle.com
311*12967Sgavin.maltby@oracle.com case DATA_TYPE_BYTE:
312*12967Sgavin.maltby@oracle.com case DATA_TYPE_UINT8:
313*12967Sgavin.maltby@oracle.com case DATA_TYPE_UINT16:
314*12967Sgavin.maltby@oracle.com case DATA_TYPE_UINT32:
315*12967Sgavin.maltby@oracle.com case DATA_TYPE_UINT64:
316*12967Sgavin.maltby@oracle.com case DATA_TYPE_BYTE_ARRAY:
317*12967Sgavin.maltby@oracle.com case DATA_TYPE_UINT8_ARRAY:
318*12967Sgavin.maltby@oracle.com case DATA_TYPE_UINT16_ARRAY:
319*12967Sgavin.maltby@oracle.com case DATA_TYPE_UINT32_ARRAY:
320*12967Sgavin.maltby@oracle.com case DATA_TYPE_UINT64_ARRAY:
321*12967Sgavin.maltby@oracle.com return (SCF_TYPE_COUNT);
322*12967Sgavin.maltby@oracle.com
323*12967Sgavin.maltby@oracle.com case DATA_TYPE_INT8:
324*12967Sgavin.maltby@oracle.com case DATA_TYPE_INT16:
325*12967Sgavin.maltby@oracle.com case DATA_TYPE_INT32:
326*12967Sgavin.maltby@oracle.com case DATA_TYPE_INT64:
327*12967Sgavin.maltby@oracle.com case DATA_TYPE_INT8_ARRAY:
328*12967Sgavin.maltby@oracle.com case DATA_TYPE_INT16_ARRAY:
329*12967Sgavin.maltby@oracle.com case DATA_TYPE_INT32_ARRAY:
330*12967Sgavin.maltby@oracle.com case DATA_TYPE_INT64_ARRAY:
331*12967Sgavin.maltby@oracle.com return (SCF_TYPE_INTEGER);
332*12967Sgavin.maltby@oracle.com
333*12967Sgavin.maltby@oracle.com case DATA_TYPE_STRING:
334*12967Sgavin.maltby@oracle.com case DATA_TYPE_STRING_ARRAY:
335*12967Sgavin.maltby@oracle.com return (SCF_TYPE_ASTRING);
336*12967Sgavin.maltby@oracle.com
337*12967Sgavin.maltby@oracle.com default:
338*12967Sgavin.maltby@oracle.com return (SCF_TYPE_INVALID);
339*12967Sgavin.maltby@oracle.com }
340*12967Sgavin.maltby@oracle.com }
341*12967Sgavin.maltby@oracle.com
342*12967Sgavin.maltby@oracle.com static int
add_entry(scf_transaction_entry_t * te,scf_value_t * val)343*12967Sgavin.maltby@oracle.com add_entry(scf_transaction_entry_t *te, scf_value_t *val)
344*12967Sgavin.maltby@oracle.com {
345*12967Sgavin.maltby@oracle.com if (scf_entry_add_value(te, val) != 0) {
346*12967Sgavin.maltby@oracle.com scf_value_destroy(val);
347*12967Sgavin.maltby@oracle.com return (SCF_FAILED);
348*12967Sgavin.maltby@oracle.com }
349*12967Sgavin.maltby@oracle.com
350*12967Sgavin.maltby@oracle.com return (SCF_SUCCESS);
351*12967Sgavin.maltby@oracle.com }
352*12967Sgavin.maltby@oracle.com
353*12967Sgavin.maltby@oracle.com static int
add_boolean_entry(scf_handle_t * h,scf_transaction_entry_t * te,uint8_t v)354*12967Sgavin.maltby@oracle.com add_boolean_entry(scf_handle_t *h, scf_transaction_entry_t *te, uint8_t v)
355*12967Sgavin.maltby@oracle.com {
356*12967Sgavin.maltby@oracle.com scf_value_t *val = scf_value_create(h);
357*12967Sgavin.maltby@oracle.com
358*12967Sgavin.maltby@oracle.com if (val == NULL)
359*12967Sgavin.maltby@oracle.com return (SCF_FAILED);
360*12967Sgavin.maltby@oracle.com
361*12967Sgavin.maltby@oracle.com scf_value_set_boolean(val, v);
362*12967Sgavin.maltby@oracle.com
363*12967Sgavin.maltby@oracle.com return (add_entry(te, val));
364*12967Sgavin.maltby@oracle.com }
365*12967Sgavin.maltby@oracle.com
366*12967Sgavin.maltby@oracle.com static int
add_count_entry(scf_handle_t * h,scf_transaction_entry_t * te,uint64_t v)367*12967Sgavin.maltby@oracle.com add_count_entry(scf_handle_t *h, scf_transaction_entry_t *te, uint64_t v)
368*12967Sgavin.maltby@oracle.com {
369*12967Sgavin.maltby@oracle.com scf_value_t *val = scf_value_create(h);
370*12967Sgavin.maltby@oracle.com
371*12967Sgavin.maltby@oracle.com if (val == NULL)
372*12967Sgavin.maltby@oracle.com return (SCF_FAILED);
373*12967Sgavin.maltby@oracle.com
374*12967Sgavin.maltby@oracle.com scf_value_set_count(val, v);
375*12967Sgavin.maltby@oracle.com
376*12967Sgavin.maltby@oracle.com return (add_entry(te, val));
377*12967Sgavin.maltby@oracle.com }
378*12967Sgavin.maltby@oracle.com
379*12967Sgavin.maltby@oracle.com static int
add_integer_entry(scf_handle_t * h,scf_transaction_entry_t * te,int64_t v)380*12967Sgavin.maltby@oracle.com add_integer_entry(scf_handle_t *h, scf_transaction_entry_t *te, int64_t v)
381*12967Sgavin.maltby@oracle.com {
382*12967Sgavin.maltby@oracle.com scf_value_t *val = scf_value_create(h);
383*12967Sgavin.maltby@oracle.com
384*12967Sgavin.maltby@oracle.com if (val == NULL)
385*12967Sgavin.maltby@oracle.com return (SCF_FAILED);
386*12967Sgavin.maltby@oracle.com
387*12967Sgavin.maltby@oracle.com scf_value_set_integer(val, v);
388*12967Sgavin.maltby@oracle.com
389*12967Sgavin.maltby@oracle.com return (add_entry(te, val));
390*12967Sgavin.maltby@oracle.com }
391*12967Sgavin.maltby@oracle.com
392*12967Sgavin.maltby@oracle.com static int
add_astring_entry(scf_handle_t * h,scf_transaction_entry_t * te,char * s)393*12967Sgavin.maltby@oracle.com add_astring_entry(scf_handle_t *h, scf_transaction_entry_t *te, char *s)
394*12967Sgavin.maltby@oracle.com {
395*12967Sgavin.maltby@oracle.com scf_value_t *val = scf_value_create(h);
396*12967Sgavin.maltby@oracle.com
397*12967Sgavin.maltby@oracle.com if (val == NULL)
398*12967Sgavin.maltby@oracle.com return (SCF_FAILED);
399*12967Sgavin.maltby@oracle.com
400*12967Sgavin.maltby@oracle.com if (scf_value_set_astring(val, s) != 0) {
401*12967Sgavin.maltby@oracle.com scf_value_destroy(val);
402*12967Sgavin.maltby@oracle.com return (SCF_FAILED);
403*12967Sgavin.maltby@oracle.com }
404*12967Sgavin.maltby@oracle.com
405*12967Sgavin.maltby@oracle.com return (add_entry(te, val));
406*12967Sgavin.maltby@oracle.com }
407*12967Sgavin.maltby@oracle.com
408*12967Sgavin.maltby@oracle.com static int
get_nvpair_vals(scf_handle_t * h,scf_transaction_entry_t * te,nvpair_t * p)409*12967Sgavin.maltby@oracle.com get_nvpair_vals(scf_handle_t *h, scf_transaction_entry_t *te, nvpair_t *p)
410*12967Sgavin.maltby@oracle.com {
411*12967Sgavin.maltby@oracle.com scf_value_t *val = scf_value_create(h);
412*12967Sgavin.maltby@oracle.com uint_t n = 1;
413*12967Sgavin.maltby@oracle.com int i;
414*12967Sgavin.maltby@oracle.com
415*12967Sgavin.maltby@oracle.com if (val == NULL)
416*12967Sgavin.maltby@oracle.com return (SCF_FAILED);
417*12967Sgavin.maltby@oracle.com
418*12967Sgavin.maltby@oracle.com switch (nvpair_type(p)) {
419*12967Sgavin.maltby@oracle.com case DATA_TYPE_BOOLEAN:
420*12967Sgavin.maltby@oracle.com return (add_boolean_entry(h, te, 1));
421*12967Sgavin.maltby@oracle.com case DATA_TYPE_BOOLEAN_VALUE:
422*12967Sgavin.maltby@oracle.com {
423*12967Sgavin.maltby@oracle.com boolean_t v;
424*12967Sgavin.maltby@oracle.com
425*12967Sgavin.maltby@oracle.com (void) nvpair_value_boolean_value(p, &v);
426*12967Sgavin.maltby@oracle.com return (add_boolean_entry(h, te, (uint8_t)v));
427*12967Sgavin.maltby@oracle.com }
428*12967Sgavin.maltby@oracle.com case DATA_TYPE_BOOLEAN_ARRAY:
429*12967Sgavin.maltby@oracle.com {
430*12967Sgavin.maltby@oracle.com boolean_t *v;
431*12967Sgavin.maltby@oracle.com
432*12967Sgavin.maltby@oracle.com (void) nvpair_value_boolean_array(p, &v, &n);
433*12967Sgavin.maltby@oracle.com for (i = 0; i < n; ++i) {
434*12967Sgavin.maltby@oracle.com if (add_boolean_entry(h, te, (uint8_t)v[i]) !=
435*12967Sgavin.maltby@oracle.com SCF_SUCCESS)
436*12967Sgavin.maltby@oracle.com return (SCF_FAILED);
437*12967Sgavin.maltby@oracle.com }
438*12967Sgavin.maltby@oracle.com return (SCF_SUCCESS);
439*12967Sgavin.maltby@oracle.com }
440*12967Sgavin.maltby@oracle.com case DATA_TYPE_BYTE:
441*12967Sgavin.maltby@oracle.com {
442*12967Sgavin.maltby@oracle.com uchar_t v;
443*12967Sgavin.maltby@oracle.com
444*12967Sgavin.maltby@oracle.com (void) nvpair_value_byte(p, &v);
445*12967Sgavin.maltby@oracle.com return (add_count_entry(h, te, v));
446*12967Sgavin.maltby@oracle.com }
447*12967Sgavin.maltby@oracle.com case DATA_TYPE_UINT8:
448*12967Sgavin.maltby@oracle.com {
449*12967Sgavin.maltby@oracle.com uint8_t v;
450*12967Sgavin.maltby@oracle.com
451*12967Sgavin.maltby@oracle.com (void) nvpair_value_uint8(p, &v);
452*12967Sgavin.maltby@oracle.com return (add_count_entry(h, te, v));
453*12967Sgavin.maltby@oracle.com }
454*12967Sgavin.maltby@oracle.com case DATA_TYPE_UINT16:
455*12967Sgavin.maltby@oracle.com {
456*12967Sgavin.maltby@oracle.com uint16_t v;
457*12967Sgavin.maltby@oracle.com
458*12967Sgavin.maltby@oracle.com (void) nvpair_value_uint16(p, &v);
459*12967Sgavin.maltby@oracle.com return (add_count_entry(h, te, v));
460*12967Sgavin.maltby@oracle.com }
461*12967Sgavin.maltby@oracle.com case DATA_TYPE_UINT32:
462*12967Sgavin.maltby@oracle.com {
463*12967Sgavin.maltby@oracle.com uint32_t v;
464*12967Sgavin.maltby@oracle.com
465*12967Sgavin.maltby@oracle.com (void) nvpair_value_uint32(p, &v);
466*12967Sgavin.maltby@oracle.com return (add_count_entry(h, te, v));
467*12967Sgavin.maltby@oracle.com }
468*12967Sgavin.maltby@oracle.com case DATA_TYPE_UINT64:
469*12967Sgavin.maltby@oracle.com {
470*12967Sgavin.maltby@oracle.com uint64_t v;
471*12967Sgavin.maltby@oracle.com
472*12967Sgavin.maltby@oracle.com (void) nvpair_value_uint64(p, &v);
473*12967Sgavin.maltby@oracle.com return (add_count_entry(h, te, v));
474*12967Sgavin.maltby@oracle.com }
475*12967Sgavin.maltby@oracle.com case DATA_TYPE_BYTE_ARRAY:
476*12967Sgavin.maltby@oracle.com {
477*12967Sgavin.maltby@oracle.com uchar_t *v;
478*12967Sgavin.maltby@oracle.com
479*12967Sgavin.maltby@oracle.com (void) nvpair_value_byte_array(p, &v, &n);
480*12967Sgavin.maltby@oracle.com for (i = 0; i < n; ++i) {
481*12967Sgavin.maltby@oracle.com if (add_count_entry(h, te, v[i]) != SCF_SUCCESS)
482*12967Sgavin.maltby@oracle.com return (SCF_FAILED);
483*12967Sgavin.maltby@oracle.com }
484*12967Sgavin.maltby@oracle.com return (SCF_SUCCESS);
485*12967Sgavin.maltby@oracle.com }
486*12967Sgavin.maltby@oracle.com case DATA_TYPE_UINT8_ARRAY:
487*12967Sgavin.maltby@oracle.com {
488*12967Sgavin.maltby@oracle.com uint8_t *v;
489*12967Sgavin.maltby@oracle.com
490*12967Sgavin.maltby@oracle.com (void) nvpair_value_uint8_array(p, &v, &n);
491*12967Sgavin.maltby@oracle.com for (i = 0; i < n; ++i) {
492*12967Sgavin.maltby@oracle.com if (add_count_entry(h, te, v[i]) != SCF_SUCCESS)
493*12967Sgavin.maltby@oracle.com return (SCF_FAILED);
494*12967Sgavin.maltby@oracle.com }
495*12967Sgavin.maltby@oracle.com return (SCF_SUCCESS);
496*12967Sgavin.maltby@oracle.com }
497*12967Sgavin.maltby@oracle.com case DATA_TYPE_UINT16_ARRAY:
498*12967Sgavin.maltby@oracle.com {
499*12967Sgavin.maltby@oracle.com uint16_t *v;
500*12967Sgavin.maltby@oracle.com
501*12967Sgavin.maltby@oracle.com (void) nvpair_value_uint16_array(p, &v, &n);
502*12967Sgavin.maltby@oracle.com for (i = 0; i < n; ++i) {
503*12967Sgavin.maltby@oracle.com if (add_count_entry(h, te, v[i]) != SCF_SUCCESS)
504*12967Sgavin.maltby@oracle.com return (SCF_FAILED);
505*12967Sgavin.maltby@oracle.com }
506*12967Sgavin.maltby@oracle.com return (SCF_SUCCESS);
507*12967Sgavin.maltby@oracle.com }
508*12967Sgavin.maltby@oracle.com case DATA_TYPE_UINT32_ARRAY:
509*12967Sgavin.maltby@oracle.com {
510*12967Sgavin.maltby@oracle.com uint32_t *v;
511*12967Sgavin.maltby@oracle.com
512*12967Sgavin.maltby@oracle.com (void) nvpair_value_uint32_array(p, &v, &n);
513*12967Sgavin.maltby@oracle.com for (i = 0; i < n; ++i) {
514*12967Sgavin.maltby@oracle.com if (add_count_entry(h, te, v[i]) != SCF_SUCCESS)
515*12967Sgavin.maltby@oracle.com return (SCF_FAILED);
516*12967Sgavin.maltby@oracle.com }
517*12967Sgavin.maltby@oracle.com return (SCF_SUCCESS);
518*12967Sgavin.maltby@oracle.com }
519*12967Sgavin.maltby@oracle.com case DATA_TYPE_UINT64_ARRAY:
520*12967Sgavin.maltby@oracle.com {
521*12967Sgavin.maltby@oracle.com uint64_t *v;
522*12967Sgavin.maltby@oracle.com
523*12967Sgavin.maltby@oracle.com (void) nvpair_value_uint64_array(p, &v, &n);
524*12967Sgavin.maltby@oracle.com for (i = 0; i < n; ++i) {
525*12967Sgavin.maltby@oracle.com if (add_count_entry(h, te, v[i]) != SCF_SUCCESS)
526*12967Sgavin.maltby@oracle.com return (SCF_FAILED);
527*12967Sgavin.maltby@oracle.com }
528*12967Sgavin.maltby@oracle.com return (SCF_SUCCESS);
529*12967Sgavin.maltby@oracle.com }
530*12967Sgavin.maltby@oracle.com case DATA_TYPE_INT8:
531*12967Sgavin.maltby@oracle.com {
532*12967Sgavin.maltby@oracle.com int8_t v;
533*12967Sgavin.maltby@oracle.com
534*12967Sgavin.maltby@oracle.com (void) nvpair_value_int8(p, &v);
535*12967Sgavin.maltby@oracle.com return (add_integer_entry(h, te, v));
536*12967Sgavin.maltby@oracle.com }
537*12967Sgavin.maltby@oracle.com case DATA_TYPE_INT16:
538*12967Sgavin.maltby@oracle.com {
539*12967Sgavin.maltby@oracle.com int16_t v;
540*12967Sgavin.maltby@oracle.com
541*12967Sgavin.maltby@oracle.com (void) nvpair_value_int16(p, &v);
542*12967Sgavin.maltby@oracle.com return (add_integer_entry(h, te, v));
543*12967Sgavin.maltby@oracle.com }
544*12967Sgavin.maltby@oracle.com case DATA_TYPE_INT32:
545*12967Sgavin.maltby@oracle.com {
546*12967Sgavin.maltby@oracle.com int32_t v;
547*12967Sgavin.maltby@oracle.com
548*12967Sgavin.maltby@oracle.com (void) nvpair_value_int32(p, &v);
549*12967Sgavin.maltby@oracle.com return (add_integer_entry(h, te, v));
550*12967Sgavin.maltby@oracle.com }
551*12967Sgavin.maltby@oracle.com case DATA_TYPE_INT64:
552*12967Sgavin.maltby@oracle.com {
553*12967Sgavin.maltby@oracle.com int64_t v;
554*12967Sgavin.maltby@oracle.com
555*12967Sgavin.maltby@oracle.com (void) nvpair_value_int64(p, &v);
556*12967Sgavin.maltby@oracle.com return (add_integer_entry(h, te, v));
557*12967Sgavin.maltby@oracle.com }
558*12967Sgavin.maltby@oracle.com case DATA_TYPE_INT8_ARRAY:
559*12967Sgavin.maltby@oracle.com {
560*12967Sgavin.maltby@oracle.com int8_t *v;
561*12967Sgavin.maltby@oracle.com
562*12967Sgavin.maltby@oracle.com (void) nvpair_value_int8_array(p, &v, &n);
563*12967Sgavin.maltby@oracle.com for (i = 0; i < n; ++i) {
564*12967Sgavin.maltby@oracle.com if (add_integer_entry(h, te, v[i]) !=
565*12967Sgavin.maltby@oracle.com SCF_SUCCESS)
566*12967Sgavin.maltby@oracle.com return (SCF_FAILED);
567*12967Sgavin.maltby@oracle.com }
568*12967Sgavin.maltby@oracle.com return (SCF_SUCCESS);
569*12967Sgavin.maltby@oracle.com }
570*12967Sgavin.maltby@oracle.com case DATA_TYPE_INT16_ARRAY:
571*12967Sgavin.maltby@oracle.com {
572*12967Sgavin.maltby@oracle.com int16_t *v;
573*12967Sgavin.maltby@oracle.com
574*12967Sgavin.maltby@oracle.com (void) nvpair_value_int16_array(p, &v, &n);
575*12967Sgavin.maltby@oracle.com for (i = 0; i < n; ++i) {
576*12967Sgavin.maltby@oracle.com if (add_integer_entry(h, te, v[i]) !=
577*12967Sgavin.maltby@oracle.com SCF_SUCCESS)
578*12967Sgavin.maltby@oracle.com return (SCF_FAILED);
579*12967Sgavin.maltby@oracle.com }
580*12967Sgavin.maltby@oracle.com return (SCF_SUCCESS);
581*12967Sgavin.maltby@oracle.com }
582*12967Sgavin.maltby@oracle.com case DATA_TYPE_INT32_ARRAY:
583*12967Sgavin.maltby@oracle.com {
584*12967Sgavin.maltby@oracle.com int32_t *v;
585*12967Sgavin.maltby@oracle.com
586*12967Sgavin.maltby@oracle.com (void) nvpair_value_int32_array(p, &v, &n);
587*12967Sgavin.maltby@oracle.com for (i = 0; i < n; ++i) {
588*12967Sgavin.maltby@oracle.com if (add_integer_entry(h, te, v[i]) !=
589*12967Sgavin.maltby@oracle.com SCF_SUCCESS)
590*12967Sgavin.maltby@oracle.com return (SCF_FAILED);
591*12967Sgavin.maltby@oracle.com }
592*12967Sgavin.maltby@oracle.com return (SCF_SUCCESS);
593*12967Sgavin.maltby@oracle.com }
594*12967Sgavin.maltby@oracle.com case DATA_TYPE_INT64_ARRAY:
595*12967Sgavin.maltby@oracle.com {
596*12967Sgavin.maltby@oracle.com int64_t *v;
597*12967Sgavin.maltby@oracle.com
598*12967Sgavin.maltby@oracle.com (void) nvpair_value_int64_array(p, &v, &n);
599*12967Sgavin.maltby@oracle.com for (i = 0; i < n; ++i) {
600*12967Sgavin.maltby@oracle.com if (add_integer_entry(h, te, v[i]) !=
601*12967Sgavin.maltby@oracle.com SCF_SUCCESS)
602*12967Sgavin.maltby@oracle.com return (SCF_FAILED);
603*12967Sgavin.maltby@oracle.com }
604*12967Sgavin.maltby@oracle.com return (SCF_SUCCESS);
605*12967Sgavin.maltby@oracle.com }
606*12967Sgavin.maltby@oracle.com case DATA_TYPE_STRING:
607*12967Sgavin.maltby@oracle.com {
608*12967Sgavin.maltby@oracle.com char *str;
609*12967Sgavin.maltby@oracle.com
610*12967Sgavin.maltby@oracle.com (void) nvpair_value_string(p, &str);
611*12967Sgavin.maltby@oracle.com return (add_astring_entry(h, te, str));
612*12967Sgavin.maltby@oracle.com }
613*12967Sgavin.maltby@oracle.com case DATA_TYPE_STRING_ARRAY:
614*12967Sgavin.maltby@oracle.com {
615*12967Sgavin.maltby@oracle.com char **v;
616*12967Sgavin.maltby@oracle.com
617*12967Sgavin.maltby@oracle.com (void) nvpair_value_string_array(p, &v, &n);
618*12967Sgavin.maltby@oracle.com for (i = 0; i < n; ++i) {
619*12967Sgavin.maltby@oracle.com if (add_astring_entry(h, te, v[i]) !=
620*12967Sgavin.maltby@oracle.com SCF_SUCCESS)
621*12967Sgavin.maltby@oracle.com return (SCF_FAILED);
622*12967Sgavin.maltby@oracle.com }
623*12967Sgavin.maltby@oracle.com return (SCF_SUCCESS);
624*12967Sgavin.maltby@oracle.com }
625*12967Sgavin.maltby@oracle.com default:
626*12967Sgavin.maltby@oracle.com (void) scf_set_error(SCF_ERROR_INVALID_ARGUMENT);
627*12967Sgavin.maltby@oracle.com return (SCF_FAILED);
628*12967Sgavin.maltby@oracle.com }
629*12967Sgavin.maltby@oracle.com
630*12967Sgavin.maltby@oracle.com /*NOTREACHED*/
631*12967Sgavin.maltby@oracle.com }
632*12967Sgavin.maltby@oracle.com
633*12967Sgavin.maltby@oracle.com /*
634*12967Sgavin.maltby@oracle.com * Add new transaction entry to scf_transaction_t
635*12967Sgavin.maltby@oracle.com *
636*12967Sgavin.maltby@oracle.com * Can fail with
637*12967Sgavin.maltby@oracle.com * SCF_ERROR_BACKEND_ACCESS
638*12967Sgavin.maltby@oracle.com * SCF_ERROR_CONNECTION_BROKEN
639*12967Sgavin.maltby@oracle.com * SCF_ERROR_DELETED
640*12967Sgavin.maltby@oracle.com * SCF_ERROR_INTERNAL
641*12967Sgavin.maltby@oracle.com * SCF_ERROR_NO_RESOURCES
642*12967Sgavin.maltby@oracle.com * SCF_ERROR_NOT_FOUND
643*12967Sgavin.maltby@oracle.com */
644*12967Sgavin.maltby@oracle.com static int
prep_transaction(scf_transaction_t * tx,scf_transaction_entry_t * te,const char * prop,scf_type_t type)645*12967Sgavin.maltby@oracle.com prep_transaction(scf_transaction_t *tx, scf_transaction_entry_t *te,
646*12967Sgavin.maltby@oracle.com const char *prop, scf_type_t type)
647*12967Sgavin.maltby@oracle.com {
648*12967Sgavin.maltby@oracle.com if (scf_transaction_property_new(tx, te, prop, type) != SCF_SUCCESS &&
649*12967Sgavin.maltby@oracle.com (scf_error() != SCF_ERROR_EXISTS ||
650*12967Sgavin.maltby@oracle.com scf_transaction_property_change(tx, te, prop, type) !=
651*12967Sgavin.maltby@oracle.com SCF_SUCCESS)) {
652*12967Sgavin.maltby@oracle.com if (check_scf_error(scf_error(), errs_2)) {
653*12967Sgavin.maltby@oracle.com return (SCF_FAILED);
654*12967Sgavin.maltby@oracle.com }
655*12967Sgavin.maltby@oracle.com }
656*12967Sgavin.maltby@oracle.com
657*12967Sgavin.maltby@oracle.com return (SCF_SUCCESS);
658*12967Sgavin.maltby@oracle.com }
659*12967Sgavin.maltby@oracle.com
660*12967Sgavin.maltby@oracle.com /*
661*12967Sgavin.maltby@oracle.com * notify_set_params()
662*12967Sgavin.maltby@oracle.com * returns 0 on success or -1 on failure
663*12967Sgavin.maltby@oracle.com * SCF_ERROR_BACKEND_ACCESS
664*12967Sgavin.maltby@oracle.com * SCF_ERROR_BACKEND_READONLY
665*12967Sgavin.maltby@oracle.com * SCF_ERROR_CONNECTION_BROKEN
666*12967Sgavin.maltby@oracle.com * SCF_ERROR_DELETED
667*12967Sgavin.maltby@oracle.com * SCF_ERROR_INTERNAL
668*12967Sgavin.maltby@oracle.com * SCF_ERROR_INVALID_ARGUMENT
669*12967Sgavin.maltby@oracle.com * SCF_ERROR_NO_MEMORY
670*12967Sgavin.maltby@oracle.com * SCF_ERROR_NO_RESOURCES
671*12967Sgavin.maltby@oracle.com * SCF_ERROR_NOT_FOUND
672*12967Sgavin.maltby@oracle.com * SCF_ERROR_PERMISSION_DENIED
673*12967Sgavin.maltby@oracle.com */
674*12967Sgavin.maltby@oracle.com static int
notify_set_params(scf_propertygroup_t * pg,nvlist_t * params)675*12967Sgavin.maltby@oracle.com notify_set_params(scf_propertygroup_t *pg, nvlist_t *params)
676*12967Sgavin.maltby@oracle.com {
677*12967Sgavin.maltby@oracle.com scf_handle_t *h = scf_pg_handle(pg);
678*12967Sgavin.maltby@oracle.com scf_error_t scf_e = scf_error();
679*12967Sgavin.maltby@oracle.com scf_transaction_t *tx = scf_transaction_create(h);
680*12967Sgavin.maltby@oracle.com int bufsz = scf_limit(SCF_LIMIT_MAX_NAME_LENGTH) + 1;
681*12967Sgavin.maltby@oracle.com char *propname = malloc(bufsz);
682*12967Sgavin.maltby@oracle.com int r = -1;
683*12967Sgavin.maltby@oracle.com int err;
684*12967Sgavin.maltby@oracle.com
685*12967Sgavin.maltby@oracle.com if (h == NULL) {
686*12967Sgavin.maltby@oracle.com /*
687*12967Sgavin.maltby@oracle.com * Use the error stored in scf_e
688*12967Sgavin.maltby@oracle.com */
689*12967Sgavin.maltby@oracle.com (void) scf_set_error(scf_e);
690*12967Sgavin.maltby@oracle.com goto cleanup;
691*12967Sgavin.maltby@oracle.com }
692*12967Sgavin.maltby@oracle.com if (tx == NULL)
693*12967Sgavin.maltby@oracle.com goto cleanup;
694*12967Sgavin.maltby@oracle.com
695*12967Sgavin.maltby@oracle.com if (propname == NULL) {
696*12967Sgavin.maltby@oracle.com (void) scf_set_error(SCF_ERROR_NO_MEMORY);
697*12967Sgavin.maltby@oracle.com goto cleanup;
698*12967Sgavin.maltby@oracle.com }
699*12967Sgavin.maltby@oracle.com
700*12967Sgavin.maltby@oracle.com do {
701*12967Sgavin.maltby@oracle.com nvpair_t *nvp;
702*12967Sgavin.maltby@oracle.com
703*12967Sgavin.maltby@oracle.com /*
704*12967Sgavin.maltby@oracle.com * make sure we have the most recent version of the pg
705*12967Sgavin.maltby@oracle.com * start the transaction
706*12967Sgavin.maltby@oracle.com */
707*12967Sgavin.maltby@oracle.com if (scf_pg_update(pg) == SCF_FAILED ||
708*12967Sgavin.maltby@oracle.com scf_transaction_start(tx, pg) != SCF_SUCCESS) {
709*12967Sgavin.maltby@oracle.com if (check_scf_error(scf_error(), errs_2)) {
710*12967Sgavin.maltby@oracle.com goto cleanup;
711*12967Sgavin.maltby@oracle.com }
712*12967Sgavin.maltby@oracle.com }
713*12967Sgavin.maltby@oracle.com
714*12967Sgavin.maltby@oracle.com for (nvp = nvlist_next_nvpair(params, NULL); nvp != NULL;
715*12967Sgavin.maltby@oracle.com nvp = nvlist_next_nvpair(params, nvp)) {
716*12967Sgavin.maltby@oracle.com nvlist_t *m;
717*12967Sgavin.maltby@oracle.com nvpair_t *p;
718*12967Sgavin.maltby@oracle.com
719*12967Sgavin.maltby@oracle.com /* we ONLY take nvlists here */
720*12967Sgavin.maltby@oracle.com if (nvpair_type(nvp) != DATA_TYPE_NVLIST) {
721*12967Sgavin.maltby@oracle.com char *name = nvpair_name(nvp);
722*12967Sgavin.maltby@oracle.com
723*12967Sgavin.maltby@oracle.com /*
724*12967Sgavin.maltby@oracle.com * if this is output from
725*12967Sgavin.maltby@oracle.com * smf_notify_get_params() we want to skip
726*12967Sgavin.maltby@oracle.com * the tset value of the nvlist
727*12967Sgavin.maltby@oracle.com */
728*12967Sgavin.maltby@oracle.com if (strcmp(name, SCF_NOTIFY_NAME_TSET) == 0)
729*12967Sgavin.maltby@oracle.com continue;
730*12967Sgavin.maltby@oracle.com
731*12967Sgavin.maltby@oracle.com (void) scf_set_error(
732*12967Sgavin.maltby@oracle.com SCF_ERROR_INVALID_ARGUMENT);
733*12967Sgavin.maltby@oracle.com goto cleanup;
734*12967Sgavin.maltby@oracle.com }
735*12967Sgavin.maltby@oracle.com
736*12967Sgavin.maltby@oracle.com if (nvpair_value_nvlist(nvp, &m) != 0) {
737*12967Sgavin.maltby@oracle.com (void) scf_set_error(
738*12967Sgavin.maltby@oracle.com SCF_ERROR_INVALID_ARGUMENT);
739*12967Sgavin.maltby@oracle.com goto cleanup;
740*12967Sgavin.maltby@oracle.com }
741*12967Sgavin.maltby@oracle.com
742*12967Sgavin.maltby@oracle.com /*
743*12967Sgavin.maltby@oracle.com * Traverse each mechanism list
744*12967Sgavin.maltby@oracle.com */
745*12967Sgavin.maltby@oracle.com for (p = nvlist_next_nvpair(m, NULL); p != NULL;
746*12967Sgavin.maltby@oracle.com p = nvlist_next_nvpair(m, p)) {
747*12967Sgavin.maltby@oracle.com scf_transaction_entry_t *te =
748*12967Sgavin.maltby@oracle.com scf_entry_create(h);
749*12967Sgavin.maltby@oracle.com /* map the nvpair type to scf type */
750*12967Sgavin.maltby@oracle.com scf_type_t type = get_scf_type(p);
751*12967Sgavin.maltby@oracle.com
752*12967Sgavin.maltby@oracle.com if (te == NULL) {
753*12967Sgavin.maltby@oracle.com if (scf_error() !=
754*12967Sgavin.maltby@oracle.com SCF_ERROR_INVALID_ARGUMENT) {
755*12967Sgavin.maltby@oracle.com scf_entry_destroy(te);
756*12967Sgavin.maltby@oracle.com goto cleanup;
757*12967Sgavin.maltby@oracle.com } else {
758*12967Sgavin.maltby@oracle.com assert(0);
759*12967Sgavin.maltby@oracle.com abort();
760*12967Sgavin.maltby@oracle.com }
761*12967Sgavin.maltby@oracle.com }
762*12967Sgavin.maltby@oracle.com
763*12967Sgavin.maltby@oracle.com if (type == SCF_TYPE_INVALID) {
764*12967Sgavin.maltby@oracle.com (void) scf_set_error(
765*12967Sgavin.maltby@oracle.com SCF_ERROR_INVALID_ARGUMENT);
766*12967Sgavin.maltby@oracle.com scf_entry_destroy(te);
767*12967Sgavin.maltby@oracle.com goto cleanup;
768*12967Sgavin.maltby@oracle.com }
769*12967Sgavin.maltby@oracle.com
770*12967Sgavin.maltby@oracle.com if (snprintf(propname, bufsz, "%s,%s",
771*12967Sgavin.maltby@oracle.com nvpair_name(nvp), nvpair_name(p)) >=
772*12967Sgavin.maltby@oracle.com bufsz) {
773*12967Sgavin.maltby@oracle.com (void) scf_set_error(
774*12967Sgavin.maltby@oracle.com SCF_ERROR_INVALID_ARGUMENT);
775*12967Sgavin.maltby@oracle.com scf_entry_destroy(te);
776*12967Sgavin.maltby@oracle.com goto cleanup;
777*12967Sgavin.maltby@oracle.com }
778*12967Sgavin.maltby@oracle.com
779*12967Sgavin.maltby@oracle.com if (prep_transaction(tx, te, propname, type) !=
780*12967Sgavin.maltby@oracle.com SCF_SUCCESS) {
781*12967Sgavin.maltby@oracle.com scf_entry_destroy(te);
782*12967Sgavin.maltby@oracle.com goto cleanup;
783*12967Sgavin.maltby@oracle.com }
784*12967Sgavin.maltby@oracle.com
785*12967Sgavin.maltby@oracle.com if (get_nvpair_vals(h, te, p) != SCF_SUCCESS) {
786*12967Sgavin.maltby@oracle.com if (check_scf_error(scf_error(),
787*12967Sgavin.maltby@oracle.com errs_2)) {
788*12967Sgavin.maltby@oracle.com goto cleanup;
789*12967Sgavin.maltby@oracle.com }
790*12967Sgavin.maltby@oracle.com }
791*12967Sgavin.maltby@oracle.com }
792*12967Sgavin.maltby@oracle.com }
793*12967Sgavin.maltby@oracle.com err = scf_transaction_commit(tx);
794*12967Sgavin.maltby@oracle.com scf_transaction_destroy_children(tx);
795*12967Sgavin.maltby@oracle.com } while (err == 0);
796*12967Sgavin.maltby@oracle.com
797*12967Sgavin.maltby@oracle.com if (err == -1) {
798*12967Sgavin.maltby@oracle.com if (check_scf_error(scf_error(), errs_2)) {
799*12967Sgavin.maltby@oracle.com goto cleanup;
800*12967Sgavin.maltby@oracle.com }
801*12967Sgavin.maltby@oracle.com }
802*12967Sgavin.maltby@oracle.com
803*12967Sgavin.maltby@oracle.com r = 0;
804*12967Sgavin.maltby@oracle.com
805*12967Sgavin.maltby@oracle.com cleanup:
806*12967Sgavin.maltby@oracle.com scf_transaction_destroy_children(tx);
807*12967Sgavin.maltby@oracle.com scf_transaction_destroy(tx);
808*12967Sgavin.maltby@oracle.com free(propname);
809*12967Sgavin.maltby@oracle.com
810*12967Sgavin.maltby@oracle.com return (r);
811*12967Sgavin.maltby@oracle.com }
812*12967Sgavin.maltby@oracle.com
813*12967Sgavin.maltby@oracle.com /*
814*12967Sgavin.maltby@oracle.com * Decode fmri. Populates service OR instance depending on which one is an
815*12967Sgavin.maltby@oracle.com * exact match to the fmri parameter.
816*12967Sgavin.maltby@oracle.com *
817*12967Sgavin.maltby@oracle.com * The function destroys and sets the unused entity (service or instance) to
818*12967Sgavin.maltby@oracle.com * NULL.
819*12967Sgavin.maltby@oracle.com *
820*12967Sgavin.maltby@oracle.com * return SCF_SUCCESS or SCF_FAILED on
821*12967Sgavin.maltby@oracle.com * SCF_ERROR_BACKEND_ACCESS
822*12967Sgavin.maltby@oracle.com * SCF_ERROR_CONNECTION_BROKEN
823*12967Sgavin.maltby@oracle.com * SCF_ERROR_CONSTRAINT_VIOLATED
824*12967Sgavin.maltby@oracle.com * SCF_ERROR_DELETED
825*12967Sgavin.maltby@oracle.com * SCF_ERROR_HANDLE_MISMATCH
826*12967Sgavin.maltby@oracle.com * SCF_ERROR_INTERNAL
827*12967Sgavin.maltby@oracle.com * SCF_ERROR_INVALID_ARGUMENT
828*12967Sgavin.maltby@oracle.com * SCF_ERROR_NO_RESOURCES
829*12967Sgavin.maltby@oracle.com * SCF_ERROR_NOT_BOUND
830*12967Sgavin.maltby@oracle.com * SCF_ERROR_NOT_FOUND
831*12967Sgavin.maltby@oracle.com * SCF_ERROR_NOT_SET
832*12967Sgavin.maltby@oracle.com */
833*12967Sgavin.maltby@oracle.com static int
decode_fmri(const char * fmri,scf_handle_t * h,scf_service_t ** s,scf_instance_t ** i)834*12967Sgavin.maltby@oracle.com decode_fmri(const char *fmri, scf_handle_t *h, scf_service_t **s,
835*12967Sgavin.maltby@oracle.com scf_instance_t **i)
836*12967Sgavin.maltby@oracle.com {
837*12967Sgavin.maltby@oracle.com if (scf_handle_decode_fmri(h, fmri, NULL, *s, NULL, NULL, NULL,
838*12967Sgavin.maltby@oracle.com SCF_DECODE_FMRI_EXACT) != SCF_SUCCESS) {
839*12967Sgavin.maltby@oracle.com if (scf_error() == SCF_ERROR_CONSTRAINT_VIOLATED) {
840*12967Sgavin.maltby@oracle.com scf_service_destroy(*s);
841*12967Sgavin.maltby@oracle.com *s = NULL;
842*12967Sgavin.maltby@oracle.com } else {
843*12967Sgavin.maltby@oracle.com return (SCF_FAILED);
844*12967Sgavin.maltby@oracle.com }
845*12967Sgavin.maltby@oracle.com }
846*12967Sgavin.maltby@oracle.com if (*s == NULL)
847*12967Sgavin.maltby@oracle.com if (scf_handle_decode_fmri(h, fmri, NULL, NULL, *i,
848*12967Sgavin.maltby@oracle.com NULL, NULL, SCF_DECODE_FMRI_EXACT) != SCF_SUCCESS) {
849*12967Sgavin.maltby@oracle.com return (SCF_FAILED);
850*12967Sgavin.maltby@oracle.com }
851*12967Sgavin.maltby@oracle.com
852*12967Sgavin.maltby@oracle.com return (SCF_SUCCESS);
853*12967Sgavin.maltby@oracle.com }
854*12967Sgavin.maltby@oracle.com
855*12967Sgavin.maltby@oracle.com /*
856*12967Sgavin.maltby@oracle.com * Return size in bytes for an SCF_TYPE_*. Not all libscf types are supported
857*12967Sgavin.maltby@oracle.com */
858*12967Sgavin.maltby@oracle.com static int
get_type_size(scf_type_t t)859*12967Sgavin.maltby@oracle.com get_type_size(scf_type_t t)
860*12967Sgavin.maltby@oracle.com {
861*12967Sgavin.maltby@oracle.com switch (t) {
862*12967Sgavin.maltby@oracle.com case SCF_TYPE_BOOLEAN:
863*12967Sgavin.maltby@oracle.com return (sizeof (uint8_t));
864*12967Sgavin.maltby@oracle.com case SCF_TYPE_COUNT:
865*12967Sgavin.maltby@oracle.com return (sizeof (uint64_t));
866*12967Sgavin.maltby@oracle.com case SCF_TYPE_INTEGER:
867*12967Sgavin.maltby@oracle.com return (sizeof (int64_t));
868*12967Sgavin.maltby@oracle.com case SCF_TYPE_ASTRING:
869*12967Sgavin.maltby@oracle.com case SCF_TYPE_USTRING:
870*12967Sgavin.maltby@oracle.com return (sizeof (void *));
871*12967Sgavin.maltby@oracle.com default:
872*12967Sgavin.maltby@oracle.com return (-1);
873*12967Sgavin.maltby@oracle.com }
874*12967Sgavin.maltby@oracle.com
875*12967Sgavin.maltby@oracle.com /*NOTREACHED*/
876*12967Sgavin.maltby@oracle.com }
877*12967Sgavin.maltby@oracle.com
878*12967Sgavin.maltby@oracle.com /*
879*12967Sgavin.maltby@oracle.com * Return a pointer to the array of values according to its type
880*12967Sgavin.maltby@oracle.com */
881*12967Sgavin.maltby@oracle.com static void **
get_v_pointer(scf_values_t * v)882*12967Sgavin.maltby@oracle.com get_v_pointer(scf_values_t *v)
883*12967Sgavin.maltby@oracle.com {
884*12967Sgavin.maltby@oracle.com switch (v->value_type) {
885*12967Sgavin.maltby@oracle.com case SCF_TYPE_BOOLEAN:
886*12967Sgavin.maltby@oracle.com return ((void **)&v->values.v_boolean);
887*12967Sgavin.maltby@oracle.com case SCF_TYPE_COUNT:
888*12967Sgavin.maltby@oracle.com return ((void **)&v->values.v_count);
889*12967Sgavin.maltby@oracle.com case SCF_TYPE_INTEGER:
890*12967Sgavin.maltby@oracle.com return ((void **)&v->values.v_integer);
891*12967Sgavin.maltby@oracle.com case SCF_TYPE_ASTRING:
892*12967Sgavin.maltby@oracle.com return ((void **)&v->values.v_astring);
893*12967Sgavin.maltby@oracle.com case SCF_TYPE_USTRING:
894*12967Sgavin.maltby@oracle.com return ((void **)&v->values.v_ustring);
895*12967Sgavin.maltby@oracle.com default:
896*12967Sgavin.maltby@oracle.com return (NULL);
897*12967Sgavin.maltby@oracle.com }
898*12967Sgavin.maltby@oracle.com
899*12967Sgavin.maltby@oracle.com /*NOTREACHED*/
900*12967Sgavin.maltby@oracle.com }
901*12967Sgavin.maltby@oracle.com
902*12967Sgavin.maltby@oracle.com /*
903*12967Sgavin.maltby@oracle.com * Populate scf_values_t value array at position c.
904*12967Sgavin.maltby@oracle.com */
905*12967Sgavin.maltby@oracle.com static int
get_value(scf_value_t * val,scf_values_t * v,int c,char * buf,int sz)906*12967Sgavin.maltby@oracle.com get_value(scf_value_t *val, scf_values_t *v, int c, char *buf, int sz)
907*12967Sgavin.maltby@oracle.com {
908*12967Sgavin.maltby@oracle.com switch (v->value_type) {
909*12967Sgavin.maltby@oracle.com case SCF_TYPE_BOOLEAN:
910*12967Sgavin.maltby@oracle.com return (scf_value_get_boolean(val, v->values.v_boolean + c));
911*12967Sgavin.maltby@oracle.com case SCF_TYPE_COUNT:
912*12967Sgavin.maltby@oracle.com return (scf_value_get_count(val, v->values.v_count + c));
913*12967Sgavin.maltby@oracle.com case SCF_TYPE_INTEGER:
914*12967Sgavin.maltby@oracle.com return (scf_value_get_integer(val, v->values.v_integer + c));
915*12967Sgavin.maltby@oracle.com case SCF_TYPE_ASTRING:
916*12967Sgavin.maltby@oracle.com if (scf_value_get_astring(val, buf, sz) < 0 ||
917*12967Sgavin.maltby@oracle.com (v->values.v_astring[c] = strdup(buf)) == NULL) {
918*12967Sgavin.maltby@oracle.com (void) scf_set_error(SCF_ERROR_NO_MEMORY);
919*12967Sgavin.maltby@oracle.com return (-1);
920*12967Sgavin.maltby@oracle.com }
921*12967Sgavin.maltby@oracle.com return (0);
922*12967Sgavin.maltby@oracle.com case SCF_TYPE_USTRING:
923*12967Sgavin.maltby@oracle.com if (scf_value_get_ustring(val, buf, sz) < 0 ||
924*12967Sgavin.maltby@oracle.com (v->values.v_ustring[c] = strdup(buf)) == NULL) {
925*12967Sgavin.maltby@oracle.com (void) scf_set_error(SCF_ERROR_NO_MEMORY);
926*12967Sgavin.maltby@oracle.com return (-1);
927*12967Sgavin.maltby@oracle.com }
928*12967Sgavin.maltby@oracle.com return (0);
929*12967Sgavin.maltby@oracle.com default:
930*12967Sgavin.maltby@oracle.com return (-1);
931*12967Sgavin.maltby@oracle.com }
932*12967Sgavin.maltby@oracle.com
933*12967Sgavin.maltby@oracle.com /*NOTREACHED*/
934*12967Sgavin.maltby@oracle.com }
935*12967Sgavin.maltby@oracle.com
936*12967Sgavin.maltby@oracle.com /*
937*12967Sgavin.maltby@oracle.com * Populate scf_values_t structure with values from prop
938*12967Sgavin.maltby@oracle.com */
939*12967Sgavin.maltby@oracle.com static int
values_get(scf_property_t * prop,scf_values_t * v)940*12967Sgavin.maltby@oracle.com values_get(scf_property_t *prop, scf_values_t *v)
941*12967Sgavin.maltby@oracle.com {
942*12967Sgavin.maltby@oracle.com scf_handle_t *h = scf_property_handle(prop);
943*12967Sgavin.maltby@oracle.com scf_error_t scf_e = scf_error();
944*12967Sgavin.maltby@oracle.com scf_value_t *val = scf_value_create(h);
945*12967Sgavin.maltby@oracle.com scf_iter_t *it = scf_iter_create(h);
946*12967Sgavin.maltby@oracle.com scf_type_t type = SCF_TYPE_INVALID;
947*12967Sgavin.maltby@oracle.com ssize_t sz = scf_limit(SCF_LIMIT_MAX_VALUE_LENGTH) + 1;
948*12967Sgavin.maltby@oracle.com char *buf = malloc(sz);
949*12967Sgavin.maltby@oracle.com void **p;
950*12967Sgavin.maltby@oracle.com int err, elem_sz, count, cursz;
951*12967Sgavin.maltby@oracle.com int r = SCF_FAILED;
952*12967Sgavin.maltby@oracle.com
953*12967Sgavin.maltby@oracle.com assert(v != NULL);
954*12967Sgavin.maltby@oracle.com assert(v->reserved == NULL);
955*12967Sgavin.maltby@oracle.com if (buf == NULL) {
956*12967Sgavin.maltby@oracle.com (void) scf_set_error(SCF_ERROR_NO_MEMORY);
957*12967Sgavin.maltby@oracle.com goto cleanup;
958*12967Sgavin.maltby@oracle.com }
959*12967Sgavin.maltby@oracle.com if (h == NULL) {
960*12967Sgavin.maltby@oracle.com /*
961*12967Sgavin.maltby@oracle.com * Use the error stored in scf_e
962*12967Sgavin.maltby@oracle.com */
963*12967Sgavin.maltby@oracle.com (void) scf_set_error(scf_e);
964*12967Sgavin.maltby@oracle.com goto cleanup;
965*12967Sgavin.maltby@oracle.com }
966*12967Sgavin.maltby@oracle.com if (val == NULL || it == NULL)
967*12967Sgavin.maltby@oracle.com goto cleanup;
968*12967Sgavin.maltby@oracle.com
969*12967Sgavin.maltby@oracle.com if (scf_property_type(prop, &type) != SCF_SUCCESS)
970*12967Sgavin.maltby@oracle.com goto cleanup;
971*12967Sgavin.maltby@oracle.com if (scf_property_is_type(prop, v->value_type) != SCF_SUCCESS)
972*12967Sgavin.maltby@oracle.com goto error;
973*12967Sgavin.maltby@oracle.com
974*12967Sgavin.maltby@oracle.com elem_sz = get_type_size(type);
975*12967Sgavin.maltby@oracle.com assert(elem_sz > 0);
976*12967Sgavin.maltby@oracle.com
977*12967Sgavin.maltby@oracle.com p = get_v_pointer(v);
978*12967Sgavin.maltby@oracle.com assert(p != NULL);
979*12967Sgavin.maltby@oracle.com
980*12967Sgavin.maltby@oracle.com cursz = count = v->value_count;
981*12967Sgavin.maltby@oracle.com if (scf_iter_property_values(it, prop) != 0) {
982*12967Sgavin.maltby@oracle.com goto error;
983*12967Sgavin.maltby@oracle.com }
984*12967Sgavin.maltby@oracle.com
985*12967Sgavin.maltby@oracle.com while ((err = scf_iter_next_value(it, val)) == 1) {
986*12967Sgavin.maltby@oracle.com if (count + 1 >= cursz) {
987*12967Sgavin.maltby@oracle.com void *tmp;
988*12967Sgavin.maltby@oracle.com
989*12967Sgavin.maltby@oracle.com /* set initial size or double it */
990*12967Sgavin.maltby@oracle.com cursz = cursz ? 2 * cursz : 8;
991*12967Sgavin.maltby@oracle.com if ((tmp = realloc(*p, cursz * elem_sz)) == NULL) {
992*12967Sgavin.maltby@oracle.com (void) scf_set_error(SCF_ERROR_NO_MEMORY);
993*12967Sgavin.maltby@oracle.com goto error;
994*12967Sgavin.maltby@oracle.com }
995*12967Sgavin.maltby@oracle.com *p = tmp;
996*12967Sgavin.maltby@oracle.com }
997*12967Sgavin.maltby@oracle.com
998*12967Sgavin.maltby@oracle.com if (get_value(val, v, count, buf, sz) != 0)
999*12967Sgavin.maltby@oracle.com goto error;
1000*12967Sgavin.maltby@oracle.com
1001*12967Sgavin.maltby@oracle.com count++;
1002*12967Sgavin.maltby@oracle.com }
1003*12967Sgavin.maltby@oracle.com
1004*12967Sgavin.maltby@oracle.com v->value_count = count;
1005*12967Sgavin.maltby@oracle.com
1006*12967Sgavin.maltby@oracle.com if (err != 0)
1007*12967Sgavin.maltby@oracle.com goto error;
1008*12967Sgavin.maltby@oracle.com
1009*12967Sgavin.maltby@oracle.com r = SCF_SUCCESS;
1010*12967Sgavin.maltby@oracle.com goto cleanup;
1011*12967Sgavin.maltby@oracle.com
1012*12967Sgavin.maltby@oracle.com error:
1013*12967Sgavin.maltby@oracle.com v->value_count = count;
1014*12967Sgavin.maltby@oracle.com scf_values_destroy(v);
1015*12967Sgavin.maltby@oracle.com
1016*12967Sgavin.maltby@oracle.com cleanup:
1017*12967Sgavin.maltby@oracle.com free(buf);
1018*12967Sgavin.maltby@oracle.com scf_iter_destroy(it);
1019*12967Sgavin.maltby@oracle.com scf_value_destroy(val);
1020*12967Sgavin.maltby@oracle.com return (r);
1021*12967Sgavin.maltby@oracle.com }
1022*12967Sgavin.maltby@oracle.com
1023*12967Sgavin.maltby@oracle.com /*
1024*12967Sgavin.maltby@oracle.com * Add values from property p to existing nvlist_t nvl. The data type in the
1025*12967Sgavin.maltby@oracle.com * nvlist is inferred from the scf_type_t of the property.
1026*12967Sgavin.maltby@oracle.com *
1027*12967Sgavin.maltby@oracle.com * Returns SCF_SUCCESS or SCF_FAILED on
1028*12967Sgavin.maltby@oracle.com * SCF_ERROR_CONNECTION_BROKEN
1029*12967Sgavin.maltby@oracle.com * SCF_ERROR_DELETED
1030*12967Sgavin.maltby@oracle.com * SCF_ERROR_HANDLE_DESTROYED
1031*12967Sgavin.maltby@oracle.com * SCF_ERROR_HANDLE_MISMATCH
1032*12967Sgavin.maltby@oracle.com * SCF_ERROR_INVALID_ARGUMENT
1033*12967Sgavin.maltby@oracle.com * SCF_ERROR_NO_MEMORY
1034*12967Sgavin.maltby@oracle.com * SCF_ERROR_NO_RESOURCES
1035*12967Sgavin.maltby@oracle.com * SCF_ERROR_NOT_BOUND
1036*12967Sgavin.maltby@oracle.com * SCF_ERROR_NOT_SET
1037*12967Sgavin.maltby@oracle.com * SCF_ERROR_PERMISSION_DENIED
1038*12967Sgavin.maltby@oracle.com * SCF_ERROR_TYPE_MISMATCH
1039*12967Sgavin.maltby@oracle.com */
1040*12967Sgavin.maltby@oracle.com static int
add_prop_to_nvlist(scf_property_t * p,const char * pname,nvlist_t * nvl,int array)1041*12967Sgavin.maltby@oracle.com add_prop_to_nvlist(scf_property_t *p, const char *pname, nvlist_t *nvl,
1042*12967Sgavin.maltby@oracle.com int array)
1043*12967Sgavin.maltby@oracle.com {
1044*12967Sgavin.maltby@oracle.com scf_values_t vals = { 0 };
1045*12967Sgavin.maltby@oracle.com scf_type_t type, base_type;
1046*12967Sgavin.maltby@oracle.com int r = SCF_FAILED;
1047*12967Sgavin.maltby@oracle.com int err = 0;
1048*12967Sgavin.maltby@oracle.com
1049*12967Sgavin.maltby@oracle.com if (p == NULL || pname == NULL || *pname == '\0' || nvl == NULL) {
1050*12967Sgavin.maltby@oracle.com (void) scf_set_error(SCF_ERROR_INVALID_ARGUMENT);
1051*12967Sgavin.maltby@oracle.com return (r);
1052*12967Sgavin.maltby@oracle.com }
1053*12967Sgavin.maltby@oracle.com
1054*12967Sgavin.maltby@oracle.com if (scf_property_type(p, &type) != 0)
1055*12967Sgavin.maltby@oracle.com goto cleanup;
1056*12967Sgavin.maltby@oracle.com
1057*12967Sgavin.maltby@oracle.com /*
1058*12967Sgavin.maltby@oracle.com * scf_values_t does not support subtypes of SCF_TYPE_USTRING,
1059*12967Sgavin.maltby@oracle.com * mapping them all to SCF_TYPE_USTRING
1060*12967Sgavin.maltby@oracle.com */
1061*12967Sgavin.maltby@oracle.com base_type = scf_true_base_type(type);
1062*12967Sgavin.maltby@oracle.com if (base_type == SCF_TYPE_ASTRING && type != SCF_TYPE_ASTRING)
1063*12967Sgavin.maltby@oracle.com type = SCF_TYPE_USTRING;
1064*12967Sgavin.maltby@oracle.com
1065*12967Sgavin.maltby@oracle.com vals.value_type = type;
1066*12967Sgavin.maltby@oracle.com if (values_get(p, &vals) != SCF_SUCCESS) {
1067*12967Sgavin.maltby@oracle.com if (scf_error() == SCF_ERROR_INVALID_ARGUMENT) {
1068*12967Sgavin.maltby@oracle.com assert(0);
1069*12967Sgavin.maltby@oracle.com abort();
1070*12967Sgavin.maltby@oracle.com }
1071*12967Sgavin.maltby@oracle.com goto cleanup;
1072*12967Sgavin.maltby@oracle.com }
1073*12967Sgavin.maltby@oracle.com
1074*12967Sgavin.maltby@oracle.com switch (vals.value_type) {
1075*12967Sgavin.maltby@oracle.com case SCF_TYPE_BOOLEAN:
1076*12967Sgavin.maltby@oracle.com {
1077*12967Sgavin.maltby@oracle.com boolean_t *v;
1078*12967Sgavin.maltby@oracle.com int i;
1079*12967Sgavin.maltby@oracle.com int n = vals.value_count;
1080*12967Sgavin.maltby@oracle.com
1081*12967Sgavin.maltby@oracle.com v = calloc(n, sizeof (boolean_t));
1082*12967Sgavin.maltby@oracle.com if (v == NULL) {
1083*12967Sgavin.maltby@oracle.com (void) scf_set_error(SCF_ERROR_NO_MEMORY);
1084*12967Sgavin.maltby@oracle.com goto cleanup;
1085*12967Sgavin.maltby@oracle.com }
1086*12967Sgavin.maltby@oracle.com for (i = 0; i < n; ++i)
1087*12967Sgavin.maltby@oracle.com v[i] = (boolean_t)vals.values.v_boolean[i];
1088*12967Sgavin.maltby@oracle.com
1089*12967Sgavin.maltby@oracle.com if (n == 1 && !array)
1090*12967Sgavin.maltby@oracle.com err = nvlist_add_boolean_value(nvl, pname, *v);
1091*12967Sgavin.maltby@oracle.com else
1092*12967Sgavin.maltby@oracle.com err = nvlist_add_boolean_array(nvl, pname,
1093*12967Sgavin.maltby@oracle.com v, n);
1094*12967Sgavin.maltby@oracle.com if (err != 0) {
1095*12967Sgavin.maltby@oracle.com free(v);
1096*12967Sgavin.maltby@oracle.com goto cleanup;
1097*12967Sgavin.maltby@oracle.com }
1098*12967Sgavin.maltby@oracle.com free(v);
1099*12967Sgavin.maltby@oracle.com }
1100*12967Sgavin.maltby@oracle.com break;
1101*12967Sgavin.maltby@oracle.com
1102*12967Sgavin.maltby@oracle.com case SCF_TYPE_COUNT:
1103*12967Sgavin.maltby@oracle.com if (vals.value_count == 1 && !array)
1104*12967Sgavin.maltby@oracle.com err = nvlist_add_uint64(nvl, pname,
1105*12967Sgavin.maltby@oracle.com *vals.values.v_count);
1106*12967Sgavin.maltby@oracle.com else
1107*12967Sgavin.maltby@oracle.com err = nvlist_add_uint64_array(nvl, pname,
1108*12967Sgavin.maltby@oracle.com vals.values.v_count, vals.value_count);
1109*12967Sgavin.maltby@oracle.com if (err != 0)
1110*12967Sgavin.maltby@oracle.com goto cleanup;
1111*12967Sgavin.maltby@oracle.com
1112*12967Sgavin.maltby@oracle.com break;
1113*12967Sgavin.maltby@oracle.com
1114*12967Sgavin.maltby@oracle.com case SCF_TYPE_INTEGER:
1115*12967Sgavin.maltby@oracle.com if (vals.value_count == 1 && !array)
1116*12967Sgavin.maltby@oracle.com err = nvlist_add_int64(nvl, pname,
1117*12967Sgavin.maltby@oracle.com *vals.values.v_integer);
1118*12967Sgavin.maltby@oracle.com else
1119*12967Sgavin.maltby@oracle.com err = nvlist_add_int64_array(nvl, pname,
1120*12967Sgavin.maltby@oracle.com vals.values.v_integer, vals.value_count);
1121*12967Sgavin.maltby@oracle.com if (err != 0)
1122*12967Sgavin.maltby@oracle.com goto cleanup;
1123*12967Sgavin.maltby@oracle.com
1124*12967Sgavin.maltby@oracle.com break;
1125*12967Sgavin.maltby@oracle.com
1126*12967Sgavin.maltby@oracle.com case SCF_TYPE_ASTRING:
1127*12967Sgavin.maltby@oracle.com if (vals.value_count == 1 && !array)
1128*12967Sgavin.maltby@oracle.com err = nvlist_add_string(nvl, pname,
1129*12967Sgavin.maltby@oracle.com *vals.values.v_astring);
1130*12967Sgavin.maltby@oracle.com else
1131*12967Sgavin.maltby@oracle.com err = nvlist_add_string_array(nvl, pname,
1132*12967Sgavin.maltby@oracle.com vals.values.v_astring, vals.value_count);
1133*12967Sgavin.maltby@oracle.com if (err != 0)
1134*12967Sgavin.maltby@oracle.com goto cleanup;
1135*12967Sgavin.maltby@oracle.com break;
1136*12967Sgavin.maltby@oracle.com
1137*12967Sgavin.maltby@oracle.com default:
1138*12967Sgavin.maltby@oracle.com (void) scf_set_error(SCF_ERROR_INVALID_ARGUMENT);
1139*12967Sgavin.maltby@oracle.com goto cleanup;
1140*12967Sgavin.maltby@oracle.com }
1141*12967Sgavin.maltby@oracle.com
1142*12967Sgavin.maltby@oracle.com r = SCF_SUCCESS;
1143*12967Sgavin.maltby@oracle.com cleanup:
1144*12967Sgavin.maltby@oracle.com scf_values_destroy(&vals);
1145*12967Sgavin.maltby@oracle.com switch (err) {
1146*12967Sgavin.maltby@oracle.com case 0:
1147*12967Sgavin.maltby@oracle.com break;
1148*12967Sgavin.maltby@oracle.com case EINVAL:
1149*12967Sgavin.maltby@oracle.com (void) scf_set_error(SCF_ERROR_INVALID_ARGUMENT);
1150*12967Sgavin.maltby@oracle.com break;
1151*12967Sgavin.maltby@oracle.com case ENOMEM:
1152*12967Sgavin.maltby@oracle.com (void) scf_set_error(SCF_ERROR_NO_MEMORY);
1153*12967Sgavin.maltby@oracle.com break;
1154*12967Sgavin.maltby@oracle.com default:
1155*12967Sgavin.maltby@oracle.com /* we should *never* get here */
1156*12967Sgavin.maltby@oracle.com abort();
1157*12967Sgavin.maltby@oracle.com }
1158*12967Sgavin.maltby@oracle.com
1159*12967Sgavin.maltby@oracle.com return (r);
1160*12967Sgavin.maltby@oracle.com }
1161*12967Sgavin.maltby@oracle.com
1162*12967Sgavin.maltby@oracle.com /*
1163*12967Sgavin.maltby@oracle.com * Parse property name "mechanism,parameter" into separate mechanism
1164*12967Sgavin.maltby@oracle.com * and parameter. *mech must be freed by caller. *val points into
1165*12967Sgavin.maltby@oracle.com * *mech and must not be freed.
1166*12967Sgavin.maltby@oracle.com *
1167*12967Sgavin.maltby@oracle.com * Returns SCF_SUCCESS or SCF_FAILED on
1168*12967Sgavin.maltby@oracle.com * SCF_ERROR_NO_MEMORY
1169*12967Sgavin.maltby@oracle.com * SCF_ERROR_NOT_FOUND
1170*12967Sgavin.maltby@oracle.com */
1171*12967Sgavin.maltby@oracle.com static int
get_mech_name(const char * name,char ** mech,char ** val)1172*12967Sgavin.maltby@oracle.com get_mech_name(const char *name, char **mech, char **val)
1173*12967Sgavin.maltby@oracle.com {
1174*12967Sgavin.maltby@oracle.com char *p;
1175*12967Sgavin.maltby@oracle.com char *m;
1176*12967Sgavin.maltby@oracle.com
1177*12967Sgavin.maltby@oracle.com if ((m = strdup(name)) == NULL) {
1178*12967Sgavin.maltby@oracle.com (void) scf_set_error(SCF_ERROR_NO_MEMORY);
1179*12967Sgavin.maltby@oracle.com return (SCF_FAILED);
1180*12967Sgavin.maltby@oracle.com }
1181*12967Sgavin.maltby@oracle.com if ((p = strchr(m, ',')) == NULL) {
1182*12967Sgavin.maltby@oracle.com free(m);
1183*12967Sgavin.maltby@oracle.com (void) scf_set_error(SCF_ERROR_NOT_FOUND);
1184*12967Sgavin.maltby@oracle.com return (SCF_FAILED);
1185*12967Sgavin.maltby@oracle.com }
1186*12967Sgavin.maltby@oracle.com *p = '\0';
1187*12967Sgavin.maltby@oracle.com *val = p + 1;
1188*12967Sgavin.maltby@oracle.com *mech = m;
1189*12967Sgavin.maltby@oracle.com
1190*12967Sgavin.maltby@oracle.com return (SCF_SUCCESS);
1191*12967Sgavin.maltby@oracle.com }
1192*12967Sgavin.maltby@oracle.com
1193*12967Sgavin.maltby@oracle.com /*
1194*12967Sgavin.maltby@oracle.com * Return the number of transitions in a transition set.
1195*12967Sgavin.maltby@oracle.com * If the transition set is invalid, it returns zero.
1196*12967Sgavin.maltby@oracle.com */
1197*12967Sgavin.maltby@oracle.com static uint_t
num_of_transitions(int32_t t)1198*12967Sgavin.maltby@oracle.com num_of_transitions(int32_t t)
1199*12967Sgavin.maltby@oracle.com {
1200*12967Sgavin.maltby@oracle.com int i;
1201*12967Sgavin.maltby@oracle.com int n = 0;
1202*12967Sgavin.maltby@oracle.com
1203*12967Sgavin.maltby@oracle.com if (SCF_TRANS_VALID(t)) {
1204*12967Sgavin.maltby@oracle.com for (i = 0x1; i < SCF_STATE_ALL; i <<= 1) {
1205*12967Sgavin.maltby@oracle.com if (i & t)
1206*12967Sgavin.maltby@oracle.com ++n;
1207*12967Sgavin.maltby@oracle.com if (SCF_TRANS_INITIAL_STATE(t) & i)
1208*12967Sgavin.maltby@oracle.com ++n;
1209*12967Sgavin.maltby@oracle.com }
1210*12967Sgavin.maltby@oracle.com }
1211*12967Sgavin.maltby@oracle.com
1212*12967Sgavin.maltby@oracle.com return (n);
1213*12967Sgavin.maltby@oracle.com }
1214*12967Sgavin.maltby@oracle.com
1215*12967Sgavin.maltby@oracle.com /*
1216*12967Sgavin.maltby@oracle.com * Return the SCF_STATE_* macro value for the state in the FMA classes for
1217*12967Sgavin.maltby@oracle.com * SMF state transitions. They are of type:
1218*12967Sgavin.maltby@oracle.com * SCF_SVC_TRANSITION_CLASS.<state>
1219*12967Sgavin.maltby@oracle.com * ireport.os.smf.state-transition.<state>
1220*12967Sgavin.maltby@oracle.com */
1221*12967Sgavin.maltby@oracle.com static int32_t
class_to_transition(const char * c)1222*12967Sgavin.maltby@oracle.com class_to_transition(const char *c)
1223*12967Sgavin.maltby@oracle.com {
1224*12967Sgavin.maltby@oracle.com const char *p;
1225*12967Sgavin.maltby@oracle.com int r = 0;
1226*12967Sgavin.maltby@oracle.com size_t n;
1227*12967Sgavin.maltby@oracle.com
1228*12967Sgavin.maltby@oracle.com if (!is_svc_stn(c)) {
1229*12967Sgavin.maltby@oracle.com return (0);
1230*12967Sgavin.maltby@oracle.com }
1231*12967Sgavin.maltby@oracle.com
1232*12967Sgavin.maltby@oracle.com /*
1233*12967Sgavin.maltby@oracle.com * if we get here, c is SCF_SVC_TRANSITION_CLASS or longer
1234*12967Sgavin.maltby@oracle.com */
1235*12967Sgavin.maltby@oracle.com p = c + strlen(SCF_SVC_TRANSITION_CLASS);
1236*12967Sgavin.maltby@oracle.com if (*p == '.')
1237*12967Sgavin.maltby@oracle.com ++p;
1238*12967Sgavin.maltby@oracle.com else
1239*12967Sgavin.maltby@oracle.com return (0);
1240*12967Sgavin.maltby@oracle.com
1241*12967Sgavin.maltby@oracle.com if ((n = base_class_len(p)) == 0)
1242*12967Sgavin.maltby@oracle.com return (0);
1243*12967Sgavin.maltby@oracle.com
1244*12967Sgavin.maltby@oracle.com if ((r = state_from_string(p, n)) == -1)
1245*12967Sgavin.maltby@oracle.com r = 0;
1246*12967Sgavin.maltby@oracle.com
1247*12967Sgavin.maltby@oracle.com return (r);
1248*12967Sgavin.maltby@oracle.com }
1249*12967Sgavin.maltby@oracle.com
1250*12967Sgavin.maltby@oracle.com /*
1251*12967Sgavin.maltby@oracle.com * return SCF_SUCCESS or SCF_FAILED on
1252*12967Sgavin.maltby@oracle.com * SCF_ERROR_BACKEND_ACCESS
1253*12967Sgavin.maltby@oracle.com * SCF_ERROR_BACKEND_READONLY
1254*12967Sgavin.maltby@oracle.com * SCF_ERROR_CONNECTION_BROKEN
1255*12967Sgavin.maltby@oracle.com * SCF_ERROR_DELETED
1256*12967Sgavin.maltby@oracle.com * SCF_ERROR_INTERNAL
1257*12967Sgavin.maltby@oracle.com * SCF_ERROR_INVALID_ARGUMENT
1258*12967Sgavin.maltby@oracle.com * SCF_ERROR_NO_MEMORY
1259*12967Sgavin.maltby@oracle.com * SCF_ERROR_NO_RESOURCES
1260*12967Sgavin.maltby@oracle.com * SCF_ERROR_NOT_FOUND
1261*12967Sgavin.maltby@oracle.com * SCF_ERROR_PERMISSION_DENIED
1262*12967Sgavin.maltby@oracle.com */
1263*12967Sgavin.maltby@oracle.com int
smf_notify_set_params(const char * class,nvlist_t * attr)1264*12967Sgavin.maltby@oracle.com smf_notify_set_params(const char *class, nvlist_t *attr)
1265*12967Sgavin.maltby@oracle.com {
1266*12967Sgavin.maltby@oracle.com uint32_t ver;
1267*12967Sgavin.maltby@oracle.com int32_t tset;
1268*12967Sgavin.maltby@oracle.com scf_handle_t *h = _scf_handle_create_and_bind(SCF_VERSION);
1269*12967Sgavin.maltby@oracle.com scf_error_t scf_e = scf_error();
1270*12967Sgavin.maltby@oracle.com scf_service_t *s = scf_service_create(h);
1271*12967Sgavin.maltby@oracle.com scf_instance_t *i = scf_instance_create(h);
1272*12967Sgavin.maltby@oracle.com scf_propertygroup_t *pg = scf_pg_create(h);
1273*12967Sgavin.maltby@oracle.com nvlist_t *params = NULL;
1274*12967Sgavin.maltby@oracle.com char *fmri = (char *)SCF_NOTIFY_PARAMS_INST;
1275*12967Sgavin.maltby@oracle.com char *pgname = NULL;
1276*12967Sgavin.maltby@oracle.com int r = SCF_FAILED;
1277*12967Sgavin.maltby@oracle.com boolean_t is_stn;
1278*12967Sgavin.maltby@oracle.com int j;
1279*12967Sgavin.maltby@oracle.com
1280*12967Sgavin.maltby@oracle.com assert(class != NULL);
1281*12967Sgavin.maltby@oracle.com if (h == NULL) {
1282*12967Sgavin.maltby@oracle.com /*
1283*12967Sgavin.maltby@oracle.com * use saved error if _scf_handle_create_and_bind() fails
1284*12967Sgavin.maltby@oracle.com */
1285*12967Sgavin.maltby@oracle.com (void) scf_set_error(scf_e);
1286*12967Sgavin.maltby@oracle.com goto cleanup;
1287*12967Sgavin.maltby@oracle.com }
1288*12967Sgavin.maltby@oracle.com if (i == NULL || s == NULL || pg == NULL)
1289*12967Sgavin.maltby@oracle.com goto cleanup;
1290*12967Sgavin.maltby@oracle.com
1291*12967Sgavin.maltby@oracle.com /* check version */
1292*12967Sgavin.maltby@oracle.com if (nvlist_lookup_uint32(attr, SCF_NOTIFY_NAME_VERSION, &ver) != 0 ||
1293*12967Sgavin.maltby@oracle.com ver != SCF_NOTIFY_PARAMS_VERSION) {
1294*12967Sgavin.maltby@oracle.com (void) scf_set_error(SCF_ERROR_INVALID_ARGUMENT);
1295*12967Sgavin.maltby@oracle.com goto cleanup;
1296*12967Sgavin.maltby@oracle.com }
1297*12967Sgavin.maltby@oracle.com
1298*12967Sgavin.maltby@oracle.com if (nvlist_lookup_nvlist(attr, SCF_NOTIFY_PARAMS, ¶ms) != 0) {
1299*12967Sgavin.maltby@oracle.com (void) scf_set_error(SCF_ERROR_INVALID_ARGUMENT);
1300*12967Sgavin.maltby@oracle.com goto cleanup;
1301*12967Sgavin.maltby@oracle.com }
1302*12967Sgavin.maltby@oracle.com
1303*12967Sgavin.maltby@oracle.com is_stn = is_svc_stn(class);
1304*12967Sgavin.maltby@oracle.com /* special case SMF state transition notification */
1305*12967Sgavin.maltby@oracle.com if (is_stn &&
1306*12967Sgavin.maltby@oracle.com (nvlist_lookup_string(attr, SCF_NOTIFY_NAME_FMRI, &fmri) != 0 ||
1307*12967Sgavin.maltby@oracle.com nvlist_lookup_int32(attr, SCF_NOTIFY_NAME_TSET, &tset) != 0 ||
1308*12967Sgavin.maltby@oracle.com !SCF_TRANS_VALID(tset))) {
1309*12967Sgavin.maltby@oracle.com (void) scf_set_error(SCF_ERROR_INVALID_ARGUMENT);
1310*12967Sgavin.maltby@oracle.com goto cleanup;
1311*12967Sgavin.maltby@oracle.com }
1312*12967Sgavin.maltby@oracle.com if (decode_fmri(fmri, h, &s, &i) != SCF_SUCCESS)
1313*12967Sgavin.maltby@oracle.com if (scf_error() == SCF_ERROR_CONSTRAINT_VIOLATED) {
1314*12967Sgavin.maltby@oracle.com (void) scf_set_error(SCF_ERROR_INVALID_ARGUMENT);
1315*12967Sgavin.maltby@oracle.com } else if (check_scf_error(scf_error(), errs_1)) {
1316*12967Sgavin.maltby@oracle.com goto cleanup;
1317*12967Sgavin.maltby@oracle.com }
1318*12967Sgavin.maltby@oracle.com
1319*12967Sgavin.maltby@oracle.com if (is_stn) {
1320*12967Sgavin.maltby@oracle.com tset |= class_to_transition(class);
1321*12967Sgavin.maltby@oracle.com
1322*12967Sgavin.maltby@oracle.com if (!SCF_TRANS_VALID(tset)) {
1323*12967Sgavin.maltby@oracle.com (void) scf_set_error(SCF_ERROR_INVALID_ARGUMENT);
1324*12967Sgavin.maltby@oracle.com goto cleanup;
1325*12967Sgavin.maltby@oracle.com }
1326*12967Sgavin.maltby@oracle.com
1327*12967Sgavin.maltby@oracle.com for (j = 0; st_pgnames[j].st_pgname != NULL; ++j) {
1328*12967Sgavin.maltby@oracle.com /* if this transition is not in the tset, continue */
1329*12967Sgavin.maltby@oracle.com if (!(tset & st_pgnames[j].st_state))
1330*12967Sgavin.maltby@oracle.com continue;
1331*12967Sgavin.maltby@oracle.com
1332*12967Sgavin.maltby@oracle.com if (get_or_add_pg(s, i, st_pgnames[j].st_pgname,
1333*12967Sgavin.maltby@oracle.com SCF_NOTIFY_PARAMS_PG_TYPE, 0, pg) != 0 &&
1334*12967Sgavin.maltby@oracle.com check_scf_error(scf_error(), errs_2))
1335*12967Sgavin.maltby@oracle.com goto cleanup;
1336*12967Sgavin.maltby@oracle.com
1337*12967Sgavin.maltby@oracle.com if (notify_set_params(pg, params) != 0)
1338*12967Sgavin.maltby@oracle.com goto cleanup;
1339*12967Sgavin.maltby@oracle.com }
1340*12967Sgavin.maltby@oracle.com if (s == NULL) {
1341*12967Sgavin.maltby@oracle.com /* We only need to refresh the instance */
1342*12967Sgavin.maltby@oracle.com if (_smf_refresh_instance_i(i) != 0 &&
1343*12967Sgavin.maltby@oracle.com check_scf_error(scf_error(), errs_1))
1344*12967Sgavin.maltby@oracle.com goto cleanup;
1345*12967Sgavin.maltby@oracle.com } else {
1346*12967Sgavin.maltby@oracle.com /* We have to refresh all instances in the service */
1347*12967Sgavin.maltby@oracle.com if (_smf_refresh_all_instances(s) != 0 &&
1348*12967Sgavin.maltby@oracle.com check_scf_error(scf_error(), errs_1))
1349*12967Sgavin.maltby@oracle.com goto cleanup;
1350*12967Sgavin.maltby@oracle.com }
1351*12967Sgavin.maltby@oracle.com } else {
1352*12967Sgavin.maltby@oracle.com if ((pgname = class_to_pgname(class)) == NULL)
1353*12967Sgavin.maltby@oracle.com goto cleanup;
1354*12967Sgavin.maltby@oracle.com if (get_or_add_pg(s, i, pgname, SCF_GROUP_APPLICATION, 0, pg) !=
1355*12967Sgavin.maltby@oracle.com 0) {
1356*12967Sgavin.maltby@oracle.com if (check_scf_error(scf_error(), errs_2)) {
1357*12967Sgavin.maltby@oracle.com goto cleanup;
1358*12967Sgavin.maltby@oracle.com }
1359*12967Sgavin.maltby@oracle.com }
1360*12967Sgavin.maltby@oracle.com if (notify_set_params(pg, params) != 0) {
1361*12967Sgavin.maltby@oracle.com goto cleanup;
1362*12967Sgavin.maltby@oracle.com }
1363*12967Sgavin.maltby@oracle.com if (_smf_refresh_instance_i(i) != 0 &&
1364*12967Sgavin.maltby@oracle.com check_scf_error(scf_error(), errs_1))
1365*12967Sgavin.maltby@oracle.com goto cleanup;
1366*12967Sgavin.maltby@oracle.com }
1367*12967Sgavin.maltby@oracle.com
1368*12967Sgavin.maltby@oracle.com r = SCF_SUCCESS;
1369*12967Sgavin.maltby@oracle.com cleanup:
1370*12967Sgavin.maltby@oracle.com scf_instance_destroy(i);
1371*12967Sgavin.maltby@oracle.com scf_service_destroy(s);
1372*12967Sgavin.maltby@oracle.com scf_pg_destroy(pg);
1373*12967Sgavin.maltby@oracle.com scf_handle_destroy(h);
1374*12967Sgavin.maltby@oracle.com free(pgname);
1375*12967Sgavin.maltby@oracle.com
1376*12967Sgavin.maltby@oracle.com return (r);
1377*12967Sgavin.maltby@oracle.com }
1378*12967Sgavin.maltby@oracle.com
1379*12967Sgavin.maltby@oracle.com /*
1380*12967Sgavin.maltby@oracle.com * returns SCF_SUCCESS or SCF_FAILED on
1381*12967Sgavin.maltby@oracle.com * SCF_ERROR_CONNECTION_BROKEN
1382*12967Sgavin.maltby@oracle.com * SCF_ERROR_DELETED
1383*12967Sgavin.maltby@oracle.com * SCF_ERROR_HANDLE_DESTROYED
1384*12967Sgavin.maltby@oracle.com * SCF_ERROR_HANDLE_MISMATCH
1385*12967Sgavin.maltby@oracle.com * SCF_ERROR_INVALID_ARGUMENT
1386*12967Sgavin.maltby@oracle.com * SCF_ERROR_NO_MEMORY
1387*12967Sgavin.maltby@oracle.com * SCF_ERROR_NO_RESOURCES
1388*12967Sgavin.maltby@oracle.com * SCF_ERROR_NOT_BOUND
1389*12967Sgavin.maltby@oracle.com * SCF_ERROR_NOT_FOUND
1390*12967Sgavin.maltby@oracle.com * SCF_ERROR_NOT_SET
1391*12967Sgavin.maltby@oracle.com * SCF_ERROR_PERMISSION_DENIED
1392*12967Sgavin.maltby@oracle.com */
1393*12967Sgavin.maltby@oracle.com int
_scf_notify_get_params(scf_propertygroup_t * pg,nvlist_t * params)1394*12967Sgavin.maltby@oracle.com _scf_notify_get_params(scf_propertygroup_t *pg, nvlist_t *params)
1395*12967Sgavin.maltby@oracle.com {
1396*12967Sgavin.maltby@oracle.com scf_handle_t *h = scf_pg_handle(pg);
1397*12967Sgavin.maltby@oracle.com scf_error_t scf_e = scf_error();
1398*12967Sgavin.maltby@oracle.com scf_property_t *p = scf_property_create(h);
1399*12967Sgavin.maltby@oracle.com scf_iter_t *it = scf_iter_create(h);
1400*12967Sgavin.maltby@oracle.com int sz = scf_limit(SCF_LIMIT_MAX_NAME_LENGTH) + 1;
1401*12967Sgavin.maltby@oracle.com char *name = malloc(sz);
1402*12967Sgavin.maltby@oracle.com int r = SCF_FAILED;
1403*12967Sgavin.maltby@oracle.com int err;
1404*12967Sgavin.maltby@oracle.com
1405*12967Sgavin.maltby@oracle.com if (h == NULL) {
1406*12967Sgavin.maltby@oracle.com /*
1407*12967Sgavin.maltby@oracle.com * Use the error stored in scf_e
1408*12967Sgavin.maltby@oracle.com */
1409*12967Sgavin.maltby@oracle.com (void) scf_set_error(scf_e);
1410*12967Sgavin.maltby@oracle.com goto cleanup;
1411*12967Sgavin.maltby@oracle.com }
1412*12967Sgavin.maltby@oracle.com if (it == NULL || p == NULL)
1413*12967Sgavin.maltby@oracle.com goto cleanup;
1414*12967Sgavin.maltby@oracle.com
1415*12967Sgavin.maltby@oracle.com if (name == NULL) {
1416*12967Sgavin.maltby@oracle.com (void) scf_set_error(SCF_ERROR_NO_MEMORY);
1417*12967Sgavin.maltby@oracle.com goto cleanup;
1418*12967Sgavin.maltby@oracle.com }
1419*12967Sgavin.maltby@oracle.com
1420*12967Sgavin.maltby@oracle.com if (scf_iter_pg_properties(it, pg) != SCF_SUCCESS) {
1421*12967Sgavin.maltby@oracle.com if (check_scf_error(scf_error(), errs_1)) {
1422*12967Sgavin.maltby@oracle.com goto cleanup;
1423*12967Sgavin.maltby@oracle.com }
1424*12967Sgavin.maltby@oracle.com }
1425*12967Sgavin.maltby@oracle.com
1426*12967Sgavin.maltby@oracle.com while ((err = scf_iter_next_property(it, p)) == 1) {
1427*12967Sgavin.maltby@oracle.com nvlist_t *nvl;
1428*12967Sgavin.maltby@oracle.com int nvl_new = 0;
1429*12967Sgavin.maltby@oracle.com char *mech;
1430*12967Sgavin.maltby@oracle.com char *val;
1431*12967Sgavin.maltby@oracle.com
1432*12967Sgavin.maltby@oracle.com if (scf_property_get_name(p, name, sz) == SCF_FAILED) {
1433*12967Sgavin.maltby@oracle.com if (check_scf_error(scf_error(), errs_1)) {
1434*12967Sgavin.maltby@oracle.com goto cleanup;
1435*12967Sgavin.maltby@oracle.com }
1436*12967Sgavin.maltby@oracle.com }
1437*12967Sgavin.maltby@oracle.com
1438*12967Sgavin.maltby@oracle.com if (get_mech_name(name, &mech, &val) != SCF_SUCCESS) {
1439*12967Sgavin.maltby@oracle.com if (scf_error() == SCF_ERROR_NOT_FOUND)
1440*12967Sgavin.maltby@oracle.com continue;
1441*12967Sgavin.maltby@oracle.com goto cleanup;
1442*12967Sgavin.maltby@oracle.com }
1443*12967Sgavin.maltby@oracle.com
1444*12967Sgavin.maltby@oracle.com if (nvlist_lookup_nvlist(params, mech, &nvl) != 0) {
1445*12967Sgavin.maltby@oracle.com if (nvlist_alloc(&nvl, NV_UNIQUE_NAME, 0) != 0) {
1446*12967Sgavin.maltby@oracle.com (void) scf_set_error(SCF_ERROR_NO_MEMORY);
1447*12967Sgavin.maltby@oracle.com free(mech);
1448*12967Sgavin.maltby@oracle.com goto cleanup;
1449*12967Sgavin.maltby@oracle.com }
1450*12967Sgavin.maltby@oracle.com nvl_new = 1;
1451*12967Sgavin.maltby@oracle.com }
1452*12967Sgavin.maltby@oracle.com
1453*12967Sgavin.maltby@oracle.com if (add_prop_to_nvlist(p, val, nvl, 1) != SCF_SUCCESS) {
1454*12967Sgavin.maltby@oracle.com if (check_scf_error(scf_error(), errs_2)) {
1455*12967Sgavin.maltby@oracle.com free(mech);
1456*12967Sgavin.maltby@oracle.com nvlist_free(nvl);
1457*12967Sgavin.maltby@oracle.com goto cleanup;
1458*12967Sgavin.maltby@oracle.com }
1459*12967Sgavin.maltby@oracle.com }
1460*12967Sgavin.maltby@oracle.com if (nvl_new) {
1461*12967Sgavin.maltby@oracle.com if (nvlist_add_nvlist(params, mech, nvl) != 0) {
1462*12967Sgavin.maltby@oracle.com (void) scf_set_error(SCF_ERROR_NO_MEMORY);
1463*12967Sgavin.maltby@oracle.com free(mech);
1464*12967Sgavin.maltby@oracle.com nvlist_free(nvl);
1465*12967Sgavin.maltby@oracle.com goto cleanup;
1466*12967Sgavin.maltby@oracle.com }
1467*12967Sgavin.maltby@oracle.com nvlist_free(nvl);
1468*12967Sgavin.maltby@oracle.com }
1469*12967Sgavin.maltby@oracle.com
1470*12967Sgavin.maltby@oracle.com free(mech);
1471*12967Sgavin.maltby@oracle.com }
1472*12967Sgavin.maltby@oracle.com
1473*12967Sgavin.maltby@oracle.com if (err == 0) {
1474*12967Sgavin.maltby@oracle.com r = SCF_SUCCESS;
1475*12967Sgavin.maltby@oracle.com } else if (check_scf_error(scf_error(), errs_2)) {
1476*12967Sgavin.maltby@oracle.com goto cleanup;
1477*12967Sgavin.maltby@oracle.com }
1478*12967Sgavin.maltby@oracle.com
1479*12967Sgavin.maltby@oracle.com cleanup:
1480*12967Sgavin.maltby@oracle.com scf_iter_destroy(it);
1481*12967Sgavin.maltby@oracle.com scf_property_destroy(p);
1482*12967Sgavin.maltby@oracle.com free(name);
1483*12967Sgavin.maltby@oracle.com
1484*12967Sgavin.maltby@oracle.com return (r);
1485*12967Sgavin.maltby@oracle.com }
1486*12967Sgavin.maltby@oracle.com
1487*12967Sgavin.maltby@oracle.com /*
1488*12967Sgavin.maltby@oracle.com * Look up pg containing an SMF state transition parameters. If it cannot find
1489*12967Sgavin.maltby@oracle.com * the pg in the composed view of the instance, it will look in the global
1490*12967Sgavin.maltby@oracle.com * instance for the system wide parameters.
1491*12967Sgavin.maltby@oracle.com * Instance, service and global instance have to be passed by caller.
1492*12967Sgavin.maltby@oracle.com *
1493*12967Sgavin.maltby@oracle.com * returns SCF_SUCCESS or SCF_FAILED on
1494*12967Sgavin.maltby@oracle.com * SCF_ERROR_BACKEND_ACCESS
1495*12967Sgavin.maltby@oracle.com * SCF_ERROR_CONNECTION_BROKEN
1496*12967Sgavin.maltby@oracle.com * SCF_ERROR_DELETED
1497*12967Sgavin.maltby@oracle.com * SCF_ERROR_HANDLE_DESTROYED
1498*12967Sgavin.maltby@oracle.com * SCF_ERROR_HANDLE_MISMATCH
1499*12967Sgavin.maltby@oracle.com * SCF_ERROR_INTERNAL
1500*12967Sgavin.maltby@oracle.com * SCF_ERROR_INVALID_ARGUMENT
1501*12967Sgavin.maltby@oracle.com * SCF_ERROR_NO_MEMORY
1502*12967Sgavin.maltby@oracle.com * SCF_ERROR_NO_RESOURCES
1503*12967Sgavin.maltby@oracle.com * SCF_ERROR_NOT_BOUND
1504*12967Sgavin.maltby@oracle.com * SCF_ERROR_NOT_FOUND
1505*12967Sgavin.maltby@oracle.com * SCF_ERROR_NOT_SET
1506*12967Sgavin.maltby@oracle.com */
1507*12967Sgavin.maltby@oracle.com static int
get_stn_pg(scf_service_t * s,scf_instance_t * i,scf_instance_t * g,const char * pgname,scf_propertygroup_t * pg)1508*12967Sgavin.maltby@oracle.com get_stn_pg(scf_service_t *s, scf_instance_t *i, scf_instance_t *g,
1509*12967Sgavin.maltby@oracle.com const char *pgname, scf_propertygroup_t *pg)
1510*12967Sgavin.maltby@oracle.com {
1511*12967Sgavin.maltby@oracle.com if (get_pg(s, i, pgname, pg, 1) == 0 ||
1512*12967Sgavin.maltby@oracle.com scf_error() == SCF_ERROR_NOT_FOUND &&
1513*12967Sgavin.maltby@oracle.com get_pg(NULL, g, pgname, pg, 0) == 0)
1514*12967Sgavin.maltby@oracle.com return (SCF_SUCCESS);
1515*12967Sgavin.maltby@oracle.com
1516*12967Sgavin.maltby@oracle.com return (SCF_FAILED);
1517*12967Sgavin.maltby@oracle.com }
1518*12967Sgavin.maltby@oracle.com
1519*12967Sgavin.maltby@oracle.com /*
1520*12967Sgavin.maltby@oracle.com * Populates nvlist_t params with the source fmri for the pg
1521*12967Sgavin.maltby@oracle.com *
1522*12967Sgavin.maltby@oracle.com * return SCF_SUCCESS or SCF_FAILED on
1523*12967Sgavin.maltby@oracle.com * SCF_ERROR_DELETED
1524*12967Sgavin.maltby@oracle.com * SCF_ERROR_CONNECTION_BROKEN
1525*12967Sgavin.maltby@oracle.com * SCF_ERROR_NO_MEMORY
1526*12967Sgavin.maltby@oracle.com */
1527*12967Sgavin.maltby@oracle.com static int
get_pg_source(scf_propertygroup_t * pg,nvlist_t * params)1528*12967Sgavin.maltby@oracle.com get_pg_source(scf_propertygroup_t *pg, nvlist_t *params)
1529*12967Sgavin.maltby@oracle.com {
1530*12967Sgavin.maltby@oracle.com size_t sz = scf_limit(SCF_LIMIT_MAX_FMRI_LENGTH) + 1;
1531*12967Sgavin.maltby@oracle.com char *fmri = malloc(sz);
1532*12967Sgavin.maltby@oracle.com char *p;
1533*12967Sgavin.maltby@oracle.com int r = SCF_FAILED;
1534*12967Sgavin.maltby@oracle.com
1535*12967Sgavin.maltby@oracle.com if (fmri == NULL) {
1536*12967Sgavin.maltby@oracle.com (void) scf_set_error(SCF_ERROR_NO_MEMORY);
1537*12967Sgavin.maltby@oracle.com goto out;
1538*12967Sgavin.maltby@oracle.com }
1539*12967Sgavin.maltby@oracle.com
1540*12967Sgavin.maltby@oracle.com if (scf_pg_to_fmri(pg, fmri, sz) == -1) {
1541*12967Sgavin.maltby@oracle.com if (check_scf_error(scf_error(), errs_1)) {
1542*12967Sgavin.maltby@oracle.com goto out;
1543*12967Sgavin.maltby@oracle.com }
1544*12967Sgavin.maltby@oracle.com }
1545*12967Sgavin.maltby@oracle.com
1546*12967Sgavin.maltby@oracle.com /* get rid of the properties part of the pg source */
1547*12967Sgavin.maltby@oracle.com if ((p = strrchr(fmri, ':')) != NULL && p > fmri)
1548*12967Sgavin.maltby@oracle.com *(p - 1) = '\0';
1549*12967Sgavin.maltby@oracle.com if (nvlist_add_string(params, SCF_NOTIFY_PARAMS_SOURCE_NAME, fmri) !=
1550*12967Sgavin.maltby@oracle.com 0) {
1551*12967Sgavin.maltby@oracle.com (void) scf_set_error(SCF_ERROR_NO_MEMORY);
1552*12967Sgavin.maltby@oracle.com goto out;
1553*12967Sgavin.maltby@oracle.com }
1554*12967Sgavin.maltby@oracle.com
1555*12967Sgavin.maltby@oracle.com r = SCF_SUCCESS;
1556*12967Sgavin.maltby@oracle.com out:
1557*12967Sgavin.maltby@oracle.com free(fmri);
1558*12967Sgavin.maltby@oracle.com return (r);
1559*12967Sgavin.maltby@oracle.com }
1560*12967Sgavin.maltby@oracle.com
1561*12967Sgavin.maltby@oracle.com /*
1562*12967Sgavin.maltby@oracle.com * Specialized function to get SMF state transition notification parameters
1563*12967Sgavin.maltby@oracle.com *
1564*12967Sgavin.maltby@oracle.com * return SCF_SUCCESS or SCF_FAILED on
1565*12967Sgavin.maltby@oracle.com * SCF_ERROR_BACKEND_ACCESS
1566*12967Sgavin.maltby@oracle.com * SCF_ERROR_CONNECTION_BROKEN
1567*12967Sgavin.maltby@oracle.com * SCF_ERROR_DELETED
1568*12967Sgavin.maltby@oracle.com * SCF_ERROR_INTERNAL
1569*12967Sgavin.maltby@oracle.com * SCF_ERROR_INVALID_ARGUMENT
1570*12967Sgavin.maltby@oracle.com * SCF_ERROR_NO_MEMORY
1571*12967Sgavin.maltby@oracle.com * SCF_ERROR_NO_RESOURCES
1572*12967Sgavin.maltby@oracle.com * SCF_ERROR_NOT_FOUND
1573*12967Sgavin.maltby@oracle.com * SCF_ERROR_PERMISSION_DENIED
1574*12967Sgavin.maltby@oracle.com */
1575*12967Sgavin.maltby@oracle.com int
_scf_get_svc_notify_params(const char * fmri,nvlist_t * nvl,int32_t tset,int getsource,int getglobal)1576*12967Sgavin.maltby@oracle.com _scf_get_svc_notify_params(const char *fmri, nvlist_t *nvl, int32_t tset,
1577*12967Sgavin.maltby@oracle.com int getsource, int getglobal)
1578*12967Sgavin.maltby@oracle.com {
1579*12967Sgavin.maltby@oracle.com scf_handle_t *h = _scf_handle_create_and_bind(SCF_VERSION);
1580*12967Sgavin.maltby@oracle.com scf_error_t scf_e = scf_error();
1581*12967Sgavin.maltby@oracle.com scf_service_t *s = scf_service_create(h);
1582*12967Sgavin.maltby@oracle.com scf_instance_t *i = scf_instance_create(h);
1583*12967Sgavin.maltby@oracle.com scf_instance_t *g = scf_instance_create(h);
1584*12967Sgavin.maltby@oracle.com scf_propertygroup_t *pg = scf_pg_create(h);
1585*12967Sgavin.maltby@oracle.com int r = SCF_FAILED;
1586*12967Sgavin.maltby@oracle.com nvlist_t **params = NULL;
1587*12967Sgavin.maltby@oracle.com uint_t c, nvl_num = 0;
1588*12967Sgavin.maltby@oracle.com int not_found = 1;
1589*12967Sgavin.maltby@oracle.com int j;
1590*12967Sgavin.maltby@oracle.com const char *pgname;
1591*12967Sgavin.maltby@oracle.com
1592*12967Sgavin.maltby@oracle.com assert(fmri != NULL && nvl != NULL);
1593*12967Sgavin.maltby@oracle.com if (h == NULL) {
1594*12967Sgavin.maltby@oracle.com /*
1595*12967Sgavin.maltby@oracle.com * use saved error if _scf_handle_create_and_bind() fails
1596*12967Sgavin.maltby@oracle.com */
1597*12967Sgavin.maltby@oracle.com (void) scf_set_error(scf_e);
1598*12967Sgavin.maltby@oracle.com goto cleanup;
1599*12967Sgavin.maltby@oracle.com }
1600*12967Sgavin.maltby@oracle.com if (s == NULL || i == NULL || g == NULL || pg == NULL)
1601*12967Sgavin.maltby@oracle.com goto cleanup;
1602*12967Sgavin.maltby@oracle.com
1603*12967Sgavin.maltby@oracle.com if (decode_fmri(fmri, h, &s, &i) != SCF_SUCCESS ||
1604*12967Sgavin.maltby@oracle.com scf_handle_decode_fmri(h, SCF_INSTANCE_GLOBAL, NULL, NULL, g, NULL,
1605*12967Sgavin.maltby@oracle.com NULL, SCF_DECODE_FMRI_EXACT) != 0) {
1606*12967Sgavin.maltby@oracle.com if (scf_error() == SCF_ERROR_CONSTRAINT_VIOLATED) {
1607*12967Sgavin.maltby@oracle.com (void) scf_set_error(SCF_ERROR_INVALID_ARGUMENT);
1608*12967Sgavin.maltby@oracle.com } else if (check_scf_error(scf_error(), errs_1)) {
1609*12967Sgavin.maltby@oracle.com goto cleanup;
1610*12967Sgavin.maltby@oracle.com }
1611*12967Sgavin.maltby@oracle.com }
1612*12967Sgavin.maltby@oracle.com
1613*12967Sgavin.maltby@oracle.com nvl_num = num_of_transitions(tset);
1614*12967Sgavin.maltby@oracle.com if ((params = calloc(nvl_num, sizeof (nvlist_t *))) == NULL) {
1615*12967Sgavin.maltby@oracle.com (void) scf_set_error(SCF_ERROR_NO_MEMORY);
1616*12967Sgavin.maltby@oracle.com goto cleanup;
1617*12967Sgavin.maltby@oracle.com }
1618*12967Sgavin.maltby@oracle.com
1619*12967Sgavin.maltby@oracle.com for (c = 0; c < nvl_num; ++c)
1620*12967Sgavin.maltby@oracle.com if (nvlist_alloc(params + c, NV_UNIQUE_NAME, 0) != 0) {
1621*12967Sgavin.maltby@oracle.com (void) scf_set_error(SCF_ERROR_NO_MEMORY);
1622*12967Sgavin.maltby@oracle.com goto cleanup;
1623*12967Sgavin.maltby@oracle.com }
1624*12967Sgavin.maltby@oracle.com
1625*12967Sgavin.maltby@oracle.com for (c = 0, j = 0; st_pgnames[j].st_pgname != NULL; ++j) {
1626*12967Sgavin.maltby@oracle.com /* if this transition is not in the tset, continue */
1627*12967Sgavin.maltby@oracle.com if (!(tset & st_pgnames[j].st_state))
1628*12967Sgavin.maltby@oracle.com continue;
1629*12967Sgavin.maltby@oracle.com
1630*12967Sgavin.maltby@oracle.com assert(c < nvl_num);
1631*12967Sgavin.maltby@oracle.com pgname = st_pgnames[j].st_pgname;
1632*12967Sgavin.maltby@oracle.com
1633*12967Sgavin.maltby@oracle.com if (nvlist_add_int32(params[c], SCF_NOTIFY_NAME_TSET,
1634*12967Sgavin.maltby@oracle.com st_pgnames[j].st_state) != 0) {
1635*12967Sgavin.maltby@oracle.com (void) scf_set_error(SCF_ERROR_NO_MEMORY);
1636*12967Sgavin.maltby@oracle.com goto cleanup;
1637*12967Sgavin.maltby@oracle.com }
1638*12967Sgavin.maltby@oracle.com if ((getglobal ? get_stn_pg(s, i, g, pgname, pg) :
1639*12967Sgavin.maltby@oracle.com get_pg(s, i, pgname, pg, 1)) == SCF_SUCCESS) {
1640*12967Sgavin.maltby@oracle.com not_found = 0;
1641*12967Sgavin.maltby@oracle.com if (_scf_notify_get_params(pg, params[c]) !=
1642*12967Sgavin.maltby@oracle.com SCF_SUCCESS)
1643*12967Sgavin.maltby@oracle.com goto cleanup;
1644*12967Sgavin.maltby@oracle.com if (getsource && get_pg_source(pg, params[c]) !=
1645*12967Sgavin.maltby@oracle.com SCF_SUCCESS)
1646*12967Sgavin.maltby@oracle.com goto cleanup;
1647*12967Sgavin.maltby@oracle.com } else if (scf_error() == SCF_ERROR_NOT_FOUND ||
1648*12967Sgavin.maltby@oracle.com scf_error() == SCF_ERROR_DELETED) {
1649*12967Sgavin.maltby@oracle.com /* keep driving */
1650*12967Sgavin.maltby@oracle.com /*EMPTY*/
1651*12967Sgavin.maltby@oracle.com } else if (check_scf_error(scf_error(), errs_1)) {
1652*12967Sgavin.maltby@oracle.com goto cleanup;
1653*12967Sgavin.maltby@oracle.com }
1654*12967Sgavin.maltby@oracle.com ++c;
1655*12967Sgavin.maltby@oracle.com }
1656*12967Sgavin.maltby@oracle.com
1657*12967Sgavin.maltby@oracle.com if (not_found) {
1658*12967Sgavin.maltby@oracle.com (void) scf_set_error(SCF_ERROR_NOT_FOUND);
1659*12967Sgavin.maltby@oracle.com goto cleanup;
1660*12967Sgavin.maltby@oracle.com }
1661*12967Sgavin.maltby@oracle.com
1662*12967Sgavin.maltby@oracle.com assert(c == nvl_num);
1663*12967Sgavin.maltby@oracle.com
1664*12967Sgavin.maltby@oracle.com if (nvlist_add_nvlist_array(nvl, SCF_NOTIFY_PARAMS, params, nvl_num) !=
1665*12967Sgavin.maltby@oracle.com 0 || nvlist_add_uint32(nvl, SCF_NOTIFY_NAME_VERSION,
1666*12967Sgavin.maltby@oracle.com SCF_NOTIFY_PARAMS_VERSION) != 0) {
1667*12967Sgavin.maltby@oracle.com (void) scf_set_error(SCF_ERROR_NO_MEMORY);
1668*12967Sgavin.maltby@oracle.com goto cleanup;
1669*12967Sgavin.maltby@oracle.com }
1670*12967Sgavin.maltby@oracle.com
1671*12967Sgavin.maltby@oracle.com r = SCF_SUCCESS;
1672*12967Sgavin.maltby@oracle.com
1673*12967Sgavin.maltby@oracle.com cleanup:
1674*12967Sgavin.maltby@oracle.com scf_pg_destroy(pg);
1675*12967Sgavin.maltby@oracle.com scf_instance_destroy(i);
1676*12967Sgavin.maltby@oracle.com scf_instance_destroy(g);
1677*12967Sgavin.maltby@oracle.com scf_service_destroy(s);
1678*12967Sgavin.maltby@oracle.com scf_handle_destroy(h);
1679*12967Sgavin.maltby@oracle.com if (params != NULL)
1680*12967Sgavin.maltby@oracle.com for (c = 0; c < nvl_num; ++c)
1681*12967Sgavin.maltby@oracle.com nvlist_free(params[c]);
1682*12967Sgavin.maltby@oracle.com free(params);
1683*12967Sgavin.maltby@oracle.com
1684*12967Sgavin.maltby@oracle.com return (r);
1685*12967Sgavin.maltby@oracle.com }
1686*12967Sgavin.maltby@oracle.com
1687*12967Sgavin.maltby@oracle.com /*
1688*12967Sgavin.maltby@oracle.com * Specialized function to get fma notification parameters
1689*12967Sgavin.maltby@oracle.com *
1690*12967Sgavin.maltby@oracle.com * return SCF_SUCCESS or SCF_FAILED on
1691*12967Sgavin.maltby@oracle.com * SCF_ERROR_BACKEND_ACCESS
1692*12967Sgavin.maltby@oracle.com * SCF_ERROR_CONNECTION_BROKEN
1693*12967Sgavin.maltby@oracle.com * SCF_ERROR_DELETED
1694*12967Sgavin.maltby@oracle.com * SCF_ERROR_INTERNAL
1695*12967Sgavin.maltby@oracle.com * SCF_ERROR_INVALID_ARGUMENT
1696*12967Sgavin.maltby@oracle.com * SCF_ERROR_NO_MEMORY
1697*12967Sgavin.maltby@oracle.com * SCF_ERROR_NO_RESOURCES
1698*12967Sgavin.maltby@oracle.com * SCF_ERROR_NOT_FOUND
1699*12967Sgavin.maltby@oracle.com * SCF_ERROR_PERMISSION_DENIED
1700*12967Sgavin.maltby@oracle.com */
1701*12967Sgavin.maltby@oracle.com int
_scf_get_fma_notify_params(const char * class,nvlist_t * nvl,int getsource)1702*12967Sgavin.maltby@oracle.com _scf_get_fma_notify_params(const char *class, nvlist_t *nvl, int getsource)
1703*12967Sgavin.maltby@oracle.com {
1704*12967Sgavin.maltby@oracle.com scf_handle_t *h = _scf_handle_create_and_bind(SCF_VERSION);
1705*12967Sgavin.maltby@oracle.com scf_error_t scf_e = scf_error();
1706*12967Sgavin.maltby@oracle.com scf_instance_t *i = scf_instance_create(h);
1707*12967Sgavin.maltby@oracle.com scf_propertygroup_t *pg = scf_pg_create(h);
1708*12967Sgavin.maltby@oracle.com int r = SCF_FAILED;
1709*12967Sgavin.maltby@oracle.com nvlist_t *params = NULL;
1710*12967Sgavin.maltby@oracle.com char *pgname = NULL;
1711*12967Sgavin.maltby@oracle.com
1712*12967Sgavin.maltby@oracle.com if (h == NULL) {
1713*12967Sgavin.maltby@oracle.com /*
1714*12967Sgavin.maltby@oracle.com * use saved error if _scf_handle_create_and_bind() fails
1715*12967Sgavin.maltby@oracle.com */
1716*12967Sgavin.maltby@oracle.com (void) scf_set_error(scf_e);
1717*12967Sgavin.maltby@oracle.com goto cleanup;
1718*12967Sgavin.maltby@oracle.com }
1719*12967Sgavin.maltby@oracle.com if (i == NULL || pg == NULL)
1720*12967Sgavin.maltby@oracle.com goto cleanup;
1721*12967Sgavin.maltby@oracle.com
1722*12967Sgavin.maltby@oracle.com if (scf_handle_decode_fmri(h, SCF_NOTIFY_PARAMS_INST, NULL, NULL, i,
1723*12967Sgavin.maltby@oracle.com NULL, NULL, SCF_DECODE_FMRI_EXACT) != SCF_SUCCESS) {
1724*12967Sgavin.maltby@oracle.com if (check_scf_error(scf_error(), errs_1)) {
1725*12967Sgavin.maltby@oracle.com goto cleanup;
1726*12967Sgavin.maltby@oracle.com }
1727*12967Sgavin.maltby@oracle.com }
1728*12967Sgavin.maltby@oracle.com
1729*12967Sgavin.maltby@oracle.com if ((pgname = class_to_pgname(class)) == NULL)
1730*12967Sgavin.maltby@oracle.com goto cleanup;
1731*12967Sgavin.maltby@oracle.com
1732*12967Sgavin.maltby@oracle.com while (get_pg(NULL, i, pgname, pg, 0) != 0) {
1733*12967Sgavin.maltby@oracle.com if (scf_error() == SCF_ERROR_NOT_FOUND) {
1734*12967Sgavin.maltby@oracle.com char *p = strrchr(pgname, '.');
1735*12967Sgavin.maltby@oracle.com
1736*12967Sgavin.maltby@oracle.com if (p != NULL) {
1737*12967Sgavin.maltby@oracle.com *p = ',';
1738*12967Sgavin.maltby@oracle.com /*
1739*12967Sgavin.maltby@oracle.com * since the resulting string is shorter,
1740*12967Sgavin.maltby@oracle.com * there is no risk of buffer overflow
1741*12967Sgavin.maltby@oracle.com */
1742*12967Sgavin.maltby@oracle.com (void) strcpy(p + 1, SCF_NOTIFY_PG_POSTFIX);
1743*12967Sgavin.maltby@oracle.com continue;
1744*12967Sgavin.maltby@oracle.com }
1745*12967Sgavin.maltby@oracle.com }
1746*12967Sgavin.maltby@oracle.com
1747*12967Sgavin.maltby@oracle.com if (check_scf_error(scf_error(), errs_1)) {
1748*12967Sgavin.maltby@oracle.com goto cleanup;
1749*12967Sgavin.maltby@oracle.com }
1750*12967Sgavin.maltby@oracle.com }
1751*12967Sgavin.maltby@oracle.com
1752*12967Sgavin.maltby@oracle.com if (nvlist_alloc(¶ms, NV_UNIQUE_NAME, 0) != 0) {
1753*12967Sgavin.maltby@oracle.com (void) scf_set_error(SCF_ERROR_NO_MEMORY);
1754*12967Sgavin.maltby@oracle.com goto cleanup;
1755*12967Sgavin.maltby@oracle.com }
1756*12967Sgavin.maltby@oracle.com
1757*12967Sgavin.maltby@oracle.com if (_scf_notify_get_params(pg, params) != SCF_SUCCESS)
1758*12967Sgavin.maltby@oracle.com goto cleanup;
1759*12967Sgavin.maltby@oracle.com
1760*12967Sgavin.maltby@oracle.com if (getsource && get_pg_source(pg, params) != SCF_SUCCESS)
1761*12967Sgavin.maltby@oracle.com goto cleanup;
1762*12967Sgavin.maltby@oracle.com
1763*12967Sgavin.maltby@oracle.com if (nvlist_add_nvlist_array(nvl, SCF_NOTIFY_PARAMS, ¶ms, 1) != 0 ||
1764*12967Sgavin.maltby@oracle.com nvlist_add_uint32(nvl, SCF_NOTIFY_NAME_VERSION,
1765*12967Sgavin.maltby@oracle.com SCF_NOTIFY_PARAMS_VERSION) != 0) {
1766*12967Sgavin.maltby@oracle.com (void) scf_set_error(SCF_ERROR_NO_MEMORY);
1767*12967Sgavin.maltby@oracle.com goto cleanup;
1768*12967Sgavin.maltby@oracle.com }
1769*12967Sgavin.maltby@oracle.com
1770*12967Sgavin.maltby@oracle.com r = SCF_SUCCESS;
1771*12967Sgavin.maltby@oracle.com
1772*12967Sgavin.maltby@oracle.com cleanup:
1773*12967Sgavin.maltby@oracle.com if (params)
1774*12967Sgavin.maltby@oracle.com nvlist_free(params);
1775*12967Sgavin.maltby@oracle.com scf_pg_destroy(pg);
1776*12967Sgavin.maltby@oracle.com scf_instance_destroy(i);
1777*12967Sgavin.maltby@oracle.com scf_handle_destroy(h);
1778*12967Sgavin.maltby@oracle.com free(pgname);
1779*12967Sgavin.maltby@oracle.com
1780*12967Sgavin.maltby@oracle.com return (r);
1781*12967Sgavin.maltby@oracle.com }
1782*12967Sgavin.maltby@oracle.com
1783*12967Sgavin.maltby@oracle.com /*
1784*12967Sgavin.maltby@oracle.com * Retrieve the notification parameters for the Event described in the
1785*12967Sgavin.maltby@oracle.com * input nvlist_t nvl.
1786*12967Sgavin.maltby@oracle.com * The function will allocate an nvlist_t to store the notification
1787*12967Sgavin.maltby@oracle.com * parameters. The notification parameters in the output nvlist will have
1788*12967Sgavin.maltby@oracle.com * the following format:
1789*12967Sgavin.maltby@oracle.com *
1790*12967Sgavin.maltby@oracle.com * version (uint32_t)
1791*12967Sgavin.maltby@oracle.com * SCF_NOTIFY_PARAMS (array of embedded nvlists)
1792*12967Sgavin.maltby@oracle.com * (start of notify-params[0])
1793*12967Sgavin.maltby@oracle.com * tset (int32_t)
1794*12967Sgavin.maltby@oracle.com * <mechanism-name> (embedded nvlist)
1795*12967Sgavin.maltby@oracle.com * <parameter-name> <parameter-type>
1796*12967Sgavin.maltby@oracle.com * ...
1797*12967Sgavin.maltby@oracle.com * (end <mechanism-name>)
1798*12967Sgavin.maltby@oracle.com * ...
1799*12967Sgavin.maltby@oracle.com * (end of notify-params[0])
1800*12967Sgavin.maltby@oracle.com * ...
1801*12967Sgavin.maltby@oracle.com *
1802*12967Sgavin.maltby@oracle.com * return SCF_SUCCESS or SCF_FAILED on
1803*12967Sgavin.maltby@oracle.com * SCF_ERROR_BACKEND_ACCESS
1804*12967Sgavin.maltby@oracle.com * SCF_ERROR_CONNECTION_BROKEN
1805*12967Sgavin.maltby@oracle.com * SCF_ERROR_DELETED
1806*12967Sgavin.maltby@oracle.com * SCF_ERROR_INTERNAL
1807*12967Sgavin.maltby@oracle.com * SCF_ERROR_INVALID_ARGUMENT
1808*12967Sgavin.maltby@oracle.com * SCF_ERROR_NO_MEMORY
1809*12967Sgavin.maltby@oracle.com * SCF_ERROR_NO_RESOURCES
1810*12967Sgavin.maltby@oracle.com * SCF_ERROR_NOT_FOUND
1811*12967Sgavin.maltby@oracle.com * SCF_ERROR_PERMISSION_DENIED
1812*12967Sgavin.maltby@oracle.com */
1813*12967Sgavin.maltby@oracle.com int
smf_notify_get_params(nvlist_t ** params,nvlist_t * nvl)1814*12967Sgavin.maltby@oracle.com smf_notify_get_params(nvlist_t **params, nvlist_t *nvl)
1815*12967Sgavin.maltby@oracle.com {
1816*12967Sgavin.maltby@oracle.com char *class;
1817*12967Sgavin.maltby@oracle.com char *from; /* from state */
1818*12967Sgavin.maltby@oracle.com char *to; /* to state */
1819*12967Sgavin.maltby@oracle.com nvlist_t *attr;
1820*12967Sgavin.maltby@oracle.com char *fmri;
1821*12967Sgavin.maltby@oracle.com int32_t tset = 0;
1822*12967Sgavin.maltby@oracle.com int r = SCF_FAILED;
1823*12967Sgavin.maltby@oracle.com
1824*12967Sgavin.maltby@oracle.com if (params == NULL || nvlist_lookup_string(nvl, "class", &class) != 0) {
1825*12967Sgavin.maltby@oracle.com (void) scf_set_error(SCF_ERROR_INVALID_ARGUMENT);
1826*12967Sgavin.maltby@oracle.com return (r);
1827*12967Sgavin.maltby@oracle.com }
1828*12967Sgavin.maltby@oracle.com if (nvlist_alloc(params, NV_UNIQUE_NAME, 0) != 0) {
1829*12967Sgavin.maltby@oracle.com (void) scf_set_error(SCF_ERROR_NO_MEMORY);
1830*12967Sgavin.maltby@oracle.com return (r);
1831*12967Sgavin.maltby@oracle.com }
1832*12967Sgavin.maltby@oracle.com
1833*12967Sgavin.maltby@oracle.com if (is_svc_stn(class)) {
1834*12967Sgavin.maltby@oracle.com if (nvlist_lookup_nvlist(nvl, "attr", &attr) != 0 ||
1835*12967Sgavin.maltby@oracle.com nvlist_lookup_string(attr, "svc-string", &fmri) != 0 ||
1836*12967Sgavin.maltby@oracle.com nvlist_lookup_string(attr, "from-state", &from) != 0 ||
1837*12967Sgavin.maltby@oracle.com nvlist_lookup_string(attr, "to-state", &to) != 0) {
1838*12967Sgavin.maltby@oracle.com (void) scf_set_error(SCF_ERROR_INVALID_ARGUMENT);
1839*12967Sgavin.maltby@oracle.com goto cleanup;
1840*12967Sgavin.maltby@oracle.com }
1841*12967Sgavin.maltby@oracle.com
1842*12967Sgavin.maltby@oracle.com tset = SCF_TRANS(smf_state_from_string(from),
1843*12967Sgavin.maltby@oracle.com smf_state_from_string(to));
1844*12967Sgavin.maltby@oracle.com if (!SCF_TRANS_VALID(tset)) {
1845*12967Sgavin.maltby@oracle.com (void) scf_set_error(SCF_ERROR_INVALID_ARGUMENT);
1846*12967Sgavin.maltby@oracle.com goto cleanup;
1847*12967Sgavin.maltby@oracle.com }
1848*12967Sgavin.maltby@oracle.com tset |= class_to_transition(class);
1849*12967Sgavin.maltby@oracle.com
1850*12967Sgavin.maltby@oracle.com r = _scf_get_svc_notify_params(fmri, *params, tset, 0, 1);
1851*12967Sgavin.maltby@oracle.com } else {
1852*12967Sgavin.maltby@oracle.com r = _scf_get_fma_notify_params(class, *params, 0);
1853*12967Sgavin.maltby@oracle.com }
1854*12967Sgavin.maltby@oracle.com
1855*12967Sgavin.maltby@oracle.com cleanup:
1856*12967Sgavin.maltby@oracle.com if (r == SCF_FAILED) {
1857*12967Sgavin.maltby@oracle.com nvlist_free(*params);
1858*12967Sgavin.maltby@oracle.com *params = NULL;
1859*12967Sgavin.maltby@oracle.com }
1860*12967Sgavin.maltby@oracle.com
1861*12967Sgavin.maltby@oracle.com return (r);
1862*12967Sgavin.maltby@oracle.com }
1863*12967Sgavin.maltby@oracle.com
1864*12967Sgavin.maltby@oracle.com /*
1865*12967Sgavin.maltby@oracle.com * return SCF_SUCCESS or SCF_FAILED on
1866*12967Sgavin.maltby@oracle.com * SCF_ERROR_BACKEND_ACCESS
1867*12967Sgavin.maltby@oracle.com * SCF_ERROR_BACKEND_READONLY
1868*12967Sgavin.maltby@oracle.com * SCF_ERROR_CONNECTION_BROKEN
1869*12967Sgavin.maltby@oracle.com * SCF_ERROR_DELETED
1870*12967Sgavin.maltby@oracle.com * SCF_ERROR_INTERNAL
1871*12967Sgavin.maltby@oracle.com * SCF_ERROR_INVALID_ARGUMENT
1872*12967Sgavin.maltby@oracle.com * SCF_ERROR_NO_MEMORY
1873*12967Sgavin.maltby@oracle.com * SCF_ERROR_NO_RESOURCES
1874*12967Sgavin.maltby@oracle.com * SCF_ERROR_NOT_FOUND
1875*12967Sgavin.maltby@oracle.com * SCF_ERROR_PERMISSION_DENIED
1876*12967Sgavin.maltby@oracle.com */
1877*12967Sgavin.maltby@oracle.com int
smf_notify_del_params(const char * class,const char * fmri,int32_t tset)1878*12967Sgavin.maltby@oracle.com smf_notify_del_params(const char *class, const char *fmri, int32_t tset)
1879*12967Sgavin.maltby@oracle.com {
1880*12967Sgavin.maltby@oracle.com scf_handle_t *h = _scf_handle_create_and_bind(SCF_VERSION);
1881*12967Sgavin.maltby@oracle.com scf_error_t scf_e = scf_error();
1882*12967Sgavin.maltby@oracle.com scf_service_t *s = scf_service_create(h);
1883*12967Sgavin.maltby@oracle.com scf_instance_t *i = scf_instance_create(h);
1884*12967Sgavin.maltby@oracle.com scf_propertygroup_t *pg = scf_pg_create(h);
1885*12967Sgavin.maltby@oracle.com int r = SCF_FAILED;
1886*12967Sgavin.maltby@oracle.com char *pgname = NULL;
1887*12967Sgavin.maltby@oracle.com int j;
1888*12967Sgavin.maltby@oracle.com
1889*12967Sgavin.maltby@oracle.com if (class == NULL) {
1890*12967Sgavin.maltby@oracle.com (void) scf_set_error(SCF_ERROR_INVALID_ARGUMENT);
1891*12967Sgavin.maltby@oracle.com goto cleanup;
1892*12967Sgavin.maltby@oracle.com }
1893*12967Sgavin.maltby@oracle.com
1894*12967Sgavin.maltby@oracle.com if (h == NULL) {
1895*12967Sgavin.maltby@oracle.com /*
1896*12967Sgavin.maltby@oracle.com * use saved error if _scf_handle_create_and_bind() fails
1897*12967Sgavin.maltby@oracle.com */
1898*12967Sgavin.maltby@oracle.com (void) scf_set_error(scf_e);
1899*12967Sgavin.maltby@oracle.com goto cleanup;
1900*12967Sgavin.maltby@oracle.com }
1901*12967Sgavin.maltby@oracle.com if (s == NULL || i == NULL || pg == NULL)
1902*12967Sgavin.maltby@oracle.com goto cleanup;
1903*12967Sgavin.maltby@oracle.com
1904*12967Sgavin.maltby@oracle.com if (is_svc_stn(class)) {
1905*12967Sgavin.maltby@oracle.com tset |= class_to_transition(class);
1906*12967Sgavin.maltby@oracle.com
1907*12967Sgavin.maltby@oracle.com if (!SCF_TRANS_VALID(tset) || fmri == NULL) {
1908*12967Sgavin.maltby@oracle.com (void) scf_set_error(SCF_ERROR_INVALID_ARGUMENT);
1909*12967Sgavin.maltby@oracle.com goto cleanup;
1910*12967Sgavin.maltby@oracle.com }
1911*12967Sgavin.maltby@oracle.com
1912*12967Sgavin.maltby@oracle.com if (decode_fmri(fmri, h, &s, &i) != SCF_SUCCESS) {
1913*12967Sgavin.maltby@oracle.com if (scf_error() == SCF_ERROR_CONSTRAINT_VIOLATED)
1914*12967Sgavin.maltby@oracle.com (void) scf_set_error(
1915*12967Sgavin.maltby@oracle.com SCF_ERROR_INVALID_ARGUMENT);
1916*12967Sgavin.maltby@oracle.com if (check_scf_error(scf_error(), errs_1)) {
1917*12967Sgavin.maltby@oracle.com goto cleanup;
1918*12967Sgavin.maltby@oracle.com }
1919*12967Sgavin.maltby@oracle.com }
1920*12967Sgavin.maltby@oracle.com
1921*12967Sgavin.maltby@oracle.com for (j = 0; st_pgnames[j].st_pgname != NULL; ++j) {
1922*12967Sgavin.maltby@oracle.com /* if this transition is not in the tset, continue */
1923*12967Sgavin.maltby@oracle.com if (!(tset & st_pgnames[j].st_state))
1924*12967Sgavin.maltby@oracle.com continue;
1925*12967Sgavin.maltby@oracle.com
1926*12967Sgavin.maltby@oracle.com if (del_pg(s, i, st_pgnames[j].st_pgname, pg) !=
1927*12967Sgavin.maltby@oracle.com SCF_SUCCESS &&
1928*12967Sgavin.maltby@oracle.com scf_error() != SCF_ERROR_DELETED &&
1929*12967Sgavin.maltby@oracle.com scf_error() != SCF_ERROR_NOT_FOUND) {
1930*12967Sgavin.maltby@oracle.com if (check_scf_error(scf_error(),
1931*12967Sgavin.maltby@oracle.com errs_1)) {
1932*12967Sgavin.maltby@oracle.com goto cleanup;
1933*12967Sgavin.maltby@oracle.com }
1934*12967Sgavin.maltby@oracle.com }
1935*12967Sgavin.maltby@oracle.com }
1936*12967Sgavin.maltby@oracle.com if (s == NULL) {
1937*12967Sgavin.maltby@oracle.com /* We only need to refresh the instance */
1938*12967Sgavin.maltby@oracle.com if (_smf_refresh_instance_i(i) != 0 &&
1939*12967Sgavin.maltby@oracle.com check_scf_error(scf_error(), errs_1))
1940*12967Sgavin.maltby@oracle.com goto cleanup;
1941*12967Sgavin.maltby@oracle.com } else {
1942*12967Sgavin.maltby@oracle.com /* We have to refresh all instances in the service */
1943*12967Sgavin.maltby@oracle.com if (_smf_refresh_all_instances(s) != 0 &&
1944*12967Sgavin.maltby@oracle.com check_scf_error(scf_error(), errs_1))
1945*12967Sgavin.maltby@oracle.com goto cleanup;
1946*12967Sgavin.maltby@oracle.com }
1947*12967Sgavin.maltby@oracle.com } else {
1948*12967Sgavin.maltby@oracle.com if ((pgname = class_to_pgname(class)) == NULL)
1949*12967Sgavin.maltby@oracle.com goto cleanup;
1950*12967Sgavin.maltby@oracle.com
1951*12967Sgavin.maltby@oracle.com if (scf_handle_decode_fmri(h, SCF_NOTIFY_PARAMS_INST, NULL,
1952*12967Sgavin.maltby@oracle.com NULL, i, NULL, NULL, SCF_DECODE_FMRI_EXACT) != SCF_SUCCESS)
1953*12967Sgavin.maltby@oracle.com goto cleanup;
1954*12967Sgavin.maltby@oracle.com
1955*12967Sgavin.maltby@oracle.com if (del_pg(NULL, i, pgname, pg) != SCF_SUCCESS &&
1956*12967Sgavin.maltby@oracle.com scf_error() != SCF_ERROR_DELETED &&
1957*12967Sgavin.maltby@oracle.com scf_error() != SCF_ERROR_NOT_FOUND) {
1958*12967Sgavin.maltby@oracle.com if (check_scf_error(scf_error(), errs_1)) {
1959*12967Sgavin.maltby@oracle.com goto cleanup;
1960*12967Sgavin.maltby@oracle.com }
1961*12967Sgavin.maltby@oracle.com }
1962*12967Sgavin.maltby@oracle.com
1963*12967Sgavin.maltby@oracle.com if (_smf_refresh_instance_i(i) != 0 &&
1964*12967Sgavin.maltby@oracle.com check_scf_error(scf_error(), errs_1))
1965*12967Sgavin.maltby@oracle.com goto cleanup;
1966*12967Sgavin.maltby@oracle.com }
1967*12967Sgavin.maltby@oracle.com
1968*12967Sgavin.maltby@oracle.com
1969*12967Sgavin.maltby@oracle.com r = SCF_SUCCESS;
1970*12967Sgavin.maltby@oracle.com
1971*12967Sgavin.maltby@oracle.com cleanup:
1972*12967Sgavin.maltby@oracle.com scf_pg_destroy(pg);
1973*12967Sgavin.maltby@oracle.com scf_instance_destroy(i);
1974*12967Sgavin.maltby@oracle.com scf_service_destroy(s);
1975*12967Sgavin.maltby@oracle.com scf_handle_destroy(h);
1976*12967Sgavin.maltby@oracle.com free(pgname);
1977*12967Sgavin.maltby@oracle.com
1978*12967Sgavin.maltby@oracle.com return (r);
1979*12967Sgavin.maltby@oracle.com }
1980