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
5d33344bbSsy  * Common Development and Distribution License (the "License").
6d33344bbSsy  * You may not use this file except in compliance with the License.
77c478bd9Sstevel@tonic-gate  *
87c478bd9Sstevel@tonic-gate  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
97c478bd9Sstevel@tonic-gate  * or http://www.opensolaris.org/os/licensing.
107c478bd9Sstevel@tonic-gate  * See the License for the specific language governing permissions
117c478bd9Sstevel@tonic-gate  * and limitations under the License.
127c478bd9Sstevel@tonic-gate  *
137c478bd9Sstevel@tonic-gate  * When distributing Covered Code, include this CDDL HEADER in each
147c478bd9Sstevel@tonic-gate  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
157c478bd9Sstevel@tonic-gate  * If applicable, add the following below this CDDL HEADER, with the
167c478bd9Sstevel@tonic-gate  * fields enclosed by brackets "[]" replaced with your own identifying
177c478bd9Sstevel@tonic-gate  * information: Portions Copyright [yyyy] [name of copyright owner]
187c478bd9Sstevel@tonic-gate  *
197c478bd9Sstevel@tonic-gate  * CDDL HEADER END
207c478bd9Sstevel@tonic-gate  */
217c478bd9Sstevel@tonic-gate /*
22af28f636SEnrico Perla - Sun Microsystems  * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
2333f5ff17SMilan Jurik  * Copyright 2012 Milan Jurik. All rights reserved.
24cc641e8dSToomas Soome  * Copyright 2016 Toomas Soome <tsoome@me.com>
259890706eSHans Rosenfeld  * Copyright 2016 Nexenta Systems, Inc. All rights reserved.
267c478bd9Sstevel@tonic-gate  */
277c478bd9Sstevel@tonic-gate 
287c478bd9Sstevel@tonic-gate #include <stdio.h>
297c478bd9Sstevel@tonic-gate #include <stdlib.h>
307c478bd9Sstevel@tonic-gate #include <libgen.h>
317c478bd9Sstevel@tonic-gate #include <malloc.h>
327c478bd9Sstevel@tonic-gate #include <string.h>
337c478bd9Sstevel@tonic-gate #include <fcntl.h>
347c478bd9Sstevel@tonic-gate #include <unistd.h>
357c478bd9Sstevel@tonic-gate #include <strings.h>
36af28f636SEnrico Perla - Sun Microsystems #include <libintl.h>
37af28f636SEnrico Perla - Sun Microsystems #include <locale.h>
38af28f636SEnrico Perla - Sun Microsystems #include <errno.h>
39af28f636SEnrico Perla - Sun Microsystems #include <libfdisk.h>
40af28f636SEnrico Perla - Sun Microsystems #include <stdarg.h>
41af28f636SEnrico Perla - Sun Microsystems #include <assert.h>
42af28f636SEnrico Perla - Sun Microsystems 
437c478bd9Sstevel@tonic-gate #include <sys/mount.h>
447c478bd9Sstevel@tonic-gate #include <sys/mnttab.h>
457c478bd9Sstevel@tonic-gate #include <sys/dktp/fdisk.h>
46d33344bbSsy #include <sys/dkio.h>
47d33344bbSsy #include <sys/vtoc.h>
48af28f636SEnrico Perla - Sun Microsystems #include <sys/types.h>
49af28f636SEnrico Perla - Sun Microsystems #include <sys/stat.h>
50af28f636SEnrico Perla - Sun Microsystems #include <sys/multiboot.h>
51af28f636SEnrico Perla - Sun Microsystems #include <sys/sysmacros.h>
521a902ef8SHans Rosenfeld #include <sys/efi_partition.h>
531a902ef8SHans Rosenfeld 
541a902ef8SHans Rosenfeld #include <libnvpair.h>
551a902ef8SHans Rosenfeld #include <libfstyp.h>
567c478bd9Sstevel@tonic-gate 
577c478bd9Sstevel@tonic-gate #include "message.h"
58af28f636SEnrico Perla - Sun Microsystems #include "installgrub.h"
59af28f636SEnrico Perla - Sun Microsystems #include "./../common/bblk_einfo.h"
60af28f636SEnrico Perla - Sun Microsystems #include "./../common/boot_utils.h"
61af28f636SEnrico Perla - Sun Microsystems #include "./../common/mboot_extra.h"
6221ba817cSToomas Soome #include "getresponse.h"
637c478bd9Sstevel@tonic-gate 
647c478bd9Sstevel@tonic-gate #ifndef	TEXT_DOMAIN
657c478bd9Sstevel@tonic-gate #define	TEXT_DOMAIN	"SUNW_OST_OSCMD"
667c478bd9Sstevel@tonic-gate #endif
677c478bd9Sstevel@tonic-gate 
68af28f636SEnrico Perla - Sun Microsystems /*
69af28f636SEnrico Perla - Sun Microsystems  * Variables to track installgrub desired mode of operation.
70af28f636SEnrico Perla - Sun Microsystems  * 'nowrite' and 'boot_debug' come from boot_common.h.
71af28f636SEnrico Perla - Sun Microsystems  */
72af28f636SEnrico Perla - Sun Microsystems static boolean_t write_mbr = B_FALSE;
73af28f636SEnrico Perla - Sun Microsystems static boolean_t force_mbr = B_FALSE;
74af28f636SEnrico Perla - Sun Microsystems static boolean_t force_update = B_FALSE;
75af28f636SEnrico Perla - Sun Microsystems static boolean_t do_getinfo = B_FALSE;
76af28f636SEnrico Perla - Sun Microsystems static boolean_t do_version = B_FALSE;
77af28f636SEnrico Perla - Sun Microsystems static boolean_t do_mirror_bblk = B_FALSE;
78af28f636SEnrico Perla - Sun Microsystems static boolean_t strip = B_FALSE;
79af28f636SEnrico Perla - Sun Microsystems static boolean_t verbose_dump = B_FALSE;
80af28f636SEnrico Perla - Sun Microsystems 
81af28f636SEnrico Perla - Sun Microsystems /* Installing the bootblock is the default operation. */
82af28f636SEnrico Perla - Sun Microsystems static boolean_t do_install = B_TRUE;
83af28f636SEnrico Perla - Sun Microsystems 
84af28f636SEnrico Perla - Sun Microsystems /* Versioning string, if present. */
85af28f636SEnrico Perla - Sun Microsystems static char *update_str;
86af28f636SEnrico Perla - Sun Microsystems 
87af28f636SEnrico Perla - Sun Microsystems /*
88af28f636SEnrico Perla - Sun Microsystems  * Temporary buffer to store the first 32K of data looking for a multiboot
89af28f636SEnrico Perla - Sun Microsystems  * signature.
90af28f636SEnrico Perla - Sun Microsystems  */
91af28f636SEnrico Perla - Sun Microsystems char	mboot_scan[MBOOT_SCAN_SIZE];
92af28f636SEnrico Perla - Sun Microsystems 
93af28f636SEnrico Perla - Sun Microsystems /* Function prototypes. */
94af28f636SEnrico Perla - Sun Microsystems static void check_options(char *);
95af28f636SEnrico Perla - Sun Microsystems static int handle_install(char *, char **);
96af28f636SEnrico Perla - Sun Microsystems static int handle_mirror(char *, char **);
97af28f636SEnrico Perla - Sun Microsystems static int handle_getinfo(char *, char **);
98af28f636SEnrico Perla - Sun Microsystems static int commit_to_disk(ig_data_t *, char *);
99af28f636SEnrico Perla - Sun Microsystems static int init_device(ig_device_t *, char *path);
100af28f636SEnrico Perla - Sun Microsystems static void cleanup_device(ig_device_t *);
101af28f636SEnrico Perla - Sun Microsystems static void cleanup_stage2(ig_stage2_t *);
102af28f636SEnrico Perla - Sun Microsystems static int get_start_sector(ig_device_t *);
103af28f636SEnrico Perla - Sun Microsystems static int get_disk_fd(ig_device_t *device);
104af28f636SEnrico Perla - Sun Microsystems static int get_raw_partition_fd(ig_device_t *);
105af28f636SEnrico Perla - Sun Microsystems static char *get_raw_partition_path(ig_device_t *);
106af28f636SEnrico Perla - Sun Microsystems static int propagate_bootblock(ig_data_t *, ig_data_t *, char *);
107af28f636SEnrico Perla - Sun Microsystems static int find_x86_bootpar(struct mboot *, int *, uint32_t *);
108af28f636SEnrico Perla - Sun Microsystems static int write_stage2(ig_data_t *);
109af28f636SEnrico Perla - Sun Microsystems static int write_stage1(ig_data_t *);
1107c478bd9Sstevel@tonic-gate static void usage(char *);
111af28f636SEnrico Perla - Sun Microsystems static int read_stage1_from_file(char *, ig_data_t *);
112af28f636SEnrico Perla - Sun Microsystems static int read_stage2_from_file(char *, ig_data_t *);
113af28f636SEnrico Perla - Sun Microsystems static int read_stage1_from_disk(int, char *);
1141a902ef8SHans Rosenfeld static int read_stage2_from_disk(int, ig_stage2_t *, int);
115af28f636SEnrico Perla - Sun Microsystems static int prepare_stage1(ig_data_t *);
116af28f636SEnrico Perla - Sun Microsystems static int prepare_stage2(ig_data_t *, char *);
117af28f636SEnrico Perla - Sun Microsystems static void prepare_fake_multiboot(ig_stage2_t *);
118af28f636SEnrico Perla - Sun Microsystems static void add_stage2_einfo(ig_stage2_t *, char *updt_str);
119af28f636SEnrico Perla - Sun Microsystems static boolean_t is_update_necessary(ig_data_t *, char *);
1207c478bd9Sstevel@tonic-gate 
121342440ecSPrasad Singamsetty extern int read_stage2_blocklist(int, unsigned int *);
1227c478bd9Sstevel@tonic-gate 
1237c478bd9Sstevel@tonic-gate int
main(int argc,char * argv[])1247c478bd9Sstevel@tonic-gate main(int argc, char *argv[])
1257c478bd9Sstevel@tonic-gate {
126af28f636SEnrico Perla - Sun Microsystems 	int	opt;
127af28f636SEnrico Perla - Sun Microsystems 	int	params = 3;
128af28f636SEnrico Perla - Sun Microsystems 	int	ret;
129af28f636SEnrico Perla - Sun Microsystems 	char	**handle_args;
130af28f636SEnrico Perla - Sun Microsystems 	char	*progname;
1317c478bd9Sstevel@tonic-gate 
1327c478bd9Sstevel@tonic-gate 	(void) setlocale(LC_ALL, "");
1337c478bd9Sstevel@tonic-gate 	(void) textdomain(TEXT_DOMAIN);
13421ba817cSToomas Soome 	if (init_yes() < 0) {
13521ba817cSToomas Soome 		(void) fprintf(stderr, gettext(ERR_MSG_INIT_YES),
13621ba817cSToomas Soome 		    strerror(errno));
13721ba817cSToomas Soome 		exit(BC_ERROR);
13821ba817cSToomas Soome 	}
1397c478bd9Sstevel@tonic-gate 
140af28f636SEnrico Perla - Sun Microsystems 	/*
141af28f636SEnrico Perla - Sun Microsystems 	 * retro-compatibility: installing the bootblock is the default
142af28f636SEnrico Perla - Sun Microsystems 	 * and there is no switch for it.
143af28f636SEnrico Perla - Sun Microsystems 	 */
144af28f636SEnrico Perla - Sun Microsystems 	do_install = B_TRUE;
145af28f636SEnrico Perla - Sun Microsystems 
146af28f636SEnrico Perla - Sun Microsystems 	while ((opt = getopt(argc, argv, "dVMFfmneiu:")) != EOF) {
1477c478bd9Sstevel@tonic-gate 		switch (opt) {
1487c478bd9Sstevel@tonic-gate 		case 'm':
149af28f636SEnrico Perla - Sun Microsystems 			write_mbr = B_TRUE;
1507c478bd9Sstevel@tonic-gate 			break;
1517c478bd9Sstevel@tonic-gate 		case 'n':
152af28f636SEnrico Perla - Sun Microsystems 			nowrite = B_TRUE;
1537c478bd9Sstevel@tonic-gate 			break;
1547c478bd9Sstevel@tonic-gate 		case 'f':
155af28f636SEnrico Perla - Sun Microsystems 			force_mbr = B_TRUE;
1567c478bd9Sstevel@tonic-gate 			break;
1577ce76caaSEnrico Perla - Sun Microsystems 		case 'i':
158af28f636SEnrico Perla - Sun Microsystems 			do_getinfo = B_TRUE;
159af28f636SEnrico Perla - Sun Microsystems 			do_install = B_FALSE;
1607ce76caaSEnrico Perla - Sun Microsystems 			params = 1;
1617ce76caaSEnrico Perla - Sun Microsystems 			break;
162af28f636SEnrico Perla - Sun Microsystems 		case 'V':
163af28f636SEnrico Perla - Sun Microsystems 			verbose_dump = B_TRUE;
164af28f636SEnrico Perla - Sun Microsystems 			break;
165af28f636SEnrico Perla - Sun Microsystems 		case 'd':
166af28f636SEnrico Perla - Sun Microsystems 			boot_debug = B_TRUE;
167af28f636SEnrico Perla - Sun Microsystems 			break;
168af28f636SEnrico Perla - Sun Microsystems 		case 'F':
169af28f636SEnrico Perla - Sun Microsystems 			force_update = B_TRUE;
170af28f636SEnrico Perla - Sun Microsystems 			break;
1717ce76caaSEnrico Perla - Sun Microsystems 		case 'e':
172af28f636SEnrico Perla - Sun Microsystems 			strip = B_TRUE;
173af28f636SEnrico Perla - Sun Microsystems 			break;
174af28f636SEnrico Perla - Sun Microsystems 		case 'M':
175af28f636SEnrico Perla - Sun Microsystems 			do_mirror_bblk = B_TRUE;
176af28f636SEnrico Perla - Sun Microsystems 			do_install = B_FALSE;
177af28f636SEnrico Perla - Sun Microsystems 			params = 2;
1787ce76caaSEnrico Perla - Sun Microsystems 			break;
179af28f636SEnrico Perla - Sun Microsystems 		case 'u':
180af28f636SEnrico Perla - Sun Microsystems 			do_version = B_TRUE;
181af28f636SEnrico Perla - Sun Microsystems 
182af28f636SEnrico Perla - Sun Microsystems 			update_str = malloc(strlen(optarg) + 1);
183af28f636SEnrico Perla - Sun Microsystems 			if (update_str == NULL) {
184af28f636SEnrico Perla - Sun Microsystems 				(void) fprintf(stderr, gettext("Unable to "
185af28f636SEnrico Perla - Sun Microsystems 				    "allocate memory\n"));
186af28f636SEnrico Perla - Sun Microsystems 				exit(BC_ERROR);
187af28f636SEnrico Perla - Sun Microsystems 			}
188af28f636SEnrico Perla - Sun Microsystems 			(void) strlcpy(update_str, optarg, strlen(optarg) + 1);
1897ce76caaSEnrico Perla - Sun Microsystems 			break;
1907c478bd9Sstevel@tonic-gate 		default:
1917c478bd9Sstevel@tonic-gate 			/* fall through to process non-optional args */
1927c478bd9Sstevel@tonic-gate 			break;
1937c478bd9Sstevel@tonic-gate 		}
1947c478bd9Sstevel@tonic-gate 	}
1957c478bd9Sstevel@tonic-gate 
1967c478bd9Sstevel@tonic-gate 	/* check arguments */
1977ce76caaSEnrico Perla - Sun Microsystems 	if (argc != optind + params) {
1987c478bd9Sstevel@tonic-gate 		usage(argv[0]);
199af28f636SEnrico Perla - Sun Microsystems 		exit(BC_ERROR);
2007c478bd9Sstevel@tonic-gate 	}
2017c478bd9Sstevel@tonic-gate 
202af28f636SEnrico Perla - Sun Microsystems 	/*
203af28f636SEnrico Perla - Sun Microsystems 	 * clean up options (and bail out if an unrecoverable combination is
204af28f636SEnrico Perla - Sun Microsystems 	 * requested.
205af28f636SEnrico Perla - Sun Microsystems 	 */
206af28f636SEnrico Perla - Sun Microsystems 	progname = argv[0];
207af28f636SEnrico Perla - Sun Microsystems 	check_options(progname);
208af28f636SEnrico Perla - Sun Microsystems 	handle_args = argv + optind;
209af28f636SEnrico Perla - Sun Microsystems 
210af28f636SEnrico Perla - Sun Microsystems 	if (nowrite)
2117c478bd9Sstevel@tonic-gate 		(void) fprintf(stdout, DRY_RUN);
212af28f636SEnrico Perla - Sun Microsystems 
213af28f636SEnrico Perla - Sun Microsystems 	if (do_getinfo) {
214af28f636SEnrico Perla - Sun Microsystems 		ret = handle_getinfo(progname, handle_args);
215af28f636SEnrico Perla - Sun Microsystems 	} else if (do_mirror_bblk) {
216af28f636SEnrico Perla - Sun Microsystems 		ret = handle_mirror(progname, handle_args);
217af28f636SEnrico Perla - Sun Microsystems 	} else {
218af28f636SEnrico Perla - Sun Microsystems 		ret = handle_install(progname, handle_args);
219af28f636SEnrico Perla - Sun Microsystems 	}
220af28f636SEnrico Perla - Sun Microsystems 	return (ret);
221af28f636SEnrico Perla - Sun Microsystems }
222af28f636SEnrico Perla - Sun Microsystems 
223af28f636SEnrico Perla - Sun Microsystems #define	MEANINGLESS_OPT	gettext("%s specified but meaningless, ignoring\n")
224af28f636SEnrico Perla - Sun Microsystems static void
check_options(char * progname)225af28f636SEnrico Perla - Sun Microsystems check_options(char *progname)
226af28f636SEnrico Perla - Sun Microsystems {
227af28f636SEnrico Perla - Sun Microsystems 	if (do_getinfo && do_mirror_bblk) {
228af28f636SEnrico Perla - Sun Microsystems 		(void) fprintf(stderr, gettext("Only one of -M and -i can be "
229af28f636SEnrico Perla - Sun Microsystems 		    "specified at the same time\n"));
230af28f636SEnrico Perla - Sun Microsystems 		usage(progname);
231af28f636SEnrico Perla - Sun Microsystems 		exit(BC_ERROR);
2327c478bd9Sstevel@tonic-gate 	}
2337c478bd9Sstevel@tonic-gate 
234af28f636SEnrico Perla - Sun Microsystems 	if (do_mirror_bblk) {
235af28f636SEnrico Perla - Sun Microsystems 		/*
236af28f636SEnrico Perla - Sun Microsystems 		 * -u and -F may actually reflect a user intent that is not
237af28f636SEnrico Perla - Sun Microsystems 		 * correct with this command (mirror can be interpreted
238af28f636SEnrico Perla - Sun Microsystems 		 * "similar" to install. Emit a message and continue.
239af28f636SEnrico Perla - Sun Microsystems 		 * -e and -V have no meaning, be quiet here and only report the
240af28f636SEnrico Perla - Sun Microsystems 		 * incongruence if a debug output is requested.
241af28f636SEnrico Perla - Sun Microsystems 		 */
242af28f636SEnrico Perla - Sun Microsystems 		if (do_version) {
243af28f636SEnrico Perla - Sun Microsystems 			(void) fprintf(stderr, MEANINGLESS_OPT, "-u");
244af28f636SEnrico Perla - Sun Microsystems 			do_version = B_FALSE;
245af28f636SEnrico Perla - Sun Microsystems 		}
246af28f636SEnrico Perla - Sun Microsystems 		if (force_update) {
247af28f636SEnrico Perla - Sun Microsystems 			(void) fprintf(stderr, MEANINGLESS_OPT, "-F");
248af28f636SEnrico Perla - Sun Microsystems 			force_update = B_FALSE;
2497ce76caaSEnrico Perla - Sun Microsystems 		}
250af28f636SEnrico Perla - Sun Microsystems 		if (strip || verbose_dump) {
251af28f636SEnrico Perla - Sun Microsystems 			BOOT_DEBUG(MEANINGLESS_OPT, "-e|-V");
252af28f636SEnrico Perla - Sun Microsystems 			strip = B_FALSE;
253af28f636SEnrico Perla - Sun Microsystems 			verbose_dump = B_FALSE;
254af28f636SEnrico Perla - Sun Microsystems 		}
255af28f636SEnrico Perla - Sun Microsystems 	}
2567c478bd9Sstevel@tonic-gate 
257af28f636SEnrico Perla - Sun Microsystems 	if (do_getinfo) {
258af28f636SEnrico Perla - Sun Microsystems 		if (write_mbr || force_mbr || do_version || force_update) {
259af28f636SEnrico Perla - Sun Microsystems 			BOOT_DEBUG(MEANINGLESS_OPT, "-m|-f|-u|-F");
260af28f636SEnrico Perla - Sun Microsystems 			write_mbr = force_mbr = do_version = B_FALSE;
261af28f636SEnrico Perla - Sun Microsystems 			force_update = B_FALSE;
2627ce76caaSEnrico Perla - Sun Microsystems 		}
2637c478bd9Sstevel@tonic-gate 	}
264af28f636SEnrico Perla - Sun Microsystems }
2657c478bd9Sstevel@tonic-gate 
266af28f636SEnrico Perla - Sun Microsystems /*
267af28f636SEnrico Perla - Sun Microsystems  * Install a new stage1/stage2 pair on the specified device. handle_install()
268af28f636SEnrico Perla - Sun Microsystems  * expects argv to contain 3 parameters (the path to stage1, the path to stage2,
269af28f636SEnrico Perla - Sun Microsystems  * the target device).
270af28f636SEnrico Perla - Sun Microsystems  *
271af28f636SEnrico Perla - Sun Microsystems  * Returns:	BC_SUCCESS - if the installation is successful
272af28f636SEnrico Perla - Sun Microsystems  *		BC_ERROR   - if the installation failed
273af28f636SEnrico Perla - Sun Microsystems  *		BC_NOUPDT  - if no installation was performed because the GRUB
274af28f636SEnrico Perla - Sun Microsystems  *		             version currently installed is more recent than the
275af28f636SEnrico Perla - Sun Microsystems  *			     supplied one.
276af28f636SEnrico Perla - Sun Microsystems  *
277af28f636SEnrico Perla - Sun Microsystems  */
278af28f636SEnrico Perla - Sun Microsystems static int
handle_install(char * progname,char ** argv)279af28f636SEnrico Perla - Sun Microsystems handle_install(char *progname, char **argv)
280af28f636SEnrico Perla - Sun Microsystems {
281af28f636SEnrico Perla - Sun Microsystems 	ig_data_t	install_data;
282af28f636SEnrico Perla - Sun Microsystems 	char		*stage1_path = NULL;
283af28f636SEnrico Perla - Sun Microsystems 	char		*stage2_path = NULL;
284af28f636SEnrico Perla - Sun Microsystems 	char		*device_path = NULL;
285af28f636SEnrico Perla - Sun Microsystems 	int		ret = BC_ERROR;
286af28f636SEnrico Perla - Sun Microsystems 
287af28f636SEnrico Perla - Sun Microsystems 	stage1_path = strdup(argv[0]);
288af28f636SEnrico Perla - Sun Microsystems 	stage2_path = strdup(argv[1]);
289af28f636SEnrico Perla - Sun Microsystems 	device_path = strdup(argv[2]);
290af28f636SEnrico Perla - Sun Microsystems 
291af28f636SEnrico Perla - Sun Microsystems 	bzero(&install_data, sizeof (ig_data_t));
292af28f636SEnrico Perla - Sun Microsystems 
293af28f636SEnrico Perla - Sun Microsystems 	if (!stage1_path || !stage2_path || !device_path) {
294af28f636SEnrico Perla - Sun Microsystems 		(void) fprintf(stderr, gettext("Missing parameter"));
295af28f636SEnrico Perla - Sun Microsystems 		usage(progname);
296af28f636SEnrico Perla - Sun Microsystems 		goto out;
297af28f636SEnrico Perla - Sun Microsystems 	}
2987c478bd9Sstevel@tonic-gate 
299af28f636SEnrico Perla - Sun Microsystems 	BOOT_DEBUG("stage1 path: %s, stage2 path: %s, device: %s\n",
300af28f636SEnrico Perla - Sun Microsystems 	    stage1_path, stage2_path, device_path);
301af28f636SEnrico Perla - Sun Microsystems 
302af28f636SEnrico Perla - Sun Microsystems 	if (init_device(&install_data.device, device_path) != BC_SUCCESS) {
303af28f636SEnrico Perla - Sun Microsystems 		(void) fprintf(stderr, gettext("Unable to gather device "
304af28f636SEnrico Perla - Sun Microsystems 		    "information for %s\n"), device_path);
305af28f636SEnrico Perla - Sun Microsystems 		goto out;
306af28f636SEnrico Perla - Sun Microsystems 	}
307af28f636SEnrico Perla - Sun Microsystems 
308af28f636SEnrico Perla - Sun Microsystems 	/* read in stage1 and stage2. */
309af28f636SEnrico Perla - Sun Microsystems 	if (read_stage1_from_file(stage1_path, &install_data) != BC_SUCCESS) {
310af28f636SEnrico Perla - Sun Microsystems 		(void) fprintf(stderr, gettext("Error opening %s\n"),
311af28f636SEnrico Perla - Sun Microsystems 		    stage1_path);
312af28f636SEnrico Perla - Sun Microsystems 		goto out_dev;
3137ce76caaSEnrico Perla - Sun Microsystems 	}
3147ce76caaSEnrico Perla - Sun Microsystems 
315af28f636SEnrico Perla - Sun Microsystems 	if (read_stage2_from_file(stage2_path, &install_data) != BC_SUCCESS) {
316af28f636SEnrico Perla - Sun Microsystems 		(void) fprintf(stderr, gettext("Error opening %s\n"),
317af28f636SEnrico Perla - Sun Microsystems 		    stage2_path);
318af28f636SEnrico Perla - Sun Microsystems 		goto out_dev;
319af28f636SEnrico Perla - Sun Microsystems 	}
3207c478bd9Sstevel@tonic-gate 
321af28f636SEnrico Perla - Sun Microsystems 	/* We do not support versioning on PCFS. */
322af28f636SEnrico Perla - Sun Microsystems 	if (is_bootpar(install_data.device.type) && do_version)
323af28f636SEnrico Perla - Sun Microsystems 		do_version = B_FALSE;
3247ce76caaSEnrico Perla - Sun Microsystems 
325af28f636SEnrico Perla - Sun Microsystems 	/*
326af28f636SEnrico Perla - Sun Microsystems 	 * is_update_necessary() will take care of checking if versioning and/or
327af28f636SEnrico Perla - Sun Microsystems 	 * forcing the update have been specified. It will also emit a warning
328af28f636SEnrico Perla - Sun Microsystems 	 * if a non-versioned update is attempted over a versioned bootblock.
329af28f636SEnrico Perla - Sun Microsystems 	 */
330af28f636SEnrico Perla - Sun Microsystems 	if (!is_update_necessary(&install_data, update_str)) {
331af28f636SEnrico Perla - Sun Microsystems 		(void) fprintf(stderr, gettext("GRUB version installed "
332af28f636SEnrico Perla - Sun Microsystems 		    "on %s is more recent or identical\n"
333af28f636SEnrico Perla - Sun Microsystems 		    "Use -F to override or install without the -u option\n"),
334af28f636SEnrico Perla - Sun Microsystems 		    device_path);
335af28f636SEnrico Perla - Sun Microsystems 		ret = BC_NOUPDT;
336af28f636SEnrico Perla - Sun Microsystems 		goto out_dev;
3377c478bd9Sstevel@tonic-gate 	}
338af28f636SEnrico Perla - Sun Microsystems 	/*
339af28f636SEnrico Perla - Sun Microsystems 	 * We get here if:
340af28f636SEnrico Perla - Sun Microsystems 	 * - the installed GRUB version is older than the one about to be
341af28f636SEnrico Perla - Sun Microsystems 	 *   installed.
342af28f636SEnrico Perla - Sun Microsystems 	 * - no versioning string has been passed through the command line.
343af28f636SEnrico Perla - Sun Microsystems 	 * - a forced update is requested (-F).
344af28f636SEnrico Perla - Sun Microsystems 	 */
345af28f636SEnrico Perla - Sun Microsystems 	BOOT_DEBUG("Ready to commit to disk\n");
346af28f636SEnrico Perla - Sun Microsystems 	ret = commit_to_disk(&install_data, update_str);
347af28f636SEnrico Perla - Sun Microsystems 
348af28f636SEnrico Perla - Sun Microsystems out_dev:
349af28f636SEnrico Perla - Sun Microsystems 	cleanup_device(&install_data.device);
350af28f636SEnrico Perla - Sun Microsystems out:
351af28f636SEnrico Perla - Sun Microsystems 	free(stage1_path);
352af28f636SEnrico Perla - Sun Microsystems 	free(stage2_path);
353af28f636SEnrico Perla - Sun Microsystems 	free(device_path);
354af28f636SEnrico Perla - Sun Microsystems 	return (ret);
355af28f636SEnrico Perla - Sun Microsystems }
3567c478bd9Sstevel@tonic-gate 
357af28f636SEnrico Perla - Sun Microsystems /*
358af28f636SEnrico Perla - Sun Microsystems  * Retrieves from a device the extended information (einfo) associated to the
359af28f636SEnrico Perla - Sun Microsystems  * installed stage2.
360af28f636SEnrico Perla - Sun Microsystems  * Expects one parameter, the device path, in the form: /dev/rdsk/c?[t?]d?s0.
361af28f636SEnrico Perla - Sun Microsystems  * Returns:
362af28f636SEnrico Perla - Sun Microsystems  *        - BC_SUCCESS (and prints out einfo contents depending on 'flags')
363af28f636SEnrico Perla - Sun Microsystems  *	  - BC_ERROR (on error)
364af28f636SEnrico Perla - Sun Microsystems  *        - BC_NOEINFO (no extended information available)
365af28f636SEnrico Perla - Sun Microsystems  */
366af28f636SEnrico Perla - Sun Microsystems static int
handle_getinfo(char * progname,char ** argv)367af28f636SEnrico Perla - Sun Microsystems handle_getinfo(char *progname, char **argv)
368af28f636SEnrico Perla - Sun Microsystems {
369af28f636SEnrico Perla - Sun Microsystems 	ig_data_t	data;
370af28f636SEnrico Perla - Sun Microsystems 	ig_stage2_t	*stage2 = &data.stage2;
371af28f636SEnrico Perla - Sun Microsystems 	ig_device_t	*device = &data.device;
372af28f636SEnrico Perla - Sun Microsystems 	bblk_einfo_t	*einfo;
373af28f636SEnrico Perla - Sun Microsystems 	uint8_t		flags = 0;
374af28f636SEnrico Perla - Sun Microsystems 	uint32_t	size;
375af28f636SEnrico Perla - Sun Microsystems 	char		*device_path;
376af28f636SEnrico Perla - Sun Microsystems 	int		retval = BC_ERROR;
377af28f636SEnrico Perla - Sun Microsystems 	int		ret;
378af28f636SEnrico Perla - Sun Microsystems 
379af28f636SEnrico Perla - Sun Microsystems 	device_path = strdup(argv[0]);
380af28f636SEnrico Perla - Sun Microsystems 	if (!device_path) {
381af28f636SEnrico Perla - Sun Microsystems 		(void) fprintf(stderr, gettext("Missing parameter"));
382af28f636SEnrico Perla - Sun Microsystems 		usage(progname);
383af28f636SEnrico Perla - Sun Microsystems 		goto out;
384af28f636SEnrico Perla - Sun Microsystems 	}
385af28f636SEnrico Perla - Sun Microsystems 
386af28f636SEnrico Perla - Sun Microsystems 	bzero(&data, sizeof (ig_data_t));
387af28f636SEnrico Perla - Sun Microsystems 	BOOT_DEBUG("device path: %s\n", device_path);
3887c478bd9Sstevel@tonic-gate 
389af28f636SEnrico Perla - Sun Microsystems 	if (init_device(device, device_path) != BC_SUCCESS) {
390af28f636SEnrico Perla - Sun Microsystems 		(void) fprintf(stderr, gettext("Unable to gather device "
391af28f636SEnrico Perla - Sun Microsystems 		    "information for %s\n"), device_path);
392af28f636SEnrico Perla - Sun Microsystems 		goto out_dev;
393af28f636SEnrico Perla - Sun Microsystems 	}
3947c478bd9Sstevel@tonic-gate 
395af28f636SEnrico Perla - Sun Microsystems 	if (is_bootpar(device->type)) {
396af28f636SEnrico Perla - Sun Microsystems 		(void) fprintf(stderr, gettext("Versioning not supported on "
397af28f636SEnrico Perla - Sun Microsystems 		    "PCFS\n"));
398af28f636SEnrico Perla - Sun Microsystems 		goto out_dev;
399af28f636SEnrico Perla - Sun Microsystems 	}
4007c478bd9Sstevel@tonic-gate 
4011a902ef8SHans Rosenfeld 	ret = read_stage2_from_disk(device->part_fd, stage2, device->type);
402af28f636SEnrico Perla - Sun Microsystems 	if (ret == BC_ERROR) {
403af28f636SEnrico Perla - Sun Microsystems 		(void) fprintf(stderr, gettext("Error reading stage2 from "
404af28f636SEnrico Perla - Sun Microsystems 		    "%s\n"), device_path);
405af28f636SEnrico Perla - Sun Microsystems 		goto out_dev;
406af28f636SEnrico Perla - Sun Microsystems 	}
4077ce76caaSEnrico Perla - Sun Microsystems 
408af28f636SEnrico Perla - Sun Microsystems 	if (ret == BC_NOEXTRA) {
409af28f636SEnrico Perla - Sun Microsystems 		(void) fprintf(stdout, gettext("No multiboot header found on "
410af28f636SEnrico Perla - Sun Microsystems 		    "%s, unable to locate extra information area\n"),
411af28f636SEnrico Perla - Sun Microsystems 		    device_path);
412af28f636SEnrico Perla - Sun Microsystems 		retval = BC_NOEINFO;
413af28f636SEnrico Perla - Sun Microsystems 		goto out_dev;
414af28f636SEnrico Perla - Sun Microsystems 	}
4157c478bd9Sstevel@tonic-gate 
41614d44f22SHans Rosenfeld 	einfo = find_einfo(stage2->extra, stage2->extra_size);
417af28f636SEnrico Perla - Sun Microsystems 	if (einfo == NULL) {
418af28f636SEnrico Perla - Sun Microsystems 		retval = BC_NOEINFO;
419af28f636SEnrico Perla - Sun Microsystems 		(void) fprintf(stderr, gettext("No extended information "
420af28f636SEnrico Perla - Sun Microsystems 		    "found\n"));
421af28f636SEnrico Perla - Sun Microsystems 		goto out_dev;
422af28f636SEnrico Perla - Sun Microsystems 	}
423af28f636SEnrico Perla - Sun Microsystems 
424af28f636SEnrico Perla - Sun Microsystems 	/* Print the extended information. */
425af28f636SEnrico Perla - Sun Microsystems 	if (strip)
426af28f636SEnrico Perla - Sun Microsystems 		flags |= EINFO_EASY_PARSE;
427af28f636SEnrico Perla - Sun Microsystems 	if (verbose_dump)
428af28f636SEnrico Perla - Sun Microsystems 		flags |= EINFO_PRINT_HEADER;
429af28f636SEnrico Perla - Sun Microsystems 
430af28f636SEnrico Perla - Sun Microsystems 	size = stage2->buf_size - P2ROUNDUP(stage2->file_size, 8);
431af28f636SEnrico Perla - Sun Microsystems 	print_einfo(flags, einfo, size);
432af28f636SEnrico Perla - Sun Microsystems 	retval = BC_SUCCESS;
433af28f636SEnrico Perla - Sun Microsystems 
434af28f636SEnrico Perla - Sun Microsystems out_dev:
435af28f636SEnrico Perla - Sun Microsystems 	cleanup_device(&data.device);
436af28f636SEnrico Perla - Sun Microsystems out:
437af28f636SEnrico Perla - Sun Microsystems 	free(device_path);
438af28f636SEnrico Perla - Sun Microsystems 	return (retval);
4397c478bd9Sstevel@tonic-gate }
4407c478bd9Sstevel@tonic-gate 
441af28f636SEnrico Perla - Sun Microsystems /*
442af28f636SEnrico Perla - Sun Microsystems  * Attempt to mirror (propagate) the current stage2 over the attaching disk.
443af28f636SEnrico Perla - Sun Microsystems  *
444af28f636SEnrico Perla - Sun Microsystems  * Returns:
445af28f636SEnrico Perla - Sun Microsystems  *	- BC_SUCCESS (a successful propagation happened)
446af28f636SEnrico Perla - Sun Microsystems  *	- BC_ERROR (an error occurred)
447af28f636SEnrico Perla - Sun Microsystems  *	- BC_NOEXTRA (it is not possible to dump the current bootblock since
448af28f636SEnrico Perla - Sun Microsystems  *			there is no multiboot information)
449af28f636SEnrico Perla - Sun Microsystems  */
450af28f636SEnrico Perla - Sun Microsystems static int
handle_mirror(char * progname,char ** argv)451af28f636SEnrico Perla - Sun Microsystems handle_mirror(char *progname, char **argv)
4527c478bd9Sstevel@tonic-gate {
453af28f636SEnrico Perla - Sun Microsystems 	ig_data_t	curr_data;
454af28f636SEnrico Perla - Sun Microsystems 	ig_data_t	attach_data;
455af28f636SEnrico Perla - Sun Microsystems 	ig_device_t	*curr_device = &curr_data.device;
456af28f636SEnrico Perla - Sun Microsystems 	ig_device_t	*attach_device = &attach_data.device;
457af28f636SEnrico Perla - Sun Microsystems 	ig_stage2_t	*stage2_curr = &curr_data.stage2;
458af28f636SEnrico Perla - Sun Microsystems 	ig_stage2_t	*stage2_attach = &attach_data.stage2;
459af28f636SEnrico Perla - Sun Microsystems 	bblk_einfo_t	*einfo_curr = NULL;
460af28f636SEnrico Perla - Sun Microsystems 	char		*curr_device_path;
461af28f636SEnrico Perla - Sun Microsystems 	char		*attach_device_path;
462af28f636SEnrico Perla - Sun Microsystems 	char		*updt_str = NULL;
463af28f636SEnrico Perla - Sun Microsystems 	int		retval = BC_ERROR;
464af28f636SEnrico Perla - Sun Microsystems 	int		ret;
465af28f636SEnrico Perla - Sun Microsystems 
466af28f636SEnrico Perla - Sun Microsystems 	curr_device_path = strdup(argv[0]);
467af28f636SEnrico Perla - Sun Microsystems 	attach_device_path = strdup(argv[1]);
468af28f636SEnrico Perla - Sun Microsystems 
469af28f636SEnrico Perla - Sun Microsystems 	if (!curr_device_path || !attach_device_path) {
470af28f636SEnrico Perla - Sun Microsystems 		(void) fprintf(stderr, gettext("Missing parameter"));
471af28f636SEnrico Perla - Sun Microsystems 		usage(progname);
472af28f636SEnrico Perla - Sun Microsystems 		goto out;
473af28f636SEnrico Perla - Sun Microsystems 	}
474af28f636SEnrico Perla - Sun Microsystems 	BOOT_DEBUG("Current device path is: %s, attaching device path is: "
475af28f636SEnrico Perla - Sun Microsystems 	    " %s\n", curr_device_path, attach_device_path);
476af28f636SEnrico Perla - Sun Microsystems 
477af28f636SEnrico Perla - Sun Microsystems 	bzero(&curr_data, sizeof (ig_data_t));
478af28f636SEnrico Perla - Sun Microsystems 	bzero(&attach_data, sizeof (ig_data_t));
479af28f636SEnrico Perla - Sun Microsystems 
480af28f636SEnrico Perla - Sun Microsystems 	if (init_device(curr_device, curr_device_path) != BC_SUCCESS) {
481af28f636SEnrico Perla - Sun Microsystems 		(void) fprintf(stderr, gettext("Unable to gather device "
482af28f636SEnrico Perla - Sun Microsystems 		    "information for %s (current device)\n"), curr_device_path);
483af28f636SEnrico Perla - Sun Microsystems 		goto out_currdev;
484af28f636SEnrico Perla - Sun Microsystems 	}
485af28f636SEnrico Perla - Sun Microsystems 
486af28f636SEnrico Perla - Sun Microsystems 	if (init_device(attach_device, attach_device_path) != BC_SUCCESS) {
487af28f636SEnrico Perla - Sun Microsystems 		(void) fprintf(stderr, gettext("Unable to gather device "
488af28f636SEnrico Perla - Sun Microsystems 		    "information for %s (attaching device)\n"),
489af28f636SEnrico Perla - Sun Microsystems 		    attach_device_path);
490af28f636SEnrico Perla - Sun Microsystems 		goto out_devs;
4917fc5d2a4SVikram Hegde 	}
4927fc5d2a4SVikram Hegde 
493af28f636SEnrico Perla - Sun Microsystems 	if (is_bootpar(curr_device->type) || is_bootpar(attach_device->type)) {
494af28f636SEnrico Perla - Sun Microsystems 		(void) fprintf(stderr, gettext("boot block mirroring is not "
495af28f636SEnrico Perla - Sun Microsystems 		    "supported on PCFS\n"));
496af28f636SEnrico Perla - Sun Microsystems 		goto out_devs;
497af28f636SEnrico Perla - Sun Microsystems 	}
498af28f636SEnrico Perla - Sun Microsystems 
4991a902ef8SHans Rosenfeld 	ret = read_stage2_from_disk(curr_device->part_fd, stage2_curr,
5001a902ef8SHans Rosenfeld 	    curr_device->type);
501af28f636SEnrico Perla - Sun Microsystems 	if (ret == BC_ERROR) {
502af28f636SEnrico Perla - Sun Microsystems 		BOOT_DEBUG("Error reading first stage2 blocks from %s\n",
503af28f636SEnrico Perla - Sun Microsystems 		    curr_device->path);
504af28f636SEnrico Perla - Sun Microsystems 		retval = BC_ERROR;
505af28f636SEnrico Perla - Sun Microsystems 		goto out_devs;
506af28f636SEnrico Perla - Sun Microsystems 	}
507af28f636SEnrico Perla - Sun Microsystems 
508af28f636SEnrico Perla - Sun Microsystems 	if (ret == BC_NOEXTRA) {
509af28f636SEnrico Perla - Sun Microsystems 		BOOT_DEBUG("No multiboot header found on %s, unable to grab "
510af28f636SEnrico Perla - Sun Microsystems 		    "stage2\n", curr_device->path);
511af28f636SEnrico Perla - Sun Microsystems 		retval = BC_NOEXTRA;
512af28f636SEnrico Perla - Sun Microsystems 		goto out_devs;
513af28f636SEnrico Perla - Sun Microsystems 	}
514af28f636SEnrico Perla - Sun Microsystems 
51514d44f22SHans Rosenfeld 	einfo_curr = find_einfo(stage2_curr->extra, stage2_curr->extra_size);
516af28f636SEnrico Perla - Sun Microsystems 	if (einfo_curr != NULL)
517af28f636SEnrico Perla - Sun Microsystems 		updt_str = einfo_get_string(einfo_curr);
518af28f636SEnrico Perla - Sun Microsystems 
519af28f636SEnrico Perla - Sun Microsystems 	write_mbr = B_TRUE;
520af28f636SEnrico Perla - Sun Microsystems 	force_mbr = B_TRUE;
521af28f636SEnrico Perla - Sun Microsystems 	retval = propagate_bootblock(&curr_data, &attach_data, updt_str);
522af28f636SEnrico Perla - Sun Microsystems 	cleanup_stage2(stage2_curr);
523af28f636SEnrico Perla - Sun Microsystems 	cleanup_stage2(stage2_attach);
524af28f636SEnrico Perla - Sun Microsystems 
525af28f636SEnrico Perla - Sun Microsystems out_devs:
526af28f636SEnrico Perla - Sun Microsystems 	cleanup_device(attach_device);
527af28f636SEnrico Perla - Sun Microsystems out_currdev:
528af28f636SEnrico Perla - Sun Microsystems 	cleanup_device(curr_device);
529af28f636SEnrico Perla - Sun Microsystems out:
530af28f636SEnrico Perla - Sun Microsystems 	free(curr_device_path);
531af28f636SEnrico Perla - Sun Microsystems 	free(attach_device_path);
532af28f636SEnrico Perla - Sun Microsystems 	return (retval);
533af28f636SEnrico Perla - Sun Microsystems }
534af28f636SEnrico Perla - Sun Microsystems 
535af28f636SEnrico Perla - Sun Microsystems static int
commit_to_disk(ig_data_t * install,char * updt_str)536af28f636SEnrico Perla - Sun Microsystems commit_to_disk(ig_data_t *install, char *updt_str)
537af28f636SEnrico Perla - Sun Microsystems {
538af28f636SEnrico Perla - Sun Microsystems 	assert(install != NULL);
5397fc5d2a4SVikram Hegde 	/*
540af28f636SEnrico Perla - Sun Microsystems 	 * vanilla stage1 and stage2 need to be updated at runtime.
541af28f636SEnrico Perla - Sun Microsystems 	 * Update stage2 before stage1 because stage1 needs to know the first
542af28f636SEnrico Perla - Sun Microsystems 	 * sector stage2 will be written to.
5437fc5d2a4SVikram Hegde 	 */
544af28f636SEnrico Perla - Sun Microsystems 	if (prepare_stage2(install, updt_str) != BC_SUCCESS) {
545af28f636SEnrico Perla - Sun Microsystems 		(void) fprintf(stderr, gettext("Error building stage2\n"));
546af28f636SEnrico Perla - Sun Microsystems 		return (BC_ERROR);
547af28f636SEnrico Perla - Sun Microsystems 	}
548af28f636SEnrico Perla - Sun Microsystems 	if (prepare_stage1(install) != BC_SUCCESS) {
549af28f636SEnrico Perla - Sun Microsystems 		(void) fprintf(stderr, gettext("Error building stage1\n"));
550af28f636SEnrico Perla - Sun Microsystems 		return (BC_ERROR);
551af28f636SEnrico Perla - Sun Microsystems 	}
552af28f636SEnrico Perla - Sun Microsystems 
553af28f636SEnrico Perla - Sun Microsystems 	/* Write stage2 out to disk. */
554af28f636SEnrico Perla - Sun Microsystems 	if (write_stage2(install) != BC_SUCCESS) {
555af28f636SEnrico Perla - Sun Microsystems 		(void) fprintf(stderr, gettext("Error writing stage2 to "
556af28f636SEnrico Perla - Sun Microsystems 		    "disk\n"));
557af28f636SEnrico Perla - Sun Microsystems 		return (BC_ERROR);
558af28f636SEnrico Perla - Sun Microsystems 	}
559af28f636SEnrico Perla - Sun Microsystems 
560af28f636SEnrico Perla - Sun Microsystems 	/* Write stage1 to disk and, if requested, to the MBR. */
561af28f636SEnrico Perla - Sun Microsystems 	if (write_stage1(install) != BC_SUCCESS) {
562af28f636SEnrico Perla - Sun Microsystems 		(void) fprintf(stderr, gettext("Error writing stage1 to "
563af28f636SEnrico Perla - Sun Microsystems 		    "disk\n"));
564af28f636SEnrico Perla - Sun Microsystems 		return (BC_ERROR);
565af28f636SEnrico Perla - Sun Microsystems 	}
566af28f636SEnrico Perla - Sun Microsystems 
567af28f636SEnrico Perla - Sun Microsystems 	return (BC_SUCCESS);
568af28f636SEnrico Perla - Sun Microsystems }
569af28f636SEnrico Perla - Sun Microsystems 
570af28f636SEnrico Perla - Sun Microsystems /*
571af28f636SEnrico Perla - Sun Microsystems  * Propagate the bootblock on the source disk to the destination disk and
572af28f636SEnrico Perla - Sun Microsystems  * version it with 'updt_str' in the process. Since we cannot trust any data
573af28f636SEnrico Perla - Sun Microsystems  * on the attaching disk, we do not perform any specific check on a potential
574af28f636SEnrico Perla - Sun Microsystems  * target extended information structure and we just blindly update.
575af28f636SEnrico Perla - Sun Microsystems  */
576af28f636SEnrico Perla - Sun Microsystems static int
propagate_bootblock(ig_data_t * source,ig_data_t * target,char * updt_str)577af28f636SEnrico Perla - Sun Microsystems propagate_bootblock(ig_data_t *source, ig_data_t *target, char *updt_str)
578af28f636SEnrico Perla - Sun Microsystems {
579af28f636SEnrico Perla - Sun Microsystems 	ig_device_t	*src_device = &source->device;
580af28f636SEnrico Perla - Sun Microsystems 	ig_device_t	*dest_device = &target->device;
581af28f636SEnrico Perla - Sun Microsystems 	ig_stage2_t	*src_stage2 = &source->stage2;
582af28f636SEnrico Perla - Sun Microsystems 	ig_stage2_t	*dest_stage2 = &target->stage2;
583af28f636SEnrico Perla - Sun Microsystems 	uint32_t	buf_size;
584af28f636SEnrico Perla - Sun Microsystems 	int		retval;
585af28f636SEnrico Perla - Sun Microsystems 
586af28f636SEnrico Perla - Sun Microsystems 	assert(source != NULL);
587af28f636SEnrico Perla - Sun Microsystems 	assert(target != NULL);
588af28f636SEnrico Perla - Sun Microsystems 
589af28f636SEnrico Perla - Sun Microsystems 	/* read in stage1 from the source disk. */
590af28f636SEnrico Perla - Sun Microsystems 	if (read_stage1_from_disk(src_device->part_fd, target->stage1_buf)
591af28f636SEnrico Perla - Sun Microsystems 	    != BC_SUCCESS)
592af28f636SEnrico Perla - Sun Microsystems 		return (BC_ERROR);
593af28f636SEnrico Perla - Sun Microsystems 
594af28f636SEnrico Perla - Sun Microsystems 	/* Prepare target stage2 for commit_to_disk. */
595af28f636SEnrico Perla - Sun Microsystems 	cleanup_stage2(dest_stage2);
596af28f636SEnrico Perla - Sun Microsystems 
597af28f636SEnrico Perla - Sun Microsystems 	if (updt_str != NULL)
598af28f636SEnrico Perla - Sun Microsystems 		do_version = B_TRUE;
599af28f636SEnrico Perla - Sun Microsystems 	else
600af28f636SEnrico Perla - Sun Microsystems 		do_version = B_FALSE;
601af28f636SEnrico Perla - Sun Microsystems 
602af28f636SEnrico Perla - Sun Microsystems 	buf_size = src_stage2->file_size + SECTOR_SIZE;
603af28f636SEnrico Perla - Sun Microsystems 
604af28f636SEnrico Perla - Sun Microsystems 	dest_stage2->buf_size = P2ROUNDUP(buf_size, SECTOR_SIZE);
605af28f636SEnrico Perla - Sun Microsystems 	dest_stage2->buf = malloc(dest_stage2->buf_size);
606af28f636SEnrico Perla - Sun Microsystems 	if (dest_stage2->buf == NULL) {
607af28f636SEnrico Perla - Sun Microsystems 		perror(gettext("Memory allocation failed"));
608af28f636SEnrico Perla - Sun Microsystems 		return (BC_ERROR);
609af28f636SEnrico Perla - Sun Microsystems 	}
610af28f636SEnrico Perla - Sun Microsystems 	dest_stage2->file = dest_stage2->buf;
611af28f636SEnrico Perla - Sun Microsystems 	dest_stage2->file_size = src_stage2->file_size;
612af28f636SEnrico Perla - Sun Microsystems 	memcpy(dest_stage2->file, src_stage2->file, dest_stage2->file_size);
613af28f636SEnrico Perla - Sun Microsystems 	dest_stage2->extra = dest_stage2->buf +
614af28f636SEnrico Perla - Sun Microsystems 	    P2ROUNDUP(dest_stage2->file_size, 8);
615af28f636SEnrico Perla - Sun Microsystems 
616af28f636SEnrico Perla - Sun Microsystems 	/* If we get down here we do have a mboot structure. */
617af28f636SEnrico Perla - Sun Microsystems 	assert(src_stage2->mboot);
618af28f636SEnrico Perla - Sun Microsystems 
619af28f636SEnrico Perla - Sun Microsystems 	dest_stage2->mboot_off = src_stage2->mboot_off;
620af28f636SEnrico Perla - Sun Microsystems 	dest_stage2->mboot = (multiboot_header_t *)(dest_stage2->buf +
621af28f636SEnrico Perla - Sun Microsystems 	    dest_stage2->mboot_off);
622af28f636SEnrico Perla - Sun Microsystems 
623af28f636SEnrico Perla - Sun Microsystems 	(void) fprintf(stdout, gettext("Propagating %s stage1/stage2 to %s\n"),
624af28f636SEnrico Perla - Sun Microsystems 	    src_device->path, dest_device->path);
625af28f636SEnrico Perla - Sun Microsystems 	retval = commit_to_disk(target, updt_str);
626af28f636SEnrico Perla - Sun Microsystems 
627af28f636SEnrico Perla - Sun Microsystems 	return (retval);
628af28f636SEnrico Perla - Sun Microsystems }
629af28f636SEnrico Perla - Sun Microsystems 
630af28f636SEnrico Perla - Sun Microsystems /*
631af28f636SEnrico Perla - Sun Microsystems  * open the device and fill the various members of ig_device_t.
632af28f636SEnrico Perla - Sun Microsystems  */
633af28f636SEnrico Perla - Sun Microsystems static int
init_device(ig_device_t * device,char * path)634af28f636SEnrico Perla - Sun Microsystems init_device(ig_device_t *device, char *path)
635af28f636SEnrico Perla - Sun Microsystems {
6361a902ef8SHans Rosenfeld 	struct dk_gpt *vtoc;
6371a902ef8SHans Rosenfeld 	fstyp_handle_t fhdl;
6381a902ef8SHans Rosenfeld 	const char *fident;
6391a902ef8SHans Rosenfeld 
640af28f636SEnrico Perla - Sun Microsystems 	bzero(device, sizeof (*device));
641af28f636SEnrico Perla - Sun Microsystems 	device->part_fd = -1;
642af28f636SEnrico Perla - Sun Microsystems 	device->disk_fd = -1;
643af28f636SEnrico Perla - Sun Microsystems 	device->path_p0 = NULL;
644af28f636SEnrico Perla - Sun Microsystems 
645af28f636SEnrico Perla - Sun Microsystems 	device->path = strdup(path);
646af28f636SEnrico Perla - Sun Microsystems 	if (device->path == NULL) {
647af28f636SEnrico Perla - Sun Microsystems 		perror(gettext("Memory allocation failed"));
648af28f636SEnrico Perla - Sun Microsystems 		return (BC_ERROR);
649af28f636SEnrico Perla - Sun Microsystems 	}
650af28f636SEnrico Perla - Sun Microsystems 
651af28f636SEnrico Perla - Sun Microsystems 	if (strstr(device->path, "diskette")) {
652af28f636SEnrico Perla - Sun Microsystems 		(void) fprintf(stderr, gettext("installing GRUB to a floppy "
653af28f636SEnrico Perla - Sun Microsystems 		    "disk is no longer supported\n"));
654af28f636SEnrico Perla - Sun Microsystems 		return (BC_ERROR);
655af28f636SEnrico Perla - Sun Microsystems 	}
656af28f636SEnrico Perla - Sun Microsystems 
657af28f636SEnrico Perla - Sun Microsystems 	/* Detect if the target device is a pcfs partition. */
658af28f636SEnrico Perla - Sun Microsystems 	if (strstr(device->path, "p0:boot"))
659af28f636SEnrico Perla - Sun Microsystems 		device->type = IG_DEV_X86BOOTPAR;
660af28f636SEnrico Perla - Sun Microsystems 
661af28f636SEnrico Perla - Sun Microsystems 	if (get_disk_fd(device) != BC_SUCCESS)
662af28f636SEnrico Perla - Sun Microsystems 		return (BC_ERROR);
663af28f636SEnrico Perla - Sun Microsystems 
664af28f636SEnrico Perla - Sun Microsystems 	/* read in the device boot sector. */
665af28f636SEnrico Perla - Sun Microsystems 	if (read(device->disk_fd, device->boot_sector, SECTOR_SIZE)
666af28f636SEnrico Perla - Sun Microsystems 	    != SECTOR_SIZE) {
667af28f636SEnrico Perla - Sun Microsystems 		(void) fprintf(stderr, gettext("Error reading boot sector\n"));
668af28f636SEnrico Perla - Sun Microsystems 		perror("read");
669af28f636SEnrico Perla - Sun Microsystems 		return (BC_ERROR);
670af28f636SEnrico Perla - Sun Microsystems 	}
671af28f636SEnrico Perla - Sun Microsystems 
672cc641e8dSToomas Soome 	if (efi_alloc_and_read(device->disk_fd, &vtoc) >= 0) {
6731a902ef8SHans Rosenfeld 		device->type = IG_DEV_EFI;
6741a902ef8SHans Rosenfeld 		efi_free(vtoc);
6751a902ef8SHans Rosenfeld 	}
6761a902ef8SHans Rosenfeld 
677af28f636SEnrico Perla - Sun Microsystems 	if (get_raw_partition_fd(device) != BC_SUCCESS)
678af28f636SEnrico Perla - Sun Microsystems 		return (BC_ERROR);
679af28f636SEnrico Perla - Sun Microsystems 
6809348d232SHans Rosenfeld 	if (is_efi(device->type)) {
6819348d232SHans Rosenfeld 		if (fstyp_init(device->part_fd, 0, NULL, &fhdl) != 0)
6829348d232SHans Rosenfeld 			return (BC_ERROR);
6831a902ef8SHans Rosenfeld 
6849348d232SHans Rosenfeld 		if (