4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
23 * Copyright 2010 Sun Microsystems, Inc. All rights reserved.
24 * Use is subject to license terms.
28 * This file contains high level functions used by multiple utilities.
31 #include "libscf_impl.h"
38 #include <sys/systeminfo.h>
39 #include <sys/uadmin.h>
40 #include <sys/utsname.h>
41 #include <sys/secflags.h>
47 * Check whether the platform is on the fastreboot_blacklist.
48 * Return 1 if the platform has been blacklisted, 0 otherwise.
51 scf_is_fb_blacklisted(void)
61 scf_simple_prop_t
*prop
= NULL
;
68 * If there's no SMBIOS, assume it's blacklisted.
70 if ((shp
= smbios_open(NULL
, SMB_VERSION
, 0, &err
)) == NULL
)
74 * If we can't read system info, assume it's blacklisted.
76 if ((id
= smbios_info_system(shp
, &sys
)) == SMB_ERR
||
77 smbios_info_common(shp
, id
, &info
) == SMB_ERR
) {
83 * If we can't read the "platforms" property from property group
84 * BOOT_CONFIG_PG_FBBLACKLIST, assume no platforms have
87 if ((prop
= scf_simple_prop_get(NULL
, FMRI_BOOT_CONFIG
,
88 BOOT_CONFIG_PG_FBBLACKLIST
, "platforms")) == NULL
)
91 numvals
= scf_simple_prop_numvalues(prop
);
93 for (i
= 0; i
< numvals
; i
++) {
94 platform_name
= scf_simple_prop_next_astring(prop
);
95 if (platform_name
== NULL
)
97 if (strcmp(platform_name
, info
.smbi_product
) == 0) {
105 scf_simple_prop_free(prop
);
107 return (blacklisted
);
111 * Add or get a property group given an FMRI.
112 * Return SCF_SUCCESS on success, SCF_FAILED on failure.
115 scf_fmri_pg_get_or_add(const char *fmri
, const char *pgname
,
116 const char *pgtype
, uint32_t pgflags
, int add
)
118 scf_handle_t
*handle
= NULL
;
119 scf_instance_t
*inst
= NULL
;
123 if ((handle
= scf_handle_create(SCF_VERSION
)) == NULL
||
124 scf_handle_bind(handle
) != 0 ||
125 (inst
= scf_instance_create(handle
)) == NULL
||
126 scf_handle_decode_fmri(handle
, fmri
, NULL
, NULL
,
127 inst
, NULL
, NULL
, SCF_DECODE_FMRI_EXACT
) != SCF_SUCCESS
)
131 rc
= scf_instance_add_pg(inst
, pgname
, pgtype
, pgflags
, NULL
);
133 * If the property group already exists, return SCF_SUCCESS.
135 if (rc
!= SCF_SUCCESS
&& scf_error() == SCF_ERROR_EXISTS
)
138 rc
= scf_instance_get_pg(inst
, pgname
, NULL
);
142 if (rc
!= SCF_SUCCESS
)
145 scf_instance_destroy(inst
);
147 (void) scf_handle_unbind(handle
);
148 scf_handle_destroy(handle
);
150 if (rc
!= SCF_SUCCESS
)
151 (void) scf_set_error(error
);
158 * Get config properties from svc:/system/boot-config:default.
159 * It prints errors with uu_warn().
162 scf_get_boot_config(uint8_t *boot_config
)
171 * Property vector for BOOT_CONFIG_PG_PARAMS property group.
173 scf_propvec_t ua_boot_config
[] = {
174 { FASTREBOOT_DEFAULT
, NULL
, SCF_TYPE_BOOLEAN
, NULL
,
175 UA_FASTREBOOT_DEFAULT
},
176 { FASTREBOOT_ONPANIC
, NULL
, SCF_TYPE_BOOLEAN
, NULL
,
177 UA_FASTREBOOT_ONPANIC
},
182 for (prop
= ua_boot_config
; prop
->pv_prop
!= NULL
; prop
++)
185 if (scf_read_propvec(FMRI_BOOT_CONFIG
, BOOT_CONFIG_PG_PARAMS
,
186 B_TRUE
, ua_boot_config
, &prop
) != SCF_FAILED
) {
190 * Unset both flags if the platform has been
193 if (scf_is_fb_blacklisted())
196 *boot_config
= (uint8_t)ret
;
199 #if defined(FASTREBOOT_DEBUG)
201 (void) uu_warn("Service %s property '%s/%s' "
202 "not found.\n", FMRI_BOOT_CONFIG
,
203 BOOT_CONFIG_PG_PARAMS
, prop
->pv_prop
);
205 (void) uu_warn("Unable to read service %s "
206 "property '%s': %s\n", FMRI_BOOT_CONFIG
,
207 BOOT_CONFIG_PG_PARAMS
, scf_strerror(scf_error()));
209 #endif /* FASTREBOOT_DEBUG */
214 * Get or set properties in non-persistent "config_ovr" property group
215 * in svc:/system/boot-config:default.
216 * It prints errors with uu_warn().
220 scf_getset_boot_config_ovr(int set
, uint8_t *boot_config_ovr
)
222 int rc
= SCF_SUCCESS
;
224 assert(boot_config_ovr
);
231 * Property vector for BOOT_CONFIG_PG_OVR property group.
233 scf_propvec_t ua_boot_config_ovr
[] = {
234 { FASTREBOOT_DEFAULT
, NULL
, SCF_TYPE_BOOLEAN
, NULL
,
235 UA_FASTREBOOT_DEFAULT
},
236 { FASTREBOOT_ONPANIC
, NULL
, SCF_TYPE_BOOLEAN
, NULL
,
237 UA_FASTREBOOT_ONPANIC
},
242 rc
= scf_fmri_pg_get_or_add(FMRI_BOOT_CONFIG
,
243 BOOT_CONFIG_PG_OVR
, SCF_GROUP_APPLICATION
,
244 SCF_PG_FLAG_NONPERSISTENT
, set
);
246 if (rc
!= SCF_SUCCESS
) {
247 #if defined(FASTREBOOT_DEBUG)
249 (void) uu_warn("Unable to add service %s "
250 "property group '%s'\n",
251 FMRI_BOOT_CONFIG
, BOOT_CONFIG_PG_OVR
);
252 #endif /* FASTREBOOT_DEBUG */
256 for (prop
= ua_boot_config_ovr
; prop
->pv_prop
!= NULL
; prop
++)
257 prop
->pv_ptr
= boot_config_ovr
;
261 rc
= scf_write_propvec(FMRI_BOOT_CONFIG
,
262 BOOT_CONFIG_PG_OVR
, ua_boot_config_ovr
, &prop
);
264 rc
= scf_read_propvec(FMRI_BOOT_CONFIG
,
265 BOOT_CONFIG_PG_OVR
, B_FALSE
, ua_boot_config_ovr
,
268 #if defined(FASTREBOOT_DEBUG)
269 if (rc
!= SCF_SUCCESS
) {
271 (void) uu_warn("Service %s property '%s/%s' "
272 "not found.\n", FMRI_BOOT_CONFIG
,
273 BOOT_CONFIG_PG_OVR
, prop
->pv_prop
);
275 (void) uu_warn("Unable to %s service %s "
276 "property '%s': %s\n", set
? "set" : "get",
277 FMRI_BOOT_CONFIG
, BOOT_CONFIG_PG_OVR
,
278 scf_strerror(scf_error()));
281 #endif /* FASTREBOOT_DEBUG */
284 (void) smf_refresh_instance(FMRI_BOOT_CONFIG
);
293 * Get values of properties in non-persistent "config_ovr" property group.
296 scf_get_boot_config_ovr(uint8_t *boot_config_ovr
)
298 (void) scf_getset_boot_config_ovr(B_FALSE
, boot_config_ovr
);
302 * Set value of "config_ovr/fastreboot_default".
305 scf_fastreboot_default_set_transient(boolean_t value
)
307 uint8_t boot_config_ovr
= 0;
310 boot_config_ovr
= UA_FASTREBOOT_DEFAULT
| UA_FASTREBOOT_ONPANIC
;
312 return (scf_getset_boot_config_ovr(B_TRUE
, &boot_config_ovr
));
316 * Check whether Fast Reboot is the default operating mode.
318 * 1. the platform is xVM
320 * 2. svc:/system/boot-config:default service doesn't exist,
322 * 3. property "config/fastreboot_default" doesn't exist,
324 * 4. value of property "config/fastreboot_default" is set to "false"
325 * and "config_ovr/fastreboot_default" is not set to "true",
327 * 5. the platform has been blacklisted.
329 * 6. value of property "config_ovr/fastreboot_default" is set to "false".
330 * Return non-zero otherwise.
333 scf_is_fastboot_default(void)
335 uint8_t boot_config
= 0, boot_config_ovr
;
336 char procbuf
[SYS_NMLN
];
339 * If we are on xVM, do not fast reboot by default.
341 if (sysinfo(SI_PLATFORM
, procbuf
, sizeof (procbuf
)) == -1 ||
342 strcmp(procbuf
, "i86xpv") == 0)
346 * Get property values from "config" property group
348 scf_get_boot_config(&boot_config
);
351 * Get property values from non-persistent "config_ovr" property group
353 boot_config_ovr
= boot_config
;
354 scf_get_boot_config_ovr(&boot_config_ovr
);
356 return (boot_config
& boot_config_ovr
& UA_FASTREBOOT_DEFAULT
);
360 * Read the default security-flags from system/process-security and return a
361 * secflagset_t suitable for psecflags(2)
363 * Unfortunately, this symbol must _exist_ in the native build, for the sake
364 * of the mapfile, even though we don't ever use it, and it will never work.
367 secflagdelta_t
*delta
;
372 scf_default_secflags(scf_handle_t
*hndl
, scf_secflags_t
*flags
)
374 #if !defined(NATIVE_BUILD)
375 scf_property_t
*prop
;
377 const char *flagname
;
379 struct group_desc
*g
;
380 struct group_desc groups
[] = {
381 {NULL
, "svc:/system/process-security/"
382 ":properties/default"},
383 {NULL
, "svc:/system/process-security/"
384 ":properties/lower"},
385 {NULL
, "svc:/system/process-security/"
386 ":properties/upper"},
390 bzero(flags
, sizeof (*flags
));
392 groups
[0].delta
= &flags
->ss_default
;
393 groups
[1].delta
= &flags
->ss_lower
;
394 groups
[2].delta
= &flags
->ss_upper
;
396 for (g
= groups
; g
->delta
!= NULL
; g
++) {
397 for (flag
= 0; (flagname
= secflag_to_str(flag
)) != NULL
;
402 if ((val
= scf_value_create(hndl
)) == NULL
)
405 if ((prop
= scf_property_create(hndl
)) == NULL
) {
406 scf_value_destroy(val
);
410 if ((pfmri
= uu_msprintf("%s/%s", g
->fmri
,
412 uu_die("Allocation failure\n");
414 if (scf_handle_decode_fmri(hndl
, pfmri
,
415 NULL
, NULL
, NULL
, NULL
, prop
, NULL
) != 0)
418 if (scf_property_get_value(prop
, val
) != 0)
421 (void) scf_value_get_boolean(val
, &flagval
);
424 secflag_set(&g
->delta
->psd_add
, flag
);
426 secflag_set(&g
->delta
->psd_rem
, flag
);
430 scf_value_destroy(val
);
431 scf_property_destroy(prop
);
439 #endif /* !NATIVE_BUILD */