Print this page
9250 remove xpv related code from bootadm
Split |
Close |
Expand all |
Collapse all |
--- old/usr/src/cmd/boot/bootadm/bootadm_loader.c
+++ new/usr/src/cmd/boot/bootadm/bootadm_loader.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
↓ open down ↓ |
16 lines elided |
↑ open up ↑ |
17 17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 18 *
19 19 * CDDL HEADER END
20 20 */
21 21 /*
22 22 * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
23 23 * Copyright 2012 Milan Jurik. All rights reserved.
24 24 */
25 25
26 26 /*
27 - * Copyright 2015 Nexenta Systems, Inc. All rights reserved.
27 + * Copyright 2018 Nexenta Systems, Inc.
28 28 * Copyright 2016 Toomas Soome <tsoome@me.com>
29 29 */
30 30
31 31 /*
32 32 * Loader menu management.
33 33 */
34 34
35 35 #include <stdio.h>
36 36 #include <stdlib.h>
37 37 #include <string.h>
38 38 #include <wchar.h>
39 39 #include <errno.h>
40 40 #include <limits.h>
41 41 #include <alloca.h>
42 42 #include <unistd.h>
43 43 #include <sys/types.h>
44 44 #include <sys/stat.h>
45 45 #include <sys/queue.h>
46 46 #include <libbe.h>
47 47 #include <ficl.h>
48 48 #include <ficlplatform/emu.h>
49 49 #include <ofmt.h>
50 50
51 51 #include "bootadm.h"
↓ open down ↓ |
14 lines elided |
↑ open up ↑ |
52 52
53 53 extern int bam_rootlen;
54 54 extern int bam_alt_root;
55 55 extern char *rootbuf;
56 56 extern char *bam_root;
57 57
58 58 #define BOOT_DIR "/boot"
59 59 #define CONF_DIR BOOT_DIR "/conf.d"
60 60 #define MENU BOOT_DIR "/menu.lst"
61 61 #define TRANSIENT BOOT_DIR "/transient.conf"
62 -#define XEN_CONFIG CONF_DIR "/xen"
63 62
64 63 typedef struct menu_entry {
65 64 int me_idx;
66 65 boolean_t me_active;
67 66 char *me_title;
68 67 char *me_type;
69 68 char *me_bootfs;
70 69 STAILQ_ENTRY(menu_entry) me_next;
71 70 } menu_entry_t;
72 71 STAILQ_HEAD(menu_lst, menu_entry);
73 72
74 73 static error_t set_option(struct menu_lst *, char *, char *);
75 74 static error_t list_entry(struct menu_lst *, char *, char *);
76 75 static error_t update_entry(struct menu_lst *, char *, char *);
77 76 static error_t update_temp(struct menu_lst *, char *, char *);
78 77 static error_t list_setting(struct menu_lst *menu, char *, char *);
79 -static error_t disable_hyper(struct menu_lst *, char *, char *);
80 -static error_t enable_hyper(struct menu_lst *, char *, char *);
81 78
82 79 /* Menu related sub commands */
83 80 static subcmd_defn_t menu_subcmds[] = {
84 81 "set_option", OPT_ABSENT, set_option, 0, /* PUB */
85 82 "list_entry", OPT_OPTIONAL, list_entry, 1, /* PUB */
86 83 "update_entry", OPT_REQ, update_entry, 0, /* menu */
87 84 "update_temp", OPT_OPTIONAL, update_temp, 0, /* reboot */
88 85 "list_setting", OPT_OPTIONAL, list_setting, 1, /* menu */
89 - "disable_hypervisor", OPT_ABSENT, disable_hyper, 0, /* menu */
90 - "enable_hypervisor", OPT_ABSENT, enable_hyper, 0, /* menu */
91 86 NULL, 0, NULL, 0 /* must be last */
92 87 };
93 88
94 89 #define NUM_COLS (5)
95 90
96 91 static boolean_t
97 92 print_menu_cb(ofmt_arg_t *ofarg, char *buf, uint_t bufsize)
98 93 {
99 94 menu_entry_t *entry = ofarg->ofmt_cbarg;
100 95
101 96 switch (ofarg->ofmt_id) {
102 97 case 0:
103 98 (void) snprintf(buf, bufsize, "%d", entry->me_idx);
104 99 break;
105 100 case 1:
106 101 (void) snprintf(buf, bufsize, "%s", entry->me_title);
107 102 break;
108 103 case 2:
109 104 (void) snprintf(buf, bufsize, "%s", entry->me_bootfs);
110 105 break;
111 106 case 3:
112 107 (void) snprintf(buf, bufsize, "%s", entry->me_type);
113 108 break;
114 109 case 4:
115 110 if (entry->me_active == B_TRUE)
116 111 (void) snprintf(buf, bufsize, " *");
117 112 else
118 113 (void) snprintf(buf, bufsize, " -");
119 114 break;
120 115 default:
121 116 return (B_FALSE);
122 117 }
123 118 return (B_TRUE);
124 119 }
125 120
126 121 static void
127 122 init_hdr_cols(ofmt_field_t *hdr)
128 123 {
129 124 uint_t i;
130 125
131 126 for (i = 0; i < NUM_COLS; i++) {
132 127 char *name = NULL;
133 128
134 129 switch (i) {
135 130 case 0:
136 131 name = _("INDEX");
137 132 break;
138 133 case 1:
139 134 name = _("NAME");
140 135 break;
141 136 case 2:
142 137 name = _("DEVICE");
143 138 break;
144 139 case 3:
145 140 name = _("TYPE");
146 141 break;
147 142 case 4:
148 143 name = _("DEFAULT");
149 144 break;
150 145 }
151 146
152 147 hdr[i].of_name = name;
153 148 hdr[i].of_id = i;
154 149 hdr[i].of_cb = print_menu_cb;
155 150
156 151 if (name != NULL) {
157 152 wchar_t wname[128];
158 153 size_t sz = mbstowcs(wname, name, sizeof (wname) /
159 154 sizeof (wchar_t));
160 155 if (sz > 0) {
161 156 int wcsw = wcswidth(wname, sz);
162 157 if (wcsw > 0)
163 158 hdr[i].of_width = wcsw;
164 159 else
165 160 hdr[i].of_width = sz;
166 161 } else {
167 162 hdr[i].of_width = strlen(name);
168 163 }
169 164 }
170 165 }
171 166 }
172 167
173 168 static void
174 169 menu_update_widths(ofmt_field_t *hdr, struct menu_lst *menu)
175 170 {
176 171 size_t len[NUM_COLS];
177 172 menu_entry_t *entry;
178 173 int i;
179 174
180 175 for (i = 0; i < NUM_COLS; i++)
181 176 len[i] = hdr[i].of_width + 1;
182 177
183 178 STAILQ_FOREACH(entry, menu, me_next) {
184 179 size_t entry_len;
185 180
186 181 entry_len = strlen(entry->me_title) + 1;
187 182 if (entry_len > len[1])
188 183 len[1] = entry_len;
189 184
190 185 entry_len = strlen(entry->me_bootfs) + 1;
191 186 if (entry_len > len[2])
192 187 len[2] = entry_len;
193 188
194 189 entry_len = strlen(entry->me_type) + 1;
195 190 if (entry_len > len[3])
196 191 len[3] = entry_len;
197 192 }
198 193
199 194 for (i = 0; i < NUM_COLS; i++)
200 195 hdr[i].of_width = len[i];
201 196 }
202 197
203 198 static ofmt_field_t *
204 199 init_menu_template(struct menu_lst *menu)
205 200 {
206 201 ofmt_field_t *temp;
207 202
208 203 if ((temp = calloc(NUM_COLS + 1, sizeof (ofmt_field_t))) == NULL)
209 204 return (temp);
210 205
211 206 init_hdr_cols(temp);
212 207 menu_update_widths(temp, menu);
213 208 return (temp);
214 209 }
215 210
216 211 static void
217 212 print_nodes(boolean_t parsable, struct menu_lst *menu)
218 213 {
219 214 ofmt_status_t oferr;
220 215 ofmt_handle_t ofmt;
221 216 uint_t ofmtflags = 0;
222 217 ofmt_field_t *menu_template;
223 218 menu_entry_t *entry;
224 219
225 220 if (parsable == B_TRUE)
226 221 ofmtflags = OFMT_PARSABLE;
227 222
228 223 menu_template = init_menu_template(menu);
229 224 oferr = ofmt_open(NULL, menu_template, ofmtflags, 0, &ofmt);
230 225
231 226 if (oferr != OFMT_SUCCESS) {
232 227 char buf[OFMT_BUFSIZE];
233 228
234 229 (void) ofmt_strerror(ofmt, oferr, buf, sizeof (buf));
235 230 (void) printf("bootadm: %s\n", buf);
236 231 free(menu_template);
237 232 return;
238 233 }
239 234
240 235 STAILQ_FOREACH(entry, menu, me_next)
241 236 ofmt_print(ofmt, entry);
242 237
243 238 ofmt_close(ofmt);
244 239 free(menu_template);
245 240 }
246 241
247 242 /*
248 243 * Get the be_active_on_boot for bootfs.
249 244 */
250 245 static boolean_t
251 246 menu_active_on_boot(be_node_list_t *be_nodes, const char *bootfs)
252 247 {
253 248 be_node_list_t *be_node;
254 249 boolean_t rv = B_FALSE;
255 250
256 251 for (be_node = be_nodes; be_node != NULL;
257 252 be_node = be_node->be_next_node) {
258 253 if (strcmp(be_node->be_root_ds, bootfs) == 0) {
259 254 rv = be_node->be_active_on_boot;
260 255 break;
261 256 }
262 257 }
263 258
264 259 return (rv);
265 260 }
266 261
267 262 error_t
268 263 menu_read(struct menu_lst *menu, char *menu_path)
269 264 {
270 265 FILE *fp;
271 266 be_node_list_t *be_nodes;
272 267 menu_entry_t *mp;
273 268 char buf[PATH_MAX];
274 269 char *title;
275 270 char *bootfs;
276 271 char *type;
277 272 char *key, *value;
278 273 int i = 0;
279 274 int ret = BAM_SUCCESS;
280 275
281 276 fp = fopen(menu_path, "r");
282 277 if (fp == NULL)
283 278 return (BAM_ERROR);
284 279
285 280 if (be_list(NULL, &be_nodes) != BE_SUCCESS)
286 281 be_nodes = NULL;
287 282
288 283 /*
289 284 * menu.lst entry is on two lines, one for title, one for bootfs
290 285 * so we process both lines in succession.
291 286 */
292 287 title = NULL;
293 288 type = NULL;
294 289 bootfs = NULL;
295 290 do {
296 291 if (fgets(buf, PATH_MAX, fp) == NULL) {
297 292 if (!feof(fp))
298 293 ret = BAM_ERROR;
299 294 goto done;
300 295 }
301 296 key = strtok(buf, " \n");
302 297 if (strcmp(key, "title") != 0) {
303 298 ret = BAM_ERROR;
304 299 goto done;
305 300 }
306 301 value = strtok(NULL, " \n");
307 302 if ((title = strdup(value)) == NULL) {
308 303 ret = BAM_ERROR;
309 304 goto done;
310 305 }
311 306
312 307 if (fgets(buf, PATH_MAX, fp) == NULL) {
313 308 ret = BAM_ERROR;
314 309 goto done;
315 310 }
316 311
317 312 key = strtok(buf, " \n");
318 313 if ((type = strdup(key)) == NULL) {
319 314 ret = BAM_ERROR;
320 315 goto done;
321 316 }
322 317 value = strtok(NULL, " \n");
323 318 if ((bootfs = strdup(value)) == NULL) {
324 319 ret = BAM_ERROR;
325 320 goto done;
326 321 }
327 322 if ((mp = malloc(sizeof (menu_entry_t))) == NULL) {
328 323 ret = BAM_ERROR;
329 324 goto done;
330 325 }
331 326 mp->me_idx = i++;
332 327 mp->me_title = title;
333 328 mp->me_type = type;
334 329 mp->me_bootfs = bootfs;
335 330 mp->me_active = menu_active_on_boot(be_nodes, bootfs);
336 331 STAILQ_INSERT_TAIL(menu, mp, me_next);
337 332
338 333 title = NULL;
339 334 type = NULL;
340 335 bootfs = NULL;
341 336 } while (feof(fp) == 0);
342 337
343 338 done:
344 339 free(title);
345 340 free(type);
346 341 free(bootfs);
347 342 (void) fclose(fp);
348 343 be_free_list(be_nodes);
349 344 return (ret);
350 345 }
351 346
352 347 void
353 348 menu_free(struct menu_lst *menu)
354 349 {
355 350 menu_entry_t *entry;
356 351 STAILQ_FOREACH(entry, menu, me_next) {
357 352 STAILQ_REMOVE_HEAD(menu, me_next);
358 353 free(entry->me_title);
359 354 free(entry->me_type);
360 355 free(entry->me_bootfs);
361 356 free(entry);
362 357 }
363 358 }
364 359
365 360 error_t
366 361 bam_loader_menu(char *subcmd, char *opt, int largc, char *largv[])
367 362 {
368 363 error_t ret;
369 364 char menu_path[PATH_MAX];
370 365 char clean_menu_root[PATH_MAX];
371 366 char menu_root[PATH_MAX];
372 367 struct stat sb;
373 368 error_t (*f)(struct menu_lst *, char *, char *);
374 369 char *special;
375 370 char *pool = NULL;
376 371 zfs_mnted_t zmnted;
377 372 char *zmntpt;
378 373 char *osdev;
379 374 char *osroot;
380 375 const char *fcn = "bam_loader_menu()";
381 376 struct menu_lst menu = {0};
382 377
383 378 STAILQ_INIT(&menu);
384 379
385 380 /*
386 381 * Check arguments
387 382 */
388 383 ret = check_subcmd_and_options(subcmd, opt, menu_subcmds, &f);
389 384 if (ret == BAM_ERROR) {
390 385 return (BAM_ERROR);
391 386 }
392 387
393 388 assert(bam_root);
394 389
395 390 (void) strlcpy(menu_root, bam_root, sizeof (menu_root));
396 391 osdev = osroot = NULL;
397 392
398 393 if (strcmp(subcmd, "update_entry") == 0) {
399 394 assert(opt);
400 395
401 396 osdev = strtok(opt, ",");
402 397 assert(osdev);
403 398 osroot = strtok(NULL, ",");
404 399 if (osroot) {
405 400 /* fixup bam_root so that it points at osroot */
406 401 if (realpath(osroot, rootbuf) == NULL) {
407 402 bam_error(_("cannot resolve path %s: %s\n"),
408 403 osroot, strerror(errno));
409 404 return (BAM_ERROR);
410 405 }
411 406 bam_alt_root = 1;
412 407 bam_root = rootbuf;
413 408 bam_rootlen = strlen(rootbuf);
414 409 }
415 410 }
416 411
417 412 if (stat(menu_root, &sb) == -1) {
418 413 bam_error(_("cannot find menu\n"));
419 414 return (BAM_ERROR);
420 415 }
421 416
422 417 if (!is_zfs(menu_root)) {
423 418 bam_error(_("only ZFS root is supported\n"));
424 419 return (BAM_ERROR);
425 420 }
426 421
427 422 assert(strcmp(menu_root, bam_root) == 0);
428 423 special = get_special(menu_root);
429 424 INJECT_ERROR1("Z_MENU_GET_SPECIAL", special = NULL);
430 425 if (special == NULL) {
431 426 bam_error(_("cant find special file for mount-point %s\n"),
432 427 menu_root);
433 428 return (BAM_ERROR);
434 429 }
435 430 pool = strtok(special, "/");
436 431 INJECT_ERROR1("Z_MENU_GET_POOL", pool = NULL);
437 432 if (pool == NULL) {
438 433 free(special);
439 434 bam_error(_("cant find pool for mount-point %s\n"), menu_root);
440 435 return (BAM_ERROR);
441 436 }
442 437 BAM_DPRINTF(("%s: derived pool=%s from special\n", fcn, pool));
443 438
444 439 zmntpt = mount_top_dataset(pool, &zmnted);
445 440 INJECT_ERROR1("Z_MENU_MOUNT_TOP_DATASET", zmntpt = NULL);
446 441 if (zmntpt == NULL) {
447 442 bam_error(_("cannot mount pool dataset for pool: %s\n"), pool);
448 443 free(special);
449 444 return (BAM_ERROR);
450 445 }
451 446 BAM_DPRINTF(("%s: top dataset mountpoint=%s\n", fcn, zmntpt));
452 447
453 448 (void) strlcpy(menu_root, zmntpt, sizeof (menu_root));
454 449 BAM_DPRINTF(("%s: zfs menu_root=%s\n", fcn, menu_root));
455 450
456 451 elide_trailing_slash(menu_root, clean_menu_root,
457 452 sizeof (clean_menu_root));
458 453
459 454 BAM_DPRINTF(("%s: cleaned menu root is <%s>\n", fcn, clean_menu_root));
460 455
461 456 (void) strlcpy(menu_path, clean_menu_root, sizeof (menu_path));
462 457 (void) strlcat(menu_path, MENU, sizeof (menu_path));
463 458
464 459 BAM_DPRINTF(("%s: menu path is: %s\n", fcn, menu_path));
465 460
466 461 /*
467 462 * update_entry is special case, its used by installer
468 463 * and needs to create menu.lst file for loader
469 464 */
470 465 if (menu_read(&menu, menu_path) == BAM_ERROR &&
471 466 strcmp(subcmd, "update_entry") != 0) {
472 467 bam_error(_("cannot find menu file: %s\n"), menu_path);
473 468 if (special != NULL)
474 469 free(special);
475 470 return (BAM_ERROR);
476 471 }
477 472
478 473 /*
479 474 * If listing the menu, display the menu location
480 475 */
481 476 if (strcmp(subcmd, "list_entry") == 0)
482 477 bam_print(_("the location for the active menu is: %s\n"),
↓ open down ↓ |
382 lines elided |
↑ open up ↑ |
483 478 menu_path);
484 479
485 480 /*
486 481 * We already checked the following case in
487 482 * check_subcmd_and_suboptions() above. Complete the
488 483 * final step now.
489 484 */
490 485 if (strcmp(subcmd, "set_option") == 0) {
491 486 assert(largc == 1 && largv[0] && largv[1] == NULL);
492 487 opt = largv[0];
493 - } else if ((strcmp(subcmd, "enable_hypervisor") != 0) &&
494 - (strcmp(subcmd, "list_setting") != 0)) {
488 + } else if (strcmp(subcmd, "list_setting") != 0) {
495 489 assert(largc == 0 && largv == NULL);
496 490 }
497 491
498 492 /*
499 493 * Once the sub-cmd handler has run
500 494 * only the line field is guaranteed to have valid values
501 495 */
502 496 if (strcmp(subcmd, "update_entry") == 0) {
503 497 ret = f(&menu, menu_root, osdev);
504 498 } else if (strcmp(subcmd, "upgrade") == 0) {
505 499 ret = f(&menu, bam_root, menu_root);
506 500 } else if (strcmp(subcmd, "list_entry") == 0) {
507 501 ret = f(&menu, menu_path, opt);
508 502 } else if (strcmp(subcmd, "list_setting") == 0) {
509 503 ret = f(&menu, ((largc > 0) ? largv[0] : ""),
510 504 ((largc > 1) ? largv[1] : ""));
511 - } else if (strcmp(subcmd, "disable_hypervisor") == 0) {
512 - if (is_sparc()) {
513 - bam_error(_("%s operation unsupported on SPARC "
514 - "machines\n"), subcmd);
515 - ret = BAM_ERROR;
516 - } else {
517 - ret = f(&menu, bam_root, NULL);
518 - }
519 - } else if (strcmp(subcmd, "enable_hypervisor") == 0) {
520 - if (is_sparc()) {
521 - bam_error(_("%s operation unsupported on SPARC "
522 - "machines\n"), subcmd);
523 - ret = BAM_ERROR;
524 - } else {
525 - char *extra_args = NULL;
526 -
527 - /*
528 - * Compress all arguments passed in the largv[] array
529 - * into one string that can then be appended to the
530 - * end of the kernel$ string the routine to enable the
531 - * hypervisor will build.
532 - *
533 - * This allows the caller to supply arbitrary unparsed
534 - * arguments, such as dom0 memory settings or APIC
535 - * options.
536 - *
537 - * This concatenation will be done without ANY syntax
538 - * checking whatsoever, so it's the responsibility of
539 - * the caller to make sure the arguments are valid and
540 - * do not duplicate arguments the conversion routines
541 - * may create.
542 - */
543 - if (largc > 0) {
544 - int extra_len, i;
545 -
546 - for (extra_len = 0, i = 0; i < largc; i++)
547 - extra_len += strlen(largv[i]);
548 -
549 - /*
550 - * Allocate space for argument strings,
551 - * intervening spaces and terminating NULL.
552 - */
553 - extra_args = alloca(extra_len + largc);
554 -
555 - (void) strcpy(extra_args, largv[0]);
556 -
557 - for (i = 1; i < largc; i++) {
558 - (void) strcat(extra_args, " ");
559 - (void) strcat(extra_args, largv[i]);
560 - }
561 - }
562 -
563 - ret = f(&menu, bam_root, extra_args);
564 - }
565 505 } else
566 506 ret = f(&menu, NULL, opt);
567 507
568 508 if (ret == BAM_WRITE) {
569 509 BAM_DPRINTF(("%s: writing menu to clean-menu-root: <%s>\n",
570 510 fcn, clean_menu_root));
571 511 /* ret = menu_write(clean_menu_root, menu); */
572 512 }
573 513
574 514 INJECT_ERROR1("POOL_SET", pool = "/pooldata");
575 515 assert((is_zfs(menu_root)) ^ (pool == NULL));
576 516 if (pool) {
577 517 (void) umount_top_dataset(pool, zmnted, zmntpt);
578 518 free(special);
579 519 }
580 520
581 521 menu_free(&menu);
582 522 return (ret);
583 523 }
584 524
585 525 /*
586 526 * To suppress output from ficl. We do not want to see messages
587 527 * from interpreting loader config.
588 528 */
589 529
590 530 /*ARGSUSED*/
591 531 static void
592 532 ficlTextOutSilent(ficlCallback *cb, char *text)
593 533 {
594 534 }
595 535
596 536 /*ARGSUSED*/
597 537 static error_t
598 538 set_option(struct menu_lst *menu, char *dummy, char *opt)
599 539 {
600 540 char path[PATH_MAX];
601 541 char *val;
602 542 char *rest;
603 543 int optval;
604 544 menu_entry_t *entry;
605 545 nvlist_t *be_attrs;
606 546 FILE *fp;
607 547 int rv, ret = BAM_SUCCESS;
608 548
609 549 assert(menu);
610 550 assert(opt);
611 551 assert(dummy == NULL);
612 552
613 553 val = strchr(opt, '=');
614 554 if (val != NULL) {
615 555 *val++ = '\0';
616 556 }
617 557
618 558 if (strcmp(opt, "default") == 0) {
619 559 errno = 0;
620 560 optval = strtol(val, &rest, 10);
621 561 if (errno != 0 || *rest != '\0') {
622 562 bam_error(_("invalid boot entry number: %s\n"), val);
623 563 return (BAM_ERROR);
624 564 }
625 565 STAILQ_FOREACH(entry, menu, me_next) {
626 566 if (entry->me_idx == optval)
627 567 break;
628 568 }
629 569 if (entry == NULL) {
630 570 bam_error(_("invalid boot entry number: %s\n"), val);
631 571 return (BAM_ERROR);
632 572 }
633 573 if (nvlist_alloc(&be_attrs, NV_UNIQUE_NAME, 0) != 0) {
634 574 bam_error(_("out of memory\n"));
635 575 return (BAM_ERROR);
636 576 }
637 577 if (nvlist_add_string(be_attrs, BE_ATTR_ORIG_BE_NAME,
638 578 entry->me_title) != 0) {
639 579 bam_error(_("out of memory\n"));
640 580 nvlist_free(be_attrs);
641 581 return (BAM_ERROR);
642 582 }
643 583 ret = be_activate(be_attrs);
644 584 nvlist_free(be_attrs);
645 585 if (ret != 0)
646 586 ret = BAM_ERROR;
647 587 return (ret);
648 588 } else if (strcmp(opt, "timeout") == 0) {
649 589 errno = 0;
650 590 optval = strtol(val, &rest, 10);
651 591 if (errno != 0 || *rest != '\0') {
652 592 bam_error(_("invalid timeout: %s\n"), val);
653 593 return (BAM_ERROR);
654 594 }
655 595
656 596 (void) snprintf(path, PATH_MAX, "%s" CONF_DIR "/timeout",
657 597 bam_root);
658 598
659 599 fp = fopen(path, "w");
660 600 if (fp == NULL) {
661 601 bam_error(_("failed to open file: %s: %s\n"),
662 602 path, strerror(errno));
663 603 return (BAM_ERROR);
664 604 }
665 605 /*
666 606 * timeout=-1 is to disable auto boot in illumos, but
667 607 * loader needs "NO" to disable auto boot.
668 608 */
669 609 if (optval == -1)
670 610 rv = fprintf(fp, "autoboot_delay=\"NO\"\n");
671 611 else
672 612 rv = fprintf(fp, "autoboot_delay=\"%d\"\n", optval);
673 613
674 614 if (rv < 0) {
675 615 bam_error(_("write to file failed: %s: %s\n"),
676 616 path, strerror(errno));
677 617 (void) fclose(fp);
678 618 ret = BAM_ERROR;
679 619 } else
680 620 rv = fclose(fp);
681 621
682 622 if (rv < 0) {
683 623 bam_error(_("failed to close file: %s: %s\n"),
684 624 path, strerror(errno));
685 625 ret = BAM_ERROR;
686 626 }
687 627 if (ret == BAM_ERROR)
688 628 (void) unlink(path);
689 629
690 630 return (BAM_SUCCESS);
691 631 }
692 632
693 633 bam_error(_("invalid option: %s\n"), opt);
694 634 return (BAM_ERROR);
695 635 }
696 636
697 637 static int
698 638 bam_mount_be(menu_entry_t *entry, char **dir)
699 639 {
700 640 nvlist_t *be_attrs = NULL;
701 641 const char *tmpdir = getenv("TMPDIR");
702 642 const char *tmpname = "bam.XXXXXX";
703 643 be_node_list_t *be_node, *be_nodes = NULL;
704 644 int ret;
705 645
706 646 *dir = NULL;
707 647 if (tmpdir == NULL)
708 648 tmpdir = "/tmp";
709 649
710 650 ret = asprintf(dir, "%s/%s", tmpdir, tmpname);
711 651 if (ret < 0) {
712 652 return (BE_ERR_NOMEM);
713 653 }
714 654 *dir = mkdtemp(*dir);
715 655
716 656 if (nvlist_alloc(&be_attrs, NV_UNIQUE_NAME, 0) != 0) {
717 657 ret = BE_ERR_NOMEM;
718 658 goto out;
719 659 }
720 660
721 661 ret = be_list(NULL, &be_nodes);
722 662 if (ret != BE_SUCCESS) {
723 663 goto out;
724 664 }
725 665
726 666 for (be_node = be_nodes; be_node;
727 667 be_node = be_node->be_next_node)
728 668 if (strcmp(be_node->be_root_ds, entry->me_bootfs) == 0)
729 669 break;
730 670
731 671 if (nvlist_add_string(be_attrs, BE_ATTR_ORIG_BE_NAME,
732 672 be_node->be_node_name) != 0) {
733 673 ret = BE_ERR_NOMEM;
734 674 goto out;
735 675 }
736 676
737 677 if (nvlist_add_string(be_attrs, BE_ATTR_MOUNTPOINT, *dir) != 0) {
738 678 ret = BE_ERR_NOMEM;
739 679 goto out;
740 680 }
741 681
742 682 ret = be_mount(be_attrs);
743 683 if (ret == BE_ERR_MOUNTED) {
744 684 /*
745 685 * if BE is mounted, dir does not point to correct directory
746 686 */
747 687 (void) rmdir(*dir);
748 688 free(*dir);
749 689 *dir = NULL;
750 690 }
751 691 out:
752 692 if (be_nodes != NULL)
753 693 be_free_list(be_nodes);
754 694 nvlist_free(be_attrs);
755 695 return (ret);
756 696 }
757 697
758 698 static int
759 699 bam_umount_be(char *dir)
760 700 {
761 701 nvlist_t *be_attrs;
762 702 int ret;
763 703
764 704 if (dir == NULL) /* nothing to do */
765 705 return (BE_SUCCESS);
766 706
767 707 if (nvlist_alloc(&be_attrs, NV_UNIQUE_NAME, 0) != 0)
768 708 return (BE_ERR_NOMEM);
769 709
770 710 if (nvlist_add_string(be_attrs, BE_ATTR_ORIG_BE_NAME, dir) != 0) {
771 711 ret = BE_ERR_NOMEM;
772 712 goto out;
773 713 }
774 714
775 715 ret = be_unmount(be_attrs);
776 716 out:
777 717 nvlist_free(be_attrs);
778 718 return (ret);
779 719 }
780 720
781 721 /*
782 722 * display details of menu entry or single property
783 723 */
784 724 static error_t
785 725 list_menu_entry(menu_entry_t *entry, char *setting)
786 726 {
787 727 int ret = BAM_SUCCESS;
788 728 char *ptr, *dir;
789 729 char buf[MAX_INPUT];
790 730 ficlVm *vm;
791 731 int mounted;
792 732
793 733 if (strcmp(entry->me_type, "bootfs") != 0 ||
794 734 strchr(entry->me_bootfs, ':') != NULL) {
795 735 (void) printf("\nTitle: %s\n", entry->me_title);
796 736 (void) printf("Type: %s\n", entry->me_type);
797 737 (void) printf("Device: %s\n", entry->me_bootfs);
798 738 return (ret);
799 739 }
800 740
801 741 mounted = bam_mount_be(entry, &dir);
802 742 if (mounted != BE_SUCCESS && mounted != BE_ERR_MOUNTED) {
803 743 if (dir != NULL) {
804 744 (void) rmdir(dir);
805 745 free(dir);
806 746 }
807 747 bam_error(_("%s is not mounted\n"), entry->me_title);
808 748 return (BAM_ERROR);
809 749 }
810 750
811 751 vm = bf_init("", ficlTextOutSilent);
812 752 if (vm == NULL) {
813 753 bam_error(_("error setting up forth interpreter\n"));
814 754 ret = BAM_ERROR;
815 755 goto done;
816 756 }
817 757
818 758 /* should only get FICL_VM_STATUS_OUT_OF_TEXT */
819 759 (void) snprintf(buf, MAX_INPUT, "set currdev=zfs:%s:",
820 760 entry->me_bootfs);
821 761 ret = ficlVmEvaluate(vm, buf);
822 762 if (ret != FICL_VM_STATUS_OUT_OF_TEXT) {
823 763 bam_error(_("error interpreting boot config\n"));
824 764 ret = BAM_ERROR;
825 765 goto done;
826 766 }
827 767 (void) snprintf(buf, MAX_INPUT, "include /boot/forth/loader.4th");
828 768 ret = ficlVmEvaluate(vm, buf);
829 769 if (ret != FICL_VM_STATUS_OUT_OF_TEXT) {
830 770 bam_error(_("error interpreting boot config\n"));
831 771 ret = BAM_ERROR;
832 772 goto done;
833 773 }
834 774 (void) snprintf(buf, MAX_INPUT, "start");
835 775 ret = ficlVmEvaluate(vm, buf);
836 776 if (ret != FICL_VM_STATUS_OUT_OF_TEXT) {
837 777 bam_error(_("error interpreting boot config\n"));
838 778 ret = BAM_ERROR;
839 779 goto done;
840 780 }
841 781 (void) snprintf(buf, MAX_INPUT, "boot");
842 782 ret = ficlVmEvaluate(vm, buf);
843 783 if (ret != FICL_VM_STATUS_OUT_OF_TEXT) {
844 784 bam_error(_("error interpreting boot config\n"));
845 785 ret = BAM_ERROR;
846 786 goto done;
847 787 }
848 788
849 789 ret = BAM_SUCCESS;
850 790 if (*setting == '\0')
851 791 (void) printf("\nTitle: %s\n", entry->me_title);
852 792 else if (strcasecmp(setting, "title") == 0) {
853 793 (void) printf("%s\n", entry->me_title);
854 794 goto done;
855 795 }
856 796
857 797 ptr = getenv("autoboot_delay");
858 798 if (ptr != NULL) {
859 799 char *timeout = "-1";
860 800
861 801 if (strcasecmp(ptr, "NO") != 0)
862 802 timeout = ptr;
863 803
864 804 if (*setting == '\0')
865 805 (void) printf("Timeout: %s\n", timeout);
866 806 else if (strcasecmp(setting, "timeout") == 0) {
867 807 (void) printf("%s\n", timeout);
868 808 goto done;
869 809 }
870 810
871 811 }
872 812 ptr = getenv("console");
873 813 if (ptr != NULL) {
874 814 if (*setting == '\0')
875 815 (void) printf("Console: %s\n", ptr);
876 816 else if (strcasecmp(setting, "console") == 0) {
877 817 (void) printf("%s\n", ptr);
878 818 goto done;
↓ open down ↓ |
304 lines elided |
↑ open up ↑ |
879 819 }
880 820 }
881 821
882 822 if (*setting == '\0')
883 823 (void) printf("Bootfs: %s\n", entry->me_bootfs);
884 824 else if (strcasecmp(setting, "bootfs") == 0) {
885 825 (void) printf("%s\n", entry->me_bootfs);
886 826 goto done;
887 827 }
888 828
889 - ptr = getenv("xen_kernel");
829 + ptr = getenv("kernelname");
890 830 if (ptr != NULL) {
891 - if (*setting == '\0') {
892 - (void) printf("Xen kernel: %s\n", ptr);
893 - } else if (strcasecmp(setting, "xen_kernel") == 0) {
894 - (void) printf("%s\n", ptr);
895 - goto done;
896 - }
897 -
898 - if (*setting == '\0') {
899 - (void) printf("Xen args: \"%s\"\n",
900 - getenv("xen_cmdline"));
901 - } else if (strcasecmp(setting, "xen_cmdline") == 0) {
902 - (void) printf("%s\n", getenv("xen_cmdline"));
903 - goto done;
904 - }
905 -
906 - if (*setting == '\0') {
907 - (void) printf("Kernel: %s\n",
908 - getenv("bootfile"));
909 - } if (strcasecmp(setting, "kernel") == 0) {
910 - (void) printf("%s\n", getenv("bootfile"));
911 - goto done;
912 - }
913 - } else {
914 - ptr = getenv("kernelname");
915 - if (ptr != NULL) {
916 - if (*setting == '\0') {
917 - (void) printf("Kernel: %s\n", ptr);
918 - } else if (strcasecmp(setting, "kernel") == 0) {
919 - (void) printf("%s\n", ptr);
920 - goto done;
921 - }
831 + if (*setting == '\0') {
832 + (void) printf("Kernel: %s\n", ptr);
833 + } else if (strcasecmp(setting, "kernel") == 0) {
834 + (void) printf("%s\n", ptr);
835 + goto done;
922 836 }
923 837 }
924 838
925 839 ptr = getenv("boot-args");
926 840 if (ptr != NULL) {
927 841 if (*setting == '\0') {
928 842 (void) printf("Boot-args: \"%s\"\n", ptr);
929 843 } else if (strcasecmp(setting, "boot-args") == 0) {
930 844 (void) printf("%s\n", ptr);
931 845 goto done;
932 846 }
933 847 }
934 848
935 849 if (*setting == '\0' || strcasecmp(setting, "modules") == 0) {
936 850 (void) printf("\nModules:\n");
937 851 ficlVmSetTextOut(vm, ficlCallbackDefaultTextOut);
938 852 (void) snprintf(buf, MAX_INPUT, "show-module-options");
939 853 ret = ficlVmEvaluate(vm, buf);
940 854 if (ret != FICL_VM_STATUS_OUT_OF_TEXT) {
941 855 bam_error(_("error interpreting boot config\n"));
942 856 ret = BAM_ERROR;
943 857 goto done;
944 858 }
945 859 ret = BAM_SUCCESS;
946 860 goto done;
947 861 }
948 862
949 863 /* if we got here with setting string, its unknown property */
950 864 if (*setting != '\0') {
951 865 bam_error(_("unknown property: %s\n"), setting);
952 866 ret = BAM_ERROR;
953 867 } else
954 868 ret = BAM_SUCCESS;
955 869 done:
956 870 bf_fini();
957 871 if (mounted != BE_ERR_MOUNTED) {
958 872 (void) bam_umount_be(dir);
959 873 }
960 874
961 875 if (dir != NULL) {
962 876 (void) rmdir(dir);
963 877 free(dir);
964 878 }
965 879
966 880 return (ret);
967 881 }
968 882
969 883 /*ARGSUSED*/
970 884 static error_t
971 885 list_entry(struct menu_lst *menu, char *menu_root, char *opt)
972 886 {
973 887 error_t ret = BAM_SUCCESS;
974 888 menu_entry_t *entry;
975 889 char *ptr, *title = NULL;
976 890 int i, e = -1;
977 891
978 892 if (opt == NULL) {
979 893 print_nodes(B_FALSE, menu);
980 894 return (ret);
981 895 }
982 896
983 897 if ((ptr = strchr(opt, '=')) == NULL) {
984 898 bam_error(_("invalid option: %s\n"), opt);
985 899 return (BAM_ERROR);
986 900 }
987 901
988 902 i = ptr - opt;
989 903 if (strncmp(opt, "entry", i) == 0) {
990 904 e = atoi(ptr+1);
991 905 } else if (strncmp(opt, "title", i) == 0) {
992 906 title = ptr+1;
993 907 } else {
994 908 bam_error(_("invalid option: %s\n"), opt);
995 909 return (BAM_ERROR);
996 910 }
997 911
998 912 STAILQ_FOREACH(entry, menu, me_next) {
999 913 if (title != NULL) {
1000 914 if (strcmp(title, entry->me_title) == 0)
1001 915 break;
1002 916 } else if (entry->me_idx == e)
1003 917 break;
1004 918 }
1005 919
1006 920 if (entry == NULL) {
1007 921 bam_error(_("no matching entry found\n"));
1008 922 return (BAM_ERROR);
1009 923 }
1010 924
1011 925 return (list_menu_entry(entry, ""));
1012 926 }
1013 927
1014 928 /*
1015 929 * For now this is just stub entry to support grub interface, the
1016 930 * known consumer is installer ict.py code, calling as:
1017 931 * bootadm update-menu -R /a -Z -o rdisk
1018 932 * Later this can be converted to do something useful.
1019 933 */
1020 934 /*ARGSUSED*/
1021 935 static error_t
1022 936 update_entry(struct menu_lst *menu, char *menu_root, char *osdev)
1023 937 {
1024 938 char path[PATH_MAX];
1025 939 char *pool = menu_root + 1;
1026 940 be_node_list_t *be_nodes, *be_node;
1027 941 int rv;
1028 942 FILE *fp;
1029 943
1030 944 (void) snprintf(path, PATH_MAX, "%s%s", menu_root, MENU);
1031 945 rv = be_list(NULL, &be_nodes);
1032 946
1033 947 if (rv != BE_SUCCESS)
1034 948 return (BAM_ERROR);
1035 949
1036 950 fp = fopen(path, "w");
1037 951 if (fp == NULL) {
1038 952 be_free_list(be_nodes);
1039 953 return (BAM_ERROR);
1040 954 }
1041 955
1042 956 for (be_node = be_nodes; be_node; be_node = be_node->be_next_node) {
1043 957 if (strcmp(be_node->be_rpool, pool) == 0) {
1044 958 (void) fprintf(fp, "title %s\n", be_node->be_node_name);
1045 959 (void) fprintf(fp, "bootfs %s\n", be_node->be_root_ds);
1046 960 }
1047 961 }
1048 962
1049 963 be_free_list(be_nodes);
1050 964 (void) fclose(fp);
1051 965 return (BAM_SUCCESS);
1052 966 }
1053 967
↓ open down ↓ |
122 lines elided |
↑ open up ↑ |
1054 968 /*ARGSUSED*/
1055 969 static error_t
1056 970 update_temp(struct menu_lst *menu, char *dummy, char *opt)
1057 971 {
1058 972 error_t ret = BAM_ERROR;
1059 973 char path[PATH_MAX];
1060 974 char buf[MAX_INPUT];
1061 975 struct mnttab mpref = { 0 };
1062 976 struct mnttab mp = { 0 };
1063 977 ficlVm *vm;
1064 - char *env, *o;
978 + char *o;
1065 979 FILE *fp;
1066 980
1067 981 (void) snprintf(path, PATH_MAX, "%s" TRANSIENT, bam_root);
1068 982 /*
1069 983 * if opt == NULL, remove transient config
1070 984 */
1071 985 if (opt == NULL) {
1072 986 (void) unlink(path);
1073 987 return (BAM_SUCCESS);
1074 988 }
1075 989
1076 990 fp = fopen(MNTTAB, "r");
1077 991 if (fp == NULL)
1078 992 return (BAM_ERROR);
1079 993
1080 994 mpref.mnt_mountp = "/";
1081 995 if (getmntany(fp, &mp, &mpref) != 0) {
1082 996 (void) fclose(fp);
1083 997 return (BAM_ERROR);
↓ open down ↓ |
9 lines elided |
↑ open up ↑ |
1084 998 }
1085 999 (void) fclose(fp);
1086 1000
1087 1001 vm = bf_init("", ficlTextOutSilent);
1088 1002 if (vm == NULL) {
1089 1003 bam_error(_("Error setting up forth interpreter\n"));
1090 1004 return (ret);
1091 1005 }
1092 1006
1093 1007 /*
1094 - * need to check current boot config, so fire up the ficl
1095 - * if its xen setup, we add option to boot-args list, not replacing it.
1008 + * Need to check current boot config, so fire up the ficl.
1096 1009 */
1097 1010 (void) snprintf(buf, MAX_INPUT, "set currdev=zfs:%s:", mp.mnt_special);
1098 1011 ret = ficlVmEvaluate(vm, buf);
1099 1012 if (ret != FICL_VM_STATUS_OUT_OF_TEXT) {
1100 1013 bam_error(_("Error interpreting boot config\n"));
1101 1014 bf_fini();
1102 1015 return (BAM_ERROR);
1103 1016 }
1104 1017 (void) snprintf(buf, MAX_INPUT, "include /boot/forth/loader.4th");
1105 1018 ret = ficlVmEvaluate(vm, buf);
1106 1019 if (ret != FICL_VM_STATUS_OUT_OF_TEXT) {
1107 1020 bam_error(_("Error interpreting boot config\n"));
1108 1021 bf_fini();
1109 1022 return (BAM_ERROR);
1110 1023 }
1111 1024 (void) snprintf(buf, MAX_INPUT, "start");
1112 1025 ret = ficlVmEvaluate(vm, buf);
1113 1026 if (ret != FICL_VM_STATUS_OUT_OF_TEXT) {
1114 1027 bam_error(_("Error interpreting boot config\n"));
1115 1028 bf_fini();
1116 1029 return (BAM_ERROR);
1117 1030 }
↓ open down ↓ |
12 lines elided |
↑ open up ↑ |
1118 1031 (void) snprintf(buf, MAX_INPUT, "boot");
1119 1032 ret = ficlVmEvaluate(vm, buf);
1120 1033 if (ret != FICL_VM_STATUS_OUT_OF_TEXT) {
1121 1034 bam_error(_("Error interpreting boot config\n"));
1122 1035 bf_fini();
1123 1036 return (BAM_ERROR);
1124 1037 }
1125 1038 bf_fini();
1126 1039
1127 1040 if (opt[0] == '-') {
1128 - env = getenv("xen_kernel");
1129 1041 fp = fopen(path, "w");
1130 1042 if (fp == NULL)
1131 1043 return (BAM_ERROR);
1132 -
1133 - if (env != NULL) {
1134 - env = getenv("boot-args");
1135 - (void) fprintf(fp, "boot-args=\"%s %s\"\n", env, opt);
1136 - } else
1137 - (void) fprintf(fp, "boot-args=\"%s\"\n", opt);
1044 + (void) fprintf(fp, "boot-args=\"%s\"\n", opt);
1138 1045 (void) fclose(fp);
1139 1046 return (BAM_SUCCESS);
1140 1047 }
1141 1048
1142 1049 /*
1143 1050 * it should be the case with "kernel args"
1144 1051 * so, we split the opt at first space
1145 1052 * and store bootfile= and boot-args=
1146 1053 */
1147 - env = getenv("xen_kernel");
1148 -
1149 1054 o = strchr(opt, ' ');
1150 1055 if (o == NULL) {
1151 1056 fp = fopen(path, "w");
1152 1057 if (fp == NULL)
1153 1058 return (BAM_ERROR);
1154 1059 (void) fprintf(fp, "bootfile=\"%s;unix\"\n", opt);
1155 1060 (void) fclose(fp);
1156 1061 return (BAM_SUCCESS);
1157 1062 }
1158 1063 *o++ = '\0';
1159 1064 fp = fopen(path, "w");
1160 1065 if (fp == NULL)
1161 1066 return (BAM_ERROR);
1162 1067 (void) fprintf(fp, "bootfile=\"%s;unix\"\n", opt);
1163 -
1164 - if (env != NULL) {
1165 - env = getenv("boot-args");
1166 - (void) fprintf(fp, "boot-args=\"%s %s\"\n", env, opt);
1167 - } else
1168 - (void) fprintf(fp, "boot-args=\"%s\"\n", o);
1169 -
1068 + (void) fprintf(fp, "boot-args=\"%s\"\n", o);
1170 1069 (void) fflush(fp);
1171 1070 (void) fclose(fp);
1172 1071 return (ret);
1173 1072 }
1174 1073
1175 1074 static error_t
1176 1075 list_setting(struct menu_lst *menu, char *which, char *setting)
1177 1076 {
1178 1077 int entry = -1;
1179 1078 menu_entry_t *m;
1180 1079 be_node_list_t *be_nodes, *be_node = NULL;
1181 1080 int ret;
1182 1081
1183 1082 assert(which);
1184 1083 assert(setting);
1185 1084
1186 1085 /*
1187 1086 * which can be:
1188 1087 * "" - list default entry
1189 1088 * number - use for entry number
1190 1089 * property name
1191 1090 */
1192 1091 if (*which != '\0') {
1193 1092 if (isdigit(*which)) {
1194 1093 char *rest;
1195 1094 errno = 0;
1196 1095 entry = strtol(which, &rest, 10);
1197 1096 if (errno != 0 || *rest != '\0') {
1198 1097 bam_error(_("invalid boot entry number: %s\n"),
1199 1098 which);
1200 1099 return (BAM_ERROR);
1201 1100 }
1202 1101 } else
1203 1102 setting = which;
1204 1103 }
1205 1104
1206 1105 /* find default entry */
1207 1106 if (entry == -1) {
1208 1107 ret = be_list(NULL, &be_nodes);
1209 1108 if (ret != BE_SUCCESS) {
1210 1109 bam_error(_("No BE's found\n"));
1211 1110 return (BAM_ERROR);
1212 1111 }
1213 1112 STAILQ_FOREACH(m, menu, me_next) {
1214 1113 entry++;
1215 1114 for (be_node = be_nodes; be_node;
1216 1115 be_node = be_node->be_next_node) {
1217 1116 if (strcmp(be_node->be_root_ds,
1218 1117 m->me_bootfs) == 0)
1219 1118 break;
1220 1119 }
1221 1120 if (be_node != NULL &&
1222 1121 be_node->be_active_on_boot == B_TRUE)
1223 1122 break; /* found active node */
1224 1123 }
1225 1124 be_free_list(be_nodes);
1226 1125 if (be_node == NULL) {
1227 1126 bam_error(_("None of BE nodes is marked active\n"));
1228 1127 return (BAM_ERROR);
1229 1128 }
1230 1129 } else {
1231 1130 STAILQ_FOREACH(m, menu, me_next)
↓ open down ↓ |
52 lines elided |
↑ open up ↑ |
1232 1131 if (m->me_idx == entry)
1233 1132 break;
1234 1133
1235 1134 if (m == NULL) {
1236 1135 bam_error(_("no matching entry found\n"));
1237 1136 return (BAM_ERROR);
1238 1137 }
1239 1138 }
1240 1139
1241 1140 return (list_menu_entry(m, setting));
1242 -}
1243 -
1244 -/*ARGSUSED*/
1245 -static error_t
1246 -disable_hyper(struct menu_lst *menu, char *osroot, char *opt)
1247 -{
1248 - char path[PATH_MAX];
1249 -
1250 - (void) snprintf(path, PATH_MAX, "%s" XEN_CONFIG, bam_root);
1251 - (void) unlink(path);
1252 - return (BAM_SUCCESS);
1253 -}
1254 -
1255 -/*ARGSUSED*/
1256 -static error_t
1257 -enable_hyper(struct menu_lst *menu, char *osroot, char *opt)
1258 -{
1259 - ficlVm *vm;
1260 - char path[PATH_MAX];
1261 - char buf[MAX_INPUT];
1262 - char *env;
1263 - FILE *fp;
1264 - struct mnttab mpref = { 0 };
1265 - struct mnttab mp = { 0 };
1266 - int ret;
1267 -
1268 - fp = fopen(MNTTAB, "r");
1269 - if (fp == NULL)
1270 - return (BAM_ERROR);
1271 -
1272 - mpref.mnt_mountp = "/";
1273 - if (getmntany(fp, &mp, &mpref) != 0) {
1274 - (void) fclose(fp);
1275 - return (BAM_ERROR);
1276 - }
1277 - (void) fclose(fp);
1278 -
1279 - vm = bf_init("", ficlTextOutSilent);
1280 - if (vm == NULL) {
1281 - bam_error(_("Error setting up forth interpreter\n"));
1282 - return (BAM_ERROR);
1283 - }
1284 -
1285 - /*
1286 - * need to check current boot config, so fire up the ficl
1287 - * if its xen setup, we add option to boot-args list, not replacing it.
1288 - */
1289 - (void) snprintf(buf, MAX_INPUT, "set currdev=zfs:%s:", mp.mnt_special);
1290 - ret = ficlVmEvaluate(vm, buf);
1291 - if (ret != FICL_VM_STATUS_OUT_OF_TEXT) {
1292 - bam_error(_("Error interpreting boot config\n"));
1293 - bf_fini();
1294 - return (BAM_ERROR);
1295 - }
1296 - (void) snprintf(buf, MAX_INPUT, "include /boot/forth/loader.4th");
1297 - ret = ficlVmEvaluate(vm, buf);
1298 - if (ret != FICL_VM_STATUS_OUT_OF_TEXT) {
1299 - bam_error(_("Error interpreting boot config\n"));
1300 - bf_fini();
1301 - return (BAM_ERROR);
1302 - }
1303 - (void) snprintf(buf, MAX_INPUT, "start");
1304 - ret = ficlVmEvaluate(vm, buf);
1305 - if (ret != FICL_VM_STATUS_OUT_OF_TEXT) {
1306 - bam_error(_("Error interpreting boot config\n"));
1307 - bf_fini();
1308 - return (BAM_ERROR);
1309 - }
1310 - (void) snprintf(buf, MAX_INPUT, "boot");
1311 - ret = ficlVmEvaluate(vm, buf);
1312 - if (ret != FICL_VM_STATUS_OUT_OF_TEXT) {
1313 - bam_error(_("Error interpreting boot config\n"));
1314 - bf_fini();
1315 - return (BAM_ERROR);
1316 - }
1317 - bf_fini();
1318 -
1319 - (void) mkdir(CONF_DIR, 0755);
1320 - (void) snprintf(path, PATH_MAX, "%s" XEN_CONFIG, bam_root);
1321 - fp = fopen(path, "w");
1322 - if (fp == NULL) {
1323 - return (BAM_ERROR); /* error, cant write config */
1324 - }
1325 -
1326 - errno = 0;
1327 - /*
1328 - * on write error, remove file to ensure we have bootable config.
1329 - * note we dont mind if config exists, it will get updated
1330 - */
1331 - (void) fprintf(fp, "xen_kernel=\"/boot/${ISADIR}/xen\"\n");
1332 - if (errno != 0)
1333 - goto error;
1334 -
1335 - /*
1336 - * really simple and stupid console conversion.
1337 - * it really has to be gone, it belongs to milestone/xvm properties.
1338 - */
1339 - env = getenv("console");
1340 - if (env != NULL) {
1341 - if (strcmp(env, "ttya") == 0)
1342 - (void) fprintf(fp, "xen_cmdline=\"console=com1 %s\"\n",
1343 - opt);
1344 - else if (strcmp(env, "ttyb") == 0)
1345 - (void) fprintf(fp, "xen_cmdline=\"console=com2 %s\"\n",
1346 - opt);
1347 - else
1348 - (void) fprintf(fp, "xen_cmdline=\"console=vga %s\"\n",
1349 - opt);
1350 - } else
1351 - (void) fprintf(fp, "xen_cmdline=\"%s\"\n", opt);
1352 - if (errno != 0)
1353 - goto error;
1354 -
1355 - (void) fprintf(fp,
1356 - "bootfile=\"/platform/i86xpv/kernel/${ISADIR}/unix\"\n");
1357 - if (errno != 0)
1358 - goto error;
1359 -
1360 - (void) fprintf(fp,
1361 - "boot-args=\"/platform/i86xpv/kernel/${ISADIR}/unix\"\n");
1362 - if (errno != 0)
1363 - goto error;
1364 -
1365 - (void) fclose(fp);
1366 - if (errno != 0) {
1367 - (void) unlink(path);
1368 - return (BAM_ERROR);
1369 - }
1370 - return (BAM_SUCCESS);
1371 -error:
1372 - (void) fclose(fp);
1373 - (void) unlink(path);
1374 - return (BAM_ERROR);
1375 1141 }
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX