Skip site navigation (1)Skip section navigation (2)
Date:      Fri, 9 Feb 2018 09:15:43 +0000 (UTC)
From:      Emmanuel Vadot <manu@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-11@freebsd.org
Subject:   svn commit: r329059 - in stable/11/usr.bin/mkimg: . tests
Message-ID:  <201802090915.w199FhKm022979@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: manu
Date: Fri Feb  9 09:15:43 2018
New Revision: 329059
URL: https://svnweb.freebsd.org/changeset/base/329059

Log:
  MFC r306325, r306329-r306330, r306333, r306620-r306622, r307544, r307550, r318137, r319125, r319295
  
  r306325 by marcel:
  Replace the use of linker sets with constructors for both the
  formats and schemes.  Formats and schemes are registered at
  runtime now, rather than collected at link time.
  
  r306329 by marcel:
  Eliminate the use of EDOOFUS.  The error code was used to signal
  programming errors, but is really a poor substitute for assert.
  And less portable as well.
  
  r306330 by marcel:
  Avoid depending on the <sys/endian.h> header for le*enc and be*enc.
  Not only is the header unportable, the encoding/decoding functions
  are as well.  Instead, duplicate the handful of small inlines we
  need into a private header called endian.h.
  
  Aside: an alternative approach is to move the encoding/decoding
  functions to a separate system header.  While the header is still
  nonportable, such an approach would make it possible to re-use the
  definitions by playing games with include paths. This may be the
  preferred approach if more (build) utilities need this.  This
  change does not preclude that.  In fact, it makes it easier.
  
  r306333 by marcel:
  Portability changes:
  1.  macOS nor Linux have MAP_NOCORE nor MAP_NOSYNC. Define as 0.
  2.  macOS doesn't have SEEK_DATA nor SEEK_HOLE. Define as -1
      so that lseek will return -1 (with errno set to EINVAL).
  3.  gcc correctly warns that error is assigned but not used in
      image_copyout_region().  Fix by returning on the first error.
  
  r306620 by marcel:
  Replace STAILQ with TAILQ. TAILQs are portable enough that they can
  be used on both macOS and Linux. STAILQs are not. In particular,
  STAILQ_LAST does not next on Linux. Since neither STAILQ_FOREACH_SAFE
  nor TAILQ_FOREACH_SAFE exist on Linux, replace its use with a regular
  TAILQ_FOREACH. The _SAFE variant was only used for having the next
  pointer in a local variable.
  
  r306621 by marcel:
  Prefer <stdint.h> over <sys/types.h>. While here remove redundant
  inclusion of <sys/queue.h>.
  
  Move the inclusion of the disk partitioning headers out of order
  and inbetween standard headers and local header. They will change
  in a subsequent commit.
  
  r306622 by marcel:
  Replace OFF_MAX with INT64_MAX. The former is defined on Linux.
  
  r307544 by marcel:
   o  Provide a private definition for UUIDs (mkimg_uuid_t) because
      UUIDs are not portable.
   o  Move mkimg_uuid() to a new file and merge both gpt_uuid_enc()
      and vhd_uuid_enc() into a single mkimg_uuid_enc() that lives
      in the same file.
   o  Move the OS-specific implementation of generating a UUID to
      osdep_uuidgen() and provide the implementations for FreeBSD,
      macOS and Linux.
   o  Expect the partitioning scheme headers to be found by having
      a search to the directory in which the headers live. This
      avoids conflicts on non-FreeBSD machines.
  
  r307550 by imp:
  Add a new flag to mkimg (-a num) to specify the active partition for
  those partitioning schemes that have this concept. Implement it as an
  override for mbr's setting 0x80 in the flags for the first partition
  when we have boot code.
  
  Differential Revision: https://reviews.freebsd.org/D4403
  
  r318137:
  mkimg: Add -C argument to specify maximum capacity
  
  Add a -C option to specify a maximum capacity for the final image file.
  It is useful to control the size of the generated image for sdcard or
  when we will add dynamic size partition.
  
  Add --capacity which is a shorthand to define min and max capacity at
  the same time.
  
  Reviewed by:	bapt, marcel, wblock (manpages)
  Sponsored by:	Gandi.net
  Differential Revision:	https://reviews.freebsd.org/D10509
  
  r319125:
  mkimg: Correct an off by one error in the PMBR size
  
  The PMBR last sector should be number of sector - 1 (As stated in UEFI Spec
  2.6 page 118 table 17).
  This fixes warning printed by linux tools like parted or fdisk.
  
  Sponsored by:	Gandi.net
  
  r319295 by ngie:
  Update the usr.bin/mkimg golden test output files after ^/head@r319125
  
  ^/head@r319125 changed the location of the backup pmbr, requiring the
  output files to be regenerated, since they're binary disk dumps.
  
  The output files were regenerated with "make rebase"--fixed in
  ^/head@r319294.
  
  MFC with:	r319125, r319294
  PR:		219673
  Sponsored by:	Dell EMC Isilon

Added:
  stable/11/usr.bin/mkimg/endian.h
     - copied unchanged from r306330, head/usr.bin/mkimg/endian.h
  stable/11/usr.bin/mkimg/uuid.c
     - copied unchanged from r307544, head/usr.bin/mkimg/uuid.c
