Print this page
9250 remove xpv related code from bootadm


 272 
 273 static int is_amd64(void);
 274 static char *get_machine(void);
 275 static void append_to_flist(filelist_t *, char *);
 276 static int ufs_add_to_sign_list(char *sign);
 277 static error_t synchronize_BE_menu(void);
 278 
 279 #if !defined(_OBP)
 280 static void ucode_install();
 281 #endif
 282 
 283 /* Menu related sub commands */
 284 static subcmd_defn_t menu_subcmds[] = {
 285         "set_option",           OPT_ABSENT,     set_option, 0,  /* PUB */
 286         "list_entry",           OPT_OPTIONAL,   list_entry, 1,  /* PUB */
 287         "delete_all_entries",   OPT_ABSENT,     delete_all_entries, 0, /* PVT */
 288         "update_entry",         OPT_REQ,        update_entry, 0, /* menu */
 289         "update_temp",          OPT_OPTIONAL,   update_temp, 0, /* reboot */
 290         "upgrade",              OPT_ABSENT,     upgrade_menu, 0, /* menu */
 291         "list_setting",         OPT_OPTIONAL,   list_setting, 1, /* menu */
 292         "disable_hypervisor",   OPT_ABSENT,     cvt_to_metal, 0, /* menu */
 293         "enable_hypervisor",    OPT_ABSENT,     cvt_to_hyper, 0, /* menu */
 294         NULL,                   0,              NULL, 0 /* must be last */
 295 };
 296 
 297 /* Archive related sub commands */
 298 static subcmd_defn_t arch_subcmds[] = {
 299         "update",               OPT_ABSENT,     update_archive, 0, /* PUB */
 300         "update_all",           OPT_ABSENT,     update_all, 0,  /* PVT */
 301         "list",                 OPT_OPTIONAL,   list_archive, 1, /* PUB */
 302         NULL,                   0,              NULL, 0 /* must be last */
 303 };
 304 
 305 /* Install related sub commands */
 306 static subcmd_defn_t inst_subcmds[] = {
 307         "install_bootloader",   OPT_ABSENT,     install_bootloader, 0, /* PUB */
 308         NULL,                   0,              NULL, 0 /* must be last */
 309 };
 310 
 311 enum dircache_copy_opt {
 312         FILE32 = 0,
 313         FILE64,


 535                         if (is_grub(bam_alt_root ? bam_root : "/")) {
 536                                 ret = bam_menu(bam_subcmd, bam_opt,
 537                                     bam_argc, bam_argv);
 538                         } else {
 539                                 ret = bam_loader_menu(bam_subcmd, bam_opt,
 540                                     bam_argc, bam_argv);
 541                         }
 542                         break;
 543                 case BAM_ARCHIVE:
 544                         ret = bam_archive(bam_subcmd, bam_opt);
 545                         break;
 546                 case BAM_INSTALL:
 547                         ret = bam_install(bam_subcmd, bam_opt);
 548                         break;
 549                 default:
 550                         usage();
 551                         bam_exit(1);
 552         }
 553 
 554         if (ret != BAM_SUCCESS)
 555                 bam_exit((ret == BAM_NOCHANGE) ? 2 : 1);
 556 
 557         bam_unlock();
 558         return (0);
 559 }
 560 
 561 /*
 562  * Equivalence of public and internal commands:
 563  *      update-archive  -- -a update
 564  *      list-archive    -- -a list
 565  *      set-menu        -- -m set_option
 566  *      list-menu       -- -m list_entry
 567  *      update-menu     -- -m update_entry
 568  *      install-bootloader      -- -i install_bootloader
 569  */
 570 static struct cmd_map {
 571         char *bam_cmdname;
 572         int bam_cmd;
 573         char *bam_subcmd;
 574 } cmd_map[] = {
 575         { "update-archive",     BAM_ARCHIVE,    "update"},


 607                         bam_exit(1);
 608                 }
 609                 argc--;
 610                 argv++;
 611         }
 612 
 613         parse_args_internal(argc, argv);
 614 }
 615 
 616 /*
 617  * A combination of public and private commands are parsed here.
 618  * The internal syntax and the corresponding functionality are:
 619  *      -a update                       -- update-archive
 620  *      -a list                         -- list-archive
 621  *      -a update-all                   -- (reboot to sync all mnted OS archive)
 622  *      -i install_bootloader           -- install-bootloader
 623  *      -m update_entry                 -- update-menu
 624  *      -m list_entry                   -- list-menu
 625  *      -m update_temp                  -- (reboot -- [boot-args])
 626  *      -m delete_all_entries           -- (called from install)
 627  *      -m enable_hypervisor [args]     -- cvt_to_hyper
 628  *      -m disable_hypervisor           -- cvt_to_metal
 629  *      -m list_setting [entry] [value] -- list_setting
 630  *
 631  * A set of private flags is there too:
 632  *      -F              -- purge the cache directories and rebuild them
 633  *      -e              -- use the (faster) archive update approach (used by
 634  *                         reboot)
 635  */
 636 static void
 637 parse_args_internal(int argc, char *argv[])
 638 {
 639         int c, error;
 640         extern char *optarg;
 641         extern int optind, opterr;
 642 #if defined(_OBP)
 643         const char *optstring = "a:d:fi:m:no:veFCR:p:P:XZ";
 644 #else
 645         const char *optstring = "a:d:fi:m:no:veFCMR:p:P:XZ";
 646 #endif
 647 
 648         /* Suppress error message from getopt */


 745                                     optarg, strerror(errno));
 746                                 break;
 747                         }
 748                         bam_alt_root = 1;
 749                         bam_root = rootbuf;
 750                         bam_rootlen = strlen(rootbuf);
 751                         break;
 752                 case 'p':
 753                         bam_alt_platform = 1;
 754                         bam_platform = optarg;
 755                         if ((strcmp(bam_platform, "i86pc") != 0) &&
 756                             (strcmp(bam_platform, "sun4u") != 0) &&
 757                             (strcmp(bam_platform, "sun4v") != 0)) {
 758                                 error = 1;
 759                                 bam_error(_("invalid platform %s - must be "
 760                                     "one of sun4u, sun4v or i86pc\n"),
 761                                     bam_platform);
 762                         }
 763                         break;
 764                 case 'X':
 765                         bam_is_hv = BAM_HV_PRESENT;
 766                         break;
 767                 case 'Z':
 768                         bam_zfs = 1;
 769                         break;
 770                 case 'e':
 771                         bam_extend = 1;
 772                         break;
 773                 case '?':
 774                         error = 1;
 775                         bam_error(_("invalid option or missing option "
 776                             "argument: -%c\n"), optopt);
 777                         break;
 778                 default :
 779                         error = 1;
 780                         bam_error(_("invalid option or missing option "
 781                             "argument: -%c\n"), c);
 782                         break;
 783                 }
 784         }
 785 


 851                         usage();
 852                         return (BAM_ERROR);
 853                 } else if (bam_argc > 1 || bam_argv[1] != NULL) {
 854                         bam_error(_("invalid trailing arguments\n"));
 855                         usage();
 856                         return (BAM_ERROR);
 857                 }
 858         } else if (strcmp(subcmd, "update_all") == 0) {
 859                 /*
 860                  * The only option we accept for the "update_all"
 861                  * subcmd is "fastboot".
 862                  */
 863                 if (bam_argc > 1 || (bam_argc == 1 &&
 864                     strcmp(bam_argv[0], "fastboot") != 0)) {
 865                         bam_error(_("invalid trailing arguments\n"));
 866                         usage();
 867                         return (BAM_ERROR);
 868                 }
 869                 if (bam_argc == 1)
 870                         sync_menu = 0;
 871         } else if (((strcmp(subcmd, "enable_hypervisor") != 0) &&
 872             (strcmp(subcmd, "list_setting") != 0)) && (bam_argc || bam_argv)) {
 873                 /*
 874                  * Of the remaining subcommands, only "enable_hypervisor" and
 875                  * "list_setting" take trailing arguments.
 876                  */
 877                 bam_error(_("invalid trailing arguments\n"));
 878                 usage();
 879                 return (BAM_ERROR);
 880         }
 881 
 882         if (bam_root == NULL) {
 883                 bam_root = rootbuf;
 884                 bam_rootlen = 1;
 885         }
 886 
 887         /* verify that subcmd is valid */
 888         for (i = 0; table[i].subcmd != NULL; i++) {
 889                 if (strcmp(table[i].subcmd, subcmd) == 0)
 890                         break;
 891         }
 892 
 893         if (table[i].subcmd == NULL) {
 894                 bam_error(_("invalid sub-command specified: %s\n"), subcmd);
 895                 return (BAM_ERROR);


1414          */
1415         if (strcmp(subcmd, "list_entry") == 0)
1416                 bam_print(_("the location for the active GRUB menu is: %s\n"),
1417                     menu_path);
1418 
1419         if ((menu = menu_read(menu_path)) == NULL) {
1420                 bam_error(_("cannot find GRUB menu file: %s\n"), menu_path);
1421                 free(special);
1422 
1423                 return (BAM_ERROR);
1424         }
1425 
1426         /*
1427          * We already checked the following case in
1428          * check_subcmd_and_suboptions() above. Complete the
1429          * final step now.
1430          */
1431         if (strcmp(subcmd, "set_option") == 0) {
1432                 assert(largc == 1 && largv[0] && largv[1] == NULL);
1433                 opt = largv[0];
1434         } else if ((strcmp(subcmd, "enable_hypervisor") != 0) &&
1435             (strcmp(subcmd, "list_setting") != 0)) {
1436                 assert(largc == 0 && largv == NULL);
1437         }
1438 
1439         ret = get_boot_cap(bam_root);
1440         if (ret != BAM_SUCCESS) {
1441                 BAM_DPRINTF(("%s: Failed to get boot capability\n", fcn));
1442                 goto out;
1443         }
1444 
1445         /*
1446          * Once the sub-cmd handler has run
1447          * only the line field is guaranteed to have valid values
1448          */
1449         if (strcmp(subcmd, "update_entry") == 0) {
1450                 ret = f(menu, menu_root, osdev);
1451         } else if (strcmp(subcmd, "upgrade") == 0) {
1452                 ret = f(menu, bam_root, menu_root);
1453         } else if (strcmp(subcmd, "list_entry") == 0) {
1454                 ret = f(menu, menu_path, opt);
1455         } else if (strcmp(subcmd, "list_setting") == 0) {
1456                 ret = f(menu, ((largc > 0) ? largv[0] : ""),
1457                     ((largc > 1) ? largv[1] : ""));
1458         } else if (strcmp(subcmd, "disable_hypervisor") == 0) {
1459                 if (is_sparc()) {
1460                         bam_error(_("%s operation unsupported on SPARC "
1461                             "machines\n"), subcmd);
1462                         ret = BAM_ERROR;
1463                 } else {
1464                         ret = f(menu, bam_root, NULL);
1465                 }
1466         } else if (strcmp(subcmd, "enable_hypervisor") == 0) {
1467                 if (is_sparc()) {
1468                         bam_error(_("%s operation unsupported on SPARC "
1469                             "machines\n"), subcmd);
1470                         ret = BAM_ERROR;
1471                 } else {
1472                         char *extra_args = NULL;
1473 
1474                         /*
1475                          * Compress all arguments passed in the largv[] array
1476                          * into one string that can then be appended to the
1477                          * end of the kernel$ string the routine to enable the
1478                          * hypervisor will build.
1479                          *
1480                          * This allows the caller to supply arbitrary unparsed
1481                          * arguments, such as dom0 memory settings or APIC
1482                          * options.
1483                          *
1484                          * This concatenation will be done without ANY syntax
1485                          * checking whatsoever, so it's the responsibility of
1486                          * the caller to make sure the arguments are valid and
1487                          * do not duplicate arguments the conversion routines
1488                          * may create.
1489                          */
1490                         if (largc > 0) {
1491                                 int extra_len, i;
1492 
1493                                 for (extra_len = 0, i = 0; i < largc; i++)
1494                                         extra_len += strlen(largv[i]);
1495 
1496                                 /*
1497                                  * Allocate space for argument strings,
1498                                  * intervening spaces and terminating NULL.
1499                                  */
1500                                 extra_args = alloca(extra_len + largc);
1501 
1502                                 (void) strcpy(extra_args, largv[0]);
1503 
1504                                 for (i = 1; i < largc; i++) {
1505                                         (void) strcat(extra_args, " ");
1506                                         (void) strcat(extra_args, largv[i]);
1507                                 }
1508                         }
1509 
1510                         ret = f(menu, bam_root, extra_args);
1511                 }
1512         } else
1513                 ret = f(menu, NULL, opt);
1514 
1515         if (ret == BAM_WRITE) {
1516                 BAM_DPRINTF(("%s: writing menu to clean-menu-root: <%s>\n",
1517                     fcn, clean_menu_root));
1518                 ret = menu_write(clean_menu_root, menu);
1519         }
1520 
1521 out:
1522         INJECT_ERROR1("POOL_SET", pool = "/pooldata");
1523         assert((is_zfs(menu_root)) ^ (pool == NULL));
1524         if (pool) {
1525                 (void) umount_top_dataset(pool, zmnted, zmntpt);
1526                 free(special);
1527         }
1528         menu_free(menu);
1529         return (ret);
1530 }
1531 


