Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 25 Aug 2015 04:03:51 +0000 (UTC)
From:      Marcel Moolenaar <marcel@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-10@freebsd.org
Subject:   svn commit: r287122 - stable/10/usr.bin/mkimg
Message-ID:  <201508250403.t7P43p2L007660@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: marcel
Date: Tue Aug 25 04:03:51 2015
New Revision: 287122
URL: https://svnweb.freebsd.org/changeset/base/287122

Log:
  MFC r286660, r286419, r286417, r286395, r286215, r284883
  
  -   Add the ntfs alias
  -   Fix the dynamic VHD format to work with qemu
  -   Update manpage
  
  MFH:
  Differential Revision:

Modified:
  stable/10/usr.bin/mkimg/gpt.c
  stable/10/usr.bin/mkimg/image.c
  stable/10/usr.bin/mkimg/image.h
  stable/10/usr.bin/mkimg/mbr.c
  stable/10/usr.bin/mkimg/mkimg.1
  stable/10/usr.bin/mkimg/scheme.c
  stable/10/usr.bin/mkimg/scheme.h
  stable/10/usr.bin/mkimg/vhd.c
Directory Properties:
  stable/10/   (props changed)

Modified: stable/10/usr.bin/mkimg/gpt.c
==============================================================================
--- stable/10/usr.bin/mkimg/gpt.c	Tue Aug 25 01:01:25 2015	(r287121)
+++ stable/10/usr.bin/mkimg/gpt.c	Tue Aug 25 04:03:51 2015	(r287122)
@@ -57,6 +57,7 @@ static uuid_t gpt_uuid_freebsd_ufs = GPT
 static uuid_t gpt_uuid_freebsd_vinum = GPT_ENT_TYPE_FREEBSD_VINUM;
 static uuid_t gpt_uuid_freebsd_zfs = GPT_ENT_TYPE_FREEBSD_ZFS;
 static uuid_t gpt_uuid_mbr = GPT_ENT_TYPE_MBR;
+static uuid_t gpt_uuid_ms_basic_data = GPT_ENT_TYPE_MS_BASIC_DATA;
 
 static struct mkimg_alias gpt_aliases[] = {
     {	ALIAS_EFI, ALIAS_PTR2TYPE(&gpt_uuid_efi) },
@@ -68,6 +69,7 @@ static struct mkimg_alias gpt_aliases[] 
     {	ALIAS_FREEBSD_VINUM, ALIAS_PTR2TYPE(&gpt_uuid_freebsd_vinum) },
     {	ALIAS_FREEBSD_ZFS, ALIAS_PTR2TYPE(&gpt_uuid_freebsd_zfs) },
     {	ALIAS_MBR, ALIAS_PTR2TYPE(&gpt_uuid_mbr) },
+    {	ALIAS_NTFS, ALIAS_PTR2TYPE(&gpt_uuid_ms_basic_data) },
     {	ALIAS_NONE, 0 }		/* Keep last! */
 };
 

Modified: stable/10/usr.bin/mkimg/image.c
==============================================================================
--- stable/10/usr.bin/mkimg/image.c	Tue Aug 25 01:01:25 2015	(r287121)
+++ stable/10/usr.bin/mkimg/image.c	Tue Aug 25 04:03:51 2015	(r287122)
@@ -517,14 +517,14 @@ image_copyout_memory(int fd, size_t size
 	return (0);
 }
 
-static int
-image_copyout_zeroes(int fd, size_t size)
+int
+image_copyout_zeroes(int fd, size_t count)
 {
 	static uint8_t *zeroes = NULL;
 	size_t sz;
 	int error;
 
-	if (lseek(fd, (off_t)size, SEEK_CUR) != -1)
+	if (lseek(fd, (off_t)count, SEEK_CUR) != -1)
 		return (0);
 
 	/*
@@ -537,12 +537,12 @@ image_copyout_zeroes(int fd, size_t size
 			return (ENOMEM);
 	}
 
-	while (size > 0) {
-		sz = (size > secsz) ? secsz : size;
+	while (count > 0) {
+		sz = (count > secsz) ? secsz : count;
 		error = image_copyout_memory(fd, sz, zeroes);
 		if (error)
 			return (error);
-		size -= sz;
+		count -= sz;
 	}
 	return (0);
 }

Modified: stable/10/usr.bin/mkimg/image.h
==============================================================================
--- stable/10/usr.bin/mkimg/image.h	Tue Aug 25 01:01:25 2015	(r287121)
+++ stable/10/usr.bin/mkimg/image.h	Tue Aug 25 04:03:51 2015	(r287122)
@@ -35,6 +35,7 @@ int image_copyin(lba_t blk, int fd, uint
 int image_copyout(int fd);
 int image_copyout_done(int fd);
 int image_copyout_region(int fd, lba_t blk, lba_t size);
+int image_copyout_zeroes(int fd, size_t count);
 int image_data(lba_t blk, lba_t size);
 lba_t image_get_size(void);
 int image_init(void);

Modified: stable/10/usr.bin/mkimg/mbr.c
==============================================================================
--- stable/10/usr.bin/mkimg/mbr.c	Tue Aug 25 01:01:25 2015	(r287121)
+++ stable/10/usr.bin/mkimg/mbr.c	Tue Aug 25 04:03:51 2015	(r287122)
@@ -51,6 +51,7 @@ static struct mkimg_alias mbr_aliases[] 
     {	ALIAS_EFI, ALIAS_INT2TYPE(DOSPTYP_EFI) },
     {	ALIAS_FAT32, ALIAS_INT2TYPE(DOSPTYP_FAT32) },
     {	ALIAS_FREEBSD, ALIAS_INT2TYPE(DOSPTYP_386BSD) },
+    {	ALIAS_NTFS, ALIAS_INT2TYPE(DOSPTYP_NTFS) },
     {	ALIAS_NONE, 0 }		/* Keep last! */
 };
 

