1*9160SSherry.Moore@Sun.COM /*
2*9160SSherry.Moore@Sun.COM  * CDDL HEADER START
3*9160SSherry.Moore@Sun.COM  *
4*9160SSherry.Moore@Sun.COM  * The contents of this file are subject to the terms of the
5*9160SSherry.Moore@Sun.COM  * Common Development and Distribution License (the "License").
6*9160SSherry.Moore@Sun.COM  * You may not use this file except in compliance with the License.
7*9160SSherry.Moore@Sun.COM  *
8*9160SSherry.Moore@Sun.COM  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9*9160SSherry.Moore@Sun.COM  * or http://www.opensolaris.org/os/licensing.
10*9160SSherry.Moore@Sun.COM  * See the License for the specific language governing permissions
11*9160SSherry.Moore@Sun.COM  * and limitations under the License.
12*9160SSherry.Moore@Sun.COM  *
13*9160SSherry.Moore@Sun.COM  * When distributing Covered Code, include this CDDL HEADER in each
14*9160SSherry.Moore@Sun.COM  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15*9160SSherry.Moore@Sun.COM  * If applicable, add the following below this CDDL HEADER, with the
16*9160SSherry.Moore@Sun.COM  * fields enclosed by brackets "[]" replaced with your own identifying
17*9160SSherry.Moore@Sun.COM  * information: Portions Copyright [yyyy] [name of copyright owner]
18*9160SSherry.Moore@Sun.COM  *
19*9160SSherry.Moore@Sun.COM  * CDDL HEADER END
20*9160SSherry.Moore@Sun.COM  */
21*9160SSherry.Moore@Sun.COM 
22*9160SSherry.Moore@Sun.COM /*
23*9160SSherry.Moore@Sun.COM  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
24*9160SSherry.Moore@Sun.COM  * Use is subject to license terms.
25*9160SSherry.Moore@Sun.COM  */
26*9160SSherry.Moore@Sun.COM 
27*9160SSherry.Moore@Sun.COM /*
28*9160SSherry.Moore@Sun.COM  * This file contains high level functions used by multiple utilities.
29*9160SSherry.Moore@Sun.COM  */
30*9160SSherry.Moore@Sun.COM 
31*9160SSherry.Moore@Sun.COM #include "libscf_impl.h"
32*9160SSherry.Moore@Sun.COM 
33*9160SSherry.Moore@Sun.COM #include <assert.h>
34*9160SSherry.Moore@Sun.COM #include <libuutil.h>
35*9160SSherry.Moore@Sun.COM #include <string.h>
36*9160SSherry.Moore@Sun.COM #include <stdlib.h>
37*9160SSherry.Moore@Sun.COM #include <sys/systeminfo.h>
38*9160SSherry.Moore@Sun.COM #include <sys/uadmin.h>
39*9160SSherry.Moore@Sun.COM #include <sys/utsname.h>
40*9160SSherry.Moore@Sun.COM 
41*9160SSherry.Moore@Sun.COM #ifdef	__x86
42*9160SSherry.Moore@Sun.COM #include <smbios.h>
43*9160SSherry.Moore@Sun.COM 
44*9160SSherry.Moore@Sun.COM /*
45*9160SSherry.Moore@Sun.COM  * Check whether the platform is on the fastreboot_blacklist.
46*9160SSherry.Moore@Sun.COM  * Return 1 if the platform has been blacklisted, 0 otherwise.
47*9160SSherry.Moore@Sun.COM  */
48*9160SSherry.Moore@Sun.COM static int
49*9160SSherry.Moore@Sun.COM scf_is_fb_blacklisted(void)
50*9160SSherry.Moore@Sun.COM {
51*9160SSherry.Moore@Sun.COM 	smbios_hdl_t *shp;
52*9160SSherry.Moore@Sun.COM 	smbios_system_t sys;
53*9160SSherry.Moore@Sun.COM 	smbios_info_t info;
54*9160SSherry.Moore@Sun.COM 
55*9160SSherry.Moore@Sun.COM 	id_t id;
56*9160SSherry.Moore@Sun.COM 	int err;
57*9160SSherry.Moore@Sun.COM 	int i;
58*9160SSherry.Moore@Sun.COM 
59*9160SSherry.Moore@Sun.COM 	scf_simple_prop_t *prop = NULL;
60*9160SSherry.Moore@Sun.COM 	ssize_t numvals;
61*9160SSherry.Moore@Sun.COM 	char *platform_name;
62*9160SSherry.Moore@Sun.COM 
63*9160SSherry.Moore@Sun.COM 	int blacklisted = 0;
64*9160SSherry.Moore@Sun.COM 
65*9160SSherry.Moore@Sun.COM 	/*
66*9160SSherry.Moore@Sun.COM 	 * If there's no SMBIOS, assume it's blacklisted.
67*9160SSherry.Moore@Sun.COM 	 */
68*9160SSherry.Moore@Sun.COM 	if ((shp = smbios_open(NULL, SMB_VERSION, 0, &err)) == NULL)
69*9160SSherry.Moore@Sun.COM 		return (1);
70*9160SSherry.Moore@Sun.COM 
71*9160SSherry.Moore@Sun.COM 	/*
72*9160SSherry.Moore@Sun.COM 	 * If we can't read system info, assume it's blacklisted.
73*9160SSherry.Moore@Sun.COM 	 */
74*9160SSherry.Moore@Sun.COM 	if ((id = smbios_info_system(shp, &sys)) == SMB_ERR ||
75*9160SSherry.Moore@Sun.COM 	    smbios_info_common(shp, id, &info) == SMB_ERR) {
76*9160SSherry.Moore@Sun.COM 		blacklisted = 1;
77*9160SSherry.Moore@Sun.COM 		goto fb_out;
78*9160SSherry.Moore@Sun.COM 	}
79*9160SSherry.Moore@Sun.COM 
80*9160SSherry.Moore@Sun.COM 	/*
81*9160SSherry.Moore@Sun.COM 	 * If we can't read the "platforms" property from property group
82*9160SSherry.Moore@Sun.COM 	 * BOOT_CONFIG_PG_FBBLACKLIST, assume no platforms have
83*9160SSherry.Moore@Sun.COM 	 * been blacklisted.
84*9160SSherry.Moore@Sun.COM 	 */
85*9160SSherry.Moore@Sun.COM 	if ((prop = scf_simple_prop_get(NULL, FMRI_BOOT_CONFIG,
86*9160SSherry.Moore@Sun.COM 	    BOOT_CONFIG_PG_FBBLACKLIST, "platforms")) == NULL)
87*9160SSherry.Moore@Sun.COM 		goto fb_out;
88*9160SSherry.Moore@Sun.COM 
89*9160SSherry.Moore@Sun.COM 	numvals = scf_simple_prop_numvalues(prop);
90*9160SSherry.Moore@Sun.COM 
91*9160SSherry.Moore@Sun.COM 	for (i = 0; i < numvals; i++) {
92*9160SSherry.Moore@Sun.COM 		platform_name = scf_simple_prop_next_astring(prop);
93*9160SSherry.Moore@Sun.COM 		if (platform_name == NULL)
94*9160SSherry.Moore@Sun.COM 			break;
95*9160SSherry.Moore@Sun.COM 		if (strcmp(platform_name, info.smbi_product) == 0) {
96*9160SSherry.Moore@Sun.COM 			blacklisted = 1;
97*9160SSherry.Moore@Sun.COM 			break;
98*9160SSherry.Moore@Sun.COM 		}
99*9160SSherry.Moore@Sun.COM 	}
100*9160SSherry.Moore@Sun.COM 
101*9160SSherry.Moore@Sun.COM fb_out:
102*9160SSherry.Moore@Sun.COM 	smbios_close(shp);
103*9160SSherry.Moore@Sun.COM 	scf_simple_prop_free(prop);
104*9160SSherry.Moore@Sun.COM 
105*9160SSherry.Moore@Sun.COM 	return (blacklisted);
106*9160SSherry.Moore@Sun.COM }
107*9160SSherry.Moore@Sun.COM #endif	/* __x86 */
108*9160SSherry.Moore@Sun.COM 
109*9160SSherry.Moore@Sun.COM /*
110*9160SSherry.Moore@Sun.COM  * Get config properties from svc:/system/boot-config:default.
111*9160SSherry.Moore@Sun.COM  * It prints errors with uu_warn().
112*9160SSherry.Moore@Sun.COM  */
113*9160SSherry.Moore@Sun.COM void
114*9160SSherry.Moore@Sun.COM scf_get_boot_config(uint8_t *boot_config)
115*9160SSherry.Moore@Sun.COM {
116*9160SSherry.Moore@Sun.COM 	assert(boot_config);
117*9160SSherry.Moore@Sun.COM 	*boot_config = 0;
118*9160SSherry.Moore@Sun.COM 
119*9160SSherry.Moore@Sun.COM #ifndef	__x86
120*9160SSherry.Moore@Sun.COM 	return;
121*9160SSherry.Moore@Sun.COM #else
122*9160SSherry.Moore@Sun.COM 	{
123*9160SSherry.Moore@Sun.COM 		/*
124*9160SSherry.Moore@Sun.COM 		 * Property vector for BOOT_CONFIG_PG_PARAMS property group.
125*9160SSherry.Moore@Sun.COM 		 */
126*9160SSherry.Moore@Sun.COM 		scf_propvec_t ua_boot_config[] = {
127*9160SSherry.Moore@Sun.COM 			{ "fastreboot_default", NULL, SCF_TYPE_BOOLEAN, NULL,
128*9160SSherry.Moore@Sun.COM 			    UA_FASTREBOOT_DEFAULT },
129*9160SSherry.Moore@Sun.COM 			{ FASTREBOOT_ONPANIC, NULL, SCF_TYPE_BOOLEAN, NULL,
130*9160SSherry.Moore@Sun.COM 			    UA_FASTREBOOT_ONPANIC },
131*9160SSherry.Moore@Sun.COM 			{ NULL }
132*9160SSherry.Moore@Sun.COM 		};
133*9160SSherry.Moore@Sun.COM 		scf_propvec_t	*prop;
134*9160SSherry.Moore@Sun.COM 
135*9160SSherry.Moore@Sun.COM 		for (prop = ua_boot_config; prop->pv_prop != NULL; prop++)
136*9160SSherry.Moore@Sun.COM 			prop->pv_ptr = boot_config;
137*9160SSherry.Moore@Sun.COM 		prop = NULL;
138*9160SSherry.Moore@Sun.COM 		if (scf_read_propvec(FMRI_BOOT_CONFIG, BOOT_CONFIG_PG_PARAMS,
139*9160SSherry.Moore@Sun.COM 		    B_TRUE, ua_boot_config, &prop) != SCF_FAILED) {
140*9160SSherry.Moore@Sun.COM 			/*
141*9160SSherry.Moore@Sun.COM 			 * Unset both flags if the platform has been
142*9160SSherry.Moore@Sun.COM 			 * blacklisted.
143*9160SSherry.Moore@Sun.COM 			 */
144*9160SSherry.Moore@Sun.COM 			if (scf_is_fb_blacklisted())
145*9160SSherry.Moore@Sun.COM 				*boot_config &= ~(UA_FASTREBOOT_DEFAULT |
146*9160SSherry.Moore@Sun.COM 				    UA_FASTREBOOT_ONPANIC);
147*9160SSherry.Moore@Sun.COM 			return;
148*9160SSherry.Moore@Sun.COM 		}
149*9160SSherry.Moore@Sun.COM #if defined(FASTREBOOT_DEBUG)
150*9160SSherry.Moore@Sun.COM 		if (prop != NULL) {
151*9160SSherry.Moore@Sun.COM 			(void) uu_warn("Service %s property '%s/%s' "
152*9160SSherry.Moore@Sun.COM 			    "not found.\n", FMRI_BOOT_CONFIG,
153*9160SSherry.Moore@Sun.COM 			    BOOT_CONFIG_PG_PARAMS, prop->pv_prop);
154*9160SSherry.Moore@Sun.COM 		} else {
155*9160SSherry.Moore@Sun.COM 			(void) uu_warn("Unable to read service %s "
156*9160SSherry.Moore@Sun.COM 			    "property '%s': %s\n", FMRI_BOOT_CONFIG,
157*9160SSherry.Moore@Sun.COM 			    BOOT_CONFIG_PG_PARAMS, scf_strerror(scf_error()));
158*9160SSherry.Moore@Sun.COM 		}
159*9160SSherry.Moore@Sun.COM #endif	/* FASTREBOOT_DEBUG */
160*9160SSherry.Moore@Sun.COM 	}
161*9160SSherry.Moore@Sun.COM #endif	/* __x86 */
162*9160SSherry.Moore@Sun.COM }
163*9160SSherry.Moore@Sun.COM 
164*9160SSherry.Moore@Sun.COM /*
165*9160SSherry.Moore@Sun.COM  * Check whether Fast Reboot is the default operating mode.
166*9160SSherry.Moore@Sun.COM  * Return 0 if
167*9160SSherry.Moore@Sun.COM  *   1. the platform is xVM
168*9160SSherry.Moore@Sun.COM  * or
169*9160SSherry.Moore@Sun.COM  *   2. svc:/system/boot-config:default service doesn't exist,
170*9160SSherry.Moore@Sun.COM  * or
171*9160SSherry.Moore@Sun.COM  *   3. property "fastreboot_default" doesn't exist,
172*9160SSherry.Moore@Sun.COM  * or
173*9160SSherry.Moore@Sun.COM  *   4. value of property "fastreboot_default" is set to 0.
174*9160SSherry.Moore@Sun.COM  * or
175*9160SSherry.Moore@Sun.COM  *   5. the platform has been blacklisted.
176*9160SSherry.Moore@Sun.COM  * Return non-zero otherwise.
177*9160SSherry.Moore@Sun.COM  */
178*9160SSherry.Moore@Sun.COM int
179*9160SSherry.Moore@Sun.COM scf_is_fastboot_default(void)
180*9160SSherry.Moore@Sun.COM {
181*9160SSherry.Moore@Sun.COM 	uint8_t	boot_config = 0;
182*9160SSherry.Moore@Sun.COM 	char procbuf[SYS_NMLN];
183*9160SSherry.Moore@Sun.COM 
184*9160SSherry.Moore@Sun.COM 	/*
185*9160SSherry.Moore@Sun.COM 	 * If we are on xVM, do not fast reboot by default.
186*9160SSherry.Moore@Sun.COM 	 */
187*9160SSherry.Moore@Sun.COM 	if (sysinfo(SI_PLATFORM, procbuf, sizeof (procbuf)) == -1 ||
188*9160SSherry.Moore@Sun.COM 	    strcmp(procbuf, "i86xpv") == 0)
189*9160SSherry.Moore@Sun.COM 		return (0);
190*9160SSherry.Moore@Sun.COM 
191*9160SSherry.Moore@Sun.COM 	scf_get_boot_config(&boot_config);
192*9160SSherry.Moore@Sun.COM 	return (boot_config & UA_FASTREBOOT_DEFAULT);
193*9160SSherry.Moore@Sun.COM }
194