Print this page
bug fix
adding functionality and fixing bugs
adding functions to menuadm
menuadm to replace bootadm menu interaction
hypervisor + bug fix


   6  * You may not use this file except in compliance with the License.
   7  *
   8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
   9  * or http://www.opensolaris.org/os/licensing.
  10  * See the License for the specific language governing permissions
  11  * and limitations under the License.
  12  *
  13  * When distributing Covered Code, include this CDDL HEADER in each
  14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
  15  * If applicable, add the following below this CDDL HEADER, with the
  16  * fields enclosed by brackets "[]" replaced with your own identifying
  17  * information: Portions Copyright [yyyy] [name of copyright owner]
  18  *
  19  * CDDL HEADER END
  20  */
  21 
  22 /*
  23  * Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved.
  24  */
  25 




  26 #include <stdio.h>
  27 #include <errno.h>
  28 #include <stdlib.h>
  29 #include <string.h>
  30 #include <unistd.h>
  31 #include <alloca.h>
  32 #include <ctype.h>
  33 #include <sys/types.h>
  34 
  35 #include "message.h"
  36 #include "bootadm.h"
  37 
  38 #define HYPER_KERNEL_DIR                "/platform/i86xpv/kernel"
  39 #define METAL_KERNEL_DIR                "/platform/i86pc/kernel"
  40 
  41 #define BOOTRC_FILE                     "/boot/solaris/bootenv.rc"
  42 #define ZFS_BOOTSTR                     "$ZFS-BOOTFS"
  43 
  44 #define BFLAG                           "-B"
  45 #define DEFAULT_SERIAL                  "9600,8,n,1"
  46 
  47 #define TTYXMODE_TO_COMNUM(ttyxmode)    ((int)(*((ttyxmode) + 3) - '`'))
  48 #define COMNAME_TO_COMNUM(comname)      ((int)(*((comname) + 3) - '0'))
  49 
  50 #define WHITESPC(x)                     (x)
  51 
  52 static char *serial_config[2] = { NULL, NULL };
  53 static char *console_dev = NULL;
  54 
  55 static char *bootenv_rc_serial[2] = { NULL, NULL };
  56 static char *bootenv_rc_console = NULL;
  57 
  58 static unsigned zfs_boot = 0;
  59 
  60 /*
  61  * Append the string pointed to by "str" to the string pointed to by "orig"
  62  * adding the delimeter "delim" in between.


 746 
 747         (void) fclose(fp);
 748 }
 749 
 750 error_t
 751 cvt_to_hyper(menu_t *mp, char *osroot, char *extra_args)
 752 {
 753         const char *fcn = "cvt_to_hyper()";
 754 
 755         line_t *lp;
 756         entry_t *ent;
 757         size_t len, zfslen;
 758 
 759         char *newstr;
 760         char *osdev;
 761 
 762         char *title = NULL;
 763         char *findroot = NULL;
 764         char *bootfs = NULL;
 765         char *kernel = NULL;

 766         char *mod_kernel = NULL;
 767         char *module = NULL;

 768 
 769         char *kern_path = NULL;
 770         char *kern_bargs = NULL;
 771 
 772         int curdef, newdef;
 773         int kp_allocated = 0;
 774         int ret = BAM_ERROR;
 775 
 776         assert(osroot);
 777 
 778         BAM_DPRINTF((D_FUNC_ENTRY2, fcn, osroot, extra_args));
 779 
 780         /*
 781          * First just check to verify osroot is a sane directory.
 782          */
 783         if ((osdev = get_special(osroot)) == NULL) {
 784                 bam_error(CANT_FIND_SPECIAL, osroot);
 785                 return (BAM_ERROR);
 786         }
 787 


 824 
 825         if (bootenv_rc_console != NULL)
 826                 console_metal_to_hyper(bootenv_rc_console);
 827 
 828         if (bootenv_rc_serial[0] != NULL)
 829                 (void) serial_metal_to_hyper("ttya-mode", bootenv_rc_serial[0]);
 830 
 831         if (bootenv_rc_serial[1] != NULL)
 832                 (void) serial_metal_to_hyper("ttyb-mode", bootenv_rc_serial[1]);
 833 
 834         /*
 835          * Now process the entry itself.
 836          */
 837         for (lp = ent->start; lp != NULL; lp = lp->next) {
 838                 /*
 839                  * Process important lines from menu.lst boot entry.
 840                  */
 841                 if (lp->flags == BAM_TITLE) {
 842                         title = strdupa(lp->arg);
 843                 } else if (lp->cmd != NULL) {
 844                         if (strcmp(lp->cmd, "findroot") == 0) {
 845                                 findroot = strdupa(lp->arg);
 846                         } else if (strcmp(lp->cmd, "bootfs") == 0) {
 847                                 bootfs = strdupa(lp->arg);


 848                         } else if (strcmp(lp->cmd,
 849                             menu_cmds[MODULE_DOLLAR_CMD]) == 0) {
 850                                 module = strdupa(lp->arg);
 851                         } else if ((strcmp(lp->cmd,
 852                             menu_cmds[KERNEL_DOLLAR_CMD]) == 0) &&
 853                             (ret = cvt_metal_kernel(lp->arg,
 854                             &kern_path)) != 0) {
 855                                 if (ret < 0) {
 856                                         ret = BAM_ERROR;
 857                                         bam_error(KERNEL_NOT_PARSEABLE, curdef);
 858                                 } else
 859                                         ret = BAM_NOCHANGE;
 860 
 861                                 goto abort;
 862                         }
 863                 }
 864 
 865                 if (lp == ent->end)
 866                         break;
 867         }
 868 

 869         /*
 870          * If findroot, module or kern_path are NULL, the boot entry is
 871          * malformed.
 872          */
 873         if (findroot == NULL) {
 874                 bam_error(FINDROOT_NOT_FOUND, curdef);
 875                 goto abort;
 876         }
 877 
 878         if (module == NULL) {
 879                 bam_error(MODULE_NOT_PARSEABLE, curdef);
 880                 goto abort;
 881         }
 882 
 883         if (kern_path == NULL) {
 884                 bam_error(KERNEL_NOT_FOUND, curdef);
 885                 goto abort;
 886         }
 887 
 888         /* assemble new kernel and module arguments from parsed values */


 931         if ((strcmp(kern_path, DIRECT_BOOT_32) == 0) ||
 932             (strcmp(kern_path, DIRECT_BOOT_64) == 0)) {
 933                 kern_path = HYPERVISOR_KERNEL;
 934         } else {
 935                 newstr = modify_path(kern_path, METAL_KERNEL_DIR,
 936                     HYPER_KERNEL_DIR);
 937                 free(kern_path);
 938                 kern_path = newstr;
 939                 kp_allocated = 1;
 940         }
 941 
 942         /*
 943          * We need to allocate space for the kernel path (twice) plus an
 944          * intervening space, possibly the ZFS boot string, and NULL,
 945          * of course.
 946          */
 947         len = (strlen(kern_path) * 2) + WHITESPC(1) + 1;
 948         zfslen = (zfs_boot ? (WHITESPC(1) + strlen(ZFS_BOOT)) : 0);
 949 
 950         mod_kernel = alloca(len + zfslen);



 951         (void) snprintf(mod_kernel, len, "%s %s", kern_path, kern_path);
 952 
 953         if (kp_allocated)
 954                 free(kern_path);
 955 
 956         if (zfs_boot) {
 957                 char *zfsstr = alloca(zfslen + 1);
 958 
 959                 (void) snprintf(zfsstr, zfslen + 1, " %s", ZFS_BOOT);
 960                 (void) strcat(mod_kernel, zfsstr);
 961         }
 962 
 963         /* shut off warning messages from the entry line parser */
 964         if (ent->flags & BAM_ENTRY_BOOTADM)
 965                 ent->flags &= ~BAM_ENTRY_BOOTADM;
 966 
 967         BAM_DPRINTF((D_CVT_CMD_KERN_DOLLAR, fcn, kernel));
 968         BAM_DPRINTF((D_CVT_CMD_MOD_DOLLAR, fcn, mod_kernel));
 969 
 970         if ((newdef = add_boot_entry(mp, title, findroot, kernel, mod_kernel,


1045         for (ent = mp->entries; ((ent != NULL) && (ent->entryNum != curdef));
1046             ent = ent->next)
1047                 ;
1048 
1049         /* couldn't find it, so error out */
1050         if (ent == NULL) {
1051                 bam_error(CANT_FIND_DEFAULT, curdef);
1052                 goto abort;
1053         }
1054 
1055         /*
1056          * Now process the entry itself.
1057          */
1058         for (lp = ent->start; lp != NULL; lp = lp->next) {
1059                 /*
1060                  * Process important lines from menu.lst boot entry.
1061                  */
1062                 if (lp->flags == BAM_TITLE) {
1063                         title = strdupa(lp->arg);
1064                 } else if (lp->cmd != NULL) {
1065                         if (strcmp(lp->cmd, "findroot") == 0) {
1066                                 findroot = strdupa(lp->arg);
1067                         } else if (strcmp(lp->cmd, "bootfs") == 0) {
1068                                 bootfs = strdupa(lp->arg);
1069                         } else if (strcmp(lp->cmd,
1070                             menu_cmds[MODULE_DOLLAR_CMD]) == 0) {
1071                                 if (strstr(lp->arg, "boot_archive") == NULL) {
1072                                         module = strdupa(lp->arg);
1073                                         cvt_hyper_module(module, &kern_path);
1074                                 } else {
1075                                         barchive_path = strdupa(lp->arg);
1076                                 }
1077                         } else if ((strcmp(lp->cmd,
1078                             menu_cmds[KERNEL_DOLLAR_CMD]) == 0) &&
1079                             (cvt_hyper_kernel(lp->arg) < 0)) {
1080                                 ret = BAM_NOCHANGE;
1081                                 goto abort;
1082                         }
1083                 }
1084 
1085                 if (lp == ent->end)
1086                         break;
1087         }




   6  * You may not use this file except in compliance with the License.
   7  *
   8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
   9  * or http://www.opensolaris.org/os/licensing.
  10  * See the License for the specific language governing permissions
  11  * and limitations under the License.
  12  *
  13  * When distributing Covered Code, include this CDDL HEADER in each
  14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
  15  * If applicable, add the following below this CDDL HEADER, with the
  16  * fields enclosed by brackets "[]" replaced with your own identifying
  17  * information: Portions Copyright [yyyy] [name of copyright owner]
  18  *
  19  * CDDL HEADER END
  20  */
  21 
  22 /*
  23  * Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved.
  24  */
  25 
  26 /*
  27  * Copyright 2012 Daniil Lunev. All rights reserved.
  28  */
  29 
  30 #include <stdio.h>
  31 #include <errno.h>
  32 #include <stdlib.h>
  33 #include <string.h>
  34 #include <unistd.h>
  35 #include <alloca.h>
  36 #include <ctype.h>
  37 #include <sys/types.h>
  38 
  39 #include "message.h"
  40 #include "bootadm.h"
  41 
  42 #define HYPER_KERNEL_DIR                "/platform/i86xpv/kernel"
  43 #define METAL_KERNEL_DIR                "/platform/i86pc/kernel"
  44 
  45 #define BOOTRC_FILE                     "/boot/solaris/bootenv.rc"
  46 #define ZFS_BOOTSTR                     "$ZFS_BOOTFS"
  47 
  48 #define BFLAG                           "-B"
  49 #define DEFAULT_SERIAL                  "9600,8,n,1"
  50 
  51 #define TTYXMODE_TO_COMNUM(ttyxmode)    ((int)(*((ttyxmode) + 3) - '`'))
  52 #define COMNAME_TO_COMNUM(comname)      ((int)(*((comname) + 3) - '0'))
  53 
  54 #define WHITESPC(x)                     (x)
  55 
  56 static char *serial_config[2] = { NULL, NULL };
  57 static char *console_dev = NULL;
  58 
  59 static char *bootenv_rc_serial[2] = { NULL, NULL };
  60 static char *bootenv_rc_console = NULL;
  61 
  62 static unsigned zfs_boot = 0;
  63 
  64 /*
  65  * Append the string pointed to by "str" to the string pointed to by "orig"
  66  * adding the delimeter "delim" in between.


 750 
 751         (void) fclose(fp);
 752 }
 753 
 754 error_t
 755 cvt_to_hyper(menu_t *mp, char *osroot, char *extra_args)
 756 {
 757         const char *fcn = "cvt_to_hyper()";
 758 
 759         line_t *lp;
 760         entry_t *ent;
 761         size_t len, zfslen;
 762 
 763         char *newstr;
 764         char *osdev;
 765 
 766         char *title = NULL;
 767         char *findroot = NULL;
 768         char *bootfs = NULL;
 769         char *kernel = NULL;
 770         char *opts = NULL;
 771         char *mod_kernel = NULL;
 772         char *module = NULL;
 773         char *tmp = NULL;
 774 
 775         char *kern_path = NULL;
 776         char *kern_bargs = NULL;
 777 
 778         int curdef, newdef;
 779         int kp_allocated = 0;
 780         int ret = BAM_ERROR;
 781 
 782         assert(osroot);
 783 
 784         BAM_DPRINTF((D_FUNC_ENTRY2, fcn, osroot, extra_args));
 785 
 786         /*
 787          * First just check to verify osroot is a sane directory.
 788          */
 789         if ((osdev = get_special(osroot)) == NULL) {
 790                 bam_error(CANT_FIND_SPECIAL, osroot);
 791                 return (BAM_ERROR);
 792         }
 793 


 830 
 831         if (bootenv_rc_console != NULL)
 832                 console_metal_to_hyper(bootenv_rc_console);
 833 
 834         if (bootenv_rc_serial[0] != NULL)
 835                 (void) serial_metal_to_hyper("ttya-mode", bootenv_rc_serial[0]);
 836 
 837         if (bootenv_rc_serial[1] != NULL)
 838                 (void) serial_metal_to_hyper("ttyb-mode", bootenv_rc_serial[1]);
 839 
 840         /*
 841          * Now process the entry itself.
 842          */
 843         for (lp = ent->start; lp != NULL; lp = lp->next) {
 844                 /*
 845                  * Process important lines from menu.lst boot entry.
 846                  */
 847                 if (lp->flags == BAM_TITLE) {
 848                         title = strdupa(lp->arg);
 849                 } else if (lp->cmd != NULL) {
 850                         if (strcmp(lp->cmd, "pool_label") == 0) {
 851                                 findroot = strdupa(lp->arg);
 852                         } else if (strcmp(lp->cmd, "data_set") == 0) {
 853                                 bootfs = strdupa(lp->arg);
 854                         } else if (strcmp(lp->cmd, "kernel_options") == 0) {
 855                                 opts = strdupa(lp->arg);
 856                         } else if (strcmp(lp->cmd,
 857                             menu_cmds[MODULE_DOLLAR_CMD]) == 0) {
 858                                 module = strdupa(lp->arg);
 859                         } else if ((strcmp(lp->cmd,
 860                             menu_cmds[KERNEL_DOLLAR_CMD]) == 0) &&
 861                             (ret = cvt_metal_kernel(lp->arg,
 862                             &kern_path)) != 0) {
 863                                 if (ret < 0) {
 864                                         ret = BAM_ERROR;
 865                                         bam_error(KERNEL_NOT_PARSEABLE, curdef);
 866                                 } else
 867                                         ret = BAM_NOCHANGE;
 868 
 869                                 goto abort;
 870                         }
 871                 }
 872 
 873                 if (lp == ent->end)
 874                         break;
 875         }
 876 
 877         
 878         /*
 879          * If findroot, module or kern_path are NULL, the boot entry is
 880          * malformed.
 881          */
 882         if (findroot == NULL) {
 883                 bam_error(FINDROOT_NOT_FOUND, curdef);
 884                 goto abort;
 885         }
 886 
 887         if (module == NULL) {
 888                 bam_error(MODULE_NOT_PARSEABLE, curdef);
 889                 goto abort;
 890         }
 891 
 892         if (kern_path == NULL) {
 893                 bam_error(KERNEL_NOT_FOUND, curdef);
 894                 goto abort;
 895         }
 896 
 897         /* assemble new kernel and module arguments from parsed values */


 940         if ((strcmp(kern_path, DIRECT_BOOT_32) == 0) ||
 941             (strcmp(kern_path, DIRECT_BOOT_64) == 0)) {
 942                 kern_path = HYPERVISOR_KERNEL;
 943         } else {
 944                 newstr = modify_path(kern_path, METAL_KERNEL_DIR,
 945                     HYPER_KERNEL_DIR);
 946                 free(kern_path);
 947                 kern_path = newstr;
 948                 kp_allocated = 1;
 949         }
 950 
 951         /*
 952          * We need to allocate space for the kernel path (twice) plus an
 953          * intervening space, possibly the ZFS boot string, and NULL,
 954          * of course.
 955          */
 956         len = (strlen(kern_path) * 2) + WHITESPC(1) + 1;
 957         zfslen = (zfs_boot ? (WHITESPC(1) + strlen(ZFS_BOOT)) : 0);
 958 
 959         mod_kernel = alloca(len + zfslen);
 960         if (opts)
 961                 (void) snprintf(mod_kernel, len + strlen(opts) + 1, "%s %s %s", kern_path, kern_path, opts);
 962         else
 963                 (void) snprintf(mod_kernel, len, "%s %s", kern_path, kern_path);
 964 
 965         if (kp_allocated)
 966                 free(kern_path);
 967 
 968         if (zfs_boot) {
 969                 char *zfsstr = alloca(zfslen + 1);
 970 
 971                 (void) snprintf(zfsstr, zfslen + 1, " %s", ZFS_BOOT);
 972                 (void) strcat(mod_kernel, zfsstr);
 973         }
 974 
 975         /* shut off warning messages from the entry line parser */
 976         if (ent->flags & BAM_ENTRY_BOOTADM)
 977                 ent->flags &= ~BAM_ENTRY_BOOTADM;
 978 
 979         BAM_DPRINTF((D_CVT_CMD_KERN_DOLLAR, fcn, kernel));
 980         BAM_DPRINTF((D_CVT_CMD_MOD_DOLLAR, fcn, mod_kernel));
 981 
 982         if ((newdef = add_boot_entry(mp, title, findroot, kernel, mod_kernel,


1057         for (ent = mp->entries; ((ent != NULL) && (ent->entryNum != curdef));
1058             ent = ent->next)
1059                 ;
1060 
1061         /* couldn't find it, so error out */
1062         if (ent == NULL) {
1063                 bam_error(CANT_FIND_DEFAULT, curdef);
1064                 goto abort;
1065         }
1066 
1067         /*
1068          * Now process the entry itself.
1069          */
1070         for (lp = ent->start; lp != NULL; lp = lp->next) {
1071                 /*
1072                  * Process important lines from menu.lst boot entry.
1073                  */
1074                 if (lp->flags == BAM_TITLE) {
1075                         title = strdupa(lp->arg);
1076                 } else if (lp->cmd != NULL) {
1077                         if (strcmp(lp->cmd, "pool_label") == 0) {
1078                                 findroot = strdupa(lp->arg);
1079                         } else if (strcmp(lp->cmd, "data_set") == 0) {
1080                                 bootfs = strdupa(lp->arg);
1081                         } else if (strcmp(lp->cmd,
1082                             menu_cmds[MODULE_DOLLAR_CMD]) == 0) {
1083                                 if (strstr(lp->arg, "boot_archive") == NULL) {
1084                                         module = strdupa(lp->arg);
1085                                         cvt_hyper_module(module, &kern_path);
1086                                 } else {
1087                                         barchive_path = strdupa(lp->arg);
1088                                 }
1089                         } else if ((strcmp(lp->cmd,
1090                             menu_cmds[KERNEL_DOLLAR_CMD]) == 0) &&
1091                             (cvt_hyper_kernel(lp->arg) < 0)) {
1092                                 ret = BAM_NOCHANGE;
1093                                 goto abort;
1094                         }
1095                 }
1096 
1097                 if (lp == ent->end)
1098                         break;
1099         }