17c478bd9Sstevel@tonic-gate /* 27c478bd9Sstevel@tonic-gate * CDDL HEADER START 37c478bd9Sstevel@tonic-gate * 47c478bd9Sstevel@tonic-gate * The contents of this file are subject to the terms of the 5d33344bbSsy25831 * Common Development and Distribution License (the "License"). 6d33344bbSsy25831 * You may not use this file except in compliance with the License. 77c478bd9Sstevel@tonic-gate * 87c478bd9Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 97c478bd9Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing. 107c478bd9Sstevel@tonic-gate * See the License for the specific language governing permissions 117c478bd9Sstevel@tonic-gate * and limitations under the License. 127c478bd9Sstevel@tonic-gate * 137c478bd9Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each 147c478bd9Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 157c478bd9Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the 167c478bd9Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying 177c478bd9Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner] 187c478bd9Sstevel@tonic-gate * 197c478bd9Sstevel@tonic-gate * CDDL HEADER END 207c478bd9Sstevel@tonic-gate */ 217c478bd9Sstevel@tonic-gate /* 22af28f636SEnrico Perla - Sun Microsystems * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved. 2333f5ff17SMilan Jurik * Copyright 2012 Milan Jurik. All rights reserved. 241a902ef8SHans Rosenfeld * Copyright 2015 Nexenta Systems, Inc. All rights reserved. 25*cc641e8dSToomas Soome * Copyright 2016 Toomas Soome <tsoome@me.com> 267c478bd9Sstevel@tonic-gate */ 277c478bd9Sstevel@tonic-gate 287c478bd9Sstevel@tonic-gate #include <stdio.h> 297c478bd9Sstevel@tonic-gate #include <stdlib.h> 307c478bd9Sstevel@tonic-gate #include <libgen.h> 317c478bd9Sstevel@tonic-gate #include <malloc.h> 327c478bd9Sstevel@tonic-gate #include <string.h> 337c478bd9Sstevel@tonic-gate #include <fcntl.h> 347c478bd9Sstevel@tonic-gate #include <unistd.h> 357c478bd9Sstevel@tonic-gate #include <strings.h> 36af28f636SEnrico Perla - Sun Microsystems #include <libintl.h> 37af28f636SEnrico Perla - Sun Microsystems #include <locale.h> 38af28f636SEnrico Perla - Sun Microsystems #include <errno.h> 39af28f636SEnrico Perla - Sun Microsystems #include <libfdisk.h> 40af28f636SEnrico Perla - Sun Microsystems #include <stdarg.h> 41af28f636SEnrico Perla - Sun Microsystems #include <assert.h> 42af28f636SEnrico Perla - Sun Microsystems 437c478bd9Sstevel@tonic-gate #include <sys/mount.h> 447c478bd9Sstevel@tonic-gate #include <sys/mnttab.h> 457c478bd9Sstevel@tonic-gate #include <sys/dktp/fdisk.h> 46d33344bbSsy25831 #include <sys/dkio.h> 47d33344bbSsy25831 #include <sys/vtoc.h> 48af28f636SEnrico Perla - Sun Microsystems #include <sys/types.h> 49af28f636SEnrico Perla - Sun Microsystems #include <sys/stat.h> 50af28f636SEnrico Perla - Sun Microsystems #include <sys/multiboot.h> 51af28f636SEnrico Perla - Sun Microsystems #include <sys/sysmacros.h> 521a902ef8SHans Rosenfeld #include <sys/efi_partition.h> 531a902ef8SHans Rosenfeld 541a902ef8SHans Rosenfeld #include <libnvpair.h> 551a902ef8SHans Rosenfeld #include <libfstyp.h> 567c478bd9Sstevel@tonic-gate 577c478bd9Sstevel@tonic-gate #include "message.h" 58af28f636SEnrico Perla - Sun Microsystems #include "installgrub.h" 59af28f636SEnrico Perla - Sun Microsystems #include "./../common/bblk_einfo.h" 60af28f636SEnrico Perla - Sun Microsystems #include "./../common/boot_utils.h" 61af28f636SEnrico Perla - Sun Microsystems #include "./../common/mboot_extra.h" 6221ba817cSToomas Soome #include "getresponse.h" 637c478bd9Sstevel@tonic-gate 647c478bd9Sstevel@tonic-gate #ifndef TEXT_DOMAIN 657c478bd9Sstevel@tonic-gate #define TEXT_DOMAIN "SUNW_OST_OSCMD" 667c478bd9Sstevel@tonic-gate #endif 677c478bd9Sstevel@tonic-gate 68af28f636SEnrico Perla - Sun Microsystems /* 69af28f636SEnrico Perla - Sun Microsystems * Variables to track installgrub desired mode of operation. 70af28f636SEnrico Perla - Sun Microsystems * 'nowrite' and 'boot_debug' come from boot_common.h. 71af28f636SEnrico Perla - Sun Microsystems */ 72af28f636SEnrico Perla - Sun Microsystems static boolean_t write_mbr = B_FALSE; 73af28f636SEnrico Perla - Sun Microsystems static boolean_t force_mbr = B_FALSE; 74af28f636SEnrico Perla - Sun Microsystems static boolean_t force_update = B_FALSE; 75af28f636SEnrico Perla - Sun Microsystems static boolean_t do_getinfo = B_FALSE; 76af28f636SEnrico Perla - Sun Microsystems static boolean_t do_version = B_FALSE; 77af28f636SEnrico Perla - Sun Microsystems static boolean_t do_mirror_bblk = B_FALSE; 78af28f636SEnrico Perla - Sun Microsystems static boolean_t strip = B_FALSE; 79af28f636SEnrico Perla - Sun Microsystems static boolean_t verbose_dump = B_FALSE; 807c478bd9Sstevel@tonic-gate 81af28f636SEnrico Perla - Sun Microsystems /* Installing the bootblock is the default operation. */ 82af28f636SEnrico Perla - Sun Microsystems static boolean_t do_install = B_TRUE; 837c478bd9Sstevel@tonic-gate 84af28f636SEnrico Perla - Sun Microsystems /* Versioning string, if present. */ 85af28f636SEnrico Perla - Sun Microsystems static char *update_str; 867c478bd9Sstevel@tonic-gate 87af28f636SEnrico Perla - Sun Microsystems /* 88af28f636SEnrico Perla - Sun Microsystems * Temporary buffer to store the first 32K of data looking for a multiboot 89af28f636SEnrico Perla - Sun Microsystems * signature. 90af28f636SEnrico Perla - Sun Microsystems */ 91af28f636SEnrico Perla - Sun Microsystems char mboot_scan[MBOOT_SCAN_SIZE]; 927ce76caaSEnrico Perla - Sun Microsystems 93af28f636SEnrico Perla - Sun Microsystems /* Function prototypes. */ 94af28f636SEnrico Perla - Sun Microsystems static void check_options(char *); 95af28f636SEnrico Perla - Sun Microsystems static int handle_install(char *, char **); 96af28f636SEnrico Perla - Sun Microsystems static int handle_mirror(char *, char **); 97af28f636SEnrico Perla - Sun Microsystems static int handle_getinfo(char *, char **); 98af28f636SEnrico Perla - Sun Microsystems static int commit_to_disk(ig_data_t *, char *); 99af28f636SEnrico Perla - Sun Microsystems static int init_device(ig_device_t *, char *path); 100af28f636SEnrico Perla - Sun Microsystems static void cleanup_device(ig_device_t *); 101af28f636SEnrico Perla - Sun Microsystems static void cleanup_stage2(ig_stage2_t *); 102af28f636SEnrico Perla - Sun Microsystems static int get_start_sector(ig_device_t *); 103af28f636SEnrico Perla - Sun Microsystems static int get_disk_fd(ig_device_t *device); 104af28f636SEnrico Perla - Sun Microsystems static int get_raw_partition_fd(ig_device_t *); 105af28f636SEnrico Perla - Sun Microsystems static char *get_raw_partition_path(ig_device_t *); 106af28f636SEnrico Perla - Sun Microsystems static boolean_t gather_stage2_from_dev(ig_data_t *); 107af28f636SEnrico Perla - Sun Microsystems static int propagate_bootblock(ig_data_t *, ig_data_t *, char *); 108af28f636SEnrico Perla - Sun Microsystems static int find_x86_bootpar(struct mboot *, int *, uint32_t *); 109af28f636SEnrico Perla - Sun Microsystems static int copy_stage2_to_pcfs(ig_data_t *); 110af28f636SEnrico Perla - Sun Microsystems static int write_stage2(ig_data_t *); 111af28f636SEnrico Perla - Sun Microsystems static int write_stage1(ig_data_t *); 1127c478bd9Sstevel@tonic-gate static void usage(char *); 113af28f636SEnrico Perla - Sun Microsystems static int read_stage1_from_file(char *, ig_data_t *); 114af28f636SEnrico Perla - Sun Microsystems static int read_stage2_from_file(char *, ig_data_t *); 115af28f636SEnrico Perla - Sun Microsystems static int read_stage1_from_disk(int, char *); 1161a902ef8SHans Rosenfeld static int read_stage2_from_disk(int, ig_stage2_t *, int); 117af28f636SEnrico Perla - Sun Microsystems static int prepare_stage1(ig_data_t *); 118af28f636SEnrico Perla - Sun Microsystems static int prepare_stage2(ig_data_t *, char *); 119af28f636SEnrico Perla - Sun Microsystems static void prepare_fake_multiboot(ig_stage2_t *); 120af28f636SEnrico Perla - Sun Microsystems static void add_stage2_einfo(ig_stage2_t *, char *updt_str); 121af28f636SEnrico Perla - Sun Microsystems static boolean_t is_update_necessary(ig_data_t *, char *); 1227c478bd9Sstevel@tonic-gate 123342440ecSPrasad Singamsetty extern int read_stage2_blocklist(int, unsigned int *); 1247c478bd9Sstevel@tonic-gate 1257c478bd9Sstevel@tonic-gate int 1267c478bd9Sstevel@tonic-gate main(int argc, char *argv[]) 1277c478bd9Sstevel@tonic-gate { 128af28f636SEnrico Perla - Sun Microsystems int opt; 129af28f636SEnrico Perla - Sun Microsystems int params = 3; 130af28f636SEnrico Perla - Sun Microsystems int ret; 131af28f636SEnrico Perla - Sun Microsystems char **handle_args; 132af28f636SEnrico Perla - Sun Microsystems char *progname; 1337c478bd9Sstevel@tonic-gate 1347c478bd9Sstevel@tonic-gate (void) setlocale(LC_ALL, ""); 1357c478bd9Sstevel@tonic-gate (void) textdomain(TEXT_DOMAIN); 13621ba817cSToomas Soome if (init_yes() < 0) { 13721ba817cSToomas Soome (void) fprintf(stderr, gettext(ERR_MSG_INIT_YES), 13821ba817cSToomas Soome strerror(errno)); 13921ba817cSToomas Soome exit(BC_ERROR); 14021ba817cSToomas Soome } 1417c478bd9Sstevel@tonic-gate 142af28f636SEnrico Perla - Sun Microsystems /* 143af28f636SEnrico Perla - Sun Microsystems * retro-compatibility: installing the bootblock is the default 144af28f636SEnrico Perla - Sun Microsystems * and there is no switch for it. 145af28f636SEnrico Perla - Sun Microsystems */ 146af28f636SEnrico Perla - Sun Microsystems do_install = B_TRUE; 147af28f636SEnrico Perla - Sun Microsystems 148af28f636SEnrico Perla - Sun Microsystems while ((opt = getopt(argc, argv, "dVMFfmneiu:")) != EOF) { 1497c478bd9Sstevel@tonic-gate switch (opt) { 1507c478bd9Sstevel@tonic-gate case 'm': 151af28f636SEnrico Perla - Sun Microsystems write_mbr = B_TRUE; 1527c478bd9Sstevel@tonic-gate break; 1537c478bd9Sstevel@tonic-gate case 'n': 154af28f636SEnrico Perla - Sun Microsystems nowrite = B_TRUE; 1557c478bd9Sstevel@tonic-gate break; 1567c478bd9Sstevel@tonic-gate case 'f': 157af28f636SEnrico Perla - Sun Microsystems force_mbr = B_TRUE; 1587c478bd9Sstevel@tonic-gate break; 1597ce76caaSEnrico Perla - Sun Microsystems case 'i': 160af28f636SEnrico Perla - Sun Microsystems do_getinfo = B_TRUE; 161af28f636SEnrico Perla - Sun Microsystems do_install = B_FALSE; 1627ce76caaSEnrico Perla - Sun Microsystems params = 1; 1637ce76caaSEnrico Perla - Sun Microsystems break; 164af28f636SEnrico Perla - Sun Microsystems case 'V': 165af28f636SEnrico Perla - Sun Microsystems verbose_dump = B_TRUE; 1667ce76caaSEnrico Perla - Sun Microsystems break; 167af28f636SEnrico Perla - Sun Microsystems case 'd': 168af28f636SEnrico Perla - Sun Microsystems boot_debug = B_TRUE; 169af28f636SEnrico Perla - Sun Microsystems break; 170af28f636SEnrico Perla - Sun Microsystems case 'F': 171af28f636SEnrico Perla - Sun Microsystems force_update = B_TRUE; 172af28f636SEnrico Perla - Sun Microsystems break; 173af28f636SEnrico Perla - Sun Microsystems case 'e': 174af28f636SEnrico Perla - Sun Microsystems strip = B_TRUE; 175af28f636SEnrico Perla - Sun Microsystems break; 176af28f636SEnrico Perla - Sun Microsystems case 'M': 177af28f636SEnrico Perla - Sun Microsystems do_mirror_bblk = B_TRUE; 178af28f636SEnrico Perla - Sun Microsystems do_install = B_FALSE; 179af28f636SEnrico Perla - Sun Microsystems params = 2; 180af28f636SEnrico Perla - Sun Microsystems break; 181af28f636SEnrico Perla - Sun Microsystems case 'u': 182af28f636SEnrico Perla - Sun Microsystems do_version = B_TRUE; 183af28f636SEnrico Perla - Sun Microsystems 184af28f636SEnrico Perla - Sun Microsystems update_str = malloc(strlen(optarg) + 1); 185af28f636SEnrico Perla - Sun Microsystems if (update_str == NULL) { 186af28f636SEnrico Perla - Sun Microsystems (void) fprintf(stderr, gettext("Unable to " 187af28f636SEnrico Perla - Sun Microsystems "allocate memory\n")); 188af28f636SEnrico Perla - Sun Microsystems exit(BC_ERROR); 189af28f636SEnrico Perla - Sun Microsystems } 190af28f636SEnrico Perla - Sun Microsystems (void) strlcpy(update_str, optarg, strlen(optarg) + 1); 1917ce76caaSEnrico Perla - Sun Microsystems break; 1927c478bd9Sstevel@tonic-gate default: 1937c478bd9Sstevel@tonic-gate /* fall through to process non-optional args */ 1947c478bd9Sstevel@tonic-gate break; 1957c478bd9Sstevel@tonic-gate } 1967c478bd9Sstevel@tonic-gate } 1977c478bd9Sstevel@tonic-gate 1987c478bd9Sstevel@tonic-gate /* check arguments */ 1997ce76caaSEnrico Perla - Sun Microsystems if (argc != optind + params) { 2007c478bd9Sstevel@tonic-gate usage(argv[0]); 201af28f636SEnrico Perla - Sun Microsystems exit(BC_ERROR); 2027c478bd9Sstevel@tonic-gate } 2037c478bd9Sstevel@tonic-gate 204af28f636SEnrico Perla - Sun Microsystems /* 205af28f636SEnrico Perla - Sun Microsystems * clean up options (and bail out if an unrecoverable combination is 206af28f636SEnrico Perla - Sun Microsystems * requested. 207af28f636SEnrico Perla - Sun Microsystems */ 208af28f636SEnrico Perla - Sun Microsystems progname = argv[0]; 209af28f636SEnrico Perla - Sun Microsystems check_options(progname); 210af28f636SEnrico Perla - Sun Microsystems handle_args = argv + optind; 211af28f636SEnrico Perla - Sun Microsystems 212af28f636SEnrico Perla - Sun Microsystems if (nowrite) 2137c478bd9Sstevel@tonic-gate (void) fprintf(stdout, DRY_RUN); 214af28f636SEnrico Perla - Sun Microsystems 215af28f636SEnrico Perla - Sun Microsystems if (do_getinfo) { 216af28f636SEnrico Perla - Sun Microsystems ret = handle_getinfo(progname, handle_args); 217af28f636SEnrico Perla - Sun Microsystems } else if (do_mirror_bblk) { 218af28f636SEnrico Perla - Sun Microsystems ret = handle_mirror(progname, handle_args); 219af28f636SEnrico Perla - Sun Microsystems } else { 220af28f636SEnrico Perla - Sun Microsystems ret = handle_install(progname, handle_args); 221af28f636SEnrico Perla - Sun Microsystems } 222af28f636SEnrico Perla - Sun Microsystems return (ret); 2237c478bd9Sstevel@tonic-gate } 2247c478bd9Sstevel@tonic-gate 225af28f636SEnrico Perla - Sun Microsystems #define MEANINGLESS_OPT gettext("%s specified but meaningless, ignoring\n") 226af28f636SEnrico Perla - Sun Microsystems static void 227af28f636SEnrico Perla - Sun Microsystems check_options(char *progname) 2287c478bd9Sstevel@tonic-gate { 229af28f636SEnrico Perla - Sun Microsystems if (do_getinfo && do_mirror_bblk) { 230af28f636SEnrico Perla - Sun Microsystems (void) fprintf(stderr, gettext("Only one of -M and -i can be " 231af28f636SEnrico Perla - Sun Microsystems "specified at the same time\n")); 232af28f636SEnrico Perla - Sun Microsystems usage(progname); 233af28f636SEnrico Perla - Sun Microsystems exit(BC_ERROR); 234af28f636SEnrico Perla - Sun Microsystems } 235af28f636SEnrico Perla - Sun Microsystems 236af28f636SEnrico Perla - Sun Microsystems if (do_mirror_bblk) { 237af28f636SEnrico Perla - Sun Microsystems /* 238af28f636SEnrico Perla - Sun Microsystems * -u and -F may actually reflect a user intent that is not 239af28f636SEnrico Perla - Sun Microsystems * correct with this command (mirror can be interpreted 240af28f636SEnrico Perla - Sun Microsystems * "similar" to install. Emit a message and continue. 241af28f636SEnrico Perla - Sun Microsystems * -e and -V have no meaning, be quiet here and only report the 242af28f636SEnrico Perla - Sun Microsystems * incongruence if a debug output is requested. 243af28f636SEnrico Perla - Sun Microsystems */ 244af28f636SEnrico Perla - Sun Microsystems if (do_version) { 245af28f636SEnrico Perla - Sun Microsystems (void) fprintf(stderr, MEANINGLESS_OPT, "-u"); 246af28f636SEnrico Perla - Sun Microsystems do_version = B_FALSE; 247af28f636SEnrico Perla - Sun Microsystems } 248af28f636SEnrico Perla - Sun Microsystems if (force_update) { 249af28f636SEnrico Perla - Sun Microsystems (void) fprintf(stderr, MEANINGLESS_OPT, "-F"); 250af28f636SEnrico Perla - Sun Microsystems force_update = B_FALSE; 251af28f636SEnrico Perla - Sun Microsystems } 252af28f636SEnrico Perla - Sun Microsystems if (strip || verbose_dump) { 253af28f636SEnrico Perla - Sun Microsystems BOOT_DEBUG(MEANINGLESS_OPT, "-e|-V"); 254af28f636SEnrico Perla - Sun Microsystems strip = B_FALSE; 255af28f636SEnrico Perla - Sun Microsystems verbose_dump = B_FALSE; 256af28f636SEnrico Perla - Sun Microsystems } 257af28f636SEnrico Perla - Sun Microsystems } 258af28f636SEnrico Perla - Sun Microsystems 259af28f636SEnrico Perla - Sun Microsystems if (do_getinfo) { 260af28f636SEnrico Perla - Sun Microsystems if (write_mbr || force_mbr || do_version || force_update) { 261af28f636SEnrico Perla - Sun Microsystems BOOT_DEBUG(MEANINGLESS_OPT, "-m|-f|-u|-F"); 262af28f636SEnrico Perla - Sun Microsystems write_mbr = force_mbr = do_version = B_FALSE; 263af28f636SEnrico Perla - Sun Microsystems force_update = B_FALSE; 264af28f636SEnrico Perla - Sun Microsystems } 265af28f636SEnrico Perla - Sun Microsystems } 266af28f636SEnrico Perla - Sun Microsystems } 267af28f636SEnrico Perla - Sun Microsystems 268af28f636SEnrico Perla - Sun Microsystems /* 269af28f636SEnrico Perla - Sun Microsystems * Install a new stage1/stage2 pair on the specified device. handle_install() 270af28f636SEnrico Perla - Sun Microsystems * expects argv to contain 3 parameters (the path to stage1, the path to stage2, 271af28f636SEnrico Perla - Sun Microsystems * the target device). 272af28f636SEnrico Perla - Sun Microsystems * 273af28f636SEnrico Perla - Sun Microsystems * Returns: BC_SUCCESS - if the installation is successful 274af28f636SEnrico Perla - Sun Microsystems * BC_ERROR - if the installation failed 275af28f636SEnrico Perla - Sun Microsystems * BC_NOUPDT - if no installation was performed because the GRUB 276af28f636SEnrico Perla - Sun Microsystems * version currently installed is more recent than the 277af28f636SEnrico Perla - Sun Microsystems * supplied one. 278af28f636SEnrico Perla - Sun Microsystems * 279af28f636SEnrico Perla - Sun Microsystems */ 280af28f636SEnrico Perla - Sun Microsystems static int 281af28f636SEnrico Perla - Sun Microsystems handle_install(char *progname, char **argv) 282af28f636SEnrico Perla - Sun Microsystems { 283af28f636SEnrico Perla - Sun Microsystems ig_data_t install_data; 284af28f636SEnrico Perla - Sun Microsystems char *stage1_path = NULL; 285af28f636SEnrico Perla - Sun Microsystems char *stage2_path = NULL; 286af28f636SEnrico Perla - Sun Microsystems char *device_path = NULL; 287af28f636SEnrico Perla - Sun Microsystems int ret = BC_ERROR; 288af28f636SEnrico Perla - Sun Microsystems 289af28f636SEnrico Perla - Sun Microsystems stage1_path = strdup(argv[0]); 290af28f636SEnrico Perla - Sun Microsystems stage2_path = strdup(argv[1]); 291af28f636SEnrico Perla - Sun Microsystems device_path = strdup(argv[2]); 292af28f636SEnrico Perla - Sun Microsystems 293af28f636SEnrico Perla - Sun Microsystems bzero(&install_data, sizeof (ig_data_t)); 294af28f636SEnrico Perla - Sun Microsystems 295af28f636SEnrico Perla - Sun Microsystems if (!stage1_path || !stage2_path || !device_path) { 296af28f636SEnrico Perla - Sun Microsystems (void) fprintf(stderr, gettext("Missing parameter")); 297af28f636SEnrico Perla - Sun Microsystems usage(progname); 298af28f636SEnrico Perla - Sun Microsystems goto out; 299af28f636SEnrico Perla - Sun Microsystems } 300af28f636SEnrico Perla - Sun Microsystems 301af28f636SEnrico Perla - Sun Microsystems BOOT_DEBUG("stage1 path: %s, stage2 path: %s, device: %s\n", 302af28f636SEnrico Perla - Sun Microsystems stage1_path, stage2_path, device_path); 303af28f636SEnrico Perla - Sun Microsystems 304af28f636SEnrico Perla - Sun Microsystems if (init_device(&install_data.device, device_path) != BC_SUCCESS) { 305af28f636SEnrico Perla - Sun Microsystems (void) fprintf(stderr, gettext("Unable to gather device " 306af28f636SEnrico Perla - Sun Microsystems "information for %s\n"), device_path); 307af28f636SEnrico Perla - Sun Microsystems goto out; 308af28f636SEnrico Perla - Sun Microsystems } 309af28f636SEnrico Perla - Sun Microsystems 310af28f636SEnrico Perla - Sun Microsystems /* read in stage1 and stage2. */ 311af28f636SEnrico Perla - Sun Microsystems if (read_stage1_from_file(stage1_path, &install_data) != BC_SUCCESS) { 312af28f636SEnrico Perla - Sun Microsystems (void) fprintf(stderr, gettext("Error opening %s\n"), 313af28f636SEnrico Perla - Sun Microsystems stage1_path); 314af28f636SEnrico Perla - Sun Microsystems goto out_dev; 315af28f636SEnrico Perla - Sun Microsystems } 316af28f636SEnrico Perla - Sun Microsystems 317af28f636SEnrico Perla - Sun Microsystems if (read_stage2_from_file(stage2_path, &install_data) != BC_SUCCESS) { 318af28f636SEnrico Perla - Sun Microsystems (void) fprintf(stderr, gettext("Error opening %s\n"), 319af28f636SEnrico Perla - Sun Microsystems stage2_path); 320af28f636SEnrico Perla - Sun Microsystems goto out_dev; 321af28f636SEnrico Perla - Sun Microsystems } 322af28f636SEnrico Perla - Sun Microsystems 323af28f636SEnrico Perla - Sun Microsystems /* We do not support versioning on PCFS. */ 324af28f636SEnrico Perla - Sun Microsystems if (is_bootpar(install_data.device.type) && do_version) 325af28f636SEnrico Perla - Sun Microsystems do_version = B_FALSE; 326af28f636SEnrico Perla - Sun Microsystems 327af28f636SEnrico Perla - Sun Microsystems /* 328af28f636SEnrico Perla - Sun Microsystems * is_update_necessary() will take care of checking if versioning and/or 329af28f636SEnrico Perla - Sun Microsystems * forcing the update have been specified. It will also emit a warning 330af28f636SEnrico Perla - Sun Microsystems * if a non-versioned update is attempted over a versioned bootblock. 331af28f636SEnrico Perla - Sun Microsystems */ 332af28f636SEnrico Perla - Sun Microsystems if (!is_update_necessary(&install_data, update_str)) { 333af28f636SEnrico Perla - Sun Microsystems (void) fprintf(stderr, gettext("GRUB version installed " 334af28f636SEnrico Perla - Sun Microsystems "on %s is more recent or identical\n" 335af28f636SEnrico Perla - Sun Microsystems "Use -F to override or install without the -u option\n"), 336af28f636SEnrico Perla - Sun Microsystems device_path); 337af28f636SEnrico Perla - Sun Microsystems ret = BC_NOUPDT; 338af28f636SEnrico Perla - Sun Microsystems goto out_dev; 339af28f636SEnrico Perla - Sun Microsystems } 340af28f636SEnrico Perla - Sun Microsystems /* 341af28f636SEnrico Perla - Sun Microsystems * We get here if: 342af28f636SEnrico Perla - Sun Microsystems * - the installed GRUB version is older than the one about to be 343af28f636SEnrico Perla - Sun Microsystems * installed. 344af28f636SEnrico Perla - Sun Microsystems * - no versioning string has been passed through the command line. 345af28f636SEnrico Perla - Sun Microsystems * - a forced update is requested (-F). 346af28f636SEnrico Perla - Sun Microsystems */ 347af28f636SEnrico Perla - Sun Microsystems BOOT_DEBUG("Ready to commit to disk\n"); 348af28f636SEnrico Perla - Sun Microsystems ret = commit_to_disk(&install_data, update_str); 349af28f636SEnrico Perla - Sun Microsystems 350af28f636SEnrico Perla - Sun Microsystems out_dev: 351af28f636SEnrico Perla - Sun Microsystems cleanup_device(&install_data.device); 352af28f636SEnrico Perla - Sun Microsystems out: 353af28f636SEnrico Perla - Sun Microsystems free(stage1_path); 354af28f636SEnrico Perla - Sun Microsystems free(stage2_path); 355af28f636SEnrico Perla - Sun Microsystems free(device_path); 356af28f636SEnrico Perla - Sun Microsystems return (ret); 357af28f636SEnrico Perla - Sun Microsystems } 358af28f636SEnrico Perla - Sun Microsystems 359af28f636SEnrico Perla - Sun Microsystems /* 360af28f636SEnrico Perla - Sun Microsystems * Retrieves from a device the extended information (einfo) associated to the 361af28f636SEnrico Perla - Sun Microsystems * installed stage2. 362af28f636SEnrico Perla - Sun Microsystems * Expects one parameter, the device path, in the form: /dev/rdsk/c?[t?]d?s0. 363af28f636SEnrico Perla - Sun Microsystems * Returns: 364af28f636SEnrico Perla - Sun Microsystems * - BC_SUCCESS (and prints out einfo contents depending on 'flags') 365af28f636SEnrico Perla - Sun Microsystems * - BC_ERROR (on error) 366af28f636SEnrico Perla - Sun Microsystems * - BC_NOEINFO (no extended information available) 367af28f636SEnrico Perla - Sun Microsystems */ 368af28f636SEnrico Perla - Sun Microsystems static int 369af28f636SEnrico Perla - Sun Microsystems handle_getinfo(char *progname, char **argv) 370af28f636SEnrico Perla - Sun Microsystems { 371af28f636SEnrico Perla - Sun Microsystems ig_data_t data; 372af28f636SEnrico Perla - Sun Microsystems ig_stage2_t *stage2 = &data.stage2; 373af28f636SEnrico Perla - Sun Microsystems ig_device_t *device = &data.device; 374af28f636SEnrico Perla - Sun Microsystems bblk_einfo_t *einfo; 375af28f636SEnrico Perla - Sun Microsystems uint8_t flags = 0; 376af28f636SEnrico Perla - Sun Microsystems uint32_t size; 377af28f636SEnrico Perla - Sun Microsystems char *device_path; 378af28f636SEnrico Perla - Sun Microsystems int retval = BC_ERROR; 379af28f636SEnrico Perla - Sun Microsystems int ret; 380af28f636SEnrico Perla - Sun Microsystems 381af28f636SEnrico Perla - Sun Microsystems device_path = strdup(argv[0]); 382af28f636SEnrico Perla - Sun Microsystems if (!device_path) { 383af28f636SEnrico Perla - Sun Microsystems (void) fprintf(stderr, gettext("Missing parameter")); 384af28f636SEnrico Perla - Sun Microsystems usage(progname); 385af28f636SEnrico Perla - Sun Microsystems goto out; 386af28f636SEnrico Perla - Sun Microsystems } 387af28f636SEnrico Perla - Sun Microsystems 388af28f636SEnrico Perla - Sun Microsystems bzero(&data, sizeof (ig_data_t)); 389af28f636SEnrico Perla - Sun Microsystems BOOT_DEBUG("device path: %s\n", device_path); 390af28f636SEnrico Perla - Sun Microsystems 391af28f636SEnrico Perla - Sun Microsystems if (init_device(device, device_path) != BC_SUCCESS) { 392af28f636SEnrico Perla - Sun Microsystems (void) fprintf(stderr, gettext("Unable to gather device " 393af28f636SEnrico Perla - Sun Microsystems "information for %s\n"), device_path); 394af28f636SEnrico Perla - Sun Microsystems goto out_dev; 395af28f636SEnrico Perla - Sun Microsystems } 396af28f636SEnrico Perla - Sun Microsystems 397af28f636SEnrico Perla - Sun Microsystems if (is_bootpar(device->type)) { 398af28f636SEnrico Perla - Sun Microsystems (void) fprintf(stderr, gettext("Versioning not supported on " 399af28f636SEnrico Perla - Sun Microsystems "PCFS\n")); 400af28f636SEnrico Perla - Sun Microsystems goto out_dev; 401af28f636SEnrico Perla - Sun Microsystems } 402af28f636SEnrico Perla - Sun Microsystems 4031a902ef8SHans Rosenfeld ret = read_stage2_from_disk(device->part_fd, stage2, device->type); 404af28f636SEnrico Perla - Sun Microsystems if (ret == BC_ERROR) { 405af28f636SEnrico Perla - Sun Microsystems (void) fprintf(stderr, gettext("Error reading stage2 from " 406af28f636SEnrico Perla - Sun Microsystems "%s\n"), device_path); 407af28f636SEnrico Perla - Sun Microsystems goto out_dev; 408af28f636SEnrico Perla - Sun Microsystems } 409af28f636SEnrico Perla - Sun Microsystems 410af28f636SEnrico Perla - Sun Microsystems if (ret == BC_NOEXTRA) { 411af28f636SEnrico Perla - Sun Microsystems (void) fprintf(stdout, gettext("No multiboot header found on " 412af28f636SEnrico Perla - Sun Microsystems "%s, unable to locate extra information area\n"), 413af28f636SEnrico Perla - Sun Microsystems device_path); 414af28f636SEnrico Perla - Sun Microsystems retval = BC_NOEINFO; 415af28f636SEnrico Perla - Sun Microsystems goto out_dev; 416af28f636SEnrico Perla - Sun Microsystems } 417af28f636SEnrico Perla - Sun Microsystems 41814d44f22SHans Rosenfeld einfo = find_einfo(stage2->extra, stage2->extra_size); 419af28f636SEnrico Perla - Sun Microsystems if (einfo == NULL) { 420af28f636SEnrico Perla - Sun Microsystems retval = BC_NOEINFO; 421af28f636SEnrico Perla - Sun Microsystems (void) fprintf(stderr, gettext("No extended information " 422af28f636SEnrico Perla - Sun Microsystems "found\n")); 423af28f636SEnrico Perla - Sun Microsystems goto out_dev; 424af28f636SEnrico Perla - Sun Microsystems } 425af28f636SEnrico Perla - Sun Microsystems 426af28f636SEnrico Perla - Sun Microsystems /* Print the extended information. */ 427af28f636SEnrico Perla - Sun Microsystems if (strip) 428af28f636SEnrico Perla - Sun Microsystems flags |= EINFO_EASY_PARSE; 429af28f636SEnrico Perla - Sun Microsystems if (verbose_dump) 430af28f636SEnrico Perla - Sun Microsystems flags |= EINFO_PRINT_HEADER; 431af28f636SEnrico Perla - Sun Microsystems 432af28f636SEnrico Perla - Sun Microsystems size = stage2->buf_size - P2ROUNDUP(stage2->file_size, 8); 433af28f636SEnrico Perla - Sun Microsystems print_einfo(flags, einfo, size); 434af28f636SEnrico Perla - Sun Microsystems retval = BC_SUCCESS; 435af28f636SEnrico Perla - Sun Microsystems 436af28f636SEnrico Perla - Sun Microsystems out_dev: 437af28f636SEnrico Perla - Sun Microsystems cleanup_device(&data.device); 438af28f636SEnrico Perla - Sun Microsystems out: 439af28f636SEnrico Perla - Sun Microsystems free(device_path); 440af28f636SEnrico Perla - Sun Microsystems return (retval); 441af28f636SEnrico Perla - Sun Microsystems } 442af28f636SEnrico Perla - Sun Microsystems 443af28f636SEnrico Perla - Sun Microsystems /* 444af28f636SEnrico Perla - Sun Microsystems * Attempt to mirror (propagate) the current stage2 over the attaching disk. 445af28f636SEnrico Perla - Sun Microsystems * 446af28f636SEnrico Perla - Sun Microsystems * Returns: 447af28f636SEnrico Perla - Sun Microsystems * - BC_SUCCESS (a successful propagation happened) 448af28f636SEnrico Perla - Sun Microsystems * - BC_ERROR (an error occurred) 449af28f636SEnrico Perla - Sun Microsystems * - BC_NOEXTRA (it is not possible to dump the current bootblock since 450af28f636SEnrico Perla - Sun Microsystems * there is no multiboot information) 451af28f636SEnrico Perla - Sun Microsystems */ 452af28f636SEnrico Perla - Sun Microsystems static int 453af28f636SEnrico Perla - Sun Microsystems handle_mirror(char *progname, char **argv) 454af28f636SEnrico Perla - Sun Microsystems { 455af28f636SEnrico Perla - Sun Microsystems ig_data_t curr_data; 456af28f636SEnrico Perla - Sun Microsystems ig_data_t attach_data; 457af28f636SEnrico Perla - Sun Microsystems ig_device_t *curr_device = &curr_data.device; 458af28f636SEnrico Perla - Sun Microsystems ig_device_t *attach_device = &attach_data.device; 459af28f636SEnrico Perla - Sun Microsystems ig_stage2_t *stage2_curr = &curr_data.stage2; 460af28f636SEnrico Perla - Sun Microsystems ig_stage2_t *stage2_attach = &attach_data.stage2; 461af28f636SEnrico Perla - Sun Microsystems bblk_einfo_t *einfo_curr = NULL; 462af28f636SEnrico Perla - Sun Microsystems char *curr_device_path; 463af28f636SEnrico Perla - Sun Microsystems char *attach_device_path; 464af28f636SEnrico Perla - Sun Microsystems char *updt_str = NULL; 465af28f636SEnrico Perla - Sun Microsystems int retval = BC_ERROR; 466af28f636SEnrico Perla - Sun Microsystems int ret; 467af28f636SEnrico Perla - Sun Microsystems 468af28f636SEnrico Perla - Sun Microsystems curr_device_path = strdup(argv[0]); 469af28f636SEnrico Perla - Sun Microsystems attach_device_path = strdup(argv[1]); 470af28f636SEnrico Perla - Sun Microsystems 471af28f636SEnrico Perla - Sun Microsystems if (!curr_device_path || !attach_device_path) { 472af28f636SEnrico Perla - Sun Microsystems (void) fprintf(stderr, gettext("Missing parameter")); 473af28f636SEnrico Perla - Sun Microsystems usage(progname); 474af28f636SEnrico Perla - Sun Microsystems goto out; 475af28f636SEnrico Perla - Sun Microsystems } 476af28f636SEnrico Perla - Sun Microsystems BOOT_DEBUG("Current device path is: %s, attaching device path is: " 477af28f636SEnrico Perla - Sun Microsystems " %s\n", curr_device_path, attach_device_path); 478af28f636SEnrico Perla - Sun Microsystems 479af28f636SEnrico Perla - Sun Microsystems bzero(&curr_data, sizeof (ig_data_t)); 480af28f636SEnrico Perla - Sun Microsystems bzero(&attach_data, sizeof (ig_data_t)); 481af28f636SEnrico Perla - Sun Microsystems 482af28f636SEnrico Perla - Sun Microsystems if (init_device(curr_device, curr_device_path) != BC_SUCCESS) { 483af28f636SEnrico Perla - Sun Microsystems (void) fprintf(stderr, gettext("Unable to gather device " 484af28f636SEnrico Perla - Sun Microsystems "information for %s (current device)\n"), curr_device_path); 485af28f636SEnrico Perla - Sun Microsystems goto out_currdev; 486af28f636SEnrico Perla - Sun Microsystems } 487af28f636SEnrico Perla - Sun Microsystems 488af28f636SEnrico Perla - Sun Microsystems if (init_device(attach_device, attach_device_path) != BC_SUCCESS) { 489af28f636SEnrico Perla - Sun Microsystems (void) fprintf(stderr, gettext("Unable to gather device " 490af28f636SEnrico Perla - Sun Microsystems "information for %s (attaching device)\n"), 491af28f636SEnrico Perla - Sun Microsystems attach_device_path); 492af28f636SEnrico Perla - Sun Microsystems goto out_devs; 493af28f636SEnrico Perla - Sun Microsystems } 494af28f636SEnrico Perla - Sun Microsystems 495af28f636SEnrico Perla - Sun Microsystems if (is_bootpar(curr_device->type) || is_bootpar(attach_device->type)) { 496af28f636SEnrico Perla - Sun Microsystems (void) fprintf(stderr, gettext("boot block mirroring is not " 497af28f636SEnrico Perla - Sun Microsystems "supported on PCFS\n")); 498af28f636SEnrico Perla - Sun Microsystems goto out_devs; 499af28f636SEnrico Perla - Sun Microsystems } 500af28f636SEnrico Perla - Sun Microsystems 5011a902ef8SHans Rosenfeld ret = read_stage2_from_disk(curr_device->part_fd, stage2_curr, 5021a902ef8SHans Rosenfeld curr_device->type); 503af28f636SEnrico Perla - Sun Microsystems if (ret == BC_ERROR) { 504af28f636SEnrico Perla - Sun Microsystems BOOT_DEBUG("Error reading first stage2 blocks from %s\n", 505af28f636SEnrico Perla - Sun Microsystems curr_device->path); 506af28f636SEnrico Perla - Sun Microsystems retval = BC_ERROR; 507af28f636SEnrico Perla - Sun Microsystems goto out_devs; 508af28f636SEnrico Perla - Sun Microsystems } 509af28f636SEnrico Perla - Sun Microsystems 510af28f636SEnrico Perla - Sun Microsystems if (ret == BC_NOEXTRA) { 511af28f636SEnrico Perla - Sun Microsystems BOOT_DEBUG("No multiboot header found on %s, unable to grab " 512af28f636SEnrico Perla - Sun Microsystems "stage2\n", curr_device->path); 513af28f636SEnrico Perla - Sun Microsystems retval = BC_NOEXTRA; 514af28f636SEnrico Perla - Sun Microsystems goto out_devs; 515af28f636SEnrico Perla - Sun Microsystems } 516af28f636SEnrico Perla - Sun Microsystems 51714d44f22SHans Rosenfeld einfo_curr = find_einfo(stage2_curr->extra, stage2_curr->extra_size); 518af28f636SEnrico Perla - Sun Microsystems if (einfo_curr != NULL) 519af28f636SEnrico Perla - Sun Microsystems updt_str = einfo_get_string(einfo_curr); 520af28f636SEnrico Perla - Sun Microsystems 521af28f636SEnrico Perla - Sun Microsystems write_mbr = B_TRUE; 522af28f636SEnrico Perla - Sun Microsystems force_mbr = B_TRUE; 523af28f636SEnrico Perla - Sun Microsystems retval = propagate_bootblock(&curr_data, &attach_data, updt_str); 524af28f636SEnrico Perla - Sun Microsystems cleanup_stage2(stage2_curr); 525af28f636SEnrico Perla - Sun Microsystems cleanup_stage2(stage2_attach); 526af28f636SEnrico Perla - Sun Microsystems 527af28f636SEnrico Perla - Sun Microsystems out_devs: 528af28f636SEnrico Perla - Sun Microsystems cleanup_device(attach_device); 529af28f636SEnrico Perla - Sun Microsystems out_currdev: 530af28f636SEnrico Perla - Sun Microsystems cleanup_device(curr_device); 531af28f636SEnrico Perla - Sun Microsystems out: 532af28f636SEnrico Perla - Sun Microsystems free(curr_device_path); 533af28f636SEnrico Perla - Sun Microsystems free(attach_device_path); 534af28f636SEnrico Perla - Sun Microsystems return (retval); 535af28f636SEnrico Perla - Sun Microsystems } 536af28f636SEnrico Perla - Sun Microsystems 537af28f636SEnrico Perla - Sun Microsystems static int 538af28f636SEnrico Perla - Sun Microsystems commit_to_disk(ig_data_t *install, char *updt_str) 539af28f636SEnrico Perla - Sun Microsystems { 540af28f636SEnrico Perla - Sun Microsystems assert(install != NULL); 541af28f636SEnrico Perla - Sun Microsystems /* 542af28f636SEnrico Perla - Sun Microsystems * vanilla stage1 and stage2 need to be updated at runtime. 543af28f636SEnrico Perla - Sun Microsystems * Update stage2 before stage1 because stage1 needs to know the first 544af28f636SEnrico Perla - Sun Microsystems * sector stage2 will be written to. 545af28f636SEnrico Perla - Sun Microsystems */ 546af28f636SEnrico Perla - Sun Microsystems if (prepare_stage2(install, updt_str) != BC_SUCCESS) { 547af28f636SEnrico Perla - Sun Microsystems (void) fprintf(stderr, gettext("Error building stage2\n")); 548af28f636SEnrico Perla - Sun Microsystems return (BC_ERROR); 549af28f636SEnrico Perla - Sun Microsystems } 550af28f636SEnrico Perla - Sun Microsystems if (prepare_stage1(install) != BC_SUCCESS) { 551af28f636SEnrico Perla - Sun Microsystems (void) fprintf(stderr, gettext("Error building stage1\n")); 552af28f636SEnrico Perla - Sun Microsystems return (BC_ERROR); 553af28f636SEnrico Perla - Sun Microsystems } 554af28f636SEnrico Perla - Sun Microsystems 555af28f636SEnrico Perla - Sun Microsystems /* Write stage2 out to disk. */ 556af28f636SEnrico Perla - Sun Microsystems if (write_stage2(install) != BC_SUCCESS) { 557af28f636SEnrico Perla - Sun Microsystems (void) fprintf(stderr, gettext("Error writing stage2 to " 558af28f636SEnrico Perla - Sun Microsystems "disk\n")); 559af28f636SEnrico Perla - Sun Microsystems return (BC_ERROR); 560af28f636SEnrico Perla - Sun Microsystems } 561af28f636SEnrico Perla - Sun Microsystems 562af28f636SEnrico Perla - Sun Microsystems /* Write stage1 to disk and, if requested, to the MBR. */ 563af28f636SEnrico Perla - Sun Microsystems if (write_stage1(install) != BC_SUCCESS) { 564af28f636SEnrico Perla - Sun Microsystems (void) fprintf(stderr, gettext("Error writing stage1 to " 565af28f636SEnrico Perla - Sun Microsystems "disk\n")); 566af28f636SEnrico Perla - Sun Microsystems return (BC_ERROR); 567af28f636SEnrico Perla - Sun Microsystems } 568af28f636SEnrico Perla - Sun Microsystems 569af28f636SEnrico Perla - Sun Microsystems return (BC_SUCCESS); 570af28f636SEnrico Perla - Sun Microsystems } 571af28f636SEnrico Perla - Sun Microsystems 572af28f636SEnrico Perla - Sun Microsystems /* 573af28f636SEnrico Perla - Sun Microsystems * Propagate the bootblock on the source disk to the destination disk and 574af28f636SEnrico Perla - Sun Microsystems * version it with 'updt_str' in the process. Since we cannot trust any data 575af28f636SEnrico Perla - Sun Microsystems * on the attaching disk, we do not perform any specific check on a potential 576af28f636SEnrico Perla - Sun Microsystems * target extended information structure and we just blindly update. 577af28f636SEnrico Perla - Sun Microsystems */ 578af28f636SEnrico Perla - Sun Microsystems static int 579af28f636SEnrico Perla - Sun Microsystems propagate_bootblock(ig_data_t *source, ig_data_t *target, char *updt_str) 580af28f636SEnrico Perla - Sun Microsystems { 581af28f636SEnrico Perla - Sun Microsystems ig_device_t *src_device = &source->device; 582af28f636SEnrico Perla - Sun Microsystems ig_device_t *dest_device = &target->device; 583af28f636SEnrico Perla - Sun Microsystems ig_stage2_t *src_stage2 = &source->stage2; 584af28f636SEnrico Perla - Sun Microsystems ig_stage2_t *dest_stage2 = &target->stage2; 585af28f636SEnrico Perla - Sun Microsystems uint32_t buf_size; 586af28f636SEnrico Perla - Sun Microsystems int retval; 587af28f636SEnrico Perla - Sun Microsystems 588af28f636SEnrico Perla - Sun Microsystems assert(source != NULL); 589af28f636SEnrico Perla - Sun Microsystems assert(target != NULL); 590af28f636SEnrico Perla - Sun Microsystems 591af28f636SEnrico Perla - Sun Microsystems /* read in stage1 from the source disk. */ 592af28f636SEnrico Perla - Sun Microsystems if (read_stage1_from_disk(src_device->part_fd, target->stage1_buf) 593af28f636SEnrico Perla - Sun Microsystems != BC_SUCCESS) 594af28f636SEnrico Perla - Sun Microsystems return (BC_ERROR); 595af28f636SEnrico Perla - Sun Microsystems 596af28f636SEnrico Perla - Sun Microsystems /* Prepare target stage2 for commit_to_disk. */ 597af28f636SEnrico Perla - Sun Microsystems cleanup_stage2(dest_stage2); 598af28f636SEnrico Perla - Sun Microsystems 599af28f636SEnrico Perla - Sun Microsystems if (updt_str != NULL) 600af28f636SEnrico Perla - Sun Microsystems do_version = B_TRUE; 601af28f636SEnrico Perla - Sun Microsystems else 602af28f636SEnrico Perla - Sun Microsystems do_version = B_FALSE; 603af28f636SEnrico Perla - Sun Microsystems 604af28f636SEnrico Perla - Sun Microsystems buf_size = src_stage2->file_size + SECTOR_SIZE; 605af28f636SEnrico Perla - Sun Microsystems 606af28f636SEnrico Perla - Sun Microsystems dest_stage2->buf_size = P2ROUNDUP(buf_size, SECTOR_SIZE); 607af28f636SEnrico Perla - Sun Microsystems dest_stage2->buf = malloc(dest_stage2->buf_size); 608af28f636SEnrico Perla - Sun Microsystems if (dest_stage2->buf == NULL) { 609af28f636SEnrico Perla - Sun Microsystems perror(gettext("Memory allocation failed")); 610af28f636SEnrico Perla - Sun Microsystems return (BC_ERROR); 611af28f636SEnrico Perla - Sun Microsystems } 612af28f636SEnrico Perla - Sun Microsystems dest_stage2->file = dest_stage2->buf; 613af28f636SEnrico Perla - Sun Microsystems dest_stage2->file_size = src_stage2->file_size; 614af28f636SEnrico Perla - Sun Microsystems memcpy(dest_stage2->file, src_stage2->file, dest_stage2->file_size); 615af28f636SEnrico Perla - Sun Microsystems dest_stage2->extra = dest_stage2->buf + 616af28f636SEnrico Perla - Sun Microsystems P2ROUNDUP(dest_stage2->file_size, 8); 617af28f636SEnrico Perla - Sun Microsystems 618af28f636SEnrico Perla - Sun Microsystems /* If we get down here we do have a mboot structure. */ 619af28f636SEnrico Perla - Sun Microsystems assert(src_stage2->mboot); 620af28f636SEnrico Perla - Sun Microsystems 621af28f636SEnrico Perla - Sun Microsystems dest_stage2->mboot_off = src_stage2->mboot_off; 622af28f636SEnrico Perla - Sun Microsystems dest_stage2->mboot = (multiboot_header_t *)(dest_stage2->buf + 623af28f636SEnrico Perla - Sun Microsystems dest_stage2->mboot_off); 624af28f636SEnrico Perla - Sun Microsystems 625af28f636SEnrico Perla - Sun Microsystems (void) fprintf(stdout, gettext("Propagating %s stage1/stage2 to %s\n"), 626af28f636SEnrico Perla - Sun Microsystems src_device->path, dest_device->path); 627af28f636SEnrico Perla - Sun Microsystems retval = commit_to_disk(target, updt_str); 628af28f636SEnrico Perla - Sun Microsystems 629af28f636SEnrico Perla - Sun Microsystems return (retval); 630af28f636SEnrico Perla - Sun Microsystems } 631af28f636SEnrico Perla - Sun Microsystems 632af28f636SEnrico Perla - Sun Microsystems /* 633af28f636SEnrico Perla - Sun Microsystems * open the device and fill the various members of ig_device_t. 634af28f636SEnrico Perla - Sun Microsystems */ 635af28f636SEnrico Perla - Sun Microsystems static int 636af28f636SEnrico Perla - Sun Microsystems init_device(ig_device_t *device, char *path) 637af28f636SEnrico Perla - Sun Microsystems { 6381a902ef8SHans Rosenfeld struct dk_gpt *vtoc; 6391a902ef8SHans Rosenfeld fstyp_handle_t fhdl; 6401a902ef8SHans Rosenfeld const char *fident; 6411a902ef8SHans Rosenfeld 642af28f636SEnrico Perla - Sun Microsystems bzero(device, sizeof (*device)); 643af28f636SEnrico Perla - Sun Microsystems device->part_fd = -1; 644af28f636SEnrico Perla - Sun Microsystems device->disk_fd = -1; 645af28f636SEnrico Perla - Sun Microsystems device->path_p0 = NULL; 646af28f636SEnrico Perla - Sun Microsystems 647af28f636SEnrico Perla - Sun Microsystems device->path = strdup(path); 648af28f636SEnrico Perla - Sun Microsystems if (device->path == NULL) { 649af28f636SEnrico Perla - Sun Microsystems perror(gettext("Memory allocation failed")); 650af28f636SEnrico Perla - Sun Microsystems return (BC_ERROR); 651af28f636SEnrico Perla - Sun Microsystems } 652af28f636SEnrico Perla - Sun Microsystems 653af28f636SEnrico Perla - Sun Microsystems if (strstr(device->path, "diskette")) { 654af28f636SEnrico Perla - Sun Microsystems (void) fprintf(stderr, gettext("installing GRUB to a floppy " 655af28f636SEnrico Perla - Sun Microsystems "disk is no longer supported\n")); 656af28f636SEnrico Perla - Sun Microsystems return (BC_ERROR); 657af28f636SEnrico Perla - Sun Microsystems } 658af28f636SEnrico Perla - Sun Microsystems 659af28f636SEnrico Perla - Sun Microsystems /* Detect if the target device is a pcfs partition. */ 660af28f636SEnrico Perla - Sun Microsystems if (strstr(device->path, "p0:boot")) 661af28f636SEnrico Perla - Sun Microsystems device->type = IG_DEV_X86BOOTPAR; 662af28f636SEnrico Perla - Sun Microsystems 663af28f636SEnrico Perla - Sun Microsystems if (get_disk_fd(device) != BC_SUCCESS) 664af28f636SEnrico Perla - Sun Microsystems return (BC_ERROR); 665af28f636SEnrico Perla - Sun Microsystems 666af28f636SEnrico Perla - Sun Microsystems /* read in the device boot sector. */ 667af28f636SEnrico Perla - Sun Microsystems if (read(device->disk_fd, device->boot_sector, SECTOR_SIZE) 668af28f636SEnrico Perla - Sun Microsystems != SECTOR_SIZE) { 669af28f636SEnrico Perla - Sun Microsystems (void) fprintf(stderr, gettext("Error reading boot sector\n")); 670af28f636SEnrico Perla - Sun Microsystems perror("read"); 671af28f636SEnrico Perla - Sun Microsystems return (BC_ERROR); 672af28f636SEnrico Perla - Sun Microsystems } 673af28f636SEnrico Perla - Sun Microsystems 674*cc641e8dSToomas Soome if (efi_alloc_and_read(device->disk_fd, &vtoc) >= 0) { 6751a902ef8SHans Rosenfeld device->type = IG_DEV_EFI; 6761a902ef8SHans Rosenfeld efi_free(vtoc); 6771a902ef8SHans Rosenfeld } 6781a902ef8SHans Rosenfeld 679af28f636SEnrico Perla - Sun Microsystems if (get_raw_partition_fd(device) != BC_SUCCESS) 680af28f636SEnrico Perla - Sun Microsystems return (BC_ERROR); 681af28f636SEnrico Perla - Sun Microsystems 6829348d232SHans Rosenfeld if (is_efi(device->type)) { 6831a902ef8SHans Rosenfeld if (fstyp_init(device->part_fd, 0, NULL, &fhdl) != 0) 6841a902ef8SHans Rosenfeld return (BC_ERROR); 6851a902ef8SHans Rosenfeld 6861a902ef8SHans Rosenfeld if (fstyp_ident(fhdl, "zfs", &fident) != 0) { 6871a902ef8SHans Rosenfeld fstyp_fini(fhdl); 6889348d232SHans Rosenfeld (void) fprintf(stderr, gettext("Booting of EFI labeled " 6899348d232SHans Rosenfeld "disks is only supported with ZFS\n")); 6901a902ef8SHans Rosenfeld return (BC_ERROR); 6911a902ef8SHans Rosenfeld } 6921a902ef8SHans Rosenfeld fstyp_fini(fhdl); 6939348d232SHans Rosenfeld } 6941a902ef8SHans Rosenfeld 695af28f636SEnrico Perla - Sun Microsystems if (get_start_sector(device) != BC_SUCCESS) 696af28f636SEnrico Perla - Sun Microsystems return (BC_ERROR); 697af28f636SEnrico Perla - Sun Microsystems 698af28f636SEnrico Perla - Sun Microsystems return (BC_SUCCESS); 699af28f636SEnrico Perla - Sun Microsystems } 700af28f636SEnrico Perla - Sun Microsystems 701af28f636SEnrico Perla - Sun Microsystems static void 702af28f636SEnrico Perla - Sun Microsystems cleanup_device(ig_device_t *device) 703af28f636SEnrico Perla - Sun Microsystems { 704af28f636SEnrico Perla - Sun Microsystems if (device->path) 705af28f636SEnrico Perla - Sun Microsystems free(device->path); 706af28f636SEnrico Perla - Sun Microsystems if (device->path_p0) 707af28f636SEnrico Perla - Sun Microsystems free(device->path_p0); 708af28f636SEnrico Perla - Sun Microsystems 709af28f636SEnrico Perla - Sun Microsystems if (device->part_fd != -1) 710af28f636SEnrico Perla - Sun Microsystems (void) close(device->part_fd); 711af28f636SEnrico Perla - Sun Microsystems if (device->disk_fd != -1) 712af28f636SEnrico Perla - Sun Microsystems (void) close(device->disk_fd); 713af28f636SEnrico Perla - Sun Microsystems 714af28f636SEnrico Perla - Sun Microsystems bzero(device, sizeof (ig_device_t)); 715af28f636SEnrico Perla - Sun Microsystems device->part_fd = -1; 716af28f636SEnrico Perla - Sun Microsystems device->disk_fd = -1; 717af28f636SEnrico Perla - Sun Microsystems } 718af28f636SEnrico Perla - Sun Microsystems 719af28f636SEnrico Perla - Sun Microsystems static void 720af28f636SEnrico Perla - Sun Microsystems cleanup_stage2(ig_stage2_t *stage2) 721af28f636SEnrico Perla - Sun Microsystems { 722af28f636SEnrico Perla - Sun Microsystems if (stage2->buf) 723af28f636SEnrico Perla - Sun Microsystems free(stage2->buf); 724af28f636SEnrico Perla - Sun Microsystems bzero(stage2, sizeof (ig_stage2_t)); 725af28f636SEnrico Perla - Sun Microsystems } 726af28f636SEnrico Perla - Sun Microsystems 727af28f636SEnrico Perla - Sun Microsystems static int 728af28f636SEnrico Perla - Sun Microsystems get_start_sector(ig_device_t *device) 729af28f636SEnrico Perla - Sun Microsystems { 7307fc5d2a4SVikram Hegde uint32_t secnum = 0, numsec = 0; 7317fc5d2a4SVikram Hegde int i, pno, rval, log_part = 0; 7327c478bd9Sstevel@tonic-gate struct mboot *mboot; 7337c478bd9Sstevel@tonic-gate struct ipart *part; 734aa1b14e7SSheshadri Vasudevan ext_part_t *epp; 7357fc5d2a4SVikram Hegde struct part_info dkpi; 7367fc5d2a4SVikram Hegde struct extpart_info edkpi; 7377c478bd9Sstevel@tonic-gate 7381a902ef8SHans Rosenfeld if (is_efi(device->type)) { 7391a902ef8SHans Rosenfeld struct dk_gpt *vtoc; 7401a902ef8SHans Rosenfeld 741*cc641e8dSToomas Soome if (efi_alloc_and_read(device->disk_fd, &vtoc) < 0) 7421a902ef8SHans Rosenfeld return (BC_ERROR); 7431a902ef8SHans Rosenfeld 7441a902ef8SHans Rosenfeld device->start_sector = vtoc->efi_parts[device->slice].p_start; 7451a902ef8SHans Rosenfeld /* GPT doesn't use traditional slice letters */ 7461a902ef8SHans Rosenfeld device->slice = 0xff; 7471a902ef8SHans Rosenfeld device->partition = 0; 7481a902ef8SHans Rosenfeld 7491a902ef8SHans Rosenfeld efi_free(vtoc); 7501a902ef8SHans Rosenfeld goto found_part; 7511a902ef8SHans Rosenfeld } 7521a902ef8SHans Rosenfeld 753af28f636SEnrico Perla - Sun Microsystems mboot = (struct mboot *)device->boot_sector; 7547c478bd9Sstevel@tonic-gate 755af28f636SEnrico Perla - Sun Microsystems if (is_bootpar(device->type)) { 756af28f636SEnrico Perla - Sun Microsystems if (find_x86_bootpar(mboot, &pno, &secnum) != BC_SUCCESS) { 757af28f636SEnrico Perla - Sun Microsystems (void) fprintf(stderr, NOBOOTPAR); 758af28f636SEnrico Perla - Sun Microsystems return (BC_ERROR); 759af28f636SEnrico Perla - Sun Microsystems } else { 760af28f636SEnrico Perla - Sun Microsystems device->start_sector = secnum; 761af28f636SEnrico Perla - Sun Microsystems device->partition = pno; 7627fc5d2a4SVikram Hegde goto found_part; 7637fc5d2a4SVikram Hegde } 764d33344bbSsy25831 } 765d33344bbSsy25831 766aa1b14e7SSheshadri Vasudevan /* 767af28f636SEnrico Perla - Sun Microsystems * Search for Solaris fdisk partition 768d33344bbSsy25831 * Get the solaris partition information from the device 769d33344bbSsy25831 * and compare the offset of S2 with offset of solaris partition 770d33344bbSsy25831 * from fdisk partition table. 771d33344bbSsy25831 */ 772af28f636SEnrico Perla - Sun Microsystems if (ioctl(device->part_fd, DKIOCEXTPARTINFO, &edkpi) < 0) { 773af28f636SEnrico Perla - Sun Microsystems if (ioctl(device->part_fd, DKIOCPARTINFO, &dkpi) < 0) { 774d33344bbSsy25831 (void) fprintf(stderr, PART_FAIL); 775af28f636SEnrico Perla - Sun Microsystems return (BC_ERROR); 776342440ecSPrasad Singamsetty } else { 777342440ecSPrasad Singamsetty edkpi.p_start = dkpi.p_start; 778342440ecSPrasad Singamsetty } 779d33344bbSsy25831 } 780d33344bbSsy25831 781d33344bbSsy25831 for (i = 0; i < FD_NUMPART; i++) { 782d33344bbSsy25831 part = (struct ipart *)mboot->parts + i; 783d33344bbSsy25831 784d33344bbSsy25831 if (part->relsect == 0) { 785d33344bbSsy25831 (void) fprintf(stderr, BAD_PART, i); 786af28f636SEnrico Perla - Sun Microsystems return (BC_ERROR); 787d33344bbSsy25831 } 788aa1b14e7SSheshadri Vasudevan 789342440ecSPrasad Singamsetty if (edkpi.p_start >= part->relsect && 790342440ecSPrasad Singamsetty edkpi.p_start < (part->relsect + part->numsect)) { 791d33344bbSsy25831 /* Found the partition */ 7927c478bd9Sstevel@tonic-gate break; 793d33344bbSsy25831 } 7947c478bd9Sstevel@tonic-gate } 7957c478bd9Sstevel@tonic-gate 7967fc5d2a4SVikram Hegde if (i == FD_NUMPART) { 7977fc5d2a4SVikram Hegde /* No solaris fdisk partitions (primary or logical) */ 7987fc5d2a4SVikram Hegde (void) fprintf(stderr, NOSOLPAR); 799af28f636SEnrico Perla - Sun Microsystems return (BC_ERROR); 8007c478bd9Sstevel@tonic-gate } 8017c478bd9Sstevel@tonic-gate 8027fc5d2a4SVikram Hegde /* 8037fc5d2a4SVikram Hegde * We have found a Solaris fdisk partition (primary or extended) 8047fc5d2a4SVikram Hegde * Handle the simple case first: Solaris in a primary partition 8057fc5d2a4SVikram Hegde */ 8067fc5d2a4SVikram Hegde if (!fdisk_is_dos_extended(part->systid)) { 807af28f636SEnrico Perla - Sun Microsystems device->start_sector = part->relsect; 808af28f636SEnrico Perla - Sun Microsystems device->partition = i; 8097fc5d2a4SVikram Hegde goto found_part; 8107fc5d2a4SVikram Hegde } 8117fc5d2a4SVikram Hegde 8127fc5d2a4SVikram Hegde /* 8137fc5d2a4SVikram Hegde * Solaris in a logical partition. Find that partition in the 8147fc5d2a4SVikram Hegde * extended part. 8157fc5d2a4SVikram Hegde */ 816af28f636SEnrico Perla - Sun Microsystems if ((rval = libfdisk_init(&epp, device->path_p0, NULL, FDISK_READ_DISK)) 8177fc5d2a4SVikram Hegde != FDISK_SUCCESS) { 8187fc5d2a4SVikram Hegde switch (rval) { 8197fc5d2a4SVikram Hegde /* 8206cb5747bSSharath M Srinivasan * The first 3 cases are not an error per-se, just that 8217fc5d2a4SVikram Hegde * there is no Solaris logical partition 8227fc5d2a4SVikram Hegde */ 8237fc5d2a4SVikram Hegde case FDISK_EBADLOGDRIVE: 8247fc5d2a4SVikram Hegde case FDISK_ENOLOGDRIVE: 8256cb5747bSSharath M Srinivasan case FDISK_EBADMAGIC: 8267fc5d2a4SVikram Hegde (void) fprintf(stderr, NOSOLPAR); 827af28f636SEnrico Perla - Sun Microsystems return (BC_ERROR); 8287fc5d2a4SVikram Hegde case FDISK_ENOVGEOM: 8297fc5d2a4SVikram Hegde (void) fprintf(stderr, NO_VIRT_GEOM); 830af28f636SEnrico Perla - Sun Microsystems return (BC_ERROR); 8317fc5d2a4SVikram Hegde case FDISK_ENOPGEOM: 8327fc5d2a4SVikram Hegde (void) fprintf(stderr, NO_PHYS_GEOM); 833af28f636SEnrico Perla - Sun Microsystems return (BC_ERROR); 8347fc5d2a4SVikram Hegde case FDISK_ENOLGEOM: 8357fc5d2a4SVikram Hegde (void) fprintf(stderr, NO_LABEL_GEOM); 836af28f636SEnrico Perla - Sun Microsystems return (BC_ERROR); 8377fc5d2a4SVikram Hegde default: 8387fc5d2a4SVikram Hegde (void) fprintf(stderr, LIBFDISK_INIT_FAIL); 839af28f636SEnrico Perla - Sun Microsystems return (BC_ERROR); 8407fc5d2a4SVikram Hegde } 8417fc5d2a4SVikram Hegde } 8427fc5d2a4SVikram Hegde 8437fc5d2a4SVikram Hegde rval = fdisk_get_solaris_part(epp, &pno, &secnum, &numsec); 8446cb5747bSSharath M Srinivasan libfdisk_fini(&epp); 8457fc5d2a4SVikram Hegde if (rval != FDISK_SUCCESS) { 8467fc5d2a4SVikram Hegde /* No solaris logical partition */ 8477fc5d2a4SVikram Hegde (void) fprintf(stderr, NOSOLPAR); 848af28f636SEnrico Perla - Sun Microsystems return (BC_ERROR); 8497fc5d2a4SVikram Hegde } 8507fc5d2a4SVikram Hegde 851af28f636SEnrico Perla - Sun Microsystems device->start_sector = secnum; 852af28f636SEnrico Perla - Sun Microsystems device->partition = pno - 1; 8537fc5d2a4SVikram Hegde log_part = 1; 8547fc5d2a4SVikram Hegde 8557fc5d2a4SVikram Hegde found_part: 8567c478bd9Sstevel@tonic-gate /* get confirmation for -m */ 857af28f636SEnrico Perla - Sun Microsystems if (write_mbr && !force_mbr) { 8587c478bd9Sstevel@tonic-gate (void) fprintf(stdout, MBOOT_PROMPT); 85921ba817cSToomas Soome if (!yes()) { 860af28f636SEnrico Perla - Sun Microsystems write_mbr = 0; 8617c478bd9Sstevel@tonic-gate (void) fprintf(stdout, MBOOT_NOT_UPDATED); 862af28f636SEnrico Perla - Sun Microsystems return (BC_ERROR); 8637c478bd9Sstevel@tonic-gate } 8647c478bd9Sstevel@tonic-gate } 8657c478bd9Sstevel@tonic-gate 8667fc5d2a4SVikram Hegde /* 8677fc5d2a4SVikram Hegde * Currently if Solaris is in an extended partition we need to 8687fc5d2a4SVikram Hegde * write GRUB to the MBR. Check for this. 8697fc5d2a4SVikram Hegde */ 870af28f636SEnrico Perla - Sun Microsystems if (log_part && !write_mbr) { 871af28f636SEnrico Perla - Sun Microsystems (void) fprintf(stdout, gettext("Installing Solaris on an " 872af28f636SEnrico Perla - Sun Microsystems "extended partition... forcing MBR update\n")); 873af28f636SEnrico Perla - Sun Microsystems write_mbr = 1; 874aa1b14e7SSheshadri Vasudevan } 875aa1b14e7SSheshadri Vasudevan 8767fc5d2a4SVikram Hegde /* 8777fc5d2a4SVikram Hegde * warn, if Solaris in primary partition and GRUB not in MBR and 8787fc5d2a4SVikram Hegde * partition is not active 8797fc5d2a4SVikram Hegde */ 880af28f636SEnrico Perla - Sun Microsystems if (!log_part && part->bootid != 128 && !write_mbr) { 881af28f636SEnrico Perla - Sun Microsystems (void) fprintf(stdout, SOLPAR_INACTIVE, device->partition + 1); 8827c478bd9Sstevel@tonic-gate } 8837c478bd9Sstevel@tonic-gate 884af28f636SEnrico Perla - Sun Microsystems return (BC_SUCCESS); 8857c478bd9Sstevel@tonic-gate } 8867c478bd9Sstevel@tonic-gate 887af28f636SEnrico Perla - Sun Microsystems static int 888af28f636SEnrico Perla - Sun Microsystems get_disk_fd(ig_device_t *device) 889af28f636SEnrico Perla - Sun Microsystems { 890af28f636SEnrico Perla - Sun Microsystems int i; 891af28f636SEnrico Perla - Sun Microsystems char save[2]; 892af28f636SEnrico Perla - Sun Microsystems char *end = NULL; 893af28f636SEnrico Perla - Sun Microsystems 894af28f636SEnrico Perla - Sun Microsystems assert(device != NULL); 895af28f636SEnrico Perla - Sun Microsystems assert(device->path != NULL); 896af28f636SEnrico Perla - Sun Microsystems 897af28f636SEnrico Perla - Sun Microsystems if (is_bootpar(device->type)) { 898af28f636SEnrico Perla - Sun Microsystems end = strstr(device->path, "p0:boot"); 899af28f636SEnrico Perla - Sun Microsystems /* tested at the start of init_device() */ 900af28f636SEnrico Perla - Sun Microsystems assert(end != NULL); 901af28f636SEnrico Perla - Sun Microsystems /* chop off :boot */ 902af28f636SEnrico Perla - Sun Microsystems save[0] = end[2]; 903af28f636SEnrico Perla - Sun Microsystems end[2] = '\0'; 904af28f636SEnrico Perla - Sun Microsystems } else { 905af28f636SEnrico Perla - Sun Microsystems i = strlen(device->path); 906af28f636SEnrico Perla - Sun Microsystems save[0] = device->path[i - 2]; 907af28f636SEnrico Perla - Sun Microsystems save[1] = device->path[i - 1]; 908af28f636SEnrico Perla - Sun Microsystems device->path[i - 2] = 'p'; 909af28f636SEnrico Perla - Sun Microsystems device->path[i - 1] = '0'; 910af28f636SEnrico Perla - Sun Microsystems } 911af28f636SEnrico Perla - Sun Microsystems 912af28f636SEnrico Perla - Sun Microsystems if (nowrite) 913af28f636SEnrico Perla - Sun Microsystems device->disk_fd = open(device->path, O_RDONLY); 914af28f636SEnrico Perla - Sun Microsystems else 915af28f636SEnrico Perla - Sun Microsystems device->disk_fd = open(device->path, O_RDWR); 916af28f636SEnrico Perla - Sun Microsystems 917af28f636SEnrico Perla - Sun Microsystems device->path_p0 = strdup(device->path); 918af28f636SEnrico Perla - Sun Microsystems if (device->path_p0 == NULL) { 919af28f636SEnrico Perla - Sun Microsystems perror("strdup"); 920af28f636SEnrico Perla - Sun Microsystems return (BC_ERROR); 921af28f636SEnrico Perla - Sun Microsystems } 922af28f636SEnrico Perla - Sun Microsystems 923af28f636SEnrico Perla - Sun Microsystems if (is_bootpar(device->type)) { 924af28f636SEnrico Perla - Sun Microsystems end[2] = save[0]; 925af28f636SEnrico Perla - Sun Microsystems } else { 926af28f636SEnrico Perla - Sun Microsystems device->path[i - 2] = save[0]; 927af28f636SEnrico Perla - Sun Microsystems device->path[i - 1] = save[1]; 928af28f636SEnrico Perla - Sun Microsystems } 929af28f636SEnrico Perla - Sun Microsystems 930af28f636SEnrico Perla - Sun Microsystems if (device->disk_fd == -1) { 931af28f636SEnrico Perla - Sun Microsystems perror("open"); 932af28f636SEnrico Perla - Sun Microsystems return (BC_ERROR); 933af28f636SEnrico Perla - Sun Microsystems } 934af28f636SEnrico Perla - Sun Microsystems 935af28f636SEnrico Perla - Sun Microsystems return (BC_SUCCESS); 936af28f636SEnrico Perla - Sun Microsystems } 937af28f636SEnrico Perla - Sun Microsystems 938af28f636SEnrico Perla - Sun Microsystems static void 939af28f636SEnrico Perla - Sun Microsystems prepare_fake_multiboot(ig_stage2_t *stage2) 940af28f636SEnrico Perla - Sun Microsystems { 941af28f636SEnrico Perla - Sun Microsystems multiboot_header_t *mboot; 942af28f636SEnrico Perla - Sun Microsystems 943af28f636SEnrico Perla - Sun Microsystems assert(stage2 != NULL); 944af28f636SEnrico Perla - Sun Microsystems assert(stage2->mboot != NULL); 945af28f636SEnrico Perla - Sun Microsystems assert(stage2->buf != NULL); 946af28f636SEnrico Perla - Sun Microsystems 947af28f636SEnrico Perla - Sun Microsystems mboot = stage2->mboot; 948af28f636SEnrico Perla - Sun Microsystems 949af28f636SEnrico Perla - Sun Microsystems /* 950af28f636SEnrico Perla - Sun Microsystems * Currently we expect find_multiboot() to have located a multiboot 951af28f636SEnrico Perla - Sun Microsystems * header with the AOUT kludge flag set. 952af28f636SEnrico Perla - Sun Microsystems */ 953af28f636SEnrico Perla - Sun Microsystems assert(mboot->flags & BB_MBOOT_AOUT_FLAG); 954af28f636SEnrico Perla - Sun Microsystems 955af28f636SEnrico Perla - Sun Microsystems /* Insert the information necessary to locate stage2. */ 956af28f636SEnrico Perla - Sun Microsystems mboot->header_addr = stage2->mboot_off; 957af28f636SEnrico Perla - Sun Microsystems mboot->load_addr = 0; 958af28f636SEnrico Perla - Sun Microsystems mboot->load_end_addr = stage2->file_size; 959af28f636SEnrico Perla - Sun Microsystems } 960af28f636SEnrico Perla - Sun Microsystems 961af28f636SEnrico Perla - Sun Microsystems static void 962af28f636SEnrico Perla - Sun Microsystems add_stage2_einfo(ig_stage2_t *stage2, char *updt_str) 963af28f636SEnrico Perla - Sun Microsystems { 964af28f636SEnrico Perla - Sun Microsystems bblk_hs_t hs; 965af28f636SEnrico Perla - Sun Microsystems uint32_t avail_space; 966af28f636SEnrico Perla - Sun Microsystems 967af28f636SEnrico Perla - Sun Microsystems assert(stage2 != NULL); 968af28f636SEnrico Perla - Sun Microsystems 969af28f636SEnrico Perla - Sun Microsystems /* Fill bootblock hashing source information. */ 970af28f636SEnrico Perla - Sun Microsystems hs.src_buf = (unsigned char *)stage2->file; 971af28f636SEnrico Perla - Sun Microsystems hs.src_size = stage2->file_size; 972af28f636SEnrico Perla - Sun Microsystems /* How much space for the extended information structure? */ 973af28f636SEnrico Perla - Sun Microsystems avail_space = stage2->buf_size - P2ROUNDUP(stage2->file_size, 8); 974af28f636SEnrico Perla - Sun Microsystems add_einfo(stage2->extra, updt_str, &hs, avail_space); 975af28f636SEnrico Perla - Sun Microsystems } 976af28f636SEnrico Perla - Sun Microsystems 977af28f636SEnrico Perla - Sun Microsystems 978af28f636SEnrico Perla - Sun Microsystems static int 979af28f636SEnrico Perla - Sun Microsystems write_stage2(ig_data_t *install) 980af28f636SEnrico Perla - Sun Microsystems { 981af28f636SEnrico Perla - Sun Microsystems ig_device_t *device = &install->device; 982af28f636SEnrico Perla - Sun Microsystems ig_stage2_t *stage2 = &install->stage2; 983af28f636SEnrico Perla - Sun Microsystems off_t offset; 984af28f636SEnrico Perla - Sun Microsystems 985af28f636SEnrico Perla - Sun Microsystems assert(install != NULL); 986af28f636SEnrico Perla - Sun Microsystems 987af28f636SEnrico Perla - Sun Microsystems if (is_bootpar(device->type)) { 988af28f636SEnrico Perla - Sun Microsystems /* 989af28f636SEnrico Perla - Sun Microsystems * stage2 is already on the filesystem, we only need to update 990af28f636SEnrico Perla - Sun Microsystems * the first two blocks (that we have modified during 991af28f636SEnrico Perla - Sun Microsystems * prepare_stage2()) 992af28f636SEnrico Perla - Sun Microsystems */ 993af28f636SEnrico Perla - Sun Microsystems if (write_out(device->part_fd, stage2->file, SECTOR_SIZE, 994af28f636SEnrico Perla - Sun Microsystems stage2->pcfs_first_sectors[0] * SECTOR_SIZE) 995af28f636SEnrico Perla - Sun Microsystems != BC_SUCCESS || 996af28f636SEnrico Perla - Sun Microsystems write_out(device->part_fd, stage2->file + SECTOR_SIZE, 997af28f636SEnrico Perla - Sun Microsystems SECTOR_SIZE, stage2->pcfs_first_sectors[1] * SECTOR_SIZE) 998af28f636SEnrico Perla - Sun Microsystems != BC_SUCCESS) { 999af28f636SEnrico Perla - Sun Microsystems (void) fprintf(stderr, WRITE_FAIL_STAGE2); 1000af28f636SEnrico Perla - Sun Microsystems return (BC_ERROR); 1001af28f636SEnrico Perla - Sun Microsystems } 1002af28f636SEnrico Perla - Sun Microsystems (void) fprintf(stdout, WRITE_STAGE2_PCFS); 1003af28f636SEnrico Perla - Sun Microsystems return (BC_SUCCESS); 1004af28f636SEnrico Perla - Sun Microsystems } 1005af28f636SEnrico Perla - Sun Microsystems 1006af28f636SEnrico Perla - Sun Microsystems /* 1007af28f636SEnrico Perla - Sun Microsystems * For disk, write stage2 starting at STAGE2_BLKOFF sector. 1008af28f636SEnrico Perla - Sun Microsystems * Note that we use stage2->buf rather than stage2->file, because we 1009af28f636SEnrico Perla - Sun Microsystems * may have extended information after the latter. 10109348d232SHans Rosenfeld * 10119348d232SHans Rosenfeld * If we're writing to an EFI-labeled disk where stage2 lives in the 10129348d232SHans Rosenfeld * 3.5MB boot loader gap following the ZFS vdev labels, make sure the 10139348d232SHans Rosenfeld * size of the buffer doesn't exceed the size of the gap. 1014af28f636SEnrico Perla - Sun Microsystems */ 10159348d232SHans Rosenfeld if (is_efi(device->type) && stage2->buf_size > STAGE2_MAXSIZE) { 10169348d232SHans Rosenfeld (void) fprintf(stderr, WRITE_FAIL_STAGE2); 10179348d232SHans Rosenfeld return (BC_ERROR); 10189348d232SHans Rosenfeld } 10199348d232SHans Rosenfeld 10201a902ef8SHans Rosenfeld offset = STAGE2_BLKOFF(device->type) * SECTOR_SIZE; 10211a902ef8SHans Rosenfeld 1022af28f636SEnrico Perla - Sun Microsystems if (write_out(device->part_fd, stage2->buf, stage2->buf_size, 1023af28f636SEnrico Perla - Sun Microsystems offset) != BC_SUCCESS) { 1024af28f636SEnrico Perla - Sun Microsystems perror("write"); 1025af28f636SEnrico Perla - Sun Microsystems return (BC_ERROR); 1026af28f636SEnrico Perla - Sun Microsystems } 1027af28f636SEnrico Perla - Sun Microsystems 1028af28f636SEnrico Perla - Sun Microsystems /* Simulate the "old" installgrub output. */ 1029af28f636SEnrico Perla - Sun Microsystems (void) fprintf(stdout, WRITE_STAGE2_DISK, device->partition, 10301a902ef8SHans Rosenfeld (stage2->buf_size / SECTOR_SIZE) + 1, STAGE2_BLKOFF(device->type), 1031af28f636SEnrico Perla - Sun Microsystems stage2->first_sector); 1032af28f636SEnrico Perla - Sun Microsystems 1033af28f636SEnrico Perla - Sun Microsystems return (BC_SUCCESS); 1034af28f636SEnrico Perla - Sun Microsystems } 1035af28f636SEnrico Perla - Sun Microsystems 1036af28f636SEnrico Perla - Sun Microsystems static int 1037af28f636SEnrico Perla - Sun Microsystems write_stage1(ig_data_t *install) 1038af28f636SEnrico Perla - Sun Microsystems { 1039af28f636SEnrico Perla - Sun Microsystems ig_device_t *device = &install->device; 1040af28f636SEnrico Perla - Sun Microsystems 1041af28f636SEnrico Perla - Sun Microsystems assert(install != NULL); 1042af28f636SEnrico Perla - Sun Microsystems 1043af28f636SEnrico Perla - Sun Microsystems if (write_out(device->part_fd, install->stage1_buf, 1044af28f636SEnrico Perla - Sun Microsystems sizeof (install->stage1_buf), 0) != BC_SUCCESS) { 1045af28f636SEnrico Perla - Sun Microsystems (void) fprintf(stdout, WRITE_FAIL_PBOOT); 1046af28f636SEnrico Perla - Sun Microsystems perror("write"); 1047af28f636SEnrico Perla - Sun Microsystems return (BC_ERROR); 1048af28f636SEnrico Perla - Sun Microsystems } 1049af28f636SEnrico Perla - Sun Microsystems 1050af28f636SEnrico Perla - Sun Microsystems /* Simulate "old" installgrub output. */ 1051af28f636SEnrico Perla - Sun Microsystems (void) fprintf(stdout, WRITE_PBOOT, device->partition, 1052af28f636SEnrico Perla - Sun Microsystems device->start_sector); 1053af28f636SEnrico Perla - Sun Microsystems 1054af28f636SEnrico Perla - Sun Microsystems if (write_mbr) { 1055af28f636SEnrico Perla - Sun Microsystems if (write_out(device->disk_fd, install->stage1_buf, 1056af28f636SEnrico Perla - Sun Microsystems sizeof (install->stage1_buf), 0) != BC_SUCCESS) { 1057af28f636SEnrico Perla - Sun Microsystems (void) fprintf(stdout, WRITE_FAIL_BOOTSEC); 1058af28f636SEnrico Perla - Sun Microsystems perror("write"); 1059af28f636SEnrico Perla - Sun Microsystems return (BC_ERROR); 1060af28f636SEnrico Perla - Sun Microsystems } 1061af28f636SEnrico Perla - Sun Microsystems /* Simulate "old" installgrub output. */ 1062af28f636SEnrico Perla - Sun Microsystems (void) fprintf(stdout, WRITE_MBOOT); 1063af28f636SEnrico Perla - Sun Microsystems } 1064af28f636SEnrico Perla - Sun Microsystems 1065af28f636SEnrico Perla - Sun Microsystems return (BC_SUCCESS); 1066af28f636SEnrico Perla - Sun Microsystems } 1067af28f636SEnrico Perla - Sun Microsystems 1068af28f636SEnrico Perla - Sun Microsystems #define USAGE_STRING "%s [-m|-f|-n|-F|-u verstr] stage1 stage2 device\n" \ 1069af28f636SEnrico Perla - Sun Microsystems "%s -M [-n] device1 device2\n" \ 1070af28f636SEnrico Perla - Sun Microsystems "%s [-V|-e] -i device\n" \ 1071af28f636SEnrico Perla - Sun Microsystems 1072af28f636SEnrico Perla - Sun Microsystems #define CANON_USAGE_STR gettext(USAGE_STRING) 1073af28f636SEnrico Perla - Sun Microsystems 10747c478bd9Sstevel@tonic-gate static void 10757c478bd9Sstevel@tonic-gate usage(char *progname) 10767c478bd9Sstevel@tonic-gate { 1077af28f636SEnrico Perla - Sun Microsystems (void) fprintf(stdout, CANON_USAGE_STR, progname, progname, progname); 10787c478bd9Sstevel@tonic-gate } 10797c478bd9Sstevel@tonic-gate 1080af28f636SEnrico Perla - Sun Microsystems 10817c478bd9Sstevel@tonic-gate static int 1082af28f636SEnrico Perla - Sun Microsystems read_stage1_from_file(char *path, ig_data_t *dest) 10837c478bd9Sstevel@tonic-gate { 10847c478bd9Sstevel@tonic-gate int fd; 10857c478bd9Sstevel@tonic-gate 1086af28f636SEnrico Perla - Sun Microsystems assert(dest); 1087af28f636SEnrico Perla - Sun Microsystems 10887c478bd9Sstevel@tonic-gate /* read the stage1 file from filesystem */ 1089af28f636SEnrico Perla - Sun Microsystems fd = open(path, O_RDONLY); 1090af28f636SEnrico Perla - Sun Microsystems if (fd == -1 || 1091af28f636SEnrico Perla - Sun Microsystems read(fd, dest->stage1_buf, SECTOR_SIZE) != SECTOR_SIZE) { 1092af28f636SEnrico Perla - Sun Microsystems (void) fprintf(stderr, READ_FAIL_STAGE1, path); 1093af28f636SEnrico Perla - Sun Microsystems return (BC_ERROR); 10947c478bd9Sstevel@tonic-gate } 10957c478bd9Sstevel@tonic-gate (void) close(fd); 1096af28f636SEnrico Perla - Sun Microsystems return (BC_SUCCESS); 10977c478bd9Sstevel@tonic-gate } 10987c478bd9Sstevel@tonic-gate 1099af28f636SEnrico Perla - Sun Microsystems static int 1100af28f636SEnrico Perla - Sun Microsystems read_stage2_from_file(char *path, ig_data_t *dest) 11017c478bd9Sstevel@tonic-gate { 1102af28f636SEnrico Perla - Sun Microsystems int fd; 1103af28f636SEnrico Perla - Sun Microsystems struct stat sb; 1104af28f636SEnrico Perla - Sun Microsystems ig_stage2_t *stage2 = &dest->stage2; 1105af28f636SEnrico Perla - Sun Microsystems ig_device_t *device = &dest->device; 1106af28f636SEnrico Perla - Sun Microsystems uint32_t buf_size; 1107af28f636SEnrico Perla - Sun Microsystems 1108af28f636SEnrico Perla - Sun Microsystems assert(dest); 1109af28f636SEnrico Perla - Sun Microsystems assert(stage2->buf == NULL); 1110af28f636SEnrico Perla - Sun Microsystems 1111af28f636SEnrico Perla - Sun Microsystems fd = open(path, O_RDONLY); 1112af28f636SEnrico Perla - Sun Microsystems if (fstat(fd, &sb) == -1) { 1113af28f636SEnrico Perla - Sun Microsystems perror("fstat"); 1114af28f636SEnrico Perla - Sun Microsystems goto out; 11157c478bd9Sstevel@tonic-gate } 11167c478bd9Sstevel@tonic-gate 1117af28f636SEnrico Perla - Sun Microsystems stage2->file_size = sb.st_size; 11187c478bd9Sstevel@tonic-gate 1119af28f636SEnrico Perla - Sun Microsystems if (!is_bootpar(device->type)) { 1120af28f636SEnrico Perla - Sun Microsystems /* 1121af28f636SEnrico Perla - Sun Microsystems * buffer size needs to account for stage2 plus the extra 1122af28f636SEnrico Perla - Sun Microsystems * versioning information at the end of it. We reserve one 1123af28f636SEnrico Perla - Sun Microsystems * extra sector (plus we round up to the next sector boundary). 1124af28f636SEnrico Perla - Sun Microsystems */ 1125af28f636SEnrico Perla - Sun Microsystems buf_size = stage2->file_size + SECTOR_SIZE; 11267c478bd9Sstevel@tonic-gate } else { 1127af28f636SEnrico Perla - Sun Microsystems /* In the PCFS case we only need to read in stage2. */ 1128af28f636SEnrico Perla - Sun Microsystems buf_size = stage2->file_size; 11297c478bd9Sstevel@tonic-gate } 11307c478bd9Sstevel@tonic-gate 1131af28f636SEnrico Perla - Sun Microsystems stage2->buf_size = P2ROUNDUP(buf_size, SECTOR_SIZE); 1132af28f636SEnrico Perla - Sun Microsystems 1133af28f636SEnrico Perla - Sun Microsystems BOOT_DEBUG("stage2 buffer size = %d (%d sectors)\n", stage2->buf_size, 1134af28f636SEnrico Perla - Sun Microsystems stage2->buf_size / SECTOR_SIZE); 1135af28f636SEnrico Perla - Sun Microsystems 1136af28f636SEnrico Perla - Sun Microsystems stage2->buf = malloc(stage2->buf_size); 1137af28f636SEnrico Perla - Sun Microsystems if (stage2->buf == NULL) { 1138af28f636SEnrico Perla - Sun Microsystems perror(gettext("Memory allocation failed")); 1139af28f636SEnrico Perla - Sun Microsystems goto out_fd; 1140af28f636SEnrico Perla - Sun Microsystems } 1141af28f636SEnrico Perla - Sun Microsystems 1142af28f636SEnrico Perla - Sun Microsystems stage2->file = stage2->buf; 11437c478bd9Sstevel@tonic-gate 11447c478bd9Sstevel@tonic-gate /* 1145af28f636SEnrico Perla - Sun Microsystems * Extra information (e.g. the versioning structure) is placed at the 1146af28f636SEnrico Perla - Sun Microsystems * end of stage2, aligned on a 8-byte boundary. 11477c478bd9Sstevel@tonic-gate */ 1148af28f636SEnrico Perla - Sun Microsystems if (!(is_bootpar(device->type))) 1149af28f636SEnrico Perla - Sun Microsystems stage2->extra = stage2->file + P2ROUNDUP(stage2->file_size, 8); 11507c478bd9Sstevel@tonic-gate 1151af28f636SEnrico Perla - Sun Microsystems if (lseek(fd, 0, SEEK_SET) == -1) { 1152af28f636SEnrico Perla - Sun Microsystems perror("lseek"); 1153af28f636SEnrico Perla - Sun Microsystems goto out_alloc; 11547c478bd9Sstevel@tonic-gate } 11557c478bd9Sstevel@tonic-gate 1156af28f636SEnrico Perla - Sun Microsystems if (read(fd, stage2->file, stage2->file_size) < 0) { 1157af28f636SEnrico Perla - Sun Microsystems perror(gettext("unable to read stage2")); 1158af28f636SEnrico Perla - Sun Microsystems goto out_alloc; 11597c478bd9Sstevel@tonic-gate } 11607c478bd9Sstevel@tonic-gate 1161af28f636SEnrico Perla - Sun Microsystems (void) close(fd); 1162af28f636SEnrico Perla - Sun Microsystems return (BC_SUCCESS); 11637ce76caaSEnrico Perla - Sun Microsystems 1164af28f636SEnrico Perla - Sun Microsystems out_alloc: 1165af28f636SEnrico Perla - Sun Microsystems free(stage2->buf); 1166af28f636SEnrico Perla - Sun Microsystems stage2->buf = NULL; 1167af28f636SEnrico Perla - Sun Microsystems out_fd: 1168af28f636SEnrico Perla - Sun Microsystems (void) close(fd); 1169af28f636SEnrico Perla - Sun Microsystems out: 1170af28f636SEnrico Perla - Sun Microsystems return (BC_ERROR); 11717ce76caaSEnrico Perla - Sun Microsystems } 11727ce76caaSEnrico Perla - Sun Microsystems 11737ce76caaSEnrico Perla - Sun Microsystems static int 1174af28f636SEnrico Perla - Sun Microsystems prepare_stage1(ig_data_t *install) 11757ce76caaSEnrico Perla - Sun Microsystems { 1176af28f636SEnrico Perla - Sun Microsystems ig_device_t *device = &install->device; 11777ce76caaSEnrico Perla - Sun Microsystems 1178af28f636SEnrico Perla - Sun Microsystems assert(install != NULL); 11797ce76caaSEnrico Perla - Sun Microsystems 1180af28f636SEnrico Perla - Sun Microsystems /* If PCFS add the BIOS Parameter Block. */ 1181af28f636SEnrico Perla - Sun Microsystems if (is_bootpar(device->type)) { 1182af28f636SEnrico Perla - Sun Microsystems char bpb_sect[SECTOR_SIZE]; 1183af28f636SEnrico Perla - Sun Microsystems 1184af28f636SEnrico Perla - Sun Microsystems if (pread(device->part_fd, bpb_sect, SECTOR_SIZE, 0) 1185af28f636SEnrico Perla - Sun Microsystems != SECTOR_SIZE) { 1186af28f636SEnrico Perla - Sun Microsystems (void) fprintf(stderr, READ_FAIL_BPB); 1187af28f636SEnrico Perla - Sun Microsystems return (BC_ERROR); 1188af28f636SEnrico Perla - Sun Microsystems } 1189af28f636SEnrico Perla - Sun Microsystems bcopy(bpb_sect + STAGE1_BPB_OFFSET, 1190af28f636SEnrico Perla - Sun Microsystems install->stage1_buf + STAGE1_BPB_OFFSET, STAGE1_BPB_SIZE); 11917ce76caaSEnrico Perla - Sun Microsystems } 11927ce76caaSEnrico Perla - Sun Microsystems 1193af28f636SEnrico Perla - Sun Microsystems /* copy MBR to stage1 in case of overwriting MBR sector. */ 1194af28f636SEnrico Perla - Sun Microsystems bcopy(device->boot_sector + BOOTSZ, install->stage1_buf + BOOTSZ, 1195af28f636SEnrico Perla - Sun Microsystems SECTOR_SIZE - BOOTSZ); 1196af28f636SEnrico Perla - Sun Microsystems /* modify default stage1 file generated by GRUB. */ 1197af28f636SEnrico Perla - Sun Microsystems *((unsigned char *)(install->stage1_buf + STAGE1_FORCE_LBA)) = 1; 1198af28f636SEnrico Perla - Sun Microsystems *((ulong_t *)(install->stage1_buf + STAGE1_STAGE2_SECTOR)) 1199af28f636SEnrico Perla - Sun Microsystems = install->stage2.first_sector; 1200af28f636SEnrico Perla - Sun Microsystems *((ushort_t *)(install->stage1_buf + STAGE1_STAGE2_ADDRESS)) 1201af28f636SEnrico Perla - Sun Microsystems = STAGE2_MEMADDR; 1202af28f636SEnrico Perla - Sun Microsystems *((ushort_t *)(install->stage1_buf + STAGE1_STAGE2_SEGMENT)) 1203af28f636SEnrico Perla - Sun Microsystems = STAGE2_MEMADDR >> 4; 12047ce76caaSEnrico Perla - Sun Microsystems 1205af28f636SEnrico Perla - Sun Microsystems return (BC_SUCCESS); 12067ce76caaSEnrico Perla - Sun Microsystems } 12077ce76caaSEnrico Perla - Sun Microsystems 1208af28f636SEnrico Perla - Sun Microsystems /* 1209af28f636SEnrico Perla - Sun Microsystems * Grab stage1 from the specified device file descriptor. 1210af28f636SEnrico Perla - Sun Microsystems */ 1211af28f636SEnrico Perla - Sun Microsystems static int 1212af28f636SEnrico Perla - Sun Microsystems read_stage1_from_disk(int dev_fd, char *stage1_buf) 1213af28f636SEnrico Perla - Sun Microsystems { 1214af28f636SEnrico Perla - Sun Microsystems assert(stage1_buf != NULL); 12157ce76caaSEnrico Perla - Sun Microsystems 1216af28f636SEnrico Perla - Sun Microsystems if (read_in(dev_fd, stage1_buf, SECTOR_SIZE, 0) != BC_SUCCESS) { 1217af28f636SEnrico Perla - Sun Microsystems perror(gettext("Unable to read stage1 from disk")); 1218af28f636SEnrico Perla - Sun Microsystems return (BC_ERROR); 12197ce76caaSEnrico Perla - Sun Microsystems } 1220af28f636SEnrico Perla - Sun Microsystems return (BC_SUCCESS); 12217ce76caaSEnrico Perla - Sun Microsystems } 12227ce76caaSEnrico Perla - Sun Microsystems 12237ce76caaSEnrico Perla - Sun Microsystems static int 12241a902ef8SHans Rosenfeld read_stage2_from_disk(int dev_fd, ig_stage2_t *stage2, int type) 12257ce76caaSEnrico Perla - Sun Microsystems { 1226af28f636SEnrico Perla - Sun Microsystems uint32_t size; 1227af28f636SEnrico Perla - Sun Microsystems uint32_t buf_size; 1228af28f636SEnrico Perla - Sun Microsystems uint32_t mboot_off; 1229af28f636SEnrico Perla - Sun Microsystems multiboot_header_t *mboot; 12307ce76caaSEnrico Perla - Sun Microsystems 1231af28f636SEnrico Perla - Sun Microsystems assert(stage2 != NULL); 1232af28f636SEnrico Perla - Sun Microsystems assert(dev_fd != -1); 12337ce76caaSEnrico Perla - Sun Microsystems 1234af28f636SEnrico Perla - Sun Microsystems if (read_in(dev_fd, mboot_scan, sizeof (mboot_scan), 12351a902ef8SHans Rosenfeld STAGE2_BLKOFF(type) * SECTOR_SIZE) != BC_SUCCESS) { 1236af28f636SEnrico Perla - Sun Microsystems perror(gettext("Error reading stage2 sectors")); 1237af28f636SEnrico Perla - Sun Microsystems return (BC_ERROR); 1238af28f636SEnrico Perla - Sun Microsystems } 12397ce76caaSEnrico Perla - Sun Microsystems 1240af28f636SEnrico Perla - Sun Microsystems /* No multiboot means no chance of knowing stage2 size */ 1241af28f636SEnrico Perla - Sun Microsystems if (find_multiboot(mboot_scan, sizeof (mboot_scan), &mboot_off) 1242af28f636SEnrico Perla - Sun Microsystems != BC_SUCCESS) { 1243af28f636SEnrico Perla - Sun Microsystems BOOT_DEBUG("Unable to find multiboot header\n"); 1244af28f636SEnrico Perla - Sun Microsystems return (BC_NOEXTRA); 1245af28f636SEnrico Perla - Sun Microsystems } 1246af28f636SEnrico Perla - Sun Microsystems mboot = (multiboot_header_t *)(mboot_scan + mboot_off); 12477ce76caaSEnrico Perla - Sun Microsystems 1248af28f636SEnrico Perla - Sun Microsystems /* 1249af28f636SEnrico Perla - Sun Microsystems * Unfilled mboot values mean an older version of installgrub installed 1250af28f636SEnrico Perla - Sun Microsystems * the stage2. Again we have no chance of knowing stage2 size. 1251af28f636SEnrico Perla - Sun Microsystems */ 1252af28f636SEnrico Perla - Sun Microsystems if (mboot->load_end_addr == 0 || 1253af28f636SEnrico Perla - Sun Microsystems mboot->load_end_addr < mboot->load_addr) 1254af28f636SEnrico Perla - Sun Microsystems return (BC_NOEXTRA); 1255af28f636SEnrico Perla - Sun Microsystems 1256af28f636SEnrico Perla - Sun Microsystems /* 1257af28f636SEnrico Perla - Sun Microsystems * Currently, the amount of space reserved for extra information 1258af28f636SEnrico Perla - Sun Microsystems * is "fixed". We may have to scan for the terminating extra payload 1259af28f636SEnrico Perla - Sun Microsystems * in the future. 1260af28f636SEnrico Perla - Sun Microsystems */ 1261af28f636SEnrico Perla - Sun Microsystems size = mboot->load_end_addr - mboot->load_addr; 1262af28f636SEnrico Perla - Sun Microsystems buf_size = P2ROUNDUP(size + SECTOR_SIZE, SECTOR_SIZE); 1263af28f636SEnrico Perla - Sun Microsystems 1264af28f636SEnrico Perla - Sun Microsystems stage2->buf = malloc(buf_size); 1265af28f636SEnrico Perla - Sun Microsystems if (stage2->buf == NULL) { 1266af28f636SEnrico Perla - Sun Microsystems perror(gettext("Memory allocation failed")); 1267af28f636SEnrico Perla - Sun Microsystems return (BC_ERROR); 1268af28f636SEnrico Perla - Sun Microsystems } 1269af28f636SEnrico Perla - Sun Microsystems stage2->buf_size = buf_size; 1270af28f636SEnrico Perla - Sun Microsystems 12711a902ef8SHans Rosenfeld if (read_in(dev_fd, stage2->buf, buf_size, STAGE2_BLKOFF(type) * 1272af28f636SEnrico Perla - Sun Microsystems SECTOR_SIZE) != BC_SUCCESS) { 1273af28f636SEnrico Perla - Sun Microsystems perror("read"); 1274af28f636SEnrico Perla - Sun Microsystems free(stage2->buf); 1275af28f636SEnrico Perla - Sun Microsystems return (BC_ERROR); 1276af28f636SEnrico Perla - Sun Microsystems } 1277af28f636SEnrico Perla - Sun Microsystems 1278af28f636SEnrico Perla - Sun Microsystems /* Update pointers. */ 1279af28f636SEnrico Perla - Sun Microsystems stage2->file = stage2->buf; 1280af28f636SEnrico Perla - Sun Microsystems stage2->file_size = size; 1281af28f636SEnrico Perla - Sun Microsystems stage2->mboot_off = mboot_off; 1282af28f636SEnrico Perla - Sun Microsystems stage2->mboot = (multiboot_header_t *)(stage2->buf + stage2->mboot_off); 1283af28f636SEnrico Perla - Sun Microsystems stage2->extra = stage2->buf + P2ROUNDUP(stage2->file_size, 8); 128414d44f22SHans Rosenfeld stage2->extra_size = stage2->buf_size - P2ROUNDUP(stage2->file_size, 8); 1285af28f636SEnrico Perla - Sun Microsystems 1286af28f636SEnrico Perla - Sun Microsystems return (BC_SUCCESS); 1287af28f636SEnrico Perla - Sun Microsystems } 1288af28f636SEnrico Perla - Sun Microsystems 1289af28f636SEnrico Perla - Sun Microsystems static boolean_t 1290af28f636SEnrico Perla - Sun Microsystems is_update_necessary(ig_data_t *data, char *updt_str) 1291af28f636SEnrico Perla - Sun Microsystems { 1292af28f636SEnrico Perla - Sun Microsystems bblk_einfo_t *einfo; 1293af28f636SEnrico Perla - Sun Microsystems bblk_hs_t stage2_hs; 1294af28f636SEnrico Perla - Sun Microsystems ig_stage2_t stage2_disk; 1295af28f636SEnrico Perla - Sun Microsystems ig_stage2_t *stage2_file = &data->stage2; 1296af28f636SEnrico Perla - Sun Microsystems ig_device_t *device = &data->device; 1297af28f636SEnrico Perla - Sun Microsystems int dev_fd = device->part_fd; 1298af28f636SEnrico Perla - Sun Microsystems 1299af28f636SEnrico Perla - Sun Microsystems assert(data != NULL); 1300af28f636SEnrico Perla - Sun Microsystems assert(device->part_fd != -1); 1301af28f636SEnrico Perla - Sun Microsystems 1302af28f636SEnrico Perla - Sun Microsystems bzero(&stage2_disk, sizeof (ig_stage2_t)); 1303af28f636SEnrico Perla - Sun Microsystems 1304af28f636SEnrico Perla - Sun Microsystems /* Gather stage2 (if present) from the target device. */ 13051a902ef8SHans Rosenfeld if (read_stage2_from_disk(dev_fd, &stage2_disk, device->type) 13061a902ef8SHans Rosenfeld != BC_SUCCESS) { 1307af28f636SEnrico Perla - Sun Microsystems BOOT_DEBUG("Unable to read stage2 from %s\n", device->path); 1308af28f636SEnrico Perla - Sun Microsystems BOOT_DEBUG("No multiboot wrapped stage2 on %s\n", device->path); 1309af28f636SEnrico Perla - Sun Microsystems return (B_TRUE); 1310af28f636SEnrico Perla - Sun Microsystems } 1311af28f636SEnrico Perla - Sun Microsystems 1312af28f636SEnrico Perla - Sun Microsystems /* 1313af28f636SEnrico Perla - Sun Microsystems * Look for the extended information structure in the extra payload 1314af28f636SEnrico Perla - Sun Microsystems * area. 1315af28f636SEnrico Perla - Sun Microsystems */ 131614d44f22SHans Rosenfeld einfo = find_einfo(stage2_disk.extra, stage2_disk.extra_size); 1317af28f636SEnrico Perla - Sun Microsystems if (einfo == NULL) { 1318af28f636SEnrico Perla - Sun Microsystems BOOT_DEBUG("No extended information available\n"); 1319af28f636SEnrico Perla - Sun Microsystems return (B_TRUE); 1320af28f636SEnrico Perla - Sun Microsystems } 1321af28f636SEnrico Perla - Sun Microsystems 1322af28f636SEnrico Perla - Sun Microsystems if (!do_version || updt_str == NULL) { 1323af28f636SEnrico Perla - Sun Microsystems (void) fprintf(stdout, "WARNING: target device %s has a " 1324af28f636SEnrico Perla - Sun Microsystems "versioned stage2 that is going to be overwritten by a non " 1325af28f636SEnrico Perla - Sun Microsystems "versioned one\n", device->path); 1326af28f636SEnrico Perla - Sun Microsystems return (B_TRUE); 1327af28f636SEnrico Perla - Sun Microsystems } 1328af28f636SEnrico Perla - Sun Microsystems 1329af28f636SEnrico Perla - Sun Microsystems if (force_update) { 1330af28f636SEnrico Perla - Sun Microsystems BOOT_DEBUG("Forcing update of %s bootblock\n", device->path); 1331af28f636SEnrico Perla - Sun Microsystems return (B_TRUE); 1332af28f636SEnrico Perla - Sun Microsystems } 1333af28f636SEnrico Perla - Sun Microsystems 1334af28f636SEnrico Perla - Sun Microsystems /* Compare the two extended information structures. */ 1335af28f636SEnrico Perla - Sun Microsystems stage2_hs.src_buf = (unsigned char *)stage2_file->file; 1336af28f636SEnrico Perla - Sun Microsystems stage2_hs.src_size = stage2_file->file_size; 1337af28f636SEnrico Perla - Sun Microsystems 1338af28f636SEnrico Perla - Sun Microsystems return (einfo_should_update(einfo, &stage2_hs, updt_str)); 13397ce76caaSEnrico Perla - Sun Microsystems } 13407ce76caaSEnrico Perla - Sun Microsystems 13417ce76caaSEnrico Perla - Sun Microsystems 13427c478bd9Sstevel@tonic-gate #define START_BLOCK(pos) (*(ulong_t *)(pos)) 13437c478bd9Sstevel@tonic-gate #define NUM_BLOCK(pos) (*(ushort_t *)((pos) + 4)) 13447c478bd9Sstevel@tonic-gate #define START_SEG(pos) (*(ushort_t *)((pos) + 6)) 13457c478bd9Sstevel@tonic-gate 1346af28f636SEnrico Perla - Sun Microsystems static int 1347af28f636SEnrico Perla - Sun Microsystems prepare_stage2(ig_data_t *install, char *updt_str) 13487c478bd9Sstevel@tonic-gate { 1349af28f636SEnrico Perla - Sun Microsystems ig_device_t *device = &install->device; 1350af28f636SEnrico Perla - Sun Microsystems ig_stage2_t *stage2 = &install->stage2; 1351af28f636SEnrico Perla - Sun Microsystems uint32_t mboot_off = 0; 13527ce76caaSEnrico Perla - Sun Microsystems 1353af28f636SEnrico Perla - Sun Microsystems assert(install != NULL); 1354af28f636SEnrico Perla - Sun Microsystems assert(stage2->file != NULL); 1355af28f636SEnrico Perla - Sun Microsystems 1356af28f636SEnrico Perla - Sun Microsystems /* New stage2 files come with an embedded stage2. */ 1357af28f636SEnrico Perla - Sun Microsystems if (find_multiboot(stage2->file, stage2->file_size, &mboot_off) 1358af28f636SEnrico Perla - Sun Microsystems != BC_SUCCESS) { 1359af28f636SEnrico Perla - Sun Microsystems BOOT_DEBUG("WARNING: no multiboot structure found in stage2, " 1360af28f636SEnrico Perla - Sun Microsystems "are you using an old GRUB stage2?\n"); 1361af28f636SEnrico Perla - Sun Microsystems if (do_version == B_TRUE) { 1362af28f636SEnrico Perla - Sun Microsystems (void) fprintf(stderr, gettext("Versioning requested " 1363af28f636SEnrico Perla - Sun Microsystems "but stage2 does not support it.. skipping.\n")); 1364af28f636SEnrico Perla - Sun Microsystems do_version = B_FALSE; 1365af28f636SEnrico Perla - Sun Microsystems } 1366af28f636SEnrico Perla - Sun Microsystems } else { 1367af28f636SEnrico Perla - Sun Microsystems /* Keep track of where the multiboot header is. */ 1368af28f636SEnrico Perla - Sun Microsystems stage2->mboot_off = mboot_off; 1369af28f636SEnrico Perla - Sun Microsystems stage2->mboot = (multiboot_header_t *)(stage2->file + 1370af28f636SEnrico Perla - Sun Microsystems mboot_off); 13717ce76caaSEnrico Perla - Sun Microsystems if (do_version) { 1372af28f636SEnrico Perla - Sun Microsystems /* 1373af28f636SEnrico Perla - Sun Microsystems * Adding stage2 information needs to happen before 1374af28f636SEnrico Perla - Sun Microsystems * we modify the copy of stage2 we have in memory, so 1375af28f636SEnrico Perla - Sun Microsystems * that the hashing reflects the one of the file. 1376af28f636SEnrico Perla - Sun Microsystems * An error here is not fatal. 1377af28f636SEnrico Perla - Sun Microsystems */ 1378af28f636SEnrico Perla - Sun Microsystems add_stage2_einfo(stage2, updt_str); 1379af28f636SEnrico Perla - Sun Microsystems } 1380af28f636SEnrico Perla - Sun Microsystems /* 1381af28f636SEnrico Perla - Sun Microsystems * Fill multiboot information. We add them even without 1382af28f636SEnrico Perla - Sun Microsystems * versioning to support as much as possible mirroring. 1383af28f636SEnrico Perla - Sun Microsystems */ 1384af28f636SEnrico Perla - Sun Microsystems prepare_fake_multiboot(stage2); 13857ce76caaSEnrico Perla - Sun Microsystems } 13867c478bd9Sstevel@tonic-gate 1387af28f636SEnrico Perla - Sun Microsystems if (is_bootpar(device->type)) { 1388af28f636SEnrico Perla - Sun Microsystems uint32_t blocklist[SECTOR_SIZE / sizeof (uint32_t)]; 1389af28f636SEnrico Perla - Sun Microsystems uint32_t install_addr = STAGE2_MEMADDR + SECTOR_SIZE; 13907c478bd9Sstevel@tonic-gate int i = 0; 1391af28f636SEnrico Perla - Sun Microsystems uchar_t *pos; 13927c478bd9Sstevel@tonic-gate 1393af28f636SEnrico Perla - Sun Microsystems bzero(blocklist, sizeof (blocklist)); 1394af28f636SEnrico Perla - Sun Microsystems if (read_stage2_blocklist(device->part_fd, blocklist) != 0) { 1395af28f636SEnrico Perla - Sun Microsystems (void) fprintf(stderr, gettext("Error reading pcfs " 1396af28f636SEnrico Perla - Sun Microsystems "stage2 blocklist\n")); 1397af28f636SEnrico Perla - Sun Microsystems return (BC_ERROR); 1398af28f636SEnrico Perla - Sun Microsystems } 13997c478bd9Sstevel@tonic-gate 1400af28f636SEnrico Perla - Sun Microsystems pos = (uchar_t *)stage2->file + STAGE2_BLOCKLIST; 1401af28f636SEnrico Perla - Sun Microsystems stage2->first_sector = device->start_sector + blocklist[0]; 1402af28f636SEnrico Perla - Sun Microsystems stage2->pcfs_first_sectors[0] = blocklist[0]; 1403af28f636SEnrico Perla - Sun Microsystems BOOT_DEBUG("stage2 first sector: %d\n", stage2->first_sector); 1404af28f636SEnrico Perla - Sun Microsystems 1405af28f636SEnrico Perla - Sun Microsystems 14067c478bd9Sstevel@tonic-gate if (blocklist[1] > 1) { 14077c478bd9Sstevel@tonic-gate blocklist[0]++; 14087c478bd9Sstevel@tonic-gate blocklist[1]--; 14097c478bd9Sstevel@tonic-gate } else { 14107c478bd9Sstevel@tonic-gate i += 2; 14117c478bd9Sstevel@tonic-gate } 14127c478bd9Sstevel@tonic-gate 1413af28f636SEnrico Perla - Sun Microsystems stage2->pcfs_first_sectors[1] = blocklist[i]; 14147c478bd9Sstevel@tonic-gate 14157c478bd9Sstevel@tonic-gate while (blocklist[i]) { 14167c478bd9Sstevel@tonic-gate if (START_BLOCK(pos - 8) != 0 && 14177c478bd9Sstevel@tonic-gate START_BLOCK(pos - 8) != blocklist[i + 2]) { 14187c478bd9Sstevel@tonic-gate (void) fprintf(stderr, PCFS_FRAGMENTED); 1419af28f636SEnrico Perla - Sun Microsystems return (BC_ERROR); 14207c478bd9Sstevel@tonic-gate } 1421af28f636SEnrico Perla - Sun Microsystems START_BLOCK(pos) = blocklist[i] + device->start_sector; 14227c478bd9Sstevel@tonic-gate START_SEG(pos) = (ushort_t)(install_addr >> 4); 14237c478bd9Sstevel@tonic-gate NUM_BLOCK(pos) = blocklist[i + 1]; 14247c478bd9Sstevel@tonic-gate install_addr += blocklist[i + 1] * SECTOR_SIZE; 14257c478bd9Sstevel@tonic-gate pos -= 8; 14267c478bd9Sstevel@tonic-gate i += 2; 14277c478bd9Sstevel@tonic-gate } 14287c478bd9Sstevel@tonic-gate } else { 1429af28f636SEnrico Perla - Sun Microsystems /* Solaris VTOC */ 14301a902ef8SHans Rosenfeld stage2->first_sector = device->start_sector + 14311a902ef8SHans Rosenfeld STAGE2_BLKOFF(device->type); 1432af28f636SEnrico Perla - Sun Microsystems BOOT_DEBUG("stage2 first sector: %d\n", stage2->first_sector); 14337c478bd9Sstevel@tonic-gate /* 14347c478bd9Sstevel@tonic-gate * In a solaris partition, stage2 is written to contiguous 14357c478bd9Sstevel@tonic-gate * blocks. So we update the starting block only. 14367c478bd9Sstevel@tonic-gate */ 1437af28f636SEnrico Perla - Sun Microsystems *((ulong_t *)(stage2->file + STAGE2_BLOCKLIST)) = 1438af28f636SEnrico Perla - Sun Microsystems stage2->first_sector + 1; 14397c478bd9Sstevel@tonic-gate } 14407c478bd9Sstevel@tonic-gate 14417c478bd9Sstevel@tonic-gate /* force lba and set disk partition */ 1442af28f636SEnrico Perla - Sun Microsystems *((unsigned char *) (stage2->file + STAGE2_FORCE_LBA)) = 1; 1443af28f636SEnrico Perla - Sun Microsystems *((long *)(stage2->file + STAGE2_INSTALLPART)) 1444af28f636SEnrico Perla - Sun Microsystems = (device->partition << 16) | (device->slice << 8) | 0xff; 1445af28f636SEnrico Perla - Sun Microsystems 1446af28f636SEnrico Perla - Sun Microsystems return (BC_SUCCESS); 14477c478bd9Sstevel@tonic-gate } 14487c478bd9Sstevel@tonic-gate 1449af28f636SEnrico Perla - Sun Microsystems static int 1450af28f636SEnrico Perla - Sun Microsystems find_x86_bootpar(struct mboot *mboot, int *part_num, uint32_t *start_sect) 1451af28f636SEnrico Perla - Sun Microsystems { 1452af28f636SEnrico Perla - Sun Microsystems int i; 14537c478bd9Sstevel@tonic-gate 1454af28f636SEnrico Perla - Sun Microsystems for (i = 0; i < FD_NUMPART; i++) { 1455af28f636SEnrico Perla - Sun Microsystems struct ipart *part; 14567c478bd9Sstevel@tonic-gate 1457af28f636SEnrico Perla - Sun Microsystems part = (struct ipart *)mboot->parts + i; 1458af28f636SEnrico Perla - Sun Microsystems if (part->systid == 0xbe) { 1459af28f636SEnrico Perla - Sun Microsystems if (start_sect) 1460af28f636SEnrico Perla - Sun Microsystems *start_sect = part->relsect; 1461af28f636SEnrico Perla - Sun Microsystems if (part_num) 1462af28f636SEnrico Perla - Sun Microsystems *part_num = i; 1463af28f636SEnrico Perla - Sun Microsystems /* solaris boot part */ 1464af28f636SEnrico Perla - Sun Microsystems return (BC_SUCCESS); 14657c478bd9Sstevel@tonic-gate } 14667c478bd9Sstevel@tonic-gate } 1467af28f636SEnrico Perla - Sun Microsystems return (BC_ERROR); 14687c478bd9Sstevel@tonic-gate } 14697c478bd9Sstevel@tonic-gate 14707c478bd9Sstevel@tonic-gate static char * 1471af28f636SEnrico Perla - Sun Microsystems get_raw_partition_path(ig_device_t *device) 14727c478bd9Sstevel@tonic-gate { 1473af28f636SEnrico Perla - Sun Microsystems char *raw; 14747c478bd9Sstevel@tonic-gate int len; 1475af28f636SEnrico Perla - Sun Microsystems 1476af28f636SEnrico Perla - Sun Microsystems if (is_bootpar(device->type)) { 1477af28f636SEnrico Perla - Sun Microsystems int part; 14787c478bd9Sstevel@tonic-gate struct mboot *mboot; 14797c478bd9Sstevel@tonic-gate 1480af28f636SEnrico Perla - Sun Microsystems mboot = (struct mboot *)device->boot_sector; 1481af28f636SEnrico Perla - Sun Microsystems if (find_x86_bootpar(mboot, &part, NULL) != BC_SUCCESS) { 1482af28f636SEnrico Perla - Sun Microsystems (void) fprintf(stderr, BOOTPAR_NOTFOUND, 1483af28f636SEnrico Perla - Sun Microsystems device->path_p0); 1484af28f636SEnrico Perla - Sun Microsystems return (NULL); 14857c478bd9Sstevel@tonic-gate } 14867c478bd9Sstevel@tonic-gate 1487af28f636SEnrico Perla - Sun Microsystems raw = strdup(device->path_p0); 1488af28f636SEnrico Perla - Sun Microsystems if (raw == NULL) { 1489af28f636SEnrico Perla - Sun Microsystems perror(gettext("Memory allocation failed")); 1490af28f636SEnrico Perla - Sun Microsystems return (NULL); 14917c478bd9Sstevel@tonic-gate } 1492af28f636SEnrico Perla - Sun Microsystems 1493af28f636SEnrico Perla - Sun Microsystems raw[strlen(raw) - 2] = '1' + part; 14947c478bd9Sstevel@tonic-gate return (raw); 14957c478bd9Sstevel@tonic-gate } 14967c478bd9Sstevel@tonic-gate 14977c478bd9Sstevel@tonic-gate /* For disk, remember slice and return whole fdisk partition */ 1498af28f636SEnrico Perla - Sun Microsystems raw = strdup(device->path); 1499af28f636SEnrico Perla - Sun Microsystems if (raw == NULL) { 1500af28f636SEnrico Perla - Sun Microsystems perror(gettext("Memory allocation failed")); 1501af28f636SEnrico Perla - Sun Microsystems return (NULL); 1502af28f636SEnrico Perla - Sun Microsystems } 1503af28f636SEnrico Perla - Sun Microsystems 15047c478bd9Sstevel@tonic-gate len = strlen(raw); 15051a902ef8SHans Rosenfeld if (!is_efi(device->type) && 15061a902ef8SHans Rosenfeld (raw[len - 2] != 's' || raw[len - 1] == '2')) { 15077c478bd9Sstevel@tonic-gate (void) fprintf(stderr, NOT_ROOT_SLICE); 1508af28f636SEnrico Perla - Sun Microsystems free(raw); 1509af28f636SEnrico Perla - Sun Microsystems return (NULL); 15107c478bd9Sstevel@tonic-gate } 1511af28f636SEnrico Perla - Sun Microsystems device->slice = atoi(&raw[len - 1]); 15127c478bd9Sstevel@tonic-gate 15131a902ef8SHans Rosenfeld if (!is_efi(device->type)) { 15147c478bd9Sstevel@tonic-gate raw[len - 2] = 's'; 15157c478bd9Sstevel@tonic-gate raw[len - 1] = '2'; 15161a902ef8SHans Rosenfeld } 1517af28f636SEnrico Perla - Sun Microsystems 15187c478bd9Sstevel@tonic-gate return (raw); 15197c478bd9Sstevel@tonic-gate } 15207c478bd9Sstevel@tonic-gate 1521af28f636SEnrico Perla - Sun Microsystems static int 1522af28f636SEnrico Perla - Sun Microsystems get_raw_partition_fd(ig_device_t *device) 1523af28f636SEnrico Perla - Sun Microsystems { 1524af28f636SEnrico Perla - Sun Microsystems struct stat stat = {0}; 1525af28f636SEnrico Perla - Sun Microsystems char *raw; 1526af28f636SEnrico Perla - Sun Microsystems 1527af28f636SEnrico Perla - Sun Microsystems raw = get_raw_partition_path(device); 1528af28f636SEnrico Perla - Sun Microsystems if (raw == NULL) 1529af28f636SEnrico Perla - Sun Microsystems return (BC_ERROR); 1530af28f636SEnrico Perla - Sun Microsystems 1531af28f636SEnrico Perla - Sun Microsystems if (nowrite) 1532af28f636SEnrico Perla - Sun Microsystems device->part_fd = open(raw, O_RDONLY); 1533af28f636SEnrico Perla - Sun Microsystems else 1534af28f636SEnrico Perla - Sun Microsystems device->part_fd = open(raw, O_RDWR); 1535af28f636SEnrico Perla - Sun Microsystems 1536af28f636SEnrico Perla - Sun Microsystems if (device->part_fd < 0 || fstat(device->part_fd, &stat) != 0) { 1537af28f636SEnrico Perla - Sun Microsystems (void) fprintf(stderr, OPEN_FAIL, raw); 1538af28f636SEnrico Perla - Sun Microsystems free(raw); 1539af28f636SEnrico Perla - Sun Microsystems return (BC_ERROR); 1540af28f636SEnrico Perla - Sun Microsystems } 1541af28f636SEnrico Perla - Sun Microsystems 1542af28f636SEnrico Perla - Sun Microsystems if (S_ISCHR(stat.st_mode) == 0) { 1543af28f636SEnrico Perla - Sun Microsystems (void) fprintf(stderr, NOT_RAW_DEVICE, raw); 1544af28f636SEnrico Perla - Sun Microsystems (void) close(device->part_fd); 1545af28f636SEnrico Perla - Sun Microsystems device->part_fd = -1; 1546af28f636SEnrico Perla - Sun Microsystems free(raw); 1547af28f636SEnrico Perla - Sun Microsystems return (BC_ERROR); 1548af28f636SEnrico Perla - Sun Microsystems } 1549af28f636SEnrico Perla - Sun Microsystems 1550af28f636SEnrico Perla - Sun Microsystems free(raw); 1551af28f636SEnrico Perla - Sun Microsystems return (BC_SUCCESS); 1552af28f636SEnrico Perla - Sun Microsystems } 1553af28f636SEnrico Perla - Sun Microsystems 15547c478bd9Sstevel@tonic-gate #define TMP_MNTPT "/tmp/installgrub_pcfs" 1555af28f636SEnrico Perla - Sun Microsystems static int 1556af28f636SEnrico Perla - Sun Microsystems copy_stage2_to_pcfs(ig_data_t *install) 15577c478bd9Sstevel@tonic-gate { 15587c478bd9Sstevel@tonic-gate FILE *mntfp; 1559af28f636SEnrico Perla - Sun Microsystems int pcfs_fp; 1560af28f636SEnrico Perla - Sun Microsystems int status = BC_ERROR; 15617c478bd9Sstevel@tonic-gate char buf[SECTOR_SIZE]; 15627c478bd9Sstevel@tonic-gate char *cp; 15637c478bd9Sstevel@tonic-gate struct mnttab mp = {0}, mpref = {0}; 1564af28f636SEnrico Perla - Sun Microsystems ig_device_t *device = &install->device; 1565af28f636SEnrico Perla - Sun Microsystems ig_stage2_t *stage2 = &install->stage2; 15667c478bd9Sstevel@tonic-gate 15677c478bd9Sstevel@tonic-gate /* convert raw to block device name by removing the first 'r' */ 1568af28f636SEnrico Perla - Sun Microsystems (void) strncpy(buf, device->path, sizeof (buf)); 15697c478bd9Sstevel@tonic-gate buf[sizeof (buf) - 1] = 0; 15707c478bd9Sstevel@tonic-gate cp = strchr(buf, 'r'); 15717c478bd9Sstevel@tonic-gate if (cp == NULL) { 1572af28f636SEnrico Perla - Sun Microsystems (void) fprintf(stderr, CONVERT_FAIL, device->path); 1573af28f636SEnrico Perla - Sun Microsystems return (BC_ERROR); 15747c478bd9Sstevel@tonic-gate } 15757c478bd9Sstevel@tonic-gate do { 15767c478bd9Sstevel@tonic-gate *cp = *(cp + 1); 15777c478bd9Sstevel@tonic-gate } while (*(++cp)); 15787c478bd9Sstevel@tonic-gate 15797c478bd9Sstevel@tonic-gate /* get the mount point, if any */ 15807c478bd9Sstevel@tonic-gate mntfp = fopen("/etc/mnttab", "r"); 15817c478bd9Sstevel@tonic-gate if (mntfp == NULL) { 15827c478bd9Sstevel@tonic-gate (void) fprintf(stderr, OPEN_FAIL_FILE, "/etc/mnttab"); 1583af28f636SEnrico Perla - Sun Microsystems return (BC_ERROR); 15847c478bd9Sstevel@tonic-gate } 15857c478bd9Sstevel@tonic-gate 15867c478bd9Sstevel@tonic-gate mpref.mnt_special = buf; 15877c478bd9Sstevel@tonic-gate if (getmntany(mntfp, &mp, &mpref) != 0) { 15887c478bd9Sstevel@tonic-gate char cmd[128]; 15897c478bd9Sstevel@tonic-gate 15907c478bd9Sstevel@tonic-gate /* not mounted, try remount */ 15917c478bd9Sstevel@tonic-gate (void) mkdir(TMP_MNTPT, S_IRWXU); 15927c478bd9Sstevel@tonic-gate (void) snprintf(cmd, sizeof (cmd), "mount -F pcfs %s %s", 15937c478bd9Sstevel@tonic-gate buf, TMP_MNTPT); 15947c478bd9Sstevel@tonic-gate (void) system(cmd); 15957c478bd9Sstevel@tonic-gate rewind(mntfp); 15967c478bd9Sstevel@tonic-gate bzero(&mp, sizeof (mp)); 15977c478bd9Sstevel@tonic-gate if (getmntany(mntfp, &mp, &mpref) != 0) { 15987c478bd9Sstevel@tonic-gate (void) fprintf(stderr, MOUNT_FAIL, buf); 1599af28f636SEnrico Perla - Sun Microsystems return (BC_ERROR); 16007c478bd9Sstevel@tonic-gate } 16017c478bd9Sstevel@tonic-gate } 16027c478bd9Sstevel@tonic-gate 16037c478bd9Sstevel@tonic-gate (void) snprintf(buf, sizeof (buf), 16047c478bd9Sstevel@tonic-gate "%s/boot", mp.mnt_mountp); 16057c478bd9Sstevel@tonic-gate (void) mkdir(buf, S_IRWXU); 16067c478bd9Sstevel@tonic-gate (void) strcat(buf, "/grub"); 16077c478bd9Sstevel@tonic-gate (void) mkdir(buf, S_IRWXU); 16087c478bd9Sstevel@tonic-gate 16097c478bd9Sstevel@tonic-gate (void) strcat(buf, "/stage2"); 16107c478bd9Sstevel@tonic-gate pcfs_fp = open(buf, O_WRONLY | O_CREAT, S_IRWXU); 16117c478bd9Sstevel@tonic-gate if (pcfs_fp == -1) { 16127c478bd9Sstevel@tonic-gate (void) fprintf(stderr, OPEN_FAIL_FILE, buf); 16137c478bd9Sstevel@tonic-gate perror("open:"); 1614af28f636SEnrico Perla - Sun Microsystems goto out; 16157c478bd9Sstevel@tonic-gate } 16167c478bd9Sstevel@tonic-gate 1617af28f636SEnrico Perla - Sun Microsystems /* write stage2 to the pcfs mounted filesystem. */ 1618af28f636SEnrico Perla - Sun Microsystems if (write(pcfs_fp, stage2->file, stage2->file_size) 1619af28f636SEnrico Perla - Sun Microsystems != stage2->file_size) { 1620af28f636SEnrico Perla - Sun Microsystems perror(gettext("Error writing stage2")); 1621af28f636SEnrico Perla - Sun Microsystems goto out; 16227c478bd9Sstevel@tonic-gate } 1623af28f636SEnrico Perla - Sun Microsystems 1624af28f636SEnrico Perla - Sun Microsystems status = BC_SUCCESS; 1625af28f636SEnrico Perla - Sun Microsystems out_fd: 16267c478bd9Sstevel@tonic-gate (void) close(pcfs_fp); 1627af28f636SEnrico Perla - Sun Microsystems out: 16287c478bd9Sstevel@tonic-gate (void) umount(TMP_MNTPT); 1629af28f636SEnrico Perla - Sun Microsystems (void) rmdir(TMP_MNTPT); 1630af28f636SEnrico Perla - Sun Microsystems return (status); 16317c478bd9Sstevel@tonic-gate } 1632