74 Commits

Author SHA1 Message Date
marcel
2a0c5f7194 Replace unchecked calls to write(2) and lseek(2) with calls to
sparse_write() and make sure to check for errors. In particular,
lseek(2) may not be possible (e.g. the output file is stdout)
and sparse_write(2) will do what is optimal (i.e. use lseek(2)
when possible).
2014-05-15 14:48:25 +00:00
marcel
bea02c4125 Give sparse_write() the same prototype as write(2) as it's supposed to
be a drop-in replacement.
2014-05-15 14:37:35 +00:00
marcel
048d89bb17 Check allocation errors and free memory we allocated. 2014-05-15 14:01:34 +00:00
marcel
2257ed47a7 As it appears the image must be rounded to the nearest megabyte, 2014-05-15 03:18:22 +00:00
marcel
20d78d563e Have the format resize twice. The first time is before we call
scheme_write(). The second time is immediately before we call
the format's write function. The first call is needed to have
the scheme know the right image size. The second call is needed
to compensate for the scheme adjusting the size while writing.
2014-05-15 00:48:05 +00:00
marcel
5a1f714ca6 Commit rough but working code:
o   The VMDK image can be queried and comverted by qemu-img
o   VMware Fusion finds no errors when recovering using
    'vmware-vdiskmanager -R' and the disk can be added to any
    vortual machine.
2014-05-15 00:24:49 +00:00
marcel
fb177229cf Give output formats a chance to (re-)size the image before the
scheme adds the partitioning metadata. This is needed by VMDK
to round the image size to the grain size.
2014-05-14 15:46:07 +00:00
marcel
9f8da783c7 Add image_get_size() so formats can query about the image size.
Create the VMDK (embedded) descriptor file and round its size
to a multiple of 512.

TODO: We need the name of the output file -- it's in the extent
description. For now, just use "mkimg.vmdk".
2014-05-09 01:13:14 +00:00
marcel
bd79c282bb Add format_write() that calls the write() function of the output
format. Have the raw format use image_copyout() for now.
2014-05-08 21:12:39 +00:00
marcel
fdd67dad26 Have image_write() call sparse_write() so that we can use SEEK_HOLE
and SEEK_DATA to "quickly" find occupied sectors. This is all short-
lived, because the image should not be kept in a file, but in memory.
To be precise: the image API should be both efficient and scalable
and using a file is not efficient -- it works, which is what I need
right now.
2014-05-08 15:33:52 +00:00
marcel
f7a8c7b2f2 Define the sparse extent header and document the steps to take
to create the VMDK file. Add some notes as well.

What I needed to know (roughly) is what interface the image API
is to provide and whether there are (knowledge) gaps that prevent
me from implementing it for real.
2014-05-08 15:24:51 +00:00
marcel
3ca7c0d5b4 Add the -f option for specifying the output format. Update the manpage
accordingly. Print the scheme and the format when running verbose.
2014-05-08 01:43:33 +00:00
marcel
7a44648d50 Add a linker set for output formats. This is mostly copied and trimmed
from the linker set for schemes. Add stubs for raw and vmdk output
formats so as to demonstrate that the usage message is correct.
2014-05-08 01:13:18 +00:00
marcel
fbb42db4a0 When write sparse files, make sure to truncate(2) the file. Otherwise
any hole at the end is lost and the file is not of the right size.
2014-05-08 00:08:19 +00:00
marcel
8e16ce11e9 Provide a file-based implementation for the image API. This almost
copies the logic verbatim from mkimg.c to image.c. The difference
is that in image.c the temporary file is always created, whereas
before we only created a temporary file when writing to stdout.

Cleanup mkimg.c now that the song and dance of using a temporary
file is gone.
2014-05-07 22:06:54 +00:00
marcel
ec5097c811 Replace 2 instances of fdcopy() with image_copyin(). With this, the
mkimg() function does not need the ofd argument and all references
to an output file descriptor in the input phase are gone.
2014-05-07 20:50:16 +00:00
marcel
24cdcc8e3f Switch to the image API:
1.  Replace calls to mkimg_set_size() with calls to image_set_size()
2.  Remove the mkimg_set_size() function
3.  As above but for mkimg_write() and image_write()

Note that this breaks mkimg(1). The image API has no implementation.
Hence doing it on my branch :-)
2014-05-07 17:33:31 +00:00
marcel
070a8547ae Add image.c and image.h. These files will contain functions to implement
the management of the raw image that's being created. The most notable of
the API is that there's no file descriptor argument. This is because the
image is managed in memory.

