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>