1050c4bfeSGangadhar Mylapuram /* 2050c4bfeSGangadhar Mylapuram * CDDL HEADER START 3050c4bfeSGangadhar Mylapuram * 4050c4bfeSGangadhar Mylapuram * The contents of this file are subject to the terms of the 5050c4bfeSGangadhar Mylapuram * Common Development and Distribution License (the "License"). 6050c4bfeSGangadhar Mylapuram * You may not use this file except in compliance with the License. 7050c4bfeSGangadhar Mylapuram * 8050c4bfeSGangadhar Mylapuram * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9050c4bfeSGangadhar Mylapuram * or http://www.opensolaris.org/os/licensing. 10050c4bfeSGangadhar Mylapuram * See the License for the specific language governing permissions 11050c4bfeSGangadhar Mylapuram * and limitations under the License. 12050c4bfeSGangadhar Mylapuram * 13050c4bfeSGangadhar Mylapuram * When distributing Covered Code, include this CDDL HEADER in each 14050c4bfeSGangadhar Mylapuram * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15050c4bfeSGangadhar Mylapuram * If applicable, add the following below this CDDL HEADER, with the 16050c4bfeSGangadhar Mylapuram * fields enclosed by brackets "[]" replaced with your own identifying 17050c4bfeSGangadhar Mylapuram * information: Portions Copyright [yyyy] [name of copyright owner] 18050c4bfeSGangadhar Mylapuram * 19050c4bfeSGangadhar Mylapuram * CDDL HEADER END 20050c4bfeSGangadhar Mylapuram */ 21050c4bfeSGangadhar Mylapuram /* 22050c4bfeSGangadhar Mylapuram * Copyright 2009 Sun Microsystems, Inc. All rights reserved. 23050c4bfeSGangadhar Mylapuram * Use is subject to license terms. 24050c4bfeSGangadhar Mylapuram */ 25050c4bfeSGangadhar Mylapuram 26*4ed6ceb3SJan Setje-Eilers #include "mtlib.h" 27050c4bfeSGangadhar Mylapuram #include <sys/types.h> 28050c4bfeSGangadhar Mylapuram #include <libscf.h> 29050c4bfeSGangadhar Mylapuram #include <sys/uadmin.h> 30050c4bfeSGangadhar Mylapuram #include <unistd.h> 31050c4bfeSGangadhar Mylapuram #include <stdlib.h> 32050c4bfeSGangadhar Mylapuram #include <zone.h> 33*4ed6ceb3SJan Setje-Eilers #include <thread.h> 34*4ed6ceb3SJan Setje-Eilers #include <dlfcn.h> 35*4ed6ceb3SJan Setje-Eilers #include <atomic.h> 36*4ed6ceb3SJan Setje-Eilers 37*4ed6ceb3SJan Setje-Eilers /* 38*4ed6ceb3SJan Setje-Eilers * Pull in the following three interfaces from libscf without introducing 39*4ed6ceb3SJan Setje-Eilers * a dependency on it, which since libscf depends on libc would be circular: 40*4ed6ceb3SJan Setje-Eilers * 41*4ed6ceb3SJan Setje-Eilers * scf_simple_prop_get 42*4ed6ceb3SJan Setje-Eilers * scf_simple_prop_next_boolean 43*4ed6ceb3SJan Setje-Eilers * scf_simple_prop_free 44*4ed6ceb3SJan Setje-Eilers */ 45*4ed6ceb3SJan Setje-Eilers typedef scf_simple_prop_t *(*scf_simple_prop_get_t)(scf_handle_t *, 46*4ed6ceb3SJan Setje-Eilers const char *, const char *, const char *); 47*4ed6ceb3SJan Setje-Eilers static scf_simple_prop_get_t real_scf_simple_prop_get = NULL; 48*4ed6ceb3SJan Setje-Eilers typedef uint8_t *(*scf_simple_prop_next_boolean_t)(scf_simple_prop_t *); 49*4ed6ceb3SJan Setje-Eilers static scf_simple_prop_next_boolean_t real_scf_simple_prop_next_boolean = NULL; 50*4ed6ceb3SJan Setje-Eilers typedef void (*scf_simple_prop_free_t)(scf_simple_prop_t *); 51*4ed6ceb3SJan Setje-Eilers static scf_simple_prop_free_t real_scf_simple_prop_free = NULL; 52*4ed6ceb3SJan Setje-Eilers static mutex_t scf_lock = DEFAULTMUTEX; 53*4ed6ceb3SJan Setje-Eilers 54*4ed6ceb3SJan Setje-Eilers static void 55*4ed6ceb3SJan Setje-Eilers load_scf(void) 56*4ed6ceb3SJan Setje-Eilers { 57*4ed6ceb3SJan Setje-Eilers void *scf_handle = dlopen("libscf.so.1", RTLD_LAZY); 58*4ed6ceb3SJan Setje-Eilers scf_simple_prop_get_t scf_simple_prop_get = (scf_handle == NULL)? NULL : 59*4ed6ceb3SJan Setje-Eilers (scf_simple_prop_get_t)dlsym(scf_handle, "scf_simple_prop_get"); 60*4ed6ceb3SJan Setje-Eilers scf_simple_prop_next_boolean_t scf_simple_prop_next_boolean = 61*4ed6ceb3SJan Setje-Eilers (scf_handle == NULL)? NULL : 62*4ed6ceb3SJan Setje-Eilers (scf_simple_prop_next_boolean_t)dlsym(scf_handle, 63*4ed6ceb3SJan Setje-Eilers "scf_simple_prop_next_boolean"); 64*4ed6ceb3SJan Setje-Eilers scf_simple_prop_free_t scf_simple_prop_free = 65*4ed6ceb3SJan Setje-Eilers (scf_handle == NULL)? NULL : 66*4ed6ceb3SJan Setje-Eilers (scf_simple_prop_free_t)dlsym(scf_handle, "scf_simple_prop_free"); 67*4ed6ceb3SJan Setje-Eilers 68*4ed6ceb3SJan Setje-Eilers lmutex_lock(&scf_lock); 69*4ed6ceb3SJan Setje-Eilers if (real_scf_simple_prop_get == NULL || 70*4ed6ceb3SJan Setje-Eilers real_scf_simple_prop_next_boolean == NULL || 71*4ed6ceb3SJan Setje-Eilers real_scf_simple_prop_free == NULL) { 72*4ed6ceb3SJan Setje-Eilers if (scf_simple_prop_get == NULL) 73*4ed6ceb3SJan Setje-Eilers real_scf_simple_prop_get = (scf_simple_prop_get_t)(-1); 74*4ed6ceb3SJan Setje-Eilers else { 75*4ed6ceb3SJan Setje-Eilers real_scf_simple_prop_get = scf_simple_prop_get; 76*4ed6ceb3SJan Setje-Eilers scf_handle = NULL; /* don't dlclose it */ 77*4ed6ceb3SJan Setje-Eilers } 78*4ed6ceb3SJan Setje-Eilers if (scf_simple_prop_next_boolean == NULL) 79*4ed6ceb3SJan Setje-Eilers real_scf_simple_prop_next_boolean = 80*4ed6ceb3SJan Setje-Eilers (scf_simple_prop_next_boolean_t)(-1); 81*4ed6ceb3SJan Setje-Eilers else { 82*4ed6ceb3SJan Setje-Eilers real_scf_simple_prop_next_boolean = 83*4ed6ceb3SJan Setje-Eilers scf_simple_prop_next_boolean; 84*4ed6ceb3SJan Setje-Eilers scf_handle = NULL; /* don't dlclose it */ 85*4ed6ceb3SJan Setje-Eilers } 86*4ed6ceb3SJan Setje-Eilers if (scf_simple_prop_free == NULL) 87*4ed6ceb3SJan Setje-Eilers real_scf_simple_prop_free = 88*4ed6ceb3SJan Setje-Eilers (scf_simple_prop_free_t)(-1); 89*4ed6ceb3SJan Setje-Eilers else { 90*4ed6ceb3SJan Setje-Eilers real_scf_simple_prop_free = scf_simple_prop_free; 91*4ed6ceb3SJan Setje-Eilers scf_handle = NULL; /* don't dlclose it */ 92*4ed6ceb3SJan Setje-Eilers } 93*4ed6ceb3SJan Setje-Eilers membar_producer(); 94*4ed6ceb3SJan Setje-Eilers } 95*4ed6ceb3SJan Setje-Eilers lmutex_unlock(&scf_lock); 96*4ed6ceb3SJan Setje-Eilers 97*4ed6ceb3SJan Setje-Eilers if (scf_handle) 98*4ed6ceb3SJan Setje-Eilers (void) dlclose(scf_handle); 99*4ed6ceb3SJan Setje-Eilers } 100*4ed6ceb3SJan Setje-Eilers 101*4ed6ceb3SJan Setje-Eilers static void 102*4ed6ceb3SJan Setje-Eilers check_archive_update(void) 103*4ed6ceb3SJan Setje-Eilers { 104*4ed6ceb3SJan Setje-Eilers scf_simple_prop_t *prop = NULL; 105*4ed6ceb3SJan Setje-Eilers boolean_t update_flag = B_FALSE; 106*4ed6ceb3SJan Setje-Eilers char *fmri = "svc:/system/boot-config:default"; 107*4ed6ceb3SJan Setje-Eilers uint8_t *ret_val = NULL; 108*4ed6ceb3SJan Setje-Eilers 109*4ed6ceb3SJan Setje-Eilers if (real_scf_simple_prop_get == NULL || 110*4ed6ceb3SJan Setje-Eilers real_scf_simple_prop_next_boolean == NULL || 111*4ed6ceb3SJan Setje-Eilers real_scf_simple_prop_free == NULL) { 112*4ed6ceb3SJan Setje-Eilers load_scf(); 113*4ed6ceb3SJan Setje-Eilers } 114*4ed6ceb3SJan Setje-Eilers if (real_scf_simple_prop_get == (scf_simple_prop_get_t)(-1) || 115*4ed6ceb3SJan Setje-Eilers real_scf_simple_prop_next_boolean == 116*4ed6ceb3SJan Setje-Eilers (scf_simple_prop_next_boolean_t)(-1) || 117*4ed6ceb3SJan Setje-Eilers real_scf_simple_prop_free == (scf_simple_prop_free_t)(-1)) { 118*4ed6ceb3SJan Setje-Eilers return; 119*4ed6ceb3SJan Setje-Eilers } 120*4ed6ceb3SJan Setje-Eilers 121*4ed6ceb3SJan Setje-Eilers prop = real_scf_simple_prop_get(NULL, fmri, "config", 122*4ed6ceb3SJan Setje-Eilers "uadmin_boot_archive_sync"); 123*4ed6ceb3SJan Setje-Eilers if (prop) { 124*4ed6ceb3SJan Setje-Eilers if ((ret_val = real_scf_simple_prop_next_boolean(prop)) != 125*4ed6ceb3SJan Setje-Eilers NULL) 126*4ed6ceb3SJan Setje-Eilers update_flag = (*ret_val == 0) ? B_FALSE : 127*4ed6ceb3SJan Setje-Eilers B_TRUE; 128*4ed6ceb3SJan Setje-Eilers real_scf_simple_prop_free(prop); 129*4ed6ceb3SJan Setje-Eilers } 130*4ed6ceb3SJan Setje-Eilers 131*4ed6ceb3SJan Setje-Eilers if (update_flag == B_TRUE) 132*4ed6ceb3SJan Setje-Eilers (void) system("/sbin/bootadm update-archive"); 133*4ed6ceb3SJan Setje-Eilers } 134050c4bfeSGangadhar Mylapuram 135050c4bfeSGangadhar Mylapuram int 136050c4bfeSGangadhar Mylapuram uadmin(int cmd, int fcn, uintptr_t mdep) 137050c4bfeSGangadhar Mylapuram { 138050c4bfeSGangadhar Mylapuram extern int __uadmin(int cmd, int fcn, uintptr_t mdep); 139050c4bfeSGangadhar Mylapuram 140050c4bfeSGangadhar Mylapuram if (geteuid() == 0 && getzoneid() == GLOBAL_ZONEID && 141050c4bfeSGangadhar Mylapuram (cmd == A_SHUTDOWN || cmd == A_REBOOT)) { 142*4ed6ceb3SJan Setje-Eilers check_archive_update(); 143050c4bfeSGangadhar Mylapuram } 144050c4bfeSGangadhar Mylapuram 145050c4bfeSGangadhar Mylapuram return (__uadmin(cmd, fcn, mdep)); 146050c4bfeSGangadhar Mylapuram } 147