xref: /dflybsd-src/sbin/gpt/create.c (revision d9306807fd00040e0598140bd4c634685f805510)
1fb9cffefSMatthew Dillon /*-
2fb9cffefSMatthew Dillon  * Copyright (c) 2002 Marcel Moolenaar
3fb9cffefSMatthew Dillon  * All rights reserved.
4fb9cffefSMatthew Dillon  *
5bd2b9b6fSMatthew Dillon  * 'init' directive added by Matthew Dillon.
6bd2b9b6fSMatthew Dillon  *
7fb9cffefSMatthew Dillon  * Redistribution and use in source and binary forms, with or without
8fb9cffefSMatthew Dillon  * modification, are permitted provided that the following conditions
9fb9cffefSMatthew Dillon  * are met:
10fb9cffefSMatthew Dillon  *
11fb9cffefSMatthew Dillon  * 1. Redistributions of source code must retain the above copyright
12fb9cffefSMatthew Dillon  *    notice, this list of conditions and the following disclaimer.
13fb9cffefSMatthew Dillon  * 2. Redistributions in binary form must reproduce the above copyright
14fb9cffefSMatthew Dillon  *    notice, this list of conditions and the following disclaimer in the
15fb9cffefSMatthew Dillon  *    documentation and/or other materials provided with the distribution.
16fb9cffefSMatthew Dillon  *
17fb9cffefSMatthew Dillon  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18fb9cffefSMatthew Dillon  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19fb9cffefSMatthew Dillon  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20fb9cffefSMatthew Dillon  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21fb9cffefSMatthew Dillon  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22fb9cffefSMatthew Dillon  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23fb9cffefSMatthew Dillon  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24fb9cffefSMatthew Dillon  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25fb9cffefSMatthew Dillon  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26fb9cffefSMatthew Dillon  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27fb9cffefSMatthew Dillon  *
28fb9cffefSMatthew Dillon  * $FreeBSD: src/sbin/gpt/create.c,v 1.11 2005/08/31 01:47:19 marcel Exp $
29fb9cffefSMatthew Dillon  * $DragonFly: src/sbin/gpt/create.c,v 1.1 2007/06/16 22:29:27 dillon Exp $
30fb9cffefSMatthew Dillon  */
31fb9cffefSMatthew Dillon 
32fb9cffefSMatthew Dillon #include <sys/types.h>
33bd2b9b6fSMatthew Dillon #include <sys/stat.h>
34*d9306807SMatthew Dillon #include <sys/errno.h>
35*d9306807SMatthew Dillon #include <sys/param.h>
36*d9306807SMatthew Dillon #include <bus/cam/scsi/scsi_daio.h>
37fb9cffefSMatthew Dillon 
38fb9cffefSMatthew Dillon #include <err.h>
39fb9cffefSMatthew Dillon #include <stddef.h>
40fb9cffefSMatthew Dillon #include <stdio.h>
41fb9cffefSMatthew Dillon #include <stdlib.h>
42bd2b9b6fSMatthew Dillon #include <stdarg.h>
43fb9cffefSMatthew Dillon #include <string.h>
44fb9cffefSMatthew Dillon #include <unistd.h>
45fb9cffefSMatthew Dillon 
46fb9cffefSMatthew Dillon #include "map.h"
47fb9cffefSMatthew Dillon #include "gpt.h"
48fb9cffefSMatthew Dillon 
49fb9cffefSMatthew Dillon static int force;
50fb9cffefSMatthew Dillon static int primary_only;
51fb9cffefSMatthew Dillon 
52*d9306807SMatthew Dillon static void do_erase(int fd);
53*d9306807SMatthew Dillon 
54fb9cffefSMatthew Dillon static void
usage_create(void)55fb9cffefSMatthew Dillon usage_create(void)
56fb9cffefSMatthew Dillon {
57bd2b9b6fSMatthew Dillon 	fprintf(stderr, "usage: %s [-fp] device ...\n", getprogname());
58bd2b9b6fSMatthew Dillon 	exit(1);
59bd2b9b6fSMatthew Dillon }
60fb9cffefSMatthew Dillon 
61bd2b9b6fSMatthew Dillon static void
usage_init(void)62bd2b9b6fSMatthew Dillon usage_init(void)
63bd2b9b6fSMatthew Dillon {
64*d9306807SMatthew Dillon 	fprintf(stderr, "usage: %s -f [-B] [-E] device ...\n", getprogname());
65bd2b9b6fSMatthew Dillon 	fprintf(stderr, "\tnote: -f is mandatory for this command\n");
66fb9cffefSMatthew Dillon 	exit(1);
67fb9cffefSMatthew Dillon }
68fb9cffefSMatthew Dillon 
69fb9cffefSMatthew Dillon static void
create(int fd)70fb9cffefSMatthew Dillon create(int fd)
71fb9cffefSMatthew Dillon {
72fb9cffefSMatthew Dillon 	uuid_t uuid;
73fb9cffefSMatthew Dillon 	off_t blocks, last;
74fb9cffefSMatthew Dillon 	map_t *gpt, *tpg;
75fb9cffefSMatthew Dillon 	map_t *tbl, *lbt;
76fb9cffefSMatthew Dillon 	map_t *map;
77fb9cffefSMatthew Dillon 	struct mbr *mbr;
78fb9cffefSMatthew Dillon 	struct gpt_hdr *hdr;
79fb9cffefSMatthew Dillon 	struct gpt_ent *ent;
80fb9cffefSMatthew Dillon 	unsigned int i;
81fb9cffefSMatthew Dillon 
82fb9cffefSMatthew Dillon 	last = mediasz / secsz - 1LL;
83fb9cffefSMatthew Dillon 
84fb9cffefSMatthew Dillon 	if (map_find(MAP_TYPE_PRI_GPT_HDR) != NULL ||
85fb9cffefSMatthew Dillon 	    map_find(MAP_TYPE_SEC_GPT_HDR) != NULL) {
86fb9cffefSMatthew Dillon 		warnx("%s: error: device already contains a GPT", device_name);
87fb9cffefSMatthew Dillon 		return;
88fb9cffefSMatthew Dillon 	}
89fb9cffefSMatthew Dillon 	map = map_find(MAP_TYPE_MBR);
90fb9cffefSMatthew Dillon 	if (map != NULL) {
91fb9cffefSMatthew Dillon 		if (!force) {
92fb9cffefSMatthew Dillon 			warnx("%s: error: device contains a MBR", device_name);
93fb9cffefSMatthew Dillon 			return;
94fb9cffefSMatthew Dillon 		}
95fb9cffefSMatthew Dillon 
96fb9cffefSMatthew Dillon 		/* Nuke the MBR in our internal map. */
97fb9cffefSMatthew Dillon 		map->map_type = MAP_TYPE_UNUSED;
98fb9cffefSMatthew Dillon 	}
99fb9cffefSMatthew Dillon 
100fb9cffefSMatthew Dillon 	/*
101fb9cffefSMatthew Dillon 	 * Create PMBR.
102fb9cffefSMatthew Dillon 	 */
103fb9cffefSMatthew Dillon 	if (map_find(MAP_TYPE_PMBR) == NULL) {
104fb9cffefSMatthew Dillon 		if (map_free(0LL, 1LL) == 0) {
105fb9cffefSMatthew Dillon 			warnx("%s: error: no room for the PMBR", device_name);
106fb9cffefSMatthew Dillon 			return;
107fb9cffefSMatthew Dillon 		}
108fb9cffefSMatthew Dillon 		mbr = gpt_read(fd, 0LL, 1);
109fb9cffefSMatthew Dillon 		bzero(mbr, sizeof(*mbr));
110fb9cffefSMatthew Dillon 		mbr->mbr_sig = htole16(MBR_SIG);
111fb9cffefSMatthew Dillon 		mbr->mbr_part[0].part_shd = 0xff;
112fb9cffefSMatthew Dillon 		mbr->mbr_part[0].part_ssect = 0xff;
113fb9cffefSMatthew Dillon 		mbr->mbr_part[0].part_scyl = 0xff;
114fb9cffefSMatthew Dillon 		mbr->mbr_part[0].part_typ = 0xee;
115fb9cffefSMatthew Dillon 		mbr->mbr_part[0].part_ehd = 0xff;
116fb9cffefSMatthew Dillon 		mbr->mbr_part[0].part_esect = 0xff;
117fb9cffefSMatthew Dillon 		mbr->mbr_part[0].part_ecyl = 0xff;
118fb9cffefSMatthew Dillon 		mbr->mbr_part[0].part_start_lo = htole16(1);
119fb9cffefSMatthew Dillon 		if (last > 0xffffffff) {
120fb9cffefSMatthew Dillon 			mbr->mbr_part[0].part_size_lo = htole16(0xffff);
121fb9cffefSMatthew Dillon 			mbr->mbr_part[0].part_size_hi = htole16(0xffff);
122fb9cffefSMatthew Dillon 		} else {
123fb9cffefSMatthew Dillon 			mbr->mbr_part[0].part_size_lo = htole16(last);
124fb9cffefSMatthew Dillon 			mbr->mbr_part[0].part_size_hi = htole16(last >> 16);
125fb9cffefSMatthew Dillon 		}
126fb9cffefSMatthew Dillon 		map = map_add(0LL, 1LL, MAP_TYPE_PMBR, mbr);
127fb9cffefSMatthew Dillon 		gpt_write(fd, map);
128fb9cffefSMatthew Dillon 	}
129fb9cffefSMatthew Dillon 
130fb9cffefSMatthew Dillon 	/* Get the amount of free space after the MBR */
131fb9cffefSMatthew Dillon 	blocks = map_free(1LL, 0LL);
132fb9cffefSMatthew Dillon 	if (blocks == 0LL) {
133fb9cffefSMatthew Dillon 		warnx("%s: error: no room for the GPT header", device_name);
134fb9cffefSMatthew Dillon 		return;
135fb9cffefSMatthew Dillon 	}
136fb9cffefSMatthew Dillon 
137fb9cffefSMatthew Dillon 	/* Don't create more than parts entries. */
138fb9cffefSMatthew Dillon 	if ((uint64_t)(blocks - 1) * secsz > parts * sizeof(struct gpt_ent)) {
139fb9cffefSMatthew Dillon 		blocks = (parts * sizeof(struct gpt_ent)) / secsz;
140fb9cffefSMatthew Dillon 		if ((parts * sizeof(struct gpt_ent)) % secsz)
141fb9cffefSMatthew Dillon 			blocks++;
142fb9cffefSMatthew Dillon 		blocks++;		/* Don't forget the header itself */
143fb9cffefSMatthew Dillon 	}
144fb9cffefSMatthew Dillon 
145fb9cffefSMatthew Dillon 	/* Never cross the median of the device. */
146fb9cffefSMatthew Dillon 	if ((blocks + 1LL) > ((last + 1LL) >> 1))
147fb9cffefSMatthew Dillon 		blocks = ((last + 1LL) >> 1) - 1LL;
148fb9cffefSMatthew Dillon 
149fb9cffefSMatthew Dillon 	/*
150fb9cffefSMatthew Dillon 	 * Get the amount of free space at the end of the device and
151fb9cffefSMatthew Dillon 	 * calculate the size for the GPT structures.
152fb9cffefSMatthew Dillon 	 */
153fb9cffefSMatthew Dillon 	map = map_last();
154fb9cffefSMatthew Dillon 	if (map->map_type != MAP_TYPE_UNUSED) {
155fb9cffefSMatthew Dillon 		warnx("%s: error: no room for the backup header", device_name);
156fb9cffefSMatthew Dillon 		return;
157fb9cffefSMatthew Dillon 	}
158fb9cffefSMatthew Dillon 
159fb9cffefSMatthew Dillon 	if (map->map_size < blocks)
160fb9cffefSMatthew Dillon 		blocks = map->map_size;
161fb9cffefSMatthew Dillon 	if (blocks == 1LL) {
162fb9cffefSMatthew Dillon 		warnx("%s: error: no room for the GPT table", device_name);
163fb9cffefSMatthew Dillon 		return;
164fb9cffefSMatthew Dillon 	}
165fb9cffefSMatthew Dillon 
166fb9cffefSMatthew Dillon 	blocks--;		/* Number of blocks in the GPT table. */
167fb9cffefSMatthew Dillon 	gpt = map_add(1LL, 1LL, MAP_TYPE_PRI_GPT_HDR, calloc(1, secsz));
168fb9cffefSMatthew Dillon 	tbl = map_add(2LL, blocks, MAP_TYPE_PRI_GPT_TBL,
169fb9cffefSMatthew Dillon 	    calloc(blocks, secsz));
170fb9cffefSMatthew Dillon 	if (gpt == NULL || tbl == NULL)
171fb9cffefSMatthew Dillon 		return;
172fb9cffefSMatthew Dillon 
173fb9cffefSMatthew Dillon 	hdr = gpt->map_data;
174fb9cffefSMatthew Dillon 	memcpy(hdr->hdr_sig, GPT_HDR_SIG, sizeof(hdr->hdr_sig));
175fb9cffefSMatthew Dillon 	hdr->hdr_revision = htole32(GPT_HDR_REVISION);
176fb9cffefSMatthew Dillon 	/*
177fb9cffefSMatthew Dillon 	 * XXX struct gpt_hdr is not a multiple of 8 bytes in size and thus
178fb9cffefSMatthew Dillon 	 * contains padding we must not include in the size.
179fb9cffefSMatthew Dillon 	 */
180fb9cffefSMatthew Dillon 	hdr->hdr_size = htole32(offsetof(struct gpt_hdr, padding));
181fb9cffefSMatthew Dillon 	hdr->hdr_lba_self = htole64(gpt->map_start);
182fb9cffefSMatthew Dillon 	hdr->hdr_lba_alt = htole64(last);
183fb9cffefSMatthew Dillon 	hdr->hdr_lba_start = htole64(tbl->map_start + blocks);
184fb9cffefSMatthew Dillon 	hdr->hdr_lba_end = htole64(last - blocks - 1LL);
185fb9cffefSMatthew Dillon 	uuid_create(&uuid, NULL);
186fb9cffefSMatthew Dillon 	le_uuid_enc(&hdr->hdr_uuid, &uuid);
187fb9cffefSMatthew Dillon 	hdr->hdr_lba_table = htole64(tbl->map_start);
188fb9cffefSMatthew Dillon 	hdr->hdr_entries = htole32((blocks * secsz) / sizeof(struct gpt_ent));
189fb9cffefSMatthew Dillon 	if (le32toh(hdr->hdr_entries) > parts)
190fb9cffefSMatthew Dillon 		hdr->hdr_entries = htole32(parts);
191fb9cffefSMatthew Dillon 	hdr->hdr_entsz = htole32(sizeof(struct gpt_ent));
192fb9cffefSMatthew Dillon 
193fb9cffefSMatthew Dillon 	ent = tbl->map_data;
194fb9cffefSMatthew Dillon 	for (i = 0; i < le32toh(hdr->hdr_entries); i++) {
195fb9cffefSMatthew Dillon 		uuid_create(&uuid, NULL);
196fb9cffefSMatthew Dillon 		le_uuid_enc(&ent[i].ent_uuid, &uuid);
197fb9cffefSMatthew Dillon 	}
198fb9cffefSMatthew Dillon 
199fb9cffefSMatthew Dillon 	hdr->hdr_crc_table = htole32(crc32(ent, le32toh(hdr->hdr_entries) *
200fb9cffefSMatthew Dillon 	    le32toh(hdr->hdr_entsz)));
201fb9cffefSMatthew Dillon 	hdr->hdr_crc_self = htole32(crc32(hdr, le32toh(hdr->hdr_size)));
202fb9cffefSMatthew Dillon 
203fb9cffefSMatthew Dillon 	gpt_write(fd, gpt);
204fb9cffefSMatthew Dillon 	gpt_write(fd, tbl);
205fb9cffefSMatthew Dillon 
206fb9cffefSMatthew Dillon 	/*
207fb9cffefSMatthew Dillon 	 * Create backup GPT if the user didn't suppress it.
208fb9cffefSMatthew Dillon 	 */
209fb9cffefSMatthew Dillon 	if (!primary_only) {
210fb9cffefSMatthew Dillon 		tpg = map_add(last, 1LL, MAP_TYPE_SEC_GPT_HDR,
211fb9cffefSMatthew Dillon 		    calloc(1, secsz));
212fb9cffefSMatthew Dillon 		lbt = map_add(last - blocks, blocks, MAP_TYPE_SEC_GPT_TBL,
213fb9cffefSMatthew Dillon 		    tbl->map_data);
214fb9cffefSMatthew Dillon 		memcpy(tpg->map_data, gpt->map_data, secsz);
215fb9cffefSMatthew Dillon 		hdr = tpg->map_data;
216fb9cffefSMatthew Dillon 		hdr->hdr_lba_self = htole64(tpg->map_start);
217fb9cffefSMatthew Dillon 		hdr->hdr_lba_alt = htole64(gpt->map_start);
218fb9cffefSMatthew Dillon 		hdr->hdr_lba_table = htole64(lbt->map_start);
219fb9cffefSMatthew Dillon 		hdr->hdr_crc_self = 0;		/* Don't ever forget this! */
220fb9cffefSMatthew Dillon 		hdr->hdr_crc_self = htole32(crc32(hdr, le32toh(hdr->hdr_size)));
221fb9cffefSMatthew Dillon 		gpt_write(fd, lbt);
222fb9cffefSMatthew Dillon 		gpt_write(fd, tpg);
223fb9cffefSMatthew Dillon 	}
224fb9cffefSMatthew Dillon }
225fb9cffefSMatthew Dillon 
226bd2b9b6fSMatthew Dillon static
227bd2b9b6fSMatthew Dillon void
dosys(const char * ctl,...)228bd2b9b6fSMatthew Dillon dosys(const char *ctl, ...)
229bd2b9b6fSMatthew Dillon {
230bd2b9b6fSMatthew Dillon 	va_list va;
231bd2b9b6fSMatthew Dillon 	char *scmd;
232bd2b9b6fSMatthew Dillon 
233bd2b9b6fSMatthew Dillon 	va_start(va, ctl);
234bd2b9b6fSMatthew Dillon 	vasprintf(&scmd, ctl, va);
235bd2b9b6fSMatthew Dillon 	va_end(va);
236bd2b9b6fSMatthew Dillon 	printf("%s\n", scmd);
237bd2b9b6fSMatthew Dillon 	if (system(scmd) != 0) {
238bd2b9b6fSMatthew Dillon 		fprintf(stderr, "Execution failed\n");
239bd2b9b6fSMatthew Dillon 		free(scmd);
240bd2b9b6fSMatthew Dillon 		exit(1);
241bd2b9b6fSMatthew Dillon 	}
242bd2b9b6fSMatthew Dillon 	free(scmd);
243bd2b9b6fSMatthew Dillon }
244bd2b9b6fSMatthew Dillon 
245fb9cffefSMatthew Dillon int
cmd_create(int argc,char * argv[])246fb9cffefSMatthew Dillon cmd_create(int argc, char *argv[])
247fb9cffefSMatthew Dillon {
248fb9cffefSMatthew Dillon 	int ch, fd;
249fb9cffefSMatthew Dillon 
250fb9cffefSMatthew Dillon 	while ((ch = getopt(argc, argv, "fp")) != -1) {
251fb9cffefSMatthew Dillon 		switch(ch) {
252fb9cffefSMatthew Dillon 		case 'f':
253fb9cffefSMatthew Dillon 			force = 1;
254fb9cffefSMatthew Dillon 			break;
255fb9cffefSMatthew Dillon 		case 'p':
256fb9cffefSMatthew Dillon 			primary_only = 1;
257fb9cffefSMatthew Dillon 			break;
258fb9cffefSMatthew Dillon 		default:
259fb9cffefSMatthew Dillon 			usage_create();
260fb9cffefSMatthew Dillon 		}
261fb9cffefSMatthew Dillon 	}
262fb9cffefSMatthew Dillon 
263fb9cffefSMatthew Dillon 	if (argc == optind)
264fb9cffefSMatthew Dillon 		usage_create();
265fb9cffefSMatthew Dillon 
266fb9cffefSMatthew Dillon 	while (optind < argc) {
267fb9cffefSMatthew Dillon 		fd = gpt_open(argv[optind++]);
268fb9cffefSMatthew Dillon 		if (fd == -1) {
269fb9cffefSMatthew Dillon 			warn("unable to open device '%s'", device_name);
270fb9cffefSMatthew Dillon 			continue;
271fb9cffefSMatthew Dillon 		}
272fb9cffefSMatthew Dillon 
273fb9cffefSMatthew Dillon 		create(fd);
274fb9cffefSMatthew Dillon 
275fb9cffefSMatthew Dillon 		gpt_close(fd);
276fb9cffefSMatthew Dillon 	}
277fb9cffefSMatthew Dillon 
278fb9cffefSMatthew Dillon 	return (0);
279fb9cffefSMatthew Dillon }
280bd2b9b6fSMatthew Dillon 
281bd2b9b6fSMatthew Dillon /*
282bd2b9b6fSMatthew Dillon  * init
283bd2b9b6fSMatthew Dillon  *
284bd2b9b6fSMatthew Dillon  * Create a fresh gpt partition table and populate it with reasonable
285bd2b9b6fSMatthew Dillon  * defaults.
286bd2b9b6fSMatthew Dillon  */
287bd2b9b6fSMatthew Dillon int
cmd_init(int argc,char * argv[])288bd2b9b6fSMatthew Dillon cmd_init(int argc, char *argv[])
289bd2b9b6fSMatthew Dillon {
290bd2b9b6fSMatthew Dillon 	int ch, fd;
291bd2b9b6fSMatthew Dillon 	int with_boot = 0;
292*d9306807SMatthew Dillon 	int with_trim = 0;
293bd2b9b6fSMatthew Dillon 
294*d9306807SMatthew Dillon 	while ((ch = getopt(argc, argv, "fBEI")) != -1) {
295bd2b9b6fSMatthew Dillon 		switch(ch) {
296bd2b9b6fSMatthew Dillon 		case 'f':
297bd2b9b6fSMatthew Dillon 			force = 1;
298bd2b9b6fSMatthew Dillon 			break;
299bd2b9b6fSMatthew Dillon 		case 'I':
300bd2b9b6fSMatthew Dillon 			fprintf(stderr, "Maybe you were trying to supply "
301bd2b9b6fSMatthew Dillon 					"fdisk options.  This is the gpt "
302bd2b9b6fSMatthew Dillon 					"program\n");
303bd2b9b6fSMatthew Dillon 			usage_init();
304bd2b9b6fSMatthew Dillon 			/* NOT REACHED */
305bd2b9b6fSMatthew Dillon 			break;
306*d9306807SMatthew Dillon 		case 'E':
307*d9306807SMatthew Dillon 			with_trim = 1;
308*d9306807SMatthew Dillon 			break;
309bd2b9b6fSMatthew Dillon 		case 'B':
310bd2b9b6fSMatthew Dillon 			with_boot = 1;
311bd2b9b6fSMatthew Dillon 			break;
312bd2b9b6fSMatthew Dillon 		default:
313bd2b9b6fSMatthew Dillon 			usage_init();
314bd2b9b6fSMatthew Dillon 			/* NOT REACHED */
315bd2b9b6fSMatthew Dillon 			break;
316bd2b9b6fSMatthew Dillon 		}
317bd2b9b6fSMatthew Dillon 	}
318bd2b9b6fSMatthew Dillon 
319bd2b9b6fSMatthew Dillon 	if (argc == optind) {
320bd2b9b6fSMatthew Dillon 		usage_init();
321bd2b9b6fSMatthew Dillon 		/* NOT REACHED */
322bd2b9b6fSMatthew Dillon 	}
323bd2b9b6fSMatthew Dillon 
324bd2b9b6fSMatthew Dillon 	while (optind < argc) {
325bd2b9b6fSMatthew Dillon 		const char *path = argv[optind++];
326bd2b9b6fSMatthew Dillon 		char *slice0;
327bd2b9b6fSMatthew Dillon 		char *slice1;
328bd2b9b6fSMatthew Dillon 
329bd2b9b6fSMatthew Dillon 		/*
330bd2b9b6fSMatthew Dillon 		 * Destroy and [re]Create the gpt
331bd2b9b6fSMatthew Dillon 		 */
332bd2b9b6fSMatthew Dillon 		fd = gpt_open(path);
333bd2b9b6fSMatthew Dillon 		if (fd == -1) {
334*d9306807SMatthew Dillon 			warn("unable to open device '%s'", path);
335bd2b9b6fSMatthew Dillon 			continue;
336bd2b9b6fSMatthew Dillon 		}
337*d9306807SMatthew Dillon 		if (with_trim) {
338*d9306807SMatthew Dillon 			do_erase(fd);
339*d9306807SMatthew Dillon 			gpt_close(fd);
340*d9306807SMatthew Dillon 			sleep(1);
341*d9306807SMatthew Dillon 			fd = gpt_open(path);
342*d9306807SMatthew Dillon 			if (fd == -1) {
343*d9306807SMatthew Dillon 				warn("unable to reopen device '%s'", path);
344*d9306807SMatthew Dillon 				continue;
345*d9306807SMatthew Dillon 			}
346*d9306807SMatthew Dillon 		}
347bd2b9b6fSMatthew Dillon 		do_destroy(fd);
348bd2b9b6fSMatthew Dillon 		gpt_close(fd);
349*d9306807SMatthew Dillon 		sleep(1);
350bd2b9b6fSMatthew Dillon 
351bd2b9b6fSMatthew Dillon 		fd = gpt_open(path);
352bd2b9b6fSMatthew Dillon 		if (fd == -1) {
353bd2b9b6fSMatthew Dillon 			warn("unable to open device '%s'", device_name);
354bd2b9b6fSMatthew Dillon 			continue;
355bd2b9b6fSMatthew Dillon 		}
356bd2b9b6fSMatthew Dillon 		create(fd);
357bd2b9b6fSMatthew Dillon 		add_defaults(fd);
358bd2b9b6fSMatthew Dillon 		gpt_close(fd);
359*d9306807SMatthew Dillon 		sleep(1);
360bd2b9b6fSMatthew Dillon 
361bd2b9b6fSMatthew Dillon 		/*
362bd2b9b6fSMatthew Dillon 		 * Setup slices
363bd2b9b6fSMatthew Dillon 		 */
364bd2b9b6fSMatthew Dillon 		if (strstr(device_name, "serno"))
365bd2b9b6fSMatthew Dillon 			asprintf(&slice0, "%s.s0", device_name);
366bd2b9b6fSMatthew Dillon 		else
367bd2b9b6fSMatthew Dillon 			asprintf(&slice0, "%ss0", device_name);
368bd2b9b6fSMatthew Dillon 
369bd2b9b6fSMatthew Dillon 		if (strstr(device_name, "serno"))
370bd2b9b6fSMatthew Dillon 			asprintf(&slice1, "%s.s1", device_name);
371bd2b9b6fSMatthew Dillon 		else
372bd2b9b6fSMatthew Dillon 			asprintf(&slice1, "%ss1", device_name);
373bd2b9b6fSMatthew Dillon 
374bd2b9b6fSMatthew Dillon 		/*
375bd2b9b6fSMatthew Dillon 		 * Label slice1
376bd2b9b6fSMatthew Dillon 		 */
377bd2b9b6fSMatthew Dillon 		dosys("disklabel -r -w %s %s auto",
378bd2b9b6fSMatthew Dillon 		      (with_boot ? "-B" : ""),
379bd2b9b6fSMatthew Dillon 		      slice1);
380*d9306807SMatthew Dillon 		sleep(1);
381bd2b9b6fSMatthew Dillon 
382bd2b9b6fSMatthew Dillon 		/*
383bd2b9b6fSMatthew Dillon 		 * newfs_msdos slice0
384bd2b9b6fSMatthew Dillon 		 */
385bd2b9b6fSMatthew Dillon 		dosys("newfs_msdos %s", slice0);
386bd2b9b6fSMatthew Dillon 
387bd2b9b6fSMatthew Dillon 		/*
388bd2b9b6fSMatthew Dillon 		 * If asked to setup an EFI boot, mount the dos partition
389bd2b9b6fSMatthew Dillon 		 * and copy a file.
390bd2b9b6fSMatthew Dillon 		 *
391bd2b9b6fSMatthew Dillon 		 * We do not setup the dragonfly disklabel with -B
392bd2b9b6fSMatthew Dillon 		 */
393bd2b9b6fSMatthew Dillon 		if (with_boot) {
394bd2b9b6fSMatthew Dillon 			char *mtpt;
395bd2b9b6fSMatthew Dillon 
396bd2b9b6fSMatthew Dillon 			srandomdev();
397bd2b9b6fSMatthew Dillon 			asprintf(&mtpt, "/tmp/gpt%08x%08x",
398bd2b9b6fSMatthew Dillon 				(int)random(), (int)random());
399bd2b9b6fSMatthew Dillon 			if (mkdir(mtpt, 0700) < 0) {
400bd2b9b6fSMatthew Dillon 				fprintf(stderr, "cannot mkdir %s\n", mtpt);
401bd2b9b6fSMatthew Dillon 				exit(1);
402bd2b9b6fSMatthew Dillon 			}
403bd2b9b6fSMatthew Dillon 
404bd2b9b6fSMatthew Dillon 			dosys("mount_msdos %s %s", slice0, mtpt);
405bd2b9b6fSMatthew Dillon 			dosys("mkdir -p %s/efi/boot", mtpt);
406bd2b9b6fSMatthew Dillon 			dosys("cpdup /boot/boot1.efi %s/efi/boot/bootx64.efi",
407bd2b9b6fSMatthew Dillon 			      mtpt);
408bd2b9b6fSMatthew Dillon 			dosys("umount %s", mtpt);
409bd2b9b6fSMatthew Dillon 		}
410bd2b9b6fSMatthew Dillon 
411bd2b9b6fSMatthew Dillon 		free(slice0);
412bd2b9b6fSMatthew Dillon 		free(slice1);
413bd2b9b6fSMatthew Dillon 	}
414bd2b9b6fSMatthew Dillon 
415bd2b9b6fSMatthew Dillon 	return (0);
416bd2b9b6fSMatthew Dillon }
417*d9306807SMatthew Dillon 
418*d9306807SMatthew Dillon static void
do_erase(int fd)419*d9306807SMatthew Dillon do_erase(int fd)
420*d9306807SMatthew Dillon {
421*d9306807SMatthew Dillon 	off_t ioarg[2];
422*d9306807SMatthew Dillon 
423*d9306807SMatthew Dillon 	ioarg[0] = 0;
424*d9306807SMatthew Dillon 	ioarg[1] = mediasz;
425*d9306807SMatthew Dillon 
426*d9306807SMatthew Dillon 	if (ioctl(fd, DAIOCTRIM, ioarg) < 0) {
427*d9306807SMatthew Dillon 		printf("Trim error %s\n", strerror(errno));
428*d9306807SMatthew Dillon 		printf("Continuing\n");
429*d9306807SMatthew Dillon 	} else {
430*d9306807SMatthew Dillon 		printf("Trim completed ok\n");
431*d9306807SMatthew Dillon 	}
432*d9306807SMatthew Dillon }
433