diff options
-rw-r--r-- | usr.bin/mkimg/Makefile | 2 | ||||
-rw-r--r-- | usr.bin/mkimg/mkimg.1 | 27 | ||||
-rw-r--r-- | usr.bin/mkimg/mkimg.c | 50 |
3 files changed, 64 insertions, 15 deletions
diff --git a/usr.bin/mkimg/Makefile b/usr.bin/mkimg/Makefile index c8fdb7d..d635924 100644 --- a/usr.bin/mkimg/Makefile +++ b/usr.bin/mkimg/Makefile @@ -6,7 +6,7 @@ PROG= mkimg SRCS= format.c image.c mkimg.c scheme.c MAN= mkimg.1 -MKIMG_VERSION=20141211 +MKIMG_VERSION=20150222 mkimg.o: Makefile CFLAGS+=-DMKIMG_VERSION=${MKIMG_VERSION} diff --git a/usr.bin/mkimg/mkimg.1 b/usr.bin/mkimg/mkimg.1 index 56cd605..3b1d63e 100644 --- a/usr.bin/mkimg/mkimg.1 +++ b/usr.bin/mkimg/mkimg.1 @@ -24,7 +24,7 @@ .\" .\" $FreeBSD$ .\" -.Dd September 27, 2014 +.Dd February 22, 2015 .Dt MKIMG 1 .Os .Sh NAME @@ -37,13 +37,12 @@ .Op Fl S Ar secsz .Op Fl T Ar tracksz .Op Fl b Ar bootcode +.Op Fl c Ar capacity .Op Fl f Ar format .Op Fl o Ar outfile .Op Fl v .Op Fl y -.Fl s Ar scheme -.Fl p Ar partition -.Op Fl p Ar partition ... +.Op Fl s Ar scheme Op Fl p Ar partition ... .Nm .Ar --formats | --schemes | --version .Sh DESCRIPTION @@ -109,13 +108,29 @@ utility will use the (physical) block size to determine the start of partitions and to round the size of the disk image. .Pp The -.Op Fl v +.Fl c +option can be used to specify a minimal capacity for the disk image. +Use this option without the +.Fl s +and +.Fl p +options to create an empty disk image with the given (virtual) size. +An empty partition table can be written to the disk when specifying a +partitioning scheme with the +.Fl s +option, but without specifying any partitions. +When the size required to for all the partitions is larger than the +given capacity, then the disk image will be larger than the capacity +given. +.Pp +The +.Fl v option increases the level of output that the .Nm utility prints. .Pp The -.Op Fl y +.Fl y option is used for testing purposes only and is not to be used in production. When present, the .Nm diff --git a/usr.bin/mkimg/mkimg.c b/usr.bin/mkimg/mkimg.c index 0528352..5a4b9f9 100644 --- a/usr.bin/mkimg/mkimg.c +++ b/usr.bin/mkimg/mkimg.c @@ -60,6 +60,8 @@ static struct option longopts[] = { { NULL, 0, NULL, 0 } }; +static uint64_t capacity; + struct partlisthead partlist = STAILQ_HEAD_INITIALIZER(partlist); u_int nparts = 0; @@ -147,6 +149,7 @@ usage(const char *why) fprintf(stderr, "\t--version\t- show version information\n"); fputc('\n', stderr); fprintf(stderr, "\t-b <file>\t- file containing boot code\n"); + fprintf(stderr, "\t-c <num>\t- capacity (in bytes) of the disk\n"); fprintf(stderr, "\t-f <format>\n"); fprintf(stderr, "\t-o <file>\t- file to write image into\n"); fprintf(stderr, "\t-p <partition>\n"); @@ -179,7 +182,7 @@ usage(const char *why) } static int -parse_number(u_int *valp, u_int min, u_int max, const char *arg) +parse_uint32(uint32_t *valp, uint32_t min, uint32_t max, const char *arg) { uint64_t val; @@ -187,7 +190,20 @@ parse_number(u_int *valp, u_int min, u_int max, const char *arg) return (errno); if (val > UINT_MAX || val < (uint64_t)min || val > (uint64_t)max) return (EINVAL); - *valp = (u_int)val; + *valp = (uint32_t)val; + return (0); +} + +static int +parse_uint64(uint64_t *valp, uint64_t min, uint64_t max, const char *arg) +{ + uint64_t val; + + if (expand_number(arg, &val) == -1) + return (errno); + if (val < min || val > max) + return (EINVAL); + *valp = val; return (0); } @@ -376,6 +392,17 @@ mkimg_uuid(struct uuid *uuid) memcpy(uuid, gen, sizeof(uuid_t)); } +static int +capacity_resize(lba_t end) +{ + lba_t capsz; + + capsz = (capacity + secsz - 1) / secsz; + if (end >= capsz) + return (0); + return (image_set_size(capsz)); +} + static void mkimg(void) { @@ -437,6 +464,8 @@ mkimg(void) block = scheme_metadata(SCHEME_META_IMG_END, block); error = image_set_size(block); if (!error) + error = capacity_resize(block); + if (!error) error = format_resize(block); if (error) errc(EX_IOERR, error, "image sizing"); @@ -455,7 +484,7 @@ main(int argc, char *argv[]) bcfd = -1; outfd = 1; /* Write to stdout by default */ - while ((c = getopt_long(argc, argv, "b:f:o:p:s:vyH:P:S:T:", + while ((c = getopt_long(argc, argv, "b:c:f:o:p:s:vyH:P:S:T:", longopts, NULL)) != -1) { switch (c) { case 'b': /* BOOT CODE */ @@ -465,6 +494,11 @@ main(int argc, char *argv[]) if (bcfd == -1) err(EX_UNAVAILABLE, "%s", optarg); break; + case 'c': /* CAPACITY */ + error = parse_uint64(&capacity, 1, OFF_MAX, optarg); + if (error) + errc(EX_DATAERR, error, "capacity in bytes"); + break; case 'f': /* OUTPUT FORMAT */ if (format_selected() != NULL) usage("multiple formats given"); @@ -499,26 +533,26 @@ main(int argc, char *argv[]) verbose++; break; case 'H': /* GEOMETRY: HEADS */ - error = parse_number(&nheads, 1, 255, optarg); + error = parse_uint32(&nheads, 1, 255, optarg); if (error) errc(EX_DATAERR, error, "number of heads"); break; case 'P': /* GEOMETRY: PHYSICAL SECTOR SIZE */ - error = parse_number(&blksz, 512, INT_MAX+1U, optarg); + error = parse_uint32(&blksz, 512, INT_MAX+1U, optarg); if (error == 0 && !pwr_of_two(blksz)) error = EINVAL; if (error) errc(EX_DATAERR, error, "physical sector size"); break; case 'S': /* GEOMETRY: LOGICAL SECTOR SIZE */ - error = parse_number(&secsz, 512, INT_MAX+1U, optarg); + error = parse_uint32(&secsz, 512, INT_MAX+1U, optarg); if (error == 0 && !pwr_of_two(secsz)) error = EINVAL; if (error) errc(EX_DATAERR, error, "logical sector size"); break; case 'T': /* GEOMETRY: TRACK SIZE */ - error = parse_number(&nsecs, 1, 63, optarg); + error = parse_uint32(&nsecs, 1, 63, optarg); if (error) errc(EX_DATAERR, error, "track size"); break; @@ -543,7 +577,7 @@ main(int argc, char *argv[]) usage("trailing arguments"); if (scheme_selected() == NULL && nparts > 0) usage("no scheme"); - if (nparts == 0) + if (nparts == 0 && capacity == 0) usage("no partitions"); if (secsz > blksz) { |