svn commit: r245092 - user/hrs/releng/usr.sbin/makevd
Hiroki Sato
hrs at FreeBSD.org
Sun Jan 6 02:52:25 UTC 2013
Author: hrs
Date: Sun Jan 6 02:52:23 2013
New Revision: 245092
URL: http://svnweb.freebsd.org/changeset/base/245092
Log:
Add Microsoft Virtual Hard Disk (VHD) Image Format support. At this moment,
it generates a Fixed Hard Disk Image with CreatorVersion=0x00050000.
Added:
user/hrs/releng/usr.sbin/makevd/vhd.c (contents, props changed)
user/hrs/releng/usr.sbin/makevd/vhd.h (contents, props changed)
Modified:
user/hrs/releng/usr.sbin/makevd/Makefile
user/hrs/releng/usr.sbin/makevd/makevd.8
user/hrs/releng/usr.sbin/makevd/makevd.c
user/hrs/releng/usr.sbin/makevd/makevd.h
Modified: user/hrs/releng/usr.sbin/makevd/Makefile
==============================================================================
--- user/hrs/releng/usr.sbin/makevd/Makefile Sun Jan 6 02:50:38 2013 (r245091)
+++ user/hrs/releng/usr.sbin/makevd/Makefile Sun Jan 6 02:52:23 2013 (r245092)
@@ -4,6 +4,7 @@ PROG= makevd
MAN= makevd.8
SRCS= makevd.c \
raw.c \
+ vhd.c \
vmdk.c
WARNS?= 6
CFLAGS+= -I${.CURDIR}
Modified: user/hrs/releng/usr.sbin/makevd/makevd.8
==============================================================================
--- user/hrs/releng/usr.sbin/makevd/makevd.8 Sun Jan 6 02:50:38 2013 (r245091)
+++ user/hrs/releng/usr.sbin/makevd/makevd.8 Sun Jan 6 02:52:23 2013 (r245092)
@@ -74,6 +74,8 @@ Create an
virtual disk image.
The following image types are supported:
.Bl -tag -width cd9660 -offset indent
+.It Sy vhd
+Microsoft Virtual Hard Disk (VHD) Image Format.
.It Sy vmdk
VMWare Virtual Machine DisK (VMDK) Format.
.It Sy raw
@@ -82,6 +84,19 @@ No conversion (default).
.El
.\"
.\"
+.Ss VHD-specific options
+.Sy vhd
+images have VHD-specific parameters that may be provided.
+Some are optional, and some are mandatory.
+Each of the options consists of a keyword, an equal sign
+.Pq Ql = ,
+and a value.
+The following keywords are supported:
+.Pp
+.Bl -tag -width optimization -offset indent -compact
+.It Fl o Sy uuid
+UUID for the image. Mandatory.
+.El
.Ss VMDK-specific options
.Sy vmdk
images have VMDK-specific parameters that may be provided.
Modified: user/hrs/releng/usr.sbin/makevd/makevd.c
==============================================================================
--- user/hrs/releng/usr.sbin/makevd/makevd.c Sun Jan 6 02:50:38 2013 (r245091)
+++ user/hrs/releng/usr.sbin/makevd/makevd.c Sun Jan 6 02:52:23 2013 (r245092)
@@ -42,6 +42,7 @@ __FBSDID("$FreeBSD$");
#include "makevd.h"
#include "vmdk.h"
+#include "vhd.h"
static LIST_HEAD(optlisthead_t, optlist) oplhead;
@@ -50,6 +51,7 @@ static struct imtype {
const char *imt_type;
int (*imt_makeim)(struct iminfo *);
} imtypes[] = {
+ { "vhd", vhd_makeim },
{ "vmdk", vmdk_makeim },
{ "none", raw_makeim },
{ "raw", raw_makeim },
Modified: user/hrs/releng/usr.sbin/makevd/makevd.h
==============================================================================
--- user/hrs/releng/usr.sbin/makevd/makevd.h Sun Jan 6 02:50:38 2013 (r245091)
+++ user/hrs/releng/usr.sbin/makevd/makevd.h Sun Jan 6 02:52:23 2013 (r245092)
@@ -49,6 +49,7 @@ struct optlist {
char *opl_val;
};
+int vhd_makeim(struct iminfo *);
int vmdk_makeim(struct iminfo *);
int raw_makeim(struct iminfo *);
Added: user/hrs/releng/usr.sbin/makevd/vhd.c
==============================================================================
--- /dev/null 00:00:00 1970 (empty, because file is newly added)
+++ user/hrs/releng/usr.sbin/makevd/vhd.c Sun Jan 6 02:52:23 2013 (r245092)
@@ -0,0 +1,184 @@
+/*-
+ * Copyright (c) 2011-2013
+ * Hiroki Sato <hrs at FreeBSD.org> 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 REGENTS 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 REGENTS 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$
+ *
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/uio.h>
+
+#include <err.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <inttypes.h>
+#include <limits.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <sysexits.h>
+#include <unistd.h>
+
+#include "makevd.h"
+#include "vhd.h"
+
+static uint32_t vhd_checksum(struct HardDiskFooter *);
+
+int
+vhd_makeim(struct iminfo *imi)
+{
+ struct HardDiskFooter DHF, *imh;
+ uint64_t sectors, heads, cylinders, imagesize;
+ uint8_t uuid[16];
+ char vhdfile[PATH_MAX + 10];
+ char buf[BUFSIZ];
+ char *p, *q;
+ ssize_t len0, len = 0;
+ int ifd, ofd;
+
+ imh = &DHF;
+ ifd = imi->imi_fd;
+ imagesize = imi->imi_size;
+
+ memset(imh, 0, sizeof(*imh));
+ if (imi->imi_uuid == NULL)
+ errx(EX_USAGE, "-o uuid option must be specified.");
+
+ p = imi->imi_uuid;
+#if _BYTE_ORDER == _BIG_ENDIAN
+ q = (uint8_t *)&uuid + 16;
+#else
+ q = (uint8_t *)&uuid;
+#endif
+ while (len < 16 && strlen(p) > 1) {
+ long digit;
+ char *endptr;
+
+ if (*p == '-') {
+ p++;
+ continue;
+ }
+ buf[0] = p[0];
+ buf[1] = p[1];
+ buf[2] = '\0';
+ errno = 0;
+ digit = strtol(buf, &endptr, 16);
+ if (errno == 0 && *endptr != '\0')
+ errno = EINVAL;
+ if (errno)
+ errx(EX_DATAERR, "invalid UUID");
+#if _BYTE_ORDER == _BIG_ENDIAN
+ *q-- = digit;
+#else
+ *q++ = digit;
+#endif
+ len++;
+ p += 2;
+ }
+#if 0
+ {
+ int i;
+
+ printf("uuid = ");
+ for (i = 0; i < 16; i++)
+ printf("%02x", uuid[i]);
+ printf("\n");
+ }
+#endif
+ snprintf(vhdfile, sizeof(vhdfile), "%s.vhd", imi->imi_imagename);
+ ofd = open(vhdfile, O_WRONLY|O_CREAT|O_TRUNC,
+ S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH);
+ if (ofd < 0)
+ err(EX_CANTCREAT, "%s", vhdfile);
+
+ /* All of the fields are in BE byte order. */
+ imh->Cookie = htobe64(HDF_COOKIE);
+ imh->Features = htobe32(HDF_FEATURES_RES);
+ imh->FileFormatVersion = htobe32(HDF_FILEFORMATVERSION_DEFAULT);
+ imh->DataOffset = htobe32(HDF_DATAOFFSET_FIXEDHDD);
+ imh->TimeStamp = 0; /* XXX */
+ imh->CreatorApplication = htobe32(HDF_CREATORAPP_VPC);
+ imh->CreatorVersion = htobe32(HDF_CREATORVERSION_VPC2004);
+ imh->CreatorHostOS = htobe32(HDF_CREATORHOSTOS_WIN);
+ imh->OriginalSize = htobe64(imagesize);
+ imh->CurrentSize = htobe64(imagesize);
+
+ sectors = 63;
+ heads = 16;
+ cylinders = imagesize / (sectors * heads * 512);
+ while (cylinders > 1024) {
+ cylinders >>= 1;
+ heads <<= 1;
+ }
+ imh->DiskGeometry.cylinder = htobe16(cylinders);
+ imh->DiskGeometry.heads = heads;
+ imh->DiskGeometry.sectcyl = sectors;
+
+ imh->DiskType = htobe32(HDF_DISKTYPE_FIXEDHDD);
+ memcpy((char *)imh->UniqueId, (char *)&uuid, sizeof(imh->UniqueId));
+ imh->SavedState = 0;
+
+ imh->Checksum = htobe32(vhd_checksum(imh));
+
+ for (;;) {
+ len0 = read(ifd, buf, sizeof(buf));
+ if (len0 == 0)
+ break;
+ if (len0 < 0) {
+ warn("read error");
+ return (1);
+ }
+ len = write(ofd, buf, len0);
+ if (len < 0) {
+ warn("write error");
+ return (1);
+ }
+ }
+ len0 = write(ofd, imh, sizeof(*imh));
+ if (len0 != sizeof(*imh)) {
+ warn("write error");
+ return (1);
+ }
+
+ return (0);
+}
+
+static uint32_t
+vhd_checksum(struct HardDiskFooter *imh)
+{
+ uint32_t sum;
+ size_t len;
+
+ sum = 0;
+ for (len = 0; len < sizeof(*imh); len++)
+ sum += ((uint8_t *)imh)[0];
+
+ return (~sum);
+}
Added: user/hrs/releng/usr.sbin/makevd/vhd.h
==============================================================================
--- /dev/null 00:00:00 1970 (empty, because file is newly added)
+++ user/hrs/releng/usr.sbin/makevd/vhd.h Sun Jan 6 02:52:23 2013 (r245092)
@@ -0,0 +1,100 @@
+/*-
+ * Copyright (c) 2011-2013
+ * Hiroki Sato <hrs at FreeBSD.org> 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 REGENTS 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 REGENTS 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 _VHD_H
+#define _VHD_H
+
+#include <sys/endian.h>
+#include <stdint.h>
+
+/* All of the fields are in BE byte order. */
+struct HardDiskFooter {
+ uint64_t Cookie;
+#define HDF_COOKIE (0x636f6e6563746978) /* "conectix" */
+ uint32_t Features;
+#define HDF_FEATURES_TEMP (0x00000001)
+#define HDF_FEATURES_RES (0x00000002)
+ uint32_t FileFormatVersion;
+#define HDF_FILEFORMATVERSION_DEFAULT (0x00010000)
+ uint64_t DataOffset;
+#define HDF_DATAOFFSET_FIXEDHDD (0xFFFFFFFF)
+ uint32_t TimeStamp;
+ uint32_t CreatorApplication;
+#define HDF_CREATORAPP_VPC (0x76707320) /* "vpc " */
+#define HDF_CREATORAPP_VS (0x76732020) /* "vs " */
+ uint32_t CreatorVersion;
+#define HDF_CREATORVERSION_VS2004 (0x00010000)
+#define HDF_CREATORVERSION_VPC2004 (0x00050000)
+ uint32_t CreatorHostOS;
+#define HDF_CREATORHOSTOS_WIN (0x5769326b) /* "Wi2k" */
+#define HDF_CREATORHOSTOS_MAC (0x4d616320) /* "Mac " */
+ uint64_t OriginalSize;
+ uint64_t CurrentSize;
+ struct {
+ uint16_t cylinder;
+ uint8_t heads;
+ uint8_t sectcyl;
+ } DiskGeometry;
+ uint32_t DiskType;
+#define HDF_DISKTYPE_FIXEDHDD (2)
+#define HDF_DISKTYPE_DYNAMICHDD (3)
+#define HDF_DISKTYPE_DIFFHDD (4)
+ uint32_t Checksum;
+ uint8_t UniqueId[16];
+ uint8_t SavedState;
+ char Reserved[427];
+} __attribute__((__packed__));
+
+struct DynamicDiskHeader {
+ uint64_t Cookie;
+#define DDH_COOKIE (0x6378737061727365) /* "cxsparse" */
+ uint64_t DataOffset;
+#define DDH_DATAOFFSET (0xffffffff)
+ uint64_t TableOffset;
+ uint32_t HeaderVersion;
+#define DDH_HEADERVERSION (0x00010000)
+ uint32_t MaxTableEntries;
+ uint32_t BlockSize;
+#define DDH_BLOCKSIZE_DEFAULT (0x00200000)
+ uint32_t Checksum;
+ uint8_t ParentUniqueID[16];
+ uint32_t ParentTimeStamp;
+ uint32_t Reserved1;
+ uint8_t ParentUnicodeName[512];
+ uint8_t ParentLocatorEntry1[24];
+ uint8_t ParentLocatorEntry2[24];
+ uint8_t ParentLocatorEntry3[24];
+ uint8_t ParentLocatorEntry4[24];
+ uint8_t ParentLocatorEntry5[24];
+ uint8_t ParentLocatorEntry6[24];
+ uint8_t ParentLocatorEntry7[24];
+ uint8_t ParentLocatorEntry8[24];
+ uint8_t Reserved2[256];
+} __attribute__((__packed__));
+
+#endif /* _VHD_H */
More information about the svn-src-user
mailing list