1 /* $OpenBSD: vioraw.c,v 1.5 2018/11/26 10:39:30 reyk Exp $ */ 2 /* 3 * Copyright (c) 2018 Ori Bernstein <ori@eigenstate.org> 4 * 5 * Permission to use, copy, modify, and distribute this software for any 6 * purpose with or without fee is hereby granted, provided that the above 7 * copyright notice and this permission notice appear in all copies. 8 * 9 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 10 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 11 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 12 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 13 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 14 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 15 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 16 */ 17 18 #include <sys/types.h> 19 #include <sys/stat.h> 20 21 #include <machine/vmmvar.h> 22 #include <dev/pci/pcireg.h> 23 24 #include <stdlib.h> 25 #include <unistd.h> 26 #include <fcntl.h> 27 #include <errno.h> 28 29 #include "vmd.h" 30 #include "vmm.h" 31 #include "virtio.h" 32 33 static ssize_t 34 raw_pread(void *file, char *buf, size_t len, off_t off) 35 { 36 return pread(*(int *)file, buf, len, off); 37 } 38 39 static ssize_t 40 raw_pwrite(void *file, char *buf, size_t len, off_t off) 41 { 42 return pwrite(*(int *)file, buf, len, off); 43 } 44 45 static void 46 raw_close(void *file, int stayopen) 47 { 48 if (!stayopen) 49 close(*(int *)file); 50 free(file); 51 } 52 53 /* 54 * Initializes a raw disk image backing file from an fd. 55 * Stores the number of 512 byte sectors in *szp, 56 * returning -1 for error, 0 for success. 57 */ 58 int 59 virtio_raw_init(struct virtio_backing *file, off_t *szp, int *fd, size_t nfd) 60 { 61 off_t sz; 62 int *fdp; 63 64 if (nfd != 1) 65 return -1; 66 sz = lseek(fd[0], 0, SEEK_END); 67 if (sz == -1) 68 return -1; 69 70 fdp = malloc(sizeof(int)); 71 if (!fdp) 72 return -1; 73 *fdp = fd[0]; 74 file->p = fdp; 75 file->pread = raw_pread; 76 file->pwrite = raw_pwrite; 77 file->close = raw_close; 78 *szp = sz; 79 return 0; 80 } 81 82 /* 83 * virtio_raw_create 84 * 85 * Create an empty imagefile with the specified path and size. 86 * 87 * Parameters: 88 * imgfile_path: path to the image file to create 89 * imgsize : size of the image file to create (in MB) 90 * 91 * Return: 92 * EEXIST: The requested image file already exists 93 * 0 : Image file successfully created 94 * Exxxx : Various other Exxxx errno codes due to other I/O errors 95 */ 96 int 97 virtio_raw_create(const char *imgfile_path, long imgsize) 98 { 99 int fd, ret; 100 101 /* Refuse to overwrite an existing image */ 102 fd = open(imgfile_path, O_RDWR | O_CREAT | O_TRUNC | O_EXCL, 103 S_IRUSR | S_IWUSR); 104 if (fd == -1) 105 return (errno); 106 107 /* Extend to desired size */ 108 if (ftruncate(fd, (off_t)imgsize * 1024 * 1024) == -1) { 109 ret = errno; 110 close(fd); 111 unlink(imgfile_path); 112 return (ret); 113 } 114 115 ret = close(fd); 116 return (ret); 117 } 118