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 <marc...@juniper.net>
+utility and manpage were written by
+.An Marcel Moolenaar Aq Mt marc...@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);
_______________________________________________
svn-src-all@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"

Reply via email to