summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--usr.sbin/vmctl/main.c4
-rw-r--r--usr.sbin/vmctl/vmctl.c187
-rw-r--r--usr.sbin/vmctl/vmctl.h5
-rw-r--r--usr.sbin/vmd/vioqcow2.c145
-rw-r--r--usr.sbin/vmd/vioraw.c43
-rw-r--r--usr.sbin/vmd/virtio.c6
-rw-r--r--usr.sbin/vmd/virtio.h10
-rw-r--r--usr.sbin/vmd/vmboot.c6
8 files changed, 205 insertions, 201 deletions
diff --git a/usr.sbin/vmctl/main.c b/usr.sbin/vmctl/main.c
index da84b5d9e5a..d0efcaf3c8c 100644
--- a/usr.sbin/vmctl/main.c
+++ b/usr.sbin/vmctl/main.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: main.c,v 1.47 2018/10/19 10:12:39 reyk Exp $ */
+/* $OpenBSD: main.c,v 1.48 2018/11/26 10:39:30 reyk Exp $ */
/*
* Copyright (c) 2015 Reyk Floeter <reyk@openbsd.org>
@@ -658,7 +658,7 @@ ctl_convert(const char *srcfile, const char *dstfile, int dsttype, size_t dstsiz
}
/* align to megabytes */
- dst.size = ALIGN(dstsize, 1048576);
+ dst.size = ALIGNSZ(dstsize, 1048576);
if ((ret = create_imagefile(dst.type, dst.disk, NULL,
dst.size / 1048576, &format)) != 0) {
diff --git a/usr.sbin/vmctl/vmctl.c b/usr.sbin/vmctl/vmctl.c
index 1feca4754d4..66200a6ab28 100644
--- a/usr.sbin/vmctl/vmctl.c
+++ b/usr.sbin/vmctl/vmctl.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: vmctl.c,v 1.62 2018/10/19 10:12:39 reyk Exp $ */
+/* $OpenBSD: vmctl.c,v 1.63 2018/11/26 10:39:30 reyk Exp $ */
/*
* Copyright (c) 2014 Mike Larkin <mlarkin@openbsd.org>
@@ -851,10 +851,10 @@ open_imagefile(int type, const char *imgfile_path, int flags,
return (-1);
}
}
- ret = virtio_init_qcow2(file, sz, basefd, nfd);
+ ret = virtio_qcow2_init(file, sz, basefd, nfd);
break;
default:
- ret = virtio_init_raw(file, sz, &fd, 1);
+ ret = virtio_raw_init(file, sz, &fd, 1);
break;
}
@@ -893,191 +893,14 @@ create_imagefile(int type, const char *imgfile_path, const char *base_path,
switch (type) {
case VMDF_QCOW2:
*format = "qcow2";
- ret = create_qc2_imagefile(imgfile_path, base_path, imgsize);
+ ret = virtio_qcow2_create(imgfile_path, base_path, imgsize);
break;
default:
*format = "raw";
- ret = create_raw_imagefile(imgfile_path, imgsize);
+ ret = virtio_raw_create(imgfile_path, imgsize);
break;
}
return (ret);
}
-/*
- * create_raw_imagefile
- *
- * Create an empty imagefile with the specified path and size.
- *
- * Parameters:
- * imgfile_path: path to the image file to create
- * imgsize : size of the image file to create (in MB)
- *
- * Return:
- * EEXIST: The requested image file already exists
- * 0 : Image file successfully created
- * Exxxx : Various other Exxxx errno codes due to other I/O errors
- */
-int
-create_raw_imagefile(const char *imgfile_path, long imgsize)
-{
- int fd, ret;
-
- /* Refuse to overwrite an existing image */
- fd = open(imgfile_path, O_RDWR | O_CREAT | O_TRUNC | O_EXCL,
- S_IRUSR | S_IWUSR);
- if (fd == -1)
- return (errno);
-
- /* Extend to desired size */
- if (ftruncate(fd, (off_t)imgsize * 1024 * 1024) == -1) {
- ret = errno;
- close(fd);
- unlink(imgfile_path);
- return (ret);
- }
-
- ret = close(fd);
- return (ret);
-}
-
-/*
- * create_qc2_imagefile
- *
- * Create an empty qcow2 imagefile with the specified path and size.
- *
- * Parameters:
- * imgfile_path: path to the image file to create
- * imgsize : size of the image file to create (in MB)
- *
- * Return:
- * EEXIST: The requested image file already exists
- * 0 : Image file successfully created
- * Exxxx : Various other Exxxx errno codes due to other I/O errors
- */
-int
-create_qc2_imagefile(const char *imgfile_path,
- const char *base_path, long imgsize)
-{
- struct qcheader {
- char magic[4];
- uint32_t version;
- uint64_t backingoff;
- uint32_t backingsz;
- uint32_t clustershift;
- uint64_t disksz;
- uint32_t cryptmethod;
- uint32_t l1sz;
- uint64_t l1off;
- uint64_t refoff;
- uint32_t refsz;
- uint32_t snapcount;
- uint64_t snapsz;
- /* v3 additions */
- uint64_t incompatfeatures;
- uint64_t compatfeatures;
- uint64_t autoclearfeatures;
- uint32_t reforder;
- uint32_t headersz;
- } __packed hdr, basehdr;
- int fd, ret;
- ssize_t base_len;
- uint64_t l1sz, refsz, disksz, initsz, clustersz;
- uint64_t l1off, refoff, v, i, l1entrysz, refentrysz;
- uint16_t refs;
-
- disksz = 1024 * 1024 * imgsize;
-
- if (base_path) {
- fd = open(base_path, O_RDONLY);
- if (read(fd, &basehdr, sizeof(basehdr)) != sizeof(basehdr))
- err(1, "failure to read base image header");
- close(fd);
- if (strncmp(basehdr.magic,
- VM_MAGIC_QCOW, strlen(VM_MAGIC_QCOW)) != 0)
- errx(1, "base image is not a qcow2 file");
- if (!disksz)
- disksz = betoh64(basehdr.disksz);
- else if (disksz != betoh64(basehdr.disksz))
- errx(1, "base size does not match requested size");
- }
- if (!base_path && !disksz)
- errx(1, "missing disk size");
-
- clustersz = (1<<16);
- l1off = ALIGN(sizeof(hdr), clustersz);
-
- l1entrysz = clustersz * clustersz / 8;
- l1sz = (disksz + l1entrysz - 1) / l1entrysz;
-
- refoff = ALIGN(l1off + 8*l1sz, clustersz);
- refentrysz = clustersz * clustersz * clustersz / 2;
- refsz = (disksz + refentrysz - 1) / refentrysz;
-
- initsz = ALIGN(refoff + refsz*clustersz, clustersz);
- base_len = base_path ? strlen(base_path) : 0;
-
- memcpy(hdr.magic, VM_MAGIC_QCOW, strlen(VM_MAGIC_QCOW));
- hdr.version = htobe32(3);
- hdr.backingoff = htobe64(base_path ? sizeof(hdr) : 0);
- hdr.backingsz = htobe32(base_len);
- hdr.clustershift = htobe32(16);
- hdr.disksz = htobe64(disksz);
- hdr.cryptmethod = htobe32(0);
- hdr.l1sz = htobe32(l1sz);
- hdr.l1off = htobe64(l1off);
- hdr.refoff = htobe64(refoff);
- hdr.refsz = htobe32(refsz);
- hdr.snapcount = htobe32(0);
- hdr.snapsz = htobe64(0);
- hdr.incompatfeatures = htobe64(0);
- hdr.compatfeatures = htobe64(0);
- hdr.autoclearfeatures = htobe64(0);
- hdr.reforder = htobe32(4);
- hdr.headersz = htobe32(sizeof(hdr));
-
- /* Refuse to overwrite an existing image */
- fd = open(imgfile_path, O_RDWR | O_CREAT | O_TRUNC | O_EXCL,
- S_IRUSR | S_IWUSR);
- if (fd == -1)
- return (errno);
-
- /* Write out the header */
- if (write(fd, &hdr, sizeof(hdr)) != sizeof(hdr))
- goto error;
-
- /* Add the base image */
- if (base_path && write(fd, base_path, base_len) != base_len)
- goto error;
-
- /* Extend to desired size, and add one refcount cluster */
- if (ftruncate(fd, (off_t)initsz + clustersz) == -1)
- goto error;
-
- /*
- * Paranoia: if our disk image takes more than one cluster
- * to refcount the initial image, fail.
- */
- if (initsz/clustersz > clustersz/2) {
- errno = ERANGE;
- goto error;
- }
-
- /* Add a refcount block, and refcount ourselves. */
- v = htobe64(initsz);
- if (pwrite(fd, &v, 8, refoff) != 8)
- goto error;
- for (i = 0; i < initsz/clustersz + 1; i++) {
- refs = htobe16(1);
- if (pwrite(fd, &refs, 2, initsz + 2*i) != 2)
- goto error;
- }
-
- ret = close(fd);
- return (ret);
-error:
- ret = errno;
- close(fd);
- unlink(imgfile_path);
- return (errno);
-}
diff --git a/usr.sbin/vmctl/vmctl.h b/usr.sbin/vmctl/vmctl.h
index 2948a4fc0ce..37aeac34ce2 100644
--- a/usr.sbin/vmctl/vmctl.h
+++ b/usr.sbin/vmctl/vmctl.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: vmctl.h,v 1.27 2018/10/19 10:12:39 reyk Exp $ */
+/* $OpenBSD: vmctl.h,v 1.28 2018/11/26 10:39:30 reyk Exp $ */
/*
* Copyright (c) 2015 Reyk Floeter <reyk@openbsd.org>
@@ -71,9 +71,6 @@ struct ctl_command {
struct imsgbuf *ibuf;
-#define ALIGN(sz, align) ((sz + align - 1) & ~(align - 1))
-#define MIN(a,b) (((a)<(b))?(a):(b))
-
/* main.c */
int vmmaction(struct parse_result *);
int parse_ifs(struct parse_result *, char *, int);
diff --git a/usr.sbin/vmd/vioqcow2.c b/usr.sbin/vmd/vioqcow2.c
index be6964bb5bd..185e8178946 100644
--- a/usr.sbin/vmd/vioqcow2.c
+++ b/usr.sbin/vmd/vioqcow2.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: vioqcow2.c,v 1.11 2018/11/24 04:51:55 ori Exp $ */
+/* $OpenBSD: vioqcow2.c,v 1.12 2018/11/26 10:39:30 reyk Exp $ */
/*
* Copyright (c) 2018 Ori Bernstein <ori@eigenstate.org>
@@ -29,6 +29,7 @@
#include <assert.h>
#include <libgen.h>
#include <err.h>
+#include <errno.h>
#include "vmd.h"
#include "vmm.h"
@@ -118,7 +119,7 @@ static void qc2_close(void *, int);
* May open snapshot base images.
*/
int
-virtio_init_qcow2(struct virtio_backing *file, off_t *szp, int *fd, size_t nfd)
+virtio_qcow2_init(struct virtio_backing *file, off_t *szp, int *fd, size_t nfd)
{
struct qcdisk *diskp;
@@ -608,3 +609,143 @@ inc_refs(struct qcdisk *disk, off_t off, int newcluster)
fatal("%s: could not write ref block", __func__);
}
+/*
+ * virtio_qcow2_create
+ *
+ * Create an empty qcow2 imagefile with the specified path and size.
+ *
+ * Parameters:
+ * imgfile_path: path to the image file to create
+ * imgsize : size of the image file to create (in MB)
+ *
+ * Return:
+ * EEXIST: The requested image file already exists
+ * 0 : Image file successfully created
+ * Exxxx : Various other Exxxx errno codes due to other I/O errors
+ */
+int
+virtio_qcow2_create(const char *imgfile_path,
+ const char *base_path, long imgsize)
+{
+ struct qcheader {
+ char magic[4];
+ uint32_t version;
+ uint64_t backingoff;
+ uint32_t backingsz;
+ uint32_t clustershift;
+ uint64_t disksz;
+ uint32_t cryptmethod;
+ uint32_t l1sz;
+ uint64_t l1off;
+ uint64_t refoff;
+ uint32_t refsz;
+ uint32_t snapcount;
+ uint64_t snapsz;
+ /* v3 additions */
+ uint64_t incompatfeatures;
+ uint64_t compatfeatures;
+ uint64_t autoclearfeatures;
+ uint32_t reforder;
+ uint32_t headersz;
+ } __packed hdr, basehdr;
+ int fd, ret;
+ ssize_t base_len;
+ uint64_t l1sz, refsz, disksz, initsz, clustersz;
+ uint64_t l1off, refoff, v, i, l1entrysz, refentrysz;
+ uint16_t refs;
+
+ disksz = 1024 * 1024 * imgsize;
+
+ if (base_path) {
+ fd = open(base_path, O_RDONLY);
+ if (read(fd, &basehdr, sizeof(basehdr)) != sizeof(basehdr))
+ err(1, "failure to read base image header");
+ close(fd);
+ if (strncmp(basehdr.magic,
+ VM_MAGIC_QCOW, strlen(VM_MAGIC_QCOW)) != 0)
+ errx(1, "base image is not a qcow2 file");
+ if (!disksz)
+ disksz = betoh64(basehdr.disksz);
+ else if (disksz != betoh64(basehdr.disksz))
+ errx(1, "base size does not match requested size");
+ }
+ if (!base_path && !disksz)
+ errx(1, "missing disk size");
+
+ clustersz = (1<<16);
+ l1off = ALIGNSZ(sizeof(hdr), clustersz);
+
+ l1entrysz = clustersz * clustersz / 8;
+ l1sz = (disksz + l1entrysz - 1) / l1entrysz;
+
+ refoff = ALIGNSZ(l1off + 8*l1sz, clustersz);
+ refentrysz = clustersz * clustersz * clustersz / 2;
+ refsz = (disksz + refentrysz - 1) / refentrysz;
+
+ initsz = ALIGNSZ(refoff + refsz*clustersz, clustersz);
+ base_len = base_path ? strlen(base_path) : 0;
+
+ memcpy(hdr.magic, VM_MAGIC_QCOW, strlen(VM_MAGIC_QCOW));
+ hdr.version = htobe32(3);
+ hdr.backingoff = htobe64(base_path ? sizeof(hdr) : 0);
+ hdr.backingsz = htobe32(base_len);
+ hdr.clustershift = htobe32(16);
+ hdr.disksz = htobe64(disksz);
+ hdr.cryptmethod = htobe32(0);
+ hdr.l1sz = htobe32(l1sz);
+ hdr.l1off = htobe64(l1off);
+ hdr.refoff = htobe64(refoff);
+ hdr.refsz = htobe32(refsz);
+ hdr.snapcount = htobe32(0);
+ hdr.snapsz = htobe64(0);
+ hdr.incompatfeatures = htobe64(0);
+ hdr.compatfeatures = htobe64(0);
+ hdr.autoclearfeatures = htobe64(0);
+ hdr.reforder = htobe32(4);
+ hdr.headersz = htobe32(sizeof(hdr));
+
+ /* Refuse to overwrite an existing image */
+ fd = open(imgfile_path, O_RDWR | O_CREAT | O_TRUNC | O_EXCL,
+ S_IRUSR | S_IWUSR);
+ if (fd == -1)
+ return (errno);
+
+ /* Write out the header */
+ if (write(fd, &hdr, sizeof(hdr)) != sizeof(hdr))
+ goto error;
+
+ /* Add the base image */
+ if (base_path && write(fd, base_path, base_len) != base_len)
+ goto error;
+
+ /* Extend to desired size, and add one refcount cluster */
+ if (ftruncate(fd, (off_t)initsz + clustersz) == -1)
+ goto error;
+
+ /*
+ * Paranoia: if our disk image takes more than one cluster
+ * to refcount the initial image, fail.
+ */
+ if (initsz/clustersz > clustersz/2) {
+ errno = ERANGE;
+ goto error;
+ }
+
+ /* Add a refcount block, and refcount ourselves. */
+ v = htobe64(initsz);
+ if (pwrite(fd, &v, 8, refoff) != 8)
+ goto error;
+ for (i = 0; i < initsz/clustersz + 1; i++) {
+ refs = htobe16(1);
+ if (pwrite(fd, &refs, 2, initsz + 2*i) != 2)
+ goto error;
+ }
+
+ ret = close(fd);
+ return (ret);
+error:
+ ret = errno;
+ close(fd);
+ unlink(imgfile_path);
+ return (errno);
+}
diff --git a/usr.sbin/vmd/vioraw.c b/usr.sbin/vmd/vioraw.c
index 370e5b06892..de9ab65258c 100644
--- a/usr.sbin/vmd/vioraw.c
+++ b/usr.sbin/vmd/vioraw.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: vioraw.c,v 1.4 2018/10/08 16:32:01 reyk Exp $ */
+/* $OpenBSD: vioraw.c,v 1.5 2018/11/26 10:39:30 reyk Exp $ */
/*
* Copyright (c) 2018 Ori Bernstein <ori@eigenstate.org>
*
@@ -16,12 +16,15 @@
*/
#include <sys/types.h>
+#include <sys/stat.h>
#include <machine/vmmvar.h>
#include <dev/pci/pcireg.h>
#include <stdlib.h>
#include <unistd.h>
+#include <fcntl.h>
+#include <errno.h>
#include "vmd.h"
#include "vmm.h"
@@ -53,7 +56,7 @@ raw_close(void *file, int stayopen)
* returning -1 for error, 0 for success.
*/
int
-virtio_init_raw(struct virtio_backing *file, off_t *szp, int *fd, size_t nfd)
+virtio_raw_init(struct virtio_backing *file, off_t *szp, int *fd, size_t nfd)
{
off_t sz;
int *fdp;
@@ -76,3 +79,39 @@ virtio_init_raw(struct virtio_backing *file, off_t *szp, int *fd, size_t nfd)
return 0;
}
+/*
+ * virtio_raw_create
+ *
+ * Create an empty imagefile with the specified path and size.
+ *
+ * Parameters:
+ * imgfile_path: path to the image file to create
+ * imgsize : size of the image file to create (in MB)
+ *
+ * Return:
+ * EEXIST: The requested image file already exists
+ * 0 : Image file successfully created
+ * Exxxx : Various other Exxxx errno codes due to other I/O errors
+ */
+int
+virtio_raw_create(const char *imgfile_path, long imgsize)
+{
+ int fd, ret;
+
+ /* Refuse to overwrite an existing image */
+ fd = open(imgfile_path, O_RDWR | O_CREAT | O_TRUNC | O_EXCL,
+ S_IRUSR | S_IWUSR);
+ if (fd == -1)
+ return (errno);
+
+ /* Extend to desired size */
+ if (ftruncate(fd, (off_t)imgsize * 1024 * 1024) == -1) {
+ ret = errno;
+ close(fd);
+ unlink(imgfile_path);
+ return (ret);
+ }
+
+ ret = close(fd);
+ return (ret);
+}
diff --git a/usr.sbin/vmd/virtio.c b/usr.sbin/vmd/virtio.c
index 4b84ae467fd..6397ba786a3 100644
--- a/usr.sbin/vmd/virtio.c
+++ b/usr.sbin/vmd/virtio.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: virtio.c,v 1.73 2018/10/19 10:12:39 reyk Exp $ */
+/* $OpenBSD: virtio.c,v 1.74 2018/11/26 10:39:30 reyk Exp $ */
/*
* Copyright (c) 2015 Mike Larkin <mlarkin@openbsd.org>
@@ -1771,9 +1771,9 @@ virtio_init_disk(struct virtio_backing *file, off_t *sz,
*/
switch (type) {
case VMDF_RAW:
- return virtio_init_raw(file, sz, fd, nfd);
+ return virtio_raw_init(file, sz, fd, nfd);
case VMDF_QCOW2:
- return virtio_init_qcow2(file, sz, fd, nfd);
+ return virtio_qcow2_init(file, sz, fd, nfd);
}
log_warnx("%s: invalid disk format", __func__);
return -1;
diff --git a/usr.sbin/vmd/virtio.h b/usr.sbin/vmd/virtio.h
index 28aedc93e84..56dc536d1d3 100644
--- a/usr.sbin/vmd/virtio.h
+++ b/usr.sbin/vmd/virtio.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: virtio.h,v 1.32 2018/10/19 10:12:39 reyk Exp $ */
+/* $OpenBSD: virtio.h,v 1.33 2018/11/26 10:39:30 reyk Exp $ */
/*
* Copyright (c) 2015 Mike Larkin <mlarkin@openbsd.org>
@@ -20,6 +20,8 @@
#define VIRTQUEUE_ALIGN(n) (((n)+(VIRTIO_PAGE_SIZE-1))& \
~(VIRTIO_PAGE_SIZE-1))
+#define ALIGNSZ(sz, align) ((sz + align - 1) & ~(align - 1))
+#define MIN(a,b) (((a)<(b))?(a):(b))
/* Queue sizes must be power of two */
#define VIORND_QUEUE_SIZE 64
@@ -272,8 +274,10 @@ void viornd_update_qa(void);
int viornd_notifyq(void);
ssize_t virtio_qcow2_get_base(int, char *, size_t, const char *);
-int virtio_init_raw(struct virtio_backing *, off_t *, int*, size_t);
-int virtio_init_qcow2(struct virtio_backing *, off_t *, int*, size_t);
+int virtio_qcow2_create(const char *, const char *, long);
+int virtio_qcow2_init(struct virtio_backing *, off_t *, int*, size_t);
+int virtio_raw_create(const char *, long);
+int virtio_raw_init(struct virtio_backing *, off_t *, int*, size_t);
int virtio_blk_io(int, uint16_t, uint32_t *, uint8_t *, void *, uint8_t);
int vioblk_dump(int);
diff --git a/usr.sbin/vmd/vmboot.c b/usr.sbin/vmd/vmboot.c
index ec8c07fd6e3..d249e8701eb 100644
--- a/usr.sbin/vmd/vmboot.c
+++ b/usr.sbin/vmd/vmboot.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: vmboot.c,v 1.6 2018/10/08 16:32:01 reyk Exp $ */
+/* $OpenBSD: vmboot.c,v 1.7 2018/11/26 10:39:30 reyk Exp $ */
/*
* Copyright (c) 2016 Reyk Floeter <reyk@openbsd.org>
@@ -414,13 +414,13 @@ vmboot_open(int kernel_fd, int *disk_fd, int nfd, unsigned int disk_type,
switch (vmboot->vbp_type) {
case VMDF_RAW:
- if (virtio_init_raw(vfp, &sz, disk_fd, nfd) == -1) {
+ if (virtio_raw_init(vfp, &sz, disk_fd, nfd) == -1) {
log_debug("%s: could not open raw disk", __func__);
goto fail;
}
break;
case VMDF_QCOW2:
- if (virtio_init_qcow2(vfp, &sz, disk_fd, nfd) == -1) {
+ if (virtio_qcow2_init(vfp, &sz, disk_fd, nfd) == -1) {
log_debug("%s: could not open qcow2 disk", __func__);
goto fail;
}