summaryrefslogtreecommitdiffstats
path: root/sbin/gpt/create.c
diff options
context:
space:
mode:
Diffstat (limited to 'sbin/gpt/create.c')
-rw-r--r--sbin/gpt/create.c245
1 files changed, 0 insertions, 245 deletions
diff --git a/sbin/gpt/create.c b/sbin/gpt/create.c
deleted file mode 100644
index 24a6a6d..0000000
--- a/sbin/gpt/create.c
+++ /dev/null
@@ -1,245 +0,0 @@
-/*-
- * Copyright (c) 2002 Marcel Moolenaar
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
-#include <sys/types.h>
-
-#include <err.h>
-#include <stddef.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
-
-#include "map.h"
-#include "gpt.h"
-
-static int force;
-static int primary_only;
-
-static void
-usage_create(void)
-{
-
- fprintf(stderr,
- "usage: %s [-fp] device ...\n", getprogname());
- exit(1);
-}
-
-static void
-create(int fd)
-{
- uuid_t uuid;
- off_t blocks, last;
- map_t *gpt, *tpg;
- map_t *tbl, *lbt;
- map_t *map;
- struct mbr *mbr;
- struct gpt_hdr *hdr;
- struct gpt_ent *ent;
- unsigned int i;
-
- last = mediasz / secsz - 1LL;
-
- if (map_find(MAP_TYPE_PRI_GPT_HDR) != NULL ||
- map_find(MAP_TYPE_SEC_GPT_HDR) != NULL) {
- warnx("%s: error: device already contains a GPT", device_name);
- return;
- }
- map = map_find(MAP_TYPE_MBR);
- if (map != NULL) {
- if (!force) {
- warnx("%s: error: device contains a MBR", device_name);
- return;
- }
-
- /* Nuke the MBR in our internal map. */
- map->map_type = MAP_TYPE_UNUSED;
- }
-
- /*
- * Create PMBR.
- */
- if (map_find(MAP_TYPE_PMBR) == NULL) {
- if (map_free(0LL, 1LL) == 0) {
- warnx("%s: error: no room for the PMBR", device_name);
- return;
- }
- mbr = gpt_read(fd, 0LL, 1);
- bzero(mbr, sizeof(*mbr));
- mbr->mbr_sig = htole16(MBR_SIG);
- mbr->mbr_part[0].part_shd = 0xff;
- mbr->mbr_part[0].part_ssect = 0xff;
- mbr->mbr_part[0].part_scyl = 0xff;
- mbr->mbr_part[0].part_typ = 0xee;
- mbr->mbr_part[0].part_ehd = 0xff;
- mbr->mbr_part[0].part_esect = 0xff;
- mbr->mbr_part[0].part_ecyl = 0xff;
- mbr->mbr_part[0].part_start_lo = htole16(1);
- if (last > 0xffffffff) {
- mbr->mbr_part[0].part_size_lo = htole16(0xffff);
- mbr->mbr_part[0].part_size_hi = htole16(0xffff);
- } else {
- mbr->mbr_part[0].part_size_lo = htole16(last);
- mbr->mbr_part[0].part_size_hi = htole16(last >> 16);
- }
- map = map_add(0LL, 1LL, MAP_TYPE_PMBR, mbr);
- gpt_write(fd, map);
- }
-
- /* Get the amount of free space after the MBR */
- blocks = map_free(1LL, 0LL);
- if (blocks == 0LL) {
- warnx("%s: error: no room for the GPT header", device_name);
- return;
- }
-
- /* Don't create more than parts entries. */
- if ((uint64_t)(blocks - 1) * secsz > parts * sizeof(struct gpt_ent)) {
- blocks = (parts * sizeof(struct gpt_ent)) / secsz;
- if ((parts * sizeof(struct gpt_ent)) % secsz)
- blocks++;
- blocks++; /* Don't forget the header itself */
- }
-
- /* Never cross the median of the device. */
- if ((blocks + 1LL) > ((last + 1LL) >> 1))
- blocks = ((last + 1LL) >> 1) - 1LL;
-
- /*
- * Get the amount of free space at the end of the device and
- * calculate the size for the GPT structures.
- */
- map = map_last();
- if (map->map_type != MAP_TYPE_UNUSED) {
- warnx("%s: error: no room for the backup header", device_name);
- return;
- }
-
- if (map->map_size < blocks)
- blocks = map->map_size;
- if (blocks == 1LL) {
- warnx("%s: error: no room for the GPT table", device_name);
- return;
- }
-
- blocks--; /* Number of blocks in the GPT table. */
- gpt = map_add(1LL, 1LL, MAP_TYPE_PRI_GPT_HDR, calloc(1, secsz));
- tbl = map_add(2LL, blocks, MAP_TYPE_PRI_GPT_TBL,
- calloc(blocks, secsz));
- if (gpt == NULL || tbl == NULL)
- return;
-
- hdr = gpt->map_data;
- memcpy(hdr->hdr_sig, GPT_HDR_SIG, sizeof(hdr->hdr_sig));
- hdr->hdr_revision = htole32(GPT_HDR_REVISION);
- /*
- * XXX struct gpt_hdr is not a multiple of 8 bytes in size and thus
- * contains padding we must not include in the size.
- */
- hdr->hdr_size = htole32(offsetof(struct gpt_hdr, padding));
- hdr->hdr_lba_self = htole64(gpt->map_start);
- hdr->hdr_lba_alt = htole64(last);
- hdr->hdr_lba_start = htole64(tbl->map_start + blocks);
- hdr->hdr_lba_end = htole64(last - blocks - 1LL);
- uuid_create(&uuid, NULL);
- le_uuid_enc(&hdr->hdr_uuid, &uuid);
- hdr->hdr_lba_table = htole64(tbl->map_start);
- hdr->hdr_entries = htole32((blocks * secsz) / sizeof(struct gpt_ent));
- if (le32toh(hdr->hdr_entries) > parts)
- hdr->hdr_entries = htole32(parts);
- hdr->hdr_entsz = htole32(sizeof(struct gpt_ent));
-
- ent = tbl->map_data;
- for (i = 0; i < le32toh(hdr->hdr_entries); i++) {
- uuid_create(&uuid, NULL);
- le_uuid_enc(&ent[i].ent_uuid, &uuid);
- }
-
- hdr->hdr_crc_table = htole32(crc32(ent, le32toh(hdr->hdr_entries) *
- le32toh(hdr->hdr_entsz)));
- hdr->hdr_crc_self = htole32(crc32(hdr, le32toh(hdr->hdr_size)));
-
- gpt_write(fd, gpt);
- gpt_write(fd, tbl);
-
- /*
- * Create backup GPT if the user didn't suppress it.
- */
- if (!primary_only) {
- tpg = map_add(last, 1LL, MAP_TYPE_SEC_GPT_HDR,
- calloc(1, secsz));
- lbt = map_add(last - blocks, blocks, MAP_TYPE_SEC_GPT_TBL,
- tbl->map_data);
- memcpy(tpg->map_data, gpt->map_data, secsz);
- hdr = tpg->map_data;
- hdr->hdr_lba_self = htole64(tpg->map_start);
- hdr->hdr_lba_alt = htole64(gpt->map_start);
- hdr->hdr_lba_table = htole64(lbt->map_start);
- hdr->hdr_crc_self = 0; /* Don't ever forget this! */
- hdr->hdr_crc_self = htole32(crc32(hdr, le32toh(hdr->hdr_size)));
- gpt_write(fd, lbt);
- gpt_write(fd, tpg);
- }
-}
-
-int
-cmd_create(int argc, char *argv[])
-{
- int ch, fd;
-
- while ((ch = getopt(argc, argv, "fp")) != -1) {
- switch(ch) {
- case 'f':
- force = 1;
- break;
- case 'p':
- primary_only = 1;
- break;
- default:
- usage_create();
- }
- }
-
- if (argc == optind)
- usage_create();
-
- while (optind < argc) {
- fd = gpt_open(argv[optind++]);
- if (fd == -1) {
- warn("unable to open device '%s'", device_name);
- continue;
- }
-
- create(fd);
-
- gpt_close(fd);
- }
-
- return (0);
-}
OpenPOWER on IntegriCloud