Modified:
  stable/11/usr.bin/mkimg/Makefile
  stable/11/usr.bin/mkimg/apm.c
  stable/11/usr.bin/mkimg/bsd.c
  stable/11/usr.bin/mkimg/ebr.c
  stable/11/usr.bin/mkimg/format.c
  stable/11/usr.bin/mkimg/format.h
  stable/11/usr.bin/mkimg/gpt.c
  stable/11/usr.bin/mkimg/image.c
  stable/11/usr.bin/mkimg/mbr.c
  stable/11/usr.bin/mkimg/mkimg.1
  stable/11/usr.bin/mkimg/mkimg.c
  stable/11/usr.bin/mkimg/mkimg.h
  stable/11/usr.bin/mkimg/pc98.c
  stable/11/usr.bin/mkimg/qcow.c
  stable/11/usr.bin/mkimg/raw.c
  stable/11/usr.bin/mkimg/scheme.c
  stable/11/usr.bin/mkimg/scheme.h
  stable/11/usr.bin/mkimg/tests/img-1x1-4096-gpt.qcow.gz.uu
  stable/11/usr.bin/mkimg/tests/img-1x1-4096-gpt.qcow2.gz.uu
  stable/11/usr.bin/mkimg/tests/img-1x1-4096-gpt.raw.gz.uu
  stable/11/usr.bin/mkimg/tests/img-1x1-4096-gpt.vhd.gz.uu
  stable/11/usr.bin/mkimg/tests/img-1x1-4096-gpt.vhdf.gz.uu
  stable/11/usr.bin/mkimg/tests/img-1x1-4096-gpt.vmdk.gz.uu
  stable/11/usr.bin/mkimg/tests/img-1x1-512-gpt.qcow.gz.uu
  stable/11/usr.bin/mkimg/tests/img-1x1-512-gpt.qcow2.gz.uu
  stable/11/usr.bin/mkimg/tests/img-1x1-512-gpt.raw.gz.uu
  stable/11/usr.bin/mkimg/tests/img-1x1-512-gpt.vhd.gz.uu
  stable/11/usr.bin/mkimg/tests/img-1x1-512-gpt.vhdf.gz.uu
  stable/11/usr.bin/mkimg/tests/img-1x1-512-gpt.vmdk.gz.uu
  stable/11/usr.bin/mkimg/tests/img-63x255-4096-gpt.qcow.gz.uu
  stable/11/usr.bin/mkimg/tests/img-63x255-4096-gpt.qcow2.gz.uu
  stable/11/usr.bin/mkimg/tests/img-63x255-4096-gpt.raw.gz.uu
  stable/11/usr.bin/mkimg/tests/img-63x255-4096-gpt.vhd.gz.uu
  stable/11/usr.bin/mkimg/tests/img-63x255-4096-gpt.vhdf.gz.uu
  stable/11/usr.bin/mkimg/tests/img-63x255-4096-gpt.vmdk.gz.uu
  stable/11/usr.bin/mkimg/tests/img-63x255-512-gpt.qcow.gz.uu
  stable/11/usr.bin/mkimg/tests/img-63x255-512-gpt.qcow2.gz.uu
  stable/11/usr.bin/mkimg/tests/img-63x255-512-gpt.raw.gz.uu
  stable/11/usr.bin/mkimg/tests/img-63x255-512-gpt.vhd.gz.uu
  stable/11/usr.bin/mkimg/tests/img-63x255-512-gpt.vhdf.gz.uu
  stable/11/usr.bin/mkimg/tests/img-63x255-512-gpt.vmdk.gz.uu
  stable/11/usr.bin/mkimg/vhd.c
  stable/11/usr.bin/mkimg/vmdk.c
  stable/11/usr.bin/mkimg/vtoc8.c
Directory Properties:
  stable/11/   (props changed)

Modified: stable/11/usr.bin/mkimg/Makefile
==============================================================================
--- stable/11/usr.bin/mkimg/Makefile	Fri Feb  9 04:45:39 2018	(r329058)
+++ stable/11/usr.bin/mkimg/Makefile	Fri Feb  9 09:15:43 2018	(r329059)
@@ -3,14 +3,15 @@
 .include <src.opts.mk>
 
 PROG=	mkimg
-SRCS=	format.c image.c mkimg.c scheme.c
+SRCS=	format.c image.c mkimg.c scheme.c uuid.c
 MAN=	mkimg.1
 
-MKIMG_VERSION=20151211
+MKIMG_VERSION=20161016
 mkimg.o: Makefile
 
 CFLAGS+=-DMKIMG_VERSION=${MKIMG_VERSION}
 CFLAGS+=-DSPARSE_WRITE
+CFLAGS+=-I${.CURDIR:H:H}/sys
 
 # List of formats to support
 SRCS+= \

Modified: stable/11/usr.bin/mkimg/apm.c
==============================================================================
--- stable/11/usr.bin/mkimg/apm.c	Fri Feb  9 04:45:39 2018	(r329058)
+++ stable/11/usr.bin/mkimg/apm.c	Fri Feb  9 09:15:43 2018	(r329059)
@@ -27,14 +27,15 @@
 #include <sys/cdefs.h>
 __FBSDID("$FreeBSD$");
 
-#include <sys/types.h>
-#include <sys/apm.h>
-#include <sys/endian.h>
 #include <sys/errno.h>
+#include <stdint.h>
 #include <stdlib.h>
 #include <string.h>
 #include <unistd.h>
 
+#include <sys/apm.h>
+
+#include "endian.h"
 #include "image.h"
 #include "mkimg.h"
 #include "scheme.h"
