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 }
|