From owner-svn-src-stable@freebsd.org Tue Apr 24 17:53:29 2018 Return-Path: Delivered-To: svn-src-stable@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id A320FFAD8BF; Tue, 24 Apr 2018 17:53:29 +0000 (UTC) (envelope-from benno@FreeBSD.org) Received: from mxrelay.nyi.freebsd.org (mxrelay.nyi.freebsd.org [IPv6:2610:1c1:1:606c::19:3]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client CN "mxrelay.nyi.freebsd.org", Issuer "Let's Encrypt Authority X3" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id 5CCDB842FF; Tue, 24 Apr 2018 17:53:28 +0000 (UTC) (envelope-from benno@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mxrelay.nyi.freebsd.org (Postfix) with ESMTPS id 5477E1672B; Tue, 24 Apr 2018 17:53:28 +0000 (UTC) (envelope-from benno@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id w3OHrSwU052913; Tue, 24 Apr 2018 17:53:28 GMT (envelope-from benno@FreeBSD.org) Received: (from benno@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id w3OHrS9D052911; Tue, 24 Apr 2018 17:53:28 GMT (envelope-from benno@FreeBSD.org) Message-Id: <201804241753.w3OHrS9D052911@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: benno set sender to benno@FreeBSD.org using -f From: Benno Rice Date: Tue, 24 Apr 2018 17:53:28 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-11@freebsd.org Subject: svn commit: r332952 - stable/11/usr.bin/mkimg X-SVN-Group: stable-11 X-SVN-Commit-Author: benno X-SVN-Commit-Paths: stable/11/usr.bin/mkimg X-SVN-Commit-Revision: 332952 X-SVN-Commit-Repository: base MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-stable@freebsd.org X-Mailman-Version: 2.1.25 Precedence: list List-Id: SVN commit messages for all the -stable branches of the src tree List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 24 Apr 2018 17:53:29 -0000 Author: benno Date: Tue Apr 24 17:53:27 2018 New Revision: 332952 URL: https://svnweb.freebsd.org/changeset/base/332952 Log: MFC r332436, r332440 r332436: Add the ability to specify absolute and relative offsets to size partitions. To create hybrid boot media we want to specify a partition at a known location. This extends the syntax of size partitions to include an optional offset that can be absolute or relative. It also introduces validation to make sure that this hasn't resulted in overlapping partitions. I haven't added this to the file and process partition specifications yet but the mechanics are designed such that if someone comes up with a good way of specifying the offset it will be fairly easy to add in. r332440: Fix a conditional that got mucked up. Sponsored by: iXsystems, Inc. Modified: stable/11/usr.bin/mkimg/mkimg.c stable/11/usr.bin/mkimg/scheme.h Modified: stable/11/usr.bin/mkimg/mkimg.c ============================================================================== --- stable/11/usr.bin/mkimg/mkimg.c Tue Apr 24 17:53:16 2018 (r332951) +++ stable/11/usr.bin/mkimg/mkimg.c Tue Apr 24 17:53:27 2018 (r332952) @@ -35,6 +35,7 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include #include #include #include @@ -170,13 +171,14 @@ usage(const char *why) print_schemes(1); fputc('\n', stderr); fprintf(stderr, " partition specification:\n"); - fprintf(stderr, "\t[/]::\t- empty partition of given " - "size\n"); - fprintf(stderr, "\t[/]:=\t- partition content and size " - "are determined\n\t\t\t\t by the named file\n"); - fprintf(stderr, "\t[/]:-\t- partition content and size " - "are taken from\n\t\t\t\t the output of the command to run\n"); - fprintf(stderr, "\t-\t\t\t- unused partition entry\n"); + fprintf(stderr, "\t[/]::[:[+]]\t- " + "empty partition of given size and\n\t\t\t\t\t" + " optional relative or absolute offset\n"); + fprintf(stderr, "\t[/]:=\t\t- partition content and size " + "are\n\t\t\t\t\t determined by the named file\n"); + fprintf(stderr, "\t[/]:-\t\t- partition content and size " + "are taken\n\t\t\t\t\t from the output of the command to run\n"); + fprintf(stderr, "\t-\t\t\t\t- unused partition entry\n"); fprintf(stderr, "\t where:\n"); fprintf(stderr, "\t\t\t- scheme neutral partition type\n"); fprintf(stderr, "\t\t\t- optional scheme-dependent partition " @@ -397,12 +399,48 @@ capacity_resize(lba_t end) } static void +mkimg_validate(void) +{ + struct part *part, *part2; + lba_t start, end, start2, end2; + int i, j; + + i = 0; + + TAILQ_FOREACH(part, &partlist, link) { + start = part->block; + end = part->block + part->size; + j = i + 1; + part2 = TAILQ_NEXT(part, link); + if (part2 == NULL) + break; + + TAILQ_FOREACH_FROM(part2, &partlist, link) { + start2 = part2->block; + end2 = part2->block + part2->size; + + if ((start >= start2 && start < end2) || + (end > start2 && end <= end2)) { + errx(1, "partition %d overlaps partition %d", + i, j); + } + + j++; + } + + i++; + } +} + +static void mkimg(void) { FILE *fp; struct part *part; - lba_t block; - off_t bytesize; + lba_t block, blkoffset; + off_t bytesize, byteoffset; + char *size, *offset; + bool abs_offset; int error, fd; /* First check partition information */ @@ -413,17 +451,46 @@ mkimg(void) } block = scheme_metadata(SCHEME_META_IMG_START, 0); + abs_offset = false; TAILQ_FOREACH(part, &partlist, link) { - block = scheme_metadata(SCHEME_META_PART_BEFORE, block); - if (verbose) - fprintf(stderr, "partition %d: starting block %llu " - "... ", part->index + 1, (long long)block); - part->block = block; + byteoffset = blkoffset = 0; + abs_offset = false; + + /* Look for an offset. Set size too if we can. */ switch (part->kind) { case PART_KIND_SIZE: - if (expand_number(part->contents, &bytesize) == -1) + offset = part->contents; + size = strsep(&offset, ":"); + if (expand_number(size, &bytesize) == -1) error = errno; + if (offset != NULL) { + if (*offset != '+') + abs_offset = true; + else + offset++; + if (expand_number(offset, &byteoffset) == -1) + error = errno; + } break; + } + + /* Work out exactly where the partition starts. */ + blkoffset = (byteoffset + secsz - 1) / secsz; + if (abs_offset) { + part->block = scheme_metadata(SCHEME_META_PART_ABSOLUTE, + blkoffset); + } else { + block = scheme_metadata(SCHEME_META_PART_BEFORE, + block + blkoffset); + part->block = block; + } + + if (verbose) + fprintf(stderr, "partition %d: starting block %llu " + "... ", part->index + 1, (long long)part->block); + + /* Pull in partition contents, set size if we haven't yet. */ + switch (part->kind) { case PART_KIND_FILE: fd = open(part->contents, O_RDONLY, 0); if (fd != -1) { @@ -449,10 +516,25 @@ mkimg(void) bytesize = part->size * secsz; fprintf(stderr, "size %llu bytes (%llu blocks)\n", (long long)bytesize, (long long)part->size); + if (abs_offset) { + fprintf(stderr, + " location %llu bytes (%llu blocks)\n", + (long long)byteoffset, + (long long)blkoffset); + } else if (blkoffset > 0) { + fprintf(stderr, + " offset %llu bytes (%llu blocks)\n", + (long long)byteoffset, + (long long)blkoffset); + } } - block = scheme_metadata(SCHEME_META_PART_AFTER, - part->block + part->size); + if (!abs_offset) { + block = scheme_metadata(SCHEME_META_PART_AFTER, + part->block + part->size); + } } + + mkimg_validate(); block = scheme_metadata(SCHEME_META_IMG_END, block); error = image_set_size(block); Modified: stable/11/usr.bin/mkimg/scheme.h ============================================================================== --- stable/11/usr.bin/mkimg/scheme.h Tue Apr 24 17:53:16 2018 (r332951) +++ stable/11/usr.bin/mkimg/scheme.h Tue Apr 24 17:53:27 2018 (r332952) @@ -65,10 +65,11 @@ struct mkimg_scheme { const char *description; struct mkimg_alias *aliases; lba_t (*metadata)(u_int, lba_t); -#define SCHEME_META_IMG_START 1 -#define SCHEME_META_IMG_END 2 -#define SCHEME_META_PART_BEFORE 3 -#define SCHEME_META_PART_AFTER 4 +#define SCHEME_META_IMG_START 1 +#define SCHEME_META_IMG_END 2 +#define SCHEME_META_PART_BEFORE 3 +#define SCHEME_META_PART_AFTER 4 +#define SCHEME_META_PART_ABSOLUTE 5 int (*write)(lba_t, void *); u_int nparts; u_int labellen;