Modified: stable/10/usr.bin/mkimg/mkimg.1
==============================================================================
--- stable/10/usr.bin/mkimg/mkimg.1	Tue Aug 25 01:01:25 2015	(r287121)
+++ stable/10/usr.bin/mkimg/mkimg.1	Tue Aug 25 04:03:51 2015	(r287122)
@@ -24,7 +24,7 @@
 .\"
 .\" $FreeBSD$
 .\"
-.Dd February 22, 2015
+.Dd August 7, 2015
 .Dt MKIMG 1
 .Os
 .Sh NAME
@@ -141,7 +141,7 @@ utility will create images that are iden
 .Pp
 A set of long options exist to query about the
 .Nm
-utilty itself.
+utility itself.
 Options in this set should be given by themselves because the
 .Nm
 utility exits immediately after providing the requested information.
@@ -165,6 +165,85 @@ run the
 .Nm
 utility without any arguments.
 This will print a usage message with all the necessary details.
+.Sh DISK FORMATS
+The
+.Nm
+utility supports a number of output file formats.
+A short description of these is given below.
+.Ss QCOW and QCOW2
+QCOW stands for "QEMU Copy On Write".
+It's a sparse file format akin to VHD and VMDK and QCOW represents the
+first version.
+QCOW2 represents version 2 of the file format.
+Version 2 is not backward compatible with version 1 and adds support for
+snapshots among other things.
+The QCOW file formats are natively supported by QEMU and Xen.
+To write QCOW, specify
+.Fl f Ar qcow
+on the command line.
+To write version 2 QCOW, specify
+.Fl f Ar qcow2
+on the command line.
+The preferred file extension is ".qcow" and ".qcow2" for QCOW and QCOW2
+(resp.), but ".qcow" is sometimes used for version 2 files as well.
+.Ss RAW file format
+This file format is a sector by sector representation of an actual disk.
+There is no extra information that describes or relates to the format
+itself. The size of the file is the size of the (virtual) disk.
+This file format is suitable for being copyied onto a disk with utilities
+like
+.Nm dd .
+To write a raw disk file, either omit the
+.Fl f
+option, or specify
+.Fl f Ar raw
+on the command line.
+The preferred file extension is one of ".img" or ".raw", but there's no
+real convention for it.
+.Ss Dynamic VHD and Fixed VHD
+Microsoft's "Virtual Hard Disk" file formats.
+The dynamic format is a sparse format akin to QCOW and VMDK.
+The fixed format is effectively a raw format with a footer appended to the
+file and as such it's often indistinguishable from the raw format.
+The fixed file format has been added to support Microsoft's Azure platform
+and due to inconsistencies in interpretation of the footer is not compatible
+with utilities like
+.Nm qemu
+when it is specifically instructed to interpreted the file as a VHD file.
+By default
+.Nm qemu
+will treat the file as a raw disk file, which mostly works fine.
+To have
+.Nm
+create a dynamic VHD file, specify
+.Fl f Ar vhd
+on the command line.
+To create a fixed VHD file for use by Azure, specify
+.Fl f Ar vhdf
+on the command line.
+The preferred file extension is ".vhd".
+.Ss VMDK
+VMware's "Virtual Machine Disk" file format.
+It's a sparse file format akin to QCOW and VHD and supported by many
+virtualization solutions.
+To create a VMDK file, specify
+.Fl f Ar vmdk
+on the command line.
+The preferred file extension is ".vmdk".
+.Pp
+Not all virtualization solutions support all file formats, but often those
+virtualization environments have utilities to convert from one format to
+another.
+Note however that conversion may require that the virtual disk size is
+changed to match the constraints of the output format and this may invalidate
+the contents of the disk image.
+For example, the GUID Partition Table (GPT) scheme has a header in the last
+sector on the disk.
+When changing the disk size, the GPT must be changed so that the last header
+is moved accordingly.
+This is typically not part of the conversion process.
+If possible, use an output format specifically for the environment in which
+the file is intended to be used.
 .Sh ENVIRONMENT
 .Bl -tag -width "TMPDIR" -compact
 .It Ev TMPDIR
