1753a6d45SSherry Moore /* 2753a6d45SSherry Moore * CDDL HEADER START 3753a6d45SSherry Moore * 4753a6d45SSherry Moore * The contents of this file are subject to the terms of the 5753a6d45SSherry Moore * Common Development and Distribution License (the "License"). 6753a6d45SSherry Moore * You may not use this file except in compliance with the License. 7753a6d45SSherry Moore * 8753a6d45SSherry Moore * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9753a6d45SSherry Moore * or http://www.opensolaris.org/os/licensing. 10753a6d45SSherry Moore * See the License for the specific language governing permissions 11753a6d45SSherry Moore * and limitations under the License. 12753a6d45SSherry Moore * 13753a6d45SSherry Moore * When distributing Covered Code, include this CDDL HEADER in each 14753a6d45SSherry Moore * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15753a6d45SSherry Moore * If applicable, add the following below this CDDL HEADER, with the 16753a6d45SSherry Moore * fields enclosed by brackets "[]" replaced with your own identifying 17753a6d45SSherry Moore * information: Portions Copyright [yyyy] [name of copyright owner] 18753a6d45SSherry Moore * 19753a6d45SSherry Moore * CDDL HEADER END 20753a6d45SSherry Moore */ 21753a6d45SSherry Moore 22753a6d45SSherry Moore /* 23e557d412SChristopher Kiick * Copyright 2010 Sun Microsystems, Inc. All rights reserved. 24753a6d45SSherry Moore * Use is subject to license terms. 25753a6d45SSherry Moore */ 26753a6d45SSherry Moore 27753a6d45SSherry Moore /* 28753a6d45SSherry Moore * This file contains high level functions used by multiple utilities. 29753a6d45SSherry Moore */ 30753a6d45SSherry Moore 31753a6d45SSherry Moore #include "libscf_impl.h" 32753a6d45SSherry Moore 33753a6d45SSherry Moore #include <assert.h> 34753a6d45SSherry Moore #include <libuutil.h> 35753a6d45SSherry Moore #include <string.h> 36753a6d45SSherry Moore #include <stdlib.h> 37753a6d45SSherry Moore #include <sys/systeminfo.h> 38753a6d45SSherry Moore #include <sys/uadmin.h> 39753a6d45SSherry Moore #include <sys/utsname.h> 40753a6d45SSherry Moore 41753a6d45SSherry Moore #ifdef __x86 42753a6d45SSherry Moore #include <smbios.h> 43753a6d45SSherry Moore 44753a6d45SSherry Moore /* 45753a6d45SSherry Moore * Check whether the platform is on the fastreboot_blacklist. 46753a6d45SSherry Moore * Return 1 if the platform has been blacklisted, 0 otherwise. 47753a6d45SSherry Moore */ 48753a6d45SSherry Moore static int 49753a6d45SSherry Moore scf_is_fb_blacklisted(void) 50753a6d45SSherry Moore { 51753a6d45SSherry Moore smbios_hdl_t *shp; 52753a6d45SSherry Moore smbios_system_t sys; 53753a6d45SSherry Moore smbios_info_t info; 54753a6d45SSherry Moore 55753a6d45SSherry Moore id_t id; 56753a6d45SSherry Moore int err; 57753a6d45SSherry Moore int i; 58753a6d45SSherry Moore 59753a6d45SSherry Moore scf_simple_prop_t *prop = NULL; 60753a6d45SSherry Moore ssize_t numvals; 61753a6d45SSherry Moore char *platform_name; 62753a6d45SSherry Moore 63753a6d45SSherry Moore int blacklisted = 0; 64753a6d45SSherry Moore 65753a6d45SSherry Moore /* 66753a6d45SSherry Moore * If there's no SMBIOS, assume it's blacklisted. 67753a6d45SSherry Moore */ 68753a6d45SSherry Moore if ((shp = smbios_open(NULL, SMB_VERSION, 0, &err)) == NULL) 69753a6d45SSherry Moore return (1); 70753a6d45SSherry Moore 71753a6d45SSherry Moore /* 72753a6d45SSherry Moore * If we can't read system info, assume it's blacklisted. 73753a6d45SSherry Moore */ 74753a6d45SSherry Moore if ((id = smbios_info_system(shp, &sys)) == SMB_ERR || 75753a6d45SSherry Moore smbios_info_common(shp, id, &info) == SMB_ERR) { 76753a6d45SSherry Moore blacklisted = 1; 77753a6d45SSherry Moore goto fb_out; 78753a6d45SSherry Moore } 79753a6d45SSherry Moore 80753a6d45SSherry Moore /* 81753a6d45SSherry Moore * If we can't read the "platforms" property from property group 82753a6d45SSherry Moore * BOOT_CONFIG_PG_FBBLACKLIST, assume no platforms have 83753a6d45SSherry Moore * been blacklisted. 84753a6d45SSherry Moore */ 85753a6d45SSherry Moore if ((prop = scf_simple_prop_get(NULL, FMRI_BOOT_CONFIG, 86753a6d45SSherry Moore BOOT_CONFIG_PG_FBBLACKLIST, "platforms")) == NULL) 87753a6d45SSherry Moore goto fb_out; 88753a6d45SSherry Moore 89753a6d45SSherry Moore numvals = scf_simple_prop_numvalues(prop); 90753a6d45SSherry Moore 91753a6d45SSherry Moore for (i = 0; i < numvals; i++) { 92753a6d45SSherry Moore platform_name = scf_simple_prop_next_astring(prop); 93753a6d45SSherry Moore if (platform_name == NULL) 94753a6d45SSherry Moore break; 95753a6d45SSherry Moore if (strcmp(platform_name, info.smbi_product) == 0) { 96753a6d45SSherry Moore blacklisted = 1; 97753a6d45SSherry Moore break; 98753a6d45SSherry Moore } 99753a6d45SSherry Moore } 100753a6d45SSherry Moore 101753a6d45SSherry Moore fb_out: 102753a6d45SSherry Moore smbios_close(shp); 103753a6d45SSherry Moore scf_simple_prop_free(prop); 104753a6d45SSherry Moore 105753a6d45SSherry Moore return (blacklisted); 106753a6d45SSherry Moore } 1074196e263SSherry Moore 1084196e263SSherry Moore /* 1094196e263SSherry Moore * Add or get a property group given an FMRI. 1104196e263SSherry Moore * Return SCF_SUCCESS on success, SCF_FAILED on failure. 1114196e263SSherry Moore */ 1124196e263SSherry Moore static int 1134196e263SSherry Moore scf_fmri_pg_get_or_add(const char *fmri, const char *pgname, 1144196e263SSherry Moore const char *pgtype, uint32_t pgflags, int add) 1154196e263SSherry Moore { 1164196e263SSherry Moore scf_handle_t *handle = NULL; 1174196e263SSherry Moore scf_instance_t *inst = NULL; 1184196e263SSherry Moore int rc = SCF_FAILED; 11957b30532SSherry Moore int error; 1204196e263SSherry Moore 1214196e263SSherry Moore if ((handle = scf_handle_create(SCF_VERSION)) == NULL || 1224196e263SSherry Moore scf_handle_bind(handle) != 0 || 1234196e263SSherry Moore (inst = scf_instance_create(handle)) == NULL || 1244196e263SSherry Moore scf_handle_decode_fmri(handle, fmri, NULL, NULL, 1254196e263SSherry Moore inst, NULL, NULL, SCF_DECODE_FMRI_EXACT) != SCF_SUCCESS) 1264196e263SSherry Moore goto scferror; 1274196e263SSherry Moore 1284196e263SSherry Moore if (add) { 1294196e263SSherry Moore rc = scf_instance_add_pg(inst, pgname, pgtype, pgflags, NULL); 1304196e263SSherry Moore /* 1314196e263SSherry Moore * If the property group already exists, return SCF_SUCCESS. 1324196e263SSherry Moore */ 13357b30532SSherry Moore if (rc != SCF_SUCCESS && scf_error() == SCF_ERROR_EXISTS) 1344196e263SSherry Moore rc = SCF_SUCCESS; 1354196e263SSherry Moore } else { 1364196e263SSherry Moore rc = scf_instance_get_pg(inst, pgname, NULL); 1374196e263SSherry Moore } 1384196e263SSherry Moore 1394196e263SSherry Moore scferror: 14057b30532SSherry Moore if (rc != SCF_SUCCESS) 1414196e263SSherry Moore error = scf_error(); 1424196e263SSherry Moore 1434196e263SSherry Moore scf_instance_destroy(inst); 1444196e263SSherry Moore if (handle) 1454196e263SSherry Moore (void) scf_handle_unbind(handle); 1464196e263SSherry Moore scf_handle_destroy(handle); 1474196e263SSherry Moore 14857b30532SSherry Moore if (rc != SCF_SUCCESS) 1494196e263SSherry Moore (void) scf_set_error(error); 15057b30532SSherry Moore 1514196e263SSherry Moore return (rc); 1524196e263SSherry Moore } 153753a6d45SSherry Moore #endif /* __x86 */ 154753a6d45SSherry Moore 155753a6d45SSherry Moore /* 156753a6d45SSherry Moore * Get config properties from svc:/system/boot-config:default. 157753a6d45SSherry Moore * It prints errors with uu_warn(). 158753a6d45SSherry Moore */ 159753a6d45SSherry Moore void 160753a6d45SSherry Moore scf_get_boot_config(uint8_t *boot_config) 161753a6d45SSherry Moore { 162*d0b2dca5SRichard Lowe uint64_t ret = 0; 163*d0b2dca5SRichard Lowe 164753a6d45SSherry Moore assert(boot_config); 165753a6d45SSherry Moore *boot_config = 0; 166753a6d45SSherry Moore 167753a6d45SSherry Moore { 168753a6d45SSherry Moore /* 169753a6d45SSherry Moore * Property vector for BOOT_CONFIG_PG_PARAMS property group. 170753a6d45SSherry Moore */ 171753a6d45SSherry Moore scf_propvec_t ua_boot_config[] = { 1724196e263SSherry Moore { FASTREBOOT_DEFAULT, NULL, SCF_TYPE_BOOLEAN, NULL, 173753a6d45SSherry Moore UA_FASTREBOOT_DEFAULT }, 174753a6d45SSherry Moore { FASTREBOOT_ONPANIC, NULL, SCF_TYPE_BOOLEAN, NULL, 175753a6d45SSherry Moore UA_FASTREBOOT_ONPANIC }, 176753a6d45SSherry Moore { NULL } 177753a6d45SSherry Moore }; 178753a6d45SSherry Moore scf_propvec_t *prop; 179753a6d45SSherry Moore 180753a6d45SSherry Moore for (prop = ua_boot_config; prop->pv_prop != NULL; prop++) 181*d0b2dca5SRichard Lowe prop->pv_ptr = &ret; 182753a6d45SSherry Moore prop = NULL; 183753a6d45SSherry Moore if (scf_read_propvec(FMRI_BOOT_CONFIG, BOOT_CONFIG_PG_PARAMS, 184753a6d45SSherry Moore B_TRUE, ua_boot_config, &prop) != SCF_FAILED) { 185e557d412SChristopher Kiick 186e557d412SChristopher Kiick #ifdef __x86 187753a6d45SSherry Moore /* 188753a6d45SSherry Moore * Unset both flags if the platform has been 189753a6d45SSherry Moore * blacklisted. 190753a6d45SSherry Moore */ 191753a6d45SSherry Moore if (scf_is_fb_blacklisted()) 192*d0b2dca5SRichard Lowe return; 193e557d412SChristopher Kiick #endif /* __x86 */ 194*d0b2dca5SRichard Lowe *boot_config = (uint8_t)ret; 195753a6d45SSherry Moore return; 196753a6d45SSherry Moore } 197753a6d45SSherry Moore #if defined(FASTREBOOT_DEBUG) 198753a6d45SSherry Moore if (prop != NULL) { 199753a6d45SSherry Moore (void) uu_warn("Service %s property '%s/%s' " 200753a6d45SSherry Moore "not found.\n", FMRI_BOOT_CONFIG, 201753a6d45SSherry Moore BOOT_CONFIG_PG_PARAMS, prop->pv_prop); 202753a6d45SSherry Moore } else { 203753a6d45SSherry Moore (void) uu_warn("Unable to read service %s " 204753a6d45SSherry Moore "property '%s': %s\n", FMRI_BOOT_CONFIG, 205753a6d45SSherry Moore BOOT_CONFIG_PG_PARAMS, scf_strerror(scf_error())); 206753a6d45SSherry Moore } 207753a6d45SSherry Moore #endif /* FASTREBOOT_DEBUG */ 208753a6d45SSherry Moore } 209753a6d45SSherry Moore } 210753a6d45SSherry Moore 211753a6d45SSherry Moore /* 2124196e263SSherry Moore * Get or set properties in non-persistent "config_ovr" property group 2134196e263SSherry Moore * in svc:/system/boot-config:default. 2144196e263SSherry Moore * It prints errors with uu_warn(). 2154196e263SSherry Moore */ 2164196e263SSherry Moore /*ARGSUSED*/ 2174196e263SSherry Moore static int 2184196e263SSherry Moore scf_getset_boot_config_ovr(int set, uint8_t *boot_config_ovr) 2194196e263SSherry Moore { 2204196e263SSherry Moore int rc = SCF_SUCCESS; 2214196e263SSherry Moore 2224196e263SSherry Moore assert(boot_config_ovr); 2234196e263SSherry Moore 2244196e263SSherry Moore #ifndef __x86 2254196e263SSherry Moore return (rc); 2264196e263SSherry Moore #else 2274196e263SSherry Moore { 2284196e263SSherry Moore /* 2294196e263SSherry Moore * Property vector for BOOT_CONFIG_PG_OVR property group. 2304196e263SSherry Moore */ 2314196e263SSherry Moore scf_propvec_t ua_boot_config_ovr[] = { 2324196e263SSherry Moore { FASTREBOOT_DEFAULT, NULL, SCF_TYPE_BOOLEAN, NULL, 2334196e263SSherry Moore UA_FASTREBOOT_DEFAULT }, 234c90a5fbeSSherry Moore { FASTREBOOT_ONPANIC, NULL, SCF_TYPE_BOOLEAN, NULL, 235c90a5fbeSSherry Moore UA_FASTREBOOT_ONPANIC }, 2364196e263SSherry Moore { NULL } 2374196e263SSherry Moore }; 2384196e263SSherry Moore scf_propvec_t *prop; 2394196e263SSherry Moore 2404196e263SSherry Moore rc = scf_fmri_pg_get_or_add(FMRI_BOOT_CONFIG, 2414196e263SSherry Moore BOOT_CONFIG_PG_OVR, SCF_GROUP_APPLICATION, 2424196e263SSherry Moore SCF_PG_FLAG_NONPERSISTENT, set); 2434196e263SSherry Moore 2444196e263SSherry Moore if (rc != SCF_SUCCESS) { 2454196e263SSherry Moore #if defined(FASTREBOOT_DEBUG) 2464196e263SSherry Moore if (set) 2474196e263SSherry Moore (void) uu_warn("Unable to add service %s " 2484196e263SSherry Moore "property group '%s'\n", 2494196e263SSherry Moore FMRI_BOOT_CONFIG, BOOT_CONFIG_PG_OVR); 2504196e263SSherry Moore #endif /* FASTREBOOT_DEBUG */ 2514196e263SSherry Moore return (rc); 2524196e263SSherry Moore } 2534196e263SSherry Moore 2544196e263SSherry Moore for (prop = ua_boot_config_ovr; prop->pv_prop != NULL; prop++) 2554196e263SSherry Moore prop->pv_ptr = boot_config_ovr; 2564196e263SSherry Moore prop = NULL; 2574196e263SSherry Moore 2584196e263SSherry Moore if (set) 2594196e263SSherry Moore rc = scf_write_propvec(FMRI_BOOT_CONFIG, 2604196e263SSherry Moore BOOT_CONFIG_PG_OVR, ua_boot_config_ovr, &prop); 2614196e263SSherry Moore else 2624196e263SSherry Moore rc = scf_read_propvec(FMRI_BOOT_CONFIG, 2634196e263SSherry Moore BOOT_CONFIG_PG_OVR, B_FALSE, ua_boot_config_ovr, 2644196e263SSherry Moore &prop); 2654196e263SSherry Moore 2664196e263SSherry Moore #if defined(FASTREBOOT_DEBUG) 2674196e263SSherry Moore if (rc != SCF_SUCCESS) { 2684196e263SSherry Moore if (prop != NULL) { 2694196e263SSherry Moore (void) uu_warn("Service %s property '%s/%s' " 2704196e263SSherry Moore "not found.\n", FMRI_BOOT_CONFIG, 2714196e263SSherry Moore BOOT_CONFIG_PG_OVR, prop->pv_prop); 2724196e263SSherry Moore } else { 2734196e263SSherry Moore (void) uu_warn("Unable to %s service %s " 2744196e263SSherry Moore "property '%s': %s\n", set ? "set" : "get", 2754196e263SSherry Moore FMRI_BOOT_CONFIG, BOOT_CONFIG_PG_OVR, 2764196e263SSherry Moore scf_strerror(scf_error())); 2774196e263SSherry Moore } 2784196e263SSherry Moore } 2794196e263SSherry Moore #endif /* FASTREBOOT_DEBUG */ 280c90a5fbeSSherry Moore 281c90a5fbeSSherry Moore if (set) 282c90a5fbeSSherry Moore (void) smf_refresh_instance(FMRI_BOOT_CONFIG); 283c90a5fbeSSherry Moore 2844196e263SSherry Moore return (rc); 2854196e263SSherry Moore 2864196e263SSherry Moore } 2874196e263SSherry Moore #endif /* __x86 */ 2884196e263SSherry Moore } 2894196e263SSherry Moore 2904196e263SSherry Moore /* 2914196e263SSherry Moore * Get values of properties in non-persistent "config_ovr" property group. 2924196e263SSherry Moore */ 293c90a5fbeSSherry Moore void 2944196e263SSherry Moore scf_get_boot_config_ovr(uint8_t *boot_config_ovr) 2954196e263SSherry Moore { 2964196e263SSherry Moore (void) scf_getset_boot_config_ovr(B_FALSE, boot_config_ovr); 2974196e263SSherry Moore } 2984196e263SSherry Moore 2994196e263SSherry Moore /* 3004196e263SSherry Moore * Set value of "config_ovr/fastreboot_default". 3014196e263SSherry Moore */ 3024196e263SSherry Moore int 3034196e263SSherry Moore scf_fastreboot_default_set_transient(boolean_t value) 3044196e263SSherry Moore { 305c90a5fbeSSherry Moore uint8_t boot_config_ovr = 0; 306c90a5fbeSSherry Moore 307c90a5fbeSSherry Moore if (value == B_TRUE) 308c90a5fbeSSherry Moore boot_config_ovr = UA_FASTREBOOT_DEFAULT | UA_FASTREBOOT_ONPANIC; 3094196e263SSherry Moore 3104196e263SSherry Moore return (scf_getset_boot_config_ovr(B_TRUE, &boot_config_ovr)); 3114196e263SSherry Moore } 3124196e263SSherry Moore 3134196e263SSherry Moore /* 314753a6d45SSherry Moore * Check whether Fast Reboot is the default operating mode. 315753a6d45SSherry Moore * Return 0 if 316753a6d45SSherry Moore * 1. the platform is xVM 317753a6d45SSherry Moore * or 318753a6d45SSherry Moore * 2. svc:/system/boot-config:default service doesn't exist, 319753a6d45SSherry Moore * or 3204196e263SSherry Moore * 3. property "config/fastreboot_default" doesn't exist, 321753a6d45SSherry Moore * or 3224196e263SSherry Moore * 4. value of property "config/fastreboot_default" is set to "false" 3234196e263SSherry Moore * and "config_ovr/fastreboot_default" is not set to "true", 324753a6d45SSherry Moore * or 325753a6d45SSherry Moore * 5. the platform has been blacklisted. 3264196e263SSherry Moore * or 3274196e263SSherry Moore * 6. value of property "config_ovr/fastreboot_default" is set to "false". 328753a6d45SSherry Moore * Return non-zero otherwise. 329753a6d45SSherry Moore */ 330753a6d45SSherry Moore int 331753a6d45SSherry Moore scf_is_fastboot_default(void) 332753a6d45SSherry Moore { 3334196e263SSherry Moore uint8_t boot_config = 0, boot_config_ovr; 334753a6d45SSherry Moore char procbuf[SYS_NMLN]; 335753a6d45SSherry Moore 336753a6d45SSherry Moore /* 337753a6d45SSherry Moore * If we are on xVM, do not fast reboot by default. 338753a6d45SSherry Moore */ 339753a6d45SSherry Moore if (sysinfo(SI_PLATFORM, procbuf, sizeof (procbuf)) == -1 || 340753a6d45SSherry Moore strcmp(procbuf, "i86xpv") == 0) 341753a6d45SSherry Moore return (0); 342753a6d45SSherry Moore 3434196e263SSherry Moore /* 3444196e263SSherry Moore * Get property values from "config" property group 3454196e263SSherry Moore */ 346753a6d45SSherry Moore scf_get_boot_config(&boot_config); 3474196e263SSherry Moore 3484196e263SSherry Moore /* 3494196e263SSherry Moore * Get property values from non-persistent "config_ovr" property group 3504196e263SSherry Moore */ 3514196e263SSherry Moore boot_config_ovr = boot_config; 3524196e263SSherry Moore scf_get_boot_config_ovr(&boot_config_ovr); 3534196e263SSherry Moore 3544196e263SSherry Moore return (boot_config & boot_config_ovr & UA_FASTREBOOT_DEFAULT); 355753a6d45SSherry Moore } 356