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);