Print this page
uadmin
Split |
Close |
Expand all |
Collapse all |
--- old/usr/src/lib/libc/i386/sys/uadmin.c
+++ new/usr/src/lib/libc/i386/sys/uadmin.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 2009 Sun Microsystems, Inc. All rights reserved.
24 24 * Use is subject to license terms.
25 25 */
26 26
27 27
28 28 /*
29 29 * Wrapper function to implement reboot w/ arguments on x86
30 30 * platforms. Extract reboot arguments and place them in
31 31 * in a transient entry in /[stub]boot/grub/menu.lst
32 32 * All other commands are passed through.
33 33 */
34 34 #include "lint.h"
35 35 #include "mtlib.h"
36 36 #include <fcntl.h>
37 37 #include <ctype.h>
38 38 #include <stdio.h>
39 39 #include <stdlib.h>
40 40 #include <sys/types.h>
41 41 #include <sys/stat.h>
42 42 #include <sys/uadmin.h>
43 43 #include <unistd.h>
44 44 #include <strings.h>
45 45 #include <pthread.h>
46 46 #include <zone.h>
47 47 #include <libscf.h>
48 48 #include <thread.h>
49 49 #include <dlfcn.h>
50 50 #include <atomic.h>
51 51
52 52 /*
53 53 * Pull in the following three interfaces from libscf without introducing
54 54 * a dependency on it, which since libscf depends on libc would be circular:
55 55 *
56 56 * scf_simple_prop_get
57 57 * scf_simple_prop_next_boolean
58 58 * scf_simple_prop_free
59 59 */
60 60 typedef scf_simple_prop_t *(*scf_simple_prop_get_t)(scf_handle_t *,
61 61 const char *, const char *, const char *);
62 62 static scf_simple_prop_get_t real_scf_simple_prop_get = NULL;
63 63 typedef uint8_t *(*scf_simple_prop_next_boolean_t)(scf_simple_prop_t *);
64 64 static scf_simple_prop_next_boolean_t real_scf_simple_prop_next_boolean = NULL;
65 65 typedef void (*scf_simple_prop_free_t)(scf_simple_prop_t *);
66 66 static scf_simple_prop_free_t real_scf_simple_prop_free = NULL;
67 67 static mutex_t scf_lock = DEFAULTMUTEX;
68 68
69 69 static void
70 70 load_scf(void)
71 71 {
72 72 void *scf_handle = dlopen("libscf.so.1", RTLD_LAZY);
73 73 scf_simple_prop_get_t scf_simple_prop_get = (scf_handle == NULL)? NULL :
74 74 (scf_simple_prop_get_t)dlsym(scf_handle, "scf_simple_prop_get");
75 75 scf_simple_prop_next_boolean_t scf_simple_prop_next_boolean =
76 76 (scf_handle == NULL)? NULL :
77 77 (scf_simple_prop_next_boolean_t)dlsym(scf_handle,
78 78 "scf_simple_prop_next_boolean");
79 79 scf_simple_prop_free_t scf_simple_prop_free =
80 80 (scf_handle == NULL)? NULL :
81 81 (scf_simple_prop_free_t)dlsym(scf_handle, "scf_simple_prop_free");
82 82
83 83 lmutex_lock(&scf_lock);
84 84 if (real_scf_simple_prop_get == NULL ||
85 85 real_scf_simple_prop_next_boolean == NULL ||
86 86 real_scf_simple_prop_free == NULL) {
87 87 if (scf_simple_prop_get == NULL)
88 88 real_scf_simple_prop_get = (scf_simple_prop_get_t)(-1);
89 89 else {
90 90 real_scf_simple_prop_get = scf_simple_prop_get;
91 91 scf_handle = NULL; /* don't dlclose it */
92 92 }
93 93 if (scf_simple_prop_next_boolean == NULL)
94 94 real_scf_simple_prop_next_boolean =
95 95 (scf_simple_prop_next_boolean_t)(-1);
96 96 else {
97 97 real_scf_simple_prop_next_boolean =
98 98 scf_simple_prop_next_boolean;
99 99 scf_handle = NULL; /* don't dlclose it */
100 100 }
101 101 if (scf_simple_prop_free == NULL)
102 102 real_scf_simple_prop_free =
103 103 (scf_simple_prop_free_t)(-1);
104 104 else {
105 105 real_scf_simple_prop_free = scf_simple_prop_free;
106 106 scf_handle = NULL; /* don't dlclose it */
107 107 }
108 108 membar_producer();
109 109 }
110 110 lmutex_unlock(&scf_lock);
111 111
112 112 if (scf_handle)
113 113 (void) dlclose(scf_handle);
114 114 }
115 115
116 116 static void
117 117 check_archive_update(void)
118 118 {
119 119 scf_simple_prop_t *prop = NULL;
120 120 boolean_t update_flag = B_FALSE;
121 121 char *fmri = "svc:/system/boot-config:default";
122 122 uint8_t *ret_val = NULL;
123 123
124 124 if (real_scf_simple_prop_get == NULL ||
125 125 real_scf_simple_prop_next_boolean == NULL ||
126 126 real_scf_simple_prop_free == NULL) {
127 127 load_scf();
128 128 }
129 129 if (real_scf_simple_prop_get == (scf_simple_prop_get_t)(-1) ||
130 130 real_scf_simple_prop_next_boolean ==
131 131 (scf_simple_prop_next_boolean_t)(-1) ||
132 132 real_scf_simple_prop_free == (scf_simple_prop_free_t)(-1)) {
133 133 return;
134 134 }
135 135
136 136 prop = real_scf_simple_prop_get(NULL, fmri, "config",
137 137 "uadmin_boot_archive_sync");
138 138 if (prop) {
139 139 if ((ret_val = real_scf_simple_prop_next_boolean(prop)) !=
140 140 NULL)
141 141 update_flag = (*ret_val == 0) ? B_FALSE :
142 142 B_TRUE;
143 143 real_scf_simple_prop_free(prop);
144 144 }
145 145
146 146 if (update_flag == B_TRUE)
147 147 (void) system("/sbin/bootadm update-archive");
148 148 }
149 149
150 150 static int
151 151 legal_arg(char *bargs)
152 152 {
153 153 int i;
154 154
155 155 for (i = 0; i < BOOTARGS_MAX; i++, bargs++) {
156 156 if (*bargs == 0 && i > 0)
157 157 return (i);
158 158 if (!isprint(*bargs))
159 159 break;
160 160 }
161 161 return (-1);
162 162 }
163 163
164 164 static char quote[] = "\'";
165 165
166 166 int
167 167 uadmin(int cmd, int fcn, uintptr_t mdep)
168 168 {
169 169 extern int __uadmin(int cmd, int fcn, uintptr_t mdep);
170 170 char *bargs, cmdbuf[256];
171 171 struct stat sbuf;
172 172 char *altroot;
173 173
174 174 bargs = (char *)mdep;
175 175
176 176 if (geteuid() == 0 && getzoneid() == GLOBAL_ZONEID &&
177 177 (cmd == A_SHUTDOWN || cmd == A_REBOOT)) {
178 178 int off = 0;
179 179
180 180 switch (fcn) {
181 181 case AD_IBOOT:
182 182 case AD_SBOOT:
183 183 case AD_SIBOOT:
184 184 /*
185 185 * These functions fabricate appropriate bootargs.
186 186 * If bootargs are passed in, map these functions
187 187 * to AD_BOOT.
188 188 */
189 189 if (bargs == 0) {
190 190 switch (fcn) {
191 191 case AD_IBOOT:
192 192 bargs = "-a";
193 193 break;
194 194 case AD_SBOOT:
195 195 bargs = "-s";
196 196 break;
197 197 case AD_SIBOOT:
198 198 bargs = "-sa";
199 199 break;
200 200 }
201 201 }
202 202 /*FALLTHROUGH*/
203 203 case AD_BOOT:
204 204 case AD_FASTREBOOT:
205 205 if (bargs == 0)
206 206 break; /* no args */
207 207 if (legal_arg(bargs) < 0)
208 208 break; /* bad args */
209 209
210 210 /* avoid cancellation in system() */
211 211 (void) pthread_setcancelstate(PTHREAD_CANCEL_DISABLE,
212 212 NULL);
213 213
214 214 /* check for /stubboot */
215 215 if (stat("/stubboot/boot/grub/menu.lst", &sbuf) == 0) {
216 216 altroot = "-R /stubboot ";
217 217 } else {
218 218 altroot = "";
219 219 }
220 220
221 221 if (fcn == AD_FASTREBOOT) {
222 222 char *newarg, *head;
223 223 char bargs_scratch[BOOTARGS_MAX];
224 224
225 225 bzero(bargs_scratch, BOOTARGS_MAX);
226 226
227 227 bcopy(bargs, bargs_scratch, strlen(bargs));
228 228 head = bargs_scratch;
229 229 newarg = strtok(bargs_scratch, " ");
230 230
231 231 if (newarg == NULL || newarg[0] == '-')
232 232 break;
233 233
234 234 /* First argument is rootdir */
235 235 if (strncmp(&newarg[strlen(newarg)-4],
236 236 "unix", 4) != 0) {
237 237 newarg = strtok(NULL, " ");
238 238 off = newarg - head;
239 239 }
240 240
241 241 /*
242 242 * If we are using alternate root via
243 243 * mountpoint or a different BE, don't
↓ open down ↓ |
243 lines elided |
↑ open up ↑ |
244 244 * bother to update the temp menu entry.
245 245 */
246 246 if (off > 0)
247 247 break;
248 248 }
249 249
250 250 /* are we rebooting to a GRUB menu entry? */
251 251 if (isdigit(bargs[0])) {
252 252 int entry = strtol(bargs, NULL, 10);
253 253 (void) snprintf(cmdbuf, sizeof (cmdbuf),
254 - "/sbin/bootadm set-menu %sdefault=%d",
254 + "/sbin/grubadm %s --set-default %d",
255 255 altroot, entry);
256 256 } else {
257 257 (void) snprintf(cmdbuf, sizeof (cmdbuf),
258 - "/sbin/bootadm -m update_temp %s"
259 - "-o %s%s%s", altroot, quote,
258 + "/sbin/grubadm --new --default %s"
259 + "--set-opts %s%s%s", altroot, quote,
260 260 &bargs[off], quote);
261 261 }
262 262 (void) system(cmdbuf);
263 263 }
264 264 check_archive_update();
265 265 }
266 266 return (__uadmin(cmd, fcn, mdep));
267 267 }
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX