Date: Sun, 7 Jun 2009 20:12:14 +0000 (UTC) From: Marcel Moolenaar <marcel@FreeBSD.org> To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r193648 - in head/sbin/geom: class/part core Message-ID: <200906072012.n57KCEC7004214@svn.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: marcel Date: Sun Jun 7 20:12:14 2009 New Revision: 193648 URL: http://svn.freebsd.org/changeset/base/193648 Log: Allow humanized numbers for LBAs, as well as partition indices for gpart(8). LBAs in particular are ugly. The ganularity is a sector, but users expect byte granularity when specifying the size or offset with a SI unit. Handle LBAs specially to deal with this. Modified: head/sbin/geom/class/part/geom_part.c head/sbin/geom/core/geom.c head/sbin/geom/core/geom.h Modified: head/sbin/geom/class/part/geom_part.c ============================================================================== --- head/sbin/geom/class/part/geom_part.c Sun Jun 7 20:02:32 2009 (r193647) +++ head/sbin/geom/class/part/geom_part.c Sun Jun 7 20:12:14 2009 (r193648) @@ -68,10 +68,10 @@ static void gpart_show(struct gctl_req * struct g_command PUBSYM(class_commands)[] = { { "add", 0, gpart_issue, { - { 'b', "start", NULL, G_TYPE_STRING }, - { 's', "size", NULL, G_TYPE_STRING }, + { 'b', "start", NULL, G_TYPE_ASCLBA }, + { 's', "size", NULL, G_TYPE_ASCLBA }, { 't', "type", NULL, G_TYPE_STRING }, - { 'i', index_param, optional, G_TYPE_STRING }, + { 'i', index_param, optional, G_TYPE_ASCNUM }, { 'l', "label", optional, G_TYPE_STRING }, { 'f', "flags", flags, G_TYPE_STRING }, G_OPT_SENTINEL }, @@ -80,7 +80,7 @@ struct g_command PUBSYM(class_commands)[ { "bootcode", 0, gpart_bootcode, { { 'b', bootcode_param, optional, G_TYPE_STRING }, { 'p', partcode_param, optional, G_TYPE_STRING }, - { 'i', index_param, optional, G_TYPE_STRING }, + { 'i', index_param, optional, G_TYPE_ASCNUM }, { 'f', "flags", flags, G_TYPE_STRING }, G_OPT_SENTINEL }, "geom", NULL @@ -88,13 +88,13 @@ struct g_command PUBSYM(class_commands)[ { "commit", 0, gpart_issue, G_NULL_OPTS, "geom", NULL }, { "create", 0, gpart_issue, { { 's', "scheme", NULL, G_TYPE_STRING }, - { 'n', "entries", optional, G_TYPE_STRING }, + { 'n', "entries", optional, G_TYPE_ASCNUM }, { 'f', "flags", flags, G_TYPE_STRING }, G_OPT_SENTINEL }, "provider", NULL }, { "delete", 0, gpart_issue, { - { 'i', index_param, NULL, G_TYPE_STRING }, + { 'i', index_param, NULL, G_TYPE_ASCNUM }, { 'f', "flags", flags, G_TYPE_STRING }, G_OPT_SENTINEL }, "geom", NULL @@ -104,7 +104,7 @@ struct g_command PUBSYM(class_commands)[ G_OPT_SENTINEL }, "geom", NULL }, { "modify", 0, gpart_issue, { - { 'i', index_param, NULL, G_TYPE_STRING }, + { 'i', index_param, NULL, G_TYPE_ASCNUM }, { 'l', "label", optional, G_TYPE_STRING }, { 't', "type", optional, G_TYPE_STRING }, { 'f', "flags", flags, G_TYPE_STRING }, @@ -113,7 +113,7 @@ struct g_command PUBSYM(class_commands)[ }, { "set", 0, gpart_issue, { { 'a', "attrib", NULL, G_TYPE_STRING }, - { 'i', index_param, NULL, G_TYPE_STRING }, + { 'i', index_param, NULL, G_TYPE_ASCNUM }, { 'f', "flags", flags, G_TYPE_STRING }, G_OPT_SENTINEL }, "geom", NULL @@ -127,7 +127,7 @@ struct g_command PUBSYM(class_commands)[ { "undo", 0, gpart_issue, G_NULL_OPTS, "geom", NULL }, { "unset", 0, gpart_issue, { { 'a', "attrib", NULL, G_TYPE_STRING }, - { 'i', index_param, NULL, G_TYPE_STRING }, + { 'i', index_param, NULL, G_TYPE_ASCNUM }, { 'f', "flags", flags, G_TYPE_STRING }, G_OPT_SENTINEL }, "geom", NULL Modified: head/sbin/geom/core/geom.c ============================================================================== --- head/sbin/geom/core/geom.c Sun Jun 7 20:02:32 2009 (r193647) +++ head/sbin/geom/core/geom.c Sun Jun 7 20:12:14 2009 (r193648) @@ -226,20 +226,117 @@ find_option(struct g_command *cmd, char static void set_option(struct gctl_req *req, struct g_option *opt, const char *val) { + char *s; + intmax_t number; - if (G_OPT_TYPE(opt) == G_TYPE_NUMBER) { - intmax_t number; - + if (G_OPT_TYPE(opt) == G_TYPE_NUMBER || + G_OPT_TYPE(opt) == G_TYPE_ASCNUM) { if (expand_number(val, &number) == -1) { err(EXIT_FAILURE, "Invalid value for '%c' argument.", opt->go_char); } - opt->go_val = malloc(sizeof(intmax_t)); + if (G_OPT_TYPE(opt) == G_TYPE_NUMBER) + opt->go_val = malloc(sizeof(intmax_t)); + else { + asprintf(&s, "%jd", number); + opt->go_val = s; + } if (opt->go_val == NULL) errx(EXIT_FAILURE, "No memory."); - *(intmax_t *)opt->go_val = number; + if (G_OPT_TYPE(opt) == G_TYPE_NUMBER) { + *(intmax_t *)opt->go_val = number; + gctl_ro_param(req, opt->go_name, sizeof(intmax_t), + opt->go_val); + } else + gctl_ro_param(req, opt->go_name, -1, opt->go_val); + } else if (G_OPT_TYPE(opt) == G_TYPE_ASCLBA) { + /* + * LBAs are ugly. The argument is a sector. The size of a + * sector is context specific (i.e. determined by the media), + * which we don't know here. But when users enter a value + * with a SI unit, they really mean the byte-size or byte- + * offset and not the size or offset in sectors. + * So how can we map the byte-oriented value into a sector- + * oriented value if we don't know the sector size in bytes? + * The approach taken here is: + * o Sectors are 512 bytes in size. Mostly the case anyway. + * o When no SI unit is specified the value is in sectors. + * o With an SI unit the value is in bytes. + * o The 'b' suffix forces byte interpretation and the 's' + * suffix forces sector interpretation. + * + * Thus: + * o 2 and 2s mean 2 sectors, and 2b means 2 bytes. + * o 4k and 4kb mean 4096 bytes, and 4ks means 4096 sectors. + * + * "This seemed like a good idea at the time" + */ + intmax_t mult, unit; - gctl_ro_param(req, opt->go_name, sizeof(intmax_t), opt->go_val); + number = strtoimax(val, &s, 0); + if (s == val) + errc(EXIT_FAILURE, EINVAL, "argument '%c'", + opt->go_char); + mult = 1; + unit = 512; /* sector */ + if (*s == '\0') + goto done; + switch (*s) { + case 'e': case 'E': + mult *= 1024; + /*FALLTHROUGH*/ + case 'p': case 'P': + mult *= 1024; + /*FALLTHROUGH*/ + case 't': case 'T': + mult *= 1024; + /*FALLTHROUGH*/ + case 'g': case 'G': + mult *= 1024; + /*FALLTHROUGH*/ + case 'm': case 'M': + mult *= 1024; + /*FALLTHROUGH*/ + case 'k': case 'K': + mult *= 1024; + break; + default: + goto sfx; + } + unit = 1; /* bytes */ + s++; + if (*s == '\0') + goto done; +sfx: + switch (*s) { + case 's': case 'S': + unit = 512; /* sector */ + break; + case 'b': case 'B': + unit = 1; /* bytes */ + break; + default: + errc(EXIT_FAILURE, EINVAL, "argument '%c': suffix '%c'", + opt->go_char, *s); + } + s++; + if (*s != '\0') + errx(EXIT_FAILURE, "argument '%c': junk at end (%s)", + opt->go_char, s); +done: + if (mult * unit < mult || number * mult * unit < number) + errc(EXIT_FAILURE, ERANGE, "argument '%c'", + opt->go_char); + number *= mult * unit; + if (number % 512) + errx(EXIT_FAILURE, "argument '%c': " + "not a valid block address", opt->go_char); + number /= 512; + asprintf(&s, "%jd", number); + if (s == NULL) + err(EXIT_FAILURE, NULL); + opt->go_val = s; + gctl_ro_param(req, opt->go_name, -1, s); } else if (G_OPT_TYPE(opt) == G_TYPE_STRING) { gctl_ro_param(req, opt->go_name, -1, val); } else if (G_OPT_TYPE(opt) == G_TYPE_BOOL) { @@ -247,9 +344,7 @@ set_option(struct gctl_req *req, struct if (opt->go_val == NULL) errx(EXIT_FAILURE, "No memory."); *(int *)opt->go_val = *val - '0'; - - gctl_ro_param(req, opt->go_name, sizeof(int), - opt->go_val); + gctl_ro_param(req, opt->go_name, sizeof(int), opt->go_val); } else { assert(!"Invalid type"); } @@ -333,7 +428,9 @@ parse_arguments(struct g_command *cmd, s if (G_OPT_TYPE(opt) == G_TYPE_NUMBER) { gctl_ro_param(req, opt->go_name, sizeof(intmax_t), opt->go_val); - } else if (G_OPT_TYPE(opt) == G_TYPE_STRING) { + } else if (G_OPT_TYPE(opt) == G_TYPE_STRING || + G_OPT_TYPE(opt) == G_TYPE_ASCNUM || + G_OPT_TYPE(opt) == G_TYPE_ASCLBA) { if (cmd->gc_argname == NULL || opt->go_val == NULL || *(char *)opt->go_val != '\0') Modified: head/sbin/geom/core/geom.h ============================================================================== --- head/sbin/geom/core/geom.h Sun Jun 7 20:02:32 2009 (r193647) +++ head/sbin/geom/core/geom.h Sun Jun 7 20:12:14 2009 (r193648) @@ -28,7 +28,7 @@ #ifndef _GEOM_H_ #define _GEOM_H_ -#define G_LIB_VERSION 3 +#define G_LIB_VERSION 4 #define G_FLAG_NONE 0x0000 #define G_FLAG_VERBOSE 0x0001 @@ -38,7 +38,9 @@ #define G_TYPE_BOOL 0x01 #define G_TYPE_STRING 0x02 #define G_TYPE_NUMBER 0x03 -#define G_TYPE_MASK 0x03 +#define G_TYPE_ASCNUM 0x04 +#define G_TYPE_ASCLBA 0x05 +#define G_TYPE_MASK 0x0f #define G_TYPE_DONE 0x10 #define G_OPT_MAX 16
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200906072012.n57KCEC7004214>