@@ -235,6 +314,7 @@ utility supports assigning labels to the
 In the following example the file system partition is labeled as 'backup':
 .Dl % mkimg -s gpt -p freebsd-ufs/backup:=file-system.ufs -o gpt.img
 .Sh SEE ALSO
+.Xr dd 1 ,
 .Xr gpart 8 ,
 .Xr makefs 8 ,
 .Xr mdconfig 8 ,
@@ -247,4 +327,5 @@ utility first appeared in
 .Sh AUTHORS
 The
 .Nm
-utility and manpage were written by Marcel Moolenaar <marcelm@juniper.net>
+utility and manpage were written by
+.An Marcel Moolenaar Aq Mt marcelm@juniper.net .

Modified: stable/10/usr.bin/mkimg/scheme.c
==============================================================================
--- stable/10/usr.bin/mkimg/scheme.c	Tue Aug 25 01:01:25 2015	(r287121)
+++ stable/10/usr.bin/mkimg/scheme.c	Tue Aug 25 04:03:51 2015	(r287122)
@@ -59,6 +59,7 @@ static struct {
 	{ "freebsd-vinum", ALIAS_FREEBSD_VINUM },
 	{ "freebsd-zfs", ALIAS_FREEBSD_ZFS },
 	{ "mbr", ALIAS_MBR },
+	{ "ntfs", ALIAS_NTFS },
 	{ NULL, ALIAS_NONE }		/* Keep last! */
 };
 

Modified: stable/10/usr.bin/mkimg/scheme.h
==============================================================================
--- stable/10/usr.bin/mkimg/scheme.h	Tue Aug 25 01:01:25 2015	(r287121)
+++ stable/10/usr.bin/mkimg/scheme.h	Tue Aug 25 04:03:51 2015	(r287122)
@@ -45,6 +45,7 @@ enum alias {
 	ALIAS_FREEBSD_VINUM,
 	ALIAS_FREEBSD_ZFS,
 	ALIAS_MBR,
+	ALIAS_NTFS,
 	/* end */
 	ALIAS_COUNT		/* Keep last! */
 };

Modified: stable/10/usr.bin/mkimg/vhd.c
==============================================================================
--- stable/10/usr.bin/mkimg/vhd.c	Tue Aug 25 01:01:25 2015	(r287121)
+++ stable/10/usr.bin/mkimg/vhd.c	Tue Aug 25 04:03:51 2015	(r287122)
@@ -159,6 +159,34 @@ vhd_geometry(uint64_t image_size, struct
 	geom->cylinders = cth / geom->heads;
 }
 
