4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
23 * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
24 * Use is subject to license terms.
29 * Wrapper function to implement reboot w/ arguments on x86
30 * platforms. Extract reboot arguments and place them in
31 * in a transient entry. All other commands are passed through.
39 #include <sys/types.h>
41 #include <sys/uadmin.h>
52 * Pull in the following three interfaces from libscf without introducing
53 * a dependency on it, which since libscf depends on libc would be circular:
56 * scf_simple_prop_next_boolean
57 * scf_simple_prop_free
59 typedef scf_simple_prop_t
*(*scf_simple_prop_get_t
)(scf_handle_t
*,
60 const char *, const char *, const char *);
61 static scf_simple_prop_get_t real_scf_simple_prop_get
= NULL
;
62 typedef uint8_t *(*scf_simple_prop_next_boolean_t
)(scf_simple_prop_t
*);
63 static scf_simple_prop_next_boolean_t real_scf_simple_prop_next_boolean
= NULL
;
64 typedef void (*scf_simple_prop_free_t
)(scf_simple_prop_t
*);
65 static scf_simple_prop_free_t real_scf_simple_prop_free
= NULL
;
66 static mutex_t scf_lock
= DEFAULTMUTEX
;
71 void *scf_handle
= dlopen("libscf.so.1", RTLD_LAZY
);
72 scf_simple_prop_get_t scf_simple_prop_get
= (scf_handle
== NULL
)? NULL
:
73 (scf_simple_prop_get_t
)dlsym(scf_handle
, "scf_simple_prop_get");
74 scf_simple_prop_next_boolean_t scf_simple_prop_next_boolean
=
75 (scf_handle
== NULL
)? NULL
:
76 (scf_simple_prop_next_boolean_t
)dlsym(scf_handle
,
77 "scf_simple_prop_next_boolean");
78 scf_simple_prop_free_t scf_simple_prop_free
=
79 (scf_handle
== NULL
)? NULL
:
80 (scf_simple_prop_free_t
)dlsym(scf_handle
, "scf_simple_prop_free");
82 lmutex_lock(&scf_lock
);
83 if (real_scf_simple_prop_get
== NULL
||
84 real_scf_simple_prop_next_boolean
== NULL
||
85 real_scf_simple_prop_free
== NULL
) {
86 if (scf_simple_prop_get
== NULL
)
87 real_scf_simple_prop_get
= (scf_simple_prop_get_t
)(-1);
89 real_scf_simple_prop_get
= scf_simple_prop_get
;
90 scf_handle
= NULL
; /* don't dlclose it */
92 if (scf_simple_prop_next_boolean
== NULL
)
93 real_scf_simple_prop_next_boolean
=
94 (scf_simple_prop_next_boolean_t
)(-1);
96 real_scf_simple_prop_next_boolean
=
97 scf_simple_prop_next_boolean
;
98 scf_handle
= NULL
; /* don't dlclose it */
100 if (scf_simple_prop_free
== NULL
)
101 real_scf_simple_prop_free
=
102 (scf_simple_prop_free_t
)(-1);
104 real_scf_simple_prop_free
= scf_simple_prop_free
;
105 scf_handle
= NULL
; /* don't dlclose it */
109 lmutex_unlock(&scf_lock
);
112 (void) dlclose(scf_handle
);
116 check_archive_update(void)
118 scf_simple_prop_t
*prop
= NULL
;
119 boolean_t update_flag
= B_FALSE
;
120 char *fmri
= "svc:/system/boot-config:default";
121 uint8_t *ret_val
= NULL
;
123 if (real_scf_simple_prop_get
== NULL
||
124 real_scf_simple_prop_next_boolean
== NULL
||
125 real_scf_simple_prop_free
== NULL
) {
128 if (real_scf_simple_prop_get
== (scf_simple_prop_get_t
)(-1) ||
129 real_scf_simple_prop_next_boolean
==
130 (scf_simple_prop_next_boolean_t
)(-1) ||
131 real_scf_simple_prop_free
== (scf_simple_prop_free_t
)(-1)) {
135 prop
= real_scf_simple_prop_get(NULL
, fmri
, "config",
136 "uadmin_boot_archive_sync");
138 if ((ret_val
= real_scf_simple_prop_next_boolean(prop
)) !=
140 update_flag
= (*ret_val
== 0) ? B_FALSE
:
142 real_scf_simple_prop_free(prop
);
145 if (update_flag
== B_TRUE
)
146 (void) system("/sbin/bootadm update-archive");
150 legal_arg(char *bargs
)
154 for (i
= 0; i
< BOOTARGS_MAX
; i
++, bargs
++) {
155 if (*bargs
== 0 && i
> 0)
157 if (!isprint(*bargs
))
163 static char quote
[] = "\'";
166 uadmin(int cmd
, int fcn
, uintptr_t mdep
)
168 extern int __uadmin(int cmd
, int fcn
, uintptr_t mdep
);
169 char *bargs
, cmdbuf
[256];
173 bargs
= (char *)mdep
;
175 if (geteuid() == 0 && getzoneid() == GLOBAL_ZONEID
&&
176 (cmd
== A_SHUTDOWN
|| cmd
== A_REBOOT
)) {
184 * These functions fabricate appropriate bootargs.
185 * If bootargs are passed in, map these functions
206 if (legal_arg(bargs
) < 0)
207 break; /* bad args */
209 /* avoid cancellation in system() */
210 (void) pthread_setcancelstate(PTHREAD_CANCEL_DISABLE
,
215 if (fcn
== AD_FASTREBOOT
) {
217 char bargs_scratch
[BOOTARGS_MAX
];
219 bzero(bargs_scratch
, BOOTARGS_MAX
);
221 bcopy(bargs
, bargs_scratch
, strlen(bargs
));
222 head
= bargs_scratch
;
223 newarg
= strtok(bargs_scratch
, " ");
225 if (newarg
== NULL
|| newarg
[0] == '-')
228 /* First argument is rootdir */
229 if (strncmp(&newarg
[strlen(newarg
)-4],
231 newarg
= strtok(NULL
, " ");
236 * If we are using alternate root via
237 * mountpoint or a different BE, don't
238 * bother to update the temp menu entry.
244 /* are we rebooting to a boot menu entry? */
245 if (isdigit(bargs
[0])) {
246 int entry
= strtol(bargs
, NULL
, 10);
247 (void) snprintf(cmdbuf
, sizeof (cmdbuf
),
248 "/sbin/bootadm set-menu %sdefault=%d",
251 (void) snprintf(cmdbuf
, sizeof (cmdbuf
),
252 "/sbin/bootadm -m update_temp %s"
253 "-o %s%s%s", altroot
, quote
,
256 (void) system(cmdbuf
);
258 check_archive_update();
260 return (__uadmin(cmd
, fcn
, mdep
));