4612         } else if (strncmp(arg, DIRECT_BOOT_FAILSAFE_32,
4613             sizeof (DIRECT_BOOT_FAILSAFE_32) - 1) == 0) {
4614                 BAM_DPRINTF(("%s: setting DBOOT|DBOOT_FAILSAFE|DBOOT_32 "
4615                     "flag: %s\n", fcn, arg));
4616                 entry->flags |= BAM_ENTRY_DBOOT | BAM_ENTRY_FAILSAFE
4617                     | BAM_ENTRY_32BIT;
4618         } else if (strncmp(arg, DIRECT_BOOT_FAILSAFE_64,
4619             sizeof (DIRECT_BOOT_FAILSAFE_64) - 1) == 0) {
4620                 BAM_DPRINTF(("%s: setting DBOOT|DBOOT_FAILSAFE|DBOOT_64 "
4621                     "flag: %s\n", fcn, arg));
4622                 entry->flags |= BAM_ENTRY_DBOOT | BAM_ENTRY_FAILSAFE
4623                     | BAM_ENTRY_64BIT;
4624         } else if (strncmp(arg, MULTI_BOOT, sizeof (MULTI_BOOT) - 1) == 0) {
4625                 BAM_DPRINTF(("%s: setting MULTIBOOT flag: %s\n", fcn, arg));
4626                 entry->flags |= BAM_ENTRY_MULTIBOOT;
4627         } else if (strncmp(arg, MULTI_BOOT_FAILSAFE,
4628             sizeof (MULTI_BOOT_FAILSAFE) - 1) == 0) {
4629                 BAM_DPRINTF(("%s: setting MULTIBOOT|MULTIBOOT_FAILSAFE "
4630                     "flag: %s\n", fcn, arg));
4631                 entry->flags |= BAM_ENTRY_MULTIBOOT | BAM_ENTRY_FAILSAFE;
4632         } else if (strstr(arg, XEN_KERNEL_SUBSTR)) {
4633                 BAM_DPRINTF(("%s: setting XEN HV flag: %s\n", fcn, arg));
4634                 entry->flags |= BAM_ENTRY_HV;
4635         } else if (!(entry->flags & (BAM_ENTRY_BOOTADM|BAM_ENTRY_LU))) {
4636                 BAM_DPRINTF(("%s: is HAND kernel flag: %s\n", fcn, arg));
4637                 return (BAM_ERROR);
4638         } else if (strncmp(arg, KERNEL_PREFIX, strlen(KERNEL_PREFIX)) == 0 &&
4639             strstr(arg, UNIX_SPACE)) {
4640                 entry->flags |= BAM_ENTRY_DBOOT | BAM_ENTRY_32BIT;
4641         } else if (strncmp(arg, KERNEL_PREFIX, strlen(KERNEL_PREFIX)) == 0 &&
4642             strstr(arg, AMD_UNIX_SPACE)) {
4643                 entry->flags |= BAM_ENTRY_DBOOT | BAM_ENTRY_64BIT;
4644         } else {
4645                 BAM_DPRINTF(("%s: is UNKNOWN kernel entry: %s\n", fcn, arg));
4646                 bam_error(_("kernel command on line %d not recognized.\n"),
4647                     linenum);
4648                 return (BAM_ERROR);
4649         }
4650 
4651         return (BAM_SUCCESS);
4652 }
4653 
4654 static error_t
4655 module_parser(entry_t *entry, char *cmd, char *arg, int linenum)
4656 {
4657         const char              *fcn = "module_parser()";
4658 
4659         assert(entry);
4660         assert(cmd);
4661         assert(arg);
4662 
4663         if (strcmp(cmd, menu_cmds[MODULE_CMD]) != 0 &&
4664             strcmp(cmd, menu_cmds[MODULE_DOLLAR_CMD]) != 0) {
4665                 BAM_DPRINTF(("%s: not module cmd: %s\n", fcn, cmd));
4666                 return (BAM_ERROR);
4667         }
4668 
4669         if (strcmp(arg, DIRECT_BOOT_ARCHIVE) == 0 ||
4670             strcmp(arg, DIRECT_BOOT_ARCHIVE_32) == 0 ||
4671             strcmp(arg, DIRECT_BOOT_ARCHIVE_64) == 0 ||
4672             strcmp(arg, MULTIBOOT_ARCHIVE) == 0 ||
4673             strcmp(arg, FAILSAFE_ARCHIVE) == 0 ||
4674             strcmp(arg, FAILSAFE_ARCHIVE_32) == 0 ||
4675             strcmp(arg, FAILSAFE_ARCHIVE_64) == 0 ||
4676             strcmp(arg, XEN_KERNEL_MODULE_LINE) == 0 ||
4677             strcmp(arg, XEN_KERNEL_MODULE_LINE_ZFS) == 0) {
4678                 BAM_DPRINTF(("%s: bootadm or LU module cmd: %s\n", fcn, arg));
4679                 return (BAM_SUCCESS);
4680         } else if (!(entry->flags & BAM_ENTRY_BOOTADM) &&
4681             !(entry->flags & BAM_ENTRY_LU)) {
4682                 /* don't emit warning for hand entries */
4683                 BAM_DPRINTF(("%s: is HAND module: %s\n", fcn, arg));
4684                 return (BAM_ERROR);
4685         } else {
4686                 BAM_DPRINTF(("%s: is UNKNOWN module: %s\n", fcn, arg));
4687                 bam_error(_("module command on line %d not recognized.\n"),
4688                     linenum);
4689                 return (BAM_ERROR);
4690         }
4691 }
4692 
4693 /*
4694  * A line in menu.lst looks like
4695  * [ ]*<cmd>[ \t=]*<arg>*
4696  */
4697 static void