Once we have the in-memory (raw) image, we can write it out acording to
different formats. This two-pass approach shields schemes from formats
and formats from schemes.
2014-05-07 17:12:15 +00:00
marcel
ef21d96a0f Abstract the use of ftruncate(2) behind mkimg_set_size(). 2014-05-07 15:08:00 +00:00
marcel
8743dd6a3b Eliminate mkimg_seek() by moving the lseek(2) calls into fdcopy().
While here, minimize use of the global tmpfd by passing it as ofd
to mkimg.
2014-05-07 14:57:56 +00:00
marcel
e22d96c863 Merge ^/head/usr.bin/mkimg@265546 2014-05-07 14:20:58 +00:00
marcel
30dea1dbd2 Build this on sparc64, where we don't have LABELSECTOR nor LABELOFFSET
defined. Improve portability by eliminating their use.
2014-03-29 04:05:57 +00:00
marcel
f017f60135 Make this build on ia64 w/ gcc. 2014-03-29 03:55:58 +00:00
marcel
4aafbd0ea1 Fix build on i386 w/ clang. 2014-03-29 03:46:36 +00:00
marcel
fae0837f6d Add a paragraph about running mkimg without arguments to get a list
of supported schemes and/or a detailed description of how to specify
partitions.
2014-03-29 03:39:22 +00:00
marcel
3b7cf0602a Document how labels can be given to partitions. 2014-03-29 03:33:31 +00:00
marcel
50a0b74b99 Handle the raw partition of the BSD and VTOC schemes. 2014-03-29 03:14:00 +00:00
marcel
650a8b44e4 Make mkimg a general command and not a maintenance command. 2014-03-28 05:06:12 +00:00
marcel
e2f9db5916 Define SPARSE_WRITE to enable writing sparse files. Output compares ok... 2014-03-28 04:51:18 +00:00
marcel
e55a2fe916 Flesh-out manpage. 2014-03-28 04:43:36 +00:00
marcel
76165e705c Use :- and not :! for pipes. ! needs to be escaped, which adds to the
hassle.
2014-03-28 04:42:34 +00:00
marcel
533cda2b92 Write verbosity to stderr. The image may be written to stdout.
While here, fix writing to stderr, by not calling errc()
unconditionally, but only when there's an error.
2014-03-28 04:14:40 +00:00
marcel
4cf1c78a43 Write sparse files by default (when SPARSE_FILE is defined).
While here, detect errors when writing to stdout.
2014-03-28 01:55:02 +00:00
marcel
ba63787689 Partitions start on cylinder boundaries. 2014-03-28 01:52:48 +00:00
marcel
fe7be9e673 Partitions start on track boundaries. 2014-03-28 01:51:45 +00:00
marcel
36046d28b3 Partitions start on track boundaries. 2014-03-28 01:50:56 +00:00
marcel
b7c3be9e45 Remove the -z flag. Let's just write a sparse file whenever we can. 2014-03-27 23:44:16 +00:00
marcel
c4d8b579ba Properly fill in d_nsectors, d_ntracks, d_ncylinders & d_secpercyl.
Round the image size to a multiple of the cyclinder size.
2014-03-27 23:16:18 +00:00
marcel
da0f041a0e Remember operator precedence? 2014-03-27 23:15:07 +00:00
marcel
452aa44886 Give vtoc8 a change to work: when setting the physical block size to 4K,
sectors/track to 8 and number or heads to 1, partitions that are block
aligned are also cyclinder aligned. With that trick, fix the vtoc8:
1.  Set physcyls, ncyls, altcyls, nheads and nsecs appropriately.
2.  Truncate the image size to exactly ncyls * nheads * nsecs * secsz.
3.  Properly write the cylinder number as the start of the partition.
4.  Oh, and actually calculate the checksum of the label...
2014-03-27 22:48:48 +00:00
marcel
bfd31b94a3 1. When calculating block addresses, round to the physical block
size.
2.  Replace scheme_first_block() & scheme_next_block() with
    scheme_metadata(). When we round to block sizes, we can't
    reliably fixup any miscalculations.
3.  In scheme_write, calculate ncyls (number of cyclinders), based
    on the total size, sectors/track and number of heads.
4.  Add verbosity when constructing the partitions. This includes
    the starting block address and size in bytes and blocks.
5.  Add verbosity about the sectors/track and number of heads.
2014-03-27 22:45:05 +00:00
marcel
5d04a4dffc Remove trksz, which was hardcoded to 1, and replace it by secs, which
can be set on the command line.
2014-03-27 22:39:22 +00:00
marcel
a349124060 Fix writing the start and size fields. 2014-03-27 21:32:02 +00:00
marcel
6084642f6d 1. Add -v option to increase vebosity levels
2.  Fix copy-paste bug -- acrually check secsz for being a power of 2
3.  Check secsz and blksz parameters
4.  Print the sector and block size when -v is given
2014-03-27 20:14:40 +00:00
marcel
e7f6c0c88b Add scheme_max_secsz() for returning the maximum sector size supported
by the partitioning scheme.
2014-03-27 20:10:26 +00:00
marcel
0a263459f5 First batch of media control:
1.  Change -h to -H and change -t to -T. Use -H to specify the number of
    heads and -T to specify the track size (number of sectors per track).
2.  Add -S and -P. Use -S to specify the logical sector size and -P to
    specify the physical sector size.

Default to 512 for both the logical and physical sector size.
Set nheads and nsecs to 1 by default.
2014-03-25 04:45:55 +00:00
marcel
572e125f42 Move setting CHS fields to mbr_chs() in preparation of ... 2014-03-25 03:58:13 +00:00
marcel
cedbce4789 Allow schemes to specify a maximum sector size. The minimum is fixed
at 512. This allows checking of the sector size up-front when given
on the command line.
2014-03-25 02:32:04 +00:00
marcel
4eff23dbe8 Mostly implement the vtoc8 scheme. The vtoc8 scheme uses cylinders for
the beginning of partitions, which makes it sensitive to geometry.
Again, we'll need to revisit this.
2014-03-25 02:15:19 +00:00
marcel
71584f05df Mostly implement the pc98 scheme. The partition table has no LBA
fields at all, so we're entirely dependent upon CHS addressing.
And CHS addressing is what needs more work.
2014-03-25 00:29:56 +00:00