1 /* $OpenBSD: vioraw.c,v 1.6 2021/06/16 16:55:02 dv 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 <stdlib.h> 22 #include <unistd.h> 23 #include <fcntl.h> 24 #include <errno.h> 25 26 #include "virtio.h" 27 28 static ssize_t 29 raw_pread(void *file, char *buf, size_t len, off_t off) 30 { 31 return pread(*(int *)file, buf, len, off); 32 } 33 34 static ssize_t 35 raw_pwrite(void *file, char *buf, size_t len, off_t off) 36 { 37 return pwrite(*(int *)file, buf, len, off); 38 } 39 40 static void 41 raw_close(void *file, int stayopen) 42 { 43 if (!stayopen) 44 close(*(int *)file); 45 free(file); 46 } 47 48 /* 49 * Initializes a raw disk image backing file from an fd. 50 * Stores the number of 512 byte sectors in *szp, 51 * returning -1 for error, 0 for success. 52 */ 53 int 54 virtio_raw_init(struct virtio_backing *file, off_t *szp, int *fd, size_t nfd) 55 { 56 off_t sz; 57 int *fdp; 58 59 if (nfd != 1) 60 return -1; 61 sz = lseek(fd[0], 0, SEEK_END); 62 if (sz == -1) 63 return -1; 64 65 fdp = malloc(sizeof(int)); 66 if (!fdp) 67 return -1; 68 *fdp = fd[0]; 69 file->p = fdp; 70 file->pread = raw_pread; 71 file->pwrite = raw_pwrite; 72 file->close = raw_close; 73 *szp = sz; 74 return 0; 75 } 76 77 /* 78 * virtio_raw_create 79 * 80 * Create an empty imagefile with the specified path and size. 81 * 82 * Parameters: 83 * imgfile_path: path to the image file to create 84 * imgsize : size of the image file to create (in MB) 85 * 86 * Return: 87 * EEXIST: The requested image file already exists 88 * 0 : Image file successfully created 89 * Exxxx : Various other Exxxx errno codes due to other I/O errors 90 */ 91 int 92 virtio_raw_create(const char *imgfile_path, long imgsize) 93 { 94 int fd, ret; 95 96 /* Refuse to overwrite an existing image */ 97 fd = open(imgfile_path, O_RDWR | O_CREAT | O_TRUNC | O_EXCL, 98 S_IRUSR | S_IWUSR); 99 if (fd == -1) 100 return (errno); 101 102 /* Extend to desired size */ 103 if (ftruncate(fd, (off_t)imgsize * 1024 * 1024) == -1) { 104 ret = errno; 105 close(fd); 106 unlink(imgfile_path); 107 return (ret); 108 } 109 110 ret = close(fd); 111 return (ret); 112 } 113