1 3446 mrj /* 2 3446 mrj * CDDL HEADER START 3 3446 mrj * 4 3446 mrj * The contents of this file are subject to the terms of the 5 3446 mrj * Common Development and Distribution License (the "License"). 6 3446 mrj * You may not use this file except in compliance with the License. 7 3446 mrj * 8 3446 mrj * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9 3446 mrj * or http://www.opensolaris.org/os/licensing. 10 3446 mrj * See the License for the specific language governing permissions 11 3446 mrj * and limitations under the License. 12 3446 mrj * 13 3446 mrj * When distributing Covered Code, include this CDDL HEADER in each 14 3446 mrj * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15 3446 mrj * If applicable, add the following below this CDDL HEADER, with the 16 3446 mrj * fields enclosed by brackets "[]" replaced with your own identifying 17 3446 mrj * information: Portions Copyright [yyyy] [name of copyright owner] 18 3446 mrj * 19 3446 mrj * CDDL HEADER END 20 3446 mrj */ 21 3446 mrj /* 22 10405 Frank * Copyright 2009 Sun Microsystems, Inc. All rights reserved. 23 3446 mrj * Use is subject to license terms. 24 3446 mrj */ 25 3446 mrj 26 3446 mrj #include <stdio.h> 27 3446 mrj #include <errno.h> 28 3446 mrj #include <stdlib.h> 29 3446 mrj #include <string.h> 30 3446 mrj #include <unistd.h> 31 3446 mrj #include <sys/types.h> 32 3446 mrj #include <sys/stat.h> 33 3446 mrj #include <limits.h> 34 3446 mrj #include <fcntl.h> 35 3446 mrj #include <strings.h> 36 3446 mrj 37 3446 mrj #include <sys/mman.h> 38 3446 mrj #include <sys/elf.h> 39 3446 mrj #include <sys/multiboot.h> 40 3446 mrj 41 3446 mrj #include "message.h" 42 3446 mrj #include "bootadm.h" 43 3446 mrj 44 3446 mrj direct_or_multi_t bam_direct = BAM_DIRECT_NOT_SET; 45 5084 johnlev hv_t bam_is_hv = BAM_HV_UNKNOWN; 46 6448 vikram findroot_t bam_is_findroot = BAM_FINDROOT_UNKNOWN; 47 6448 vikram 48 6448 vikram static void 49 6448 vikram get_findroot_cap(const char *osroot) 50 6448 vikram { 51 6448 vikram FILE *fp; 52 6448 vikram char path[PATH_MAX]; 53 6448 vikram char buf[BAM_MAXLINE]; 54 6448 vikram struct stat sb; 55 6448 vikram int dboot; 56 6448 vikram int error; 57 6448 vikram int ret; 58 6448 vikram const char *fcn = "get_findroot_cap()"; 59 6448 vikram 60 6448 vikram assert(is_grub(osroot)); 61 6448 vikram 62 6448 vikram (void) snprintf(path, sizeof (path), "%s/%s", 63 6448 vikram osroot, "boot/grub/capability"); 64 6448 vikram 65 6448 vikram if (stat(path, &sb) == -1) { 66 6448 vikram bam_is_findroot = BAM_FINDROOT_ABSENT; 67 6448 vikram BAM_DPRINTF((D_FINDROOT_ABSENT, fcn)); 68 6448 vikram return; 69 6448 vikram } 70 6448 vikram 71 6448 vikram fp = fopen(path, "r"); 72 6448 vikram error = errno; 73 6448 vikram INJECT_ERROR1("GET_CAP_FINDROOT_FOPEN", fp = NULL); 74 6448 vikram if (fp == NULL) { 75 6448 vikram bam_error(OPEN_FAIL, path, strerror(error)); 76 6448 vikram return; 77 6448 vikram } 78 6448 vikram 79 10405 Frank dboot = 0; 80 6448 vikram while (s_fgets(buf, sizeof (buf), fp) != NULL) { 81 6448 vikram if (strcmp(buf, "findroot") == 0) { 82 6448 vikram BAM_DPRINTF((D_FINDROOT_PRESENT, fcn)); 83 6448 vikram bam_is_findroot = BAM_FINDROOT_PRESENT; 84 6448 vikram } 85 6448 vikram if (strcmp(buf, "dboot") == 0) { 86 6448 vikram BAM_DPRINTF((D_DBOOT_PRESENT, fcn)); 87 6448 vikram dboot = 1; 88 6448 vikram } 89 6448 vikram } 90 6448 vikram 91 6448 vikram assert(dboot); 92 6448 vikram 93 6448 vikram if (bam_is_findroot == BAM_FINDROOT_UNKNOWN) { 94 6448 vikram bam_is_findroot = BAM_FINDROOT_ABSENT; 95 6448 vikram BAM_DPRINTF((D_FINDROOT_ABSENT, fcn)); 96 6448 vikram } 97 6448 vikram out: 98 6448 vikram ret = fclose(fp); 99 6448 vikram error = errno; 100 6448 vikram INJECT_ERROR1("GET_CAP_FINDROOT_FCLOSE", ret = 1); 101 6448 vikram if (ret != 0) { 102 6448 vikram bam_error(CLOSE_FAIL, path, strerror(error)); 103 6448 vikram } 104 6448 vikram } 105 3446 mrj 106 3446 mrj error_t 107 6448 vikram get_boot_cap(const char *osroot) 108 3446 mrj { 109 6448 vikram char fname[PATH_MAX]; 110 6448 vikram char *image; 111 6448 vikram uchar_t *ident; 112 6448 vikram int fd; 113 6448 vikram int m; 114 3446 mrj multiboot_header_t *mbh; 115 6448 vikram struct stat sb; 116 6448 vikram int error; 117 6448 vikram const char *fcn = "get_boot_cap()"; 118 5648 setje 119 6448 vikram if (is_sparc()) { 120 5648 setje /* there is no non dboot sparc new-boot */ 121 5648 setje bam_direct = BAM_DIRECT_DBOOT; 122 6448 vikram BAM_DPRINTF((D_IS_SPARC_DBOOT, fcn)); 123 5648 setje return (BAM_SUCCESS); 124 5648 setje } 125 3446 mrj 126 6448 vikram if (!is_grub(osroot)) { 127 6448 vikram bam_error(NOT_GRUB_ROOT, osroot); 128 6448 vikram return (BAM_ERROR); 129 6448 vikram } 130 6448 vikram 131 6448 vikram (void) snprintf(fname, PATH_MAX, "%s/%s", osroot, 132 3446 mrj "platform/i86pc/kernel/unix"); 133 3446 mrj fd = open(fname, O_RDONLY); 134 6448 vikram error = errno; 135 6448 vikram INJECT_ERROR1("GET_CAP_UNIX_OPEN", fd = -1); 136 3446 mrj if (fd < 0) { 137 6448 vikram bam_error(OPEN_FAIL, fname, strerror(error)); 138 6448 vikram return (BAM_ERROR); 139 6448 vikram } 140 6448 vikram 141 6448 vikram /* 142 6448 vikram * Verify that this is a sane unix at least 8192 bytes in length 143 6448 vikram */ 144 6448 vikram if (fstat(fd, &sb) == -1 || sb.st_size < 8192) { 145 6448 vikram (void) close(fd); 146 6448 vikram bam_error(INVALID_BINARY, fname); 147 3446 mrj return (BAM_ERROR); 148 3446 mrj } 149 3446 mrj 150 3446 mrj /* 151 3446 mrj * mmap the first 8K 152 3446 mrj */ 153 3446 mrj image = mmap(NULL, 8192, PROT_READ, MAP_SHARED, fd, 0); 154 6448 vikram error = errno; 155 6448 vikram INJECT_ERROR1("GET_CAP_MMAP", image = MAP_FAILED); 156 3446 mrj if (image == MAP_FAILED) { 157 6448 vikram bam_error(MMAP_FAIL, fname, strerror(error)); 158 3446 mrj return (BAM_ERROR); 159 3446 mrj } 160 3446 mrj 161 3446 mrj ident = (uchar_t *)image; 162 3446 mrj if (ident[EI_MAG0] != ELFMAG0 || ident[EI_MAG1] != ELFMAG1 || 163 3446 mrj ident[EI_MAG2] != ELFMAG2 || ident[EI_MAG3] != ELFMAG3) { 164 3446 mrj bam_error(NOT_ELF_FILE, fname); 165 3446 mrj return (BAM_ERROR); 166 3446 mrj } 167 3446 mrj if (ident[EI_CLASS] != ELFCLASS32) { 168 3446 mrj bam_error(WRONG_ELF_CLASS, fname, ident[EI_CLASS]); 169 3446 mrj return (BAM_ERROR); 170 3446 mrj } 171 3446 mrj 172 3446 mrj /* 173 3446 mrj * The GRUB multiboot header must be 32-bit aligned and completely 174 3446 mrj * contained in the 1st 8K of the file. If the unix binary has 175 3446 mrj * a multiboot header, then it is a 'dboot' kernel. Otherwise, 176 3446 mrj * this kernel must be booted via multiboot -- we call this a 177 3446 mrj * 'multiboot' kernel. 178 3446 mrj */ 179 3446 mrj bam_direct = BAM_DIRECT_MULTIBOOT; 180 3446 mrj for (m = 0; m < 8192 - sizeof (multiboot_header_t); m += 4) { 181 3446 mrj mbh = (void *)(image + m); 182 3446 mrj if (mbh->magic == MB_HEADER_MAGIC) { 183 6448 vikram BAM_DPRINTF((D_IS_DBOOT, fcn)); 184 3446 mrj bam_direct = BAM_DIRECT_DBOOT; 185 3446 mrj break; 186 3446 mrj } 187 3446 mrj } 188 3446 mrj (void) munmap(image, 8192); 189 3446 mrj (void) close(fd); 190 5084 johnlev 191 6448 vikram INJECT_ERROR1("GET_CAP_MULTIBOOT", bam_direct = BAM_DIRECT_MULTIBOOT); 192 5084 johnlev if (bam_direct == BAM_DIRECT_DBOOT) { 193 10405 Frank if (bam_is_hv == BAM_HV_PRESENT) { 194 6448 vikram BAM_DPRINTF((D_IS_XVM, fcn)); 195 5084 johnlev } else { 196 6448 vikram BAM_DPRINTF((D_IS_NOT_XVM, fcn)); 197 5084 johnlev } 198 6448 vikram } else { 199 6448 vikram BAM_DPRINTF((D_IS_MULTIBOOT, fcn)); 200 5084 johnlev } 201 5084 johnlev 202 6448 vikram /* Not a fatal error if this fails */ 203 6448 vikram get_findroot_cap(osroot); 204 6448 vikram 205 6448 vikram BAM_DPRINTF((D_RETURN_SUCCESS, fcn)); 206 3446 mrj return (BAM_SUCCESS); 207 3446 mrj } 208 3446 mrj 209 3446 mrj #define INST_RELEASE "var/sadm/system/admin/INST_RELEASE" 210 3446 mrj 211 3446 mrj /* 212 3446 mrj * Return true if root has been bfu'ed. bfu will blow away 213 3446 mrj * var/sadm/system/admin/INST_RELEASE, so if it's still there, we can 214 3446 mrj * assume the system has not been bfu'ed. 215 3446 mrj */ 216 3446 mrj static int 217 3446 mrj is_bfu_system(const char *root) 218 3446 mrj { 219 6448 vikram static int is_bfu = -1; 220 6448 vikram char path[PATH_MAX]; 221 6448 vikram struct stat sb; 222 6448 vikram const char *fcn = "is_bfu_system()"; 223 3446 mrj 224 6448 vikram if (is_bfu != -1) { 225 6448 vikram BAM_DPRINTF((D_ALREADY_BFU_TEST, fcn, is_bfu ? "" : "NOT")); 226 3446 mrj return (is_bfu); 227 6448 vikram } 228 3446 mrj 229 3446 mrj (void) snprintf(path, sizeof (path), "%s/%s", root, INST_RELEASE); 230 3446 mrj if (stat(path, &sb) != 0) { 231 3446 mrj is_bfu = 1; 232 6448 vikram BAM_DPRINTF((D_RETURN_SUCCESS, fcn)); 233 3446 mrj } else { 234 3446 mrj is_bfu = 0; 235 6448 vikram BAM_DPRINTF((D_RETURN_FAILURE, fcn)); 236 3446 mrj } 237 3446 mrj return (is_bfu); 238 3446 mrj } 239 3446 mrj 240 3446 mrj #define MENU_URL(root) (is_bfu_system(root) ? \ 241 3446 mrj "http://www.sun.com/msg/SUNOS-8000-CF" : \ 242 3446 mrj "http://www.sun.com/msg/SUNOS-8000-AK") 243 3446 mrj 244 3446 mrj /* 245 3446 mrj * Simply allocate a new line and copy in cmd + sep + arg 246 3446 mrj */ 247 3446 mrj void 248 3446 mrj update_line(line_t *linep) 249 3446 mrj { 250 6448 vikram size_t size; 251 6448 vikram const char *fcn = "update_line()"; 252 3446 mrj 253 6448 vikram BAM_DPRINTF((D_UPDATE_LINE_BEFORE, fcn, linep->line)); 254 3446 mrj free(linep->line); 255 3446 mrj size = strlen(linep->cmd) + strlen(linep->sep) + strlen(linep->arg) + 1; 256 3446 mrj linep->line = s_calloc(1, size); 257 3446 mrj (void) snprintf(linep->line, size, "%s%s%s", linep->cmd, linep->sep, 258 3446 mrj linep->arg); 259 6448 vikram BAM_DPRINTF((D_UPDATE_LINE_AFTER, fcn, linep->line)); 260 6448 vikram } 261 6448 vikram 262 6448 vikram static char * 263 6448 vikram skip_wspace(char *ptr) 264 6448 vikram { 265 6448 vikram const char *fcn = "skip_wspace()"; 266 6448 vikram 267 6448 vikram INJECT_ERROR1("SKIP_WSPACE", ptr = NULL); 268 6448 vikram if (ptr == NULL) { 269 6448 vikram BAM_DPRINTF((D_SKIP_WSPACE_PTR_NULL, fcn)); 270 6448 vikram return (NULL); 271 6448 vikram } 272 6448 vikram 273 6448 vikram BAM_DPRINTF((D_SKIP_WSPACE_ENTRY_PTR, fcn, ptr)); 274 6448 vikram for (; *ptr != '\0'; ptr++) { 275 6448 vikram if ((*ptr != ' ') && (*ptr != '\t') && 276 6448 vikram (*ptr != '\n')) 277 6448 vikram break; 278 6448 vikram } 279 6448 vikram 280 6448 vikram ptr = (*ptr == '\0' ? NULL : ptr); 281 6448 vikram 282 6448 vikram BAM_DPRINTF((D_SKIP_WSPACE_EXIT_PTR, fcn, ptr ? ptr : "NULL")); 283 6448 vikram 284 6448 vikram return (ptr); 285 6448 vikram } 286 6448 vikram 287 6448 vikram static char * 288 6448 vikram rskip_bspace(char *bound, char *ptr) 289 6448 vikram { 290 6448 vikram const char *fcn = "rskip_bspace()"; 291 6448 vikram assert(bound); 292 6448 vikram assert(ptr); 293 6448 vikram assert(bound <= ptr); 294 6448 vikram assert(*bound != ' ' && *bound != '\t' && *bound != '\n'); 295 6448 vikram 296 6448 vikram BAM_DPRINTF((D_RSKIP_BSPACE_ENTRY, fcn, ptr)); 297 6448 vikram for (; ptr > bound; ptr--) { 298 6448 vikram if (*ptr == ' ' || *ptr == '\t' || *ptr == '\n') 299 6448 vikram break; 300 6448 vikram } 301 6448 vikram 302 6448 vikram BAM_DPRINTF((D_RSKIP_BSPACE_EXIT, fcn, ptr)); 303 6448 vikram return (ptr); 304 3446 mrj } 305 3446 mrj 306 3446 mrj /* 307 3446 mrj * The parse_kernel_line function examines a menu.lst kernel line. For 308 3446 mrj * multiboot, this is: 309 3446 mrj * 310 3446 mrj * kernel <multiboot path> <flags1> <kernel path> <flags2> 311 3446 mrj * 312 3446 mrj * <multiboot path> is either /platform/i86pc/multiboot or /boot/multiboot 313 3446 mrj * 314 3446 mrj * <kernel path> may be missing, or may be any full or relative path to unix. 315 3446 mrj * We check for it by looking for a word ending in "/unix". If it ends 316 3446 mrj * in "kernel/unix", we upgrade it to a 32-bit entry. If it ends in 317 3446 mrj * "kernel/amd64/unix", we upgrade it to the default entry. Otherwise, 318 3446 mrj * it's a custom kernel, and we skip it. 319 3446 mrj * 320 3446 mrj * <flags*> are anything that doesn't fit either of the above - these will be 321 3446 mrj * copied over. 322 3446 mrj * 323 3446 mrj * For direct boot, the defaults are 324 3446 mrj * 325 3446 mrj * kernel$ <kernel path> <flags> 326 3446 mrj * 327 3446 mrj * <kernel path> is one of: 328 3446 mrj * /platform/i86pc/kernel/$ISADIR/unix 329 8104 Enrico * /boot/platform/i86pc/kernel/$ISADIR/unix 330 3446 mrj * /platform/i86pc/kernel/unix 331 3446 mrj * /platform/i86pc/kernel/amd64/unix 332 3446 mrj * /boot/platform/i86pc/kernel/unix 333 8104 Enrico * /boot/platform/i86pc/kernel/amd64/unix 334 3446 mrj * 335 8104 Enrico * If <kernel path> is any of the last four, the command may also be "kernel". 336 3446 mrj * 337 3446 mrj * <flags> is anything that isn't <kernel path>. 338 3446 mrj * 339 6448 vikram * This function is only called to convert a multiboot entry to a dboot entry 340 3446 mrj * 341 3446 mrj * For safety, we do one more check: if the kernel path starts with /boot, 342 3446 mrj * we verify that the new kernel exists before changing it. This is mainly 343 3446 mrj * done for bfu, as it may cause the failsafe archives to be a different 344 3446 mrj * boot architecture from the newly bfu'ed system. 345 3446 mrj */ 346 3446 mrj static error_t 347 6448 vikram cvt_kernel_line(line_t *line, const char *osroot, entry_t *entry) 348 3446 mrj { 349 8104 Enrico char path[PATH_MAX], path_64[PATH_MAX]; 350 6448 vikram char linebuf[PATH_MAX]; 351 6448 vikram char new_arg[PATH_MAX]; 352 8104 Enrico struct stat sb, sb_64; 353 6448 vikram char *old_ptr; 354 6448 vikram char *unix_ptr; 355 6448 vikram char *flags1_ptr; 356 6448 vikram char *flags2_ptr; 357 6448 vikram const char *fcn = "cvt_kernel_line()"; 358 3446 mrj 359 6448 vikram BAM_DPRINTF((D_FUNC_ENTRY2, fcn, line->line, osroot)); 360 3446 mrj 361 3446 mrj /* 362 6448 vikram * We only convert multiboot to dboot and nothing else. 363 3446 mrj */ 364 6448 vikram if (!(entry->flags & BAM_ENTRY_MULTIBOOT)) { 365 6448 vikram BAM_DPRINTF((D_NOT_MULTIBOOT_CONVERT, fcn)); 366 3446 mrj return (BAM_SUCCESS); 367 3446 mrj } 368 3446 mrj 369 6448 vikram if (entry->flags & BAM_ENTRY_FAILSAFE) { 370 3446 mrj /* 371 6448 vikram * We're attempting to change failsafe to dboot. 372 6448 vikram * In the bfu case, we may not have a dboot failsafe 373 6448 vikram * kernel i.e. a "unix" under the "/boot" hierarchy. 374 6448 vikram * If so, just emit a message in verbose mode and 375 6448 vikram * return success. 376 3446 mrj */ 377 6448 vikram BAM_DPRINTF((D_TRYING_FAILSAFE_CVT_TO_DBOOT, fcn)); 378 6448 vikram (void) snprintf(path, PATH_MAX, "%s%s", osroot, 379 8104 Enrico DIRECT_BOOT_FAILSAFE_32); 380 8104 Enrico (void) snprintf(path_64, PATH_MAX, "%s%s", osroot, 381 8104 Enrico DIRECT_BOOT_FAILSAFE_64); 382 8104 Enrico if (stat(path, &sb) != 0 && stat(path_64, &sb_64) != 0) { 383 3446 mrj if (bam_verbose) { 384 6448 vikram bam_error(FAILSAFE_MISSING, line->lineNum); 385 3446 mrj } 386 6448 vikram BAM_DPRINTF((D_NO_FAILSAFE_UNIX_CONVERT, fcn)); 387 3446 mrj return (BAM_SUCCESS); 388 3446 mrj } 389 3446 mrj } 390 3446 mrj 391 3446 mrj /* 392 8104 Enrico * Make sure we have the correct cmd 393 3446 mrj */ 394 8104 Enrico 395 8104 Enrico free(line->cmd); 396 8104 Enrico line->cmd = s_strdup(menu_cmds[KERNEL_DOLLAR_CMD]); 397 8104 Enrico BAM_DPRINTF((D_CVT_CMD_KERN_DOLLAR, fcn, line->cmd)); 398 3446 mrj 399 6448 vikram assert(sizeof (linebuf) > strlen(line->arg) + 32); 400 6448 vikram (void) strlcpy(linebuf, line->arg, sizeof (linebuf)); 401 3446 mrj 402 6448 vikram old_ptr = strpbrk(linebuf, " \t\n"); 403 6448 vikram old_ptr = skip_wspace(old_ptr); 404 6448 vikram if (old_ptr == NULL) { 405 6448 vikram /* 406 6448 vikram * only multiboot and nothing else 407 6448 vikram * i.e. flags1 = unix = flags2 = NULL 408 6448 vikram */ 409 6448 vikram flags1_ptr = unix_ptr = flags2_ptr = NULL; 410 6448 vikram BAM_DPRINTF((D_FLAGS1_UNIX_FLAGS2_NULL, fcn)) 411 6448 vikram goto create; 412 3446 mrj } 413 3446 mrj 414 3446 mrj /* 415 3446 mrj * 416 6448 vikram * old_ptr is either at "flags1" or "unix" 417 3446 mrj */ 418 6448 vikram if (unix_ptr = strstr(old_ptr, "/unix")) { 419 6448 vikram 420 6448 vikram /* 421 6448 vikram * There is a unix. 422 6448 vikram */ 423 6448 vikram BAM_DPRINTF((D_UNIX_PRESENT, fcn)); 424 6448 vikram 425 6448 vikram /* See if there's a flags2 past unix */ 426 6448 vikram flags2_ptr = unix_ptr + strlen("/unix"); 427 6448 vikram flags2_ptr = skip_wspace(flags2_ptr); 428 6448 vikram if (flags2_ptr) { 429 6448 vikram BAM_DPRINTF((D_FLAGS2_PRESENT, fcn, flags2_ptr)); 430 6448 vikram } else { 431 6448 vikram BAM_DPRINTF((D_FLAGS2_ABSENT, fcn)); 432 3446 mrj } 433 3446 mrj 434 6448 vikram /* see if there is a flags1 before unix */ 435 6448 vikram unix_ptr = rskip_bspace(old_ptr, unix_ptr); 436 3446 mrj 437 3446 mrj if (unix_ptr == old_ptr) { 438 3446 mrj flags1_ptr = NULL; 439 6448 vikram BAM_DPRINTF((D_FLAGS1_ABSENT, fcn)); 440 3446 mrj } else { 441 3446 mrj flags1_ptr = old_ptr; 442 6448 vikram *unix_ptr = '\0'; 443 6448 vikram unix_ptr++; 444 6448 vikram BAM_DPRINTF((D_FLAGS1_PRESENT, fcn, flags1_ptr)); 445 3446 mrj } 446 3446 mrj 447 6448 vikram } else { 448 6448 vikram /* There is no unix, there is only a bunch of flags */ 449 3446 mrj flags1_ptr = old_ptr; 450 6448 vikram unix_ptr = flags2_ptr = NULL; 451 6448 vikram BAM_DPRINTF((D_FLAGS1_ONLY, fcn, flags1_ptr)); 452 3446 mrj } 453 3446 mrj 454 3446 mrj /* 455 6448 vikram * With dboot, unix is fixed and is at the beginning. We need to 456 6448 vikram * migrate flags1 and flags2 457 3446 mrj */ 458 6448 vikram create: 459 6448 vikram if (entry->flags & BAM_ENTRY_FAILSAFE) { 460 6448 vikram (void) snprintf(new_arg, sizeof (new_arg), "%s", 461 6448 vikram DIRECT_BOOT_FAILSAFE_KERNEL); 462 6448 vikram } else { 463 6448 vikram (void) snprintf(new_arg, sizeof (new_arg), "%s", 464 6448 vikram DIRECT_BOOT_KERNEL); 465 6448 vikram } 466 6448 vikram BAM_DPRINTF((D_CVTED_UNIX, fcn, new_arg)); 467 6448 vikram 468 3446 mrj if (flags1_ptr != NULL) { 469 6448 vikram (void) strlcat(new_arg, " ", sizeof (new_arg)); 470 6448 vikram (void) strlcat(new_arg, flags1_ptr, sizeof (new_arg)); 471 3446 mrj } 472 3446 mrj 473 6448 vikram if (flags2_ptr != NULL) { 474 6448 vikram (void) strlcat(new_arg, " ", sizeof (new_arg)); 475 6448 vikram (void) strlcat(new_arg, flags2_ptr, sizeof (new_arg)); 476 6448 vikram } 477 6448 vikram 478 6448 vikram BAM_DPRINTF((D_CVTED_UNIX_AND_FLAGS, fcn, new_arg)); 479 6448 vikram 480 6448 vikram free(line->arg); 481 6448 vikram line->arg = s_strdup(new_arg); 482 6448 vikram update_line(line); 483 6448 vikram BAM_DPRINTF((D_CVTED_KERNEL_LINE, fcn, line->line)); 484 3446 mrj return (BAM_SUCCESS); 485 3446 mrj } 486 3446 mrj 487 3446 mrj /* 488 3446 mrj * Similar to above, except this time we're looking at a module line, 489 3446 mrj * which is quite a bit simpler. 490 3446 mrj * 491 3446 mrj * Under multiboot, the archive line is: 492 3446 mrj * 493 3446 mrj * module /platform/i86pc/boot_archive 494 3446 mrj * 495 3446 mrj * Under directboot, the archive line is: 496 3446 mrj * 497 3446 mrj * module$ /platform/i86pc/$ISADIR/boot_archive 498 3446 mrj * 499 3446 mrj * which may be specified exactly as either of: 500 3446 mrj * 501 3446 mrj * module /platform/i86pc/boot_archive 502 3446 mrj * module /platform/i86pc/amd64/boot_archive 503 3446 mrj * 504 8104 Enrico * Under multiboot, the failsafe is: 505 3446 mrj * 506 3446 mrj * module /boot/x86.miniroot-safe 507 8104 Enrico * 508 8104 Enrico * Under dboot, the failsafe is: 509 8104 Enrico * 510 8104 Enrico * module$ /boot/$ISADIR/x86.miniroot-safe 511 8104 Enrico * 512 8104 Enrico * which may be specified exactly as either of: 513 8104 Enrico * 514 8104 Enrico * module /boot/x86.miniroot-safe 515 8104 Enrico * module /boot/amd64/x86.miniroot-safe 516 3446 mrj */ 517 3446 mrj static error_t 518 6448 vikram cvt_module_line(line_t *line, entry_t *entry) 519 3446 mrj { 520 6448 vikram const char *fcn = "cvt_module_line()"; 521 6448 vikram 522 6448 vikram BAM_DPRINTF((D_FUNC_ENTRY1, fcn, line->line)); 523 3446 mrj 524 3446 mrj /* 525 6448 vikram * We only convert multiboot to dboot and nothing else 526 3446 mrj */ 527 6448 vikram if (!(entry->flags & BAM_ENTRY_MULTIBOOT)) { 528 6448 vikram BAM_DPRINTF((D_NOT_MULTIBOOT_CONVERT, fcn)); 529 3446 mrj return (BAM_SUCCESS); 530 3446 mrj } 531 3446 mrj 532 6448 vikram if (entry->flags & BAM_ENTRY_FAILSAFE) { 533 6448 vikram if (strcmp(line->arg, FAILSAFE_ARCHIVE) == 0) { 534 6448 vikram BAM_DPRINTF((D_FAILSAFE_NO_CVT_NEEDED, fcn, line->arg)); 535 6448 vikram BAM_DPRINTF((D_RETURN_SUCCESS, fcn)); 536 6448 vikram return (BAM_SUCCESS); 537 6448 vikram } 538 6448 vikram } else if (strcmp(line->arg, MULTIBOOT_ARCHIVE) != 0) { 539 6448 vikram bam_error(UNKNOWN_MODULE_LINE, line->lineNum); 540 6448 vikram BAM_DPRINTF((D_RETURN_FAILURE, fcn)); 541 6448 vikram return (BAM_MSG); 542 3446 mrj } 543 3446 mrj 544 8104 Enrico free(line->cmd); 545 8104 Enrico free(line->arg); 546 8104 Enrico line->cmd = s_strdup(menu_cmds[MODULE_DOLLAR_CMD]); 547 8104 Enrico 548 8104 Enrico line->arg = s_strdup(entry->flags & BAM_ENTRY_FAILSAFE ? 549 8104 Enrico FAILSAFE_ARCHIVE : DIRECT_BOOT_ARCHIVE); 550 6448 vikram 551 6448 vikram update_line(line); 552 6448 vikram BAM_DPRINTF((D_CVTED_MODULE, fcn, line->line)); 553 6448 vikram BAM_DPRINTF((D_RETURN_SUCCESS, fcn)); 554 6448 vikram return (BAM_SUCCESS); 555 6448 vikram } 556 6448 vikram 557 6448 vikram static void 558 6448 vikram bam_warn_hand_entries(menu_t *mp, char *osroot) 559 6448 vikram { 560 6448 vikram int hand_num; 561 6448 vikram int hand_max; 562 6448 vikram int *hand_list; 563 6448 vikram int i; 564 6448 vikram entry_t *entry; 565 6448 vikram const char *fcn = "bam_warn_hand_entries()"; 566 6448 vikram 567 6448 vikram if (bam_force) { 568 6448 vikram /* 569 6448 vikram * No warning needed, we are automatically converting 570 6448 vikram * the "hand" entries 571 6448 vikram */ 572 6448 vikram BAM_DPRINTF((D_FORCE_HAND_CVT, fcn)); 573 6448 vikram return; 574 6448 vikram } 575 6448 vikram 576 6448 vikram hand_num = 0; 577 6448 vikram hand_max = BAM_ENTRY_NUM; 578 6448 vikram hand_list = s_calloc(1, hand_max); 579 6448 vikram 580 6448 vikram for (entry = mp->entries; entry; entry = entry->next) { 581 6448 vikram if (entry->flags & (BAM_ENTRY_BOOTADM|BAM_ENTRY_LU)) 582 6448 vikram continue; 583 6448 vikram BAM_DPRINTF((D_FOUND_HAND, fcn, entry->entryNum)); 584 6448 vikram if (++hand_num > hand_max) { 585 6448 vikram hand_max *= 2; 586 6448 vikram hand_list = s_realloc(hand_list, 587 6448 vikram hand_max * sizeof (int)); 588 6448 vikram } 589 6448 vikram hand_list[hand_num - 1] = entry->entryNum; 590 6448 vikram } 591 6448 vikram 592 6448 vikram bam_error(HAND_ADDED_ENTRIES, osroot, MENU_URL(osroot)); 593 6448 vikram bam_print_stderr("Entry Number%s: ", (hand_num > 1) ? 594 6448 vikram "s" : ""); 595 6448 vikram for (i = 0; i < hand_num; i++) { 596 6448 vikram bam_print_stderr("%d ", hand_list[i]); 597 6448 vikram } 598 6448 vikram bam_print_stderr("\n"); 599 6448 vikram } 600 6448 vikram 601 6448 vikram static entry_t * 602 6448 vikram find_matching_entry( 603 6448 vikram entry_t *estart, 604 6448 vikram char *grubsign, 605 6448 vikram char *grubroot, 606 6448 vikram int root_opt) 607 6448 vikram { 608 6448 vikram entry_t *entry; 609 6448 vikram line_t *line; 610 6448 vikram char opt[10]; 611 6448 vikram const char *fcn = "find_matching_entry()"; 612 6448 vikram 613 6448 vikram assert(grubsign); 614 6448 vikram assert(root_opt == 0 || root_opt == 1); 615 6448 vikram 616 6448 vikram (void) snprintf(opt, sizeof (opt), "%d", root_opt); 617 6448 vikram BAM_DPRINTF((D_FUNC_ENTRY3, fcn, grubsign, grubroot, opt)); 618 6448 vikram 619 6448 vikram for (entry = estart; entry; entry = entry->next) { 620 6694 vikram 621 6448 vikram if (!(entry->flags & (BAM_ENTRY_BOOTADM|BAM_ENTRY_LU)) && 622 6448 vikram !bam_force) { 623 6448 vikram BAM_DPRINTF((D_SKIP_ENTRY, fcn, entry->entryNum)); 624 6448 vikram continue; 625 6448 vikram } 626 6448 vikram 627 6448 vikram if (entry->flags & BAM_ENTRY_ROOT) { 628 6448 vikram for (line = entry->start; line; line = line->next) { 629 6448 vikram if (line->cmd == NULL || line->arg == NULL) { 630 6448 vikram if (line == entry->end) { 631 6448 vikram BAM_DPRINTF((D_ENTRY_END, fcn)); 632 6448 vikram break; 633 6448 vikram } else { 634 6448 vikram BAM_DPRINTF((D_SKIP_NULL, fcn)); 635 6448 vikram continue; 636 6448 vikram } 637 6448 vikram } 638 6448 vikram if (strcmp(line->cmd, menu_cmds[ROOT_CMD]) 639 6448 vikram == 0 && strcmp(line->arg, grubroot) == 0) { 640 6448 vikram BAM_DPRINTF((D_ROOT_MATCH, fcn, 641 6448 vikram line->line, grubsign)); 642 6448 vikram return (entry); 643 6448 vikram } 644 6448 vikram if (line == entry->end) { 645 6448 vikram BAM_DPRINTF((D_ENTRY_END, fcn)); 646 6448 vikram break; 647 6448 vikram } 648 6448 vikram } 649 6448 vikram } else if (entry->flags & BAM_ENTRY_FINDROOT) { 650 6448 vikram for (line = entry->start; line; line = line->next) { 651 6448 vikram if (line->cmd == NULL || line->arg == NULL) { 652 6448 vikram if (line == entry->end) { 653 6448 vikram BAM_DPRINTF((D_ENTRY_END, fcn)); 654 6448 vikram break; 655 6448 vikram } else { 656 6448 vikram BAM_DPRINTF((D_SKIP_NULL, fcn)); 657 6448 vikram continue; 658 6448 vikram } 659 6448 vikram } 660 6448 vikram if (strcmp(line->cmd, menu_cmds[FINDROOT_CMD]) 661 6448 vikram == 0 && strcmp(line->arg, grubsign) == 0) { 662 6448 vikram BAM_DPRINTF((D_FINDROOT_MATCH, fcn, 663 6448 vikram line->line, grubsign)); 664 6448 vikram return (entry); 665 6448 vikram } 666 6448 vikram if (line == entry->end) { 667 6448 vikram BAM_DPRINTF((D_ENTRY_END, fcn)); 668 6448 vikram break; 669 6448 vikram } 670 6448 vikram } 671 6448 vikram } else if (root_opt) { 672 6448 vikram /* Neither root nor findroot */ 673 6448 vikram BAM_DPRINTF((D_NO_ROOT_FINDROOT, fcn, entry->entryNum)); 674 6448 vikram return (entry); 675 6448 vikram } 676 6448 vikram } 677 6448 vikram 678 6448 vikram BAM_DPRINTF((D_NO_MATCH, fcn)); 679 6448 vikram return (NULL); 680 6448 vikram } 681 6448 vikram 682 6448 vikram /* 683 6448 vikram * The following is a set of routines that attempt to convert the 684 6448 vikram * menu entries for the supplied osroot into a format compatible 685 6448 vikram * with the GRUB installation on osroot. 686 6448 vikram * 687 6448 vikram * Each of these conversion routines make no assumptions about 688 6448 vikram * the current state of the menu entry, it does its best to 689 6448 vikram * convert the menu entry to the new state. In the process 690 6448 vikram * we may either upgrade or downgrade. 691 6448 vikram * 692 6448 vikram * We don't make any heroic efforts at conversion. It is better 693 6448 vikram * to be conservative and bail out at the first sign of error. We will 694 6448 vikram * in such cases, point the user at the knowledge-base article 695 6448 vikram * so that they can upgrade manually. 696 6448 vikram */ 697 6448 vikram static error_t 698 6448 vikram bam_add_findroot(menu_t *mp, char *grubsign, char *grubroot, int root_opt) 699 6448 vikram { 700 6448 vikram entry_t *entry; 701 6448 vikram line_t *line; 702 6448 vikram line_t *newlp; 703 6448 vikram int update_num; 704 6448 vikram char linebuf[PATH_MAX]; 705 6448 vikram const char *fcn = "bam_add_findroot()"; 706 6448 vikram 707 6448 vikram update_num = 0; 708 6448 vikram 709 6448 vikram bam_print(CVT_FINDROOT); 710 6448 vikram 711 6448 vikram entry = mp->entries; 712 6448 vikram for (; entry = find_matching_entry(entry, grubsign, grubroot, root_opt); 713 6448 vikram entry = entry->next) { 714 6448 vikram if (entry->flags & BAM_ENTRY_FINDROOT) { 715 6448 vikram /* already converted */ 716 6448 vikram BAM_DPRINTF((D_ALREADY_FINDROOT, fcn, entry->entryNum)); 717 6448 vikram continue; 718 6448 vikram } 719 6448 vikram for (line = entry->start; line; line = line->next) { 720 6448 vikram if (line->cmd == NULL || line->arg == NULL) { 721 6448 vikram if (line == entry->end) { 722 6448 vikram BAM_DPRINTF((D_ENTRY_END, fcn)); 723 6448 vikram break; 724 6448 vikram } else { 725 6448 vikram BAM_DPRINTF((D_SKIP_NULL, fcn)); 726 6448 vikram continue; 727 6448 vikram } 728 6448 vikram } 729 6448 vikram if (strcmp(line->cmd, menu_cmds[TITLE_CMD]) == 0) { 730 6448 vikram newlp = s_calloc(1, sizeof (line_t)); 731 6448 vikram newlp->cmd = s_strdup(menu_cmds[FINDROOT_CMD]); 732 6448 vikram newlp->sep = s_strdup(" "); 733 6448 vikram newlp->arg = s_strdup(grubsign); 734 6448 vikram (void) snprintf(linebuf, sizeof (linebuf), 735 6448 vikram "%s%s%s", newlp->cmd, newlp->sep, 736 6448 vikram newlp->arg); 737 6448 vikram newlp->line = s_strdup(linebuf); 738 6448 vikram bam_add_line(mp, entry, line, newlp); 739 6448 vikram update_num = 1; 740 6448 vikram entry->flags &= ~BAM_ENTRY_ROOT; 741 6448 vikram entry->flags |= BAM_ENTRY_FINDROOT; 742 6448 vikram BAM_DPRINTF((D_ADDED_FINDROOT, fcn, 743 6448 vikram newlp->line)); 744 6448 vikram line = newlp; 745 6448 vikram } 746 6448 vikram if (strcmp(line->cmd, menu_cmds[ROOT_CMD]) == 0) { 747 6448 vikram BAM_DPRINTF((D_FREEING_ROOT, fcn, line->line)); 748 6448 vikram unlink_line(mp, line); 749 6448 vikram line_free(line); 750 6448 vikram } 751 6448 vikram if (line == entry->end) { 752 6448 vikram BAM_DPRINTF((D_ENTRY_END, fcn)); 753 6448 vikram break; 754 6448 vikram } 755 6448 vikram } 756 6448 vikram } 757 6448 vikram 758 6448 vikram if (update_num) { 759 6448 vikram BAM_DPRINTF((D_UPDATED_NUMBERING, fcn)); 760 6448 vikram update_numbering(mp); 761 6448 vikram } 762 6448 vikram 763 6448 vikram BAM_DPRINTF((D_RETURN_SUCCESS, fcn)); 764 6448 vikram return (BAM_SUCCESS); 765 6448 vikram } 766 6448 vikram 767 6448 vikram static error_t 768 6448 vikram bam_add_hv(menu_t *mp, char *grubsign, char *grubroot, int root_opt) 769 6448 vikram { 770 6448 vikram entry_t *entry; 771 6448 vikram const char *fcn = "bam_add_hv()"; 772 6448 vikram 773 6448 vikram bam_print(CVT_HV); 774 6448 vikram 775 6448 vikram entry = mp->entries; 776 6448 vikram for (; entry = find_matching_entry(entry, grubsign, grubroot, root_opt); 777 6448 vikram entry = entry->next) { 778 6448 vikram if (entry->flags & BAM_ENTRY_HV) { 779 6448 vikram BAM_DPRINTF((D_ALREADY_HV, fcn, entry->entryNum)); 780 6448 vikram return (BAM_SUCCESS); 781 6448 vikram } 782 6448 vikram } 783 6448 vikram 784 6448 vikram (void) add_boot_entry(mp, NEW_HV_ENTRY, grubsign, XEN_MENU, 785 10499 William XEN_KERNEL_MODULE_LINE, DIRECT_BOOT_ARCHIVE, NULL); 786 6448 vikram 787 6448 vikram BAM_DPRINTF((D_ADDED_XVM_ENTRY, fcn)); 788 6448 vikram 789 6448 vikram update_numbering(mp); 790 6448 vikram 791 6448 vikram BAM_DPRINTF((D_RETURN_SUCCESS, fcn)); 792 3446 mrj 793 3446 mrj return (BAM_SUCCESS); 794 3446 mrj } 795 3446 mrj 796 6448 vikram static error_t 797 6448 vikram bam_add_dboot( 798 6448 vikram menu_t *mp, 799 6448 vikram char *osroot, 800 6448 vikram char *grubsign, 801 6448 vikram char *grubroot, 802 6448 vikram int root_opt) 803 3446 mrj { 804 6448 vikram int msg = 0; 805 6448 vikram entry_t *entry; 806 6448 vikram line_t *line; 807 6448 vikram error_t ret; 808 6448 vikram const char *fcn = "bam_add_dboot()"; 809 5084 johnlev 810 6448 vikram bam_print(CVT_DBOOT); 811 3446 mrj 812 6448 vikram entry = mp->entries; 813 6448 vikram for (; entry = find_matching_entry(entry, grubsign, grubroot, root_opt); 814 6448 vikram entry = entry->next) { 815 6448 vikram for (line = entry->start; line; line = line->next) { 816 6448 vikram if (line->cmd == NULL || line->arg == NULL) { 817 6448 vikram if (line == entry->end) { 818 6448 vikram BAM_DPRINTF((D_ENTRY_END, fcn)); 819 6448 vikram break; 820 6448 vikram } else { 821 6448 vikram BAM_DPRINTF((D_SKIP_NULL, fcn)); 822 6448 vikram continue; 823 6448 vikram } 824 3446 mrj } 825 3446 mrj 826 3446 mrj /* 827 6448 vikram * If we have a kernel$ command, assume it 828 6448 vikram * is dboot already. If it is not a dboot 829 6448 vikram * entry, something funny is going on and 830 6448 vikram * we will leave it alone 831 3446 mrj */ 832 6448 vikram if (strcmp(line->cmd, menu_cmds[KERNEL_CMD]) == 0) { 833 6448 vikram ret = cvt_kernel_line(line, osroot, entry); 834 6448 vikram INJECT_ERROR1("ADD_DBOOT_KERN_ERR", 835 6448 vikram ret = BAM_ERROR); 836 6448 vikram INJECT_ERROR1("ADD_DBOOT_KERN_MSG", 837 6448 vikram ret = BAM_MSG); 838 6448 vikram if (ret == BAM_ERROR) { 839 6448 vikram BAM_DPRINTF((D_CVT_KERNEL_FAIL, fcn)); 840 6448 vikram return (ret); 841 6448 vikram } else if (ret == BAM_MSG) { 842 6448 vikram msg = 1; 843 6448 vikram BAM_DPRINTF((D_CVT_KERNEL_MSG, fcn)); 844 3446 mrj } 845 3446 mrj } 846 6448 vikram if (strcmp(line->cmd, menu_cmds[MODULE_CMD]) == 0) { 847 6448 vikram ret = cvt_module_line(line, entry); 848 6448 vikram INJECT_ERROR1("ADD_DBOOT_MOD_ERR", 849 6448 vikram ret = BAM_ERROR); 850 6448 vikram INJECT_ERROR1("ADD_DBOOT_MOD_MSG", 851 6448 vikram ret = BAM_MSG); 852 6448 vikram if (ret == BAM_ERROR) { 853 6448 vikram BAM_DPRINTF((D_CVT_MODULE_FAIL, fcn)); 854 6448 vikram return (ret); 855 6448 vikram } else if (ret == BAM_MSG) { 856 6448 vikram BAM_DPRINTF((D_CVT_MODULE_MSG, fcn)); 857 6448 vikram msg = 1; 858 6448 vikram } 859 6448 vikram } 860 6448 vikram 861 6448 vikram if (line == entry->end) { 862 6448 vikram BAM_DPRINTF((D_ENTRY_END, fcn)); 863 3446 mrj break; 864 6448 vikram } 865 3446 mrj } 866 3446 mrj } 867 3446 mrj 868 6448 vikram ret = msg ? BAM_MSG : BAM_SUCCESS; 869 6448 vikram BAM_DPRINTF((D_RETURN_RET, fcn, ret)); 870 6448 vikram return (ret); 871 6448 vikram } 872 6448 vikram 873 6448 vikram /*ARGSUSED*/ 874 6448 vikram error_t 875 6448 vikram upgrade_menu(menu_t *mp, char *osroot, char *menu_root) 876 6448 vikram { 877 6448 vikram char *osdev; 878 6448 vikram char *grubsign; 879 6448 vikram char *grubroot; 880 6448 vikram int ret1; 881 6448 vikram int ret2; 882 6448 vikram int ret3; 883 6448 vikram const char *fcn = "upgrade_menu()"; 884 6448 vikram 885 6448 vikram assert(osroot); 886 6448 vikram assert(menu_root); 887 6448 vikram 888 6448 vikram BAM_DPRINTF((D_FUNC_ENTRY2, fcn, osroot, menu_root)); 889 6448 vikram 890 3446 mrj /* 891 6448 vikram * We only support upgrades. Xen may not be present 892 6448 vikram * on smaller metaclusters so we don't check for that. 893 5084 johnlev */ 894 6448 vikram if (bam_is_findroot != BAM_FINDROOT_PRESENT || 895 6448 vikram bam_direct != BAM_DIRECT_DBOOT) { 896 6448 vikram bam_error(DOWNGRADE_NOTSUP, osroot); 897 6448 vikram return (BAM_ERROR); 898 5084 johnlev } 899 5084 johnlev 900 5084 johnlev /* 901 6448 vikram * First get the GRUB signature 902 3446 mrj */ 903 6448 vikram osdev = get_special(osroot); 904 6448 vikram INJECT_ERROR1("UPGRADE_OSDEV", osdev = NULL); 905 6448 vikram if (osdev == NULL) { 906 6448 vikram bam_error(CANT_FIND_SPECIAL, osroot); 907 3446 mrj return (BAM_ERROR); 908 3446 mrj } 909 6448 vikram 910 6448 vikram grubsign = get_grubsign(osroot, osdev); 911 6448 vikram INJECT_ERROR1("UPGRADE_GRUBSIGN", grubsign = NULL); 912 6448 vikram if (grubsign == NULL) { 913 6448 vikram free(osdev); 914 6448 vikram bam_error(CANT_FIND_GRUBSIGN, osroot); 915 6448 vikram return (BAM_ERROR); 916 6448 vikram } 917 6448 vikram 918 6448 vikram /* not fatal if we can't get grubroot */ 919 6448 vikram grubroot = get_grubroot(osroot, osdev, menu_root); 920 6448 vikram INJECT_ERROR1("UPGRADE_GRUBROOT", grubroot = NULL); 921 6448 vikram 922 6448 vikram free(osdev); 923 6448 vikram 924 6448 vikram ret1 = bam_add_findroot(mp, grubsign, 925 6448 vikram grubroot, root_optional(osroot, menu_root)); 926 6448 vikram INJECT_ERROR1("UPGRADE_ADD_FINDROOT", ret1 = BAM_ERROR); 927 6448 vikram if (ret1 == BAM_ERROR) 928 6448 vikram goto abort; 929 6448 vikram 930 10405 Frank if (bam_is_hv == BAM_HV_PRESENT) { 931 10405 Frank ret2 = bam_add_hv(mp, grubsign, grubroot, 932 10405 Frank root_optional(osroot, menu_root)); 933 10405 Frank INJECT_ERROR1("UPGRADE_ADD_HV", ret2 = BAM_ERROR); 934 10405 Frank if (ret2 == BAM_ERROR) 935 10405 Frank goto abort; 936 10405 Frank } else 937 10405 Frank ret2 = BAM_SUCCESS; 938 6448 vikram 939 6448 vikram ret3 = bam_add_dboot(mp, osroot, grubsign, 940 6448 vikram grubroot, root_optional(osroot, menu_root)); 941 6448 vikram INJECT_ERROR1("UPGRADE_ADD_DBOOT", ret3 = BAM_ERROR); 942 6448 vikram if (ret3 == BAM_ERROR) 943 6448 vikram goto abort; 944 6448 vikram 945 6448 vikram if (ret1 == BAM_MSG || ret2 == BAM_MSG || ret3 == BAM_MSG) { 946 6448 vikram bam_error(CVT_TODO, MENU_URL(osroot)); 947 6448 vikram } else { 948 6448 vikram bam_warn_hand_entries(mp, osroot); 949 6448 vikram } 950 6448 vikram 951 6448 vikram free(grubsign); 952 6448 vikram 953 6448 vikram BAM_DPRINTF((D_RETURN_RET, fcn, BAM_WRITE)); 954 3446 mrj return (BAM_WRITE); 955 6448 vikram 956 6448 vikram abort: 957 6448 vikram free(grubsign); 958 6448 vikram bam_error(CVT_ABORT, osroot, MENU_URL(osroot)); 959 6448 vikram return (BAM_ERROR); 960 3446 mrj } 961