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