xref: /titanic_54/usr/src/cmd/fmthard/fmthard.c (revision 7c478bd95313f5f23a4c958a745db2134aa03244)
1*7c478bd9Sstevel@tonic-gate /*
2*7c478bd9Sstevel@tonic-gate  * CDDL HEADER START
3*7c478bd9Sstevel@tonic-gate  *
4*7c478bd9Sstevel@tonic-gate  * The contents of this file are subject to the terms of the
5*7c478bd9Sstevel@tonic-gate  * Common Development and Distribution License, Version 1.0 only
6*7c478bd9Sstevel@tonic-gate  * (the "License").  You may not use this file except in compliance
7*7c478bd9Sstevel@tonic-gate  * with the License.
8*7c478bd9Sstevel@tonic-gate  *
9*7c478bd9Sstevel@tonic-gate  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10*7c478bd9Sstevel@tonic-gate  * or http://www.opensolaris.org/os/licensing.
11*7c478bd9Sstevel@tonic-gate  * See the License for the specific language governing permissions
12*7c478bd9Sstevel@tonic-gate  * and limitations under the License.
13*7c478bd9Sstevel@tonic-gate  *
14*7c478bd9Sstevel@tonic-gate  * When distributing Covered Code, include this CDDL HEADER in each
15*7c478bd9Sstevel@tonic-gate  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16*7c478bd9Sstevel@tonic-gate  * If applicable, add the following below this CDDL HEADER, with the
17*7c478bd9Sstevel@tonic-gate  * fields enclosed by brackets "[]" replaced with your own identifying
18*7c478bd9Sstevel@tonic-gate  * information: Portions Copyright [yyyy] [name of copyright owner]
19*7c478bd9Sstevel@tonic-gate  *
20*7c478bd9Sstevel@tonic-gate  * CDDL HEADER END
21*7c478bd9Sstevel@tonic-gate  */
22*7c478bd9Sstevel@tonic-gate /*	Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T	*/
23*7c478bd9Sstevel@tonic-gate /*	  All Rights Reserved  	*/
24*7c478bd9Sstevel@tonic-gate 
25*7c478bd9Sstevel@tonic-gate 
26*7c478bd9Sstevel@tonic-gate /*
27*7c478bd9Sstevel@tonic-gate  *
28*7c478bd9Sstevel@tonic-gate  *	Portions of this source code were provided by International
29*7c478bd9Sstevel@tonic-gate  *	Computers Limited (ICL) under a development agreement with AT&T.
30*7c478bd9Sstevel@tonic-gate  */
31*7c478bd9Sstevel@tonic-gate 
32*7c478bd9Sstevel@tonic-gate #pragma ident	"%Z%%M%	%I%	%E% SMI"
33*7c478bd9Sstevel@tonic-gate 
34*7c478bd9Sstevel@tonic-gate /*
35*7c478bd9Sstevel@tonic-gate  * Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
36*7c478bd9Sstevel@tonic-gate  * Use is subject to license terms.
37*7c478bd9Sstevel@tonic-gate  */
38*7c478bd9Sstevel@tonic-gate 
39*7c478bd9Sstevel@tonic-gate /*
40*7c478bd9Sstevel@tonic-gate  * Sun Microsystems version of fmthard:
41*7c478bd9Sstevel@tonic-gate  *
42*7c478bd9Sstevel@tonic-gate  * Supports the following arguments:
43*7c478bd9Sstevel@tonic-gate  *
44*7c478bd9Sstevel@tonic-gate  *	-i		Writes VTOC to stdout, rather than disk
45*7c478bd9Sstevel@tonic-gate  *	-q		Quick check: exit code 0 if VTOC ok
46*7c478bd9Sstevel@tonic-gate  *	-d <data>	Incremental changes to the VTOC
47*7c478bd9Sstevel@tonic-gate  *	-n <vname>	Change volume name to <vname>
48*7c478bd9Sstevel@tonic-gate  *	-s <file>	Read VTOC information from <file>, or stdin ("-")
49*7c478bd9Sstevel@tonic-gate  *	-u <state>	Reboot after writing VTOC, according to <state>:
50*7c478bd9Sstevel@tonic-gate  *				boot: AD_BOOT (standard reboot)
51*7c478bd9Sstevel@tonic-gate  *				firm: AD_IBOOT (interactive reboot)
52*7c478bd9Sstevel@tonic-gate  *
53*7c478bd9Sstevel@tonic-gate  * Note that fmthard cannot write a VTOC on an unlabeled disk.
54*7c478bd9Sstevel@tonic-gate  * You must use format or SunInstall for this purpose.
55*7c478bd9Sstevel@tonic-gate  * (NOTE: the above restriction only applies on Sparc systems).
56*7c478bd9Sstevel@tonic-gate  *
57*7c478bd9Sstevel@tonic-gate  * The primary motivation for fmthard is to duplicate the
58*7c478bd9Sstevel@tonic-gate  * partitioning from disk to disk:
59*7c478bd9Sstevel@tonic-gate  *
60*7c478bd9Sstevel@tonic-gate  *	prtvtoc /dev/rdsk/c0t0d0s2 | fmthard -s - /dev/rdsk/c0t1d0s2
61*7c478bd9Sstevel@tonic-gate  */
62*7c478bd9Sstevel@tonic-gate 
63*7c478bd9Sstevel@tonic-gate #include <stdio.h>
64*7c478bd9Sstevel@tonic-gate #include <fcntl.h>
65*7c478bd9Sstevel@tonic-gate #include <errno.h>
66*7c478bd9Sstevel@tonic-gate #include <string.h>
67*7c478bd9Sstevel@tonic-gate #include <stdlib.h>
68*7c478bd9Sstevel@tonic-gate #include <unistd.h>
69*7c478bd9Sstevel@tonic-gate #include <sys/types.h>
70*7c478bd9Sstevel@tonic-gate #include <sys/param.h>
71*7c478bd9Sstevel@tonic-gate #include <sys/stat.h>
72*7c478bd9Sstevel@tonic-gate #include <sys/uadmin.h>
73*7c478bd9Sstevel@tonic-gate #include <sys/open.h>
74*7c478bd9Sstevel@tonic-gate #include <sys/vtoc.h>
75*7c478bd9Sstevel@tonic-gate #include <sys/dkio.h>
76*7c478bd9Sstevel@tonic-gate #include <sys/isa_defs.h>
77*7c478bd9Sstevel@tonic-gate #include <sys/efi_partition.h>
78*7c478bd9Sstevel@tonic-gate 
79*7c478bd9Sstevel@tonic-gate #if defined(_SUNOS_VTOC_16)
80*7c478bd9Sstevel@tonic-gate #include <sys/dklabel.h>
81*7c478bd9Sstevel@tonic-gate #endif
82*7c478bd9Sstevel@tonic-gate 
83*7c478bd9Sstevel@tonic-gate #include <sys/sysmacros.h>
84*7c478bd9Sstevel@tonic-gate 
85*7c478bd9Sstevel@tonic-gate #ifndef	SECSIZE
86*7c478bd9Sstevel@tonic-gate #define	SECSIZE			DEV_BSIZE
87*7c478bd9Sstevel@tonic-gate #endif	/* SECSIZE */
88*7c478bd9Sstevel@tonic-gate 
89*7c478bd9Sstevel@tonic-gate 
90*7c478bd9Sstevel@tonic-gate /*
91*7c478bd9Sstevel@tonic-gate  * External functions.
92*7c478bd9Sstevel@tonic-gate  */
93*7c478bd9Sstevel@tonic-gate extern	int	read_vtoc(int, struct vtoc *);
94*7c478bd9Sstevel@tonic-gate extern	int	write_vtoc(int, struct vtoc *);
95*7c478bd9Sstevel@tonic-gate 
96*7c478bd9Sstevel@tonic-gate /*
97*7c478bd9Sstevel@tonic-gate  * Externals
98*7c478bd9Sstevel@tonic-gate  */
99*7c478bd9Sstevel@tonic-gate extern	char	*optarg;
100*7c478bd9Sstevel@tonic-gate extern	int	optind;
101*7c478bd9Sstevel@tonic-gate extern	int	errno;
102*7c478bd9Sstevel@tonic-gate extern	char	*sys_errlist[];
103*7c478bd9Sstevel@tonic-gate 
104*7c478bd9Sstevel@tonic-gate /*
105*7c478bd9Sstevel@tonic-gate  * Internal functions.
106*7c478bd9Sstevel@tonic-gate  */
107*7c478bd9Sstevel@tonic-gate extern	int	main(int, char **);
108*7c478bd9Sstevel@tonic-gate static	void	display(struct dk_geom *, struct vtoc *, char *);
109*7c478bd9Sstevel@tonic-gate static	void	display64(struct dk_gpt *,  char *);
110*7c478bd9Sstevel@tonic-gate static	void	insert(char *, struct vtoc *);
111*7c478bd9Sstevel@tonic-gate static	void	insert64(char *, struct dk_gpt *);
112*7c478bd9Sstevel@tonic-gate static	void	load(FILE *, struct dk_geom *, struct vtoc *);
113*7c478bd9Sstevel@tonic-gate static	void	load64(FILE *, int fd, struct dk_gpt **);
114*7c478bd9Sstevel@tonic-gate static	void	usage(void);
115*7c478bd9Sstevel@tonic-gate static	void	validate(struct dk_geom *, struct vtoc *);
116*7c478bd9Sstevel@tonic-gate static	void	validate64(struct dk_gpt *);
117*7c478bd9Sstevel@tonic-gate static	int	vread(int, struct vtoc *, char *);
118*7c478bd9Sstevel@tonic-gate static	void	vread64(int, struct dk_gpt **, char *);
119*7c478bd9Sstevel@tonic-gate static	void	vwrite(int, struct vtoc *, char *);
120*7c478bd9Sstevel@tonic-gate static	void	vwrite64(int, struct dk_gpt *, char *);
121*7c478bd9Sstevel@tonic-gate 
122*7c478bd9Sstevel@tonic-gate /*
123*7c478bd9Sstevel@tonic-gate  * Static variables.
124*7c478bd9Sstevel@tonic-gate  */
125*7c478bd9Sstevel@tonic-gate static char	*delta;		/* Incremental update */
126*7c478bd9Sstevel@tonic-gate static short	eflag;		/* force write of an EFI label */
127*7c478bd9Sstevel@tonic-gate static short	iflag;		/* Prints VTOC w/o updating */
128*7c478bd9Sstevel@tonic-gate static short	qflag;		/* Check for a formatted disk */
129*7c478bd9Sstevel@tonic-gate static short	uflag;		/* Exit to firmware after writing  */
130*7c478bd9Sstevel@tonic-gate 				/* new vtoc and reboot. Used during */
131*7c478bd9Sstevel@tonic-gate 				/* installation of core floppies */
132*7c478bd9Sstevel@tonic-gate static diskaddr_t	lastlba = 0;	/* last LBA on 64-bit VTOC */
133*7c478bd9Sstevel@tonic-gate 
134*7c478bd9Sstevel@tonic-gate #if defined(sparc)
135*7c478bd9Sstevel@tonic-gate static char	*uboot = "boot";
136*7c478bd9Sstevel@tonic-gate 
137*7c478bd9Sstevel@tonic-gate #elif defined(i386)
138*7c478bd9Sstevel@tonic-gate /* use installgrub(1M) to install boot blocks */
139*7c478bd9Sstevel@tonic-gate static char *uboot = "";
140*7c478bd9Sstevel@tonic-gate #else
141*7c478bd9Sstevel@tonic-gate #error No platform defined.
142*7c478bd9Sstevel@tonic-gate #endif	/* various platform-specific definitions */
143*7c478bd9Sstevel@tonic-gate 
144*7c478bd9Sstevel@tonic-gate static char	*ufirm = "firm";
145*7c478bd9Sstevel@tonic-gate #if defined(_SUNOS_VTOC_16)
146*7c478bd9Sstevel@tonic-gate static int		sectsiz;
147*7c478bd9Sstevel@tonic-gate static struct vtoc	disk_vtoc;
148*7c478bd9Sstevel@tonic-gate #endif	/* defined(_SUNOS_VTOC_16) */
149*7c478bd9Sstevel@tonic-gate 
150*7c478bd9Sstevel@tonic-gate int
151*7c478bd9Sstevel@tonic-gate main(int argc, char **argv)
152*7c478bd9Sstevel@tonic-gate {
153*7c478bd9Sstevel@tonic-gate 	int		fd;
154*7c478bd9Sstevel@tonic-gate 	int		c;
155*7c478bd9Sstevel@tonic-gate 	char		*dfile;
156*7c478bd9Sstevel@tonic-gate 	char		*vname;
157*7c478bd9Sstevel@tonic-gate 	struct stat	statbuf;
158*7c478bd9Sstevel@tonic-gate #if defined(_SUNOS_VTOC_8)
159*7c478bd9Sstevel@tonic-gate 	struct vtoc	disk_vtoc;
160*7c478bd9Sstevel@tonic-gate #endif	/* defined(_SUNOS_VTOC_8) */
161*7c478bd9Sstevel@tonic-gate 	struct dk_gpt	*disk_efi;
162*7c478bd9Sstevel@tonic-gate 	struct dk_geom	disk_geom;
163*7c478bd9Sstevel@tonic-gate 	int		n;
164*7c478bd9Sstevel@tonic-gate 
165*7c478bd9Sstevel@tonic-gate 
166*7c478bd9Sstevel@tonic-gate 	dfile = NULL;
167*7c478bd9Sstevel@tonic-gate 	vname = NULL;
168*7c478bd9Sstevel@tonic-gate #if defined(sparc)
169*7c478bd9Sstevel@tonic-gate 	while ((c = getopt(argc, argv, "ed:u:in:qs:")) != EOF)
170*7c478bd9Sstevel@tonic-gate 
171*7c478bd9Sstevel@tonic-gate #elif defined(i386)
172*7c478bd9Sstevel@tonic-gate 	while ((c = getopt(argc, argv, "ed:u:in:qb:p:s:")) != EOF)
173*7c478bd9Sstevel@tonic-gate 
174*7c478bd9Sstevel@tonic-gate #else
175*7c478bd9Sstevel@tonic-gate #error No platform defined.
176*7c478bd9Sstevel@tonic-gate #endif
177*7c478bd9Sstevel@tonic-gate 		switch (c) {
178*7c478bd9Sstevel@tonic-gate #if defined(i386)
179*7c478bd9Sstevel@tonic-gate 		case 'p':
180*7c478bd9Sstevel@tonic-gate 		case 'b':
181*7c478bd9Sstevel@tonic-gate 			(void) fprintf(stderr,
182*7c478bd9Sstevel@tonic-gate 			    "fmthard: -p and -b no longer supported."
183*7c478bd9Sstevel@tonic-gate 			    " Use installgrub(1M) to install boot blocks\n");
184*7c478bd9Sstevel@tonic-gate 			break;
185*7c478bd9Sstevel@tonic-gate #endif	/* defined(i386) */
186*7c478bd9Sstevel@tonic-gate 
187*7c478bd9Sstevel@tonic-gate 		case 'd':
188*7c478bd9Sstevel@tonic-gate 			delta = optarg;
189*7c478bd9Sstevel@tonic-gate 			break;
190*7c478bd9Sstevel@tonic-gate 		case 'e':
191*7c478bd9Sstevel@tonic-gate 			++eflag;
192*7c478bd9Sstevel@tonic-gate 			break;
193*7c478bd9Sstevel@tonic-gate 		case 'i':
194*7c478bd9Sstevel@tonic-gate 			++iflag;
195*7c478bd9Sstevel@tonic-gate 			break;
196*7c478bd9Sstevel@tonic-gate 		case 'n':
197*7c478bd9Sstevel@tonic-gate 			vname = optarg;
198*7c478bd9Sstevel@tonic-gate 			break;
199*7c478bd9Sstevel@tonic-gate 		case 'q':
200*7c478bd9Sstevel@tonic-gate 			++qflag;
201*7c478bd9Sstevel@tonic-gate 			break;
202*7c478bd9Sstevel@tonic-gate 		case 's':
203*7c478bd9Sstevel@tonic-gate 			dfile = optarg;
204*7c478bd9Sstevel@tonic-gate 			break;
205*7c478bd9Sstevel@tonic-gate 		case 'u':
206*7c478bd9Sstevel@tonic-gate 			if (strcmp(uboot, optarg) == 0)
207*7c478bd9Sstevel@tonic-gate 				++uflag;
208*7c478bd9Sstevel@tonic-gate 			else if (strcmp(ufirm, optarg) == 0)
209*7c478bd9Sstevel@tonic-gate 				uflag = 2;
210*7c478bd9Sstevel@tonic-gate 
211*7c478bd9Sstevel@tonic-gate 			break;
212*7c478bd9Sstevel@tonic-gate 		default:
213*7c478bd9Sstevel@tonic-gate 			usage();
214*7c478bd9Sstevel@tonic-gate 		}
215*7c478bd9Sstevel@tonic-gate 
216*7c478bd9Sstevel@tonic-gate 
217*7c478bd9Sstevel@tonic-gate 	if (argc - optind != 1)
218*7c478bd9Sstevel@tonic-gate 		usage();
219*7c478bd9Sstevel@tonic-gate 
220*7c478bd9Sstevel@tonic-gate 	if (stat(argv[optind], (struct stat *)&statbuf) == -1) {
221*7c478bd9Sstevel@tonic-gate 		(void) fprintf(stderr,
222*7c478bd9Sstevel@tonic-gate 			"fmthard:  Cannot stat device %s\n",
223*7c478bd9Sstevel@tonic-gate 			argv[optind]);
224*7c478bd9Sstevel@tonic-gate 		exit(1);
225*7c478bd9Sstevel@tonic-gate 	}
226*7c478bd9Sstevel@tonic-gate 
227*7c478bd9Sstevel@tonic-gate 	if ((statbuf.st_mode & S_IFMT) != S_IFCHR) {
228*7c478bd9Sstevel@tonic-gate 		(void) fprintf(stderr,
229*7c478bd9Sstevel@tonic-gate 			"fmthard:  %s must be a raw device.\n",
230*7c478bd9Sstevel@tonic-gate 			argv[optind]);
231*7c478bd9Sstevel@tonic-gate 		exit(1);
232*7c478bd9Sstevel@tonic-gate 	}
233*7c478bd9Sstevel@tonic-gate 
234*7c478bd9Sstevel@tonic-gate 	if ((fd = open(argv[optind], O_RDWR|O_NDELAY)) < 0) {
235*7c478bd9Sstevel@tonic-gate 		(void) fprintf(stderr, "fmthard:  Cannot open device %s - %s\n",
236*7c478bd9Sstevel@tonic-gate 			argv[optind], sys_errlist[errno]);
237*7c478bd9Sstevel@tonic-gate 		exit(1);
238*7c478bd9Sstevel@tonic-gate 	}
239*7c478bd9Sstevel@tonic-gate 
240*7c478bd9Sstevel@tonic-gate 	/*
241*7c478bd9Sstevel@tonic-gate 	 * Get the geometry information for this disk from the driver
242*7c478bd9Sstevel@tonic-gate 	 */
243*7c478bd9Sstevel@tonic-gate 	if (!eflag && ioctl(fd, DKIOCGGEOM, &disk_geom)) {
244*7c478bd9Sstevel@tonic-gate #ifdef DEBUG
245*7c478bd9Sstevel@tonic-gate 		perror("DKIOCGGEOM failed");
246*7c478bd9Sstevel@tonic-gate #endif /* DEBUG */
247*7c478bd9Sstevel@tonic-gate 		if (errno == ENOTSUP) {
248*7c478bd9Sstevel@tonic-gate 			/* disk has EFI labels */
249*7c478bd9Sstevel@tonic-gate 			eflag++;
250*7c478bd9Sstevel@tonic-gate 		} else {
251*7c478bd9Sstevel@tonic-gate 			(void) fprintf(stderr,
252*7c478bd9Sstevel@tonic-gate 				"%s: Cannot get disk geometry\n", argv[optind]);
253*7c478bd9Sstevel@tonic-gate 			(void) close(fd);
254*7c478bd9Sstevel@tonic-gate 			exit(1);
255*7c478bd9Sstevel@tonic-gate 		}
256*7c478bd9Sstevel@tonic-gate 	}
257*7c478bd9Sstevel@tonic-gate 
258*7c478bd9Sstevel@tonic-gate 	/*
259*7c478bd9Sstevel@tonic-gate 	 * Read the vtoc on the disk
260*7c478bd9Sstevel@tonic-gate 	 */
261*7c478bd9Sstevel@tonic-gate 	if (!eflag) {
262*7c478bd9Sstevel@tonic-gate 		if (vread(fd, &disk_vtoc, argv[optind]) == 1)
263*7c478bd9Sstevel@tonic-gate 			eflag++;
264*7c478bd9Sstevel@tonic-gate 	}
265*7c478bd9Sstevel@tonic-gate 	if (eflag && (dfile == NULL)) {
266*7c478bd9Sstevel@tonic-gate 		vread64(fd, &disk_efi, argv[optind]);
267*7c478bd9Sstevel@tonic-gate 	}
268*7c478bd9Sstevel@tonic-gate 
269*7c478bd9Sstevel@tonic-gate 	/*
270*7c478bd9Sstevel@tonic-gate 	 * Quick check for valid disk: 0 if ok, 1 if not
271*7c478bd9Sstevel@tonic-gate 	 */
272*7c478bd9Sstevel@tonic-gate 	if (qflag) {
273*7c478bd9Sstevel@tonic-gate 		(void) close(fd);
274*7c478bd9Sstevel@tonic-gate 		if (!eflag) {
275*7c478bd9Sstevel@tonic-gate 			exit(disk_vtoc.v_sanity == VTOC_SANE ? 0 : 1);
276*7c478bd9Sstevel@tonic-gate 		} else {
277*7c478bd9Sstevel@tonic-gate 			exit(disk_efi->efi_version <= EFI_VERSION102 ? 0 : 1);
278*7c478bd9Sstevel@tonic-gate 		}
279*7c478bd9Sstevel@tonic-gate 	}
280*7c478bd9Sstevel@tonic-gate 
281*7c478bd9Sstevel@tonic-gate 	/*
282*7c478bd9Sstevel@tonic-gate 	 * Incremental changes to the VTOC
283*7c478bd9Sstevel@tonic-gate 	 */
284*7c478bd9Sstevel@tonic-gate 	if (delta) {
285*7c478bd9Sstevel@tonic-gate 		if (!eflag) {
286*7c478bd9Sstevel@tonic-gate 			insert(delta, &disk_vtoc);
287*7c478bd9Sstevel@tonic-gate 			validate(&disk_geom, &disk_vtoc);
288*7c478bd9Sstevel@tonic-gate 			vwrite(fd, &disk_vtoc, argv[optind]);
289*7c478bd9Sstevel@tonic-gate 		} else {
290*7c478bd9Sstevel@tonic-gate 			insert64(delta, disk_efi);
291*7c478bd9Sstevel@tonic-gate 			validate64(disk_efi);
292*7c478bd9Sstevel@tonic-gate 			vwrite64(fd, disk_efi, argv[optind]);
293*7c478bd9Sstevel@tonic-gate 		}
294*7c478bd9Sstevel@tonic-gate 		(void) close(fd);
295*7c478bd9Sstevel@tonic-gate 		exit(0);
296*7c478bd9Sstevel@tonic-gate 	}
297*7c478bd9Sstevel@tonic-gate 
298*7c478bd9Sstevel@tonic-gate 	if (!dfile && !vname)
299*7c478bd9Sstevel@tonic-gate 		usage();
300*7c478bd9Sstevel@tonic-gate 
301*7c478bd9Sstevel@tonic-gate 	/*
302*7c478bd9Sstevel@tonic-gate 	 * Read new VTOC from stdin or data file
303*7c478bd9Sstevel@tonic-gate 	 */
304*7c478bd9Sstevel@tonic-gate 	if (dfile) {
305*7c478bd9Sstevel@tonic-gate 		if (strcmp(dfile, "-") == 0) {
306*7c478bd9Sstevel@tonic-gate 			if (!eflag)
307*7c478bd9Sstevel@tonic-gate 				load(stdin, &disk_geom, &disk_vtoc);
308*7c478bd9Sstevel@tonic-gate 			else
309*7c478bd9Sstevel@tonic-gate 				load64(stdin, fd, &disk_efi);
310*7c478bd9Sstevel@tonic-gate 		} else {
311*7c478bd9Sstevel@tonic-gate 			FILE *fp;
312*7c478bd9Sstevel@tonic-gate 			if ((fp = fopen(dfile, "r")) == NULL) {
313*7c478bd9Sstevel@tonic-gate 				(void) fprintf(stderr, "Cannot open file %s\n",
314*7c478bd9Sstevel@tonic-gate 					dfile);
315*7c478bd9Sstevel@tonic-gate 				(void) close(fd);
316*7c478bd9Sstevel@tonic-gate 				exit(1);
317*7c478bd9Sstevel@tonic-gate 			}
318*7c478bd9Sstevel@tonic-gate 			if (!eflag)
319*7c478bd9Sstevel@tonic-gate 				load(fp, &disk_geom, &disk_vtoc);
320*7c478bd9Sstevel@tonic-gate 			else
321*7c478bd9Sstevel@tonic-gate 				load64(fp, fd, &disk_efi);
322*7c478bd9Sstevel@tonic-gate 			(void) fclose(fp);
323*7c478bd9Sstevel@tonic-gate 		}
324*7c478bd9Sstevel@tonic-gate 	}
325*7c478bd9Sstevel@tonic-gate 
326*7c478bd9Sstevel@tonic-gate 
327*7c478bd9Sstevel@tonic-gate 	/*
328*7c478bd9Sstevel@tonic-gate 	 * Print the modified VTOC, rather than updating the disk
329*7c478bd9Sstevel@tonic-gate 	 */
330*7c478bd9Sstevel@tonic-gate 	if (iflag) {
331*7c478bd9Sstevel@tonic-gate 		if (!eflag)
332*7c478bd9Sstevel@tonic-gate 			display(&disk_geom, &disk_vtoc, argv[optind]);
333*7c478bd9Sstevel@tonic-gate 		else
334*7c478bd9Sstevel@tonic-gate 			display64(disk_efi, argv[optind]);
335*7c478bd9Sstevel@tonic-gate 		(void) close(fd);
336*7c478bd9Sstevel@tonic-gate 		exit(0);
337*7c478bd9Sstevel@tonic-gate 	}
338*7c478bd9Sstevel@tonic-gate 
339*7c478bd9Sstevel@tonic-gate 	if (vname) {
340*7c478bd9Sstevel@tonic-gate 		n = MIN(strlen(vname) + 1, LEN_DKL_VVOL);
341*7c478bd9Sstevel@tonic-gate 		if (!eflag) {
342*7c478bd9Sstevel@tonic-gate 			(void) memcpy(disk_vtoc.v_volume, vname, n);
343*7c478bd9Sstevel@tonic-gate 		} else {
344*7c478bd9Sstevel@tonic-gate 			for (c = 0; c < disk_efi->efi_nparts; c++) {
345*7c478bd9Sstevel@tonic-gate 			    if (disk_efi->efi_parts[c].p_tag ==
346*7c478bd9Sstevel@tonic-gate 				    V_RESERVED) {
347*7c478bd9Sstevel@tonic-gate 				(void) memcpy(&disk_efi->efi_parts[c].p_name,
348*7c478bd9Sstevel@tonic-gate 					    vname, n);
349*7c478bd9Sstevel@tonic-gate 				}
350*7c478bd9Sstevel@tonic-gate 			}
351*7c478bd9Sstevel@tonic-gate 		}
352*7c478bd9Sstevel@tonic-gate 
353*7c478bd9Sstevel@tonic-gate 	}
354*7c478bd9Sstevel@tonic-gate 	/*
355*7c478bd9Sstevel@tonic-gate 	 * Write the new VTOC on the disk
356*7c478bd9Sstevel@tonic-gate 	 */
357*7c478bd9Sstevel@tonic-gate 	if (!eflag) {
358*7c478bd9Sstevel@tonic-gate 		validate(&disk_geom, &disk_vtoc);
359*7c478bd9Sstevel@tonic-gate 		vwrite(fd, &disk_vtoc, argv[optind]);
360*7c478bd9Sstevel@tonic-gate 	} else {
361*7c478bd9Sstevel@tonic-gate 		validate64(disk_efi);
362*7c478bd9Sstevel@tonic-gate 		vwrite64(fd, disk_efi, argv[optind]);
363*7c478bd9Sstevel@tonic-gate 	}
364*7c478bd9Sstevel@tonic-gate 
365*7c478bd9Sstevel@tonic-gate 	/*
366*7c478bd9Sstevel@tonic-gate 	 * Shut system down after writing a new vtoc to disk
367*7c478bd9Sstevel@tonic-gate 	 * This is used during installation of core floppies.
368*7c478bd9Sstevel@tonic-gate 	 */
369*7c478bd9Sstevel@tonic-gate 	if (uflag == 1)
370*7c478bd9Sstevel@tonic-gate 		uadmin(A_REBOOT, AD_BOOT, 0);
371*7c478bd9Sstevel@tonic-gate 	else if (uflag == 2)
372*7c478bd9Sstevel@tonic-gate 		uadmin(A_REBOOT, AD_IBOOT, 0);
373*7c478bd9Sstevel@tonic-gate 
374*7c478bd9Sstevel@tonic-gate 	(void) printf("fmthard:  New volume table of contents now in place.\n");
375*7c478bd9Sstevel@tonic-gate 
376*7c478bd9Sstevel@tonic-gate 	return (0);
377*7c478bd9Sstevel@tonic-gate 	/*NOTREACHED*/
378*7c478bd9Sstevel@tonic-gate }
379*7c478bd9Sstevel@tonic-gate 
380*7c478bd9Sstevel@tonic-gate 
381*7c478bd9Sstevel@tonic-gate 
382*7c478bd9Sstevel@tonic-gate /*
383*7c478bd9Sstevel@tonic-gate  * display ()
384*7c478bd9Sstevel@tonic-gate  *
385*7c478bd9Sstevel@tonic-gate  * display contents of VTOC without writing it to disk
386*7c478bd9Sstevel@tonic-gate  */
387*7c478bd9Sstevel@tonic-gate static void
388*7c478bd9Sstevel@tonic-gate display(struct dk_geom *geom, struct vtoc *vtoc, char *device)
389*7c478bd9Sstevel@tonic-gate {
390*7c478bd9Sstevel@tonic-gate 	int	i;
391*7c478bd9Sstevel@tonic-gate 	int	c;
392*7c478bd9Sstevel@tonic-gate 
393*7c478bd9Sstevel@tonic-gate 	/*
394*7c478bd9Sstevel@tonic-gate 	 * Print out the VTOC
395*7c478bd9Sstevel@tonic-gate 	 */
396*7c478bd9Sstevel@tonic-gate 	(void) printf("* %s default partition map\n", device);
397*7c478bd9Sstevel@tonic-gate 	if (*vtoc->v_volume) {
398*7c478bd9Sstevel@tonic-gate 		(void) printf("* Volume Name:  ");
399*7c478bd9Sstevel@tonic-gate 		for (i = 0; i < LEN_DKL_VVOL; i++) {
400*7c478bd9Sstevel@tonic-gate 			if ((c = vtoc->v_volume[i]) == 0)
401*7c478bd9Sstevel@tonic-gate 				break;
402*7c478bd9Sstevel@tonic-gate 			(void) printf("%c", c);
403*7c478bd9Sstevel@tonic-gate 		}
404*7c478bd9Sstevel@tonic-gate 		(void) printf("\n");
405*7c478bd9Sstevel@tonic-gate 	}
406*7c478bd9Sstevel@tonic-gate 	(void) printf("*\n");
407*7c478bd9Sstevel@tonic-gate 	(void) printf("* Dimensions:\n");
408*7c478bd9Sstevel@tonic-gate 	(void) printf("*     %d bytes/sector\n", SECSIZE);
409*7c478bd9Sstevel@tonic-gate 	(void) printf("*      %d sectors/track\n", geom->dkg_nsect);
410*7c478bd9Sstevel@tonic-gate 	(void) printf("*       %d tracks/cylinder\n", geom->dkg_nhead);
411*7c478bd9Sstevel@tonic-gate 	(void) printf("*     %d cylinders\n", geom->dkg_pcyl);
412*7c478bd9Sstevel@tonic-gate 	(void) printf("*     %d accessible cylinders\n", geom->dkg_ncyl);
413*7c478bd9Sstevel@tonic-gate 	(void) printf("*\n");
414*7c478bd9Sstevel@tonic-gate 	(void) printf("* Flags:\n");
415*7c478bd9Sstevel@tonic-gate 	(void) printf("*   1:  unmountable\n");
416*7c478bd9Sstevel@tonic-gate 	(void) printf("*  10:  read-only\n");
417*7c478bd9Sstevel@tonic-gate 	(void) printf("*\n");
418*7c478bd9Sstevel@tonic-gate 	(void) printf(
419*7c478bd9Sstevel@tonic-gate "\n* Partition    Tag     Flag	    First Sector    Sector Count\n");
420*7c478bd9Sstevel@tonic-gate 	for (i = 0; i < V_NUMPAR; i++) {
421*7c478bd9Sstevel@tonic-gate 		if (vtoc->v_part[i].p_size > 0)
422*7c478bd9Sstevel@tonic-gate 			(void) printf(
423*7c478bd9Sstevel@tonic-gate "    %d		%d	0%x		%ld		%ld\n",
424*7c478bd9Sstevel@tonic-gate 				i, vtoc->v_part[i].p_tag,
425*7c478bd9Sstevel@tonic-gate 				vtoc->v_part[i].p_flag,
426*7c478bd9Sstevel@tonic-gate 				vtoc->v_part[i].p_start,
427*7c478bd9Sstevel@tonic-gate 				vtoc->v_part[i].p_size);
428*7c478bd9Sstevel@tonic-gate 	}
429*7c478bd9Sstevel@tonic-gate 	exit(0);
430*7c478bd9Sstevel@tonic-gate }
431*7c478bd9Sstevel@tonic-gate 
432*7c478bd9Sstevel@tonic-gate /*
433*7c478bd9Sstevel@tonic-gate  * display64 ()
434*7c478bd9Sstevel@tonic-gate  *
435*7c478bd9Sstevel@tonic-gate  * display64 contents of EFI partition without writing it to disk
436*7c478bd9Sstevel@tonic-gate  */
437*7c478bd9Sstevel@tonic-gate static void
438*7c478bd9Sstevel@tonic-gate display64(struct dk_gpt *efi, char *device)
439*7c478bd9Sstevel@tonic-gate {
440*7c478bd9Sstevel@tonic-gate 	int	i;
441*7c478bd9Sstevel@tonic-gate 
442*7c478bd9Sstevel@tonic-gate 	/*
443*7c478bd9Sstevel@tonic-gate 	 * Print out the VTOC
444*7c478bd9Sstevel@tonic-gate 	 */
445*7c478bd9Sstevel@tonic-gate 	(void) printf("* %s default partition map\n", device);
446*7c478bd9Sstevel@tonic-gate 	(void) printf("*\n");
447*7c478bd9Sstevel@tonic-gate 	(void) printf("* Dimensions:\n");
448*7c478bd9Sstevel@tonic-gate 	(void) printf("*     %d bytes/sector\n", efi->efi_lbasize);
449*7c478bd9Sstevel@tonic-gate 	(void) printf("*     N/A sectors/track\n");
450*7c478bd9Sstevel@tonic-gate 	(void) printf("*     N/A tracks/cylinder\n");
451*7c478bd9Sstevel@tonic-gate 	(void) printf("*     N/A cylinders\n");
452*7c478bd9Sstevel@tonic-gate 	(void) printf("*     N/A accessible cylinders\n");
453*7c478bd9Sstevel@tonic-gate 	(void) printf("*\n");
454*7c478bd9Sstevel@tonic-gate 	(void) printf("* Flags:\n");
455*7c478bd9Sstevel@tonic-gate 	(void) printf("*   1:  unmountable\n");
456*7c478bd9Sstevel@tonic-gate 	(void) printf("*  10:  read-only\n");
457*7c478bd9Sstevel@tonic-gate 	(void) printf("*\n");
458*7c478bd9Sstevel@tonic-gate 	(void) printf(
459*7c478bd9Sstevel@tonic-gate "\n* Partition    Tag     Flag	    First Sector    Sector Count\n");
460*7c478bd9Sstevel@tonic-gate 	for (i = 0; i < efi->efi_nparts; i++) {
461*7c478bd9Sstevel@tonic-gate 		if (efi->efi_parts[i].p_size > 0)
462*7c478bd9Sstevel@tonic-gate 			(void) printf(
463*7c478bd9Sstevel@tonic-gate "    %d		%d	0%x		%8lld	%8lld\n",
464*7c478bd9Sstevel@tonic-gate 				i, efi->efi_parts[i].p_tag,
465*7c478bd9Sstevel@tonic-gate 				efi->efi_parts[i].p_flag,
466*7c478bd9Sstevel@tonic-gate 				efi->efi_parts[i].p_start,
467*7c478bd9Sstevel@tonic-gate 				efi->efi_parts[i].p_size);
468*7c478bd9Sstevel@tonic-gate 	}
469*7c478bd9Sstevel@tonic-gate 	exit(0);
470*7c478bd9Sstevel@tonic-gate }
471*7c478bd9Sstevel@tonic-gate 
472*7c478bd9Sstevel@tonic-gate 
473*7c478bd9Sstevel@tonic-gate /*
474*7c478bd9Sstevel@tonic-gate  * insert()
475*7c478bd9Sstevel@tonic-gate  *
476*7c478bd9Sstevel@tonic-gate  * Insert a change into the VTOC.
477*7c478bd9Sstevel@tonic-gate  */
478*7c478bd9Sstevel@tonic-gate static void
479*7c478bd9Sstevel@tonic-gate insert(char *data, struct vtoc *vtoc)
480*7c478bd9Sstevel@tonic-gate {
481*7c478bd9Sstevel@tonic-gate 	int	part;
482*7c478bd9Sstevel@tonic-gate 	int	tag;
483*7c478bd9Sstevel@tonic-gate 	uint_t	flag;
484*7c478bd9Sstevel@tonic-gate 	daddr_t	start;
485*7c478bd9Sstevel@tonic-gate 	long	size;
486*7c478bd9Sstevel@tonic-gate 
487*7c478bd9Sstevel@tonic-gate 	if (sscanf(data, "%d:%d:%x:%ld:%ld",
488*7c478bd9Sstevel@tonic-gate 	    &part, &tag, &flag, &start, &size) != 5) {
489*7c478bd9Sstevel@tonic-gate 		(void) fprintf(stderr, "Delta syntax error on \"%s\"\n", data);
490*7c478bd9Sstevel@tonic-gate 		exit(1);
491*7c478bd9Sstevel@tonic-gate 	}
492*7c478bd9Sstevel@tonic-gate 	if (part >= V_NUMPAR) {
493*7c478bd9Sstevel@tonic-gate 		(void) fprintf(stderr,
494*7c478bd9Sstevel@tonic-gate 			"Error in data \"%s\": No such partition %x\n",
495*7c478bd9Sstevel@tonic-gate 			data, part);
496*7c478bd9Sstevel@tonic-gate 		exit(1);
497*7c478bd9Sstevel@tonic-gate 	}
498*7c478bd9Sstevel@tonic-gate 	vtoc->v_part[part].p_tag = (ushort_t)tag;
499*7c478bd9Sstevel@tonic-gate 	vtoc->v_part[part].p_flag = (ushort_t)flag;
500*7c478bd9Sstevel@tonic-gate 	vtoc->v_part[part].p_start = start;
501*7c478bd9Sstevel@tonic-gate 	vtoc->v_part[part].p_size = size;
502*7c478bd9Sstevel@tonic-gate }
503*7c478bd9Sstevel@tonic-gate 
504*7c478bd9Sstevel@tonic-gate /*
505*7c478bd9Sstevel@tonic-gate  * insert64()
506*7c478bd9Sstevel@tonic-gate  *
507*7c478bd9Sstevel@tonic-gate  * Insert a change into the VTOC.
508*7c478bd9Sstevel@tonic-gate  */
509*7c478bd9Sstevel@tonic-gate static void
510*7c478bd9Sstevel@tonic-gate insert64(char *data, struct dk_gpt *efi)
511*7c478bd9Sstevel@tonic-gate {
512*7c478bd9Sstevel@tonic-gate 	int		part;
513*7c478bd9Sstevel@tonic-gate 	int		tag;
514*7c478bd9Sstevel@tonic-gate 	uint_t		flag;
515*7c478bd9Sstevel@tonic-gate 	diskaddr_t	start;
516*7c478bd9Sstevel@tonic-gate 	diskaddr_t	size;
517*7c478bd9Sstevel@tonic-gate 
518*7c478bd9Sstevel@tonic-gate 	if (sscanf(data, "%d:%d:%x:%lld:%lld",
519*7c478bd9Sstevel@tonic-gate 	    &part, &tag, &flag, &start, &size) != 5) {
520*7c478bd9Sstevel@tonic-gate 		(void) fprintf(stderr, "Delta syntax error on \"%s\"\n", data);
521*7c478bd9Sstevel@tonic-gate 		exit(1);
522*7c478bd9Sstevel@tonic-gate 	}
523*7c478bd9Sstevel@tonic-gate 	if (part >= efi->efi_nparts) {
524*7c478bd9Sstevel@tonic-gate 		(void) fprintf(stderr,
525*7c478bd9Sstevel@tonic-gate 			"Error in data \"%s\": No such partition %x\n",
526*7c478bd9Sstevel@tonic-gate 			data, part);
527*7c478bd9Sstevel@tonic-gate 		exit(1);
528*7c478bd9Sstevel@tonic-gate 	}
529*7c478bd9Sstevel@tonic-gate 	efi->efi_parts[part].p_tag = (ushort_t)tag;
530*7c478bd9Sstevel@tonic-gate 	efi->efi_parts[part].p_flag = (ushort_t)flag;
531*7c478bd9Sstevel@tonic-gate 	efi->efi_parts[part].p_start = start;
532*7c478bd9Sstevel@tonic-gate 	efi->efi_parts[part].p_size = size;
533*7c478bd9Sstevel@tonic-gate }
534*7c478bd9Sstevel@tonic-gate 
535*7c478bd9Sstevel@tonic-gate /*
536*7c478bd9Sstevel@tonic-gate  * load()
537*7c478bd9Sstevel@tonic-gate  *
538*7c478bd9Sstevel@tonic-gate  * Load VTOC information from a datafile.
539*7c478bd9Sstevel@tonic-gate  */
540*7c478bd9Sstevel@tonic-gate static void
541*7c478bd9Sstevel@tonic-gate load(FILE *fp, struct dk_geom *geom, struct vtoc *vtoc)
542*7c478bd9Sstevel@tonic-gate {
543*7c478bd9Sstevel@tonic-gate 	int	part;
544*7c478bd9Sstevel@tonic-gate 	int	tag;
545*7c478bd9Sstevel@tonic-gate 	uint_t	flag;
546*7c478bd9Sstevel@tonic-gate 	daddr_t	start;
547*7c478bd9Sstevel@tonic-gate 	long	size;
548*7c478bd9Sstevel@tonic-gate 	char	line[256];
549*7c478bd9Sstevel@tonic-gate 	int	i;
550*7c478bd9Sstevel@tonic-gate 	long	nblks;
551*7c478bd9Sstevel@tonic-gate 	long	fullsz;
552*7c478bd9Sstevel@tonic-gate 
553*7c478bd9Sstevel@tonic-gate 	for (i = 0; i < V_NUMPAR; ++i) {
554*7c478bd9Sstevel@tonic-gate 		vtoc->v_part[i].p_tag = 0;
555*7c478bd9Sstevel@tonic-gate 		vtoc->v_part[i].p_flag = V_UNMNT;
556*7c478bd9Sstevel@tonic-gate 		vtoc->v_part[i].p_start = 0;
557*7c478bd9Sstevel@tonic-gate 		vtoc->v_part[i].p_size = 0;
558*7c478bd9Sstevel@tonic-gate 	}
559*7c478bd9Sstevel@tonic-gate 	/*
560*7c478bd9Sstevel@tonic-gate 	 * initialize partition 2, by convention it corresponds to whole
561*7c478bd9Sstevel@tonic-gate 	 * disk. It will be overwritten, if specified in the input datafile
562*7c478bd9Sstevel@tonic-gate 	 */
563*7c478bd9Sstevel@tonic-gate 	fullsz = geom->dkg_ncyl * geom->dkg_nsect * geom->dkg_nhead;
564*7c478bd9Sstevel@tonic-gate 	vtoc->v_part[2].p_tag = V_BACKUP;
565*7c478bd9Sstevel@tonic-gate 	vtoc->v_part[2].p_flag = V_UNMNT;
566*7c478bd9Sstevel@tonic-gate 	vtoc->v_part[2].p_start = 0;
567*7c478bd9Sstevel@tonic-gate 	vtoc->v_part[2].p_size = fullsz;
568*7c478bd9Sstevel@tonic-gate 
569*7c478bd9Sstevel@tonic-gate 	nblks = geom->dkg_nsect * geom->dkg_nhead;
570*7c478bd9Sstevel@tonic-gate 
571*7c478bd9Sstevel@tonic-gate 	while (fgets(line, sizeof (line) - 1, fp)) {
572*7c478bd9Sstevel@tonic-gate 		if (line[0] == '\0' || line[0] == '\n' || line[0] == '*')
573*7c478bd9Sstevel@tonic-gate 			continue;
574*7c478bd9Sstevel@tonic-gate 		line[strlen(line) - 1] = '\0';
575*7c478bd9Sstevel@tonic-gate 		if (sscanf(line, "%d %d %x %ld %ld",
576*7c478bd9Sstevel@tonic-gate 		    &part, &tag, &flag, &start, &size) != 5) {
577*7c478bd9Sstevel@tonic-gate 			(void) fprintf(stderr, "Syntax error: \"%s\"\n",
578*7c478bd9Sstevel@tonic-gate 				line);
579*7c478bd9Sstevel@tonic-gate 			exit(1);
580*7c478bd9Sstevel@tonic-gate 		}
581*7c478bd9Sstevel@tonic-gate 		if (part >= V_NUMPAR) {
582*7c478bd9Sstevel@tonic-gate 			(void) fprintf(stderr,
583*7c478bd9Sstevel@tonic-gate 				"No such partition %x: \"%s\"\n",
584*7c478bd9Sstevel@tonic-gate 				part, line);
585*7c478bd9Sstevel@tonic-gate 			exit(1);
586*7c478bd9Sstevel@tonic-gate 		}
587*7c478bd9Sstevel@tonic-gate 		if (!eflag && ((start % nblks) != 0 || (size % nblks) != 0)) {
588*7c478bd9Sstevel@tonic-gate 			(void) fprintf(stderr,
589*7c478bd9Sstevel@tonic-gate "Partition %d not aligned on cylinder boundary: \"%s\"\n",
590*7c478bd9Sstevel@tonic-gate 					part, line);
591*7c478bd9Sstevel@tonic-gate 			exit(1);
592*7c478bd9Sstevel@tonic-gate 		}
593*7c478bd9Sstevel@tonic-gate 		vtoc->v_part[part].p_tag = (ushort_t)tag;
594*7c478bd9Sstevel@tonic-gate 		vtoc->v_part[part].p_flag = (ushort_t)flag;
595*7c478bd9Sstevel@tonic-gate 		vtoc->v_part[part].p_start = start;
596*7c478bd9Sstevel@tonic-gate 		vtoc->v_part[part].p_size = size;
597*7c478bd9Sstevel@tonic-gate 	}
598*7c478bd9Sstevel@tonic-gate 	for (part = 0; part < V_NUMPAR; part++) {
599*7c478bd9Sstevel@tonic-gate 		vtoc->timestamp[part] = (time_t)0;
600*7c478bd9Sstevel@tonic-gate 	}
601*7c478bd9Sstevel@tonic-gate }
602*7c478bd9Sstevel@tonic-gate 
603*7c478bd9Sstevel@tonic-gate /*
604*7c478bd9Sstevel@tonic-gate  * load64()
605*7c478bd9Sstevel@tonic-gate  *
606*7c478bd9Sstevel@tonic-gate  * Load VTOC information from a datafile.
607*7c478bd9Sstevel@tonic-gate  */
608*7c478bd9Sstevel@tonic-gate static void
609*7c478bd9Sstevel@tonic-gate load64(FILE *fp, int fd, struct dk_gpt **efi)
610*7c478bd9Sstevel@tonic-gate {
611*7c478bd9Sstevel@tonic-gate 	int	part;
612*7c478bd9Sstevel@tonic-gate 	int	tag;
613*7c478bd9Sstevel@tonic-gate 	uint_t	flag;
614*7c478bd9Sstevel@tonic-gate 	diskaddr_t	start;
615*7c478bd9Sstevel@tonic-gate 	diskaddr_t	size;
616*7c478bd9Sstevel@tonic-gate 	int	nlines = 0;
617*7c478bd9Sstevel@tonic-gate 	char	line[256];
618*7c478bd9Sstevel@tonic-gate 	int	i;
619*7c478bd9Sstevel@tonic-gate 	uint_t	max_part = 0;
620*7c478bd9Sstevel@tonic-gate 	char	**mem = NULL;
621*7c478bd9Sstevel@tonic-gate 
622*7c478bd9Sstevel@tonic-gate 	while (fgets(line, sizeof (line) - 1, fp)) {
623*7c478bd9Sstevel@tonic-gate 		if (line[0] == '\0' || line[0] == '\n' || line[0] == '*')
624*7c478bd9Sstevel@tonic-gate 			continue;
625*7c478bd9Sstevel@tonic-gate 		line[strlen(line) - 1] = '\0';
626*7c478bd9Sstevel@tonic-gate 		if (sscanf(line, "%d %d %x %lld %lld",
627*7c478bd9Sstevel@tonic-gate 		    &part, &tag, &flag, &start, &size) != 5) {
628*7c478bd9Sstevel@tonic-gate 			(void) fprintf(stderr, "Syntax error: \"%s\"\n",
629*7c478bd9Sstevel@tonic-gate 				line);
630*7c478bd9Sstevel@tonic-gate 			exit(1);
631*7c478bd9Sstevel@tonic-gate 		}
632*7c478bd9Sstevel@tonic-gate 		mem = realloc(mem, sizeof (*mem) * (nlines + 1));
633*7c478bd9Sstevel@tonic-gate 		if (mem == NULL) {
634*7c478bd9Sstevel@tonic-gate 			(void) fprintf(stderr, "realloc failed\n");
635*7c478bd9Sstevel@tonic-gate 			exit(1);
636*7c478bd9Sstevel@tonic-gate 		}
637*7c478bd9Sstevel@tonic-gate 		mem[nlines] = strdup(line);
638*7c478bd9Sstevel@tonic-gate 		if (mem[nlines] == NULL) {
639*7c478bd9Sstevel@tonic-gate 			(void) fprintf(stderr, "strdup failed\n");
640*7c478bd9Sstevel@tonic-gate 			exit(1);
641*7c478bd9Sstevel@tonic-gate 		}
642*7c478bd9Sstevel@tonic-gate 		nlines++;
643*7c478bd9Sstevel@tonic-gate 		if (part > max_part)
644*7c478bd9Sstevel@tonic-gate 		    max_part = part;
645*7c478bd9Sstevel@tonic-gate 	}
646*7c478bd9Sstevel@tonic-gate 	max_part++;
647*7c478bd9Sstevel@tonic-gate 
648*7c478bd9Sstevel@tonic-gate 	if ((i = efi_alloc_and_init(fd, max_part, efi)) < 0) {
649*7c478bd9Sstevel@tonic-gate 		(void) fprintf(stderr,
650*7c478bd9Sstevel@tonic-gate 				"efi_alloc_and_init failed: %d\n", i);
651*7c478bd9Sstevel@tonic-gate 		exit(1);
652*7c478bd9Sstevel@tonic-gate 	}
653*7c478bd9Sstevel@tonic-gate 	for (i = 0; i < (*efi)->efi_nparts; ++i) {
654*7c478bd9Sstevel@tonic-gate 		(*efi)->efi_parts[i].p_tag = V_UNASSIGNED;
655*7c478bd9Sstevel@tonic-gate 		(*efi)->efi_parts[i].p_flag = V_UNMNT;
656*7c478bd9Sstevel@tonic-gate 		(*efi)->efi_parts[i].p_start = 0;
657*7c478bd9Sstevel@tonic-gate 		(*efi)->efi_parts[i].p_size = 0;
658*7c478bd9Sstevel@tonic-gate 	}
659*7c478bd9Sstevel@tonic-gate 	lastlba = (*efi)->efi_last_u_lba;
660*7c478bd9Sstevel@tonic-gate 
661*7c478bd9Sstevel@tonic-gate 	for (i = 0; i < nlines; i++) {
662*7c478bd9Sstevel@tonic-gate 		if (sscanf(mem[i], "%d %d %x %lld %lld",
663*7c478bd9Sstevel@tonic-gate 		    &part, &tag, &flag, &start, &size) != 5) {
664*7c478bd9Sstevel@tonic-gate 			(void) fprintf(stderr, "Syntax error: \"%s\"\n",
665*7c478bd9Sstevel@tonic-gate 				line);
666*7c478bd9Sstevel@tonic-gate 			exit(1);
667*7c478bd9Sstevel@tonic-gate 		}
668*7c478bd9Sstevel@tonic-gate 		free(mem[i]);
669*7c478bd9Sstevel@tonic-gate 		if (part >= (*efi)->efi_nparts) {
670*7c478bd9Sstevel@tonic-gate 			(void) fprintf(stderr,
671*7c478bd9Sstevel@tonic-gate 				"No such partition %x: \"%s\"\n",
672*7c478bd9Sstevel@tonic-gate 				part, line);
673*7c478bd9Sstevel@tonic-gate 			exit(1);
674*7c478bd9Sstevel@tonic-gate 		}
675*7c478bd9Sstevel@tonic-gate 		(*efi)->efi_parts[part].p_tag = (ushort_t)tag;
676*7c478bd9Sstevel@tonic-gate 		(*efi)->efi_parts[part].p_flag = (ushort_t)flag;
677*7c478bd9Sstevel@tonic-gate 		(*efi)->efi_parts[part].p_start = start;
678*7c478bd9Sstevel@tonic-gate 		(*efi)->efi_parts[part].p_size = size;
679*7c478bd9Sstevel@tonic-gate 	}
680*7c478bd9Sstevel@tonic-gate 	(*efi)->efi_nparts = max_part;
681*7c478bd9Sstevel@tonic-gate 	free(mem);
682*7c478bd9Sstevel@tonic-gate }
683*7c478bd9Sstevel@tonic-gate 
684*7c478bd9Sstevel@tonic-gate 
685*7c478bd9Sstevel@tonic-gate static void
686*7c478bd9Sstevel@tonic-gate usage()
687*7c478bd9Sstevel@tonic-gate {
688*7c478bd9Sstevel@tonic-gate 	(void) fprintf(stderr,
689*7c478bd9Sstevel@tonic-gate #if defined(sparc)
690*7c478bd9Sstevel@tonic-gate "Usage:	fmthard [ -i ] [ -n volumename ] [ -s datafile ] [ -d arguments] \
691*7c478bd9Sstevel@tonic-gate raw-device\n");
692*7c478bd9Sstevel@tonic-gate 
693*7c478bd9Sstevel@tonic-gate #elif defined(i386)
694*7c478bd9Sstevel@tonic-gate "Usage:	fmthard [ -i ] [ -S ] [-I geom_file]  \
695*7c478bd9Sstevel@tonic-gate -n volumename | -s datafile  [ -d arguments] raw-device\n");
696*7c478bd9Sstevel@tonic-gate 
697*7c478bd9Sstevel@tonic-gate #else
698*7c478bd9Sstevel@tonic-gate #error No platform defined.
699*7c478bd9Sstevel@tonic-gate #endif
700*7c478bd9Sstevel@tonic-gate 	exit(2);
701*7c478bd9Sstevel@tonic-gate }
702*7c478bd9Sstevel@tonic-gate 
703*7c478bd9Sstevel@tonic-gate /*
704*7c478bd9Sstevel@tonic-gate  * validate()
705*7c478bd9Sstevel@tonic-gate  *
706*7c478bd9Sstevel@tonic-gate  * Validate the new VTOC.
707*7c478bd9Sstevel@tonic-gate  */
708*7c478bd9Sstevel@tonic-gate static void
709*7c478bd9Sstevel@tonic-gate validate(struct dk_geom *geom, struct vtoc *vtoc)
710*7c478bd9Sstevel@tonic-gate {
711*7c478bd9Sstevel@tonic-gate 	int	i;
712*7c478bd9Sstevel@tonic-gate 	int	j;
713*7c478bd9Sstevel@tonic-gate 	long	fullsz;
714*7c478bd9Sstevel@tonic-gate 	long	endsect;
715*7c478bd9Sstevel@tonic-gate 	daddr_t	istart;
716*7c478bd9Sstevel@tonic-gate 	daddr_t	jstart;
717*7c478bd9Sstevel@tonic-gate 	long	isize;
718*7c478bd9Sstevel@tonic-gate 	long	jsize;
719*7c478bd9Sstevel@tonic-gate 	long	nblks;
720*7c478bd9Sstevel@tonic-gate 
721*7c478bd9Sstevel@tonic-gate 	nblks = geom->dkg_nsect * geom->dkg_nhead;
722*7c478bd9Sstevel@tonic-gate 
723*7c478bd9Sstevel@tonic-gate 	fullsz = geom->dkg_ncyl * geom->dkg_nsect * geom->dkg_nhead;
724*7c478bd9Sstevel@tonic-gate 
725*7c478bd9Sstevel@tonic-gate #if defined(_SUNOS_VTOC_16)
726*7c478bd9Sstevel@tonic-gate 	/* make the vtoc look sane - ha ha */
727*7c478bd9Sstevel@tonic-gate 	vtoc->v_version = V_VERSION;
728*7c478bd9Sstevel@tonic-gate 	vtoc->v_sanity = VTOC_SANE;
729*7c478bd9Sstevel@tonic-gate 	vtoc->v_nparts = V_NUMPAR;
730*7c478bd9Sstevel@tonic-gate 	if (sectsiz == 0)
731*7c478bd9Sstevel@tonic-gate 		sectsiz = SECSIZE;
732*7c478bd9Sstevel@tonic-gate 	if (vtoc->v_sectorsz == 0)
733*7c478bd9Sstevel@tonic-gate 		vtoc->v_sectorsz = sectsiz;
734*7c478bd9Sstevel@tonic-gate #endif				/* defined(_SUNOS_VTOC_16) */
735*7c478bd9Sstevel@tonic-gate 
736*7c478bd9Sstevel@tonic-gate 	for (i = 0; i < V_NUMPAR; i++) {
737*7c478bd9Sstevel@tonic-gate 		if (vtoc->v_part[i].p_tag == V_BACKUP) {
738*7c478bd9Sstevel@tonic-gate 			if (vtoc->v_part[i].p_size != fullsz) {
739*7c478bd9Sstevel@tonic-gate 				(void) fprintf(stderr, "\
740*7c478bd9Sstevel@tonic-gate fmthard: Partition %d specifies the full disk and is not equal\n\
741*7c478bd9Sstevel@tonic-gate full size of disk.  The full disk capacity is %lu sectors.\n", i, fullsz);
742*7c478bd9Sstevel@tonic-gate #if defined(sparc)
743*7c478bd9Sstevel@tonic-gate 			exit(1);
744*7c478bd9Sstevel@tonic-gate #endif
745*7c478bd9Sstevel@tonic-gate 			}
746*7c478bd9Sstevel@tonic-gate 		}
747*7c478bd9Sstevel@tonic-gate 		if (vtoc->v_part[i].p_size == 0)
748*7c478bd9Sstevel@tonic-gate 			continue;	/* Undefined partition */
749*7c478bd9Sstevel@tonic-gate 		if ((vtoc->v_part[i].p_start % nblks) ||
750*7c478bd9Sstevel@tonic-gate 				(vtoc->v_part[i].p_size % nblks)) {
751*7c478bd9Sstevel@tonic-gate 			(void) fprintf(stderr, "\
752*7c478bd9Sstevel@tonic-gate fmthard: Partition %d not aligned on cylinder boundary \n", i);
753*7c478bd9Sstevel@tonic-gate 				exit(1);
754*7c478bd9Sstevel@tonic-gate 		}
755*7c478bd9Sstevel@tonic-gate 		if (vtoc->v_part[i].p_start > fullsz ||
756*7c478bd9Sstevel@tonic-gate 			vtoc->v_part[i].p_start +
757*7c478bd9Sstevel@tonic-gate 				vtoc->v_part[i].p_size > fullsz) {
758*7c478bd9Sstevel@tonic-gate 			(void) fprintf(stderr, "\
759*7c478bd9Sstevel@tonic-gate fmthard: Partition %d specified as %lu sectors starting at %lu\n\
760*7c478bd9Sstevel@tonic-gate \tdoes not fit. The full disk contains %lu sectors.\n",
761*7c478bd9Sstevel@tonic-gate 				i, vtoc->v_part[i].p_size,
762*7c478bd9Sstevel@tonic-gate 				vtoc->v_part[i].p_start, fullsz);
763*7c478bd9Sstevel@tonic-gate #if defined(sparc)
764*7c478bd9Sstevel@tonic-gate 			exit(1);
765*7c478bd9Sstevel@tonic-gate #endif
766*7c478bd9Sstevel@tonic-gate 		}
767*7c478bd9Sstevel@tonic-gate 
768*7c478bd9Sstevel@tonic-gate 		if (vtoc->v_part[i].p_tag != V_BACKUP &&
769*7c478bd9Sstevel@tonic-gate 		    vtoc->v_part[i].p_size != fullsz) {
770*7c478bd9Sstevel@tonic-gate 			for (j = 0; j < V_NUMPAR; j++) {
771*7c478bd9Sstevel@tonic-gate 				if (vtoc->v_part[j].p_tag == V_BACKUP)
772*7c478bd9Sstevel@tonic-gate 					continue;
773*7c478bd9Sstevel@tonic-gate 				if (vtoc->v_part[j].p_size == fullsz)
774*7c478bd9Sstevel@tonic-gate 					continue;
775*7c478bd9Sstevel@tonic-gate 				isize = vtoc->v_part[i].p_size;
776*7c478bd9Sstevel@tonic-gate 				jsize = vtoc->v_part[j].p_size;
777*7c478bd9Sstevel@tonic-gate 				istart = vtoc->v_part[i].p_start;
778*7c478bd9Sstevel@tonic-gate 				jstart = vtoc->v_part[j].p_start;
779*7c478bd9Sstevel@tonic-gate 				if ((i != j) &&
780*7c478bd9Sstevel@tonic-gate 				    (isize != 0) && (jsize != 0)) {
781*7c478bd9Sstevel@tonic-gate 					endsect = jstart + jsize -1;
782*7c478bd9Sstevel@tonic-gate 					if ((jstart <= istart) &&
783*7c478bd9Sstevel@tonic-gate 						(istart <= endsect)) {
784*7c478bd9Sstevel@tonic-gate 						(void) fprintf(stderr, "\
785*7c478bd9Sstevel@tonic-gate fmthard: Partition %d overlaps partition %d. Overlap is allowed\n\
786*7c478bd9Sstevel@tonic-gate \tonly on partition on the full disk partition).\n",
787*7c478bd9Sstevel@tonic-gate 						    i, j);
788*7c478bd9Sstevel@tonic-gate #if defined(sparc)
789*7c478bd9Sstevel@tonic-gate 						exit(1);
790*7c478bd9Sstevel@tonic-gate #endif
791*7c478bd9Sstevel@tonic-gate 					}
792*7c478bd9Sstevel@tonic-gate 				}
793*7c478bd9Sstevel@tonic-gate 			}
794*7c478bd9Sstevel@tonic-gate 		}
795*7c478bd9Sstevel@tonic-gate 	}
796*7c478bd9Sstevel@tonic-gate }
797*7c478bd9Sstevel@tonic-gate 
798*7c478bd9Sstevel@tonic-gate /*
799*7c478bd9Sstevel@tonic-gate  * validate64()
800*7c478bd9Sstevel@tonic-gate  *
801*7c478bd9Sstevel@tonic-gate  * Validate the new VTOC.
802*7c478bd9Sstevel@tonic-gate  */
803*7c478bd9Sstevel@tonic-gate static void
804*7c478bd9Sstevel@tonic-gate validate64(struct dk_gpt *efi)
805*7c478bd9Sstevel@tonic-gate {
806*7c478bd9Sstevel@tonic-gate 	int		i;
807*7c478bd9Sstevel@tonic-gate 	int		j;
808*7c478bd9Sstevel@tonic-gate 	int		resv_part = 0;
809*7c478bd9Sstevel@tonic-gate 	diskaddr_t	endsect;
810*7c478bd9Sstevel@tonic-gate 	diskaddr_t	fullsz;
811*7c478bd9Sstevel@tonic-gate 	diskaddr_t		istart;
812*7c478bd9Sstevel@tonic-gate 	diskaddr_t		jstart;
813*7c478bd9Sstevel@tonic-gate 	diskaddr_t		isize;
814*7c478bd9Sstevel@tonic-gate 	diskaddr_t		jsize;
815*7c478bd9Sstevel@tonic-gate 
816*7c478bd9Sstevel@tonic-gate 	fullsz = lastlba + 1;
817*7c478bd9Sstevel@tonic-gate 
818*7c478bd9Sstevel@tonic-gate 	for (i = 0; i < efi->efi_nparts; i++) {
819*7c478bd9Sstevel@tonic-gate 		if (efi->efi_parts[i].p_size == 0)
820*7c478bd9Sstevel@tonic-gate 			continue;	/* Undefined partition */
821*7c478bd9Sstevel@tonic-gate 		if (efi->efi_parts[i].p_tag == V_RESERVED)
822*7c478bd9Sstevel@tonic-gate 			resv_part++;
823*7c478bd9Sstevel@tonic-gate 		if (efi->efi_parts[i].p_start > fullsz ||
824*7c478bd9Sstevel@tonic-gate 			efi->efi_parts[i].p_start +
825*7c478bd9Sstevel@tonic-gate 				efi->efi_parts[i].p_size > fullsz) {
826*7c478bd9Sstevel@tonic-gate 			(void) fprintf(stderr, "\
827*7c478bd9Sstevel@tonic-gate fmthard: Partition %d specified as %lld sectors starting at %lld\n\
828*7c478bd9Sstevel@tonic-gate \tdoes not fit. The full disk contains %lld sectors.\n",
829*7c478bd9Sstevel@tonic-gate 				i, efi->efi_parts[i].p_size,
830*7c478bd9Sstevel@tonic-gate 				efi->efi_parts[i].p_start, fullsz);
831*7c478bd9Sstevel@tonic-gate 			exit(1);
832*7c478bd9Sstevel@tonic-gate 		}
833*7c478bd9Sstevel@tonic-gate 
834*7c478bd9Sstevel@tonic-gate 		if (efi->efi_parts[i].p_tag != V_BACKUP &&
835*7c478bd9Sstevel@tonic-gate 		    efi->efi_parts[i].p_size != fullsz) {
836*7c478bd9Sstevel@tonic-gate 			for (j = 0; j < V_NUMPAR; j++) {
837*7c478bd9Sstevel@tonic-gate 				if (efi->efi_parts[j].p_size == fullsz)
838*7c478bd9Sstevel@tonic-gate 					continue;
839*7c478bd9Sstevel@tonic-gate 				isize = efi->efi_parts[i].p_size;
840*7c478bd9Sstevel@tonic-gate 				jsize = efi->efi_parts[j].p_size;
841*7c478bd9Sstevel@tonic-gate 				istart = efi->efi_parts[i].p_start;
842*7c478bd9Sstevel@tonic-gate 				jstart = efi->efi_parts[j].p_start;
843*7c478bd9Sstevel@tonic-gate 				if ((i != j) &&
844*7c478bd9Sstevel@tonic-gate 				    (isize != 0) && (jsize != 0)) {
845*7c478bd9Sstevel@tonic-gate 					endsect = jstart + jsize - 1;
846*7c478bd9Sstevel@tonic-gate 					if ((jstart <= istart) &&
847*7c478bd9Sstevel@tonic-gate 						(istart <= endsect)) {
848*7c478bd9Sstevel@tonic-gate 						(void) fprintf(stderr, "\
849*7c478bd9Sstevel@tonic-gate fmthard: Partition %d overlaps partition %d. Overlap is allowed\n\
850*7c478bd9Sstevel@tonic-gate \tonly on partition on the full disk partition).\n",
851*7c478bd9Sstevel@tonic-gate 						    i, j);
852*7c478bd9Sstevel@tonic-gate #if defined(sparc)
853*7c478bd9Sstevel@tonic-gate 						exit(1);
854*7c478bd9Sstevel@tonic-gate #endif
855*7c478bd9Sstevel@tonic-gate 					}
856*7c478bd9Sstevel@tonic-gate 				}
857*7c478bd9Sstevel@tonic-gate 			}
858*7c478bd9Sstevel@tonic-gate 		}
859*7c478bd9Sstevel@tonic-gate 	}
860*7c478bd9Sstevel@tonic-gate 	if (resv_part != 1) {
861*7c478bd9Sstevel@tonic-gate 		(void) fprintf(stderr,
862*7c478bd9Sstevel@tonic-gate 		    "expected one reserved partition, but found %d\n",
863*7c478bd9Sstevel@tonic-gate 		    resv_part);
864*7c478bd9Sstevel@tonic-gate 		exit(1);
865*7c478bd9Sstevel@tonic-gate 	}
866*7c478bd9Sstevel@tonic-gate }
867*7c478bd9Sstevel@tonic-gate 
868*7c478bd9Sstevel@tonic-gate 
869*7c478bd9Sstevel@tonic-gate /*
870*7c478bd9Sstevel@tonic-gate  * Read the VTOC
871*7c478bd9Sstevel@tonic-gate  */
872*7c478bd9Sstevel@tonic-gate int
873*7c478bd9Sstevel@tonic-gate vread(int fd, struct vtoc *vtoc, char *devname)
874*7c478bd9Sstevel@tonic-gate {
875*7c478bd9Sstevel@tonic-gate 	int	i;
876*7c478bd9Sstevel@tonic-gate 
877*7c478bd9Sstevel@tonic-gate 	if ((i = read_vtoc(fd, vtoc)) < 0) {
878*7c478bd9Sstevel@tonic-gate 		if (i == VT_ENOTSUP) {
879*7c478bd9Sstevel@tonic-gate 			return (1);
880*7c478bd9Sstevel@tonic-gate 		}
881*7c478bd9Sstevel@tonic-gate 		if (i == VT_EINVAL) {
882*7c478bd9Sstevel@tonic-gate 			(void) fprintf(stderr, "%s: Invalid VTOC\n",
883*7c478bd9Sstevel@tonic-gate 				devname);
884*7c478bd9Sstevel@tonic-gate 		} else {
885*7c478bd9Sstevel@tonic-gate 			(void) fprintf(stderr, "%s: Cannot read VTOC\n",
886*7c478bd9Sstevel@tonic-gate 				devname);
887*7c478bd9Sstevel@tonic-gate 		}
888*7c478bd9Sstevel@tonic-gate 		exit(1);
889*7c478bd9Sstevel@tonic-gate 	}
890*7c478bd9Sstevel@tonic-gate 	return (0);
891*7c478bd9Sstevel@tonic-gate }
892*7c478bd9Sstevel@tonic-gate 
893*7c478bd9Sstevel@tonic-gate void
894*7c478bd9Sstevel@tonic-gate vread64(int fd, struct dk_gpt **efi_hdr, char *devname)
895*7c478bd9Sstevel@tonic-gate {
896*7c478bd9Sstevel@tonic-gate 	int i;
897*7c478bd9Sstevel@tonic-gate 
898*7c478bd9Sstevel@tonic-gate 	if ((i = efi_alloc_and_read(fd, efi_hdr)) < 0) {
899*7c478bd9Sstevel@tonic-gate 		if (i == VT_EINVAL)
900*7c478bd9Sstevel@tonic-gate 			(void) fprintf(stderr,
901*7c478bd9Sstevel@tonic-gate 				"%s: this disk must be labeled first\n",
902*7c478bd9Sstevel@tonic-gate 				devname);
903*7c478bd9Sstevel@tonic-gate 		else
904*7c478bd9Sstevel@tonic-gate 			(void) fprintf(stderr,
905*7c478bd9Sstevel@tonic-gate 				"%s: read_efi failed %d\n",
906*7c478bd9Sstevel@tonic-gate 				devname, i);
907*7c478bd9Sstevel@tonic-gate 		exit(1);
908*7c478bd9Sstevel@tonic-gate 	}
909*7c478bd9Sstevel@tonic-gate 	lastlba = (*efi_hdr)->efi_last_u_lba;
910*7c478bd9Sstevel@tonic-gate }
911*7c478bd9Sstevel@tonic-gate 
912*7c478bd9Sstevel@tonic-gate /*
913*7c478bd9Sstevel@tonic-gate  * Write the VTOC
914*7c478bd9Sstevel@tonic-gate  */
915*7c478bd9Sstevel@tonic-gate void
916*7c478bd9Sstevel@tonic-gate vwrite(int fd, struct vtoc *vtoc, char *devname)
917*7c478bd9Sstevel@tonic-gate {
918*7c478bd9Sstevel@tonic-gate 	int	i;
919*7c478bd9Sstevel@tonic-gate 
920*7c478bd9Sstevel@tonic-gate 	if ((i = write_vtoc(fd, vtoc)) != 0) {
921*7c478bd9Sstevel@tonic-gate 		if (i == VT_EINVAL) {
922*7c478bd9Sstevel@tonic-gate 			(void) fprintf(stderr,
923*7c478bd9Sstevel@tonic-gate 			"%s: invalid entry exists in vtoc\n",
924*7c478bd9Sstevel@tonic-gate 				devname);
925*7c478bd9Sstevel@tonic-gate 		} else {
926*7c478bd9Sstevel@tonic-gate 			(void) fprintf(stderr, "%s: Cannot write VTOC\n",
927*7c478bd9Sstevel@tonic-gate 				devname);
928*7c478bd9Sstevel@tonic-gate 		}
929*7c478bd9Sstevel@tonic-gate 		exit(1);
930*7c478bd9Sstevel@tonic-gate 	}
931*7c478bd9Sstevel@tonic-gate }
932*7c478bd9Sstevel@tonic-gate 
933*7c478bd9Sstevel@tonic-gate /*
934*7c478bd9Sstevel@tonic-gate  * Write the VTOC
935*7c478bd9Sstevel@tonic-gate  */
936*7c478bd9Sstevel@tonic-gate void
937*7c478bd9Sstevel@tonic-gate vwrite64(int fd, struct dk_gpt *efi, char *devname)
938*7c478bd9Sstevel@tonic-gate {
939*7c478bd9Sstevel@tonic-gate 	int	i;
940*7c478bd9Sstevel@tonic-gate 
941*7c478bd9Sstevel@tonic-gate 	if ((i = efi_write(fd, efi)) != 0) {
942*7c478bd9Sstevel@tonic-gate 		if (i == VT_EINVAL) {
943*7c478bd9Sstevel@tonic-gate 			(void) fprintf(stderr,
944*7c478bd9Sstevel@tonic-gate 			"%s: invalid entry exists in vtoc\n",
945*7c478bd9Sstevel@tonic-gate 				devname);
946*7c478bd9Sstevel@tonic-gate 		} else {
947*7c478bd9Sstevel@tonic-gate 			(void) fprintf(stderr, "%s: Cannot write EFI\n",
948*7c478bd9Sstevel@tonic-gate 				devname);
949*7c478bd9Sstevel@tonic-gate 		}
950*7c478bd9Sstevel@tonic-gate 		exit(1);
951*7c478bd9Sstevel@tonic-gate 	}
952*7c478bd9Sstevel@tonic-gate }
953