Module Name: src Committed By: jnemeth Date: Tue Nov 19 05:03:41 UTC 2013
Modified Files: src/sbin/gpt: add.c gpt.8 gpt.c map.c map.h Log Message: Add two new options to the "add" subcommand: -a alignment -- attempt to align the start and size of the partition -l label -- supply a label for the partition These options were inspired by FreeBSD's gpart(8) command, but the code was written by me. To generate a diff of this commit: cvs rdiff -u -r1.14 -r1.15 src/sbin/gpt/add.c src/sbin/gpt/gpt.8 cvs rdiff -u -r1.20 -r1.21 src/sbin/gpt/gpt.c cvs rdiff -u -r1.3 -r1.4 src/sbin/gpt/map.c cvs rdiff -u -r1.1.1.1 -r1.2 src/sbin/gpt/map.h Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/sbin/gpt/add.c diff -u src/sbin/gpt/add.c:1.14 src/sbin/gpt/add.c:1.15 --- src/sbin/gpt/add.c:1.14 Sun May 26 21:26:17 2013 +++ src/sbin/gpt/add.c Tue Nov 19 05:03:41 2013 @@ -29,7 +29,7 @@ __FBSDID("$FreeBSD: src/sbin/gpt/add.c,v 1.14 2006/06/22 22:05:28 marcel Exp $"); #endif #ifdef __RCSID -__RCSID("$NetBSD: add.c,v 1.14 2013/05/26 21:26:17 wiz Exp $"); +__RCSID("$NetBSD: add.c,v 1.15 2013/11/19 05:03:41 jnemeth Exp $"); #endif #include <sys/types.h> @@ -46,19 +46,21 @@ __RCSID("$NetBSD: add.c,v 1.14 2013/05/2 #include "gpt.h" static uuid_t type; -static off_t block, size; +static off_t alignment, block, size; static unsigned int entry; +static uint8_t *name; -const char addmsg[] = "add [-b lba] [-i index] [-s lba] [-t type] " - "device ..."; +const char addmsg1[] = "add [-a alignment] [-b lba] [-i index] [-l label]"; +const char addmsg2[] = " [-s lba] [-t type] device ..."; __dead static void usage_add(void) { fprintf(stderr, - "usage: %s %s\n", - getprogname(), addmsg); + "usage: %s %s\n" + " %*s %s\n", getprogname(), addmsg1, + (int)strlen(getprogname()), "", addmsg2); exit(1); } @@ -72,6 +74,8 @@ add(int fd) struct gpt_hdr *hdr; struct gpt_ent *ent; unsigned int i; + off_t alignsecs; + gpt = map_find(MAP_TYPE_PRI_GPT_HDR); ent = NULL; @@ -128,15 +132,30 @@ add(int fd) } } - map = map_alloc(block, size); - if (map == NULL) { - warnx("%s: error: not enough space available on device", device_name); - return; + if (alignment > 0) { + alignsecs = alignment / secsz; + map = map_alloc(block, size, alignsecs); + if (map == NULL) { + warnx("%s: error: not enough space available on device for an aligned partition", device_name); + map = map_alloc(block, size, 0); + if (map == NULL) { + warnx("%s: error: not enough available on device", device_name); + return; + } + } + } else { + map = map_alloc(block, size, 0); + if (map == NULL) { + warnx("%s: error: not enough space available on device", device_name); + return; + } } le_uuid_enc(ent->ent_type, &type); ent->ent_lba_start = htole64(map->map_start); ent->ent_lba_end = htole64(map->map_start + map->map_size - 1LL); + if (name != NULL) + utf8_to_utf16(name, ent->ent_name, 36); hdr->hdr_crc_table = htole32(crc32(tbl->map_data, le32toh(hdr->hdr_entries) * le32toh(hdr->hdr_entsz))); @@ -177,10 +196,18 @@ cmd_add(int argc, char *argv[]) { char *p; int ch, fd; + int64_t human_num; /* Get the migrate options */ - while ((ch = getopt(argc, argv, "b:i:s:t:")) != -1) { + while ((ch = getopt(argc, argv, "a:b:i:l:s:t:")) != -1) { switch(ch) { + case 'a': + if (alignment > 0) + usage_add(); + if (dehumanize_number(optarg, &human_num) < 0) + usage_add(); + alignment = human_num; + break; case 'b': if (block > 0) usage_add(); @@ -195,6 +222,11 @@ cmd_add(int argc, char *argv[]) if (*p != 0 || entry < 1) usage_add(); break; + case 'l': + if (name != NULL) + usage_add(); + name = (uint8_t *)strdup(optarg); + break; case 's': if (size > 0) usage_add(); @@ -229,6 +261,13 @@ cmd_add(int argc, char *argv[]) continue; } + if (alignment % secsz != 0) { + warnx("Alignment must be a multiple of sector size; "); + warnx("the sector size for %s is %d bytes.", + device_name, secsz); + continue; + } + add(fd); gpt_close(fd); Index: src/sbin/gpt/gpt.8 diff -u src/sbin/gpt/gpt.8:1.14 src/sbin/gpt/gpt.8:1.15 --- src/sbin/gpt/gpt.8:1.14 Thu Oct 24 06:59:03 2013 +++ src/sbin/gpt/gpt.8 Tue Nov 19 05:03:41 2013 @@ -1,4 +1,4 @@ -.\" $NetBSD: gpt.8,v 1.14 2013/10/24 06:59:03 jnemeth Exp $ +.\" $NetBSD: gpt.8,v 1.15 2013/11/19 05:03:41 jnemeth Exp $ .\" .\" Copyright (c) 2002 Marcel Moolenaar .\" All rights reserved. @@ -26,7 +26,7 @@ .\" .\" $FreeBSD: src/sbin/gpt/gpt.8,v 1.17 2006/06/22 22:22:32 marcel Exp $ .\" -.Dd October 23, 2013 +.Dd November 18, 2013 .Dt GPT 8 .Os .Sh NAME @@ -104,6 +104,14 @@ of an unused disk space. The command-specific options can be used to control this behaviour. .Pp The +.Fl a Ar alignment +option allows the user to specify an alignment for the start and size. +The alignment may have a suffix to indicate its magnitude. +.Nm +will attempt to align the partition. +If it can not, then it will attempt to create an unaligned partition. +.Pp +The .Fl b Ar number option allows the user to specify the starting (beginning) sector number of the partition. @@ -117,6 +125,10 @@ be used for the new partition. By default, the first free entry is selected. .Pp The +.Fl l Ar label +option allows the user to specify a label for the partition. +.Pp +The .Fl s Ar count option allows the user to specify the size of the partition in sectors. The minimum size is 1. Index: src/sbin/gpt/gpt.c diff -u src/sbin/gpt/gpt.c:1.20 src/sbin/gpt/gpt.c:1.21 --- src/sbin/gpt/gpt.c:1.20 Sat Apr 13 18:32:01 2013 +++ src/sbin/gpt/gpt.c Tue Nov 19 05:03:41 2013 @@ -31,7 +31,7 @@ __FBSDID("$FreeBSD: src/sbin/gpt/gpt.c,v 1.16 2006/07/07 02:44:23 marcel Exp $"); #endif #ifdef __RCSID -__RCSID("$NetBSD: gpt.c,v 1.20 2013/04/13 18:32:01 jakllsch Exp $"); +__RCSID("$NetBSD: gpt.c,v 1.21 2013/11/19 05:03:41 jnemeth Exp $"); #endif #include <sys/param.h> @@ -784,8 +784,8 @@ static struct { __dead static void usage(void) { - extern const char addmsg[], biosbootmsg[], createmsg[], destroymsg[]; - extern const char labelmsg1[], labelmsg2[], labelmsg3[]; + extern const char addmsg1[], addmsg2[], biosbootmsg[], createmsg[]; + extern const char destroymsg[], labelmsg1[], labelmsg2[], labelmsg3[]; extern const char migratemsg[], recovermsg[], removemsg1[]; extern const char removemsg2[], showmsg[]; @@ -796,13 +796,15 @@ usage(void) " %s %s\n" " %s %s\n" " %s %s\n" + " %s %s\n" " %*s %s\n" " %s %s\n" " %s %s\n" " %s %s\n" " %s %s\n" " %s %s\n", - getprogname(), addmsg, + getprogname(), addmsg1, + getprogname(), addmsg2, getprogname(), biosbootmsg, getprogname(), createmsg, getprogname(), destroymsg, Index: src/sbin/gpt/map.c diff -u src/sbin/gpt/map.c:1.3 src/sbin/gpt/map.c:1.4 --- src/sbin/gpt/map.c:1.3 Sat Oct 26 20:31:23 2013 +++ src/sbin/gpt/map.c Tue Nov 19 05:03:41 2013 @@ -29,7 +29,7 @@ __FBSDID("$FreeBSD: src/sbin/gpt/map.c,v 1.6 2005/08/31 01:47:19 marcel Exp $"); #endif #ifdef __RCSID -__RCSID("$NetBSD: map.c,v 1.3 2013/10/26 20:31:23 jnemeth Exp $"); +__RCSID("$NetBSD: map.c,v 1.4 2013/11/19 05:03:41 jnemeth Exp $"); #endif #include <sys/types.h> @@ -141,28 +141,49 @@ map_add(off_t start, off_t size, int typ } map_t * -map_alloc(off_t start, off_t size) +map_alloc(off_t start, off_t size, off_t alignment) { off_t delta; map_t *m; + if (alignment > 0) { + if ((start % alignment) != 0) + start = (start + alignment) / alignment * alignment; + if ((size % alignment) != 0) + size = (size + alignment) / alignment * alignment; + } + for (m = mediamap; m != NULL; m = m->map_next) { if (m->map_type != MAP_TYPE_UNUSED || m->map_start < 2) continue; if (start != 0 && m->map_start > start) return (NULL); - delta = (start != 0) ? start - m->map_start : 0; - if (size == 0 || m->map_size - delta >= size) { - if (m->map_size - delta <= 0) + + if (start != 0) + delta = start - m->map_start; + else if (alignment > 0 && m->map_start % alignment != 0) + delta = (m->map_start + alignment) / + alignment * alignment - m->map_start; + else + delta = 0; + + if (size == 0 || m->map_size - delta >= size) { + if (m->map_size - delta < alignment) continue; - if (size == 0) - size = m->map_size - delta; - return (map_add(m->map_start + delta, size, - MAP_TYPE_GPT_PART, NULL)); + if (size == 0) { + if (alignment > 0 && + (m->map_size - delta) % alignment != 0) + size = (m->map_size - delta) / + alignment * alignment; + else + size = m->map_size - delta; + } + return map_add(m->map_start + delta, size, + MAP_TYPE_GPT_PART, NULL); } } - return (NULL); + return NULL; } map_t * Index: src/sbin/gpt/map.h diff -u src/sbin/gpt/map.h:1.1.1.1 src/sbin/gpt/map.h:1.2 --- src/sbin/gpt/map.h:1.1.1.1 Sun Oct 15 22:34:16 2006 +++ src/sbin/gpt/map.h Tue Nov 19 05:03:41 2013 @@ -51,7 +51,7 @@ typedef struct map { extern int lbawidth; map_t *map_add(off_t, off_t, int, void*); -map_t *map_alloc(off_t, off_t); +map_t *map_alloc(off_t, off_t, off_t); map_t *map_find(int); map_t *map_first(void); map_t *map_last(void);