8236                 if (lp == NULL || lp->next == NULL) {
8237                         continue;
8238                 }
8239 
8240                 if (kernel &&
8241                     (!check_cmd(lp->cmd, KERNEL_CMD, lp->arg, kernel))) {
8242                         if (!(ent->flags & BAM_ENTRY_FAILSAFE) ||
8243                             !(ent->flags & BAM_ENTRY_DBOOT) ||
8244                             strcmp(kernel, DIRECT_BOOT_FAILSAFE_LINE) != 0)
8245                                 continue;
8246 
8247                         ent->flags |= BAM_ENTRY_UPGFSKERNEL;
8248 
8249                 }
8250                 BAM_DPRINTF(("%s: kernel match: %s, %s\n", fcn,
8251                     kernel, lp->arg));
8252 
8253                 /*
8254                  * Check for matching module entry (failsafe or normal).
8255                  * If it fails to match, we go around the loop again.
8256                  * For xpv entries, there are two module lines, so we
8257                  * do the check twice.
8258                  */
8259                 lp = lp->next;       /* advance to module line */
8260                 if (check_cmd(lp->cmd, MODULE_CMD, lp->arg, module) ||
8261                     (((lp = lp->next) != NULL) &&
8262                     check_cmd(lp->cmd, MODULE_CMD, lp->arg, module))) {
8263                         /* match found */
8264                         BAM_DPRINTF(("%s: module match: %s, %s\n", fcn,
8265                             module, lp->arg));
8266                         break;
8267                 }
8268 
8269                 if (strcmp(module, FAILSAFE_ARCHIVE) == 0 &&
8270                     (strcmp(lp->prev->arg, FAILSAFE_ARCHIVE_32) == 0 ||
8271                     strcmp(lp->prev->arg, FAILSAFE_ARCHIVE_64) == 0)) {
8272                         ent->flags |= BAM_ENTRY_UPGFSMODULE;
8273                         break;
8274                 }
8275 
8276         }
8277 
8278         if (ent && entry_num) {
8279                 *entry_num = i;
8280         }
8281 
8282         if (ent) {


8571         grubroot = get_grubroot(osroot, osdev, menu_root);
8572         INJECT_ERROR1("GET_GRUBROOT_FAIL", grubroot = NULL);
8573         if (grubroot) {
8574                 BAM_DPRINTF(("%s: get_grubroot success. osroot=%s, osdev=%s, "
8575                     "menu_root=%s\n", fcn, osroot, osdev, menu_root));
8576         } else {
8577                 BAM_DPRINTF(("%s: get_grubroot failed. osroot=%s, osdev=%s, "
8578                     "menu_root=%s\n", fcn, osroot, osdev, menu_root));
8579         }
8580 
8581         /* add the entry for normal Solaris */
8582         INJECT_ERROR1("UPDATE_ENTRY_MULTIBOOT",
8583             bam_direct = BAM_DIRECT_MULTIBOOT);
8584         if (bam_direct == BAM_DIRECT_DBOOT) {
8585                 entry = update_boot_entry(mp, title, grubsign, grubroot,
8586                     (bam_zfs ? DIRECT_BOOT_KERNEL_ZFS : DIRECT_BOOT_KERNEL),
8587                     NULL, DIRECT_BOOT_ARCHIVE,
8588                     root_optional(osroot, menu_root));
8589                 BAM_DPRINTF(("%s: updated boot entry bam_zfs=%d, "
8590                     "grubsign = %s\n", fcn, bam_zfs, grubsign));
8591                 if ((entry != BAM_ERROR) && (bam_is_hv == BAM_HV_PRESENT)) {
8592                         (void) update_boot_entry(mp, NEW_HV_ENTRY, grubsign,
8593                             grubroot, XEN_MENU, bam_zfs ?
8594                             XEN_KERNEL_MODULE_LINE_ZFS : XEN_KERNEL_MODULE_LINE,
8595                             DIRECT_BOOT_ARCHIVE,
8596                             root_optional(osroot, menu_root));
8597                         BAM_DPRINTF(("%s: updated HV entry bam_zfs=%d, "
8598                             "grubsign = %s\n", fcn, bam_zfs, grubsign));
8599                 }
8600         } else {
8601                 entry = update_boot_entry(mp, title, grubsign, grubroot,
8602                     MULTI_BOOT, NULL, MULTIBOOT_ARCHIVE,
8603                     root_optional(osroot, menu_root));
8604 
8605                 BAM_DPRINTF(("%s: updated MULTIBOOT entry grubsign = %s\n",
8606                     fcn, grubsign));
8607         }
8608 
8609         /*
8610          * Add the entry for failsafe archive.  On a bfu'd system, the
8611          * failsafe may be different than the installed kernel.
8612          */
8613         (void) snprintf(failsafe, sizeof (failsafe), "%s%s",
8614             osroot, FAILSAFE_ARCHIVE_32);
8615         (void) snprintf(failsafe_64, sizeof (failsafe_64), "%s%s",
8616             osroot, FAILSAFE_ARCHIVE_64);
8617 
8618         /*
8619          * Check if at least one of the two archives exists
8620          * Using $ISADIR as the default line, we have an entry which works
8621          * for both the cases.
8622          */
8623 
8624         if (stat(failsafe, &sbuf) == 0 || stat(failsafe_64, &sbuf) == 0) {




 272 
 273 static int is_amd64(void);
 274 static char *get_machine(void);
 275 static void append_to_flist(filelist_t *, char *);
 276 static int ufs_add_to_sign_list(char *sign);
 277 static error_t synchronize_BE_menu(void);
 278 
 279 #if !defined(_OBP)
 280 static void ucode_install();
 281 #endif
 282 
 283 /* Menu related sub commands */
 284 static subcmd_defn_t menu_subcmds[] = {
 285         "set_option",           OPT_ABSENT,     set_option, 0,  /* PUB */
 286         "list_entry",           OPT_OPTIONAL,   list_entry, 1,  /* PUB */
 287         "delete_all_entries",   OPT_ABSENT,     delete_all_entries, 0, /* PVT */
 288         "update_entry",         OPT_REQ,        update_entry, 0, /* menu */
 289         "update_temp",          OPT_OPTIONAL,   update_temp, 0, /* reboot */
 290         "upgrade",              OPT_ABSENT,     upgrade_menu, 0, /* menu */
 291         "list_setting",         OPT_OPTIONAL,   list_setting, 1, /* menu */


 292         NULL,                   0,              NULL, 0 /* must be last */
 293 };
 294 
 295 /* Archive related sub commands */
 296 static subcmd_defn_t arch_subcmds[] = {
 297         "update",               OPT_ABSENT,     update_archive, 0, /* PUB */
 298         "update_all",           OPT_ABSENT,     update_all, 0,  /* PVT */
 299         "list",                 OPT_OPTIONAL,   list_archive, 1, /* PUB */
 300         NULL,                   0,              NULL, 0 /* must be last */
 301 };
 302 
 303 /* Install related sub commands */
 304 static subcmd_defn_t inst_subcmds[] = {
 305         "install_bootloader",   OPT_ABSENT,     install_bootloader, 0, /* PUB */
 306         NULL,                   0,              NULL, 0 /* must be last */
 307 };
 308 
 309 enum dircache_copy_opt {
 310         FILE32 = 0,
 311         FILE64,


 533                         if (is_grub(bam_alt_root ? bam_root : "/")) {
 534                                 ret = bam_menu(bam_subcmd, bam_opt,
 535                                     bam_argc, bam_argv);
 536                         } else {
 537                                 ret = bam_loader_menu(bam_subcmd, bam_opt,
 538                                     bam_argc, bam_argv);
 539                         }
 540                         break;
 541                 case BAM_ARCHIVE:
 542                         ret = bam_archive(bam_subcmd, bam_opt);
 543                         break;
 544                 case BAM_INSTALL:
 545                         ret = bam_install(bam_subcmd, bam_opt);
 546                         break;
 547                 default:
 548                         usage();
 549                         bam_exit(1);
 550         }
 551 
 552         if (ret != BAM_SUCCESS)
 553                 bam_exit(1);
 554 
 555         bam_unlock();
 556         return (0);
 557 }
 558 
 559 /*
 560  * Equivalence of public and internal commands:
 561  *      update-archive  -- -a update
 562  *      list-archive    -- -a list
 563  *      set-menu        -- -m set_option
 564  *      list-menu       -- -m list_entry
 565  *      update-menu     -- -m update_entry
 566  *      install-bootloader      -- -i install_bootloader
 567  */
 568 static struct cmd_map {
 569         char *bam_cmdname;
 570         int bam_cmd;
 571         char *bam_subcmd;
 572 } cmd_map[] = {
 573         { "update-archive",     BAM_ARCHIVE,    "update"},


 605                         bam_exit(1);
 606                 }
 607                 argc--;
 608                 argv++;
 609         }
 610 
 611         parse_args_internal(argc, argv);
 612 }
 613 
 614 /*
 615  * A combination of public and private commands are parsed here.
 616  * The internal syntax and the corresponding functionality are:
 617  *      -a update                       -- update-archive
 618  *      -a list                         -- list-archive
 619  *      -a update-all                   -- (reboot to sync all mnted OS archive)
 620  *      -i install_bootloader           -- install-bootloader
 621  *      -m update_entry                 -- update-menu
 622  *      -m list_entry                   -- list-menu
 623  *      -m update_temp                  -- (reboot -- [boot-args])
 624  *      -m delete_all_entries           -- (called from install)


 625  *      -m list_setting [entry] [value] -- list_setting
 626  *
 627  * A set of private flags is there too:
 628  *      -F              -- purge the cache directories and rebuild them
 629  *      -e              -- use the (faster) archive update approach (used by
 630  *                         reboot)
 631  */
 632 static void
 633 parse_args_internal(int argc, char *argv[])
 634 {
 635         int c, error;
 636         extern char *optarg;
 637         extern int optind, opterr;
 638 #if defined(_OBP)
 639         const char *optstring = "a:d:fi:m:no:veFCR:p:P:XZ";
 640 #else
 641         const char *optstring = "a:d:fi:m:no:veFCMR:p:P:XZ";
 642 #endif
 643 
 644         /* Suppress error message from getopt */


 741                                     optarg, strerror(errno));
 742                                 break;
 743                         }
 744                         bam_alt_root = 1;
 745                         bam_root = rootbuf;
 746                         bam_rootlen = strlen(rootbuf);
 747                         break;
 748                 case 'p':
 749                         bam_alt_platform = 1;
 750                         bam_platform = optarg;
 751                         if ((strcmp(bam_platform, "i86pc") != 0) &&
 752                             (strcmp(bam_platform, "sun4u") != 0) &&
 753                             (strcmp(bam_platform, "sun4v") != 0)) {
 754                                 error = 1;
 755                                 bam_error(_("invalid platform %s - must be "
 756                                     "one of sun4u, sun4v or i86pc\n"),
 757                                     bam_platform);
 758                         }
 759                         break;
 760                 case 'X':
 761                         /* obsolete */
 762                         break;
 763                 case 'Z':
 764                         bam_zfs = 1;
 765                         break;
 766                 case 'e':
 767                         bam_extend = 1;
 768                         break;
 769                 case '?':
 770                         error = 1;
 771                         bam_error(_("invalid option or missing option "
 772                             "argument: -%c\n"), optopt);
 773                         break;
 774                 default :
 775                         error = 1;
 776                         bam_error(_("invalid option or missing option "
 777                             "argument: -%c\n"), c);
 778                         break;
 779                 }
 780         }
 781 


 847                         usage();
 848                         return (BAM_ERROR);
 849                 } else if (bam_argc > 1 || bam_argv[1] != NULL) {
 850                         bam_error(_("invalid trailing arguments\n"));
 851                         usage();
 852                         return (BAM_ERROR);
 853                 }
 854         } else if (strcmp(subcmd, "update_all") == 0) {
 855                 /*
 856                  * The only option we accept for the "update_all"
 857                  * subcmd is "fastboot".
 858                  */
 859                 if (bam_argc > 1 || (bam_argc == 1 &&
 860                     strcmp(bam_argv[0], "fastboot") != 0)) {
 861                         bam_error(_("invalid trailing arguments\n"));
 862                         usage();
 863                         return (BAM_ERROR);
 864                 }
 865                 if (bam_argc == 1)
 866                         sync_menu = 0;
 867         } else if (strcmp(subcmd, "list_setting") != 0 &&
 868             (bam_argc || bam_argv)) {
 869                 /*
 870                  * Of the remaining subcommands, only "list_setting" takes
 871                  * trailing arguments.
 872                  */
 873                 bam_error(_("invalid trailing arguments\n"));
 874                 usage();
 875                 return (BAM_ERROR);
 876         }
 877 
 878         if (bam_root == NULL) {
 879                 bam_root = rootbuf;
 880                 bam_rootlen = 1;
 881         }
 882 
 883         /* verify that subcmd is valid */
 884         for (i = 0; table[i].subcmd != NULL; i++) {
 885                 if (strcmp(table[i].subcmd, subcmd) == 0)
 886                         break;
 887         }
 888 
 889         if (table[i].subcmd == NULL) {
 890                 bam_error(_("invalid sub-command specified: %s\n"), subcmd);
 891                 return (BAM_ERROR);


1410          */
1411         if (strcmp(subcmd, "list_entry") == 0)
1412                 bam_print(_("the location for the active GRUB menu is: %s\n"),
1413                     menu_path);
1414 
1415         if ((menu = menu_read(menu_path)) == NULL) {
1416                 bam_error(_("cannot find GRUB menu file: %s\n"), menu_path);
1417                 free(special);
1418 
1419                 return (BAM_ERROR);
1420         }
1421 
1422         /*
1423          * We already checked the following case in
1424          * check_subcmd_and_suboptions() above. Complete the
1425          * final step now.
1426          */
1427         if (strcmp(subcmd, "set_option") == 0) {
1428                 assert(largc == 1 && largv[0] && largv[1] == NULL);
1429                 opt = largv[0];
1430         } else if (strcmp(subcmd, "list_setting") != 0) {

1431                 assert(largc == 0 && largv == NULL);
1432         }
1433 
1434         ret = get_boot_cap(bam_root);
1435         if (ret != BAM_SUCCESS) {
1436                 BAM_DPRINTF(("%s: Failed to get boot capability\n", fcn));
1437                 goto out;
1438         }
1439 
1440         /*
1441          * Once the sub-cmd handler has run
1442          * only the line field is guaranteed to have valid values
1443          */
1444         if (strcmp(subcmd, "update_entry") == 0) {
1445                 ret = f(menu, menu_root, osdev);
1446         } else if (strcmp(subcmd, "upgrade") == 0) {
1447                 ret = f(menu, bam_root, menu_root);
1448         } else if (strcmp(subcmd, "list_entry") == 0) {
1449                 ret = f(menu, menu_path, opt);
1450         } else if (strcmp(subcmd, "list_setting") == 0) {
1451                 ret = f(menu, ((largc > 0) ? largv[0] : ""),
1452                     ((largc > 1) ? largv[1] : ""));






















































1453         } else
1454                 ret = f(menu, NULL, opt);
1455 
1456         if (ret == BAM_WRITE) {
1457                 BAM_DPRINTF(("%s: writing menu to clean-menu-root: <%s>\n",
1458                     fcn, clean_menu_root));
1459                 ret = menu_write(clean_menu_root, menu);
1460         }
1461 
1462 out:
1463         INJECT_ERROR1("POOL_SET", pool = "/pooldata");
1464         assert((is_zfs(menu_root)) ^ (pool == NULL));
1465         if (pool) {
1466                 (void) umount_top_dataset(pool, zmnted, zmntpt);
1467                 free(special);
1468         }
1469         menu_free(menu);
1470         return (ret);
1471 }
1472 


