Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/sbin/gpt Add two new options to the "add" subcommand:



details:   https://anonhg.NetBSD.org/src/rev/1b5bfcddc00b
branches:  trunk
changeset: 791454:1b5bfcddc00b
user:      jnemeth <jnemeth%NetBSD.org@localhost>
date:      Tue Nov 19 05:03:41 2013 +0000

description:
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.

diffstat:

 sbin/gpt/add.c |  61 +++++++++++++++++++++++++++++++++++++++++++++++----------
 sbin/gpt/gpt.8 |  16 +++++++++++++-
 sbin/gpt/gpt.c |  10 +++++---
 sbin/gpt/map.c |  41 +++++++++++++++++++++++++++++---------
 sbin/gpt/map.h |   2 +-
 5 files changed, 102 insertions(+), 28 deletions(-)

diffs (296 lines):

diff -r 0a4f3f0a9292 -r 1b5bfcddc00b sbin/gpt/add.c
--- a/sbin/gpt/add.c    Tue Nov 19 03:53:09 2013 +0000
+++ b/sbin/gpt/add.c    Tue Nov 19 05:03:41 2013 +0000
@@ -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 @@
 #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 @@
        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 @@
                }
        }
 
-       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 @@
 {
        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 @@
                        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 @@
                        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);
diff -r 0a4f3f0a9292 -r 1b5bfcddc00b sbin/gpt/gpt.8
--- a/sbin/gpt/gpt.8    Tue Nov 19 03:53:09 2013 +0000
+++ b/sbin/gpt/gpt.8    Tue Nov 19 05:03:41 2013 +0000
@@ -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 @@
 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 @@
 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.
diff -r 0a4f3f0a9292 -r 1b5bfcddc00b sbin/gpt/gpt.c
--- a/sbin/gpt/gpt.c    Tue Nov 19 03:53:09 2013 +0000
+++ b/sbin/gpt/gpt.c    Tue Nov 19 05:03:41 2013 +0000
@@ -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 @@
 __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 @@
            "       %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,
diff -r 0a4f3f0a9292 -r 1b5bfcddc00b sbin/gpt/map.c
--- a/sbin/gpt/map.c    Tue Nov 19 03:53:09 2013 +0000
+++ b/sbin/gpt/map.c    Tue Nov 19 05:03:41 2013 +0000
@@ -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_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 *
diff -r 0a4f3f0a9292 -r 1b5bfcddc00b sbin/gpt/map.h
--- a/sbin/gpt/map.h    Tue Nov 19 03:53:09 2013 +0000
+++ b/sbin/gpt/map.h    Tue Nov 19 05:03:41 2013 +0000
@@ -51,7 +51,7 @@
 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);



Home | Main Index | Thread Index | Old Index