xref: /openbsd/usr.sbin/vmd/vioraw.c (revision 20e554f8)
1*20e554f8Sdv /*	$OpenBSD: vioraw.c,v 1.11 2023/09/14 15:25:43 dv Exp $	*/
29617633bSccardenas /*
39617633bSccardenas  * Copyright (c) 2018 Ori Bernstein <ori@eigenstate.org>
49617633bSccardenas  *
59617633bSccardenas  * Permission to use, copy, modify, and distribute this software for any
69617633bSccardenas  * purpose with or without fee is hereby granted, provided that the above
79617633bSccardenas  * copyright notice and this permission notice appear in all copies.
89617633bSccardenas  *
99617633bSccardenas  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
109617633bSccardenas  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
119617633bSccardenas  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
129617633bSccardenas  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
139617633bSccardenas  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
149617633bSccardenas  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
159617633bSccardenas  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
169617633bSccardenas  */
179617633bSccardenas 
189617633bSccardenas #include <sys/types.h>
1962df93eeSreyk #include <sys/stat.h>
209617633bSccardenas 
219617633bSccardenas #include <stdlib.h>
229617633bSccardenas #include <unistd.h>
2362df93eeSreyk #include <fcntl.h>
2462df93eeSreyk #include <errno.h>
259617633bSccardenas 
269617633bSccardenas #include "virtio.h"
279617633bSccardenas 
289617633bSccardenas static ssize_t
raw_pread(void * file,char * buf,size_t len,off_t off)299617633bSccardenas raw_pread(void *file, char *buf, size_t len, off_t off)
309617633bSccardenas {
319617633bSccardenas 	return pread(*(int *)file, buf, len, off);
329617633bSccardenas }
339617633bSccardenas 
349617633bSccardenas static ssize_t
raw_preadv(void * file,struct iovec * iov,int cnt,off_t offset)35*20e554f8Sdv raw_preadv(void *file, struct iovec *iov, int cnt, off_t offset)
36*20e554f8Sdv {
37*20e554f8Sdv 	return preadv(*(int *)file, iov, cnt, offset);
38*20e554f8Sdv }
39*20e554f8Sdv 
40*20e554f8Sdv static ssize_t
raw_pwrite(void * file,char * buf,size_t len,off_t off)419617633bSccardenas raw_pwrite(void *file, char *buf, size_t len, off_t off)
429617633bSccardenas {
439617633bSccardenas 	return pwrite(*(int *)file, buf, len, off);
449617633bSccardenas }
459617633bSccardenas 
46*20e554f8Sdv static ssize_t
raw_pwritev(void * file,struct iovec * iov,int cnt,off_t offset)47*20e554f8Sdv raw_pwritev(void *file, struct iovec *iov, int cnt, off_t offset)
48*20e554f8Sdv {
49*20e554f8Sdv 	return pwritev(*(int *)file, iov, cnt, offset);
50*20e554f8Sdv }
51*20e554f8Sdv 
529617633bSccardenas static void
raw_close(void * file,int stayopen)53f6c09be3Sreyk raw_close(void *file, int stayopen)
549617633bSccardenas {
55f6c09be3Sreyk 	if (!stayopen)
569617633bSccardenas 		close(*(int *)file);
579617633bSccardenas 	free(file);
589617633bSccardenas }
599617633bSccardenas 
609617633bSccardenas /*
613d346d65Sdv  * Initializes a raw disk image backing file from an fd.  Stores the
62a3500374Sasou  * number of bytes in *szp, returning -1 for error, 0 for success.
639617633bSccardenas  */
649617633bSccardenas int
virtio_raw_init(struct virtio_backing * file,off_t * szp,int * fd,size_t nfd)6562df93eeSreyk virtio_raw_init(struct virtio_backing *file, off_t *szp, int *fd, size_t nfd)
669617633bSccardenas {
679617633bSccardenas 	off_t sz;
689617633bSccardenas 	int *fdp;
699617633bSccardenas 
7073613953Sreyk 	if (nfd != 1)
713d346d65Sdv 		return (-1);
723481ecdfSdv 
7373613953Sreyk 	sz = lseek(fd[0], 0, SEEK_END);
749617633bSccardenas 	if (sz == -1)
753d346d65Sdv 		return (-1);
769617633bSccardenas 
779617633bSccardenas 	fdp = malloc(sizeof(int));
7850bebf2cSccardenas 	if (!fdp)
793d346d65Sdv 		return (-1);
8073613953Sreyk 	*fdp = fd[0];
819617633bSccardenas 	file->p = fdp;
829617633bSccardenas 	file->pread = raw_pread;
83*20e554f8Sdv 	file->preadv = raw_preadv;
849617633bSccardenas 	file->pwrite = raw_pwrite;
85*20e554f8Sdv 	file->pwritev = raw_pwritev;
869617633bSccardenas 	file->close = raw_close;
87a3500374Sasou 	*szp = sz;
883d346d65Sdv 	return (0);
899617633bSccardenas }
909617633bSccardenas 
9162df93eeSreyk /*
9262df93eeSreyk  * virtio_raw_create
9362df93eeSreyk  *
9462df93eeSreyk  * Create an empty imagefile with the specified path and size.
9562df93eeSreyk  *
9662df93eeSreyk  * Parameters:
9762df93eeSreyk  *  imgfile_path: path to the image file to create
98ead1b146Sdv  *  imgsize     : size of the image file to create (in bytes)
9962df93eeSreyk  *
10062df93eeSreyk  * Return:
10162df93eeSreyk  *  EEXIST: The requested image file already exists
10262df93eeSreyk  *  0     : Image file successfully created
10362df93eeSreyk  *  Exxxx : Various other Exxxx errno codes due to other I/O errors
10462df93eeSreyk  */
10562df93eeSreyk int
virtio_raw_create(const char * imgfile_path,uint64_t imgsize)106ead1b146Sdv virtio_raw_create(const char *imgfile_path, uint64_t imgsize)
10762df93eeSreyk {
10862df93eeSreyk 	int fd, ret;
10962df93eeSreyk 
11062df93eeSreyk 	/* Refuse to overwrite an existing image */
11162df93eeSreyk 	fd = open(imgfile_path, O_RDWR | O_CREAT | O_TRUNC | O_EXCL,
11262df93eeSreyk 	    S_IRUSR | S_IWUSR);
11362df93eeSreyk 	if (fd == -1)
11462df93eeSreyk 		return (errno);
11562df93eeSreyk 
11662df93eeSreyk 	/* Extend to desired size */
117ead1b146Sdv 	if (ftruncate(fd, (off_t)imgsize) == -1) {
11862df93eeSreyk 		ret = errno;
11962df93eeSreyk 		close(fd);
12062df93eeSreyk 		unlink(imgfile_path);
12162df93eeSreyk 		return (ret);
12262df93eeSreyk 	}
12362df93eeSreyk 
12462df93eeSreyk 	ret = close(fd);
12562df93eeSreyk 	return (ret);
12662df93eeSreyk }
127