+static uint64_t
+vhd_resize(uint64_t origsz)
+{
+	struct vhd_geom geom;
+	uint64_t newsz;
+
+	/*
+	 * Round the image size to the pre-determined geometry that
+	 * matches the image size. This circular dependency implies
+	 * that we need to loop to handle boundary conditions.
+	 * The first time, newsz equals origsz and the geometry will
+	 * typically yield a new size that's smaller. We keep adding
+	 * cylinder's worth of sectors to the new size until its
+	 * larger or equal or origsz. But during those iterations,
+	 * the geometry can change, so we need to account for that.
+	 */
+	newsz = origsz;
+	while (1) {
+		vhd_geometry(newsz, &geom);
+		newsz = (int64_t)geom.cylinders * geom.heads *
+		    geom.sectors * VHD_SECTOR_SIZE;
+		if (newsz >= origsz)
+			break;
+		newsz += geom.heads * geom.sectors * VHD_SECTOR_SIZE;
+	}
+	return (newsz);
+}
+
 static uint32_t
 vhd_timestamp(void)
 {
@@ -256,8 +284,7 @@ vhd_dyn_resize(lba_t imgsz)
 {
 	uint64_t imagesz;
 
-	imagesz = imgsz * secsz;
-	imagesz = (imagesz + VHD_BLOCK_SIZE - 1) & ~(VHD_BLOCK_SIZE - 1);
+	imagesz = vhd_resize(imgsz * secsz);
 	return (image_set_size(imagesz / secsz));
 }
 
@@ -266,7 +293,7 @@ vhd_dyn_write(int fd)
 {
 	struct vhd_footer footer;
 	struct vhd_dyn_header header;
-	uint64_t imgsz;
+	uint64_t imgsz, rawsz;
 	lba_t blk, blkcnt, nblks;
 	uint32_t *bat;
 	void *bitmap;
@@ -274,13 +301,14 @@ vhd_dyn_write(int fd)
 	uint32_t sector;
 	int bat_entries, error, entry;
 
-	imgsz = image_get_size() * secsz;
-	bat_entries = imgsz / VHD_BLOCK_SIZE;
+	rawsz = image_get_size() * secsz;
+	imgsz = (rawsz + VHD_BLOCK_SIZE - 1) & ~(VHD_BLOCK_SIZE - 1);
 
-	vhd_make_footer(&footer, imgsz, VHD_DISK_TYPE_DYNAMIC, sizeof(footer));
+	vhd_make_footer(&footer, rawsz, VHD_DISK_TYPE_DYNAMIC, sizeof(footer));
 	if (sparse_write(fd, &footer, sizeof(footer)) < 0)
 		return (errno);
 
+	bat_entries = imgsz / VHD_BLOCK_SIZE;
 	memset(&header, 0, sizeof(header));
 	be64enc(&header.cookie, VHD_HEADER_COOKIE);
 	be64enc(&header.data_offset, ~0ULL);
@@ -321,7 +349,7 @@ vhd_dyn_write(int fd)
 	blk = 0;
 	blkcnt = VHD_BLOCK_SIZE / secsz;
 	error = 0;
-	nblks = image_get_size();
+	nblks = rawsz / secsz;
 	while (blk < nblks) {
 		if (!image_data(blk, blkcnt)) {
 			blk += blkcnt;
@@ -331,15 +359,20 @@ vhd_dyn_write(int fd)
 			error = errno;
 			break;
 		}
+		/* Handle partial last block */
+		if (blk + blkcnt > nblks)
+			blkcnt = nblks - blk;
 		error = image_copyout_region(fd, blk, blkcnt);
 		if (error)
 			break;
 		blk += blkcnt;
 	}
 	free(bitmap);
-	if (blk != nblks)
+	if (error)
+		return (error);
+	error = image_copyout_zeroes(fd, imgsz - rawsz);
+	if (error)
 		return (error);
-
 	if (sparse_write(fd, &footer, sizeof(footer)) < 0)
 		return (errno);
 
@@ -362,24 +395,9 @@ FORMAT_DEFINE(vhd_dyn_format);
 static int
 vhd_fix_resize(lba_t imgsz)
 {
-	struct vhd_geom geom;
-	int64_t imagesz;
+	uint64_t imagesz;
 
-	/*
-	 * Round the image size to the pre-determined geometry that
-	 * matches the image size. This circular dependency implies
-	 * that we need to loop to handle boundary conditions.
-	 */
-	imgsz *= secsz;
-	imagesz = imgsz;
-	while (1) {
-		vhd_geometry(imagesz, &geom);
-		imagesz = (int64_t)geom.cylinders * geom.heads *
-		    geom.sectors * VHD_SECTOR_SIZE;
-		if (imagesz >= imgsz)
-			break;
-		imagesz += geom.heads * geom.sectors * VHD_SECTOR_SIZE;
-	}
+	imagesz = vhd_resize(imgsz * secsz);
 	/*
 	 * Azure demands that images are a whole number of megabytes.
 	 */
@@ -391,24 +409,24 @@ static int
 vhd_fix_write(int fd)
 {
 	struct vhd_footer footer;
-	uint64_t imgsz;
+	uint64_t imagesz;
 	int error;
 
 	error = image_copyout(fd);
-	if (!error) {
-		imgsz = image_get_size() * secsz;
-		vhd_make_footer(&footer, imgsz, VHD_DISK_TYPE_FIXED, ~0ULL);
-		if (sparse_write(fd, &footer, sizeof(footer)) < 0)
-			error = errno;
-	}
+	if (error)
+		return (error);
+
+	imagesz = image_get_size() * secsz;
+	vhd_make_footer(&footer, imagesz, VHD_DISK_TYPE_FIXED, ~0ULL);
+	error = (sparse_write(fd, &footer, sizeof(footer)) < 0) ? errno : 0;
 	return (error);
 }
 
 static struct mkimg_format vhd_fix_format = {
-        .name = "vhdf",
-        .description = "Fixed Virtual Hard Disk",
-        .resize = vhd_fix_resize,
-        .write = vhd_fix_write,
+	.name = "vhdf",
+	.description = "Fixed Virtual Hard Disk",
+	.resize = vhd_fix_resize,
+	.write = vhd_fix_write,
 };
 
 FORMAT_DEFINE(vhd_fix_format);



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201508250403.t7P43p2L007660>