195 static char **bam_argv; |
196 static char **bam_argv; |
196 static int bam_argc; |
197 static int bam_argc; |
197 static int bam_check; |
198 static int bam_check; |
198 static int bam_smf_check; |
199 static int bam_smf_check; |
199 static int bam_lock_fd = -1; |
200 static int bam_lock_fd = -1; |
|
201 static int bam_zfs; |
200 static char rootbuf[PATH_MAX] = "/"; |
202 static char rootbuf[PATH_MAX] = "/"; |
201 static int bam_update_all; |
203 static int bam_update_all; |
202 static int bam_alt_platform; |
204 static int bam_alt_platform; |
203 static char *bam_platform; |
205 static char *bam_platform; |
204 |
206 |
240 static long s_strtol(char *); |
242 static long s_strtol(char *); |
241 static int s_fputs(char *, FILE *); |
243 static int s_fputs(char *, FILE *); |
242 |
244 |
243 static char *s_strdup(char *); |
245 static char *s_strdup(char *); |
244 static int is_readonly(char *); |
246 static int is_readonly(char *); |
|
247 static int is_zfs(char *, char **); |
245 static int is_amd64(void); |
248 static int is_amd64(void); |
246 static int is_sun4u(void); |
249 static int is_sun4u(void); |
247 static int is_sun4v(void); |
250 static int is_sun4v(void); |
248 static void append_to_flist(filelist_t *, char *); |
251 static void append_to_flist(filelist_t *, char *); |
249 |
252 |
891 bam_menu(char *subcmd, char *opt, int largc, char *largv[]) |
897 bam_menu(char *subcmd, char *opt, int largc, char *largv[]) |
892 { |
898 { |
893 error_t ret; |
899 error_t ret; |
894 char menu_path[PATH_MAX]; |
900 char menu_path[PATH_MAX]; |
895 char path[PATH_MAX]; |
901 char path[PATH_MAX]; |
|
902 char full_menu_root[PATH_MAX]; |
896 menu_t *menu; |
903 menu_t *menu; |
897 char *mntpt, *menu_root, *logslice, *fstype; |
904 char *mntpt, *menu_root, *logslice, *fstype, *grubSLICEpool, *pool; |
898 struct stat sb; |
905 struct stat sb; |
899 int mnted; /* set if we did a mount */ |
906 int mnted; /* set if we did a mount */ |
900 error_t (*f)(menu_t *mp, char *menu_path, char *opt); |
907 error_t (*f)(menu_t *mp, char *menu_path, char *opt); |
901 char *rootpath; |
908 char *rootpath; |
902 |
909 |
929 * 2. Use the alternate root, if given. |
936 * 2. Use the alternate root, if given. |
930 * 3. Check /stubboot |
937 * 3. Check /stubboot |
931 * 4. Use / |
938 * 4. Use / |
932 */ |
939 */ |
933 if (bam_alt_root) { |
940 if (bam_alt_root) { |
934 (void) snprintf(path, sizeof (path), "%s%s", bam_root, |
941 if (is_zfs(bam_root, &grubSLICEpool)) |
935 GRUB_slice); |
942 (void) snprintf(path, sizeof (path), "%s/%s%s", |
|
943 bam_root, grubSLICEpool, GRUB_slice); |
|
944 else |
|
945 (void) snprintf(path, sizeof (path), "%s%s", |
|
946 bam_root, GRUB_slice); |
936 } else { |
947 } else { |
937 (void) snprintf(path, sizeof (path), "%s", GRUB_slice); |
948 if (is_zfs(bam_root, &grubSLICEpool)) |
|
949 (void) snprintf(path, sizeof (path), "/%s%s", |
|
950 grubSLICEpool, GRUB_slice); |
|
951 else |
|
952 (void) snprintf(path, sizeof (path), "%s", GRUB_slice); |
938 } |
953 } |
939 |
954 |
940 if (stat(path, &sb) == 0) { |
955 if (stat(path, &sb) == 0) { |
941 mntpt = mount_grub_slice(&mnted, NULL, &logslice, &fstype); |
956 mntpt = mount_grub_slice(&mnted, NULL, &logslice, &fstype); |
942 menu_root = mntpt; |
957 menu_root = mntpt; |
951 if (menu_root == NULL) { |
966 if (menu_root == NULL) { |
952 bam_error(CANNOT_LOCATE_GRUB_MENU); |
967 bam_error(CANNOT_LOCATE_GRUB_MENU); |
953 return (BAM_ERROR); |
968 return (BAM_ERROR); |
954 } |
969 } |
955 |
970 |
956 elide_trailing_slash(menu_root, menu_path, sizeof (menu_path)); |
971 /* |
|
972 * menu_root is the root file system of the boot environment being |
|
973 * operated on. |
|
974 * full_menu_root is the location of the /boot/grub directory. |
|
975 * With a ufs root, this is simply menu_root. With a zfs |
|
976 * root, it's <menu_root>/<poolname> |
|
977 */ |
|
978 elide_trailing_slash(menu_root, full_menu_root, |
|
979 sizeof (full_menu_root)); |
|
980 |
|
981 if (is_zfs(menu_root, &pool)) { |
|
982 (void) strlcat(full_menu_root, "/", sizeof (full_menu_root)); |
|
983 (void) strlcat(full_menu_root, pool, sizeof (full_menu_root)); |
|
984 } |
|
985 |
|
986 /* |
|
987 * menu_path is the directory that contains the menu.lst file |
|
988 */ |
|
989 (void) strlcpy(menu_path, full_menu_root, sizeof (menu_path)); |
957 (void) strlcat(menu_path, GRUB_MENU, sizeof (menu_path)); |
990 (void) strlcat(menu_path, GRUB_MENU, sizeof (menu_path)); |
958 |
991 |
959 /* |
992 /* |
960 * If listing the menu, display the active menu |
993 * If listing the menu, display the active menu |
961 * location |
994 * location |
997 (strcmp(subcmd, "upgrade") == 0)) |
1030 (strcmp(subcmd, "upgrade") == 0)) |
998 ret = f(menu, bam_root, opt); |
1031 ret = f(menu, bam_root, opt); |
999 else |
1032 else |
1000 ret = f(menu, menu_path, opt); |
1033 ret = f(menu, menu_path, opt); |
1001 if (ret == BAM_WRITE) { |
1034 if (ret == BAM_WRITE) { |
1002 ret = menu_write(menu_root, menu); |
1035 ret = menu_write(full_menu_root, menu); |
1003 } |
1036 } |
1004 |
1037 |
1005 menu_free(menu); |
1038 menu_free(menu); |
1006 |
1039 |
1007 umount_grub_slice(mnted, mntpt, NULL, logslice, fstype); |
1040 umount_grub_slice(mnted, mntpt, NULL, logslice, fstype); |
1008 |
1041 |
|
1042 if (grubSLICEpool) |
|
1043 free(grubSLICEpool); |
|
1044 if (pool) |
|
1045 free(pool); |
1009 return (ret); |
1046 return (ret); |
1010 } |
1047 } |
1011 |
1048 |
1012 |
1049 |
1013 static error_t |
1050 static error_t |
2091 } |
2128 } |
2092 |
2129 |
2093 return (0); |
2130 return (0); |
2094 } |
2131 } |
2095 |
2132 |
|
2133 static int |
|
2134 is_zfs(char *root, char **poolname) |
|
2135 { |
|
2136 struct statvfs64 vfs; |
|
2137 FILE *fp; |
|
2138 struct extmnttab mnt; |
|
2139 dev_t devicenum; |
|
2140 char *special = NULL; |
|
2141 char *cp; |
|
2142 |
|
2143 /* poolname can be null */ |
|
2144 if (poolname) |
|
2145 *poolname = NULL; |
|
2146 |
|
2147 if (statvfs64(root, &vfs) != 0) { |
|
2148 if (bam_verbose) |
|
2149 bam_error(STATVFS_FAIL, root, strerror(errno)); |
|
2150 return (0); |
|
2151 } |
|
2152 |
|
2153 if (strncmp(vfs.f_basetype, "zfs", strlen("zfs")) != 0) |
|
2154 return (0); |
|
2155 |
|
2156 if (poolname == NULL) |
|
2157 return (1); |
|
2158 |
|
2159 /* |
|
2160 * Now find the mnttab entry so that we can extract the |
|
2161 * pool name from the special device field. |
|
2162 */ |
|
2163 fp = fopen(MNTTAB, "r"); |
|
2164 if (fp == NULL) { |
|
2165 bam_error(OPEN_FAIL, MNTTAB, strerror(errno)); |
|
2166 return (0); |
|
2167 } |
|
2168 |
|
2169 resetmnttab(fp); |
|
2170 |
|
2171 while (getextmntent(fp, &mnt, sizeof (mnt)) == 0) { |
|
2172 devicenum = makedevice(mnt.mnt_major, mnt.mnt_minor); |
|
2173 if (devicenum == vfs.f_fsid) { |
|
2174 special = s_strdup(mnt.mnt_special); |
|
2175 if ((cp = strchr(special, '/')) != NULL) |
|
2176 *cp = '\0'; |
|
2177 *poolname = s_strdup(special); |
|
2178 break; |
|
2179 } |
|
2180 } |
|
2181 |
|
2182 (void) fclose(fp); |
|
2183 |
|
2184 if (special) { |
|
2185 free(special); |
|
2186 return (1); |
|
2187 } |
|
2188 |
|
2189 return (0); |
|
2190 } |
|
2191 |
2096 static error_t |
2192 static error_t |
2097 update_archive(char *root, char *opt) |
2193 update_archive(char *root, char *opt) |
2098 { |
2194 { |
2099 error_t ret; |
2195 error_t ret; |
2100 |
2196 |
3478 } |
3574 } |
3479 |
3575 |
3480 /* add the entry for normal Solaris */ |
3576 /* add the entry for normal Solaris */ |
3481 if (bam_direct == BAM_DIRECT_DBOOT) { |
3577 if (bam_direct == BAM_DIRECT_DBOOT) { |
3482 entry = update_boot_entry(mp, title, grubdisk, |
3578 entry = update_boot_entry(mp, title, grubdisk, |
3483 DIRECT_BOOT_KERNEL, NULL, DIRECT_BOOT_ARCHIVE, |
3579 (bam_zfs ? DIRECT_BOOT_KERNEL_ZFS : DIRECT_BOOT_KERNEL), |
3484 osroot == menu_root); |
3580 NULL, DIRECT_BOOT_ARCHIVE, osroot == menu_root); |
3485 if ((entry != BAM_ERROR) && (bam_is_hv == BAM_HV_PRESENT)) { |
3581 if ((entry != BAM_ERROR) && (bam_is_hv == BAM_HV_PRESENT)) { |
3486 (void) update_boot_entry(mp, NEW_HV_ENTRY, grubdisk, |
3582 (void) update_boot_entry(mp, NEW_HV_ENTRY, grubdisk, |
3487 XEN_MENU, KERNEL_MODULE_LINE, DIRECT_BOOT_ARCHIVE, |
3583 XEN_MENU, (bam_zfs ? |
3488 osroot == menu_root); |
3584 KERNEL_MODULE_LINE_ZFS : KERNEL_MODULE_LINE), |
|
3585 DIRECT_BOOT_ARCHIVE, osroot == menu_root); |
3489 } |
3586 } |
3490 } else { |
3587 } else { |
3491 entry = update_boot_entry(mp, title, grubdisk, MULTI_BOOT, |
3588 entry = update_boot_entry(mp, title, grubdisk, MULTI_BOOT, |
3492 NULL, MULTI_BOOT_ARCHIVE, osroot == menu_root); |
3589 NULL, MULTI_BOOT_ARCHIVE, osroot == menu_root); |
3493 } |
3590 } |
3501 |
3598 |
3502 /* Figure out where the kernel line should point */ |
3599 /* Figure out where the kernel line should point */ |
3503 (void) snprintf(failsafe, sizeof (failsafe), "%s%s", osroot, |
3600 (void) snprintf(failsafe, sizeof (failsafe), "%s%s", osroot, |
3504 DIRECT_BOOT_FAILSAFE_KERNEL); |
3601 DIRECT_BOOT_FAILSAFE_KERNEL); |
3505 if (stat(failsafe, &sbuf) == 0) { |
3602 if (stat(failsafe, &sbuf) == 0) { |
3506 failsafe_kernel = DIRECT_BOOT_FAILSAFE_LINE; |
3603 failsafe_kernel = |
|
3604 (bam_zfs ? DIRECT_BOOT_FAILSAFE_LINE_ZFS : |
|
3605 DIRECT_BOOT_FAILSAFE_LINE); |
3507 } else { |
3606 } else { |
3508 (void) snprintf(failsafe, sizeof (failsafe), "%s%s", |
3607 (void) snprintf(failsafe, sizeof (failsafe), "%s%s", |
3509 osroot, MULTI_BOOT_FAILSAFE); |
3608 osroot, MULTI_BOOT_FAILSAFE); |
3510 if (stat(failsafe, &sbuf) == 0) { |
3609 if (stat(failsafe, &sbuf) == 0) { |
3511 failsafe_kernel = MULTI_BOOT_FAILSAFE_LINE; |
3610 failsafe_kernel = MULTI_BOOT_FAILSAFE_LINE; |