Print this page
Code review comments from jeffpc
Split |
Close |
Expand all |
Collapse all |
--- old/usr/src/lib/libscf/common/highlevel.c
+++ new/usr/src/lib/libscf/common/highlevel.c
1 1 /*
2 2 * CDDL HEADER START
3 3 *
4 4 * The contents of this file are subject to the terms of the
5 5 * Common Development and Distribution License (the "License").
6 6 * You may not use this file except in compliance with the License.
7 7 *
8 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 9 * or http://www.opensolaris.org/os/licensing.
10 10 * See the License for the specific language governing permissions
11 11 * and limitations under the License.
12 12 *
13 13 * When distributing Covered Code, include this CDDL HEADER in each
14 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 15 * If applicable, add the following below this CDDL HEADER, with the
16 16 * fields enclosed by brackets "[]" replaced with your own identifying
17 17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 18 *
19 19 * CDDL HEADER END
20 20 */
21 21
22 22 /*
23 23 * Copyright 2010 Sun Microsystems, Inc. All rights reserved.
24 24 * Use is subject to license terms.
25 25 */
26 26
27 27 /*
28 28 * This file contains high level functions used by multiple utilities.
29 29 */
30 30
31 31 #include "libscf_impl.h"
32 32
33 33 #include <assert.h>
34 34 #include <libuutil.h>
35 35 #include <string.h>
36 36 #include <stdlib.h>
37 37 #include <sys/systeminfo.h>
38 38 #include <sys/uadmin.h>
39 39 #include <sys/utsname.h>
40 40 #include <sys/secflags.h>
41 41
42 42 #ifdef __x86
43 43 #include <smbios.h>
44 44
45 45 /*
46 46 * Check whether the platform is on the fastreboot_blacklist.
47 47 * Return 1 if the platform has been blacklisted, 0 otherwise.
48 48 */
49 49 static int
50 50 scf_is_fb_blacklisted(void)
51 51 {
52 52 smbios_hdl_t *shp;
53 53 smbios_system_t sys;
54 54 smbios_info_t info;
55 55
56 56 id_t id;
57 57 int err;
58 58 int i;
59 59
60 60 scf_simple_prop_t *prop = NULL;
61 61 ssize_t numvals;
62 62 char *platform_name;
63 63
64 64 int blacklisted = 0;
65 65
66 66 /*
67 67 * If there's no SMBIOS, assume it's blacklisted.
68 68 */
69 69 if ((shp = smbios_open(NULL, SMB_VERSION, 0, &err)) == NULL)
70 70 return (1);
71 71
72 72 /*
73 73 * If we can't read system info, assume it's blacklisted.
74 74 */
75 75 if ((id = smbios_info_system(shp, &sys)) == SMB_ERR ||
76 76 smbios_info_common(shp, id, &info) == SMB_ERR) {
77 77 blacklisted = 1;
78 78 goto fb_out;
79 79 }
80 80
81 81 /*
82 82 * If we can't read the "platforms" property from property group
83 83 * BOOT_CONFIG_PG_FBBLACKLIST, assume no platforms have
84 84 * been blacklisted.
85 85 */
86 86 if ((prop = scf_simple_prop_get(NULL, FMRI_BOOT_CONFIG,
87 87 BOOT_CONFIG_PG_FBBLACKLIST, "platforms")) == NULL)
88 88 goto fb_out;
89 89
90 90 numvals = scf_simple_prop_numvalues(prop);
91 91
92 92 for (i = 0; i < numvals; i++) {
93 93 platform_name = scf_simple_prop_next_astring(prop);
94 94 if (platform_name == NULL)
95 95 break;
96 96 if (strcmp(platform_name, info.smbi_product) == 0) {
97 97 blacklisted = 1;
98 98 break;
99 99 }
100 100 }
101 101
102 102 fb_out:
103 103 smbios_close(shp);
104 104 scf_simple_prop_free(prop);
105 105
106 106 return (blacklisted);
107 107 }
108 108
109 109 /*
110 110 * Add or get a property group given an FMRI.
111 111 * Return SCF_SUCCESS on success, SCF_FAILED on failure.
112 112 */
113 113 static int
114 114 scf_fmri_pg_get_or_add(const char *fmri, const char *pgname,
115 115 const char *pgtype, uint32_t pgflags, int add)
116 116 {
117 117 scf_handle_t *handle = NULL;
118 118 scf_instance_t *inst = NULL;
119 119 int rc = SCF_FAILED;
120 120 int error;
121 121
122 122 if ((handle = scf_handle_create(SCF_VERSION)) == NULL ||
123 123 scf_handle_bind(handle) != 0 ||
124 124 (inst = scf_instance_create(handle)) == NULL ||
125 125 scf_handle_decode_fmri(handle, fmri, NULL, NULL,
126 126 inst, NULL, NULL, SCF_DECODE_FMRI_EXACT) != SCF_SUCCESS)
127 127 goto scferror;
128 128
129 129 if (add) {
130 130 rc = scf_instance_add_pg(inst, pgname, pgtype, pgflags, NULL);
131 131 /*
132 132 * If the property group already exists, return SCF_SUCCESS.
133 133 */
134 134 if (rc != SCF_SUCCESS && scf_error() == SCF_ERROR_EXISTS)
135 135 rc = SCF_SUCCESS;
136 136 } else {
137 137 rc = scf_instance_get_pg(inst, pgname, NULL);
138 138 }
139 139
140 140 scferror:
141 141 if (rc != SCF_SUCCESS)
142 142 error = scf_error();
143 143
144 144 scf_instance_destroy(inst);
145 145 if (handle)
146 146 (void) scf_handle_unbind(handle);
147 147 scf_handle_destroy(handle);
148 148
149 149 if (rc != SCF_SUCCESS)
150 150 (void) scf_set_error(error);
151 151
152 152 return (rc);
153 153 }
154 154 #endif /* __x86 */
155 155
156 156 /*
157 157 * Get config properties from svc:/system/boot-config:default.
158 158 * It prints errors with uu_warn().
159 159 */
160 160 void
161 161 scf_get_boot_config(uint8_t *boot_config)
162 162 {
163 163 uint64_t ret = 0;
164 164
165 165 assert(boot_config);
166 166 *boot_config = 0;
167 167
168 168 {
169 169 /*
170 170 * Property vector for BOOT_CONFIG_PG_PARAMS property group.
171 171 */
172 172 scf_propvec_t ua_boot_config[] = {
173 173 { FASTREBOOT_DEFAULT, NULL, SCF_TYPE_BOOLEAN, NULL,
174 174 UA_FASTREBOOT_DEFAULT },
175 175 { FASTREBOOT_ONPANIC, NULL, SCF_TYPE_BOOLEAN, NULL,
176 176 UA_FASTREBOOT_ONPANIC },
177 177 { NULL }
178 178 };
179 179 scf_propvec_t *prop;
180 180
181 181 for (prop = ua_boot_config; prop->pv_prop != NULL; prop++)
182 182 prop->pv_ptr = &ret;
183 183 prop = NULL;
184 184 if (scf_read_propvec(FMRI_BOOT_CONFIG, BOOT_CONFIG_PG_PARAMS,
185 185 B_TRUE, ua_boot_config, &prop) != SCF_FAILED) {
186 186
187 187 #ifdef __x86
188 188 /*
189 189 * Unset both flags if the platform has been
190 190 * blacklisted.
191 191 */
192 192 if (scf_is_fb_blacklisted())
193 193 return;
194 194 #endif /* __x86 */
195 195 *boot_config = (uint8_t)ret;
196 196 return;
197 197 }
198 198 #if defined(FASTREBOOT_DEBUG)
199 199 if (prop != NULL) {
200 200 (void) uu_warn("Service %s property '%s/%s' "
201 201 "not found.\n", FMRI_BOOT_CONFIG,
202 202 BOOT_CONFIG_PG_PARAMS, prop->pv_prop);
203 203 } else {
204 204 (void) uu_warn("Unable to read service %s "
205 205 "property '%s': %s\n", FMRI_BOOT_CONFIG,
206 206 BOOT_CONFIG_PG_PARAMS, scf_strerror(scf_error()));
207 207 }
208 208 #endif /* FASTREBOOT_DEBUG */
209 209 }
210 210 }
211 211
212 212 /*
213 213 * Get or set properties in non-persistent "config_ovr" property group
214 214 * in svc:/system/boot-config:default.
215 215 * It prints errors with uu_warn().
216 216 */
217 217 /*ARGSUSED*/
218 218 static int
219 219 scf_getset_boot_config_ovr(int set, uint8_t *boot_config_ovr)
220 220 {
221 221 int rc = SCF_SUCCESS;
222 222
223 223 assert(boot_config_ovr);
224 224
225 225 #ifndef __x86
226 226 return (rc);
227 227 #else
228 228 {
229 229 /*
230 230 * Property vector for BOOT_CONFIG_PG_OVR property group.
231 231 */
232 232 scf_propvec_t ua_boot_config_ovr[] = {
233 233 { FASTREBOOT_DEFAULT, NULL, SCF_TYPE_BOOLEAN, NULL,
234 234 UA_FASTREBOOT_DEFAULT },
235 235 { FASTREBOOT_ONPANIC, NULL, SCF_TYPE_BOOLEAN, NULL,
236 236 UA_FASTREBOOT_ONPANIC },
237 237 { NULL }
238 238 };
239 239 scf_propvec_t *prop;
240 240
241 241 rc = scf_fmri_pg_get_or_add(FMRI_BOOT_CONFIG,
242 242 BOOT_CONFIG_PG_OVR, SCF_GROUP_APPLICATION,
243 243 SCF_PG_FLAG_NONPERSISTENT, set);
244 244
245 245 if (rc != SCF_SUCCESS) {
246 246 #if defined(FASTREBOOT_DEBUG)
247 247 if (set)
248 248 (void) uu_warn("Unable to add service %s "
249 249 "property group '%s'\n",
250 250 FMRI_BOOT_CONFIG, BOOT_CONFIG_PG_OVR);
251 251 #endif /* FASTREBOOT_DEBUG */
252 252 return (rc);
253 253 }
254 254
255 255 for (prop = ua_boot_config_ovr; prop->pv_prop != NULL; prop++)
256 256 prop->pv_ptr = boot_config_ovr;
257 257 prop = NULL;
258 258
259 259 if (set)
260 260 rc = scf_write_propvec(FMRI_BOOT_CONFIG,
261 261 BOOT_CONFIG_PG_OVR, ua_boot_config_ovr, &prop);
262 262 else
263 263 rc = scf_read_propvec(FMRI_BOOT_CONFIG,
264 264 BOOT_CONFIG_PG_OVR, B_FALSE, ua_boot_config_ovr,
265 265 &prop);
266 266
267 267 #if defined(FASTREBOOT_DEBUG)
268 268 if (rc != SCF_SUCCESS) {
269 269 if (prop != NULL) {
270 270 (void) uu_warn("Service %s property '%s/%s' "
271 271 "not found.\n", FMRI_BOOT_CONFIG,
272 272 BOOT_CONFIG_PG_OVR, prop->pv_prop);
273 273 } else {
274 274 (void) uu_warn("Unable to %s service %s "
275 275 "property '%s': %s\n", set ? "set" : "get",
276 276 FMRI_BOOT_CONFIG, BOOT_CONFIG_PG_OVR,
277 277 scf_strerror(scf_error()));
278 278 }
279 279 }
280 280 #endif /* FASTREBOOT_DEBUG */
281 281
282 282 if (set)
283 283 (void) smf_refresh_instance(FMRI_BOOT_CONFIG);
284 284
285 285 return (rc);
286 286
287 287 }
288 288 #endif /* __x86 */
289 289 }
290 290
291 291 /*
292 292 * Get values of properties in non-persistent "config_ovr" property group.
293 293 */
294 294 void
295 295 scf_get_boot_config_ovr(uint8_t *boot_config_ovr)
296 296 {
297 297 (void) scf_getset_boot_config_ovr(B_FALSE, boot_config_ovr);
298 298 }
299 299
300 300 /*
301 301 * Set value of "config_ovr/fastreboot_default".
302 302 */
303 303 int
304 304 scf_fastreboot_default_set_transient(boolean_t value)
305 305 {
306 306 uint8_t boot_config_ovr = 0;
307 307
308 308 if (value == B_TRUE)
309 309 boot_config_ovr = UA_FASTREBOOT_DEFAULT | UA_FASTREBOOT_ONPANIC;
310 310
311 311 return (scf_getset_boot_config_ovr(B_TRUE, &boot_config_ovr));
312 312 }
313 313
314 314 /*
315 315 * Check whether Fast Reboot is the default operating mode.
316 316 * Return 0 if
317 317 * 1. the platform is xVM
318 318 * or
319 319 * 2. svc:/system/boot-config:default service doesn't exist,
320 320 * or
321 321 * 3. property "config/fastreboot_default" doesn't exist,
322 322 * or
323 323 * 4. value of property "config/fastreboot_default" is set to "false"
324 324 * and "config_ovr/fastreboot_default" is not set to "true",
325 325 * or
326 326 * 5. the platform has been blacklisted.
327 327 * or
328 328 * 6. value of property "config_ovr/fastreboot_default" is set to "false".
329 329 * Return non-zero otherwise.
330 330 */
331 331 int
332 332 scf_is_fastboot_default(void)
333 333 {
334 334 uint8_t boot_config = 0, boot_config_ovr;
335 335 char procbuf[SYS_NMLN];
336 336
337 337 /*
338 338 * If we are on xVM, do not fast reboot by default.
339 339 */
340 340 if (sysinfo(SI_PLATFORM, procbuf, sizeof (procbuf)) == -1 ||
341 341 strcmp(procbuf, "i86xpv") == 0)
342 342 return (0);
343 343
344 344 /*
345 345 * Get property values from "config" property group
346 346 */
347 347 scf_get_boot_config(&boot_config);
348 348
349 349 /*
350 350 * Get property values from non-persistent "config_ovr" property group
351 351 */
352 352 boot_config_ovr = boot_config;
353 353 scf_get_boot_config_ovr(&boot_config_ovr);
354 354
355 355 return (boot_config & boot_config_ovr & UA_FASTREBOOT_DEFAULT);
356 356 }
357 357
358 358 /*
359 359 * Read the default security-flags from system/process-security and return a
360 360 * secflagset_t suitable for psecflags(2)
361 361 *
362 362 * Unfortunately, this symbol must _exist_ in the native build, for the sake
363 363 * of the mapfile, even though we don't ever use it, and it will never work.
364 364 */
365 365 struct group_desc {
366 366 secflagset_t *set;
367 367 char *fmri;
368 368 };
369 369
370 370 int
371 371 scf_default_secflags(scf_handle_t *hndl, psecflags_t *flags)
372 372 {
373 373 #if !defined(NATIVE_BUILD)
374 374 scf_property_t *prop;
375 375 scf_value_t *val;
376 376 const char *flagname;
377 377 int flag;
378 378 struct group_desc *g;
379 379 struct group_desc groups[] = {
380 380 {NULL, "svc:/system/process-security/"
381 381 ":properties/default"},
382 382 {NULL, "svc:/system/process-security/"
383 383 ":properties/lower"},
384 384 {NULL, "svc:/system/process-security/"
385 385 ":properties/upper"},
386 386 {NULL, NULL}
387 387 };
388 388
389 389 groups[0].set = &flags->psf_inherit;
390 390 groups[1].set = &flags->psf_lower;
391 391 groups[2].set = &flags->psf_upper;
392 392
393 393 /* Ensure sane defaults */
394 394 psecflags_default(flags);
395 395
396 396 for (g = groups; g->set != NULL; g++) {
397 397 for (flag = 0; (flagname = secflag_to_str(flag)) != NULL;
398 398 flag++) {
399 399 char *pfmri;
400 400 uint8_t flagval = 0;
401 401
402 402 if ((val = scf_value_create(hndl)) == NULL)
403 403 return (-1);
404 404
405 405 if ((prop = scf_property_create(hndl)) == NULL) {
406 406 scf_value_destroy(val);
407 407 return (-1);
408 408 }
409 409
410 410 if ((pfmri = uu_msprintf("%s/%s", g->fmri,
411 411 flagname)) == NULL)
412 412 uu_die("Allocation failure\n");
413 413
414 414 if (scf_handle_decode_fmri(hndl, pfmri,
415 415 NULL, NULL, NULL, NULL, prop, NULL) != 0)
416 416 goto next;
417 417
418 418 if (scf_property_get_value(prop, val) != 0)
419 419 goto next;
420 420
421 421 (void) scf_value_get_boolean(val, &flagval);
422 422
423 423 if (flagval != 0)
424 424 secflag_set(g->set, flag);
425 425 else
426 426 secflag_clear(g->set, flag);
427 427
↓ open down ↓ |
427 lines elided |
↑ open up ↑ |
428 428 next:
429 429 uu_free(pfmri);
430 430 scf_value_destroy(val);
431 431 scf_property_destroy(prop);
432 432 }
433 433 }
434 434
435 435 if (!psecflags_validate(flags))
436 436 return (-1);
437 437
438 -#endif /* !NATIVE_BUILD */
439 438 return (0);
439 +#else
440 + assert(0);
441 + abort();
442 +#endif /* !NATIVE_BUILD */
440 443 }
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX