Index: head/usr.bin/mkimg/mkimg.1 =================================================================== --- head/usr.bin/mkimg/mkimg.1 +++ head/usr.bin/mkimg/mkimg.1 @@ -24,7 +24,7 @@ .\" .\" $FreeBSD$ .\" -.Dd August 7, 2015 +.Dd April 26, 2017 .Dt MKIMG 1 .Os .Sh NAME @@ -37,7 +37,9 @@ .Op Fl S Ar secsz .Op Fl T Ar tracksz .Op Fl b Ar bootcode -.Op Fl c Ar capacity +.Op Fl c Ar min_capacity +.Op Fl C Ar max_capacity +.Op Fl -capacity Ar capacity .Op Fl f Ar format .Op Fl o Ar outfile .Op Fl a Ar active @@ -125,6 +127,18 @@ given. .Pp The +.Fl C +option specifies a maximum capacity for the disk image. +If the combined sizes of the given partitions exceed the size given with +.Fl C , +image creation fails. +.Pp +The +.Fl -capacity +option is a shorthand to specify the minimum and maximum capacity at the +same time. +.Pp +The .Fl v option increases the level of output that the .Nm Index: head/usr.bin/mkimg/mkimg.c =================================================================== --- head/usr.bin/mkimg/mkimg.c +++ head/usr.bin/mkimg/mkimg.c @@ -27,6 +27,7 @@ #include __FBSDID("$FreeBSD$"); +#include #include #include #include @@ -46,18 +47,21 @@ #include "mkimg.h" #include "scheme.h" -#define LONGOPT_FORMATS 0x01000001 -#define LONGOPT_SCHEMES 0x01000002 -#define LONGOPT_VERSION 0x01000003 +#define LONGOPT_FORMATS 0x01000001 +#define LONGOPT_SCHEMES 0x01000002 +#define LONGOPT_VERSION 0x01000003 +#define LONGOPT_CAPACITY 0x01000004 static struct option longopts[] = { { "formats", no_argument, NULL, LONGOPT_FORMATS }, { "schemes", no_argument, NULL, LONGOPT_SCHEMES }, { "version", no_argument, NULL, LONGOPT_VERSION }, + { "capacity", required_argument, NULL, LONGOPT_CAPACITY }, { NULL, 0, NULL, 0 } }; -static uint64_t capacity; +static uint64_t min_capacity = 0; +static uint64_t max_capacity = 0; struct partlisthead partlist = TAILQ_HEAD_INITIALIZER(partlist); u_int nparts = 0; @@ -148,7 +152,8 @@ fputc('\n', stderr); fprintf(stderr, "\t-a \t- mark num'th partion as active\n"); fprintf(stderr, "\t-b \t- file containing boot code\n"); - fprintf(stderr, "\t-c \t- capacity (in bytes) of the disk\n"); + fprintf(stderr, "\t-c \t- minimum capacity (in bytes) of the disk\n"); + fprintf(stderr, "\t-C \t- maximum capacity (in bytes) of the disk\n"); fprintf(stderr, "\t-f \n"); fprintf(stderr, "\t-o \t- file to write image into\n"); fprintf(stderr, "\t-p \n"); @@ -378,12 +383,17 @@ static int capacity_resize(lba_t end) { - lba_t capsz; + lba_t min_capsz, max_capsz; - capsz = (capacity + secsz - 1) / secsz; - if (end >= capsz) + min_capsz = (min_capacity + secsz - 1) / secsz; + max_capsz = (max_capacity + secsz - 1) / secsz; + + if (max_capsz != 0 && end > max_capsz) + return (ENOSPC); + if (end >= min_capsz) return (0); - return (image_set_size(capsz)); + + return (image_set_size(min_capsz)); } static void @@ -470,7 +480,7 @@ bcfd = -1; outfd = 1; /* Write to stdout by default */ - while ((c = getopt_long(argc, argv, "a:b:c:f:o:p:s:vyH:P:S:T:", + while ((c = getopt_long(argc, argv, "a:b:c:C:f:o:p:s:vyH:P:S:T:", longopts, NULL)) != -1) { switch (c) { case 'a': /* ACTIVE PARTITION, if supported */ @@ -485,10 +495,15 @@ if (bcfd == -1) err(EX_UNAVAILABLE, "%s", optarg); break; - case 'c': /* CAPACITY */ - error = parse_uint64(&capacity, 1, INT64_MAX, optarg); + case 'c': /* MINIMUM CAPACITY */ + error = parse_uint64(&min_capacity, 1, INT64_MAX, optarg); if (error) - errc(EX_DATAERR, error, "capacity in bytes"); + errc(EX_DATAERR, error, "minimum capacity in bytes"); + break; + case 'C': /* MAXIMUM CAPACITY */ + error = parse_uint64(&max_capacity, 1, INT64_MAX, optarg); + if (error) + errc(EX_DATAERR, error, "maximum capacity in bytes"); break; case 'f': /* OUTPUT FORMAT */ if (format_selected() != NULL) @@ -559,6 +574,12 @@ print_version(); exit(EX_OK); /*NOTREACHED*/ + case LONGOPT_CAPACITY: + error = parse_uint64(&min_capacity, 1, INT64_MAX, optarg); + if (error) + errc(EX_DATAERR, error, "capacity in bytes"); + max_capacity = min_capacity; + break; default: usage("unknown option"); } @@ -568,8 +589,10 @@ usage("trailing arguments"); if (scheme_selected() == NULL && nparts > 0) usage("no scheme"); - if (nparts == 0 && capacity == 0) + if (nparts == 0 && min_capacity == 0) usage("no partitions"); + if (max_capacity != 0 && min_capacity > max_capacity) + usage("minimum capacity cannot be larger than the maximum one"); if (secsz > blksz) { if (blksz != 0)