4553         } else if (strncmp(arg, DIRECT_BOOT_FAILSAFE_32,
4554             sizeof (DIRECT_BOOT_FAILSAFE_32) - 1) == 0) {
4555                 BAM_DPRINTF(("%s: setting DBOOT|DBOOT_FAILSAFE|DBOOT_32 "
4556                     "flag: %s\n", fcn, arg));
4557                 entry->flags |= BAM_ENTRY_DBOOT | BAM_ENTRY_FAILSAFE
4558                     | BAM_ENTRY_32BIT;
4559         } else if (strncmp(arg, DIRECT_BOOT_FAILSAFE_64,
4560             sizeof (DIRECT_BOOT_FAILSAFE_64) - 1) == 0) {
4561                 BAM_DPRINTF(("%s: setting DBOOT|DBOOT_FAILSAFE|DBOOT_64 "
4562                     "flag: %s\n", fcn, arg));
4563                 entry->flags |= BAM_ENTRY_DBOOT | BAM_ENTRY_FAILSAFE
4564                     | BAM_ENTRY_64BIT;
4565         } else if (strncmp(arg, MULTI_BOOT, sizeof (MULTI_BOOT) - 1) == 0) {
4566                 BAM_DPRINTF(("%s: setting MULTIBOOT flag: %s\n", fcn, arg));
4567                 entry->flags |= BAM_ENTRY_MULTIBOOT;
4568         } else if (strncmp(arg, MULTI_BOOT_FAILSAFE,
4569             sizeof (MULTI_BOOT_FAILSAFE) - 1) == 0) {
4570                 BAM_DPRINTF(("%s: setting MULTIBOOT|MULTIBOOT_FAILSAFE "
4571                     "flag: %s\n", fcn, arg));
4572                 entry->flags |= BAM_ENTRY_MULTIBOOT | BAM_ENTRY_FAILSAFE;



4573         } else if (!(entry->flags & (BAM_ENTRY_BOOTADM|BAM_ENTRY_LU))) {
4574                 BAM_DPRINTF(("%s: is HAND kernel flag: %s\n", fcn, arg));
4575                 return (BAM_ERROR);
4576         } else if (strncmp(arg, KERNEL_PREFIX, strlen(KERNEL_PREFIX)) == 0 &&
4577             strstr(arg, UNIX_SPACE)) {
4578                 entry->flags |= BAM_ENTRY_DBOOT | BAM_ENTRY_32BIT;
4579         } else if (strncmp(arg, KERNEL_PREFIX, strlen(KERNEL_PREFIX)) == 0 &&
4580             strstr(arg, AMD_UNIX_SPACE)) {
4581                 entry->flags |= BAM_ENTRY_DBOOT | BAM_ENTRY_64BIT;
4582         } else {
4583                 BAM_DPRINTF(("%s: is UNKNOWN kernel entry: %s\n", fcn, arg));
4584                 bam_error(_("kernel command on line %d not recognized.\n"),
4585                     linenum);
4586                 return (BAM_ERROR);
4587         }
4588 
4589         return (BAM_SUCCESS);
4590 }
4591 
4592 static error_t
4593 module_parser(entry_t *entry, char *cmd, char *arg, int linenum)
4594 {
4595         const char              *fcn = "module_parser()";
4596 
4597         assert(entry);
4598         assert(cmd);
4599         assert(arg);
4600 
4601         if (strcmp(cmd, menu_cmds[MODULE_CMD]) != 0 &&
4602             strcmp(cmd, menu_cmds[MODULE_DOLLAR_CMD]) != 0) {
4603                 BAM_DPRINTF(("%s: not module cmd: %s\n", fcn, cmd));
4604                 return (BAM_ERROR);
4605         }
4606 
4607         if (strcmp(arg, DIRECT_BOOT_ARCHIVE) == 0 ||
4608             strcmp(arg, DIRECT_BOOT_ARCHIVE_32) == 0 ||
4609             strcmp(arg, DIRECT_BOOT_ARCHIVE_64) == 0 ||
4610             strcmp(arg, MULTIBOOT_ARCHIVE) == 0 ||
4611             strcmp(arg, FAILSAFE_ARCHIVE) == 0 ||
4612             strcmp(arg, FAILSAFE_ARCHIVE_32) == 0 ||
4613             strcmp(arg, FAILSAFE_ARCHIVE_64) == 0) {


4614                 BAM_DPRINTF(("%s: bootadm or LU module cmd: %s\n", fcn, arg));
4615                 return (BAM_SUCCESS);
4616         } else if (!(entry->flags & BAM_ENTRY_BOOTADM) &&
4617             !(entry->flags & BAM_ENTRY_LU)) {
4618                 /* don't emit warning for hand entries */
4619                 BAM_DPRINTF(("%s: is HAND module: %s\n", fcn, arg));
4620                 return (BAM_ERROR);
4621         } else {
4622                 BAM_DPRINTF(("%s: is UNKNOWN module: %s\n", fcn, arg));
4623                 bam_error(_("module command on line %d not recognized.\n"),
4624                     linenum);
4625                 return (BAM_ERROR);
4626         }
4627 }
4628 
4629 /*
4630  * A line in menu.lst looks like
4631  * [ ]*<cmd>[ \t=]*<arg>*
4632  */
4633 static void


