[Cluster-devel] [PATCH 1/6] mkfs.gfs2: Add options for stripe size and width
Andrew Price
anprice at redhat.com
Tue May 14 11:21:45 UTC 2013
On 14/05/13 11:49, Steven Whitehouse wrote:
> Hi,
>
> On Tue, 2013-05-14 at 11:45 +0100, Andrew Price wrote:
>> Add generic parsing of options passed in with -o and use it to accept
>> sunit and swidth options (names chosen to be the same as mkfs.xfs). We
>> don't do anything with these options yet.
>>
>> Signed-off-by: Andrew Price <anprice at redhat.com>
>> ---
>> gfs2/mkfs/main_mkfs.c | 107 +++++++++++++++++++++++++++++++++++++++++++++++++-
>> 1 file changed, 105 insertions(+), 2 deletions(-)
>>
>> diff --git a/gfs2/mkfs/main_mkfs.c b/gfs2/mkfs/main_mkfs.c
>> index 610a641..8d5549d 100644
>> --- a/gfs2/mkfs/main_mkfs.c
>> +++ b/gfs2/mkfs/main_mkfs.c
>> @@ -19,6 +19,7 @@
>> #include <sys/time.h>
>> #include <libintl.h>
>> #include <sys/ioctl.h>
>> +#include <limits.h>
>>
>> #define _(String) gettext(String)
>>
>> @@ -55,6 +56,7 @@ static void print_usage(const char *prog_name)
>> "-j", _("<number>"), _("Number of journals"),
>> "-K", NULL, _("Don't try to discard unused blocks"),
>> "-O", NULL, _("Don't ask for confirmation"),
>> + "-o", _("<key>[=<value>][,...]"), _("Specify extended options"),
>> "-p", _("<name>"), _("Name of the locking protocol"),
>> "-q", NULL, _("Don't print anything"),
>> "-r", _("<size>"), _("Size of resource groups, in megabytes"),
>> @@ -73,7 +75,7 @@ static void print_usage(const char *prog_name)
>> option = options[i];
>> param = options[i+1];
>> desc = options[i+2];
>> - printf("%3s %-15s %s\n", option, param ? param : "", desc);
>> + printf("%3s %-22s %s\n", option, param ? param : "", desc);
>> }
>> }
>>
>> @@ -82,6 +84,8 @@ struct mkfs_opts {
>> unsigned qcsize;
>> unsigned jsize;
>> unsigned rgsize;
>> + unsigned sunit;
>> + unsigned swidth;
>> uint64_t fssize;
>> uint32_t journals;
>> const char *lockproto;
>> @@ -93,6 +97,8 @@ struct mkfs_opts {
>> unsigned got_qcsize:1;
>> unsigned got_jsize:1;
>> unsigned got_rgsize:1;
>> + unsigned got_sunit:1;
>> + unsigned got_swidth:1;
>> unsigned got_fssize:1;
>> unsigned got_journals:1;
>> unsigned got_lockproto:1;
>> @@ -145,11 +151,95 @@ static int discard_blocks(int fd, uint64_t len, int debug)
>> return 0;
>> }
>>
>> +/**
>> + * Convert a human-readable size string to a long long.
>> + * Copied and adapted from xfs_mkfs.c.
>> + */
>> +static long long cvtnum(unsigned int blocksize, unsigned int sectorsize, char *s)
>> +{
>> + long long i;
>> + char *sp;
>> +
>> + i = strtoll(s, &sp, 0);
>> + if (i == 0 && sp == s)
>> + return -1LL;
>> + if (*sp == '\0')
>> + return i;
>> +
>> + *sp = tolower(*sp);
>> + if (*sp == 'b' && sp[1] == '\0') {
>> + if (blocksize)
>> + return i * blocksize;
>> + fprintf(stderr, _("Block size not available yet.\n"));
>> + exit(1);
>> + }
>> + if (*sp == 's' && sp[1] == '\0') {
>> + if (sectorsize)
>> + return i * sectorsize;
>> + return i * GFS2_BASIC_BLOCK;
>> + }
>> + if (*sp == 'k' && sp[1] == '\0')
>> + return 1024LL * i;
>> + if (*sp == 'm' && sp[1] == '\0')
>> + return 1024LL * 1024LL * i;
>> + if (*sp == 'g' && sp[1] == '\0')
>> + return 1024LL * 1024LL * 1024LL * i;
>> + if (*sp == 't' && sp[1] == '\0')
>> + return 1024LL * 1024LL * 1024LL * 1024LL * i;
>> + if (*sp == 'p' && sp[1] == '\0')
>> + return 1024LL * 1024LL * 1024LL * 1024LL * 1024LL * i;
>> + if (*sp == 'e' && sp[1] == '\0')
>> + return 1024LL * 1024LL * 1024LL * 1024LL * 1024LL * 1024LL * i;
>> + return -1LL;
>> +}
>> +
>> +static void opt_tok_unsigned(struct mkfs_opts *opts, char *s, unsigned *n, const char *key)
>> +{
>> + long long l;
>> + char *val = strtok_r(NULL, "=", &s);
>> + if (val == NULL || *val == '\0') {
>> + fprintf(stderr, _("Missing argument to '%s'\n"), key);
>> + exit(-1);
>> + }
>> + l = cvtnum(opts->bsize, 0, val);
>> + if (l > UINT_MAX || l < 0) {
>> + fprintf(stderr, _("Value of '%s' is invalid\n"), key);
>> + exit(-1);
>> + }
>> + *n = (unsigned)l;
>> +}
>> +
>> +static void opt_parse_options(char *str, struct mkfs_opts *opts)
>> +{
>> + char *tok;
>> + char *key;
>> + char *o, *a;
>> +
>> + for (tok = strtok_r(str, ",", &o); tok != NULL; tok = strtok_r(NULL, ",", &o)) {
>> + key = strtok_r(tok, "=", &a);
>> + if (key == NULL || *key == '\0') {
>> + fprintf(stderr, _("Missing argument to '-o' option\n"));
>> + exit(-1);
>> + }
>> + if (strcmp("sunit", key) == 0) {
>> + opt_tok_unsigned(opts, a, &opts->sunit, "sunit");
>> + opts->got_sunit = 1;
>> + } else if (strcmp("swidth", key) == 0) {
>> + opt_tok_unsigned(opts, a, &opts->swidth, "swidth");
>> + opts->got_swidth = 1;
>> + } else {
>> + fprintf(stderr, _("Invalid option '%s'\n"), key);
>> + exit(-1);
>> + }
>> + }
>> +}
>> +
> Hmm, strsep maybe better than strtok_r perhaps?
It could be cleaner I guess. I'll give it a try.
>> static void opts_get(int argc, char *argv[], struct mkfs_opts *opts)
>> {
>> int c;
>> + char *o = NULL;
>> while (1) {
>> - c = getopt(argc, argv, "-b:c:DhJ:j:KOp:qr:t:VX");
>> + c = getopt(argc, argv, "-b:c:DhJ:j:KOo:p:qr:t:VX");
>> if (c == -1)
>> break;
>>
>> @@ -197,6 +287,10 @@ static void opts_get(int argc, char *argv[], struct mkfs_opts *opts)
>> opts->rgsize = atoi(optarg);
>> opts->got_rgsize = 1;
>> break;
>> + case 'o':
>> + /* Defer until the other options are gathered */
>> + o = optarg;
>> + break;
>> case 'V':
>> printf("mkfs.gfs2 %s (built %s %s)\n", VERSION,
>> __DATE__, __TIME__);
>> @@ -228,6 +322,8 @@ static void opts_get(int argc, char *argv[], struct mkfs_opts *opts)
>> break;
>> };
>> }
>> + if (o)
>> + opt_parse_options(o, opts);
>
> Looks like this might silently ignore multiple -o options, only parsing
> the last one?
Hm good point, I hadn't thought of multiple -o's. Will redo this one.
Thanks,
Andy
>
>> }
>>
>> /**
>> @@ -655,6 +751,8 @@ static void sbd_init(struct gfs2_sbd *sdp, struct mkfs_opts *opts, struct lgfs2_
>> printf(" rgsize = %u\n", sdp->rgsize);
>> printf(" table = %s\n", sdp->locktable);
>> printf(" fssize = %"PRIu64"\n", opts->fssize);
>> + printf(" sunit = %u\n", opts->sunit);
>> + printf(" swidth = %u\n", opts->swidth);
>> }
>> }
>>
>> @@ -673,6 +771,11 @@ void main_mkfs(int argc, char *argv[])
>> opts_init(&opts);
>> opts_get(argc, argv, &opts);
>>
>> + if (!opts.got_device) {
>> + fprintf(stderr, _("No device specified. Use -h for help\n"));
>> + exit(1);
>> + }
>> +
>> fd = open(opts.device, O_RDWR | O_CLOEXEC);
>> if (fd < 0){
>> perror(opts.device);
>
> Otherwise looks good,
>
> Steve.
>
>
More information about the Cluster-devel
mailing list