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 /* 22*af28f636SEnrico Perla - Sun Microsystems * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved. 237c478bd9Sstevel@tonic-gate */ 247c478bd9Sstevel@tonic-gate 257c478bd9Sstevel@tonic-gate #include <stdio.h> 267c478bd9Sstevel@tonic-gate #include <stdlib.h> 277c478bd9Sstevel@tonic-gate #include <libgen.h> 287c478bd9Sstevel@tonic-gate #include <malloc.h> 297c478bd9Sstevel@tonic-gate #include <string.h> 307c478bd9Sstevel@tonic-gate #include <fcntl.h> 317c478bd9Sstevel@tonic-gate #include <unistd.h> 327c478bd9Sstevel@tonic-gate #include <strings.h> 33*af28f636SEnrico Perla - Sun Microsystems #include <libintl.h> 34*af28f636SEnrico Perla - Sun Microsystems #include <locale.h> 35*af28f636SEnrico Perla - Sun Microsystems #include <errno.h> 36*af28f636SEnrico Perla - Sun Microsystems #include <libfdisk.h> 37*af28f636SEnrico Perla - Sun Microsystems #include <stdarg.h> 38*af28f636SEnrico Perla - Sun Microsystems #include <assert.h> 39*af28f636SEnrico Perla - Sun Microsystems 407c478bd9Sstevel@tonic-gate #include <sys/mount.h> 417c478bd9Sstevel@tonic-gate #include <sys/mnttab.h> 427c478bd9Sstevel@tonic-gate #include <sys/dktp/fdisk.h> 43d33344bbSsy25831 #include <sys/dkio.h> 44d33344bbSsy25831 #include <sys/vtoc.h> 45*af28f636SEnrico Perla - Sun Microsystems #include <sys/types.h> 46*af28f636SEnrico Perla - Sun Microsystems #include <sys/stat.h> 47*af28f636SEnrico Perla - Sun Microsystems #include <sys/multiboot.h> 48*af28f636SEnrico Perla - Sun Microsystems #include <sys/sysmacros.h> 497c478bd9Sstevel@tonic-gate 507c478bd9Sstevel@tonic-gate #include "message.h" 51*af28f636SEnrico Perla - Sun Microsystems #include "installgrub.h" 52*af28f636SEnrico Perla - Sun Microsystems #include "./../common/bblk_einfo.h" 53*af28f636SEnrico Perla - Sun Microsystems #include "./../common/boot_utils.h" 54*af28f636SEnrico Perla - Sun Microsystems #include "./../common/mboot_extra.h" 557c478bd9Sstevel@tonic-gate 567c478bd9Sstevel@tonic-gate #ifndef TEXT_DOMAIN 577c478bd9Sstevel@tonic-gate #define TEXT_DOMAIN "SUNW_OST_OSCMD" 587c478bd9Sstevel@tonic-gate #endif 597c478bd9Sstevel@tonic-gate 60*af28f636SEnrico Perla - Sun Microsystems /* 61*af28f636SEnrico Perla - Sun Microsystems * Variables to track installgrub desired mode of operation. 62*af28f636SEnrico Perla - Sun Microsystems * 'nowrite' and 'boot_debug' come from boot_common.h. 63*af28f636SEnrico Perla - Sun Microsystems */ 64*af28f636SEnrico Perla - Sun Microsystems static boolean_t write_mbr = B_FALSE; 65*af28f636SEnrico Perla - Sun Microsystems static boolean_t force_mbr = B_FALSE; 66*af28f636SEnrico Perla - Sun Microsystems static boolean_t force_update = B_FALSE; 67*af28f636SEnrico Perla - Sun Microsystems static boolean_t do_getinfo = B_FALSE; 68*af28f636SEnrico Perla - Sun Microsystems static boolean_t do_version = B_FALSE; 69*af28f636SEnrico Perla - Sun Microsystems static boolean_t do_mirror_bblk = B_FALSE; 70*af28f636SEnrico Perla - Sun Microsystems static boolean_t strip = B_FALSE; 71*af28f636SEnrico Perla - Sun Microsystems static boolean_t verbose_dump = B_FALSE; 727c478bd9Sstevel@tonic-gate 73*af28f636SEnrico Perla - Sun Microsystems /* Installing the bootblock is the default operation. */ 74*af28f636SEnrico Perla - Sun Microsystems static boolean_t do_install = B_TRUE; 757c478bd9Sstevel@tonic-gate 76*af28f636SEnrico Perla - Sun Microsystems /* Versioning string, if present. */ 77*af28f636SEnrico Perla - Sun Microsystems static char *update_str; 787c478bd9Sstevel@tonic-gate 79*af28f636SEnrico Perla - Sun Microsystems /* 80*af28f636SEnrico Perla - Sun Microsystems * Temporary buffer to store the first 32K of data looking for a multiboot 81*af28f636SEnrico Perla - Sun Microsystems * signature. 82*af28f636SEnrico Perla - Sun Microsystems */ 83*af28f636SEnrico Perla - Sun Microsystems char mboot_scan[MBOOT_SCAN_SIZE]; 847ce76caaSEnrico Perla - Sun Microsystems 85*af28f636SEnrico Perla - Sun Microsystems /* Function prototypes. */ 86*af28f636SEnrico Perla - Sun Microsystems static void check_options(char *); 87*af28f636SEnrico Perla - Sun Microsystems static int handle_install(char *, char **); 88*af28f636SEnrico Perla - Sun Microsystems static int handle_mirror(char *, char **); 89*af28f636SEnrico Perla - Sun Microsystems static int handle_getinfo(char *, char **); 90*af28f636SEnrico Perla - Sun Microsystems static int commit_to_disk(ig_data_t *, char *); 91*af28f636SEnrico Perla - Sun Microsystems static int init_device(ig_device_t *, char *path); 92*af28f636SEnrico Perla - Sun Microsystems static void cleanup_device(ig_device_t *); 93*af28f636SEnrico Perla - Sun Microsystems static void cleanup_stage2(ig_stage2_t *); 94*af28f636SEnrico Perla - Sun Microsystems static int get_start_sector(ig_device_t *); 95*af28f636SEnrico Perla - Sun Microsystems static int get_disk_fd(ig_device_t *device); 96*af28f636SEnrico Perla - Sun Microsystems static int get_raw_partition_fd(ig_device_t *); 97*af28f636SEnrico Perla - Sun Microsystems static char *get_raw_partition_path(ig_device_t *); 98*af28f636SEnrico Perla - Sun Microsystems static boolean_t gather_stage2_from_dev(ig_data_t *); 99*af28f636SEnrico Perla - Sun Microsystems static int propagate_bootblock(ig_data_t *, ig_data_t *, char *); 100*af28f636SEnrico Perla - Sun Microsystems static int find_x86_bootpar(struct mboot *, int *, uint32_t *); 101*af28f636SEnrico Perla - Sun Microsystems static int copy_stage2_to_pcfs(ig_data_t *); 102*af28f636SEnrico Perla - Sun Microsystems static int write_stage2(ig_data_t *); 103*af28f636SEnrico Perla - Sun Microsystems static int write_stage1(ig_data_t *); 1047c478bd9Sstevel@tonic-gate static void usage(char *); 105*af28f636SEnrico Perla - Sun Microsystems static int read_stage1_from_file(char *, ig_data_t *); 106*af28f636SEnrico Perla - Sun Microsystems static int read_stage2_from_file(char *, ig_data_t *); 107*af28f636SEnrico Perla - Sun Microsystems static int read_stage1_from_disk(int, char *); 108*af28f636SEnrico Perla - Sun Microsystems static int read_stage2_from_disk(int, ig_stage2_t *); 109*af28f636SEnrico Perla - Sun Microsystems static int prepare_stage1(ig_data_t *); 110*af28f636SEnrico Perla - Sun Microsystems static int prepare_stage2(ig_data_t *, char *); 111*af28f636SEnrico Perla - Sun Microsystems static void prepare_fake_multiboot(ig_stage2_t *); 112*af28f636SEnrico Perla - Sun Microsystems static void add_stage2_einfo(ig_stage2_t *, char *updt_str); 113*af28f636SEnrico Perla - Sun Microsystems static boolean_t is_update_necessary(ig_data_t *, char *); 1147c478bd9Sstevel@tonic-gate 115342440ecSPrasad Singamsetty extern int read_stage2_blocklist(int, unsigned int *); 1167c478bd9Sstevel@tonic-gate 1177c478bd9Sstevel@tonic-gate int 1187c478bd9Sstevel@tonic-gate main(int argc, char *argv[]) 1197c478bd9Sstevel@tonic-gate { 120*af28f636SEnrico Perla - Sun Microsystems int opt; 121*af28f636SEnrico Perla - Sun Microsystems int params = 3; 122*af28f636SEnrico Perla - Sun Microsystems int ret; 123*af28f636SEnrico Perla - Sun Microsystems char **handle_args; 124*af28f636SEnrico Perla - Sun Microsystems char *progname; 1257c478bd9Sstevel@tonic-gate 1267c478bd9Sstevel@tonic-gate (void) setlocale(LC_ALL, ""); 1277c478bd9Sstevel@tonic-gate (void) textdomain(TEXT_DOMAIN); 1287c478bd9Sstevel@tonic-gate 129*af28f636SEnrico Perla - Sun Microsystems /* 130*af28f636SEnrico Perla - Sun Microsystems * retro-compatibility: installing the bootblock is the default 131*af28f636SEnrico Perla - Sun Microsystems * and there is no switch for it. 132*af28f636SEnrico Perla - Sun Microsystems */ 133*af28f636SEnrico Perla - Sun Microsystems do_install = B_TRUE; 134*af28f636SEnrico Perla - Sun Microsystems 135*af28f636SEnrico Perla - Sun Microsystems while ((opt = getopt(argc, argv, "dVMFfmneiu:")) != EOF) { 1367c478bd9Sstevel@tonic-gate switch (opt) { 1377c478bd9Sstevel@tonic-gate case 'm': 138*af28f636SEnrico Perla - Sun Microsystems write_mbr = B_TRUE; 1397c478bd9Sstevel@tonic-gate break; 1407c478bd9Sstevel@tonic-gate case 'n': 141*af28f636SEnrico Perla - Sun Microsystems nowrite = B_TRUE; 1427c478bd9Sstevel@tonic-gate break; 1437c478bd9Sstevel@tonic-gate case 'f': 144*af28f636SEnrico Perla - Sun Microsystems force_mbr = B_TRUE; 1457c478bd9Sstevel@tonic-gate break; 1467ce76caaSEnrico Perla - Sun Microsystems case 'i': 147*af28f636SEnrico Perla - Sun Microsystems do_getinfo = B_TRUE; 148*af28f636SEnrico Perla - Sun Microsystems do_install = B_FALSE; 1497ce76caaSEnrico Perla - Sun Microsystems params = 1; 1507ce76caaSEnrico Perla - Sun Microsystems break; 151*af28f636SEnrico Perla - Sun Microsystems case 'V': 152*af28f636SEnrico Perla - Sun Microsystems verbose_dump = B_TRUE; 1537ce76caaSEnrico Perla - Sun Microsystems break; 154*af28f636SEnrico Perla - Sun Microsystems case 'd': 155*af28f636SEnrico Perla - Sun Microsystems boot_debug = B_TRUE; 156*af28f636SEnrico Perla - Sun Microsystems break; 157*af28f636SEnrico Perla - Sun Microsystems case 'F': 158*af28f636SEnrico Perla - Sun Microsystems force_update = B_TRUE; 159*af28f636SEnrico Perla - Sun Microsystems break; 160*af28f636SEnrico Perla - Sun Microsystems case 'e': 161*af28f636SEnrico Perla - Sun Microsystems strip = B_TRUE; 162*af28f636SEnrico Perla - Sun Microsystems break; 163*af28f636SEnrico Perla - Sun Microsystems case 'M': 164*af28f636SEnrico Perla - Sun Microsystems do_mirror_bblk = B_TRUE; 165*af28f636SEnrico Perla - Sun Microsystems do_install = B_FALSE; 166*af28f636SEnrico Perla - Sun Microsystems params = 2; 167*af28f636SEnrico Perla - Sun Microsystems break; 168*af28f636SEnrico Perla - Sun Microsystems case 'u': 169*af28f636SEnrico Perla - Sun Microsystems do_version = B_TRUE; 170*af28f636SEnrico Perla - Sun Microsystems 171*af28f636SEnrico Perla - Sun Microsystems update_str = malloc(strlen(optarg) + 1); 172*af28f636SEnrico Perla - Sun Microsystems if (update_str == NULL) { 173*af28f636SEnrico Perla - Sun Microsystems (void) fprintf(stderr, gettext("Unable to " 174*af28f636SEnrico Perla - Sun Microsystems "allocate memory\n")); 175*af28f636SEnrico Perla - Sun Microsystems exit(BC_ERROR); 176*af28f636SEnrico Perla - Sun Microsystems } 177*af28f636SEnrico Perla - Sun Microsystems (void) strlcpy(update_str, optarg, strlen(optarg) + 1); 1787ce76caaSEnrico Perla - Sun Microsystems break; 1797c478bd9Sstevel@tonic-gate default: 1807c478bd9Sstevel@tonic-gate /* fall through to process non-optional args */ 1817c478bd9Sstevel@tonic-gate break; 1827c478bd9Sstevel@tonic-gate } 1837c478bd9Sstevel@tonic-gate } 1847c478bd9Sstevel@tonic-gate 1857c478bd9Sstevel@tonic-gate /* check arguments */ 1867ce76caaSEnrico Perla - Sun Microsystems if (argc != optind + params) { 1877c478bd9Sstevel@tonic-gate usage(argv[0]); 188*af28f636SEnrico Perla - Sun Microsystems exit(BC_ERROR); 1897c478bd9Sstevel@tonic-gate } 1907c478bd9Sstevel@tonic-gate 191*af28f636SEnrico Perla - Sun Microsystems /* 192*af28f636SEnrico Perla - Sun Microsystems * clean up options (and bail out if an unrecoverable combination is 193*af28f636SEnrico Perla - Sun Microsystems * requested. 194*af28f636SEnrico Perla - Sun Microsystems */ 195*af28f636SEnrico Perla - Sun Microsystems progname = argv[0]; 196*af28f636SEnrico Perla - Sun Microsystems check_options(progname); 197*af28f636SEnrico Perla - Sun Microsystems handle_args = argv + optind; 198*af28f636SEnrico Perla - Sun Microsystems 199*af28f636SEnrico Perla - Sun Microsystems if (nowrite) 2007c478bd9Sstevel@tonic-gate (void) fprintf(stdout, DRY_RUN); 201*af28f636SEnrico Perla - Sun Microsystems 202*af28f636SEnrico Perla - Sun Microsystems if (do_getinfo) { 203*af28f636SEnrico Perla - Sun Microsystems ret = handle_getinfo(progname, handle_args); 204*af28f636SEnrico Perla - Sun Microsystems } else if (do_mirror_bblk) { 205*af28f636SEnrico Perla - Sun Microsystems ret = handle_mirror(progname, handle_args); 206*af28f636SEnrico Perla - Sun Microsystems } else { 207*af28f636SEnrico Perla - Sun Microsystems ret = handle_install(progname, handle_args); 208*af28f636SEnrico Perla - Sun Microsystems } 209*af28f636SEnrico Perla - Sun Microsystems return (ret); 2107c478bd9Sstevel@tonic-gate } 2117c478bd9Sstevel@tonic-gate 212*af28f636SEnrico Perla - Sun Microsystems #define MEANINGLESS_OPT gettext("%s specified but meaningless, ignoring\n") 213*af28f636SEnrico Perla - Sun Microsystems static void 214*af28f636SEnrico Perla - Sun Microsystems check_options(char *progname) 2157c478bd9Sstevel@tonic-gate { 216*af28f636SEnrico Perla - Sun Microsystems if (do_getinfo && do_mirror_bblk) { 217*af28f636SEnrico Perla - Sun Microsystems (void) fprintf(stderr, gettext("Only one of -M and -i can be " 218*af28f636SEnrico Perla - Sun Microsystems "specified at the same time\n")); 219*af28f636SEnrico Perla - Sun Microsystems usage(progname); 220*af28f636SEnrico Perla - Sun Microsystems exit(BC_ERROR); 221*af28f636SEnrico Perla - Sun Microsystems } 222*af28f636SEnrico Perla - Sun Microsystems 223*af28f636SEnrico Perla - Sun Microsystems if (do_mirror_bblk) { 224*af28f636SEnrico Perla - Sun Microsystems /* 225*af28f636SEnrico Perla - Sun Microsystems * -u and -F may actually reflect a user intent that is not 226*af28f636SEnrico Perla - Sun Microsystems * correct with this command (mirror can be interpreted 227*af28f636SEnrico Perla - Sun Microsystems * "similar" to install. Emit a message and continue. 228*af28f636SEnrico Perla - Sun Microsystems * -e and -V have no meaning, be quiet here and only report the 229*af28f636SEnrico Perla - Sun Microsystems * incongruence if a debug output is requested. 230*af28f636SEnrico Perla - Sun Microsystems */ 231*af28f636SEnrico Perla - Sun Microsystems if (do_version) { 232*af28f636SEnrico Perla - Sun Microsystems (void) fprintf(stderr, MEANINGLESS_OPT, "-u"); 233*af28f636SEnrico Perla - Sun Microsystems do_version = B_FALSE; 234*af28f636SEnrico Perla - Sun Microsystems } 235*af28f636SEnrico Perla - Sun Microsystems if (force_update) { 236*af28f636SEnrico Perla - Sun Microsystems (void) fprintf(stderr, MEANINGLESS_OPT, "-F"); 237*af28f636SEnrico Perla - Sun Microsystems force_update = B_FALSE; 238*af28f636SEnrico Perla - Sun Microsystems } 239*af28f636SEnrico Perla - Sun Microsystems if (strip || verbose_dump) { 240*af28f636SEnrico Perla - Sun Microsystems BOOT_DEBUG(MEANINGLESS_OPT, "-e|-V"); 241*af28f636SEnrico Perla - Sun Microsystems strip = B_FALSE; 242*af28f636SEnrico Perla - Sun Microsystems verbose_dump = B_FALSE; 243*af28f636SEnrico Perla - Sun Microsystems } 244*af28f636SEnrico Perla - Sun Microsystems } 245*af28f636SEnrico Perla - Sun Microsystems 246*af28f636SEnrico Perla - Sun Microsystems if (do_getinfo) { 247*af28f636SEnrico Perla - Sun Microsystems if (write_mbr || force_mbr || do_version || force_update) { 248*af28f636SEnrico Perla - Sun Microsystems BOOT_DEBUG(MEANINGLESS_OPT, "-m|-f|-u|-F"); 249*af28f636SEnrico Perla - Sun Microsystems write_mbr = force_mbr = do_version = B_FALSE; 250*af28f636SEnrico Perla - Sun Microsystems force_update = B_FALSE; 251*af28f636SEnrico Perla - Sun Microsystems } 252*af28f636SEnrico Perla - Sun Microsystems } 253*af28f636SEnrico Perla - Sun Microsystems } 254*af28f636SEnrico Perla - Sun Microsystems 255*af28f636SEnrico Perla - Sun Microsystems /* 256*af28f636SEnrico Perla - Sun Microsystems * Install a new stage1/stage2 pair on the specified device. handle_install() 257*af28f636SEnrico Perla - Sun Microsystems * expects argv to contain 3 parameters (the path to stage1, the path to stage2, 258*af28f636SEnrico Perla - Sun Microsystems * the target device). 259*af28f636SEnrico Perla - Sun Microsystems * 260*af28f636SEnrico Perla - Sun Microsystems * Returns: BC_SUCCESS - if the installation is successful 261*af28f636SEnrico Perla - Sun Microsystems * BC_ERROR - if the installation failed 262*af28f636SEnrico Perla - Sun Microsystems * BC_NOUPDT - if no installation was performed because the GRUB 263*af28f636SEnrico Perla - Sun Microsystems * version currently installed is more recent than the 264*af28f636SEnrico Perla - Sun Microsystems * supplied one. 265*af28f636SEnrico Perla - Sun Microsystems * 266*af28f636SEnrico Perla - Sun Microsystems */ 267*af28f636SEnrico Perla - Sun Microsystems static int 268*af28f636SEnrico Perla - Sun Microsystems handle_install(char *progname, char **argv) 269*af28f636SEnrico Perla - Sun Microsystems { 270*af28f636SEnrico Perla - Sun Microsystems ig_data_t install_data; 271*af28f636SEnrico Perla - Sun Microsystems char *stage1_path = NULL; 272*af28f636SEnrico Perla - Sun Microsystems char *stage2_path = NULL; 273*af28f636SEnrico Perla - Sun Microsystems char *device_path = NULL; 274*af28f636SEnrico Perla - Sun Microsystems int ret = BC_ERROR; 275*af28f636SEnrico Perla - Sun Microsystems 276*af28f636SEnrico Perla - Sun Microsystems stage1_path = strdup(argv[0]); 277*af28f636SEnrico Perla - Sun Microsystems stage2_path = strdup(argv[1]); 278*af28f636SEnrico Perla - Sun Microsystems device_path = strdup(argv[2]); 279*af28f636SEnrico Perla - Sun Microsystems 280*af28f636SEnrico Perla - Sun Microsystems bzero(&install_data, sizeof (ig_data_t)); 281*af28f636SEnrico Perla - Sun Microsystems 282*af28f636SEnrico Perla - Sun Microsystems if (!stage1_path || !stage2_path || !device_path) { 283*af28f636SEnrico Perla - Sun Microsystems (void) fprintf(stderr, gettext("Missing parameter")); 284*af28f636SEnrico Perla - Sun Microsystems usage(progname); 285*af28f636SEnrico Perla - Sun Microsystems goto out; 286*af28f636SEnrico Perla - Sun Microsystems } 287*af28f636SEnrico Perla - Sun Microsystems 288*af28f636SEnrico Perla - Sun Microsystems BOOT_DEBUG("stage1 path: %s, stage2 path: %s, device: %s\n", 289*af28f636SEnrico Perla - Sun Microsystems stage1_path, stage2_path, device_path); 290*af28f636SEnrico Perla - Sun Microsystems 291*af28f636SEnrico Perla - Sun Microsystems if (init_device(&install_data.device, device_path) != BC_SUCCESS) { 292*af28f636SEnrico Perla - Sun Microsystems (void) fprintf(stderr, gettext("Unable to gather device " 293*af28f636SEnrico Perla - Sun Microsystems "information for %s\n"), device_path); 294*af28f636SEnrico Perla - Sun Microsystems goto out; 295*af28f636SEnrico Perla - Sun Microsystems } 296*af28f636SEnrico Perla - Sun Microsystems 297*af28f636SEnrico Perla - Sun Microsystems /* read in stage1 and stage2. */ 298*af28f636SEnrico Perla - Sun Microsystems if (read_stage1_from_file(stage1_path, &install_data) != BC_SUCCESS) { 299*af28f636SEnrico Perla - Sun Microsystems (void) fprintf(stderr, gettext("Error opening %s\n"), 300*af28f636SEnrico Perla - Sun Microsystems stage1_path); 301*af28f636SEnrico Perla - Sun Microsystems goto out_dev; 302*af28f636SEnrico Perla - Sun Microsystems } 303*af28f636SEnrico Perla - Sun Microsystems 304*af28f636SEnrico Perla - Sun Microsystems if (read_stage2_from_file(stage2_path, &install_data) != BC_SUCCESS) { 305*af28f636SEnrico Perla - Sun Microsystems (void) fprintf(stderr, gettext("Error opening %s\n"), 306*af28f636SEnrico Perla - Sun Microsystems stage2_path); 307*af28f636SEnrico Perla - Sun Microsystems goto out_dev; 308*af28f636SEnrico Perla - Sun Microsystems } 309*af28f636SEnrico Perla - Sun Microsystems 310*af28f636SEnrico Perla - Sun Microsystems /* We do not support versioning on PCFS. */ 311*af28f636SEnrico Perla - Sun Microsystems if (is_bootpar(install_data.device.type) && do_version) 312*af28f636SEnrico Perla - Sun Microsystems do_version = B_FALSE; 313*af28f636SEnrico Perla - Sun Microsystems 314*af28f636SEnrico Perla - Sun Microsystems /* 315*af28f636SEnrico Perla - Sun Microsystems * is_update_necessary() will take care of checking if versioning and/or 316*af28f636SEnrico Perla - Sun Microsystems * forcing the update have been specified. It will also emit a warning 317*af28f636SEnrico Perla - Sun Microsystems * if a non-versioned update is attempted over a versioned bootblock. 318*af28f636SEnrico Perla - Sun Microsystems */ 319*af28f636SEnrico Perla - Sun Microsystems if (!is_update_necessary(&install_data, update_str)) { 320*af28f636SEnrico Perla - Sun Microsystems (void) fprintf(stderr, gettext("GRUB version installed " 321*af28f636SEnrico Perla - Sun Microsystems "on %s is more recent or identical\n" 322*af28f636SEnrico Perla - Sun Microsystems "Use -F to override or install without the -u option\n"), 323*af28f636SEnrico Perla - Sun Microsystems device_path); 324*af28f636SEnrico Perla - Sun Microsystems ret = BC_NOUPDT; 325*af28f636SEnrico Perla - Sun Microsystems goto out_dev; 326*af28f636SEnrico Perla - Sun Microsystems } 327*af28f636SEnrico Perla - Sun Microsystems /* 328*af28f636SEnrico Perla - Sun Microsystems * We get here if: 329*af28f636SEnrico Perla - Sun Microsystems * - the installed GRUB version is older than the one about to be 330*af28f636SEnrico Perla - Sun Microsystems * installed. 331*af28f636SEnrico Perla - Sun Microsystems * - no versioning string has been passed through the command line. 332*af28f636SEnrico Perla - Sun Microsystems * - a forced update is requested (-F). 333*af28f636SEnrico Perla - Sun Microsystems */ 334*af28f636SEnrico Perla - Sun Microsystems BOOT_DEBUG("Ready to commit to disk\n"); 335*af28f636SEnrico Perla - Sun Microsystems ret = commit_to_disk(&install_data, update_str); 336*af28f636SEnrico Perla - Sun Microsystems 337*af28f636SEnrico Perla - Sun Microsystems out_dev: 338*af28f636SEnrico Perla - Sun Microsystems cleanup_device(&install_data.device); 339*af28f636SEnrico Perla - Sun Microsystems out: 340*af28f636SEnrico Perla - Sun Microsystems free(stage1_path); 341*af28f636SEnrico Perla - Sun Microsystems free(stage2_path); 342*af28f636SEnrico Perla - Sun Microsystems free(device_path); 343*af28f636SEnrico Perla - Sun Microsystems return (ret); 344*af28f636SEnrico Perla - Sun Microsystems } 345*af28f636SEnrico Perla - Sun Microsystems 346*af28f636SEnrico Perla - Sun Microsystems /* 347*af28f636SEnrico Perla - Sun Microsystems * Retrieves from a device the extended information (einfo) associated to the 348*af28f636SEnrico Perla - Sun Microsystems * installed stage2. 349*af28f636SEnrico Perla - Sun Microsystems * Expects one parameter, the device path, in the form: /dev/rdsk/c?[t?]d?s0. 350*af28f636SEnrico Perla - Sun Microsystems * Returns: 351*af28f636SEnrico Perla - Sun Microsystems * - BC_SUCCESS (and prints out einfo contents depending on 'flags') 352*af28f636SEnrico Perla - Sun Microsystems * - BC_ERROR (on error) 353*af28f636SEnrico Perla - Sun Microsystems * - BC_NOEINFO (no extended information available) 354*af28f636SEnrico Perla - Sun Microsystems */ 355*af28f636SEnrico Perla - Sun Microsystems static int 356*af28f636SEnrico Perla - Sun Microsystems handle_getinfo(char *progname, char **argv) 357*af28f636SEnrico Perla - Sun Microsystems { 358*af28f636SEnrico Perla - Sun Microsystems ig_data_t data; 359*af28f636SEnrico Perla - Sun Microsystems ig_stage2_t *stage2 = &data.stage2; 360*af28f636SEnrico Perla - Sun Microsystems ig_device_t *device = &data.device; 361*af28f636SEnrico Perla - Sun Microsystems bblk_einfo_t *einfo; 362*af28f636SEnrico Perla - Sun Microsystems uint8_t flags = 0; 363*af28f636SEnrico Perla - Sun Microsystems uint32_t size; 364*af28f636SEnrico Perla - Sun Microsystems char *device_path; 365*af28f636SEnrico Perla - Sun Microsystems int retval = BC_ERROR; 366*af28f636SEnrico Perla - Sun Microsystems int ret; 367*af28f636SEnrico Perla - Sun Microsystems 368*af28f636SEnrico Perla - Sun Microsystems device_path = strdup(argv[0]); 369*af28f636SEnrico Perla - Sun Microsystems if (!device_path) { 370*af28f636SEnrico Perla - Sun Microsystems (void) fprintf(stderr, gettext("Missing parameter")); 371*af28f636SEnrico Perla - Sun Microsystems usage(progname); 372*af28f636SEnrico Perla - Sun Microsystems goto out; 373*af28f636SEnrico Perla - Sun Microsystems } 374*af28f636SEnrico Perla - Sun Microsystems 375*af28f636SEnrico Perla - Sun Microsystems bzero(&data, sizeof (ig_data_t)); 376*af28f636SEnrico Perla - Sun Microsystems BOOT_DEBUG("device path: %s\n", device_path); 377*af28f636SEnrico Perla - Sun Microsystems 378*af28f636SEnrico Perla - Sun Microsystems if (init_device(device, device_path) != BC_SUCCESS) { 379*af28f636SEnrico Perla - Sun Microsystems (void) fprintf(stderr, gettext("Unable to gather device " 380*af28f636SEnrico Perla - Sun Microsystems "information for %s\n"), device_path); 381*af28f636SEnrico Perla - Sun Microsystems goto out_dev; 382*af28f636SEnrico Perla - Sun Microsystems } 383*af28f636SEnrico Perla - Sun Microsystems 384*af28f636SEnrico Perla - Sun Microsystems if (is_bootpar(device->type)) { 385*af28f636SEnrico Perla - Sun Microsystems (void) fprintf(stderr, gettext("Versioning not supported on " 386*af28f636SEnrico Perla - Sun Microsystems "PCFS\n")); 387*af28f636SEnrico Perla - Sun Microsystems goto out_dev; 388*af28f636SEnrico Perla - Sun Microsystems } 389*af28f636SEnrico Perla - Sun Microsystems 390*af28f636SEnrico Perla - Sun Microsystems ret = read_stage2_from_disk(device->part_fd, stage2); 391*af28f636SEnrico Perla - Sun Microsystems if (ret == BC_ERROR) { 392*af28f636SEnrico Perla - Sun Microsystems (void) fprintf(stderr, gettext("Error reading stage2 from " 393*af28f636SEnrico Perla - Sun Microsystems "%s\n"), device_path); 394*af28f636SEnrico Perla - Sun Microsystems goto out_dev; 395*af28f636SEnrico Perla - Sun Microsystems } 396*af28f636SEnrico Perla - Sun Microsystems 397*af28f636SEnrico Perla - Sun Microsystems if (ret == BC_NOEXTRA) { 398*af28f636SEnrico Perla - Sun Microsystems (void) fprintf(stdout, gettext("No multiboot header found on " 399*af28f636SEnrico Perla - Sun Microsystems "%s, unable to locate extra information area\n"), 400*af28f636SEnrico Perla - Sun Microsystems device_path); 401*af28f636SEnrico Perla - Sun Microsystems retval = BC_NOEINFO; 402*af28f636SEnrico Perla - Sun Microsystems goto out_dev; 403*af28f636SEnrico Perla - Sun Microsystems } 404*af28f636SEnrico Perla - Sun Microsystems 405*af28f636SEnrico Perla - Sun Microsystems einfo = find_einfo(stage2->extra); 406*af28f636SEnrico Perla - Sun Microsystems if (einfo == NULL) { 407*af28f636SEnrico Perla - Sun Microsystems retval = BC_NOEINFO; 408*af28f636SEnrico Perla - Sun Microsystems (void) fprintf(stderr, gettext("No extended information " 409*af28f636SEnrico Perla - Sun Microsystems "found\n")); 410*af28f636SEnrico Perla - Sun Microsystems goto out_dev; 411*af28f636SEnrico Perla - Sun Microsystems } 412*af28f636SEnrico Perla - Sun Microsystems 413*af28f636SEnrico Perla - Sun Microsystems /* Print the extended information. */ 414*af28f636SEnrico Perla - Sun Microsystems if (strip) 415*af28f636SEnrico Perla - Sun Microsystems flags |= EINFO_EASY_PARSE; 416*af28f636SEnrico Perla - Sun Microsystems if (verbose_dump) 417*af28f636SEnrico Perla - Sun Microsystems flags |= EINFO_PRINT_HEADER; 418*af28f636SEnrico Perla - Sun Microsystems 419*af28f636SEnrico Perla - Sun Microsystems size = stage2->buf_size - P2ROUNDUP(stage2->file_size, 8); 420*af28f636SEnrico Perla - Sun Microsystems print_einfo(flags, einfo, size); 421*af28f636SEnrico Perla - Sun Microsystems retval = BC_SUCCESS; 422*af28f636SEnrico Perla - Sun Microsystems 423*af28f636SEnrico Perla - Sun Microsystems out_dev: 424*af28f636SEnrico Perla - Sun Microsystems cleanup_device(&data.device); 425*af28f636SEnrico Perla - Sun Microsystems out: 426*af28f636SEnrico Perla - Sun Microsystems free(device_path); 427*af28f636SEnrico Perla - Sun Microsystems return (retval); 428*af28f636SEnrico Perla - Sun Microsystems } 429*af28f636SEnrico Perla - Sun Microsystems 430*af28f636SEnrico Perla - Sun Microsystems /* 431*af28f636SEnrico Perla - Sun Microsystems * Attempt to mirror (propagate) the current stage2 over the attaching disk. 432*af28f636SEnrico Perla - Sun Microsystems * 433*af28f636SEnrico Perla - Sun Microsystems * Returns: 434*af28f636SEnrico Perla - Sun Microsystems * - BC_SUCCESS (a successful propagation happened) 435*af28f636SEnrico Perla - Sun Microsystems * - BC_ERROR (an error occurred) 436*af28f636SEnrico Perla - Sun Microsystems * - BC_NOEXTRA (it is not possible to dump the current bootblock since 437*af28f636SEnrico Perla - Sun Microsystems * there is no multiboot information) 438*af28f636SEnrico Perla - Sun Microsystems */ 439*af28f636SEnrico Perla - Sun Microsystems static int 440*af28f636SEnrico Perla - Sun Microsystems handle_mirror(char *progname, char **argv) 441*af28f636SEnrico Perla - Sun Microsystems { 442*af28f636SEnrico Perla - Sun Microsystems ig_data_t curr_data; 443*af28f636SEnrico Perla - Sun Microsystems ig_data_t attach_data; 444*af28f636SEnrico Perla - Sun Microsystems ig_device_t *curr_device = &curr_data.device; 445*af28f636SEnrico Perla - Sun Microsystems ig_device_t *attach_device = &attach_data.device; 446*af28f636SEnrico Perla - Sun Microsystems ig_stage2_t *stage2_curr = &curr_data.stage2; 447*af28f636SEnrico Perla - Sun Microsystems ig_stage2_t *stage2_attach = &attach_data.stage2; 448*af28f636SEnrico Perla - Sun Microsystems bblk_einfo_t *einfo_curr = NULL; 449*af28f636SEnrico Perla - Sun Microsystems char *curr_device_path; 450*af28f636SEnrico Perla - Sun Microsystems char *attach_device_path; 451*af28f636SEnrico Perla - Sun Microsystems char *updt_str = NULL; 452*af28f636SEnrico Perla - Sun Microsystems int retval = BC_ERROR; 453*af28f636SEnrico Perla - Sun Microsystems int ret; 454*af28f636SEnrico Perla - Sun Microsystems 455*af28f636SEnrico Perla - Sun Microsystems curr_device_path = strdup(argv[0]); 456*af28f636SEnrico Perla - Sun Microsystems attach_device_path = strdup(argv[1]); 457*af28f636SEnrico Perla - Sun Microsystems 458*af28f636SEnrico Perla - Sun Microsystems if (!curr_device_path || !attach_device_path) { 459*af28f636SEnrico Perla - Sun Microsystems (void) fprintf(stderr, gettext("Missing parameter")); 460*af28f636SEnrico Perla - Sun Microsystems usage(progname); 461*af28f636SEnrico Perla - Sun Microsystems goto out; 462*af28f636SEnrico Perla - Sun Microsystems } 463*af28f636SEnrico Perla - Sun Microsystems BOOT_DEBUG("Current device path is: %s, attaching device path is: " 464*af28f636SEnrico Perla - Sun Microsystems " %s\n", curr_device_path, attach_device_path); 465*af28f636SEnrico Perla - Sun Microsystems 466*af28f636SEnrico Perla - Sun Microsystems bzero(&curr_data, sizeof (ig_data_t)); 467*af28f636SEnrico Perla - Sun Microsystems bzero(&attach_data, sizeof (ig_data_t)); 468*af28f636SEnrico Perla - Sun Microsystems 469*af28f636SEnrico Perla - Sun Microsystems if (init_device(curr_device, curr_device_path) != BC_SUCCESS) { 470*af28f636SEnrico Perla - Sun Microsystems (void) fprintf(stderr, gettext("Unable to gather device " 471*af28f636SEnrico Perla - Sun Microsystems "information for %s (current device)\n"), curr_device_path); 472*af28f636SEnrico Perla - Sun Microsystems goto out_currdev; 473*af28f636SEnrico Perla - Sun Microsystems } 474*af28f636SEnrico Perla - Sun Microsystems 475*af28f636SEnrico Perla - Sun Microsystems if (init_device(attach_device, attach_device_path) != BC_SUCCESS) { 476*af28f636SEnrico Perla - Sun Microsystems (void) fprintf(stderr, gettext("Unable to gather device " 477*af28f636SEnrico Perla - Sun Microsystems "information for %s (attaching device)\n"), 478*af28f636SEnrico Perla - Sun Microsystems attach_device_path); 479*af28f636SEnrico Perla - Sun Microsystems goto out_devs; 480*af28f636SEnrico Perla - Sun Microsystems } 481*af28f636SEnrico Perla - Sun Microsystems 482*af28f636SEnrico Perla - Sun Microsystems if (is_bootpar(curr_device->type) || is_bootpar(attach_device->type)) { 483*af28f636SEnrico Perla - Sun Microsystems (void) fprintf(stderr, gettext("boot block mirroring is not " 484*af28f636SEnrico Perla - Sun Microsystems "supported on PCFS\n")); 485*af28f636SEnrico Perla - Sun Microsystems goto out_devs; 486*af28f636SEnrico Perla - Sun Microsystems } 487*af28f636SEnrico Perla - Sun Microsystems 488*af28f636SEnrico Perla - Sun Microsystems ret = read_stage2_from_disk(curr_device->part_fd, stage2_curr); 489*af28f636SEnrico Perla - Sun Microsystems if (ret == BC_ERROR) { 490*af28f636SEnrico Perla - Sun Microsystems BOOT_DEBUG("Error reading first stage2 blocks from %s\n", 491*af28f636SEnrico Perla - Sun Microsystems curr_device->path); 492*af28f636SEnrico Perla - Sun Microsystems retval = BC_ERROR; 493*af28f636SEnrico Perla - Sun Microsystems goto out_devs; 494*af28f636SEnrico Perla - Sun Microsystems } 495*af28f636SEnrico Perla - Sun Microsystems 496*af28f636SEnrico Perla - Sun Microsystems if (ret == BC_NOEXTRA) { 497*af28f636SEnrico Perla - Sun Microsystems BOOT_DEBUG("No multiboot header found on %s, unable to grab " 498*af28f636SEnrico Perla - Sun Microsystems "stage2\n", curr_device->path); 499*af28f636SEnrico Perla - Sun Microsystems retval = BC_NOEXTRA; 500*af28f636SEnrico Perla - Sun Microsystems goto out_devs; 501*af28f636SEnrico Perla - Sun Microsystems } 502*af28f636SEnrico Perla - Sun Microsystems 503*af28f636SEnrico Perla - Sun Microsystems einfo_curr = find_einfo(stage2_curr->extra); 504*af28f636SEnrico Perla - Sun Microsystems if (einfo_curr != NULL) 505*af28f636SEnrico Perla - Sun Microsystems updt_str = einfo_get_string(einfo_curr); 506*af28f636SEnrico Perla - Sun Microsystems 507*af28f636SEnrico Perla - Sun Microsystems write_mbr = B_TRUE; 508*af28f636SEnrico Perla - Sun Microsystems force_mbr = B_TRUE; 509*af28f636SEnrico Perla - Sun Microsystems retval = propagate_bootblock(&curr_data, &attach_data, updt_str); 510*af28f636SEnrico Perla - Sun Microsystems cleanup_stage2(stage2_curr); 511*af28f636SEnrico Perla - Sun Microsystems cleanup_stage2(stage2_attach); 512*af28f636SEnrico Perla - Sun Microsystems 513*af28f636SEnrico Perla - Sun Microsystems out_devs: 514*af28f636SEnrico Perla - Sun Microsystems cleanup_device(attach_device); 515*af28f636SEnrico Perla - Sun Microsystems out_currdev: 516*af28f636SEnrico Perla - Sun Microsystems cleanup_device(curr_device); 517*af28f636SEnrico Perla - Sun Microsystems out: 518*af28f636SEnrico Perla - Sun Microsystems free(curr_device_path); 519*af28f636SEnrico Perla - Sun Microsystems free(attach_device_path); 520*af28f636SEnrico Perla - Sun Microsystems return (retval); 521*af28f636SEnrico Perla - Sun Microsystems } 522*af28f636SEnrico Perla - Sun Microsystems 523*af28f636SEnrico Perla - Sun Microsystems static int 524*af28f636SEnrico Perla - Sun Microsystems commit_to_disk(ig_data_t *install, char *updt_str) 525*af28f636SEnrico Perla - Sun Microsystems { 526*af28f636SEnrico Perla - Sun Microsystems assert(install != NULL); 527*af28f636SEnrico Perla - Sun Microsystems /* 528*af28f636SEnrico Perla - Sun Microsystems * vanilla stage1 and stage2 need to be updated at runtime. 529*af28f636SEnrico Perla - Sun Microsystems * Update stage2 before stage1 because stage1 needs to know the first 530*af28f636SEnrico Perla - Sun Microsystems * sector stage2 will be written to. 531*af28f636SEnrico Perla - Sun Microsystems */ 532*af28f636SEnrico Perla - Sun Microsystems if (prepare_stage2(install, updt_str) != BC_SUCCESS) { 533*af28f636SEnrico Perla - Sun Microsystems (void) fprintf(stderr, gettext("Error building stage2\n")); 534*af28f636SEnrico Perla - Sun Microsystems return (BC_ERROR); 535*af28f636SEnrico Perla - Sun Microsystems } 536*af28f636SEnrico Perla - Sun Microsystems if (prepare_stage1(install) != BC_SUCCESS) { 537*af28f636SEnrico Perla - Sun Microsystems (void) fprintf(stderr, gettext("Error building stage1\n")); 538*af28f636SEnrico Perla - Sun Microsystems return (BC_ERROR); 539*af28f636SEnrico Perla - Sun Microsystems } 540*af28f636SEnrico Perla - Sun Microsystems 541*af28f636SEnrico Perla - Sun Microsystems /* Write stage2 out to disk. */ 542*af28f636SEnrico Perla - Sun Microsystems if (write_stage2(install) != BC_SUCCESS) { 543*af28f636SEnrico Perla - Sun Microsystems (void) fprintf(stderr, gettext("Error writing stage2 to " 544*af28f636SEnrico Perla - Sun Microsystems "disk\n")); 545*af28f636SEnrico Perla - Sun Microsystems return (BC_ERROR); 546*af28f636SEnrico Perla - Sun Microsystems } 547*af28f636SEnrico Perla - Sun Microsystems 548*af28f636SEnrico Perla - Sun Microsystems /* Write stage1 to disk and, if requested, to the MBR. */ 549*af28f636SEnrico Perla - Sun Microsystems if (write_stage1(install) != BC_SUCCESS) { 550*af28f636SEnrico Perla - Sun Microsystems (void) fprintf(stderr, gettext("Error writing stage1 to " 551*af28f636SEnrico Perla - Sun Microsystems "disk\n")); 552*af28f636SEnrico Perla - Sun Microsystems return (BC_ERROR); 553*af28f636SEnrico Perla - Sun Microsystems } 554*af28f636SEnrico Perla - Sun Microsystems 555*af28f636SEnrico Perla - Sun Microsystems return (BC_SUCCESS); 556*af28f636SEnrico Perla - Sun Microsystems } 557*af28f636SEnrico Perla - Sun Microsystems 558*af28f636SEnrico Perla - Sun Microsystems /* 559*af28f636SEnrico Perla - Sun Microsystems * Propagate the bootblock on the source disk to the destination disk and 560*af28f636SEnrico Perla - Sun Microsystems * version it with 'updt_str' in the process. Since we cannot trust any data 561*af28f636SEnrico Perla - Sun Microsystems * on the attaching disk, we do not perform any specific check on a potential 562*af28f636SEnrico Perla - Sun Microsystems * target extended information structure and we just blindly update. 563*af28f636SEnrico Perla - Sun Microsystems */ 564*af28f636SEnrico Perla - Sun Microsystems static int 565*af28f636SEnrico Perla - Sun Microsystems propagate_bootblock(ig_data_t *source, ig_data_t *target, char *updt_str) 566*af28f636SEnrico Perla - Sun Microsystems { 567*af28f636SEnrico Perla - Sun Microsystems ig_device_t *src_device = &source->device; 568*af28f636SEnrico Perla - Sun Microsystems ig_device_t *dest_device = &target->device; 569*af28f636SEnrico Perla - Sun Microsystems ig_stage2_t *src_stage2 = &source->stage2; 570*af28f636SEnrico Perla - Sun Microsystems ig_stage2_t *dest_stage2 = &target->stage2; 571*af28f636SEnrico Perla - Sun Microsystems uint32_t buf_size; 572*af28f636SEnrico Perla - Sun Microsystems int retval; 573*af28f636SEnrico Perla - Sun Microsystems 574*af28f636SEnrico Perla - Sun Microsystems assert(source != NULL); 575*af28f636SEnrico Perla - Sun Microsystems assert(target != NULL); 576*af28f636SEnrico Perla - Sun Microsystems 577*af28f636SEnrico Perla - Sun Microsystems /* read in stage1 from the source disk. */ 578*af28f636SEnrico Perla - Sun Microsystems if (read_stage1_from_disk(src_device->part_fd, target->stage1_buf) 579*af28f636SEnrico Perla - Sun Microsystems != BC_SUCCESS) 580*af28f636SEnrico Perla - Sun Microsystems return (BC_ERROR); 581*af28f636SEnrico Perla - Sun Microsystems 582*af28f636SEnrico Perla - Sun Microsystems /* Prepare target stage2 for commit_to_disk. */ 583*af28f636SEnrico Perla - Sun Microsystems cleanup_stage2(dest_stage2); 584*af28f636SEnrico Perla - Sun Microsystems 585*af28f636SEnrico Perla - Sun Microsystems if (updt_str != NULL) 586*af28f636SEnrico Perla - Sun Microsystems do_version = B_TRUE; 587*af28f636SEnrico Perla - Sun Microsystems else 588*af28f636SEnrico Perla - Sun Microsystems do_version = B_FALSE; 589*af28f636SEnrico Perla - Sun Microsystems 590*af28f636SEnrico Perla - Sun Microsystems buf_size = src_stage2->file_size + SECTOR_SIZE; 591*af28f636SEnrico Perla - Sun Microsystems 592*af28f636SEnrico Perla - Sun Microsystems dest_stage2->buf_size = P2ROUNDUP(buf_size, SECTOR_SIZE); 593*af28f636SEnrico Perla - Sun Microsystems dest_stage2->buf = malloc(dest_stage2->buf_size); 594*af28f636SEnrico Perla - Sun Microsystems if (dest_stage2->buf == NULL) { 595*af28f636SEnrico Perla - Sun Microsystems perror(gettext("Memory allocation failed")); 596*af28f636SEnrico Perla - Sun Microsystems return (BC_ERROR); 597*af28f636SEnrico Perla - Sun Microsystems } 598*af28f636SEnrico Perla - Sun Microsystems dest_stage2->file = dest_stage2->buf; 599*af28f636SEnrico Perla - Sun Microsystems dest_stage2->file_size = src_stage2->file_size; 600*af28f636SEnrico Perla - Sun Microsystems memcpy(dest_stage2->file, src_stage2->file, dest_stage2->file_size); 601*af28f636SEnrico Perla - Sun Microsystems dest_stage2->extra = dest_stage2->buf + 602*af28f636SEnrico Perla - Sun Microsystems P2ROUNDUP(dest_stage2->file_size, 8); 603*af28f636SEnrico Perla - Sun Microsystems 604*af28f636SEnrico Perla - Sun Microsystems /* If we get down here we do have a mboot structure. */ 605*af28f636SEnrico Perla - Sun Microsystems assert(src_stage2->mboot); 606*af28f636SEnrico Perla - Sun Microsystems 607*af28f636SEnrico Perla - Sun Microsystems dest_stage2->mboot_off = src_stage2->mboot_off; 608*af28f636SEnrico Perla - Sun Microsystems dest_stage2->mboot = (multiboot_header_t *)(dest_stage2->buf + 609*af28f636SEnrico Perla - Sun Microsystems dest_stage2->mboot_off); 610*af28f636SEnrico Perla - Sun Microsystems 611*af28f636SEnrico Perla - Sun Microsystems (void) fprintf(stdout, gettext("Propagating %s stage1/stage2 to %s\n"), 612*af28f636SEnrico Perla - Sun Microsystems src_device->path, dest_device->path); 613*af28f636SEnrico Perla - Sun Microsystems retval = commit_to_disk(target, updt_str); 614*af28f636SEnrico Perla - Sun Microsystems 615*af28f636SEnrico Perla - Sun Microsystems return (retval); 616*af28f636SEnrico Perla - Sun Microsystems } 617*af28f636SEnrico Perla - Sun Microsystems 618*af28f636SEnrico Perla - Sun Microsystems /* 619*af28f636SEnrico Perla - Sun Microsystems * open the device and fill the various members of ig_device_t. 620*af28f636SEnrico Perla - Sun Microsystems */ 621*af28f636SEnrico Perla - Sun Microsystems static int 622*af28f636SEnrico Perla - Sun Microsystems init_device(ig_device_t *device, char *path) 623*af28f636SEnrico Perla - Sun Microsystems { 624*af28f636SEnrico Perla - Sun Microsystems bzero(device, sizeof (*device)); 625*af28f636SEnrico Perla - Sun Microsystems device->part_fd = -1; 626*af28f636SEnrico Perla - Sun Microsystems device->disk_fd = -1; 627*af28f636SEnrico Perla - Sun Microsystems device->path_p0 = NULL; 628*af28f636SEnrico Perla - Sun Microsystems 629*af28f636SEnrico Perla - Sun Microsystems device->path = strdup(path); 630*af28f636SEnrico Perla - Sun Microsystems if (device->path == NULL) { 631*af28f636SEnrico Perla - Sun Microsystems perror(gettext("Memory allocation failed")); 632*af28f636SEnrico Perla - Sun Microsystems return (BC_ERROR); 633*af28f636SEnrico Perla - Sun Microsystems } 634*af28f636SEnrico Perla - Sun Microsystems 635*af28f636SEnrico Perla - Sun Microsystems if (strstr(device->path, "diskette")) { 636*af28f636SEnrico Perla - Sun Microsystems (void) fprintf(stderr, gettext("installing GRUB to a floppy " 637*af28f636SEnrico Perla - Sun Microsystems "disk is no longer supported\n")); 638*af28f636SEnrico Perla - Sun Microsystems return (BC_ERROR); 639*af28f636SEnrico Perla - Sun Microsystems } 640*af28f636SEnrico Perla - Sun Microsystems 641*af28f636SEnrico Perla - Sun Microsystems /* Detect if the target device is a pcfs partition. */ 642*af28f636SEnrico Perla - Sun Microsystems if (strstr(device->path, "p0:boot")) 643*af28f636SEnrico Perla - Sun Microsystems device->type = IG_DEV_X86BOOTPAR; 644*af28f636SEnrico Perla - Sun Microsystems 645*af28f636SEnrico Perla - Sun Microsystems if (get_disk_fd(device) != BC_SUCCESS) 646*af28f636SEnrico Perla - Sun Microsystems return (BC_ERROR); 647*af28f636SEnrico Perla - Sun Microsystems 648*af28f636SEnrico Perla - Sun Microsystems /* read in the device boot sector. */ 649*af28f636SEnrico Perla - Sun Microsystems if (read(device->disk_fd, device->boot_sector, SECTOR_SIZE) 650*af28f636SEnrico Perla - Sun Microsystems != SECTOR_SIZE) { 651*af28f636SEnrico Perla - Sun Microsystems (void) fprintf(stderr, gettext("Error reading boot sector\n")); 652*af28f636SEnrico Perla - Sun Microsystems perror("read"); 653*af28f636SEnrico Perla - Sun Microsystems return (BC_ERROR); 654*af28f636SEnrico Perla - Sun Microsystems } 655*af28f636SEnrico Perla - Sun Microsystems 656*af28f636SEnrico Perla - Sun Microsystems if (get_raw_partition_fd(device) != BC_SUCCESS) 657*af28f636SEnrico Perla - Sun Microsystems return (BC_ERROR); 658*af28f636SEnrico Perla - Sun Microsystems 659*af28f636SEnrico Perla - Sun Microsystems if (get_start_sector(device) != BC_SUCCESS) 660*af28f636SEnrico Perla - Sun Microsystems return (BC_ERROR); 661*af28f636SEnrico Perla - Sun Microsystems 662*af28f636SEnrico Perla - Sun Microsystems return (BC_SUCCESS); 663*af28f636SEnrico Perla - Sun Microsystems } 664*af28f636SEnrico Perla - Sun Microsystems 665*af28f636SEnrico Perla - Sun Microsystems static void 666*af28f636SEnrico Perla - Sun Microsystems cleanup_device(ig_device_t *device) 667*af28f636SEnrico Perla - Sun Microsystems { 668*af28f636SEnrico Perla - Sun Microsystems if (device->path) 669*af28f636SEnrico Perla - Sun Microsystems free(device->path); 670*af28f636SEnrico Perla - Sun Microsystems if (device->path_p0) 671*af28f636SEnrico Perla - Sun Microsystems free(device->path_p0); 672*af28f636SEnrico Perla - Sun Microsystems 673*af28f636SEnrico Perla - Sun Microsystems if (device->part_fd != -1) 674*af28f636SEnrico Perla - Sun Microsystems (void) close(device->part_fd); 675*af28f636SEnrico Perla - Sun Microsystems if (device->disk_fd != -1) 676*af28f636SEnrico Perla - Sun Microsystems (void) close(device->disk_fd); 677*af28f636SEnrico Perla - Sun Microsystems 678*af28f636SEnrico Perla - Sun Microsystems bzero(device, sizeof (ig_device_t)); 679*af28f636SEnrico Perla - Sun Microsystems device->part_fd = -1; 680*af28f636SEnrico Perla - Sun Microsystems device->disk_fd = -1; 681*af28f636SEnrico Perla - Sun Microsystems } 682*af28f636SEnrico Perla - Sun Microsystems 683*af28f636SEnrico Perla - Sun Microsystems static void 684*af28f636SEnrico Perla - Sun Microsystems cleanup_stage2(ig_stage2_t *stage2) 685*af28f636SEnrico Perla - Sun Microsystems { 686*af28f636SEnrico Perla - Sun Microsystems if (stage2->buf) 687*af28f636SEnrico Perla - Sun Microsystems free(stage2->buf); 688*af28f636SEnrico Perla - Sun Microsystems bzero(stage2, sizeof (ig_stage2_t)); 689*af28f636SEnrico Perla - Sun Microsystems } 690*af28f636SEnrico Perla - Sun Microsystems 691*af28f636SEnrico Perla - Sun Microsystems static int 692*af28f636SEnrico Perla - Sun Microsystems get_start_sector(ig_device_t *device) 693*af28f636SEnrico Perla - Sun Microsystems { 6947fc5d2a4SVikram Hegde uint32_t secnum = 0, numsec = 0; 6957fc5d2a4SVikram Hegde int i, pno, rval, log_part = 0; 6967c478bd9Sstevel@tonic-gate struct mboot *mboot; 6977c478bd9Sstevel@tonic-gate struct ipart *part; 698aa1b14e7SSheshadri Vasudevan ext_part_t *epp; 6997fc5d2a4SVikram Hegde struct part_info dkpi; 7007fc5d2a4SVikram Hegde struct extpart_info edkpi; 7017c478bd9Sstevel@tonic-gate 702*af28f636SEnrico Perla - Sun Microsystems mboot = (struct mboot *)device->boot_sector; 7037c478bd9Sstevel@tonic-gate 704*af28f636SEnrico Perla - Sun Microsystems if (is_bootpar(device->type)) { 705*af28f636SEnrico Perla - Sun Microsystems if (find_x86_bootpar(mboot, &pno, &secnum) != BC_SUCCESS) { 706*af28f636SEnrico Perla - Sun Microsystems (void) fprintf(stderr, NOBOOTPAR); 707*af28f636SEnrico Perla - Sun Microsystems return (BC_ERROR); 708*af28f636SEnrico Perla - Sun Microsystems } else { 709*af28f636SEnrico Perla - Sun Microsystems device->start_sector = secnum; 710*af28f636SEnrico Perla - Sun Microsystems device->partition = pno; 7117fc5d2a4SVikram Hegde goto found_part; 7127fc5d2a4SVikram Hegde } 713d33344bbSsy25831 } 714d33344bbSsy25831 715aa1b14e7SSheshadri Vasudevan /* 716*af28f636SEnrico Perla - Sun Microsystems * Search for Solaris fdisk partition 717d33344bbSsy25831 * Get the solaris partition information from the device 718d33344bbSsy25831 * and compare the offset of S2 with offset of solaris partition 719d33344bbSsy25831 * from fdisk partition table. 720d33344bbSsy25831 */ 721*af28f636SEnrico Perla - Sun Microsystems if (ioctl(device->part_fd, DKIOCEXTPARTINFO, &edkpi) < 0) { 722*af28f636SEnrico Perla - Sun Microsystems if (ioctl(device->part_fd, DKIOCPARTINFO, &dkpi) < 0) { 723d33344bbSsy25831 (void) fprintf(stderr, PART_FAIL); 724*af28f636SEnrico Perla - Sun Microsystems return (BC_ERROR); 725342440ecSPrasad Singamsetty } else { 726342440ecSPrasad Singamsetty edkpi.p_start = dkpi.p_start; 727342440ecSPrasad Singamsetty } 728d33344bbSsy25831 } 729d33344bbSsy25831 730d33344bbSsy25831 for (i = 0; i < FD_NUMPART; i++) { 731d33344bbSsy25831 part = (struct ipart *)mboot->parts + i; 732d33344bbSsy25831 733d33344bbSsy25831 if (part->relsect == 0) { 734d33344bbSsy25831 (void) fprintf(stderr, BAD_PART, i); 735*af28f636SEnrico Perla - Sun Microsystems return (BC_ERROR); 736d33344bbSsy25831 } 737aa1b14e7SSheshadri Vasudevan 738342440ecSPrasad Singamsetty if (edkpi.p_start >= part->relsect && 739342440ecSPrasad Singamsetty edkpi.p_start < (part->relsect + part->numsect)) { 740d33344bbSsy25831 /* Found the partition */ 7417c478bd9Sstevel@tonic-gate break; 742d33344bbSsy25831 } 7437c478bd9Sstevel@tonic-gate } 7447c478bd9Sstevel@tonic-gate 7457fc5d2a4SVikram Hegde if (i == FD_NUMPART) { 7467fc5d2a4SVikram Hegde /* No solaris fdisk partitions (primary or logical) */ 7477fc5d2a4SVikram Hegde (void) fprintf(stderr, NOSOLPAR); 748*af28f636SEnrico Perla - Sun Microsystems return (BC_ERROR); 7497c478bd9Sstevel@tonic-gate } 7507c478bd9Sstevel@tonic-gate 7517fc5d2a4SVikram Hegde /* 7527fc5d2a4SVikram Hegde * We have found a Solaris fdisk partition (primary or extended) 7537fc5d2a4SVikram Hegde * Handle the simple case first: Solaris in a primary partition 7547fc5d2a4SVikram Hegde */ 7557fc5d2a4SVikram Hegde if (!fdisk_is_dos_extended(part->systid)) { 756*af28f636SEnrico Perla - Sun Microsystems device->start_sector = part->relsect; 757*af28f636SEnrico Perla - Sun Microsystems device->partition = i; 7587fc5d2a4SVikram Hegde goto found_part; 7597fc5d2a4SVikram Hegde } 7607fc5d2a4SVikram Hegde 7617fc5d2a4SVikram Hegde /* 7627fc5d2a4SVikram Hegde * Solaris in a logical partition. Find that partition in the 7637fc5d2a4SVikram Hegde * extended part. 7647fc5d2a4SVikram Hegde */ 765*af28f636SEnrico Perla - Sun Microsystems if ((rval = libfdisk_init(&epp, device->path_p0, NULL, FDISK_READ_DISK)) 7667fc5d2a4SVikram Hegde != FDISK_SUCCESS) { 7677fc5d2a4SVikram Hegde switch (rval) { 7687fc5d2a4SVikram Hegde /* 7696cb5747bSSharath M Srinivasan * The first 3 cases are not an error per-se, just that 7707fc5d2a4SVikram Hegde * there is no Solaris logical partition 7717fc5d2a4SVikram Hegde */ 7727fc5d2a4SVikram Hegde case FDISK_EBADLOGDRIVE: 7737fc5d2a4SVikram Hegde case FDISK_ENOLOGDRIVE: 7746cb5747bSSharath M Srinivasan case FDISK_EBADMAGIC: 7757fc5d2a4SVikram Hegde (void) fprintf(stderr, NOSOLPAR); 776*af28f636SEnrico Perla - Sun Microsystems return (BC_ERROR); 7777fc5d2a4SVikram Hegde case FDISK_ENOVGEOM: 7787fc5d2a4SVikram Hegde (void) fprintf(stderr, NO_VIRT_GEOM); 779*af28f636SEnrico Perla - Sun Microsystems return (BC_ERROR); 7807fc5d2a4SVikram Hegde case FDISK_ENOPGEOM: 7817fc5d2a4SVikram Hegde (void) fprintf(stderr, NO_PHYS_GEOM); 782*af28f636SEnrico Perla - Sun Microsystems return (BC_ERROR); 7837fc5d2a4SVikram Hegde case FDISK_ENOLGEOM: 7847fc5d2a4SVikram Hegde (void) fprintf(stderr, NO_LABEL_GEOM); 785*af28f636SEnrico Perla - Sun Microsystems return (BC_ERROR); 7867fc5d2a4SVikram Hegde default: 7877fc5d2a4SVikram Hegde (void) fprintf(stderr, LIBFDISK_INIT_FAIL); 788*af28f636SEnrico Perla - Sun Microsystems return (BC_ERROR); 7897fc5d2a4SVikram Hegde break; 7907fc5d2a4SVikram Hegde } 7917fc5d2a4SVikram Hegde } 7927fc5d2a4SVikram Hegde 7937fc5d2a4SVikram Hegde rval = fdisk_get_solaris_part(epp, &pno, &secnum, &numsec); 7946cb5747bSSharath M Srinivasan libfdisk_fini(&epp); 7957fc5d2a4SVikram Hegde if (rval != FDISK_SUCCESS) { 7967fc5d2a4SVikram Hegde /* No solaris logical partition */ 7977fc5d2a4SVikram Hegde (void) fprintf(stderr, NOSOLPAR); 798*af28f636SEnrico Perla - Sun Microsystems return (BC_ERROR); 7997fc5d2a4SVikram Hegde } 8007fc5d2a4SVikram Hegde 801*af28f636SEnrico Perla - Sun Microsystems device->start_sector = secnum; 802*af28f636SEnrico Perla - Sun Microsystems device->partition = pno - 1; 8037fc5d2a4SVikram Hegde log_part = 1; 8047fc5d2a4SVikram Hegde 8057fc5d2a4SVikram Hegde found_part: 8067c478bd9Sstevel@tonic-gate /* get confirmation for -m */ 807*af28f636SEnrico Perla - Sun Microsystems if (write_mbr && !force_mbr) { 8087c478bd9Sstevel@tonic-gate (void) fprintf(stdout, MBOOT_PROMPT); 8097c478bd9Sstevel@tonic-gate if (getchar() != 'y') { 810*af28f636SEnrico Perla - Sun Microsystems write_mbr = 0; 8117c478bd9Sstevel@tonic-gate (void) fprintf(stdout, MBOOT_NOT_UPDATED); 812*af28f636SEnrico Perla - Sun Microsystems return (BC_ERROR); 8137c478bd9Sstevel@tonic-gate } 8147c478bd9Sstevel@tonic-gate } 8157c478bd9Sstevel@tonic-gate 8167fc5d2a4SVikram Hegde /* 8177fc5d2a4SVikram Hegde * Currently if Solaris is in an extended partition we need to 8187fc5d2a4SVikram Hegde * write GRUB to the MBR. Check for this. 8197fc5d2a4SVikram Hegde */ 820*af28f636SEnrico Perla - Sun Microsystems if (log_part && !write_mbr) { 821*af28f636SEnrico Perla - Sun Microsystems (void) fprintf(stdout, gettext("Installing Solaris on an " 822*af28f636SEnrico Perla - Sun Microsystems "extended partition... forcing MBR update\n")); 823*af28f636SEnrico Perla - Sun Microsystems write_mbr = 1; 824aa1b14e7SSheshadri Vasudevan } 825aa1b14e7SSheshadri Vasudevan 8267fc5d2a4SVikram Hegde /* 8277fc5d2a4SVikram Hegde * warn, if Solaris in primary partition and GRUB not in MBR and 8287fc5d2a4SVikram Hegde * partition is not active 8297fc5d2a4SVikram Hegde */ 830*af28f636SEnrico Perla - Sun Microsystems if (!log_part && part->bootid != 128 && !write_mbr) { 831*af28f636SEnrico Perla - Sun Microsystems (void) fprintf(stdout, SOLPAR_INACTIVE, device->partition + 1); 8327c478bd9Sstevel@tonic-gate } 8337c478bd9Sstevel@tonic-gate 834*af28f636SEnrico Perla - Sun Microsystems return (BC_SUCCESS); 8357c478bd9Sstevel@tonic-gate } 8367c478bd9Sstevel@tonic-gate 837*af28f636SEnrico Perla - Sun Microsystems static int 838*af28f636SEnrico Perla - Sun Microsystems get_disk_fd(ig_device_t *device) 839*af28f636SEnrico Perla - Sun Microsystems { 840*af28f636SEnrico Perla - Sun Microsystems int i; 841*af28f636SEnrico Perla - Sun Microsystems char save[2]; 842*af28f636SEnrico Perla - Sun Microsystems char *end = NULL; 843*af28f636SEnrico Perla - Sun Microsystems 844*af28f636SEnrico Perla - Sun Microsystems assert(device != NULL); 845*af28f636SEnrico Perla - Sun Microsystems assert(device->path != NULL); 846*af28f636SEnrico Perla - Sun Microsystems 847*af28f636SEnrico Perla - Sun Microsystems if (is_bootpar(device->type)) { 848*af28f636SEnrico Perla - Sun Microsystems end = strstr(device->path, "p0:boot"); 849*af28f636SEnrico Perla - Sun Microsystems /* tested at the start of init_device() */ 850*af28f636SEnrico Perla - Sun Microsystems assert(end != NULL); 851*af28f636SEnrico Perla - Sun Microsystems /* chop off :boot */ 852*af28f636SEnrico Perla - Sun Microsystems save[0] = end[2]; 853*af28f636SEnrico Perla - Sun Microsystems end[2] = '\0'; 854*af28f636SEnrico Perla - Sun Microsystems } else { 855*af28f636SEnrico Perla - Sun Microsystems i = strlen(device->path); 856*af28f636SEnrico Perla - Sun Microsystems save[0] = device->path[i - 2]; 857*af28f636SEnrico Perla - Sun Microsystems save[1] = device->path[i - 1]; 858*af28f636SEnrico Perla - Sun Microsystems device->path[i - 2] = 'p'; 859*af28f636SEnrico Perla - Sun Microsystems device->path[i - 1] = '0'; 860*af28f636SEnrico Perla - Sun Microsystems } 861*af28f636SEnrico Perla - Sun Microsystems 862*af28f636SEnrico Perla - Sun Microsystems if (nowrite) 863*af28f636SEnrico Perla - Sun Microsystems device->disk_fd = open(device->path, O_RDONLY); 864*af28f636SEnrico Perla - Sun Microsystems else 865*af28f636SEnrico Perla - Sun Microsystems device->disk_fd = open(device->path, O_RDWR); 866*af28f636SEnrico Perla - Sun Microsystems 867*af28f636SEnrico Perla - Sun Microsystems device->path_p0 = strdup(device->path); 868*af28f636SEnrico Perla - Sun Microsystems if (device->path_p0 == NULL) { 869*af28f636SEnrico Perla - Sun Microsystems perror("strdup"); 870*af28f636SEnrico Perla - Sun Microsystems return (BC_ERROR); 871*af28f636SEnrico Perla - Sun Microsystems } 872*af28f636SEnrico Perla - Sun Microsystems 873*af28f636SEnrico Perla - Sun Microsystems if (is_bootpar(device->type)) { 874*af28f636SEnrico Perla - Sun Microsystems end[2] = save[0]; 875*af28f636SEnrico Perla - Sun Microsystems } else { 876*af28f636SEnrico Perla - Sun Microsystems device->path[i - 2] = save[0]; 877*af28f636SEnrico Perla - Sun Microsystems device->path[i - 1] = save[1]; 878*af28f636SEnrico Perla - Sun Microsystems } 879*af28f636SEnrico Perla - Sun Microsystems 880*af28f636SEnrico Perla - Sun Microsystems if (device->disk_fd == -1) { 881*af28f636SEnrico Perla - Sun Microsystems perror("open"); 882*af28f636SEnrico Perla - Sun Microsystems return (BC_ERROR); 883*af28f636SEnrico Perla - Sun Microsystems } 884*af28f636SEnrico Perla - Sun Microsystems 885*af28f636SEnrico Perla - Sun Microsystems return (BC_SUCCESS); 886*af28f636SEnrico Perla - Sun Microsystems } 887*af28f636SEnrico Perla - Sun Microsystems 888*af28f636SEnrico Perla - Sun Microsystems static void 889*af28f636SEnrico Perla - Sun Microsystems prepare_fake_multiboot(ig_stage2_t *stage2) 890*af28f636SEnrico Perla - Sun Microsystems { 891*af28f636SEnrico Perla - Sun Microsystems multiboot_header_t *mboot; 892*af28f636SEnrico Perla - Sun Microsystems 893*af28f636SEnrico Perla - Sun Microsystems assert(stage2 != NULL); 894*af28f636SEnrico Perla - Sun Microsystems assert(stage2->mboot != NULL); 895*af28f636SEnrico Perla - Sun Microsystems assert(stage2->buf != NULL); 896*af28f636SEnrico Perla - Sun Microsystems 897*af28f636SEnrico Perla - Sun Microsystems mboot = stage2->mboot; 898*af28f636SEnrico Perla - Sun Microsystems 899*af28f636SEnrico Perla - Sun Microsystems /* 900*af28f636SEnrico Perla - Sun Microsystems * Currently we expect find_multiboot() to have located a multiboot 901*af28f636SEnrico Perla - Sun Microsystems * header with the AOUT kludge flag set. 902*af28f636SEnrico Perla - Sun Microsystems */ 903*af28f636SEnrico Perla - Sun Microsystems assert(mboot->flags & BB_MBOOT_AOUT_FLAG); 904*af28f636SEnrico Perla - Sun Microsystems 905*af28f636SEnrico Perla - Sun Microsystems /* Insert the information necessary to locate stage2. */ 906*af28f636SEnrico Perla - Sun Microsystems mboot->header_addr = stage2->mboot_off; 907*af28f636SEnrico Perla - Sun Microsystems mboot->load_addr = 0; 908*af28f636SEnrico Perla - Sun Microsystems mboot->load_end_addr = stage2->file_size; 909*af28f636SEnrico Perla - Sun Microsystems } 910*af28f636SEnrico Perla - Sun Microsystems 911*af28f636SEnrico Perla - Sun Microsystems static void 912*af28f636SEnrico Perla - Sun Microsystems add_stage2_einfo(ig_stage2_t *stage2, char *updt_str) 913*af28f636SEnrico Perla - Sun Microsystems { 914*af28f636SEnrico Perla - Sun Microsystems bblk_hs_t hs; 915*af28f636SEnrico Perla - Sun Microsystems uint32_t avail_space; 916*af28f636SEnrico Perla - Sun Microsystems 917*af28f636SEnrico Perla - Sun Microsystems assert(stage2 != NULL); 918*af28f636SEnrico Perla - Sun Microsystems 919*af28f636SEnrico Perla - Sun Microsystems /* Fill bootblock hashing source information. */ 920*af28f636SEnrico Perla - Sun Microsystems hs.src_buf = (unsigned char *)stage2->file; 921*af28f636SEnrico Perla - Sun Microsystems hs.src_size = stage2->file_size; 922*af28f636SEnrico Perla - Sun Microsystems /* How much space for the extended information structure? */ 923*af28f636SEnrico Perla - Sun Microsystems avail_space = stage2->buf_size - P2ROUNDUP(stage2->file_size, 8); 924*af28f636SEnrico Perla - Sun Microsystems add_einfo(stage2->extra, updt_str, &hs, avail_space); 925*af28f636SEnrico Perla - Sun Microsystems } 926*af28f636SEnrico Perla - Sun Microsystems 927*af28f636SEnrico Perla - Sun Microsystems 928*af28f636SEnrico Perla - Sun Microsystems static int 929*af28f636SEnrico Perla - Sun Microsystems write_stage2(ig_data_t *install) 930*af28f636SEnrico Perla - Sun Microsystems { 931*af28f636SEnrico Perla - Sun Microsystems ig_device_t *device = &install->device; 932*af28f636SEnrico Perla - Sun Microsystems ig_stage2_t *stage2 = &install->stage2; 933*af28f636SEnrico Perla - Sun Microsystems off_t offset; 934*af28f636SEnrico Perla - Sun Microsystems 935*af28f636SEnrico Perla - Sun Microsystems assert(install != NULL); 936*af28f636SEnrico Perla - Sun Microsystems 937*af28f636SEnrico Perla - Sun Microsystems if (is_bootpar(device->type)) { 938*af28f636SEnrico Perla - Sun Microsystems /* 939*af28f636SEnrico Perla - Sun Microsystems * stage2 is already on the filesystem, we only need to update 940*af28f636SEnrico Perla - Sun Microsystems * the first two blocks (that we have modified during 941*af28f636SEnrico Perla - Sun Microsystems * prepare_stage2()) 942*af28f636SEnrico Perla - Sun Microsystems */ 943*af28f636SEnrico Perla - Sun Microsystems if (write_out(device->part_fd, stage2->file, SECTOR_SIZE, 944*af28f636SEnrico Perla - Sun Microsystems stage2->pcfs_first_sectors[0] * SECTOR_SIZE) 945*af28f636SEnrico Perla - Sun Microsystems != BC_SUCCESS || 946*af28f636SEnrico Perla - Sun Microsystems write_out(device->part_fd, stage2->file + SECTOR_SIZE, 947*af28f636SEnrico Perla - Sun Microsystems SECTOR_SIZE, stage2->pcfs_first_sectors[1] * SECTOR_SIZE) 948*af28f636SEnrico Perla - Sun Microsystems != BC_SUCCESS) { 949*af28f636SEnrico Perla - Sun Microsystems (void) fprintf(stderr, WRITE_FAIL_STAGE2); 950*af28f636SEnrico Perla - Sun Microsystems return (BC_ERROR); 951*af28f636SEnrico Perla - Sun Microsystems } 952*af28f636SEnrico Perla - Sun Microsystems (void) fprintf(stdout, WRITE_STAGE2_PCFS); 953*af28f636SEnrico Perla - Sun Microsystems return (BC_SUCCESS); 954*af28f636SEnrico Perla - Sun Microsystems } 955*af28f636SEnrico Perla - Sun Microsystems 956*af28f636SEnrico Perla - Sun Microsystems /* 957*af28f636SEnrico Perla - Sun Microsystems * For disk, write stage2 starting at STAGE2_BLKOFF sector. 958*af28f636SEnrico Perla - Sun Microsystems * Note that we use stage2->buf rather than stage2->file, because we 959*af28f636SEnrico Perla - Sun Microsystems * may have extended information after the latter. 960*af28f636SEnrico Perla - Sun Microsystems */ 961*af28f636SEnrico Perla - Sun Microsystems offset = STAGE2_BLKOFF * SECTOR_SIZE; 962*af28f636SEnrico Perla - Sun Microsystems if (write_out(device->part_fd, stage2->buf, stage2->buf_size, 963*af28f636SEnrico Perla - Sun Microsystems offset) != BC_SUCCESS) { 964*af28f636SEnrico Perla - Sun Microsystems perror("write"); 965*af28f636SEnrico Perla - Sun Microsystems return (BC_ERROR); 966*af28f636SEnrico Perla - Sun Microsystems } 967*af28f636SEnrico Perla - Sun Microsystems 968*af28f636SEnrico Perla - Sun Microsystems /* Simulate the "old" installgrub output. */ 969*af28f636SEnrico Perla - Sun Microsystems (void) fprintf(stdout, WRITE_STAGE2_DISK, device->partition, 970*af28f636SEnrico Perla - Sun Microsystems (stage2->buf_size / SECTOR_SIZE) + 1, STAGE2_BLKOFF, 971*af28f636SEnrico Perla - Sun Microsystems stage2->first_sector); 972*af28f636SEnrico Perla - Sun Microsystems 973*af28f636SEnrico Perla - Sun Microsystems return (BC_SUCCESS); 974*af28f636SEnrico Perla - Sun Microsystems } 975*af28f636SEnrico Perla - Sun Microsystems 976*af28f636SEnrico Perla - Sun Microsystems static int 977*af28f636SEnrico Perla - Sun Microsystems write_stage1(ig_data_t *install) 978*af28f636SEnrico Perla - Sun Microsystems { 979*af28f636SEnrico Perla - Sun Microsystems ig_device_t *device = &install->device; 980*af28f636SEnrico Perla - Sun Microsystems 981*af28f636SEnrico Perla - Sun Microsystems assert(install != NULL); 982*af28f636SEnrico Perla - Sun Microsystems 983*af28f636SEnrico Perla - Sun Microsystems if (write_out(device->part_fd, install->stage1_buf, 984*af28f636SEnrico Perla - Sun Microsystems sizeof (install->stage1_buf), 0) != BC_SUCCESS) { 985*af28f636SEnrico Perla - Sun Microsystems (void) fprintf(stdout, WRITE_FAIL_PBOOT); 986*af28f636SEnrico Perla - Sun Microsystems perror("write"); 987*af28f636SEnrico Perla - Sun Microsystems return (BC_ERROR); 988*af28f636SEnrico Perla - Sun Microsystems } 989*af28f636SEnrico Perla - Sun Microsystems 990*af28f636SEnrico Perla - Sun Microsystems /* Simulate "old" installgrub output. */ 991*af28f636SEnrico Perla - Sun Microsystems (void) fprintf(stdout, WRITE_PBOOT, device->partition, 992*af28f636SEnrico Perla - Sun Microsystems device->start_sector); 993*af28f636SEnrico Perla - Sun Microsystems 994*af28f636SEnrico Perla - Sun Microsystems if (write_mbr) { 995*af28f636SEnrico Perla - Sun Microsystems if (write_out(device->disk_fd, install->stage1_buf, 996*af28f636SEnrico Perla - Sun Microsystems sizeof (install->stage1_buf), 0) != BC_SUCCESS) { 997*af28f636SEnrico Perla - Sun Microsystems (void) fprintf(stdout, WRITE_FAIL_BOOTSEC); 998*af28f636SEnrico Perla - Sun Microsystems perror("write"); 999*af28f636SEnrico Perla - Sun Microsystems return (BC_ERROR); 1000*af28f636SEnrico Perla - Sun Microsystems } 1001*af28f636SEnrico Perla - Sun Microsystems /* Simulate "old" installgrub output. */ 1002*af28f636SEnrico Perla - Sun Microsystems (void) fprintf(stdout, WRITE_MBOOT); 1003*af28f636SEnrico Perla - Sun Microsystems } 1004*af28f636SEnrico Perla - Sun Microsystems 1005*af28f636SEnrico Perla - Sun Microsystems return (BC_SUCCESS); 1006*af28f636SEnrico Perla - Sun Microsystems } 1007*af28f636SEnrico Perla - Sun Microsystems 1008*af28f636SEnrico Perla - Sun Microsystems #define USAGE_STRING "%s [-m|-f|-n|-F|-u verstr] stage1 stage2 device\n" \ 1009*af28f636SEnrico Perla - Sun Microsystems "%s -M [-n] device1 device2\n" \ 1010*af28f636SEnrico Perla - Sun Microsystems "%s [-V|-e] -i device\n" \ 1011*af28f636SEnrico Perla - Sun Microsystems 1012*af28f636SEnrico Perla - Sun Microsystems #define CANON_USAGE_STR gettext(USAGE_STRING) 1013*af28f636SEnrico Perla - Sun Microsystems 10147c478bd9Sstevel@tonic-gate static void 10157c478bd9Sstevel@tonic-gate usage(char *progname) 10167c478bd9Sstevel@tonic-gate { 1017*af28f636SEnrico Perla - Sun Microsystems (void) fprintf(stdout, CANON_USAGE_STR, progname, progname, progname); 10187c478bd9Sstevel@tonic-gate } 10197c478bd9Sstevel@tonic-gate 1020*af28f636SEnrico Perla - Sun Microsystems 10217c478bd9Sstevel@tonic-gate static int 1022*af28f636SEnrico Perla - Sun Microsystems read_stage1_from_file(char *path, ig_data_t *dest) 10237c478bd9Sstevel@tonic-gate { 10247c478bd9Sstevel@tonic-gate int fd; 10257c478bd9Sstevel@tonic-gate 1026*af28f636SEnrico Perla - Sun Microsystems assert(dest); 1027*af28f636SEnrico Perla - Sun Microsystems 10287c478bd9Sstevel@tonic-gate /* read the stage1 file from filesystem */ 1029*af28f636SEnrico Perla - Sun Microsystems fd = open(path, O_RDONLY); 1030*af28f636SEnrico Perla - Sun Microsystems if (fd == -1 || 1031*af28f636SEnrico Perla - Sun Microsystems read(fd, dest->stage1_buf, SECTOR_SIZE) != SECTOR_SIZE) { 1032*af28f636SEnrico Perla - Sun Microsystems (void) fprintf(stderr, READ_FAIL_STAGE1, path); 1033*af28f636SEnrico Perla - Sun Microsystems return (BC_ERROR); 10347c478bd9Sstevel@tonic-gate } 10357c478bd9Sstevel@tonic-gate (void) close(fd); 1036*af28f636SEnrico Perla - Sun Microsystems return (BC_SUCCESS); 10377c478bd9Sstevel@tonic-gate } 10387c478bd9Sstevel@tonic-gate 1039*af28f636SEnrico Perla - Sun Microsystems static int 1040*af28f636SEnrico Perla - Sun Microsystems read_stage2_from_file(char *path, ig_data_t *dest) 10417c478bd9Sstevel@tonic-gate { 1042*af28f636SEnrico Perla - Sun Microsystems int fd; 1043*af28f636SEnrico Perla - Sun Microsystems struct stat sb; 1044*af28f636SEnrico Perla - Sun Microsystems ig_stage2_t *stage2 = &dest->stage2; 1045*af28f636SEnrico Perla - Sun Microsystems ig_device_t *device = &dest->device; 1046*af28f636SEnrico Perla - Sun Microsystems uint32_t buf_size; 1047*af28f636SEnrico Perla - Sun Microsystems 1048*af28f636SEnrico Perla - Sun Microsystems assert(dest); 1049*af28f636SEnrico Perla - Sun Microsystems assert(stage2->buf == NULL); 1050*af28f636SEnrico Perla - Sun Microsystems 1051*af28f636SEnrico Perla - Sun Microsystems fd = open(path, O_RDONLY); 1052*af28f636SEnrico Perla - Sun Microsystems if (fstat(fd, &sb) == -1) { 1053*af28f636SEnrico Perla - Sun Microsystems perror("fstat"); 1054*af28f636SEnrico Perla - Sun Microsystems goto out; 10557c478bd9Sstevel@tonic-gate } 10567c478bd9Sstevel@tonic-gate 1057*af28f636SEnrico Perla - Sun Microsystems stage2->file_size = sb.st_size; 10587c478bd9Sstevel@tonic-gate 1059*af28f636SEnrico Perla - Sun Microsystems if (!is_bootpar(device->type)) { 1060*af28f636SEnrico Perla - Sun Microsystems /* 1061*af28f636SEnrico Perla - Sun Microsystems * buffer size needs to account for stage2 plus the extra 1062*af28f636SEnrico Perla - Sun Microsystems * versioning information at the end of it. We reserve one 1063*af28f636SEnrico Perla - Sun Microsystems * extra sector (plus we round up to the next sector boundary). 1064*af28f636SEnrico Perla - Sun Microsystems */ 1065*af28f636SEnrico Perla - Sun Microsystems buf_size = stage2->file_size + SECTOR_SIZE; 10667c478bd9Sstevel@tonic-gate } else { 1067*af28f636SEnrico Perla - Sun Microsystems /* In the PCFS case we only need to read in stage2. */ 1068*af28f636SEnrico Perla - Sun Microsystems buf_size = stage2->file_size; 10697c478bd9Sstevel@tonic-gate } 10707c478bd9Sstevel@tonic-gate 1071*af28f636SEnrico Perla - Sun Microsystems stage2->buf_size = P2ROUNDUP(buf_size, SECTOR_SIZE); 1072*af28f636SEnrico Perla - Sun Microsystems 1073*af28f636SEnrico Perla - Sun Microsystems BOOT_DEBUG("stage2 buffer size = %d (%d sectors)\n", stage2->buf_size, 1074*af28f636SEnrico Perla - Sun Microsystems stage2->buf_size / SECTOR_SIZE); 1075*af28f636SEnrico Perla - Sun Microsystems 1076*af28f636SEnrico Perla - Sun Microsystems stage2->buf = malloc(stage2->buf_size); 1077*af28f636SEnrico Perla - Sun Microsystems if (stage2->buf == NULL) { 1078*af28f636SEnrico Perla - Sun Microsystems perror(gettext("Memory allocation failed")); 1079*af28f636SEnrico Perla - Sun Microsystems goto out_fd; 1080*af28f636SEnrico Perla - Sun Microsystems } 1081*af28f636SEnrico Perla - Sun Microsystems 1082*af28f636SEnrico Perla - Sun Microsystems stage2->file = stage2->buf; 10837c478bd9Sstevel@tonic-gate 10847c478bd9Sstevel@tonic-gate /* 1085*af28f636SEnrico Perla - Sun Microsystems * Extra information (e.g. the versioning structure) is placed at the 1086*af28f636SEnrico Perla - Sun Microsystems * end of stage2, aligned on a 8-byte boundary. 10877c478bd9Sstevel@tonic-gate */ 1088*af28f636SEnrico Perla - Sun Microsystems if (!(is_bootpar(device->type))) 1089*af28f636SEnrico Perla - Sun Microsystems stage2->extra = stage2->file + P2ROUNDUP(stage2->file_size, 8); 10907c478bd9Sstevel@tonic-gate 1091*af28f636SEnrico Perla - Sun Microsystems if (lseek(fd, 0, SEEK_SET) == -1) { 1092*af28f636SEnrico Perla - Sun Microsystems perror("lseek"); 1093*af28f636SEnrico Perla - Sun Microsystems goto out_alloc; 10947c478bd9Sstevel@tonic-gate } 10957c478bd9Sstevel@tonic-gate 1096*af28f636SEnrico Perla - Sun Microsystems if (read(fd, stage2->file, stage2->file_size) < 0) { 1097*af28f636SEnrico Perla - Sun Microsystems perror(gettext("unable to read stage2")); 1098*af28f636SEnrico Perla - Sun Microsystems goto out_alloc; 10997c478bd9Sstevel@tonic-gate } 11007c478bd9Sstevel@tonic-gate 1101*af28f636SEnrico Perla - Sun Microsystems (void) close(fd); 1102*af28f636SEnrico Perla - Sun Microsystems return (BC_SUCCESS); 11037ce76caaSEnrico Perla - Sun Microsystems 1104*af28f636SEnrico Perla - Sun Microsystems out_alloc: 1105*af28f636SEnrico Perla - Sun Microsystems free(stage2->buf); 1106*af28f636SEnrico Perla - Sun Microsystems stage2->buf = NULL; 1107*af28f636SEnrico Perla - Sun Microsystems out_fd: 1108*af28f636SEnrico Perla - Sun Microsystems (void) close(fd); 1109*af28f636SEnrico Perla - Sun Microsystems out: 1110*af28f636SEnrico Perla - Sun Microsystems return (BC_ERROR); 11117ce76caaSEnrico Perla - Sun Microsystems } 11127ce76caaSEnrico Perla - Sun Microsystems 11137ce76caaSEnrico Perla - Sun Microsystems static int 1114*af28f636SEnrico Perla - Sun Microsystems prepare_stage1(ig_data_t *install) 11157ce76caaSEnrico Perla - Sun Microsystems { 1116*af28f636SEnrico Perla - Sun Microsystems ig_device_t *device = &install->device; 11177ce76caaSEnrico Perla - Sun Microsystems 1118*af28f636SEnrico Perla - Sun Microsystems assert(install != NULL); 11197ce76caaSEnrico Perla - Sun Microsystems 1120*af28f636SEnrico Perla - Sun Microsystems /* If PCFS add the BIOS Parameter Block. */ 1121*af28f636SEnrico Perla - Sun Microsystems if (is_bootpar(device->type)) { 1122*af28f636SEnrico Perla - Sun Microsystems char bpb_sect[SECTOR_SIZE]; 1123*af28f636SEnrico Perla - Sun Microsystems 1124*af28f636SEnrico Perla - Sun Microsystems if (pread(device->part_fd, bpb_sect, SECTOR_SIZE, 0) 1125*af28f636SEnrico Perla - Sun Microsystems != SECTOR_SIZE) { 1126*af28f636SEnrico Perla - Sun Microsystems (void) fprintf(stderr, READ_FAIL_BPB); 1127*af28f636SEnrico Perla - Sun Microsystems return (BC_ERROR); 1128*af28f636SEnrico Perla - Sun Microsystems } 1129*af28f636SEnrico Perla - Sun Microsystems bcopy(bpb_sect + STAGE1_BPB_OFFSET, 1130*af28f636SEnrico Perla - Sun Microsystems install->stage1_buf + STAGE1_BPB_OFFSET, STAGE1_BPB_SIZE); 11317ce76caaSEnrico Perla - Sun Microsystems } 11327ce76caaSEnrico Perla - Sun Microsystems 1133*af28f636SEnrico Perla - Sun Microsystems /* copy MBR to stage1 in case of overwriting MBR sector. */ 1134*af28f636SEnrico Perla - Sun Microsystems bcopy(device->boot_sector + BOOTSZ, install->stage1_buf + BOOTSZ, 1135*af28f636SEnrico Perla - Sun Microsystems SECTOR_SIZE - BOOTSZ); 1136*af28f636SEnrico Perla - Sun Microsystems /* modify default stage1 file generated by GRUB. */ 1137*af28f636SEnrico Perla - Sun Microsystems *((unsigned char *)(install->stage1_buf + STAGE1_FORCE_LBA)) = 1; 1138*af28f636SEnrico Perla - Sun Microsystems *((ulong_t *)(install->stage1_buf + STAGE1_STAGE2_SECTOR)) 1139*af28f636SEnrico Perla - Sun Microsystems = install->stage2.first_sector; 1140*af28f636SEnrico Perla - Sun Microsystems *((ushort_t *)(install->stage1_buf + STAGE1_STAGE2_ADDRESS)) 1141*af28f636SEnrico Perla - Sun Microsystems = STAGE2_MEMADDR; 1142*af28f636SEnrico Perla - Sun Microsystems *((ushort_t *)(install->stage1_buf + STAGE1_STAGE2_SEGMENT)) 1143*af28f636SEnrico Perla - Sun Microsystems = STAGE2_MEMADDR >> 4; 11447ce76caaSEnrico Perla - Sun Microsystems 1145*af28f636SEnrico Perla - Sun Microsystems return (BC_SUCCESS); 11467ce76caaSEnrico Perla - Sun Microsystems } 11477ce76caaSEnrico Perla - Sun Microsystems 1148*af28f636SEnrico Perla - Sun Microsystems /* 1149*af28f636SEnrico Perla - Sun Microsystems * Grab stage1 from the specified device file descriptor. 1150*af28f636SEnrico Perla - Sun Microsystems */ 1151*af28f636SEnrico Perla - Sun Microsystems static int 1152*af28f636SEnrico Perla - Sun Microsystems read_stage1_from_disk(int dev_fd, char *stage1_buf) 1153*af28f636SEnrico Perla - Sun Microsystems { 1154*af28f636SEnrico Perla - Sun Microsystems assert(stage1_buf != NULL); 11557ce76caaSEnrico Perla - Sun Microsystems 1156*af28f636SEnrico Perla - Sun Microsystems if (read_in(dev_fd, stage1_buf, SECTOR_SIZE, 0) != BC_SUCCESS) { 1157*af28f636SEnrico Perla - Sun Microsystems perror(gettext("Unable to read stage1 from disk")); 1158*af28f636SEnrico Perla - Sun Microsystems return (BC_ERROR); 11597ce76caaSEnrico Perla - Sun Microsystems } 1160*af28f636SEnrico Perla - Sun Microsystems return (BC_SUCCESS); 11617ce76caaSEnrico Perla - Sun Microsystems } 11627ce76caaSEnrico Perla - Sun Microsystems 11637ce76caaSEnrico Perla - Sun Microsystems static int 1164*af28f636SEnrico Perla - Sun Microsystems read_stage2_from_disk(int dev_fd, ig_stage2_t *stage2) 11657ce76caaSEnrico Perla - Sun Microsystems { 1166*af28f636SEnrico Perla - Sun Microsystems uint32_t size; 1167*af28f636SEnrico Perla - Sun Microsystems uint32_t buf_size; 1168*af28f636SEnrico Perla - Sun Microsystems uint32_t mboot_off; 1169*af28f636SEnrico Perla - Sun Microsystems multiboot_header_t *mboot; 11707ce76caaSEnrico Perla - Sun Microsystems 1171*af28f636SEnrico Perla - Sun Microsystems assert(stage2 != NULL); 1172*af28f636SEnrico Perla - Sun Microsystems assert(dev_fd != -1); 11737ce76caaSEnrico Perla - Sun Microsystems 1174*af28f636SEnrico Perla - Sun Microsystems if (read_in(dev_fd, mboot_scan, sizeof (mboot_scan), 1175*af28f636SEnrico Perla - Sun Microsystems STAGE2_BLKOFF * SECTOR_SIZE) != BC_SUCCESS) { 1176*af28f636SEnrico Perla - Sun Microsystems perror(gettext("Error reading stage2 sectors")); 1177*af28f636SEnrico Perla - Sun Microsystems return (BC_ERROR); 1178*af28f636SEnrico Perla - Sun Microsystems } 11797ce76caaSEnrico Perla - Sun Microsystems 1180*af28f636SEnrico Perla - Sun Microsystems /* No multiboot means no chance of knowing stage2 size */ 1181*af28f636SEnrico Perla - Sun Microsystems if (find_multiboot(mboot_scan, sizeof (mboot_scan), &mboot_off) 1182*af28f636SEnrico Perla - Sun Microsystems != BC_SUCCESS) { 1183*af28f636SEnrico Perla - Sun Microsystems BOOT_DEBUG("Unable to find multiboot header\n"); 1184*af28f636SEnrico Perla - Sun Microsystems return (BC_NOEXTRA); 1185*af28f636SEnrico Perla - Sun Microsystems } 1186*af28f636SEnrico Perla - Sun Microsystems mboot = (multiboot_header_t *)(mboot_scan + mboot_off); 11877ce76caaSEnrico Perla - Sun Microsystems 1188*af28f636SEnrico Perla - Sun Microsystems /* 1189*af28f636SEnrico Perla - Sun Microsystems * Unfilled mboot values mean an older version of installgrub installed 1190*af28f636SEnrico Perla - Sun Microsystems * the stage2. Again we have no chance of knowing stage2 size. 1191*af28f636SEnrico Perla - Sun Microsystems */ 1192*af28f636SEnrico Perla - Sun Microsystems if (mboot->load_end_addr == 0 || 1193*af28f636SEnrico Perla - Sun Microsystems mboot->load_end_addr < mboot->load_addr) 1194*af28f636SEnrico Perla - Sun Microsystems return (BC_NOEXTRA); 1195*af28f636SEnrico Perla - Sun Microsystems 1196*af28f636SEnrico Perla - Sun Microsystems /* 1197*af28f636SEnrico Perla - Sun Microsystems * Currently, the amount of space reserved for extra information 1198*af28f636SEnrico Perla - Sun Microsystems * is "fixed". We may have to scan for the terminating extra payload 1199*af28f636SEnrico Perla - Sun Microsystems * in the future. 1200*af28f636SEnrico Perla - Sun Microsystems */ 1201*af28f636SEnrico Perla - Sun Microsystems size = mboot->load_end_addr - mboot->load_addr; 1202*af28f636SEnrico Perla - Sun Microsystems buf_size = P2ROUNDUP(size + SECTOR_SIZE, SECTOR_SIZE); 1203*af28f636SEnrico Perla - Sun Microsystems 1204*af28f636SEnrico Perla - Sun Microsystems stage2->buf = malloc(buf_size); 1205*af28f636SEnrico Perla - Sun Microsystems if (stage2->buf == NULL) { 1206*af28f636SEnrico Perla - Sun Microsystems perror(gettext("Memory allocation failed")); 1207*af28f636SEnrico Perla - Sun Microsystems return (BC_ERROR); 1208*af28f636SEnrico Perla - Sun Microsystems } 1209*af28f636SEnrico Perla - Sun Microsystems stage2->buf_size = buf_size; 1210*af28f636SEnrico Perla - Sun Microsystems 1211*af28f636SEnrico Perla - Sun Microsystems if (read_in(dev_fd, stage2->buf, buf_size, STAGE2_BLKOFF * 1212*af28f636SEnrico Perla - Sun Microsystems SECTOR_SIZE) != BC_SUCCESS) { 1213*af28f636SEnrico Perla - Sun Microsystems perror("read"); 1214*af28f636SEnrico Perla - Sun Microsystems free(stage2->buf); 1215*af28f636SEnrico Perla - Sun Microsystems return (BC_ERROR); 1216*af28f636SEnrico Perla - Sun Microsystems } 1217*af28f636SEnrico Perla - Sun Microsystems 1218*af28f636SEnrico Perla - Sun Microsystems /* Update pointers. */ 1219*af28f636SEnrico Perla - Sun Microsystems stage2->file = stage2->buf; 1220*af28f636SEnrico Perla - Sun Microsystems stage2->file_size = size; 1221*af28f636SEnrico Perla - Sun Microsystems stage2->mboot_off = mboot_off; 1222*af28f636SEnrico Perla - Sun Microsystems stage2->mboot = (multiboot_header_t *)(stage2->buf + stage2->mboot_off); 1223*af28f636SEnrico Perla - Sun Microsystems stage2->extra = stage2->buf + P2ROUNDUP(stage2->file_size, 8); 1224*af28f636SEnrico Perla - Sun Microsystems 1225*af28f636SEnrico Perla - Sun Microsystems return (BC_SUCCESS); 1226*af28f636SEnrico Perla - Sun Microsystems } 1227*af28f636SEnrico Perla - Sun Microsystems 1228*af28f636SEnrico Perla - Sun Microsystems static boolean_t 1229*af28f636SEnrico Perla - Sun Microsystems is_update_necessary(ig_data_t *data, char *updt_str) 1230*af28f636SEnrico Perla - Sun Microsystems { 1231*af28f636SEnrico Perla - Sun Microsystems bblk_einfo_t *einfo; 1232*af28f636SEnrico Perla - Sun Microsystems bblk_hs_t stage2_hs; 1233*af28f636SEnrico Perla - Sun Microsystems ig_stage2_t stage2_disk; 1234*af28f636SEnrico Perla - Sun Microsystems ig_stage2_t *stage2_file = &data->stage2; 1235*af28f636SEnrico Perla - Sun Microsystems ig_device_t *device = &data->device; 1236*af28f636SEnrico Perla - Sun Microsystems int dev_fd = device->part_fd; 1237*af28f636SEnrico Perla - Sun Microsystems 1238*af28f636SEnrico Perla - Sun Microsystems assert(data != NULL); 1239*af28f636SEnrico Perla - Sun Microsystems assert(device->part_fd != -1); 1240*af28f636SEnrico Perla - Sun Microsystems 1241*af28f636SEnrico Perla - Sun Microsystems bzero(&stage2_disk, sizeof (ig_stage2_t)); 1242*af28f636SEnrico Perla - Sun Microsystems 1243*af28f636SEnrico Perla - Sun Microsystems /* Gather stage2 (if present) from the target device. */ 1244*af28f636SEnrico Perla - Sun Microsystems if (read_stage2_from_disk(dev_fd, &stage2_disk) != BC_SUCCESS) { 1245*af28f636SEnrico Perla - Sun Microsystems BOOT_DEBUG("Unable to read stage2 from %s\n", device->path); 1246*af28f636SEnrico Perla - Sun Microsystems BOOT_DEBUG("No multiboot wrapped stage2 on %s\n", device->path); 1247*af28f636SEnrico Perla - Sun Microsystems return (B_TRUE); 1248*af28f636SEnrico Perla - Sun Microsystems } 1249*af28f636SEnrico Perla - Sun Microsystems 1250*af28f636SEnrico Perla - Sun Microsystems /* 1251*af28f636SEnrico Perla - Sun Microsystems * Look for the extended information structure in the extra payload 1252*af28f636SEnrico Perla - Sun Microsystems * area. 1253*af28f636SEnrico Perla - Sun Microsystems */ 1254*af28f636SEnrico Perla - Sun Microsystems einfo = find_einfo(stage2_disk.extra); 1255*af28f636SEnrico Perla - Sun Microsystems if (einfo == NULL) { 1256*af28f636SEnrico Perla - Sun Microsystems BOOT_DEBUG("No extended information available\n"); 1257*af28f636SEnrico Perla - Sun Microsystems return (B_TRUE); 1258*af28f636SEnrico Perla - Sun Microsystems } 1259*af28f636SEnrico Perla - Sun Microsystems 1260*af28f636SEnrico Perla - Sun Microsystems if (!do_version || updt_str == NULL) { 1261*af28f636SEnrico Perla - Sun Microsystems (void) fprintf(stdout, "WARNING: target device %s has a " 1262*af28f636SEnrico Perla - Sun Microsystems "versioned stage2 that is going to be overwritten by a non " 1263*af28f636SEnrico Perla - Sun Microsystems "versioned one\n", device->path); 1264*af28f636SEnrico Perla - Sun Microsystems return (B_TRUE); 1265*af28f636SEnrico Perla - Sun Microsystems } 1266*af28f636SEnrico Perla - Sun Microsystems 1267*af28f636SEnrico Perla - Sun Microsystems if (force_update) { 1268*af28f636SEnrico Perla - Sun Microsystems BOOT_DEBUG("Forcing update of %s bootblock\n", device->path); 1269*af28f636SEnrico Perla - Sun Microsystems return (B_TRUE); 1270*af28f636SEnrico Perla - Sun Microsystems } 1271*af28f636SEnrico Perla - Sun Microsystems 1272*af28f636SEnrico Perla - Sun Microsystems /* Compare the two extended information structures. */ 1273*af28f636SEnrico Perla - Sun Microsystems stage2_hs.src_buf = (unsigned char *)stage2_file->file; 1274*af28f636SEnrico Perla - Sun Microsystems stage2_hs.src_size = stage2_file->file_size; 1275*af28f636SEnrico Perla - Sun Microsystems 1276*af28f636SEnrico Perla - Sun Microsystems return (einfo_should_update(einfo, &stage2_hs, updt_str)); 12777ce76caaSEnrico Perla - Sun Microsystems } 12787ce76caaSEnrico Perla - Sun Microsystems 12797ce76caaSEnrico Perla - Sun Microsystems 12807c478bd9Sstevel@tonic-gate #define START_BLOCK(pos) (*(ulong_t *)(pos)) 12817c478bd9Sstevel@tonic-gate #define NUM_BLOCK(pos) (*(ushort_t *)((pos) + 4)) 12827c478bd9Sstevel@tonic-gate #define START_SEG(pos) (*(ushort_t *)((pos) + 6)) 12837c478bd9Sstevel@tonic-gate 1284*af28f636SEnrico Perla - Sun Microsystems static int 1285*af28f636SEnrico Perla - Sun Microsystems prepare_stage2(ig_data_t *install, char *updt_str) 12867c478bd9Sstevel@tonic-gate { 1287*af28f636SEnrico Perla - Sun Microsystems ig_device_t *device = &install->device; 1288*af28f636SEnrico Perla - Sun Microsystems ig_stage2_t *stage2 = &install->stage2; 1289*af28f636SEnrico Perla - Sun Microsystems uint32_t mboot_off = 0; 12907ce76caaSEnrico Perla - Sun Microsystems 1291*af28f636SEnrico Perla - Sun Microsystems assert(install != NULL); 1292*af28f636SEnrico Perla - Sun Microsystems assert(stage2->file != NULL); 1293*af28f636SEnrico Perla - Sun Microsystems 1294*af28f636SEnrico Perla - Sun Microsystems /* New stage2 files come with an embedded stage2. */ 1295*af28f636SEnrico Perla - Sun Microsystems if (find_multiboot(stage2->file, stage2->file_size, &mboot_off) 1296*af28f636SEnrico Perla - Sun Microsystems != BC_SUCCESS) { 1297*af28f636SEnrico Perla - Sun Microsystems BOOT_DEBUG("WARNING: no multiboot structure found in stage2, " 1298*af28f636SEnrico Perla - Sun Microsystems "are you using an old GRUB stage2?\n"); 1299*af28f636SEnrico Perla - Sun Microsystems if (do_version == B_TRUE) { 1300*af28f636SEnrico Perla - Sun Microsystems (void) fprintf(stderr, gettext("Versioning requested " 1301*af28f636SEnrico Perla - Sun Microsystems "but stage2 does not support it.. skipping.\n")); 1302*af28f636SEnrico Perla - Sun Microsystems do_version = B_FALSE; 1303*af28f636SEnrico Perla - Sun Microsystems } 1304*af28f636SEnrico Perla - Sun Microsystems } else { 1305*af28f636SEnrico Perla - Sun Microsystems /* Keep track of where the multiboot header is. */ 1306*af28f636SEnrico Perla - Sun Microsystems stage2->mboot_off = mboot_off; 1307*af28f636SEnrico Perla - Sun Microsystems stage2->mboot = (multiboot_header_t *)(stage2->file + 1308*af28f636SEnrico Perla - Sun Microsystems mboot_off); 13097ce76caaSEnrico Perla - Sun Microsystems if (do_version) { 1310*af28f636SEnrico Perla - Sun Microsystems /* 1311*af28f636SEnrico Perla - Sun Microsystems * Adding stage2 information needs to happen before 1312*af28f636SEnrico Perla - Sun Microsystems * we modify the copy of stage2 we have in memory, so 1313*af28f636SEnrico Perla - Sun Microsystems * that the hashing reflects the one of the file. 1314*af28f636SEnrico Perla - Sun Microsystems * An error here is not fatal. 1315*af28f636SEnrico Perla - Sun Microsystems */ 1316*af28f636SEnrico Perla - Sun Microsystems add_stage2_einfo(stage2, updt_str); 1317*af28f636SEnrico Perla - Sun Microsystems } 1318*af28f636SEnrico Perla - Sun Microsystems /* 1319*af28f636SEnrico Perla - Sun Microsystems * Fill multiboot information. We add them even without 1320*af28f636SEnrico Perla - Sun Microsystems * versioning to support as much as possible mirroring. 1321*af28f636SEnrico Perla - Sun Microsystems */ 1322*af28f636SEnrico Perla - Sun Microsystems prepare_fake_multiboot(stage2); 13237ce76caaSEnrico Perla - Sun Microsystems } 13247c478bd9Sstevel@tonic-gate 1325*af28f636SEnrico Perla - Sun Microsystems if (is_bootpar(device->type)) { 1326*af28f636SEnrico Perla - Sun Microsystems uint32_t blocklist[SECTOR_SIZE / sizeof (uint32_t)]; 1327*af28f636SEnrico Perla - Sun Microsystems uint32_t install_addr = STAGE2_MEMADDR + SECTOR_SIZE; 13287c478bd9Sstevel@tonic-gate int i = 0; 1329*af28f636SEnrico Perla - Sun Microsystems uchar_t *pos; 13307c478bd9Sstevel@tonic-gate 1331*af28f636SEnrico Perla - Sun Microsystems bzero(blocklist, sizeof (blocklist)); 1332*af28f636SEnrico Perla - Sun Microsystems if (read_stage2_blocklist(device->part_fd, blocklist) != 0) { 1333*af28f636SEnrico Perla - Sun Microsystems (void) fprintf(stderr, gettext("Error reading pcfs " 1334*af28f636SEnrico Perla - Sun Microsystems "stage2 blocklist\n")); 1335*af28f636SEnrico Perla - Sun Microsystems return (BC_ERROR); 1336*af28f636SEnrico Perla - Sun Microsystems } 13377c478bd9Sstevel@tonic-gate 1338*af28f636SEnrico Perla - Sun Microsystems pos = (uchar_t *)stage2->file + STAGE2_BLOCKLIST; 1339*af28f636SEnrico Perla - Sun Microsystems stage2->first_sector = device->start_sector + blocklist[0]; 1340*af28f636SEnrico Perla - Sun Microsystems stage2->pcfs_first_sectors[0] = blocklist[0]; 1341*af28f636SEnrico Perla - Sun Microsystems BOOT_DEBUG("stage2 first sector: %d\n", stage2->first_sector); 1342*af28f636SEnrico Perla - Sun Microsystems 1343*af28f636SEnrico Perla - Sun Microsystems 13447c478bd9Sstevel@tonic-gate if (blocklist[1] > 1) { 13457c478bd9Sstevel@tonic-gate blocklist[0]++; 13467c478bd9Sstevel@tonic-gate blocklist[1]--; 13477c478bd9Sstevel@tonic-gate } else { 13487c478bd9Sstevel@tonic-gate i += 2; 13497c478bd9Sstevel@tonic-gate } 13507c478bd9Sstevel@tonic-gate 1351*af28f636SEnrico Perla - Sun Microsystems stage2->pcfs_first_sectors[1] = blocklist[i]; 13527c478bd9Sstevel@tonic-gate 13537c478bd9Sstevel@tonic-gate while (blocklist[i]) { 13547c478bd9Sstevel@tonic-gate if (START_BLOCK(pos - 8) != 0 && 13557c478bd9Sstevel@tonic-gate START_BLOCK(pos - 8) != blocklist[i + 2]) { 13567c478bd9Sstevel@tonic-gate (void) fprintf(stderr, PCFS_FRAGMENTED); 1357*af28f636SEnrico Perla - Sun Microsystems return (BC_ERROR); 13587c478bd9Sstevel@tonic-gate } 1359*af28f636SEnrico Perla - Sun Microsystems START_BLOCK(pos) = blocklist[i] + device->start_sector; 13607c478bd9Sstevel@tonic-gate START_SEG(pos) = (ushort_t)(install_addr >> 4); 13617c478bd9Sstevel@tonic-gate NUM_BLOCK(pos) = blocklist[i + 1]; 13627c478bd9Sstevel@tonic-gate install_addr += blocklist[i + 1] * SECTOR_SIZE; 13637c478bd9Sstevel@tonic-gate pos -= 8; 13647c478bd9Sstevel@tonic-gate i += 2; 13657c478bd9Sstevel@tonic-gate } 13667c478bd9Sstevel@tonic-gate } else { 1367*af28f636SEnrico Perla - Sun Microsystems /* Solaris VTOC */ 1368*af28f636SEnrico Perla - Sun Microsystems stage2->first_sector = device->start_sector + STAGE2_BLKOFF; 1369*af28f636SEnrico Perla - Sun Microsystems BOOT_DEBUG("stage2 first sector: %d\n", stage2->first_sector); 13707c478bd9Sstevel@tonic-gate /* 13717c478bd9Sstevel@tonic-gate * In a solaris partition, stage2 is written to contiguous 13727c478bd9Sstevel@tonic-gate * blocks. So we update the starting block only. 13737c478bd9Sstevel@tonic-gate */ 1374*af28f636SEnrico Perla - Sun Microsystems *((ulong_t *)(stage2->file + STAGE2_BLOCKLIST)) = 1375*af28f636SEnrico Perla - Sun Microsystems stage2->first_sector + 1; 13767c478bd9Sstevel@tonic-gate } 13777c478bd9Sstevel@tonic-gate 13787c478bd9Sstevel@tonic-gate /* force lba and set disk partition */ 1379*af28f636SEnrico Perla - Sun Microsystems *((unsigned char *) (stage2->file + STAGE2_FORCE_LBA)) = 1; 1380*af28f636SEnrico Perla - Sun Microsystems *((long *)(stage2->file + STAGE2_INSTALLPART)) 1381*af28f636SEnrico Perla - Sun Microsystems = (device->partition << 16) | (device->slice << 8) | 0xff; 1382*af28f636SEnrico Perla - Sun Microsystems 1383*af28f636SEnrico Perla - Sun Microsystems return (BC_SUCCESS); 13847c478bd9Sstevel@tonic-gate } 13857c478bd9Sstevel@tonic-gate 1386*af28f636SEnrico Perla - Sun Microsystems static int 1387*af28f636SEnrico Perla - Sun Microsystems find_x86_bootpar(struct mboot *mboot, int *part_num, uint32_t *start_sect) 1388*af28f636SEnrico Perla - Sun Microsystems { 1389*af28f636SEnrico Perla - Sun Microsystems int i; 13907c478bd9Sstevel@tonic-gate 1391*af28f636SEnrico Perla - Sun Microsystems for (i = 0; i < FD_NUMPART; i++) { 1392*af28f636SEnrico Perla - Sun Microsystems struct ipart *part; 13937c478bd9Sstevel@tonic-gate 1394*af28f636SEnrico Perla - Sun Microsystems part = (struct ipart *)mboot->parts + i; 1395*af28f636SEnrico Perla - Sun Microsystems if (part->systid == 0xbe) { 1396*af28f636SEnrico Perla - Sun Microsystems if (start_sect) 1397*af28f636SEnrico Perla - Sun Microsystems *start_sect = part->relsect; 1398*af28f636SEnrico Perla - Sun Microsystems if (part_num) 1399*af28f636SEnrico Perla - Sun Microsystems *part_num = i; 1400*af28f636SEnrico Perla - Sun Microsystems /* solaris boot part */ 1401*af28f636SEnrico Perla - Sun Microsystems return (BC_SUCCESS); 14027c478bd9Sstevel@tonic-gate } 14037c478bd9Sstevel@tonic-gate } 1404*af28f636SEnrico Perla - Sun Microsystems return (BC_ERROR); 14057c478bd9Sstevel@tonic-gate } 14067c478bd9Sstevel@tonic-gate 14077c478bd9Sstevel@tonic-gate static char * 1408*af28f636SEnrico Perla - Sun Microsystems get_raw_partition_path(ig_device_t *device) 14097c478bd9Sstevel@tonic-gate { 1410*af28f636SEnrico Perla - Sun Microsystems char *raw; 14117c478bd9Sstevel@tonic-gate int len; 1412*af28f636SEnrico Perla - Sun Microsystems 1413*af28f636SEnrico Perla - Sun Microsystems if (is_bootpar(device->type)) { 1414*af28f636SEnrico Perla - Sun Microsystems int part; 14157c478bd9Sstevel@tonic-gate struct mboot *mboot; 14167c478bd9Sstevel@tonic-gate 1417*af28f636SEnrico Perla - Sun Microsystems mboot = (struct mboot *)device->boot_sector; 1418*af28f636SEnrico Perla - Sun Microsystems if (find_x86_bootpar(mboot, &part, NULL) != BC_SUCCESS) { 1419*af28f636SEnrico Perla - Sun Microsystems (void) fprintf(stderr, BOOTPAR_NOTFOUND, 1420*af28f636SEnrico Perla - Sun Microsystems device->path_p0); 1421*af28f636SEnrico Perla - Sun Microsystems return (NULL); 14227c478bd9Sstevel@tonic-gate } 14237c478bd9Sstevel@tonic-gate 1424*af28f636SEnrico Perla - Sun Microsystems raw = strdup(device->path_p0); 1425*af28f636SEnrico Perla - Sun Microsystems if (raw == NULL) { 1426*af28f636SEnrico Perla - Sun Microsystems perror(gettext("Memory allocation failed")); 1427*af28f636SEnrico Perla - Sun Microsystems return (NULL); 14287c478bd9Sstevel@tonic-gate } 1429*af28f636SEnrico Perla - Sun Microsystems 1430*af28f636SEnrico Perla - Sun Microsystems raw[strlen(raw) - 2] = '1' + part; 14317c478bd9Sstevel@tonic-gate return (raw); 14327c478bd9Sstevel@tonic-gate } 14337c478bd9Sstevel@tonic-gate 14347c478bd9Sstevel@tonic-gate /* For disk, remember slice and return whole fdisk partition */ 1435*af28f636SEnrico Perla - Sun Microsystems raw = strdup(device->path); 1436*af28f636SEnrico Perla - Sun Microsystems if (raw == NULL) { 1437*af28f636SEnrico Perla - Sun Microsystems perror(gettext("Memory allocation failed")); 1438*af28f636SEnrico Perla - Sun Microsystems return (NULL); 1439*af28f636SEnrico Perla - Sun Microsystems } 1440*af28f636SEnrico Perla - Sun Microsystems 14417c478bd9Sstevel@tonic-gate len = strlen(raw); 14427c478bd9Sstevel@tonic-gate if (raw[len - 2] != 's' || raw[len - 1] == '2') { 14437c478bd9Sstevel@tonic-gate (void) fprintf(stderr, NOT_ROOT_SLICE); 1444*af28f636SEnrico Perla - Sun Microsystems free(raw); 1445*af28f636SEnrico Perla - Sun Microsystems return (NULL); 14467c478bd9Sstevel@tonic-gate } 1447*af28f636SEnrico Perla - Sun Microsystems device->slice = atoi(&raw[len - 1]); 14487c478bd9Sstevel@tonic-gate 14497c478bd9Sstevel@tonic-gate raw[len - 2] = 's'; 14507c478bd9Sstevel@tonic-gate raw[len - 1] = '2'; 1451*af28f636SEnrico Perla - Sun Microsystems 14527c478bd9Sstevel@tonic-gate return (raw); 14537c478bd9Sstevel@tonic-gate } 14547c478bd9Sstevel@tonic-gate 1455*af28f636SEnrico Perla - Sun Microsystems static int 1456*af28f636SEnrico Perla - Sun Microsystems get_raw_partition_fd(ig_device_t *device) 1457*af28f636SEnrico Perla - Sun Microsystems { 1458*af28f636SEnrico Perla - Sun Microsystems struct stat stat = {0}; 1459*af28f636SEnrico Perla - Sun Microsystems char *raw; 1460*af28f636SEnrico Perla - Sun Microsystems 1461*af28f636SEnrico Perla - Sun Microsystems raw = get_raw_partition_path(device); 1462*af28f636SEnrico Perla - Sun Microsystems if (raw == NULL) 1463*af28f636SEnrico Perla - Sun Microsystems return (BC_ERROR); 1464*af28f636SEnrico Perla - Sun Microsystems 1465*af28f636SEnrico Perla - Sun Microsystems if (nowrite) 1466*af28f636SEnrico Perla - Sun Microsystems device->part_fd = open(raw, O_RDONLY); 1467*af28f636SEnrico Perla - Sun Microsystems else 1468*af28f636SEnrico Perla - Sun Microsystems device->part_fd = open(raw, O_RDWR); 1469*af28f636SEnrico Perla - Sun Microsystems 1470*af28f636SEnrico Perla - Sun Microsystems if (device->part_fd < 0 || fstat(device->part_fd, &stat) != 0) { 1471*af28f636SEnrico Perla - Sun Microsystems (void) fprintf(stderr, OPEN_FAIL, raw); 1472*af28f636SEnrico Perla - Sun Microsystems free(raw); 1473*af28f636SEnrico Perla - Sun Microsystems return (BC_ERROR); 1474*af28f636SEnrico Perla - Sun Microsystems } 1475*af28f636SEnrico Perla - Sun Microsystems 1476*af28f636SEnrico Perla - Sun Microsystems if (S_ISCHR(stat.st_mode) == 0) { 1477*af28f636SEnrico Perla - Sun Microsystems (void) fprintf(stderr, NOT_RAW_DEVICE, raw); 1478*af28f636SEnrico Perla - Sun Microsystems (void) close(device->part_fd); 1479*af28f636SEnrico Perla - Sun Microsystems device->part_fd = -1; 1480*af28f636SEnrico Perla - Sun Microsystems free(raw); 1481*af28f636SEnrico Perla - Sun Microsystems return (BC_ERROR); 1482*af28f636SEnrico Perla - Sun Microsystems } 1483*af28f636SEnrico Perla - Sun Microsystems 1484*af28f636SEnrico Perla - Sun Microsystems free(raw); 1485*af28f636SEnrico Perla - Sun Microsystems return (BC_SUCCESS); 1486*af28f636SEnrico Perla - Sun Microsystems } 1487*af28f636SEnrico Perla - Sun Microsystems 14887c478bd9Sstevel@tonic-gate #define TMP_MNTPT "/tmp/installgrub_pcfs" 1489*af28f636SEnrico Perla - Sun Microsystems static int 1490*af28f636SEnrico Perla - Sun Microsystems copy_stage2_to_pcfs(ig_data_t *install) 14917c478bd9Sstevel@tonic-gate { 14927c478bd9Sstevel@tonic-gate FILE *mntfp; 1493*af28f636SEnrico Perla - Sun Microsystems int pcfs_fp; 1494*af28f636SEnrico Perla - Sun Microsystems int status = BC_ERROR; 14957c478bd9Sstevel@tonic-gate char buf[SECTOR_SIZE]; 14967c478bd9Sstevel@tonic-gate char *cp; 14977c478bd9Sstevel@tonic-gate struct mnttab mp = {0}, mpref = {0}; 1498*af28f636SEnrico Perla - Sun Microsystems ig_device_t *device = &install->device; 1499*af28f636SEnrico Perla - Sun Microsystems ig_stage2_t *stage2 = &install->stage2; 15007c478bd9Sstevel@tonic-gate 15017c478bd9Sstevel@tonic-gate /* convert raw to block device name by removing the first 'r' */ 1502*af28f636SEnrico Perla - Sun Microsystems (void) strncpy(buf, device->path, sizeof (buf)); 15037c478bd9Sstevel@tonic-gate buf[sizeof (buf) - 1] = 0; 15047c478bd9Sstevel@tonic-gate cp = strchr(buf, 'r'); 15057c478bd9Sstevel@tonic-gate if (cp == NULL) { 1506*af28f636SEnrico Perla - Sun Microsystems (void) fprintf(stderr, CONVERT_FAIL, device->path); 1507*af28f636SEnrico Perla - Sun Microsystems return (BC_ERROR); 15087c478bd9Sstevel@tonic-gate } 15097c478bd9Sstevel@tonic-gate do { 15107c478bd9Sstevel@tonic-gate *cp = *(cp + 1); 15117c478bd9Sstevel@tonic-gate } while (*(++cp)); 15127c478bd9Sstevel@tonic-gate 15137c478bd9Sstevel@tonic-gate /* get the mount point, if any */ 15147c478bd9Sstevel@tonic-gate mntfp = fopen("/etc/mnttab", "r"); 15157c478bd9Sstevel@tonic-gate if (mntfp == NULL) { 15167c478bd9Sstevel@tonic-gate (void) fprintf(stderr, OPEN_FAIL_FILE, "/etc/mnttab"); 1517*af28f636SEnrico Perla - Sun Microsystems return (BC_ERROR); 15187c478bd9Sstevel@tonic-gate } 15197c478bd9Sstevel@tonic-gate 15207c478bd9Sstevel@tonic-gate mpref.mnt_special = buf; 15217c478bd9Sstevel@tonic-gate if (getmntany(mntfp, &mp, &mpref) != 0) { 15227c478bd9Sstevel@tonic-gate char cmd[128]; 15237c478bd9Sstevel@tonic-gate 15247c478bd9Sstevel@tonic-gate /* not mounted, try remount */ 15257c478bd9Sstevel@tonic-gate (void) mkdir(TMP_MNTPT, S_IRWXU); 15267c478bd9Sstevel@tonic-gate (void) snprintf(cmd, sizeof (cmd), "mount -F pcfs %s %s", 15277c478bd9Sstevel@tonic-gate buf, TMP_MNTPT); 15287c478bd9Sstevel@tonic-gate (void) system(cmd); 15297c478bd9Sstevel@tonic-gate rewind(mntfp); 15307c478bd9Sstevel@tonic-gate bzero(&mp, sizeof (mp)); 15317c478bd9Sstevel@tonic-gate if (getmntany(mntfp, &mp, &mpref) != 0) { 15327c478bd9Sstevel@tonic-gate (void) fprintf(stderr, MOUNT_FAIL, buf); 1533*af28f636SEnrico Perla - Sun Microsystems return (BC_ERROR); 15347c478bd9Sstevel@tonic-gate } 15357c478bd9Sstevel@tonic-gate } 15367c478bd9Sstevel@tonic-gate 15377c478bd9Sstevel@tonic-gate (void) snprintf(buf, sizeof (buf), 15387c478bd9Sstevel@tonic-gate "%s/boot", mp.mnt_mountp); 15397c478bd9Sstevel@tonic-gate (void) mkdir(buf, S_IRWXU); 15407c478bd9Sstevel@tonic-gate (void) strcat(buf, "/grub"); 15417c478bd9Sstevel@tonic-gate (void) mkdir(buf, S_IRWXU); 15427c478bd9Sstevel@tonic-gate 15437c478bd9Sstevel@tonic-gate (void) strcat(buf, "/stage2"); 15447c478bd9Sstevel@tonic-gate pcfs_fp = open(buf, O_WRONLY | O_CREAT, S_IRWXU); 15457c478bd9Sstevel@tonic-gate if (pcfs_fp == -1) { 15467c478bd9Sstevel@tonic-gate (void) fprintf(stderr, OPEN_FAIL_FILE, buf); 15477c478bd9Sstevel@tonic-gate perror("open:"); 1548*af28f636SEnrico Perla - Sun Microsystems goto out; 15497c478bd9Sstevel@tonic-gate } 15507c478bd9Sstevel@tonic-gate 1551*af28f636SEnrico Perla - Sun Microsystems /* write stage2 to the pcfs mounted filesystem. */ 1552*af28f636SEnrico Perla - Sun Microsystems if (write(pcfs_fp, stage2->file, stage2->file_size) 1553*af28f636SEnrico Perla - Sun Microsystems != stage2->file_size) { 1554*af28f636SEnrico Perla - Sun Microsystems perror(gettext("Error writing stage2")); 1555*af28f636SEnrico Perla - Sun Microsystems goto out; 15567c478bd9Sstevel@tonic-gate } 1557*af28f636SEnrico Perla - Sun Microsystems 1558*af28f636SEnrico Perla - Sun Microsystems status = BC_SUCCESS; 1559*af28f636SEnrico Perla - Sun Microsystems out_fd: 15607c478bd9Sstevel@tonic-gate (void) close(pcfs_fp); 1561*af28f636SEnrico Perla - Sun Microsystems out: 15627c478bd9Sstevel@tonic-gate (void) umount(TMP_MNTPT); 1563*af28f636SEnrico Perla - Sun Microsystems (void) rmdir(TMP_MNTPT); 1564*af28f636SEnrico Perla - Sun Microsystems return (status); 15657c478bd9Sstevel@tonic-gate } 1566