summaryrefslogtreecommitdiffstats
path: root/usr.bin/mkimg
diff options
context:
space:
mode:
Diffstat (limited to 'usr.bin/mkimg')
-rw-r--r--usr.bin/mkimg/Makefile2
-rw-r--r--usr.bin/mkimg/mkimg.127
-rw-r--r--usr.bin/mkimg/mkimg.c50
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) {
OpenPOWER on IntegriCloud