summaryrefslogtreecommitdiffstats
path: root/usr.bin/mkimg
diff options
context:
space:
mode:
authormarcel <marcel@FreeBSD.org>2015-06-17 19:03:32 +0000
committermarcel <marcel@FreeBSD.org>2015-06-17 19:03:32 +0000
commite4538d7f16467dec857ab8e8974664043aebed5a (patch)
treefe2addc6b4a85748ef76a2c0c4081956b008588d /usr.bin/mkimg
parentd2f2bb87e8f9590ff5d8eb0745530c9f78bad751 (diff)
downloadFreeBSD-src-e4538d7f16467dec857ab8e8974664043aebed5a.zip
FreeBSD-src-e4538d7f16467dec857ab8e8974664043aebed5a.tar.gz
MFC 279125, 279126, 279128, 279139:
Add the -c option for specifying the capacity of the disk image. Bump the version to 20150222.
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.c59
-rw-r--r--usr.bin/mkimg/scheme.c17
4 files changed, 78 insertions, 27 deletions
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 <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,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 <sys/linker_set.h>
#include <sys/queue.h>
#include <sys/stat.h>
+#include <assert.h>
#include <err.h>
#include <errno.h>
+#include <limits.h>
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
@@ -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));
}
OpenPOWER on IntegriCloud