8172                 if (lp == NULL || lp->next == NULL) {
8173                         continue;
8174                 }
8175 
8176                 if (kernel &&
8177                     (!check_cmd(lp->cmd, KERNEL_CMD, lp->arg, kernel))) {
8178                         if (!(ent->flags & BAM_ENTRY_FAILSAFE) ||
8179                             !(ent->flags & BAM_ENTRY_DBOOT) ||
8180                             strcmp(kernel, DIRECT_BOOT_FAILSAFE_LINE) != 0)
8181                                 continue;
8182 
8183                         ent->flags |= BAM_ENTRY_UPGFSKERNEL;
8184 
8185                 }
8186                 BAM_DPRINTF(("%s: kernel match: %s, %s\n", fcn,
8187                     kernel, lp->arg));
8188 
8189                 /*
8190                  * Check for matching module entry (failsafe or normal).
8191                  * If it fails to match, we go around the loop again.


8192                  */
8193                 lp = lp->next;       /* advance to module line */
8194                 if (check_cmd(lp->cmd, MODULE_CMD, lp->arg, module)) {


8195                         /* match found */
8196                         BAM_DPRINTF(("%s: module match: %s, %s\n", fcn,
8197                             module, lp->arg));
8198                         break;
8199                 }
8200 
8201                 if (strcmp(module, FAILSAFE_ARCHIVE) == 0 &&
8202                     (strcmp(lp->prev->arg, FAILSAFE_ARCHIVE_32) == 0 ||
8203                     strcmp(lp->prev->arg, FAILSAFE_ARCHIVE_64) == 0)) {
8204                         ent->flags |= BAM_ENTRY_UPGFSMODULE;
8205                         break;
8206                 }
8207 
8208         }
8209 
8210         if (ent && entry_num) {
8211                 *entry_num = i;
8212         }
8213 
8214         if (ent) {


8503         grubroot = get_grubroot(osroot, osdev, menu_root);
8504         INJECT_ERROR1("GET_GRUBROOT_FAIL", grubroot = NULL);
8505         if (grubroot) {
8506                 BAM_DPRINTF(("%s: get_grubroot success. osroot=%s, osdev=%s, "
8507                     "menu_root=%s\n", fcn, osroot, osdev, menu_root));
8508         } else {
8509                 BAM_DPRINTF(("%s: get_grubroot failed. osroot=%s, osdev=%s, "
8510                     "menu_root=%s\n", fcn, osroot, osdev, menu_root));
8511         }
8512 
8513         /* add the entry for normal Solaris */
8514         INJECT_ERROR1("UPDATE_ENTRY_MULTIBOOT",
8515             bam_direct = BAM_DIRECT_MULTIBOOT);
8516         if (bam_direct == BAM_DIRECT_DBOOT) {
8517                 entry = update_boot_entry(mp, title, grubsign, grubroot,
8518                     (bam_zfs ? DIRECT_BOOT_KERNEL_ZFS : DIRECT_BOOT_KERNEL),
8519                     NULL, DIRECT_BOOT_ARCHIVE,
8520                     root_optional(osroot, menu_root));
8521                 BAM_DPRINTF(("%s: updated boot entry bam_zfs=%d, "
8522                     "grubsign = %s\n", fcn, bam_zfs, grubsign));









8523         } else {
8524                 entry = update_boot_entry(mp, title, grubsign, grubroot,
8525                     MULTI_BOOT, NULL, MULTIBOOT_ARCHIVE,
8526                     root_optional(osroot, menu_root));

8527                 BAM_DPRINTF(("%s: updated MULTIBOOT entry grubsign = %s\n",
8528                     fcn, grubsign));
8529         }
8530 
8531         /*
8532          * Add the entry for failsafe archive.  On a bfu'd system, the
8533          * failsafe may be different than the installed kernel.
8534          */
8535         (void) snprintf(failsafe, sizeof (failsafe), "%s%s",
8536             osroot, FAILSAFE_ARCHIVE_32);
8537         (void) snprintf(failsafe_64, sizeof (failsafe_64), "%s%s",
8538             osroot, FAILSAFE_ARCHIVE_64);
8539 
8540         /*
8541          * Check if at least one of the two archives exists
8542          * Using $ISADIR as the default line, we have an entry which works
8543          * for both the cases.
8544          */
8545 
8546         if (stat(failsafe, &sbuf) == 0 || stat(failsafe_64, &sbuf) == 0) {