From owner-svn-src-all@FreeBSD.ORG Wed Jul 2 14:54:44 2014 Return-Path: Delivered-To: svn-src-all@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [8.8.178.115]) (using TLSv1 with cipher ADH-AES256-SHA (256/256 bits)) (No client certificate requested) by hub.freebsd.org (Postfix) with ESMTPS id C2ACDB57; Wed, 2 Jul 2014 14:54:44 +0000 (UTC) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:1900:2254:2068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id AD3252E47; Wed, 2 Jul 2014 14:54:44 +0000 (UTC) Received: from svn.freebsd.org ([127.0.1.70]) by svn.freebsd.org (8.14.8/8.14.8) with ESMTP id s62Esio4009021; Wed, 2 Jul 2014 14:54:44 GMT (envelope-from marcel@svn.freebsd.org) Received: (from marcel@localhost) by svn.freebsd.org (8.14.8/8.14.8/Submit) id s62Esg64009007; Wed, 2 Jul 2014 14:54:42 GMT (envelope-from marcel@svn.freebsd.org) Message-Id: <201407021454.s62Esg64009007@svn.freebsd.org> From: Marcel Moolenaar Date: Wed, 2 Jul 2014 14:54:42 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-10@freebsd.org Subject: svn commit: r268161 - in stable/10/usr.bin: . mkimg X-SVN-Group: stable-10 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-all@freebsd.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: "SVN commit messages for the entire src tree \(except for " user" and " projects" \)" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 02 Jul 2014 14:54:44 -0000 Author: marcel Date: Wed Jul 2 14:54:41 2014 New Revision: 268161 URL: http://svnweb.freebsd.org/changeset/base/268161 Log: MFC mkimg(1) -- revisions 268159, 268134, 266556, 266514, 266513, 266512, 266511, 266510, 266509, 266176, 265468, 265467, 265462, 265170, 263926, 263924, 263923, 263919 and 263918. Revision 267182 changed mkimg.1 alongside other unrelated manpages. The change to mkimg.1 has been applied without registering a merge of the revision. This allows a future merge of r267182 to happen. Relnotes: yes Added: stable/10/usr.bin/mkimg/ - copied from r263918, head/usr.bin/mkimg/ stable/10/usr.bin/mkimg/format.c - copied unchanged from r266176, head/usr.bin/mkimg/format.c stable/10/usr.bin/mkimg/format.h - copied unchanged from r266176, head/usr.bin/mkimg/format.h stable/10/usr.bin/mkimg/image.c - copied, changed from r266176, head/usr.bin/mkimg/image.c stable/10/usr.bin/mkimg/image.h - copied unchanged from r266176, head/usr.bin/mkimg/image.h stable/10/usr.bin/mkimg/raw.c - copied unchanged from r266176, head/usr.bin/mkimg/raw.c stable/10/usr.bin/mkimg/vmdk.c - copied unchanged from r266176, head/usr.bin/mkimg/vmdk.c Modified: stable/10/usr.bin/Makefile stable/10/usr.bin/mkimg/Makefile (contents, props changed) stable/10/usr.bin/mkimg/apm.c stable/10/usr.bin/mkimg/bsd.c stable/10/usr.bin/mkimg/ebr.c stable/10/usr.bin/mkimg/gpt.c stable/10/usr.bin/mkimg/mbr.c stable/10/usr.bin/mkimg/mkimg.1 (contents, props changed) stable/10/usr.bin/mkimg/mkimg.c (contents, props changed) stable/10/usr.bin/mkimg/mkimg.h stable/10/usr.bin/mkimg/pc98.c stable/10/usr.bin/mkimg/scheme.c (contents, props changed) stable/10/usr.bin/mkimg/scheme.h (contents, props changed) stable/10/usr.bin/mkimg/vtoc8.c Directory Properties: stable/10/ (props changed) Modified: stable/10/usr.bin/Makefile ============================================================================== --- stable/10/usr.bin/Makefile Wed Jul 2 14:47:48 2014 (r268160) +++ stable/10/usr.bin/Makefile Wed Jul 2 14:54:41 2014 (r268161) @@ -106,6 +106,7 @@ SUBDIR= alias \ mkdep \ ${_mkesdb} \ mkfifo \ + mkimg \ mklocale \ mktemp \ mkulzma \ Modified: stable/10/usr.bin/mkimg/Makefile ============================================================================== --- head/usr.bin/mkimg/Makefile Sat Mar 29 19:03:10 2014 (r263918) +++ stable/10/usr.bin/mkimg/Makefile Wed Jul 2 14:54:41 2014 (r268161) @@ -1,11 +1,16 @@ # $FreeBSD$ PROG= mkimg -SRCS= mkimg.c scheme.c +SRCS= format.c image.c mkimg.c scheme.c MAN= mkimg.1 CFLAGS+=-DSPARSE_WRITE +# List of formats to support +SRCS+= \ + raw.c \ + vmdk.c + # List of schemes to support SRCS+= \ apm.c \ Modified: stable/10/usr.bin/mkimg/apm.c ============================================================================== --- head/usr.bin/mkimg/apm.c Sat Mar 29 19:03:10 2014 (r263918) +++ stable/10/usr.bin/mkimg/apm.c Wed Jul 2 14:54:41 2014 (r268161) @@ -35,11 +35,17 @@ __FBSDID("$FreeBSD$"); #include #include +#include "image.h" #include "mkimg.h" #include "scheme.h" +#ifndef APM_ENT_TYPE_FREEBSD_NANDFS +#define APM_ENT_TYPE_FREEBSD_NANDFS "FreeBSD-nandfs" +#endif + static struct mkimg_alias apm_aliases[] = { { ALIAS_FREEBSD, ALIAS_PTR2TYPE(APM_ENT_TYPE_FREEBSD) }, + { ALIAS_FREEBSD_BOOT, ALIAS_PTR2TYPE(APM_ENT_TYPE_APPLE_BOOT) }, { ALIAS_FREEBSD_NANDFS, ALIAS_PTR2TYPE(APM_ENT_TYPE_FREEBSD_NANDFS) }, { ALIAS_FREEBSD_SWAP, ALIAS_PTR2TYPE(APM_ENT_TYPE_FREEBSD_SWAP) }, { ALIAS_FREEBSD_UFS, ALIAS_PTR2TYPE(APM_ENT_TYPE_FREEBSD_UFS) }, @@ -58,13 +64,12 @@ apm_metadata(u_int where) } static int -apm_write(int fd __unused, lba_t imgsz __unused, void *bootcode __unused) +apm_write(lba_t imgsz, void *bootcode __unused) { u_char *buf; struct apm_ddr *ddr; struct apm_ent *ent; struct part *part; - ssize_t nbytes; int error; buf = calloc(nparts + 2, secsz); @@ -81,8 +86,8 @@ apm_write(int fd __unused, lba_t imgsz _ be32enc(&ent->ent_pmblkcnt, nparts + 1); be32enc(&ent->ent_start, 1); be32enc(&ent->ent_size, nparts + 1); - strcpy(ent->ent_type, APM_ENT_TYPE_SELF); - strcpy(ent->ent_name, "Apple"); + 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) { ent = (void *)(buf + (part->index + 2) * secsz); @@ -90,17 +95,14 @@ apm_write(int fd __unused, lba_t imgsz _ be32enc(&ent->ent_pmblkcnt, nparts + 1); be32enc(&ent->ent_start, part->block); be32enc(&ent->ent_size, part->size); - strcpy(ent->ent_type, ALIAS_TYPE2PTR(part->type)); + strncpy(ent->ent_type, ALIAS_TYPE2PTR(part->type), + sizeof(ent->ent_type)); if (part->label != NULL) - strcpy(ent->ent_name, part->label); + strncpy(ent->ent_name, part->label, + sizeof(ent->ent_name)); } - error = mkimg_seek(fd, 0); - if (error == 0) { - nbytes = (nparts + 2) * secsz; - if (write(fd, buf, nbytes) != nbytes) - error = errno; - } + error = image_write(0, buf, nparts + 2); free(buf); return (error); } Modified: stable/10/usr.bin/mkimg/bsd.c ============================================================================== --- head/usr.bin/mkimg/bsd.c Sat Mar 29 19:03:10 2014 (r263918) +++ stable/10/usr.bin/mkimg/bsd.c Wed Jul 2 14:54:41 2014 (r268161) @@ -35,9 +35,14 @@ __FBSDID("$FreeBSD$"); #include #include +#include "image.h" #include "mkimg.h" #include "scheme.h" +#ifndef FS_NANDFS +#define FS_NANDFS 30 +#endif + static struct mkimg_alias bsd_aliases[] = { { ALIAS_FREEBSD_NANDFS, ALIAS_INT2TYPE(FS_NANDFS) }, { ALIAS_FREEBSD_SWAP, ALIAS_INT2TYPE(FS_SWAP) }, @@ -57,7 +62,7 @@ bsd_metadata(u_int where) } static int -bsd_write(int fd, lba_t imgsz, void *bootcode) +bsd_write(lba_t imgsz, void *bootcode) { u_char *buf, *p; struct disklabel *d; @@ -75,8 +80,12 @@ bsd_write(int fd, lba_t imgsz, void *boo } else memset(buf, 0, BBSIZE); - imgsz = ncyls * nheads * nsecs; - ftruncate(fd, imgsz * secsz); + imgsz = (lba_t)ncyls * nheads * nsecs; + error = image_set_size(imgsz); + if (error) { + free(buf); + return (error); + } d = (void *)(buf + secsz); le32enc(&d->d_magic, DISKMAGIC); @@ -107,11 +116,7 @@ bsd_write(int fd, lba_t imgsz, void *boo checksum ^= le16dec(p); le16enc(&d->d_checksum, checksum); - error = mkimg_seek(fd, 0); - if (error == 0) { - if (write(fd, buf, BBSIZE) != BBSIZE) - error = errno; - } + error = image_write(0, buf, BBSIZE / secsz); free(buf); return (error); } Modified: stable/10/usr.bin/mkimg/ebr.c ============================================================================== --- head/usr.bin/mkimg/ebr.c Sat Mar 29 19:03:10 2014 (r263918) +++ stable/10/usr.bin/mkimg/ebr.c Wed Jul 2 14:54:41 2014 (r268161) @@ -35,9 +35,14 @@ __FBSDID("$FreeBSD$"); #include #include +#include "image.h" #include "mkimg.h" #include "scheme.h" +#ifndef DOSPTYP_FAT32 +#define DOSPTYP_FAT32 0x0b +#endif + static struct mkimg_alias ebr_aliases[] = { { ALIAS_FAT32, ALIAS_INT2TYPE(DOSPTYP_FAT32) }, { ALIAS_FREEBSD, ALIAS_INT2TYPE(DOSPTYP_386BSD) }, @@ -63,7 +68,7 @@ ebr_chs(u_char *cyl, u_char *hd, u_char } static int -ebr_write(int fd, lba_t imgsz __unused, void *bootcode __unused) +ebr_write(lba_t imgsz __unused, void *bootcode __unused) { u_char *ebr; struct dos_partition *dp; @@ -100,11 +105,7 @@ ebr_write(int fd, lba_t imgsz __unused, le32enc(&dp->dp_size, next->size + nsecs); } - error = mkimg_seek(fd, block); - if (error == 0) { - if (write(fd, ebr, secsz) != (ssize_t)secsz) - error = errno; - } + error = image_write(block, ebr, 1); if (error) break; Copied: stable/10/usr.bin/mkimg/format.c (from r266176, head/usr.bin/mkimg/format.c) ============================================================================== --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ stable/10/usr.bin/mkimg/format.c Wed Jul 2 14:54:41 2014 (r268161, copy of r266176, head/usr.bin/mkimg/format.c) @@ -0,0 +1,91 @@ +/*- + * Copyright (c) 2014 Juniper Networks, Inc. + * 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. + */ + +#include +__FBSDID("$FreeBSD$"); + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "image.h" +#include "format.h" +#include "mkimg.h" + +static struct mkimg_format *format; + +int +format_resize(lba_t end) +{ + + if (format == NULL) + return (ENOSYS); + return (format->resize(end)); +} + +int +format_select(const char *spec) +{ + struct mkimg_format *f, **iter; + + SET_FOREACH(iter, formats) { + f = *iter; + if (strcasecmp(spec, f->name) == 0) { + format = f; + return (0); + } + } + return (EINVAL); +} + +struct mkimg_format * +format_selected(void) +{ + + return (format); +} + +int +format_write(int fd) +{ + lba_t size; + int error; + + if (format == NULL) + return (ENOSYS); + size = image_get_size(); + error = format->resize(size); + if (!error) + error = format->write(fd); + return (error); +} Copied: stable/10/usr.bin/mkimg/format.h (from r266176, head/usr.bin/mkimg/format.h) ============================================================================== --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ stable/10/usr.bin/mkimg/format.h Wed Jul 2 14:54:41 2014 (r268161, copy of r266176, head/usr.bin/mkimg/format.h) @@ -0,0 +1,49 @@ +/*- + * Copyright (c) 2014 Juniper Networks, Inc. + * 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_FORMAT_H_ +#define _MKIMG_FORMAT_H_ + +#include + +struct mkimg_format { + 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) + +int format_resize(lba_t); +int format_select(const char *); +struct mkimg_format *format_selected(void); +int format_write(int); + +#endif /* _MKIMG_FORMAT_H_ */ Modified: stable/10/usr.bin/mkimg/gpt.c ============================================================================== --- head/usr.bin/mkimg/gpt.c Sat Mar 29 19:03:10 2014 (r263918) +++ stable/10/usr.bin/mkimg/gpt.c Wed Jul 2 14:54:41 2014 (r268161) @@ -39,9 +39,15 @@ __FBSDID("$FreeBSD$"); #include #include +#include "image.h" #include "mkimg.h" #include "scheme.h" +#ifndef GPT_ENT_TYPE_FREEBSD_NANDFS +#define GPT_ENT_TYPE_FREEBSD_NANDFS \ + {0x74ba7dd9,0xa689,0x11e1,0xbd,0x04,{0x00,0xe0,0x81,0x28,0x6a,0xcf}} +#endif + static uuid_t gpt_uuid_efi = GPT_ENT_TYPE_EFI; static uuid_t gpt_uuid_freebsd = GPT_ENT_TYPE_FREEBSD; static uuid_t gpt_uuid_freebsd_boot = GPT_ENT_TYPE_FREEBSD_BOOT; @@ -123,6 +129,21 @@ 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) { @@ -146,20 +167,7 @@ gpt_metadata(u_int where) } static int -gpt_filewrite(int fd, lba_t blk, void *buf, ssize_t bufsz) -{ - int error; - - error = mkimg_seek(fd, blk); - if (error == 0) { - if (write(fd, buf, bufsz) != bufsz) - error = errno; - } - return (error); -} - -static int -gpt_write_pmbr(int fd, lba_t blks, void *bootcode) +gpt_write_pmbr(lba_t blks, void *bootcode) { u_char *pmbr; uint32_t secs; @@ -183,7 +191,7 @@ gpt_write_pmbr(int fd, lba_t blks, void le32enc(pmbr + DOSPARTOFF + 8, 1); le32enc(pmbr + DOSPARTOFF + 12, secs); le16enc(pmbr + DOSMAGICOFFSET, DOSMAGIC); - error = gpt_filewrite(fd, 0, pmbr, secsz); + error = image_write(0, pmbr, 1); free(pmbr); return (error); } @@ -202,9 +210,9 @@ gpt_mktbl(u_int tblsz) STAILQ_FOREACH(part, &partlist, link) { ent = tbl + part->index; - uuid_enc_le(&ent->ent_type, ALIAS_TYPE2PTR(part->type)); + gpt_uuid_enc(&ent->ent_type, ALIAS_TYPE2PTR(part->type)); uuidgen(&uuid, 1); - uuid_enc_le(&ent->ent_uuid, &uuid); + gpt_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) { @@ -219,8 +227,7 @@ gpt_mktbl(u_int tblsz) } static int -gpt_write_hdr(int fd, struct gpt_hdr *hdr, uint64_t self, uint64_t alt, - uint64_t tbl) +gpt_write_hdr(struct gpt_hdr *hdr, uint64_t self, uint64_t alt, uint64_t tbl) { uint32_t crc; @@ -230,11 +237,11 @@ gpt_write_hdr(int fd, struct gpt_hdr *hd hdr->hdr_crc_self = 0; crc = crc32(hdr, offsetof(struct gpt_hdr, padding)); le64enc(&hdr->hdr_crc_self, crc); - return (gpt_filewrite(fd, self, hdr, secsz)); + return (image_write(self, hdr, 1)); } static int -gpt_write(int fd, lba_t imgsz, void *bootcode) +gpt_write(lba_t imgsz, void *bootcode) { uuid_t uuid; struct gpt_ent *tbl; @@ -244,7 +251,7 @@ gpt_write(int fd, lba_t imgsz, void *boo int error; /* PMBR */ - error = gpt_write_pmbr(fd, imgsz, bootcode); + error = gpt_write_pmbr(imgsz, bootcode); if (error) return (error); @@ -253,10 +260,10 @@ gpt_write(int fd, lba_t imgsz, void *boo tbl = gpt_mktbl(tblsz); if (tbl == NULL) return (errno); - error = gpt_filewrite(fd, 2, tbl, tblsz * secsz); + error = image_write(2, tbl, tblsz); if (error) goto out; - error = gpt_filewrite(fd, imgsz - (tblsz + 1), tbl, tblsz * secsz); + error = image_write(imgsz - (tblsz + 1), tbl, tblsz); if (error) goto out; @@ -273,14 +280,14 @@ gpt_write(int fd, lba_t imgsz, void *boo le64enc(&hdr->hdr_lba_start, 2 + tblsz); le64enc(&hdr->hdr_lba_end, imgsz - tblsz - 2); uuidgen(&uuid, 1); - uuid_enc_le(&hdr->hdr_uuid, &uuid); + gpt_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)); le32enc(&hdr->hdr_crc_table, crc); - error = gpt_write_hdr(fd, hdr, 1, imgsz - 1, 2); + error = gpt_write_hdr(hdr, 1, imgsz - 1, 2); if (!error) - error = gpt_write_hdr(fd, hdr, imgsz - 1, 1, imgsz - tblsz - 1); + error = gpt_write_hdr(hdr, imgsz - 1, 1, imgsz - tblsz - 1); free(hdr); out: Copied and modified: stable/10/usr.bin/mkimg/image.c (from r266176, head/usr.bin/mkimg/image.c) ============================================================================== --- head/usr.bin/mkimg/image.c Thu May 15 19:19:57 2014 (r266176, copy source) +++ stable/10/usr.bin/mkimg/image.c Wed Jul 2 14:54:41 2014 (r268161) @@ -30,6 +30,9 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include +#include +#include #include #include @@ -38,7 +41,7 @@ __FBSDID("$FreeBSD$"); #define BUFFER_SIZE (1024*1024) -static char image_tmpfile[] = "/tmp/mkimg-XXXXXX"; +static char image_tmpfile[PATH_MAX]; static int image_fd = -1; static lba_t image_size; @@ -98,11 +101,11 @@ image_copyout(int fd) ofs = lseek(fd, 0L, SEEK_CUR); + if (lseek(image_fd, 0, SEEK_SET) != 0) + return (errno); buffer = malloc(BUFFER_SIZE); if (buffer == NULL) return (errno); - if (lseek(image_fd, 0, SEEK_SET) != 0) - return (errno); error = 0; while (1) { rdsz = read(image_fd, buffer, BUFFER_SIZE); @@ -119,8 +122,12 @@ image_copyout(int fd) } } free(buffer); + if (error) + return (error); ofs = lseek(fd, 0L, SEEK_CUR); - ftruncate(fd, ofs); + if (ofs == -1) + return (errno); + error = (ftruncate(fd, ofs) == -1) ? errno : 0; return (error); } @@ -157,9 +164,14 @@ image_write(lba_t blk, void *buf, ssize_ int image_init(void) { + const char *tmpdir; if (atexit(cleanup) == -1) return (errno); + if ((tmpdir = getenv("TMPDIR")) == NULL || *tmpdir == '\0') + tmpdir = _PATH_TMP; + snprintf(image_tmpfile, sizeof(image_tmpfile), "%s/mkimg-XXXXXX", + tmpdir); image_fd = mkstemp(image_tmpfile); if (image_fd == -1) return (errno); Copied: stable/10/usr.bin/mkimg/image.h (from r266176, head/usr.bin/mkimg/image.h) ============================================================================== --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ stable/10/usr.bin/mkimg/image.h Wed Jul 2 14:54:41 2014 (r268161, copy of r266176, head/usr.bin/mkimg/image.h) @@ -0,0 +1,41 @@ +/*- + * Copyright (c) 2014 Juniper Networks, Inc. + * 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_IMAGE_H_ +#define _MKIMG_IMAGE_H_ + +typedef int64_t lba_t; + +int image_copyin(lba_t blk, int fd, uint64_t *sizep); +int image_copyout(int fd); +lba_t image_get_size(void); +int image_init(void); +int image_set_size(lba_t blk); +int image_write(lba_t blk, void *buf, ssize_t len); + +#endif /* _MKIMG_IMAGE_H_ */ Modified: stable/10/usr.bin/mkimg/mbr.c ============================================================================== --- head/usr.bin/mkimg/mbr.c Sat Mar 29 19:03:10 2014 (r263918) +++ stable/10/usr.bin/mkimg/mbr.c Wed Jul 2 14:54:41 2014 (r268161) @@ -35,9 +35,14 @@ __FBSDID("$FreeBSD$"); #include #include +#include "image.h" #include "mkimg.h" #include "scheme.h" +#ifndef DOSPTYP_FAT32 +#define DOSPTYP_FAT32 0x0b +#endif + static struct mkimg_alias mbr_aliases[] = { { ALIAS_EBR, ALIAS_INT2TYPE(DOSPTYP_EXT) }, { ALIAS_FAT32, ALIAS_INT2TYPE(DOSPTYP_FAT32) }, @@ -64,7 +69,7 @@ mbr_chs(u_char *cyl, u_char *hd, u_char } static int -mbr_write(int fd, lba_t imgsz __unused, void *bootcode) +mbr_write(lba_t imgsz __unused, void *bootcode) { u_char *mbr; struct dos_partition *dpbase, *dp; @@ -92,11 +97,7 @@ mbr_write(int fd, lba_t imgsz __unused, le32enc(&dp->dp_start, part->block); le32enc(&dp->dp_size, part->size); } - error = mkimg_seek(fd, 0); - if (error == 0) { - if (write(fd, mbr, secsz) != (ssize_t)secsz) - error = errno; - } + error = image_write(0, mbr, 1); free(mbr); return (error); } Modified: stable/10/usr.bin/mkimg/mkimg.1 ============================================================================== --- head/usr.bin/mkimg/mkimg.1 Sat Mar 29 19:03:10 2014 (r263918) +++ stable/10/usr.bin/mkimg/mkimg.1 Wed Jul 2 14:54:41 2014 (r268161) @@ -24,7 +24,7 @@ .\" .\" $FreeBSD$ .\" -.Dd March 27, 2014 +.Dd July 2, 2014 .Dt MKIMG 1 .Os .Sh NAME @@ -37,6 +37,7 @@ .Op Fl S Ar secsz .Op Fl T Ar tracksz .Op Fl b Ar bootcode +.Op Fl f Ar format .Op Fl o Ar outfile .Op Fl v .Fl s Ar scheme @@ -56,6 +57,10 @@ The disk image is written to by default or the file specified with the .Ar outfile argument. +The image file is a raw disk image by default, but the format of the +image file can be specified with the +.Ar format +argument. .Pp The disk image can be made bootable by specifying the scheme-specific boot block contents with the @@ -106,10 +111,16 @@ option increases the level of output tha .Nm utility prints. .Pp -For a complete list of supported partitioning schemes or for a detailed -description of how to specify partitions, run the +For a complete list of supported partitioning schemes or supported output +format, or for a detailed description of how to specify partitions, run the .Nm utility without any arguments. +.Sh ENVIRONMENT +.Bl -tag -width "TMPDIR" -compact +.It Ev TMPDIR +Directory to put temporary files in; default is +.Pa /tmp . +.El .Sh EXAMPLES To create a bootable disk image that is partitioned using the GPT scheme and containing a root file system that was previously created using @@ -121,6 +132,14 @@ utility as follows: -p freebsd-ufs:=root-file-system.ufs -p freebsd-swap::1G \ -o gpt.img .Pp +The command line given above results in a raw image file. +This is because no output format was given. +To create a VMDK image for example, add the +.Fl f Ar vmdk +argument to the +.Nm +utility and name the output file accordingly. +.Pp A nested partitioning scheme is created by running the .Nm utility twice. @@ -154,8 +173,8 @@ In the following example the file system .Sh HISTORY The .Nm -utility appeared in -.Fx 11.0 +utility first appeared in +.Fx 10.1 . .Sh AUTHORS The .Nm Modified: stable/10/usr.bin/mkimg/mkimg.c ============================================================================== --- head/usr.bin/mkimg/mkimg.c Sat Mar 29 19:03:10 2014 (r263918) +++ stable/10/usr.bin/mkimg/mkimg.c Wed Jul 2 14:54:41 2014 (r268161) @@ -42,15 +42,11 @@ __FBSDID("$FreeBSD$"); #include #include +#include "image.h" +#include "format.h" #include "mkimg.h" #include "scheme.h" -#if !defined(SPARSE_WRITE) -#define sparse_write write -#endif - -#define BUFFER_SIZE (1024*1024) - struct partlisthead partlist = STAILQ_HEAD_INITIALIZER(partlist); u_int nparts = 0; @@ -62,31 +58,18 @@ u_int nsecs = 1; u_int secsz = 512; u_int blksz = 0; -static int bcfd = -1; -static int outfd = 0; -static int tmpfd = -1; - -static char tmpfname[] = "/tmp/mkimg-XXXXXX"; - -static void -cleanup(void) -{ - - if (tmpfd != -1) - close(tmpfd); - unlink(tmpfname); -} - static void usage(const char *why) { - struct mkimg_scheme *s, **iter; + struct mkimg_format *f, **f_iter; + struct mkimg_scheme *s, **s_iter; warnx("error: %s", why); fprintf(stderr, "\nusage: %s \n", getprogname()); fprintf(stderr, " options:\n"); fprintf(stderr, "\t-b \t- file containing boot code\n"); + fprintf(stderr, "\t-f \n"); fprintf(stderr, "\t-o \t- file to write image into\n"); fprintf(stderr, "\t-p \n"); fprintf(stderr, "\t-s \n"); @@ -95,13 +78,19 @@ usage(const char *why) fprintf(stderr, "\t-S \t- logical sector size\n"); fprintf(stderr, "\t-T \t- number of tracks to simulate\n"); - fprintf(stderr, " schemes:\n"); - SET_FOREACH(iter, schemes) { - s = *iter; + fprintf(stderr, "\n formats:\n"); + SET_FOREACH(f_iter, formats) { + f = *f_iter; + fprintf(stderr, "\t%s\t- %s\n", f->name, f->description); + } + + fprintf(stderr, "\n schemes:\n"); + SET_FOREACH(s_iter, schemes) { + s = *s_iter; fprintf(stderr, "\t%s\t- %s\n", s->name, s->description); } - fprintf(stderr, " partition specification:\n"); + fprintf(stderr, "\n partition specification:\n"); fprintf(stderr, "\t[/]::\t- empty partition of given " "size\n"); fprintf(stderr, "\t[/]:=\t- partition content and size " @@ -228,14 +217,15 @@ parse_part(const char *spec) } #if defined(SPARSE_WRITE) -static ssize_t -sparse_write(int fd, const char *buf, size_t sz) +ssize_t +sparse_write(int fd, const void *ptr, size_t sz) { - const char *p; + const char *buf, *p; off_t ofs; size_t len; ssize_t wr, wrsz; + buf = ptr; wrsz = 0; p = memchr(buf, 0, sz); while (sz > 0) { @@ -268,53 +258,8 @@ sparse_write(int fd, const char *buf, si } #endif /* SPARSE_WRITE */ -static int -fdcopy(int src, int dst, uint64_t *count) -{ - char *buffer; - off_t ofs; - ssize_t rdsz, wrsz; - - /* A return value of -1 means that we can't write a sparse file. */ - ofs = lseek(dst, 0L, SEEK_CUR); - - if (count != NULL) - *count = 0; - - buffer = malloc(BUFFER_SIZE); - if (buffer == NULL) - return (errno); - while (1) { - rdsz = read(src, buffer, BUFFER_SIZE); - if (rdsz <= 0) { - free(buffer); - return ((rdsz < 0) ? errno : 0); - } - if (count != NULL) - *count += rdsz; - wrsz = (ofs == -1) ? - write(dst, buffer, rdsz) : - sparse_write(dst, buffer, rdsz); - if (wrsz < 0) - break; - } - free(buffer); - return (errno); -} - -int -mkimg_seek(int fd, lba_t blk) -{ - off_t off; - - off = blk * secsz; - if (lseek(fd, off, SEEK_SET) != off) - return (errno); - return (0); -} - static void -mkimg(int bfd) +mkimg(void) { FILE *fp; struct part *part; @@ -322,10 +267,6 @@ mkimg(int bfd) off_t bytesize; int error, fd; - error = scheme_bootcode(bfd); - if (error) - errc(EX_DATAERR, error, "boot code"); - /* First check partition information */ STAILQ_FOREACH(part, &partlist, link) { error = scheme_check_part(part); @@ -340,7 +281,6 @@ mkimg(int bfd) fprintf(stderr, "partition %d: starting block %llu " "... ", part->index + 1, (long long)block); part->block = block; - error = mkimg_seek(tmpfd, block); switch (part->kind) { case PART_KIND_SIZE: if (expand_number(part->contents, &bytesize) == -1) @@ -349,7 +289,7 @@ mkimg(int bfd) case PART_KIND_FILE: fd = open(part->contents, O_RDONLY, 0); if (fd != -1) { - error = fdcopy(fd, tmpfd, &bytesize); + error = image_copyin(block, fd, &bytesize); close(fd); } else error = errno; @@ -357,7 +297,8 @@ mkimg(int bfd) case PART_KIND_PIPE: fp = popen(part->contents, "r"); if (fp != NULL) { - error = fdcopy(fileno(fp), tmpfd, &bytesize); + fd = fileno(fp); + error = image_copyin(block, fd, &bytesize); pclose(fp); } else error = errno; @@ -376,15 +317,27 @@ mkimg(int bfd) } block = scheme_metadata(SCHEME_META_IMG_END, block); - error = (scheme_write(tmpfd, block)); + error = image_set_size(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)); + if (error) + errc(EX_IOERR, error, "writing metadata"); } int main(int argc, char *argv[]) { + int bcfd, outfd; int c, error; - while ((c = getopt(argc, argv, "b:o:p:s:vH:P:S:T:")) != -1) { + bcfd = -1; + outfd = 1; /* Write to stdout by default */ + while ((c = getopt(argc, argv, "b:f:o:p:s:vH:P:S:T:")) != -1) { switch (c) { case 'b': /* BOOT CODE */ if (bcfd != -1) @@ -393,8 +346,15 @@ main(int argc, char *argv[]) if (bcfd == -1) err(EX_UNAVAILABLE, "%s", optarg); break; + case 'f': /* OUTPUT FORMAT */ + if (format_selected() != NULL) + usage("multiple formats given"); + error = format_select(optarg); + if (error) + errc(EX_DATAERR, error, "format"); + break; case 'o': /* OUTPUT FILE */ - if (outfd != 0) + if (outfd != 1) usage("multiple output files given"); outfd = open(optarg, O_WRONLY | O_CREAT | O_TRUNC, S_IWUSR | S_IRUSR | S_IRGRP | S_IROTH); @@ -467,35 +427,43 @@ main(int argc, char *argv[]) errx(EX_DATAERR, "%d partitions supported; %d given", scheme_max_parts(), nparts); - if (outfd == 0) { - if (atexit(cleanup) == -1) - err(EX_OSERR, "cannot register cleanup function"); - outfd = 1; - tmpfd = mkstemp(tmpfname); - if (tmpfd == -1) - err(EX_OSERR, "cannot create temporary file"); - } else - tmpfd = outfd; + if (format_selected() == NULL) + format_select("raw"); + + if (bcfd != -1) { + error = scheme_bootcode(bcfd); + close(bcfd); + if (error) + errc(EX_DATAERR, error, "boot code"); + } if (verbose) { fprintf(stderr, "Logical sector size: %u\n", secsz); fprintf(stderr, "Physical block size: %u\n", blksz); 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); + fprintf(stderr, "Output file format: %s\n", + format_selected()->name); + fputc('\n', stderr); } - mkimg(bcfd); + error = image_init(); + if (error) + errc(EX_OSERR, error, "cannot initialize"); - if (verbose) - fprintf(stderr, "Number of cylinders: %u\n", ncyls); + mkimg(); - if (tmpfd != outfd) { - error = mkimg_seek(tmpfd, 0); - if (error == 0) - error = fdcopy(tmpfd, outfd, NULL); - if (error) - errc(EX_IOERR, error, "writing to stdout"); + if (verbose) { + fputc('\n', stderr); + fprintf(stderr, "Number of cylinders: %u\n", ncyls); } *** DIFF OUTPUT TRUNCATED AT 1000 LINES ***