History log of /freebsd-current/usr.bin/mkimg/image.c
Revision Date Author Comments
# 1d386b48 16-Aug-2023 Warner Losh <imp@FreeBSD.org>

Remove $FreeBSD$: one-line .c pattern

Remove /^[\s*]*__FBSDID\("\$FreeBSD\$"\);?\s*\n/


# baf4abfc 02-Mar-2017 Simon J. Gerraty <sjg@FreeBSD.org>

Allow building mkimg as cross-tool

For linux the mmap offset must also be page aligned, and we
need to disable macros like __FBSDID()

Change the linux osdep_uuidgen() to use more portable gettimeofday().

Reviewed by: marcel


# 6b123571 02-Oct-2016 Marcel Moolenaar <marcel@FreeBSD.org>

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.


# 1080fb19 02-Oct-2016 Marcel Moolenaar <marcel@FreeBSD.org>

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.


# 7b5a53ea 25-Sep-2016 Marcel Moolenaar <marcel@FreeBSD.org>

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.


# 4039ea7c 25-Sep-2016 Marcel Moolenaar <marcel@FreeBSD.org>

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.


# cc7f01a5 31-May-2016 Mark Johnston <markj@FreeBSD.org>

mkimg: Indicate that input file pages are unlikely to be reused.

mkimg(1) uses a swap file to back input file chunks. When the output file
is being written out, blocks of the swap file are mapped and their contents
copied. This causes the backing VM pages to enter the active queue, and when
the output file is large relative to system memory (as is generally the
case), can result in a shortfall of inactive memory. This causes the
pagedaemon to aggressively scan the active queue and swap out process
memory in an attempt to meet the shortfall. Because mkimg's input files
are typically the intermediate result of some build process, there's no
need to push them all through the active queue. Use madvise(2) to indicate
that the backing pages may be reclaimed in preference to active pages. In
the case of the swap file, these pages will be freed as soon as mkimg
exits anyway.

When using mkimg on a desktop-class system with large amounts of dirty
process memory, this change substantially improves mkimg runtime and
reduces swap usage.

Reviewed by: marcel
MFC after: 2 weeks
Differential Revision: https://reviews.freebsd.org/D6654


# ddaceed2 02-Aug-2015 Marcel Moolenaar <marcel@FreeBSD.org>

Make image_copyout_zeroes() an interface function.


# 9ba57342 11-Nov-2014 Marcel Moolenaar <marcel@FreeBSD.org>

SEEK_DATA has interesting behaviour for sparse files on ZFS. A sparse file
with 128K of random data and truncated to 800K can have SEEK_DATA return -1
when given an offset of 128K. On UFS, the SEEK_DATA returns 800K (the size
of the file). SEEK_HOLE on ZFS seems to behave the same as UFS.

To handle this, map -1 to the size of the file (`end') when lseek returns
this for either SEEK_HOLE or SEEK_DATA. When sparse files are not supported
by the file system both `hole' and `data' will now be equal to `end' and we
will treat the entire file as data. This way, the -1 return for SEEK_DATA
on ZFS will end up doing the right thing.

Reported by: gjb@

MFC after: 3 days


# 852a0932 01-Oct-2014 Marcel Moolenaar <marcel@FreeBSD.org>

Improve performance of mking(1) by keeping a list of "chunks" in memory,
that keeps track of a particular region of the image. In particular the
image_data() function needs to return to the caller whether a region
contains data or is all zeroes. This required reading the region from
the temporary file and comparing the bytes. When image_data() is used
multiple times for the same region, this will get painful fast.

With a chunk describing a region of the image, we now also have a way
to refer to the image provided on the command line. This means we don't
need to copy the image into a temporary file. We just keep track of the
file descriptor and offset within the source file on a per-chunk basis.

For streams (pipes, sockets, fifos, etc) we now use the temporary file
as a swap file. We read from the input file and create a chunk of type
"zeroes" for each sequence of zeroes that's a multiple of the sector
size. Otherwise, we allocte from the swap file, mmap(2) it, read into
the mmap(2)'d memory and create a chunk representing data.

For regular files, we use SEEK_HOLE and SEEK_DATA to handle sparse files
eficiently and create a chunk of type zeroes for holes and a chunk of
type data for data regions. For data regions, we still compare the bytes
we read to handle differences between a file system's block size and our
sector size.

After reading all files, image_write() is used by schemes to scribble in
the reserved sectors. Since this never amounts to much, keep this data
in memory in chunks of exactly 1 sector.

The output image is created by looking using the chunk list to find the
data and write it out to the output file. For chunks of type "zeroes"
we prefer to seek, but fall back to writing zeroes to handle pipes.
For chunks of type "file" and "memoty" we simply write.

The net effect of this is that for reasonably large images the execution
time drops from 1-2 minutes to 10-20 seconds. A typical speedup is about
5 to 8 times, depending on partition sizes, output format whether in
input files are sparse or not.

Bump version to 20141001.


# a0f136e1 14-Jul-2014 Marcel Moolenaar <marcel@FreeBSD.org>

Add image_data() for checking whether a sequence of blocks has data.
Use this for VHD and VMDK to avoid allocating space in the image
for empty sectors.

Note that this negatively affects performance because mkimg uses a
temporary file for the intermediate storage. When mkimg has better
internal book keeping, performance can be significantly improved.


# f3582a72 03-Jul-2014 Marcel Moolenaar <marcel@FreeBSD.org>

Add VHD support to mkimg(1). VHD is used by Xen and Microsoft's Hyper-V
among others.

Add an undocumented option for unit testing (-y). When given, the image
will have UUIDs and timestamps synthesized in a way that gives identical
results across runs. As such, UUIDs stop being unique, globally or
otherwise.

VHD support requested by: gjb@


# aa30ba04 22-May-2014 Marcel Moolenaar <marcel@FreeBSD.org>

Create our temporary file in $TMPDIR, if the environment variable
is set. /tmp otherwise.

Submitted by: Dan McGregor <danismostlikely@gmail.com>


# 645c7219 21-May-2014 Marcel Moolenaar <marcel@FreeBSD.org>

Fix CID 1215124: Handle errors properly.


# bce9a24a 21-May-2014 Marcel Moolenaar <marcel@FreeBSD.org>

Fix CID 1215129: move the call to lseek(2) before the call to malloc(3)
so that the error path (taken due to lseek(2) failing) isn't leaking
memory.


# f0e9dced 15-May-2014 Marcel Moolenaar <marcel@FreeBSD.org>

MFuser/marcel/mkimg:
Add support for different output formats:
1. The output file that was previously written is now called the raw format.
2. Add the vmdk output format to create VMDK images.

When the format is not given, the raw output format is assumed.