From e4538d7f16467dec857ab8e8974664043aebed5a Mon Sep 17 00:00:00 2001 From: marcel Date: Wed, 17 Jun 2015 19:03:32 +0000 Subject: MFC 279125, 279126, 279128, 279139: Add the -c option for specifying the capacity of the disk image. Bump the version to 20150222. --- usr.bin/mkimg/Makefile | 2 +- usr.bin/mkimg/mkimg.1 | 27 ++++++++++++++++++----- usr.bin/mkimg/mkimg.c | 59 ++++++++++++++++++++++++++++++++++++++++---------- usr.bin/mkimg/scheme.c | 17 ++++++++------- 4 files changed, 78 insertions(+), 27 deletions(-) (limited to 'usr.bin/mkimg') diff --git a/usr.bin/mkimg/Makefile b/usr.bin/mkimg/Makefile index 7bdf0b2..9fe18e5 100644 --- a/usr.bin/mkimg/Makefile +++ b/usr.bin/mkimg/Makefile @@ -4,7 +4,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 b55ee7e..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 \t- file containing boot code\n"); + fprintf(stderr, "\t-c \t- 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"); @@ -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,12 +464,14 @@ 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"); block = image_get_size(); ncyls = block / (nsecs * nheads); - error = (scheme_write(block)); + error = scheme_write(block); if (error) errc(EX_IOERR, error, "writing metadata"); } @@ -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; @@ -541,9 +575,9 @@ main(int argc, char *argv[]) if (argc > optind) usage("trailing arguments"); - if (scheme_selected() == NULL) + if (scheme_selected() == NULL && nparts > 0) usage("no scheme"); - if (nparts == 0) + if (nparts == 0 && capacity == 0) usage("no partitions"); if (secsz > blksz) { @@ -577,8 +611,9 @@ main(int argc, char *argv[]) fprintf(stderr, "Sectors per track: %u\n", nsecs); fprintf(stderr, "Number of heads: %u\n", nheads); fputc('\n', stderr); - fprintf(stderr, "Partitioning scheme: %s\n", - scheme_selected()->name); + if (scheme_selected()) + fprintf(stderr, "Partitioning scheme: %s\n", + scheme_selected()->name); fprintf(stderr, "Output file format: %s\n", format_selected()->name); fputc('\n', stderr); diff --git a/usr.bin/mkimg/scheme.c b/usr.bin/mkimg/scheme.c index ff5e201..336f953 100644 --- a/usr.bin/mkimg/scheme.c +++ b/usr.bin/mkimg/scheme.c @@ -31,8 +31,10 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include #include #include +#include #include #include #include @@ -104,7 +106,7 @@ scheme_bootcode(int fd) { struct stat sb; - if (scheme->bootcode == 0) + if (scheme == NULL || scheme->bootcode == 0) return (ENXIO); if (fstat(fd, &sb) == -1) @@ -130,6 +132,8 @@ scheme_check_part(struct part *p) struct mkimg_alias *iter; enum alias alias; + assert(scheme != NULL); + /* Check the partition type alias */ alias = scheme_parse_alias(p->alias); if (alias == ALIAS_NONE) @@ -158,29 +162,26 @@ u_int scheme_max_parts(void) { - return (scheme->nparts); + return ((scheme == NULL) ? 0 : scheme->nparts); } u_int scheme_max_secsz(void) { - return (scheme->maxsecsz); + return ((scheme == NULL) ? INT_MAX+1U : scheme->maxsecsz); } lba_t scheme_metadata(u_int where, lba_t start) { - return (scheme->metadata(where, start)); + return ((scheme == NULL) ? start : scheme->metadata(where, start)); } int scheme_write(lba_t end) { - int error; - end = image_get_size(); - error = scheme->write(end, bootcode); - return (error); + return ((scheme == NULL) ? 0 : scheme->write(end, bootcode)); } -- cgit v1.1