@@ -91,7 +92,7 @@ apm_write(lba_t imgsz, void *bootcode __unused)
 	strncpy(ent->ent_type, APM_ENT_TYPE_SELF, sizeof(ent->ent_type));
 	strncpy(ent->ent_name, "Apple", sizeof(ent->ent_name));
 
-	STAILQ_FOREACH(part, &partlist, link) {
+	TAILQ_FOREACH(part, &partlist, link) {
 		ent = (void *)(buf + (part->index + 2) * secsz);
 		be16enc(&ent->ent_sig, APM_ENT_SIG);
 		be32enc(&ent->ent_pmblkcnt, nparts + 1);

Modified: stable/11/usr.bin/mkimg/bsd.c
==============================================================================
--- stable/11/usr.bin/mkimg/bsd.c	Fri Feb  9 04:45:39 2018	(r329058)
+++ stable/11/usr.bin/mkimg/bsd.c	Fri Feb  9 09:15:43 2018	(r329059)
@@ -27,14 +27,15 @@
 #include <sys/cdefs.h>
 __FBSDID("$FreeBSD$");
 
-#include <sys/types.h>
-#include <sys/disklabel.h>
-#include <sys/endian.h>
 #include <sys/errno.h>
+#include <stdint.h>
 #include <stdlib.h>
 #include <string.h>
 #include <unistd.h>
 
+#include <sys/disklabel.h>
+
+#include "endian.h"
 #include "image.h"
 #include "mkimg.h"
 #include "scheme.h"
@@ -103,7 +104,7 @@ bsd_write(lba_t imgsz, void *bootcode)
 
 	dp = &d->d_partitions[RAW_PART];
 	le32enc(&dp->p_size, imgsz);
-	STAILQ_FOREACH(part, &partlist, link) {
+	TAILQ_FOREACH(part, &partlist, link) {
 		n = part->index + ((part->index >= RAW_PART) ? 1 : 0);
 		dp = &d->d_partitions[n];
 		le32enc(&dp->p_size, part->size);

Modified: stable/11/usr.bin/mkimg/ebr.c
==============================================================================
--- stable/11/usr.bin/mkimg/ebr.c	Fri Feb  9 04:45:39 2018	(r329058)
+++ stable/11/usr.bin/mkimg/ebr.c	Fri Feb  9 09:15:43 2018	(r329059)
@@ -27,14 +27,15 @@
 #include <sys/cdefs.h>
 __FBSDID("$FreeBSD$");
 
-#include <sys/types.h>
-#include <sys/diskmbr.h>
-#include <sys/endian.h>
 #include <sys/errno.h>
+#include <stdint.h>
 #include <stdlib.h>
 #include <string.h>
 #include <unistd.h>
 
+#include <sys/diskmbr.h>
+
+#include "endian.h"
 #include "image.h"
 #include "mkimg.h"
 #include "scheme.h"
@@ -88,7 +89,7 @@ ebr_write(lba_t imgsz __unused, void *bootcode __unuse
 	le16enc(ebr + DOSMAGICOFFSET, DOSMAGIC);
 
 	error = 0;
-	STAILQ_FOREACH_SAFE(part, &partlist, link, next) {
+	TAILQ_FOREACH(part, &partlist, link) {
 		block = part->block - nsecs;
 		size = round_track(part->size);
 		dp = (void *)(ebr + DOSPARTOFF);
@@ -100,6 +101,7 @@ ebr_write(lba_t imgsz __unused, void *bootcode __unuse
 		le32enc(&dp->dp_size, size);
 
 		/* Add link entry */
+		next = TAILQ_NEXT(part, link);
 		if (next != NULL) {
 			size = round_track(next->size);
 			dp++;

Copied: stable/11/usr.bin/mkimg/endian.h (from r306330, head/usr.bin/mkimg/endian.h)
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ stable/11/usr.bin/mkimg/endian.h	Fri Feb  9 09:15:43 2018	(r329059, copy of r306330, head/usr.bin/mkimg/endian.h)
@@ -0,0 +1,106 @@
+/*-
+ * Copyright (c) 2002 Thomas Moestl <tmm@FreeBSD.org>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+#ifndef _MKIMG_ENDIAN_H_
+#define _MKIMG_ENDIAN_H_
+
+static __inline uint16_t
+be16dec(const void *pp)
+{
+	uint8_t const *p = (uint8_t const *)pp;
+
+	return ((p[0] << 8) | p[1]);
+}
+
+static __inline void
+be16enc(void *pp, uint16_t u)
+{
+	uint8_t *p = (uint8_t *)pp;
+
+	p[0] = (u >> 8) & 0xff;
+	p[1] = u & 0xff;
+}
+
+static __inline void
+be32enc(void *pp, uint32_t u)
+{
+	uint8_t *p = (uint8_t *)pp;
+
+	p[0] = (u >> 24) & 0xff;
+	p[1] = (u >> 16) & 0xff;
+	p[2] = (u >> 8) & 0xff;
+	p[3] = u & 0xff;
+}
+
+static __inline void
+be64enc(void *pp, uint64_t u)
+{
+	uint8_t *p = (uint8_t *)pp;
+
+	be32enc(p, (uint32_t)(u >> 32));
+	be32enc(p + 4, (uint32_t)(u & 0xffffffffU));
+}
+
+static __inline uint16_t
+le16dec(const void *pp)
+{
+	uint8_t const *p = (uint8_t const *)pp;
+
+	return ((p[1] << 8) | p[0]);
+}
+
+static __inline void
+le16enc(void *pp, uint16_t u)
+{
+	uint8_t *p = (uint8_t *)pp;
+
+	p[0] = u & 0xff;
+	p[1] = (u >> 8) & 0xff;
+}
+
+static __inline void
+le32enc(void *pp, uint32_t u)
+{
+	uint8_t *p = (uint8_t *)pp;
+
+	p[0] = u & 0xff;
+	p[1] = (u >> 8) & 0xff;
+	p[2] = (u >> 16) & 0xff;
+	p[3] = (u >> 24) & 0xff;
+}
+
+static __inline void
+le64enc(void *pp, uint64_t u)
+{
+	uint8_t *p = (uint8_t *)pp;
+
+	le32enc(p, (uint32_t)(u & 0xffffffffU));
+	le32enc(p + 4, (uint32_t)(u >> 32));
+}
+
+#endif /* _MKIMG_ENDIAN_H_ */

Modified: stable/11/usr.bin/mkimg/format.c
==============================================================================
--- stable/11/usr.bin/mkimg/format.c	Fri Feb  9 04:45:39 2018	(r329058)
+++ stable/11/usr.bin/mkimg/format.c	Fri Feb  9 09:15:43 2018	(r329059)
@@ -27,9 +27,6 @@
 #include <sys/cdefs.h>
 __FBSDID("$FreeBSD$");
 
-#include <sys/types.h>
-#include <sys/linker_set.h>
-#include <sys/queue.h>
 #include <sys/stat.h>
 #include <err.h>
 #include <errno.h>
@@ -42,8 +39,24 @@ __FBSDID("$FreeBSD$");
 #include "format.h"
 #include "mkimg.h"
 
+static struct mkimg_format *first;
 static struct mkimg_format *format;
 
+struct mkimg_format *
+format_iterate(struct mkimg_format *f)
+{
+
+	return ((f == NULL) ? first : f->next);
+}
+
+void
+format_register(struct mkimg_format *f)
+{
+
+	f->next = first;
+	first = f;
+}
+
 int
 format_resize(lba_t end)
 {
@@ -56,10 +69,10 @@ format_resize(lba_t end)
 int
 format_select(const char *spec)
 {
-	struct mkimg_format *f, **iter;
+	struct mkimg_format *f;
 
-	SET_FOREACH(iter, formats) {
-		f = *iter;
+	f = NULL;
+	while ((f = format_iterate(f)) != NULL) {
 		if (strcasecmp(spec, f->name) == 0) {
 			format = f;
 			return (0);

Modified: stable/11/usr.bin/mkimg/format.h
==============================================================================
--- stable/11/usr.bin/mkimg/format.h	Fri Feb  9 04:45:39 2018	(r329058)
+++ stable/11/usr.bin/mkimg/format.h	Fri Feb  9 09:15:43 2018	(r329059)
@@ -29,21 +29,24 @@
 #ifndef _MKIMG_FORMAT_H_
 #define	_MKIMG_FORMAT_H_
 
-#include <sys/linker_set.h>
-
 struct mkimg_format {
+	struct mkimg_format *next;
 	const char	*name;
 	const char	*description;
 	int		(*resize)(lba_t);
 	int		(*write)(int);
 };
 
-SET_DECLARE(formats, struct mkimg_format);
-#define	FORMAT_DEFINE(nm)	DATA_SET(formats, nm)
+#define	FORMAT_DEFINE(nm)						\
+static void format_register_##nm(void) __attribute__((constructor));	\
+static void format_register_##nm(void) { format_register(&nm); }
 
-int	format_resize(lba_t);
+struct mkimg_format *format_iterate(struct mkimg_format *);
+void	format_register(struct mkimg_format *);
 int	format_select(const char *);
 struct mkimg_format *format_selected(void);
+
+int	format_resize(lba_t);
 int	format_write(int);
 
 #endif /* _MKIMG_FORMAT_H_ */

Modified: stable/11/usr.bin/mkimg/gpt.c
==============================================================================
--- stable/11/usr.bin/mkimg/gpt.c	Fri Feb  9 04:45:39 2018	(r329058)
+++ stable/11/usr.bin/mkimg/gpt.c	Fri Feb  9 09:15:43 2018	(r329059)
@@ -27,18 +27,17 @@
 #include <sys/cdefs.h>
 __FBSDID("$FreeBSD$");
 
-#include <sys/types.h>
-#include <sys/diskmbr.h>
-#include <sys/endian.h>
 #include <sys/errno.h>
-#include <sys/gpt.h>
 #include <stddef.h>
 #include <stdint.h>
 #include <stdlib.h>
 #include <string.h>
 #include <unistd.h>
-#include <uuid.h>
 
+#include <sys/diskmbr.h>
+#include <sys/gpt.h>
+
+#include "endian.h"
 #include "image.h"
 #include "mkimg.h"
 #include "scheme.h"
@@ -131,21 +130,6 @@ crc32(const void *buf, size_t sz)
 	return (crc ^ ~0U);
 }
 
-static void
-gpt_uuid_enc(void *buf, const uuid_t *uuid)
-{
-	uint8_t *p = buf;
-	int i;
-
-	le32enc(p, uuid->time_low);
-	le16enc(p + 4, uuid->time_mid);
-	le16enc(p + 6, uuid->time_hi_and_version);
-	p[8] = uuid->clock_seq_hi_and_reserved;
-	p[9] = uuid->clock_seq_low;
-	for (i = 0; i < _UUID_NODE_LEN; i++)
-		p[10 + i] = uuid->node[i];
-}
-
 static u_int
 gpt_tblsz(void)
 {
@@ -173,7 +157,7 @@ gpt_write_pmbr(lba_t blks, void *bootcode)
 	uint32_t secs;
 	int error;
 
-	secs = (blks > UINT32_MAX) ? UINT32_MAX : (uint32_t)blks;
+	secs = (blks > UINT32_MAX) ? UINT32_MAX : (uint32_t)blks - 1;
 
 	pmbr = malloc(secsz);
 	if (pmbr == NULL)
@@ -199,7 +183,7 @@ gpt_write_pmbr(lba_t blks, void *bootcode)
 static struct gpt_ent *
 gpt_mktbl(u_int tblsz)
 {
-	uuid_t uuid;
+	mkimg_uuid_t uuid;
 	struct gpt_ent *tbl, *ent;
 	struct part *part;
 	int c, idx;
@@ -208,11 +192,11 @@ gpt_mktbl(u_int tblsz)
 	if (tbl == NULL)
 		return (NULL);
 
-	STAILQ_FOREACH(part, &partlist, link) {
+	TAILQ_FOREACH(part, &partlist, link) {
 		ent = tbl + part->index;
-		gpt_uuid_enc(&ent->ent_type, ALIAS_TYPE2PTR(part->type));
+		mkimg_uuid_enc(&ent->ent_type, ALIAS_TYPE2PTR(part->type));
 		mkimg_uuid(&uuid);
-		gpt_uuid_enc(&ent->ent_uuid, &uuid);
+		mkimg_uuid_enc(&ent->ent_uuid, &uuid);
 		le64enc(&ent->ent_lba_start, part->block);
 		le64enc(&ent->ent_lba_end, part->block + part->size - 1);
 		if (part->label != NULL) {
@@ -243,7 +227,7 @@ gpt_write_hdr(struct gpt_hdr *hdr, uint64_t self, uint
 static int
 gpt_write(lba_t imgsz, void *bootcode)
 {
-	uuid_t uuid;
+	mkimg_uuid_t uuid;
 	struct gpt_ent *tbl;
 	struct gpt_hdr *hdr;
 	uint32_t crc;
@@ -280,7 +264,7 @@ gpt_write(lba_t imgsz, void *bootcode)
 	le64enc(&hdr->hdr_lba_start, 2 + tblsz);
 	le64enc(&hdr->hdr_lba_end, imgsz - tblsz - 2);
 	mkimg_uuid(&uuid);
-	gpt_uuid_enc(&hdr->hdr_uuid, &uuid);
+	mkimg_uuid_enc(&hdr->hdr_uuid, &uuid);
 	le32enc(&hdr->hdr_entries, nparts);
 	le32enc(&hdr->hdr_entsz, sizeof(struct gpt_ent));
 	crc = crc32(tbl, nparts * sizeof(struct gpt_ent));

Modified: stable/11/usr.bin/mkimg/image.c
==============================================================================
--- stable/11/usr.bin/mkimg/image.c	Fri Feb  9 04:45:39 2018	(r329058)
+++ stable/11/usr.bin/mkimg/image.c	Fri Feb  9 09:15:43 2018	(r329059)
@@ -28,9 +28,7 @@
 __FBSDID("$FreeBSD$");
 
 #include <sys/mman.h>
-#include <sys/queue.h>
 #include <sys/stat.h>
-#include <sys/types.h>
 #include <assert.h>
 #include <err.h>
 #include <errno.h>
@@ -45,8 +43,22 @@ __FBSDID("$FreeBSD$");
 #include "image.h"
 #include "mkimg.h"
 
+#ifndef MAP_NOCORE
+#define	MAP_NOCORE	0
+#endif
+#ifndef MAP_NOSYNC
+#define	MAP_NOSYNC	0
+#endif
+
+#ifndef SEEK_DATA
+#define	SEEK_DATA	-1
+#endif
+#ifndef SEEK_HOLE
+#define	SEEK_HOLE	-1
+#endif
+
 struct chunk {
-	STAILQ_ENTRY(chunk) ch_list;
+	TAILQ_ENTRY(chunk) ch_list;
 	size_t	ch_size;		/* Size of chunk in bytes. */
 	lba_t	ch_block;		/* Block address in image. */
 	union {
@@ -64,7 +76,7 @@ struct chunk {
 #define	CH_TYPE_MEMORY		2	/* Memory-backed chunk */
 };
 
-static STAILQ_HEAD(chunk_head, chunk) image_chunks;
+static TAILQ_HEAD(chunk_head, chunk) image_chunks;
 static u_int image_nchunks;
 
 static char image_swap_file[PATH_MAX];
@@ -125,14 +137,14 @@ image_chunk_find(lba_t blk)
 	struct chunk *ch;
 
 	ch = (last != NULL && last->ch_block <= blk)
-	    ? last : STAILQ_FIRST(&image_chunks);
+	    ? last : TAILQ_FIRST(&image_chunks);
 	while (ch != NULL) {
 		if (ch->ch_block <= blk &&
 		    (lba_t)(ch->ch_block + (ch->ch_size / secsz)) > blk) {
 			last = ch;
 			break;
 		}
-		ch = STAILQ_NEXT(ch, ch_list);
+		ch = TAILQ_NEXT(ch, ch_list);
 	}
 	return (ch);
 }
@@ -174,7 +186,7 @@ image_chunk_memory(struct chunk *ch, lba_t blk)
 		ch->ch_size = (blk - ch->ch_block) * secsz;
 		new->ch_block = blk;
 		new->ch_size -= ch->ch_size;
-		STAILQ_INSERT_AFTER(&image_chunks, ch, new, ch_list);
+		TAILQ_INSERT_AFTER(&image_chunks, ch, new, ch_list);
 		image_nchunks++;
 		ch = new;
 	}
@@ -189,7 +201,7 @@ image_chunk_memory(struct chunk *ch, lba_t blk)
 		ch->ch_size = secsz;
 		new->ch_block++;
 		new->ch_size -= secsz;
-		STAILQ_INSERT_AFTER(&image_chunks, ch, new, ch_list);
+		TAILQ_INSERT_AFTER(&image_chunks, ch, new, ch_list);
 		image_nchunks++;
 	}
 
@@ -205,7 +217,7 @@ image_chunk_skipto(lba_t to)
 	lba_t from;
 	size_t sz;
 
-	ch = STAILQ_LAST(&image_chunks, chunk, ch_list);
+	ch = TAILQ_LAST(&image_chunks, chunk_head);
 	from = (ch != NULL) ? ch->ch_block + (ch->ch_size / secsz) : 0LL;
 
 	assert(from <= to);
@@ -230,7 +242,7 @@ image_chunk_skipto(lba_t to)
 	ch->ch_block = from;
 	ch->ch_size = sz;
 	ch->ch_type = CH_TYPE_ZEROES;
-	STAILQ_INSERT_TAIL(&image_chunks, ch, ch_list);
+	TAILQ_INSERT_TAIL(&image_chunks, ch, ch_list);
 	image_nchunks++;
 	return (0);
 }
@@ -240,7 +252,7 @@ image_chunk_append(lba_t blk, size_t sz, off_t ofs, in
 {
 	struct chunk *ch;
 
-	ch = STAILQ_LAST(&image_chunks, chunk, ch_list);
+	ch = TAILQ_LAST(&image_chunks, chunk_head);
 	if (ch != NULL && ch->ch_type == CH_TYPE_FILE) {
 		if (fd == ch->ch_u.file.fd &&
 		    blk == (lba_t)(ch->ch_block + (ch->ch_size / secsz)) &&
@@ -261,7 +273,7 @@ image_chunk_append(lba_t blk, size_t sz, off_t ofs, in
 	ch->ch_type = CH_TYPE_FILE;
 	ch->ch_u.file.ofs = ofs;
 	ch->ch_u.file.fd = fd;
-	STAILQ_INSERT_TAIL(&image_chunks, ch, ch_list);
+	TAILQ_INSERT_TAIL(&image_chunks, ch, ch_list);
 	image_nchunks++;
 	return (0);
 }
@@ -456,8 +468,7 @@ image_copyin_mapped(lba_t blk, int fd, uint64_t *sizep
 			 * I don't know what this means or whether it
 			 * can happen at all...
 			 */
-			error = EDOOFUS;
-			break;
+			assert(0);
 		}
 	}
 	if (error)
@@ -583,10 +594,13 @@ image_copyout_region(int fd, lba_t blk, lba_t size)
 
 	size *= secsz;
 
-	while (size > 0) {
+	error = 0;
+	while (!error && size > 0) {
 		ch = image_chunk_find(blk);
-		if (ch == NULL)
-			return (EINVAL);
+		if (ch == NULL) {
+			error = EINVAL;
+			break;
+		}
 		ofs = (blk - ch->ch_block) * secsz;
 		sz = ch->ch_size - ofs;
 		sz = ((lba_t)sz < size) ? sz : (size_t)size;
@@ -602,12 +616,12 @@ image_copyout_region(int fd, lba_t blk, lba_t size)
 			error = image_copyout_memory(fd, sz, ch->ch_u.mem.ptr);
 			break;
 		default:
-			return (EDOOFUS);
+			assert(0);
 		}
 		size -= sz;
 		blk += sz / secsz;
 	}
-	return (0);
+	return (error);
 }
 
 int
@@ -682,7 +696,7 @@ image_cleanup(void)
 {
 	struct chunk *ch;
 
-	while ((ch = STAILQ_FIRST(&image_chunks)) != NULL) {
+	while ((ch = TAILQ_FIRST(&image_chunks)) != NULL) {
 		switch (ch->ch_type) {
 		case CH_TYPE_FILE:
 			/* We may be closing the same file multiple times. */
@@ -695,7 +709,7 @@ image_cleanup(void)
 		default:
 			break;
 		}
-		STAILQ_REMOVE_HEAD(&image_chunks, ch_list);
+		TAILQ_REMOVE(&image_chunks, ch, ch_list);
 		free(ch);
 	}
 	if (image_swap_fd != -1)
@@ -708,7 +722,7 @@ image_init(void)
 {
 	const char *tmpdir;
 
-	STAILQ_INIT(&image_chunks);
+	TAILQ_INIT(&image_chunks);
 	image_nchunks = 0;
 
 	image_swap_size = 0;

Modified: stable/11/usr.bin/mkimg/mbr.c
==============================================================================
--- stable/11/usr.bin/mkimg/mbr.c	Fri Feb  9 04:45:39 2018	(r329058)
+++ stable/11/usr.bin/mkimg/mbr.c	Fri Feb  9 09:15:43 2018	(r329059)
@@ -27,14 +27,15 @@
 #include <sys/cdefs.h>
 __FBSDID("$FreeBSD$");
 
-#include <sys/types.h>
-#include <sys/diskmbr.h>
-#include <sys/endian.h>
 #include <sys/errno.h>
+#include <stdint.h>
 #include <stdlib.h>
 #include <string.h>
 #include <unistd.h>
 
+#include <sys/diskmbr.h>
+
+#include "endian.h"
 #include "image.h"
 #include "mkimg.h"
 #include "scheme.h"
@@ -101,10 +102,15 @@ mbr_write(lba_t imgsz __unused, void *bootcode)
 		memset(mbr, 0, secsz);
 	le16enc(mbr + DOSMAGICOFFSET, DOSMAGIC);
 	dpbase = (void *)(mbr + DOSPARTOFF);
-	STAILQ_FOREACH(part, &partlist, link) {
+	TAILQ_FOREACH(part, &partlist, link) {
 		size = round_track(part->size);
 		dp = dpbase + part->index;
-		dp->dp_flag = (part->index == 0 && bootcode != NULL) ? 0x80 : 0;
+		if (active_partition != 0)
+			dp->dp_flag =
+			    (part->index + 1 == active_partition) ? 0x80 : 0;
+		else
+			dp->dp_flag =
+			    (part->index == 0 && bootcode != NULL) ? 0x80 : 0;
 		mbr_chs(&dp->dp_scyl, &dp->dp_shd, &dp->dp_ssect,
 		    part->block);
 		dp->dp_typ = ALIAS_TYPE2INT(part->type);

Modified: stable/11/usr.bin/mkimg/mkimg.1
==============================================================================
--- stable/11/usr.bin/mkimg/mkimg.1	Fri Feb  9 04:45:39 2018	(r329058)
+++ stable/11/usr.bin/mkimg/mkimg.1	Fri Feb  9 09:15:43 2018	(r329059)
@@ -24,7 +24,7 @@
 .\"
 .\" $FreeBSD$
 .\"
-.Dd August 7, 2015
+.Dd April 26, 2017
 .Dt MKIMG 1
 .Os
 .Sh NAME
@@ -37,9 +37,12 @@
 .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
 .Op Fl v
 .Op Fl y
 .Op Fl s Ar scheme Op Fl p Ar partition ...
@@ -119,11 +122,23 @@ An empty partition table can be written to the disk wh
 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
+When the size required for all the partitions is larger than the
 given capacity, then the disk image will be larger than the capacity
 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
@@ -138,6 +153,26 @@ utility will generate predictable values for Universal
 (UUIDs) and time stamps so that consecutive runs of the
 .Nm
 utility will create images that are identical.
+.Pp
+The
+.Ar active
+option marks a partition as active, if the partitioning
+scheme supports it.
+Currently, only the
+.Ar mbr
+scheme supports this concept.
+By default,
+.Nm
+will only mark the first partition as active when boot code is
+specified.
+Use the
+.Ar active
+option to override the active partition.
+The number specified corresponds to the number after the 's' in the
+partition's
+.Xr geom 8
+name.
+No partitions are marked active when the value is 0.
 .Pp
 A set of long options exist to query about the
 .Nm

Modified: stable/11/usr.bin/mkimg/mkimg.c
==============================================================================
--- stable/11/usr.bin/mkimg/mkimg.c	Fri Feb  9 04:45:39 2018	(r329058)
+++ stable/11/usr.bin/mkimg/mkimg.c	Fri Feb  9 09:15:43 2018	(r329059)
@@ -27,17 +27,15 @@
 #include <sys/cdefs.h>
 __FBSDID("$FreeBSD$");
 
-#include <sys/linker_set.h>
-#include <sys/queue.h>
+#include <sys/param.h>
 #include <sys/stat.h>
-#include <sys/types.h>
-#include <sys/uuid.h>
 #include <errno.h>
 #include <err.h>
 #include <fcntl.h>
 #include <getopt.h>
 #include <libutil.h>
 #include <limits.h>
+#include <stdint.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
@@ -49,20 +47,23 @@ __FBSDID("$FreeBSD$");
 #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 = STAILQ_HEAD_INITIALIZER(partlist);
+struct partlisthead partlist = TAILQ_HEAD_INITIALIZER(partlist);
 u_int nparts = 0;
 
 u_int unit_testing;
@@ -73,24 +74,25 @@ u_int nheads = 1;
 u_int nsecs = 1;
 u_int secsz = 512;
 u_int blksz = 0;
+uint32_t active_partition = 0;
 
 static void
 print_formats(int usage)
 {
-	struct mkimg_format *f, **f_iter;
+	struct mkimg_format *f;
 	const char *sep;
 
 	if (usage) {
 		fprintf(stderr, "    formats:\n");
-		SET_FOREACH(f_iter, formats) {
-			f = *f_iter;
+		f = NULL;
+		while ((f = format_iterate(f)) != NULL) {
 			fprintf(stderr, "\t%s\t-  %s\n", f->name,
 			    f->description);
 		}
 	} else {
 		sep = "";
-		SET_FOREACH(f_iter, formats) {
-			f = *f_iter;
+		f = NULL;
+		while ((f = format_iterate(f)) != NULL) {
 			printf("%s%s", sep, f->name);
 			sep = " ";
 		}
@@ -101,20 +103,20 @@ print_formats(int usage)
 static void
 print_schemes(int usage)
 {
-	struct mkimg_scheme *s, **s_iter;
+	struct mkimg_scheme *s;
 	const char *sep;
 
 	if (usage) {
 		fprintf(stderr, "    schemes:\n");
-		SET_FOREACH(s_iter, schemes) {
-			s = *s_iter;
+		s = NULL;
+		while ((s = scheme_iterate(s)) != NULL) {
 			fprintf(stderr, "\t%s\t-  %s\n", s->name,
 			    s->description);
 		}
 	} else {
 		sep = "";
-		SET_FOREACH(s_iter, schemes) {
-			s = *s_iter;
+		s = NULL;
+		while ((s = scheme_iterate(s)) != NULL) {
 			printf("%s%s", sep, s->name);
 			sep = " ";
 		}
@@ -148,8 +150,10 @@ usage(const char *why)
 	fprintf(stderr, "\t--schemes\t-  list partition schemes\n");
 	fprintf(stderr, "\t--version\t-  show version information\n");
 	fputc('\n', stderr);
+	fprintf(stderr, "\t-a <num>\t-  mark num'th partion as active\n");
 	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-c <num>\t-  minimum capacity (in bytes) of the disk\n");
+	fprintf(stderr, "\t-C <num>\t-  maximum 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");
@@ -302,7 +306,7 @@ parse_part(const char *spec)
 	}
 
 	part->index = nparts;
-	STAILQ_INSERT_TAIL(&partlist, part, link);
+	TAILQ_INSERT_TAIL(&partlist, part, link);
 	nparts++;
 	return (0);
 
@@ -376,31 +380,20 @@ mkimg_chs(lba_t lba, u_int maxcyl, u_int *cylp, u_int 
 	*secp = sec;
 }
 
-void
-mkimg_uuid(struct uuid *uuid)
-{
-	static uint8_t gen[sizeof(struct uuid)];
-	u_int i;
-
-	if (!unit_testing) {
-		uuidgen(uuid, 1);
-		return;
-	}
-
-	for (i = 0; i < sizeof(gen); i++)
-		gen[i]++;
-	memcpy(uuid, gen, sizeof(uuid_t));
-}
-
 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
@@ -413,14 +406,14 @@ mkimg(void)
 	int error, fd;
 
 	/* First check partition information */
-	STAILQ_FOREACH(part, &partlist, link) {
+	TAILQ_FOREACH(part, &partlist, link) {
 		error = scheme_check_part(part);
 		if (error)
 			errc(EX_DATAERR, error, "partition %d", part->index+1);
 	}
 
 	block = scheme_metadata(SCHEME_META_IMG_START, 0);
-	STAILQ_FOREACH(part, &partlist, link) {
+	TAILQ_FOREACH(part, &partlist, link) {
 		block = scheme_metadata(SCHEME_META_PART_BEFORE, block);
 		if (verbose)
 			fprintf(stderr, "partition %d: starting block %llu "
@@ -487,9 +480,14 @@ main(int argc, char *argv[])
 
 	bcfd = -1;
 	outfd = 1;	/* Write to stdout by default */
-	while ((c = getopt_long(argc, argv, "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 */
+			error = parse_uint32(&active_partition, 1, 100, optarg);
+			if (error)
+				errc(EX_DATAERR, error, "Partition ordinal");
+			break;
 		case 'b':	/* BOOT CODE */
 			if (bcfd != -1)
 				usage("multiple bootcode given");
@@ -497,11 +495,16 @@ 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);
+		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)
 				usage("multiple formats given");
@@ -571,6 +574,12 @@ main(int argc, char *argv[])
 			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");
 		}
@@ -580,8 +589,10 @@ main(int argc, char *argv[])
 		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)

Modified: stable/11/usr.bin/mkimg/mkimg.h
==============================================================================
--- stable/11/usr.bin/mkimg/mkimg.h	Fri Feb  9 04:45:39 2018	(r329058)
+++ stable/11/usr.bin/mkimg/mkimg.h	Fri Feb  9 09:15:43 2018	(r329059)
@@ -30,9 +30,10 @@
 #define	_MKIMG_MKIMG_H_
 
 #include <sys/queue.h>
+#include <sys/types.h>
 
 struct part {
-	STAILQ_ENTRY(part) link;
+	TAILQ_ENTRY(part) link;
 	char	*alias;		/* Partition type alias. */
 	char	*contents;	/* Contents/size specification. */
 	u_int	kind;		/* Content kind. */
@@ -47,7 +48,7 @@ struct part {
 	char	*label;		/* Partition label. */
 };
 
-extern STAILQ_HEAD(partlisthead, part) partlist;
+extern TAILQ_HEAD(partlisthead, part) partlist;
 extern u_int nparts;
 
 extern u_int unit_testing;
@@ -58,6 +59,7 @@ extern u_int nheads;
 extern u_int nsecs;
 extern u_int secsz;	/* Logical block size. */
 extern u_int blksz;	/* Physical block size. */
+extern uint32_t active_partition;
 
 static inline lba_t
 round_block(lba_t n)
@@ -89,7 +91,17 @@ ssize_t sparse_write(int, const void *, size_t);
 
 void mkimg_chs(lba_t, u_int, u_int *, u_int *, u_int *);
 
-struct uuid;
-void mkimg_uuid(struct uuid *);
+struct mkimg_uuid {
+	uint32_t	time_low;
+	uint16_t	time_mid;
+	uint16_t	time_hi_and_version;
+	uint8_t		clock_seq_hi_and_reserved;
+	uint8_t		clock_seq_low;

*** DIFF OUTPUT TRUNCATED AT 1000 LINES ***



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201802090915.w199FhKm022979>