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