110052SGangadhar.M@Sun.COM /* 210052SGangadhar.M@Sun.COM * CDDL HEADER START 310052SGangadhar.M@Sun.COM * 410052SGangadhar.M@Sun.COM * The contents of this file are subject to the terms of the 510052SGangadhar.M@Sun.COM * Common Development and Distribution License (the "License"). 610052SGangadhar.M@Sun.COM * You may not use this file except in compliance with the License. 710052SGangadhar.M@Sun.COM * 810052SGangadhar.M@Sun.COM * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 910052SGangadhar.M@Sun.COM * or http://www.opensolaris.org/os/licensing. 1010052SGangadhar.M@Sun.COM * See the License for the specific language governing permissions 1110052SGangadhar.M@Sun.COM * and limitations under the License. 1210052SGangadhar.M@Sun.COM * 1310052SGangadhar.M@Sun.COM * When distributing Covered Code, include this CDDL HEADER in each 1410052SGangadhar.M@Sun.COM * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 1510052SGangadhar.M@Sun.COM * If applicable, add the following below this CDDL HEADER, with the 1610052SGangadhar.M@Sun.COM * fields enclosed by brackets "[]" replaced with your own identifying 1710052SGangadhar.M@Sun.COM * information: Portions Copyright [yyyy] [name of copyright owner] 1810052SGangadhar.M@Sun.COM * 1910052SGangadhar.M@Sun.COM * CDDL HEADER END 2010052SGangadhar.M@Sun.COM */ 2110052SGangadhar.M@Sun.COM /* 2210052SGangadhar.M@Sun.COM * Copyright 2009 Sun Microsystems, Inc. All rights reserved. 2310052SGangadhar.M@Sun.COM * Use is subject to license terms. 2410052SGangadhar.M@Sun.COM */ 2510052SGangadhar.M@Sun.COM 26*10054SJan.Setje-Eilers@Sun.COM #include "mtlib.h" 2710052SGangadhar.M@Sun.COM #include <sys/types.h> 2810052SGangadhar.M@Sun.COM #include <libscf.h> 2910052SGangadhar.M@Sun.COM #include <sys/uadmin.h> 3010052SGangadhar.M@Sun.COM #include <unistd.h> 3110052SGangadhar.M@Sun.COM #include <stdlib.h> 3210052SGangadhar.M@Sun.COM #include <zone.h> 33*10054SJan.Setje-Eilers@Sun.COM #include <thread.h> 34*10054SJan.Setje-Eilers@Sun.COM #include <dlfcn.h> 35*10054SJan.Setje-Eilers@Sun.COM #include <atomic.h> 36*10054SJan.Setje-Eilers@Sun.COM 37*10054SJan.Setje-Eilers@Sun.COM /* 38*10054SJan.Setje-Eilers@Sun.COM * Pull in the following three interfaces from libscf without introducing 39*10054SJan.Setje-Eilers@Sun.COM * a dependency on it, which since libscf depends on libc would be circular: 40*10054SJan.Setje-Eilers@Sun.COM * 41*10054SJan.Setje-Eilers@Sun.COM * scf_simple_prop_get 42*10054SJan.Setje-Eilers@Sun.COM * scf_simple_prop_next_boolean 43*10054SJan.Setje-Eilers@Sun.COM * scf_simple_prop_free 44*10054SJan.Setje-Eilers@Sun.COM */ 45*10054SJan.Setje-Eilers@Sun.COM typedef scf_simple_prop_t *(*scf_simple_prop_get_t)(scf_handle_t *, 46*10054SJan.Setje-Eilers@Sun.COM const char *, const char *, const char *); 47*10054SJan.Setje-Eilers@Sun.COM static scf_simple_prop_get_t real_scf_simple_prop_get = NULL; 48*10054SJan.Setje-Eilers@Sun.COM typedef uint8_t *(*scf_simple_prop_next_boolean_t)(scf_simple_prop_t *); 49*10054SJan.Setje-Eilers@Sun.COM static scf_simple_prop_next_boolean_t real_scf_simple_prop_next_boolean = NULL; 50*10054SJan.Setje-Eilers@Sun.COM typedef void (*scf_simple_prop_free_t)(scf_simple_prop_t *); 51*10054SJan.Setje-Eilers@Sun.COM static scf_simple_prop_free_t real_scf_simple_prop_free = NULL; 52*10054SJan.Setje-Eilers@Sun.COM static mutex_t scf_lock = DEFAULTMUTEX; 53*10054SJan.Setje-Eilers@Sun.COM 54*10054SJan.Setje-Eilers@Sun.COM static void 55*10054SJan.Setje-Eilers@Sun.COM load_scf(void) 56*10054SJan.Setje-Eilers@Sun.COM { 57*10054SJan.Setje-Eilers@Sun.COM void *scf_handle = dlopen("libscf.so.1", RTLD_LAZY); 58*10054SJan.Setje-Eilers@Sun.COM scf_simple_prop_get_t scf_simple_prop_get = (scf_handle == NULL)? NULL : 59*10054SJan.Setje-Eilers@Sun.COM (scf_simple_prop_get_t)dlsym(scf_handle, "scf_simple_prop_get"); 60*10054SJan.Setje-Eilers@Sun.COM scf_simple_prop_next_boolean_t scf_simple_prop_next_boolean = 61*10054SJan.Setje-Eilers@Sun.COM (scf_handle == NULL)? NULL : 62*10054SJan.Setje-Eilers@Sun.COM (scf_simple_prop_next_boolean_t)dlsym(scf_handle, 63*10054SJan.Setje-Eilers@Sun.COM "scf_simple_prop_next_boolean"); 64*10054SJan.Setje-Eilers@Sun.COM scf_simple_prop_free_t scf_simple_prop_free = 65*10054SJan.Setje-Eilers@Sun.COM (scf_handle == NULL)? NULL : 66*10054SJan.Setje-Eilers@Sun.COM (scf_simple_prop_free_t)dlsym(scf_handle, "scf_simple_prop_free"); 67*10054SJan.Setje-Eilers@Sun.COM 68*10054SJan.Setje-Eilers@Sun.COM lmutex_lock(&scf_lock); 69*10054SJan.Setje-Eilers@Sun.COM if (real_scf_simple_prop_get == NULL || 70*10054SJan.Setje-Eilers@Sun.COM real_scf_simple_prop_next_boolean == NULL || 71*10054SJan.Setje-Eilers@Sun.COM real_scf_simple_prop_free == NULL) { 72*10054SJan.Setje-Eilers@Sun.COM if (scf_simple_prop_get == NULL) 73*10054SJan.Setje-Eilers@Sun.COM real_scf_simple_prop_get = (scf_simple_prop_get_t)(-1); 74*10054SJan.Setje-Eilers@Sun.COM else { 75*10054SJan.Setje-Eilers@Sun.COM real_scf_simple_prop_get = scf_simple_prop_get; 76*10054SJan.Setje-Eilers@Sun.COM scf_handle = NULL; /* don't dlclose it */ 77*10054SJan.Setje-Eilers@Sun.COM } 78*10054SJan.Setje-Eilers@Sun.COM if (scf_simple_prop_next_boolean == NULL) 79*10054SJan.Setje-Eilers@Sun.COM real_scf_simple_prop_next_boolean = 80*10054SJan.Setje-Eilers@Sun.COM (scf_simple_prop_next_boolean_t)(-1); 81*10054SJan.Setje-Eilers@Sun.COM else { 82*10054SJan.Setje-Eilers@Sun.COM real_scf_simple_prop_next_boolean = 83*10054SJan.Setje-Eilers@Sun.COM scf_simple_prop_next_boolean; 84*10054SJan.Setje-Eilers@Sun.COM scf_handle = NULL; /* don't dlclose it */ 85*10054SJan.Setje-Eilers@Sun.COM } 86*10054SJan.Setje-Eilers@Sun.COM if (scf_simple_prop_free == NULL) 87*10054SJan.Setje-Eilers@Sun.COM real_scf_simple_prop_free = 88*10054SJan.Setje-Eilers@Sun.COM (scf_simple_prop_free_t)(-1); 89*10054SJan.Setje-Eilers@Sun.COM else { 90*10054SJan.Setje-Eilers@Sun.COM real_scf_simple_prop_free = scf_simple_prop_free; 91*10054SJan.Setje-Eilers@Sun.COM scf_handle = NULL; /* don't dlclose it */ 92*10054SJan.Setje-Eilers@Sun.COM } 93*10054SJan.Setje-Eilers@Sun.COM membar_producer(); 94*10054SJan.Setje-Eilers@Sun.COM } 95*10054SJan.Setje-Eilers@Sun.COM lmutex_unlock(&scf_lock); 96*10054SJan.Setje-Eilers@Sun.COM 97*10054SJan.Setje-Eilers@Sun.COM if (scf_handle) 98*10054SJan.Setje-Eilers@Sun.COM (void) dlclose(scf_handle); 99*10054SJan.Setje-Eilers@Sun.COM } 100*10054SJan.Setje-Eilers@Sun.COM 101*10054SJan.Setje-Eilers@Sun.COM static void 102*10054SJan.Setje-Eilers@Sun.COM check_archive_update(void) 103*10054SJan.Setje-Eilers@Sun.COM { 104*10054SJan.Setje-Eilers@Sun.COM scf_simple_prop_t *prop = NULL; 105*10054SJan.Setje-Eilers@Sun.COM boolean_t update_flag = B_FALSE; 106*10054SJan.Setje-Eilers@Sun.COM char *fmri = "svc:/system/boot-config:default"; 107*10054SJan.Setje-Eilers@Sun.COM uint8_t *ret_val = NULL; 108*10054SJan.Setje-Eilers@Sun.COM 109*10054SJan.Setje-Eilers@Sun.COM if (real_scf_simple_prop_get == NULL || 110*10054SJan.Setje-Eilers@Sun.COM real_scf_simple_prop_next_boolean == NULL || 111*10054SJan.Setje-Eilers@Sun.COM real_scf_simple_prop_free == NULL) { 112*10054SJan.Setje-Eilers@Sun.COM load_scf(); 113*10054SJan.Setje-Eilers@Sun.COM } 114*10054SJan.Setje-Eilers@Sun.COM if (real_scf_simple_prop_get == (scf_simple_prop_get_t)(-1) || 115*10054SJan.Setje-Eilers@Sun.COM real_scf_simple_prop_next_boolean == 116*10054SJan.Setje-Eilers@Sun.COM (scf_simple_prop_next_boolean_t)(-1) || 117*10054SJan.Setje-Eilers@Sun.COM real_scf_simple_prop_free == (scf_simple_prop_free_t)(-1)) { 118*10054SJan.Setje-Eilers@Sun.COM return; 119*10054SJan.Setje-Eilers@Sun.COM } 120*10054SJan.Setje-Eilers@Sun.COM 121*10054SJan.Setje-Eilers@Sun.COM prop = real_scf_simple_prop_get(NULL, fmri, "config", 122*10054SJan.Setje-Eilers@Sun.COM "uadmin_boot_archive_sync"); 123*10054SJan.Setje-Eilers@Sun.COM if (prop) { 124*10054SJan.Setje-Eilers@Sun.COM if ((ret_val = real_scf_simple_prop_next_boolean(prop)) != 125*10054SJan.Setje-Eilers@Sun.COM NULL) 126*10054SJan.Setje-Eilers@Sun.COM update_flag = (*ret_val == 0) ? B_FALSE : 127*10054SJan.Setje-Eilers@Sun.COM B_TRUE; 128*10054SJan.Setje-Eilers@Sun.COM real_scf_simple_prop_free(prop); 129*10054SJan.Setje-Eilers@Sun.COM } 130*10054SJan.Setje-Eilers@Sun.COM 131*10054SJan.Setje-Eilers@Sun.COM if (update_flag == B_TRUE) 132*10054SJan.Setje-Eilers@Sun.COM (void) system("/sbin/bootadm update-archive"); 133*10054SJan.Setje-Eilers@Sun.COM } 13410052SGangadhar.M@Sun.COM 13510052SGangadhar.M@Sun.COM int 13610052SGangadhar.M@Sun.COM uadmin(int cmd, int fcn, uintptr_t mdep) 13710052SGangadhar.M@Sun.COM { 13810052SGangadhar.M@Sun.COM extern int __uadmin(int cmd, int fcn, uintptr_t mdep); 13910052SGangadhar.M@Sun.COM 14010052SGangadhar.M@Sun.COM if (geteuid() == 0 && getzoneid() == GLOBAL_ZONEID && 14110052SGangadhar.M@Sun.COM (cmd == A_SHUTDOWN || cmd == A_REBOOT)) { 142*10054SJan.Setje-Eilers@Sun.COM check_archive_update(); 14310052SGangadhar.M@Sun.COM } 14410052SGangadhar.M@Sun.COM 14510052SGangadhar.M@Sun.COM return (__uadmin(cmd, fcn, mdep)); 14610052SGangadhar.M@Sun.COM } 147