> On 12 Mar 2021, at 05:41, Mike Larkin <mlar...@nested.page> wrote: > > On Thu, Mar 11, 2021 at 06:11:03PM -0500, Dave Voutila wrote: >> tl;dr: tedu vmboot.{c,h}, ufs.c from vmd(8) to remove broken ability to >> exract and boot a kernel image from a raw or qcow2 disk image >> >> The following diff removes the ability to boot directly from a disk >> image containing a FFS filesystem. No new functionality is added. It's >> still possible to boot via a kernel image or with either disk or iso >> images via seabios. (PXE booting should still work via a kernel image, >> but I haven't tested it personally.) >> >> Why remove this? >> >> - since 6.7 switched to FFS2 as the default filesystem for new installs, >> the ability for vmd(8) to load a kernel and boot.conf from a disk >> image directly (without seabios) has been broken. tb@ apparently sent >> a diff to update support for FFS2 awhile back, but it never made it >> into the tree. >> >> - on 5th Jan 2021, new ramdisks for amd64 have started shipping gzip'd, >> breaking the ability to load the bsd.rd directly as a kernel image for >> a vmd(8) guest without first uncompressing the image >> >> Why not fix it? >> >> - using bios (via seabios) works >> >> - the FFS2 change happened ten months ago and afaict few if any have >> complained about the breakage, so I'm not sure the value in fixing >> it. vmctl(8) is still vague about supporting it per its man page and >> you still have to pass the disk image twice as a -b and -d arg if >> you're trying to avoid using seabios to boot an OpenBSD guest. >> >> - Josh Rickmar reported the gzip issue on bugs@ and provided patches to >> add in support for compressed ramdisks and kernel images. In doing so, >> we found the easiest way to add gzip kernel image support was to drop >> support for FFS images since they require a call to fmemopen(3) while >> all the other logic uses fopen(3)/fdopen(3) calls and a file >> descriptor. I think it would be easier to get his patches into vmd(8) >> if they don't have to account for extracting kernels from disk >> images. >> >> I can understand an argument to shy away from relying on seabios for >> booting, but given it's readily available via fw_update(1) and is part >> of the default behavior, I'd imagine most won't miss this feature. >> >> If people ARE using direct booting of raw/qcow2 images (without using >> seabios) please speak up and instead I can look into dusting off tb@'s >> old diff. >> > > reyk@ wrote that ffs module for vmd but since he has not stepped up to > maintain it after the ffs2 switch, I vote to remove it. If someone wants > to come back and fixup ffs2 support with the tb@ diff we can look at that > when said person steps up. > > ok mlarkin
I’m not using it anymore and I’m not interested in maintaining it. It was a nice feature for some tests and to boot small VMs in about a second but that’s about it. Removing it makes sense. Reyk >> -- >> -Dave Voutila >> >> >> Index: Makefile >> =================================================================== >> RCS file: /cvs/src/usr.sbin/vmd/Makefile,v >> retrieving revision 1.24 >> diff -u -p -u -p -r1.24 Makefile >> --- Makefile 23 Sep 2020 19:18:18 -0000 1.24 >> +++ Makefile 11 Mar 2021 22:10:08 -0000 >> @@ -5,7 +5,7 @@ >> PROG= vmd >> SRCS= vmd.c control.c log.c priv.c proc.c config.c vmm.c >> SRCS+= vm.c loadfile_elf.c pci.c virtio.c i8259.c mc146818.c >> -SRCS+= ns8250.c i8253.c vmboot.c ufs.c disklabel.c dhcp.c packet.c >> +SRCS+= ns8250.c i8253.c dhcp.c packet.c >> SRCS+= parse.y atomicio.c vioscsi.c vioraw.c vioqcow2.c fw_cfg.c >> >> CFLAGS+= -Wall -I${.CURDIR} >> Index: loadfile.h >> =================================================================== >> RCS file: /cvs/src/usr.sbin/vmd/loadfile.h,v >> retrieving revision 1.12 >> diff -u -p -u -p -r1.12 loadfile.h >> --- loadfile.h 16 May 2019 21:16:04 -0000 1.12 >> +++ loadfile.h 11 Mar 2021 22:10:08 -0000 >> @@ -73,8 +73,6 @@ >> #define PML2_PAGE 0x13000 >> #define NPTE_PG (PAGE_SIZE / sizeof(uint64_t)) >> >> -int loadfile_elf(FILE *, struct vm_create_params *, >> - struct vcpu_reg_state *, uint32_t, uint32_t, unsigned int); >> +int loadfile_elf(FILE *, struct vm_create_params *, struct vcpu_reg_state >> *); >> >> size_t mread(FILE *, paddr_t, size_t); >> - >> Index: loadfile_elf.c >> =================================================================== >> RCS file: /cvs/src/usr.sbin/vmd/loadfile_elf.c,v >> retrieving revision 1.36 >> diff -u -p -u -p -r1.36 loadfile_elf.c >> --- loadfile_elf.c 26 Oct 2020 04:04:31 -0000 1.36 >> +++ loadfile_elf.c 11 Mar 2021 22:10:10 -0000 >> @@ -118,8 +118,8 @@ static void setsegment(struct mem_segmen >> static int elf32_exec(FILE *, Elf32_Ehdr *, u_long *, int); >> static int elf64_exec(FILE *, Elf64_Ehdr *, u_long *, int); >> static size_t create_bios_memmap(struct vm_create_params *, bios_memmap_t *); >> -static uint32_t push_bootargs(bios_memmap_t *, size_t, bios_bootmac_t *); >> -static size_t push_stack(uint32_t, uint32_t, uint32_t, uint32_t); >> +static uint32_t push_bootargs(bios_memmap_t *, size_t); >> +static size_t push_stack(uint32_t, uint32_t); >> static void push_gdt(void); >> static void push_pt_32(void); >> static void push_pt_64(void); >> @@ -263,16 +263,13 @@ push_pt_64(void) >> * various error codes returned from read(2) or loadelf functions >> */ >> int >> -loadfile_elf(FILE *fp, struct vm_create_params *vcp, >> - struct vcpu_reg_state *vrs, uint32_t bootdev, uint32_t howto, >> - unsigned int bootdevice) >> +loadfile_elf(FILE *fp, struct vm_create_params *vcp, struct vcpu_reg_state >> *vrs) >> { >> int r, is_i386 = 0; >> uint32_t bootargsz; >> size_t n, stacksize; >> u_long marks[MARK_MAX]; >> bios_memmap_t memmap[VMM_MAX_MEM_RANGES + 1]; >> - bios_bootmac_t bm, *bootmac = NULL; >> >> if ((r = fread(&hdr, 1, sizeof(hdr), fp)) != sizeof(hdr)) >> return 1; >> @@ -303,13 +300,9 @@ loadfile_elf(FILE *fp, struct vm_create_ >> else >> push_pt_64(); >> >> - if (bootdevice & VMBOOTDEV_NET) { >> - bootmac = &bm; >> - memcpy(bootmac, vcp->vcp_macs[0], ETHER_ADDR_LEN); >> - } >> n = create_bios_memmap(vcp, memmap); >> - bootargsz = push_bootargs(memmap, n, bootmac); >> - stacksize = push_stack(bootargsz, marks[MARK_END], bootdev, howto); >> + bootargsz = push_bootargs(memmap, n); >> + stacksize = push_stack(bootargsz, marks[MARK_END]); >> >> vrs->vrs_gprs[VCPU_REGS_RIP] = (uint64_t)marks[MARK_ENTRY]; >> vrs->vrs_gprs[VCPU_REGS_RSP] = (uint64_t)(STACK_PAGE + PAGE_SIZE) - >> stacksize; >> @@ -388,9 +381,9 @@ create_bios_memmap(struct vm_create_para >> * The size of the bootargs >> */ >> static uint32_t >> -push_bootargs(bios_memmap_t *memmap, size_t n, bios_bootmac_t *bootmac) >> +push_bootargs(bios_memmap_t *memmap, size_t n) >> { >> - uint32_t memmap_sz, consdev_sz, bootmac_sz, i; >> + uint32_t memmap_sz, consdev_sz, i; >> bios_consdev_t consdev; >> uint32_t ba[1024]; >> >> @@ -414,15 +407,6 @@ push_bootargs(bios_memmap_t *memmap, siz >> memcpy(&ba[i + 3], &consdev, sizeof(bios_consdev_t)); >> i += consdev_sz / sizeof(int); >> >> - if (bootmac) { >> - bootmac_sz = 3 * sizeof(int) + (sizeof(bios_bootmac_t) + 3) & ~3; >> - ba[i] = 0x7; /* bootmac */ >> - ba[i + 1] = bootmac_sz; >> - ba[i + 2] = bootmac_sz; >> - memcpy(&ba[i + 3], bootmac, sizeof(bios_bootmac_t)); >> - i += bootmac_sz / sizeof(int); >> - } >> - >> ba[i++] = 0xFFFFFFFF; /* BOOTARG_END */ >> >> write_mem(BOOTARGS_PAGE, ba, PAGE_SIZE); >> @@ -458,7 +442,7 @@ push_bootargs(bios_memmap_t *memmap, siz >> * size of the stack >> */ >> static size_t >> -push_stack(uint32_t bootargsz, uint32_t end, uint32_t bootdev, uint32_t >> howto) >> +push_stack(uint32_t bootargsz, uint32_t end) >> { >> uint32_t stack[1024]; >> uint16_t loc; >> @@ -466,17 +450,14 @@ push_stack(uint32_t bootargsz, uint32_t >> memset(&stack, 0, sizeof(stack)); >> loc = 1024; >> >> - if (bootdev == 0) >> - bootdev = MAKEBOOTDEV(0x4, 0, 0, 0, 0); /* bootdev: sd0a */ >> - >> stack[--loc] = BOOTARGS_PAGE; >> stack[--loc] = bootargsz; >> stack[--loc] = 0; /* biosbasemem */ >> stack[--loc] = 0; /* biosextmem */ >> stack[--loc] = end; >> stack[--loc] = 0x0e; >> - stack[--loc] = bootdev; >> - stack[--loc] = howto; >> + stack[--loc] = MAKEBOOTDEV(0x4, 0, 0, 0, 0); /* bootdev: sd0a */ >> + stack[--loc] = 0; >> >> write_mem(STACK_PAGE, &stack, PAGE_SIZE); >> >> Index: ufs.c >> =================================================================== >> RCS file: ufs.c >> diff -N ufs.c >> --- ufs.c 7 Oct 2017 19:48:30 -0000 1.6 >> +++ /dev/null 1 Jan 1970 00:00:00 -0000 >> @@ -1,721 +0,0 @@ >> -/* $OpenBSD: ufs.c,v 1.6 2017/10/07 19:48:30 guenther Exp $ */ >> -/* $NetBSD: ufs.c,v 1.16 1996/09/30 16:01:22 ws Exp $ */ >> - >> -/*- >> - * Copyright (c) 1993 >> - * The Regents of the University of California. All rights reserved. >> - * >> - * This code is derived from software contributed to Berkeley by >> - * The Mach Operating System project at Carnegie-Mellon University. >> - * >> - * Redistribution and use in source and binary forms, with or without >> - * modification, are permitted provided that the following conditions >> - * are met: >> - * 1. Redistributions of source code must retain the above copyright >> - * notice, this list of conditions and the following disclaimer. >> - * 2. Redistributions in binary form must reproduce the above copyright >> - * notice, this list of conditions and the following disclaimer in the >> - * documentation and/or other materials provided with the distribution. >> - * 3. Neither the name of the University nor the names of its contributors >> - * may be used to endorse or promote products derived from this software >> - * without specific prior written permission. >> - * >> - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND >> - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE >> - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR >> PURPOSE >> - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE >> - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR >> CONSEQUENTIAL >> - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS >> - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) >> - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, >> STRICT >> - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY >> - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF >> - * SUCH DAMAGE. >> - * >> - * >> - * Copyright (c) 1990, 1991 Carnegie Mellon University >> - * All Rights Reserved. >> - * >> - * Author: David Golub >> - * >> - * Permission to use, copy, modify and distribute this software and its >> - * documentation is hereby granted, provided that both the copyright >> - * notice and this permission notice appear in all copies of the >> - * software, derivative works or modified versions, and any portions >> - * thereof, and that both notices appear in supporting documentation. >> - * >> - * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" >> - * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR >> - * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. >> - * >> - * Carnegie Mellon requests users of this software to return to >> - * >> - * Software Distribution Coordinator or software.distribut...@cs.cmu.edu >> - * School of Computer Science >> - * Carnegie Mellon University >> - * Pittsburgh PA 15213-3890 >> - * >> - * any improvements or extensions that they make and grant Carnegie the >> - * rights to redistribute these changes. >> - */ >> - >> -/* >> - * Stand-alone file reading package. >> - */ >> - >> -#include <sys/param.h> /* DEV_BSIZE MAXBSIZE */ >> -#include <sys/time.h> >> -#include <sys/stat.h> >> -#include <ufs/ffs/fs.h> >> -#include <ufs/ufs/dinode.h> >> -#include <ufs/ufs/dir.h> >> - >> -#include <limits.h> >> - >> -#include "vmboot.h" >> - >> -/* Used in the kernel by libsa */ >> -#define alloc malloc >> -#define free(_p, _n) free(_p) >> -#define twiddle() do { } while(0) >> -#define NO_READDIR 1 >> - >> -/* >> - * In-core open file. >> - */ >> -struct file { >> - off_t f_seekp; /* seek pointer */ >> - struct fs *f_fs; /* pointer to super-block */ >> - struct ufs1_dinode f_di; /* copy of on-disk inode */ >> - int f_nindir[NIADDR]; >> - /* number of blocks mapped by >> - indirect block at level i */ >> - char *f_blk[NIADDR]; /* buffer for indirect block at >> - level i */ >> - size_t f_blksize[NIADDR]; >> - /* size of buffer */ >> - daddr32_t f_blkno[NIADDR];/* disk address of block in buffer */ >> - char *f_buf; /* buffer for data block */ >> - size_t f_buf_size; /* size of data block */ >> - daddr32_t f_buf_blkno; /* block number of data block */ >> -}; >> - >> -static int read_inode(ufsino_t, struct open_file *); >> -static int block_map(struct open_file *, daddr32_t, daddr32_t *); >> -static int buf_read_file(struct open_file *, char **, size_t *); >> -static int search_directory(char *, struct open_file *, ufsino_t *); >> -static int ufs_close_internal(struct file *); >> -#ifdef COMPAT_UFS >> -static void ffs_oldfscompat(struct fs *); >> -#endif >> - >> -/* >> - * Read a new inode into a file structure. >> - */ >> -static int >> -read_inode(ufsino_t inumber, struct open_file *f) >> -{ >> - struct file *fp = (struct file *)f->f_fsdata; >> - struct fs *fs = fp->f_fs; >> - char *buf; >> - size_t rsize; >> - int rc; >> - >> - /* >> - * Read inode and save it. >> - */ >> - buf = alloc(fs->fs_bsize); >> - twiddle(); >> - rc = (f->f_dev->dv_strategy)(f->f_devdata, F_READ, >> - fsbtodb(fs, (daddr32_t)ino_to_fsba(fs, inumber)), fs->fs_bsize, >> - buf, &rsize); >> - if (rc) >> - goto out; >> - if (rsize != (size_t)fs->fs_bsize) { >> - rc = EIO; >> - goto out; >> - } >> - >> - { >> - struct ufs1_dinode *dp; >> - >> - dp = (struct ufs1_dinode *)buf; >> - fp->f_di = dp[ino_to_fsbo(fs, inumber)]; >> - } >> - >> - /* >> - * Clear out the old buffers >> - */ >> - { >> - int level; >> - >> - for (level = 0; level < NIADDR; level++) >> - fp->f_blkno[level] = -1; >> - fp->f_buf_blkno = -1; >> - fp->f_seekp = 0; >> - } >> -out: >> - free(buf, fs->fs_bsize); >> - return (rc); >> -} >> - >> -/* >> - * Given an offset in a file, find the disk block number that >> - * contains that block. >> - */ >> -static int >> -block_map(struct open_file *f, daddr32_t file_block, daddr32_t >> *disk_block_p) >> -{ >> - struct file *fp = (struct file *)f->f_fsdata; >> - daddr32_t ind_block_num, *ind_p; >> - struct fs *fs = fp->f_fs; >> - int level, idx, rc; >> - >> - /* >> - * Index structure of an inode: >> - * >> - * di_db[0..NDADDR-1] hold block numbers for blocks >> - * 0..NDADDR-1 >> - * >> - * di_ib[0] index block 0 is the single indirect block >> - * holds block numbers for blocks >> - * NDADDR .. NDADDR + NINDIR(fs)-1 >> - * >> - * di_ib[1] index block 1 is the double indirect block >> - * holds block numbers for INDEX blocks for blocks >> - * NDADDR + NINDIR(fs) .. >> - * NDADDR + NINDIR(fs) + NINDIR(fs)**2 - 1 >> - * >> - * di_ib[2] index block 2 is the triple indirect block >> - * holds block numbers for double-indirect >> - * blocks for blocks >> - * NDADDR + NINDIR(fs) + NINDIR(fs)**2 .. >> - * NDADDR + NINDIR(fs) + NINDIR(fs)**2 >> - * + NINDIR(fs)**3 - 1 >> - */ >> - >> - if (file_block < NDADDR) { >> - /* Direct block. */ >> - *disk_block_p = fp->f_di.di_db[file_block]; >> - return (0); >> - } >> - >> - file_block -= NDADDR; >> - >> - /* >> - * nindir[0] = NINDIR >> - * nindir[1] = NINDIR**2 >> - * nindir[2] = NINDIR**3 >> - * etc >> - */ >> - for (level = 0; level < NIADDR; level++) { >> - if (file_block < fp->f_nindir[level]) >> - break; >> - file_block -= fp->f_nindir[level]; >> - } >> - if (level == NIADDR) { >> - /* Block number too high */ >> - return (EFBIG); >> - } >> - >> - ind_block_num = fp->f_di.di_ib[level]; >> - >> - for (; level >= 0; level--) { >> - if (ind_block_num == 0) { >> - *disk_block_p = 0; /* missing */ >> - return (0); >> - } >> - >> - if (fp->f_blkno[level] != ind_block_num) { >> - if (fp->f_blk[level] == NULL) >> - fp->f_blk[level] = >> - alloc(fs->fs_bsize); >> - twiddle(); >> - rc = (f->f_dev->dv_strategy)(f->f_devdata, F_READ, >> - fsbtodb(fp->f_fs, ind_block_num), fs->fs_bsize, >> - fp->f_blk[level], &fp->f_blksize[level]); >> - if (rc) >> - return (rc); >> - if (fp->f_blksize[level] != (size_t)fs->fs_bsize) >> - return (EIO); >> - fp->f_blkno[level] = ind_block_num; >> - } >> - >> - ind_p = (daddr32_t *)fp->f_blk[level]; >> - >> - if (level > 0) { >> - idx = file_block / fp->f_nindir[level - 1]; >> - file_block %= fp->f_nindir[level - 1]; >> - } else >> - idx = file_block; >> - >> - ind_block_num = ind_p[idx]; >> - } >> - >> - *disk_block_p = ind_block_num; >> - return (0); >> -} >> - >> -/* >> - * Read a portion of a file into an internal buffer. Return >> - * the location in the buffer and the amount in the buffer. >> - */ >> -static int >> -buf_read_file(struct open_file *f, char **buf_p, size_t *size_p) >> -{ >> - struct file *fp = (struct file *)f->f_fsdata; >> - struct fs *fs = fp->f_fs; >> - daddr32_t file_block, disk_block; >> - size_t block_size; >> - long off; >> - int rc; >> - >> - off = blkoff(fs, fp->f_seekp); >> - file_block = lblkno(fs, fp->f_seekp); >> - block_size = dblksize(fs, &fp->f_di, (u_int64_t)file_block); >> - >> - if (file_block != fp->f_buf_blkno) { >> - rc = block_map(f, file_block, &disk_block); >> - if (rc) >> - return (rc); >> - >> - if (fp->f_buf == NULL) >> - fp->f_buf = alloc(fs->fs_bsize); >> - >> - if (disk_block == 0) { >> - memset(fp->f_buf, 0, block_size); >> - fp->f_buf_size = block_size; >> - } else { >> - twiddle(); >> - rc = (f->f_dev->dv_strategy)(f->f_devdata, F_READ, >> - fsbtodb(fs, disk_block), >> - block_size, fp->f_buf, &fp->f_buf_size); >> - if (rc) >> - return (rc); >> - } >> - >> - fp->f_buf_blkno = file_block; >> - } >> - >> - /* >> - * Return address of byte in buffer corresponding to >> - * offset, and size of remainder of buffer after that >> - * byte. >> - */ >> - *buf_p = fp->f_buf + off; >> - *size_p = block_size - off; >> - >> - /* >> - * But truncate buffer at end of file. >> - */ >> - if (*size_p > fp->f_di.di_size - fp->f_seekp) >> - *size_p = fp->f_di.di_size - fp->f_seekp; >> - >> - return (0); >> -} >> - >> -/* >> - * Search a directory for a name and return its >> - * i_number. >> - */ >> -static int >> -search_directory(char *name, struct open_file *f, ufsino_t *inumber_p) >> -{ >> - struct file *fp = (struct file *)f->f_fsdata; >> - int namlen, length, rc; >> - struct direct *dp, *edp; >> - size_t buf_size; >> - char *buf; >> - >> - length = strlen(name); >> - >> - fp->f_seekp = 0; >> - while ((u_int64_t)fp->f_seekp < fp->f_di.di_size) { >> - rc = buf_read_file(f, &buf, &buf_size); >> - if (rc) >> - return (rc); >> - >> - dp = (struct direct *)buf; >> - edp = (struct direct *)(buf + buf_size); >> - while (dp < edp) { >> - if (dp->d_ino == 0) >> - goto next; >> -#if BYTE_ORDER == LITTLE_ENDIAN >> - if (fp->f_fs->fs_maxsymlinklen <= 0) >> - namlen = dp->d_type; >> - else >> -#endif >> - namlen = dp->d_namlen; >> - if (namlen == length && >> - !strcmp(name, dp->d_name)) { >> - /* found entry */ >> - *inumber_p = dp->d_ino; >> - return (0); >> - } >> - next: >> - dp = (struct direct *)((char *)dp + dp->d_reclen); >> - } >> - fp->f_seekp += buf_size; >> - } >> - return (ENOENT); >> -} >> - >> -/* >> - * Open a file. >> - */ >> -int >> -ufs_open(char *path, struct open_file *f) >> -{ >> - char namebuf[PATH_MAX+1], *cp, *ncp, *buf = NULL; >> - ufsino_t inumber, parent_inumber; >> - int rc, c, nlinks = 0; >> - struct file *fp; >> - size_t buf_size; >> - struct fs *fs; >> - >> - /* allocate file system specific data structure */ >> - fp = alloc(sizeof(struct file)); >> - memset(fp, 0, sizeof(struct file)); >> - f->f_fsdata = (void *)fp; >> - >> - /* allocate space and read super block */ >> - fs = alloc(SBSIZE); >> - fp->f_fs = fs; >> - twiddle(); >> - rc = (f->f_dev->dv_strategy)(f->f_devdata, F_READ, >> - SBLOCK, SBSIZE, (char *)fs, &buf_size); >> - if (rc) >> - goto out; >> - >> - if (buf_size != SBSIZE || fs->fs_magic != FS_MAGIC || >> - (size_t)fs->fs_bsize > MAXBSIZE || >> - (size_t)fs->fs_bsize < sizeof(struct fs)) { >> - rc = EINVAL; >> - goto out; >> - } >> -#ifdef COMPAT_UFS >> - ffs_oldfscompat(fs); >> -#endif >> - >> - /* >> - * Calculate indirect block levels. >> - */ >> - { >> - int mult; >> - int level; >> - >> - mult = 1; >> - for (level = 0; level < NIADDR; level++) { >> - mult *= NINDIR(fs); >> - fp->f_nindir[level] = mult; >> - } >> - } >> - >> - inumber = ROOTINO; >> - if ((rc = read_inode(inumber, f)) != 0) >> - goto out; >> - >> - cp = path; >> - while (*cp) { >> - >> - /* >> - * Remove extra separators >> - */ >> - while (*cp == '/') >> - cp++; >> - if (*cp == '\0') >> - break; >> - >> - /* >> - * Check that current node is a directory. >> - */ >> - if ((fp->f_di.di_mode & IFMT) != IFDIR) { >> - rc = ENOTDIR; >> - goto out; >> - } >> - >> - /* >> - * Get next component of path name. >> - */ >> - { >> - int len = 0; >> - >> - ncp = cp; >> - while ((c = *cp) != '\0' && c != '/') { >> - if (++len > MAXNAMLEN) { >> - rc = ENOENT; >> - goto out; >> - } >> - cp++; >> - } >> - *cp = '\0'; >> - } >> - >> - /* >> - * Look up component in current directory. >> - * Save directory inumber in case we find a >> - * symbolic link. >> - */ >> - parent_inumber = inumber; >> - rc = search_directory(ncp, f, &inumber); >> - *cp = c; >> - if (rc) >> - goto out; >> - >> - /* >> - * Open next component. >> - */ >> - if ((rc = read_inode(inumber, f)) != 0) >> - goto out; >> - >> - /* >> - * Check for symbolic link. >> - */ >> - if ((fp->f_di.di_mode & IFMT) == IFLNK) { >> - u_int64_t link_len = fp->f_di.di_size; >> - size_t len; >> - >> - len = strlen(cp); >> - >> - if (link_len + len > PATH_MAX || >> - ++nlinks > SYMLOOP_MAX) { >> - rc = ENOENT; >> - goto out; >> - } >> - >> - bcopy(cp, &namebuf[link_len], len + 1); >> - >> - if (link_len < (u_int64_t)fs->fs_maxsymlinklen) { >> - bcopy(fp->f_di.di_shortlink, namebuf, link_len); >> - } else { >> - /* >> - * Read file for symbolic link >> - */ >> - daddr32_t disk_block; >> - fs = fp->f_fs; >> - >> - if (!buf) >> - buf = alloc(fs->fs_bsize); >> - rc = block_map(f, (daddr32_t)0, &disk_block); >> - if (rc) >> - goto out; >> - >> - twiddle(); >> - rc = (f->f_dev->dv_strategy)(f->f_devdata, >> - F_READ, fsbtodb(fs, disk_block), >> - fs->fs_bsize, buf, &buf_size); >> - if (rc) >> - goto out; >> - >> - bcopy(buf, namebuf, link_len); >> - } >> - >> - /* >> - * If relative pathname, restart at parent directory. >> - * If absolute pathname, restart at root. >> - */ >> - cp = namebuf; >> - if (*cp != '/') >> - inumber = parent_inumber; >> - else >> - inumber = ROOTINO; >> - >> - if ((rc = read_inode(inumber, f)) != 0) >> - goto out; >> - } >> - } >> - >> - /* >> - * Found terminal component. >> - */ >> - rc = 0; >> -out: >> - if (buf) >> - free(buf, fs->fs_bsize); >> - if (rc) >> - (void)ufs_close_internal(fp); >> - >> - return (rc); >> -} >> - >> -int >> -ufs_close(struct open_file *f) >> -{ >> - struct file *fp = (struct file *)f->f_fsdata; >> - >> - f->f_fsdata = NULL; >> - if (fp == NULL) >> - return (0); >> - >> - return (ufs_close_internal(fp)); >> -} >> - >> -static int >> -ufs_close_internal(struct file *fp) >> -{ >> - int level; >> - >> - for (level = 0; level < NIADDR; level++) { >> - if (fp->f_blk[level]) >> - free(fp->f_blk[level], fp->f_fs->fs_bsize); >> - } >> - if (fp->f_buf) >> - free(fp->f_buf, fp->f_fs->fs_bsize); >> - free(fp->f_fs, SBSIZE); >> - free(fp, sizeof(struct file)); >> - return (0); >> -} >> - >> -/* >> - * Copy a portion of a file into kernel memory. >> - * Cross block boundaries when necessary. >> - */ >> -int >> -ufs_read(struct open_file *f, void *start, size_t size, size_t *resid) >> -{ >> - struct file *fp = (struct file *)f->f_fsdata; >> - char *buf, *addr = start; >> - size_t csize, buf_size; >> - int rc = 0; >> - >> - while (size != 0) { >> - if ((u_int64_t)fp->f_seekp >= fp->f_di.di_size) >> - break; >> - >> - rc = buf_read_file(f, &buf, &buf_size); >> - if (rc) >> - break; >> - >> - csize = size; >> - if (csize > buf_size) >> - csize = buf_size; >> - >> - bcopy(buf, addr, csize); >> - >> - fp->f_seekp += csize; >> - addr += csize; >> - size -= csize; >> - } >> - if (resid) >> - *resid = size; >> - return (rc); >> -} >> - >> -/* >> - * Not implemented. >> - */ >> -int >> -ufs_write(struct open_file *f, void *start, size_t size, size_t *resid) >> -{ >> - >> - return (EROFS); >> -} >> - >> -off_t >> -ufs_seek(struct open_file *f, off_t offset, int where) >> -{ >> - struct file *fp = (struct file *)f->f_fsdata; >> - >> - switch (where) { >> - case SEEK_SET: >> - fp->f_seekp = offset; >> - break; >> - case SEEK_CUR: >> - fp->f_seekp += offset; >> - break; >> - case SEEK_END: >> - fp->f_seekp = fp->f_di.di_size - offset; >> - break; >> - default: >> - return (-1); >> - } >> - return (fp->f_seekp); >> -} >> - >> -int >> -ufs_stat(struct open_file *f, struct stat *sb) >> -{ >> - struct file *fp = (struct file *)f->f_fsdata; >> - >> - /* only important stuff */ >> - sb->st_mode = fp->f_di.di_mode; >> - sb->st_uid = fp->f_di.di_uid; >> - sb->st_gid = fp->f_di.di_gid; >> - sb->st_size = fp->f_di.di_size; >> - return (0); >> -} >> - >> -#ifndef NO_READDIR >> -int >> -ufs_readdir(struct open_file *f, char *name) >> -{ >> - struct file *fp = (struct file *)f->f_fsdata; >> - struct direct *dp, *edp; >> - size_t buf_size; >> - int rc, namlen; >> - char *buf; >> - >> - if (name == NULL) >> - fp->f_seekp = 0; >> - else { >> - /* end of dir */ >> - if ((u_int64_t)fp->f_seekp >= fp->f_di.di_size) { >> - *name = '\0'; >> - return -1; >> - } >> - >> - do { >> - if ((rc = buf_read_file(f, &buf, &buf_size)) != 0) >> - return rc; >> - >> - dp = (struct direct *)buf; >> - edp = (struct direct *)(buf + buf_size); >> - while (dp < edp && dp->d_ino == 0) >> - dp = (struct direct *)((char *)dp + dp->d_reclen); >> - fp->f_seekp += buf_size - >> - ((u_int8_t *)edp - (u_int8_t *)dp); >> - } while (dp >= edp); >> - >> -#if BYTE_ORDER == LITTLE_ENDIAN >> - if (fp->f_fs->fs_maxsymlinklen <= 0) >> - namlen = dp->d_type; >> - else >> -#endif >> - namlen = dp->d_namlen; >> - strncpy(name, dp->d_name, namlen + 1); >> - >> - fp->f_seekp += dp->d_reclen; >> - } >> - >> - return 0; >> -} >> -#endif >> - >> -#ifdef COMPAT_UFS >> -/* >> - * Sanity checks for old file systems. >> - * >> - * XXX - goes away some day. >> - */ >> -static void >> -ffs_oldfscompat(struct fs *fs) >> -{ >> - int i; >> - >> - fs->fs_npsect = max(fs->fs_npsect, fs->fs_nsect); /* XXX */ >> - fs->fs_interleave = max(fs->fs_interleave, 1); /* XXX */ >> - if (fs->fs_postblformat == FS_42POSTBLFMT) /* XXX */ >> - fs->fs_nrpos = 8; /* XXX */ >> - if (fs->fs_inodefmt < FS_44INODEFMT) { /* XXX */ >> - quad_t sizepb = fs->fs_bsize; /* XXX */ >> - /* XXX */ >> - fs->fs_maxfilesize = fs->fs_bsize * NDADDR - 1; /* XXX */ >> - for (i = 0; i < NIADDR; i++) { /* XXX */ >> - sizepb *= NINDIR(fs); /* XXX */ >> - fs->fs_maxfilesize += sizepb; /* XXX */ >> - } /* XXX */ >> - fs->fs_qbmask = ~fs->fs_bmask; /* XXX */ >> - fs->fs_qfmask = ~fs->fs_fmask; /* XXX */ >> - } /* XXX */ >> -} >> -#endif >> Index: vm.c >> =================================================================== >> RCS file: /cvs/src/usr.sbin/vmd/vm.c,v >> retrieving revision 1.59 >> diff -u -p -u -p -r1.59 vm.c >> --- vm.c 13 Feb 2021 07:56:26 -0000 1.59 >> +++ vm.c 11 Mar 2021 22:10:22 -0000 >> @@ -278,7 +278,6 @@ start_vm(struct vmd_vm *vm, int fd) >> int nicfds[VMM_MAX_NICS_PER_VM]; >> int ret; >> FILE *fp; >> - struct vmboot_params vmboot; >> size_t i; >> struct vm_rwregs_params vrp; >> >> @@ -332,14 +331,11 @@ start_vm(struct vmd_vm *vm, int fd) >> memcpy(&vrs, &vcpu_init_flat64, sizeof(vrs)); >> >> /* Find and open kernel image */ >> - if ((fp = vmboot_open(vm->vm_kernel, >> - vm->vm_disks[0], vmc->vmc_diskbases[0], >> - vmc->vmc_disktypes[0], &vmboot)) == NULL) >> + if ((fp = fdopen(vm->vm_kernel, "r")) == NULL) >> fatalx("failed to open kernel - exiting"); >> >> /* Load kernel image */ >> - ret = loadfile_elf(fp, vcp, &vrs, >> - vmboot.vbp_bootdev, vmboot.vbp_howto, vmc->vmc_bootdevice); >> + ret = loadfile_elf(fp, vcp, &vrs); >> >> /* >> * Try BIOS as a fallback (only if it was provided as an image >> @@ -351,7 +347,8 @@ start_vm(struct vmd_vm *vm, int fd) >> if (ret) >> fatal("failed to load kernel or BIOS - exiting"); >> >> - vmboot_close(fp, &vmboot); >> + if (fp) >> + fclose(fp); >> } >> >> if (vm->vm_kernel != -1) >> Index: vmboot.c >> =================================================================== >> RCS file: vmboot.c >> diff -N vmboot.c >> --- vmboot.c 10 Dec 2020 16:58:03 -0000 1.8 >> +++ /dev/null 1 Jan 1970 00:00:00 -0000 >> @@ -1,501 +0,0 @@ >> -/* $OpenBSD: vmboot.c,v 1.8 2020/12/10 16:58:03 krw Exp $ */ >> - >> -/* >> - * Copyright (c) 2016 Reyk Floeter <r...@openbsd.org> >> - * >> - * Permission to use, copy, modify, and distribute this software for any >> - * purpose with or without fee is hereby granted, provided that the above >> - * copyright notice and this permission notice appear in all copies. >> - * >> - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES >> - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF >> - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR >> - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES >> - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN >> - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF >> - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. >> - */ >> - >> -#include <sys/param.h> /* DEV_BSIZE roundup */ >> -#include <sys/reboot.h> >> -#include <sys/time.h> >> -#include <sys/stat.h> >> -#include <sys/disklabel.h> >> - >> -#include <ufs/ffs/fs.h> >> -#include <ufs/ufs/dinode.h> >> -#include <ufs/ufs/dir.h> >> - >> -#include <stdio.h> >> -#include <unistd.h> >> -#include <ctype.h> >> -#include <fcntl.h> >> -#include <err.h> >> -#include <vis.h> >> - >> -#include "vmd.h" >> -#include "vmboot.h" >> -#include "virtio.h" >> - >> -int vmboot_bootconf(char *, size_t, struct vmboot_params *); >> -int vmboot_bootcmd(char *, struct vmboot_params *); >> -int vmboot_bootargs(int argc, char **argv, struct vmboot_params *); >> -uint32_t vmboot_bootdevice(const char *); >> - >> -int vmboot_strategy(void *, int, daddr_t, size_t, void *, size_t *); >> -off_t vmboot_findopenbsd(struct open_file *, off_t, struct disklabel *); >> -void *vmboot_loadfile(struct open_file *, char *, size_t *); >> - >> -int >> -vmboot_bootcmd(char *line, struct vmboot_params *bp) >> -{ >> - char *p, *args[16]; >> - int ac = 0; >> - char *last; >> - >> - for (args[0] = NULL, (p = strtok_r(line, " ", &last)); p; >> - (p = strtok_r(NULL, " ", &last))) { >> - if (ac < (int)(sizeof(args) / sizeof(args[0])) - 1) >> - args[ac++] = p; >> - } >> - if (ac == 0) >> - return (0); >> - args[ac] = NULL; >> - >> - /* >> - * Subset of boot.conf(8) options >> - */ >> - if (strcmp("boot", args[0]) == 0) >> - return (vmboot_bootargs(ac, args, bp)); >> - else if (strcmp("set", args[0]) == 0) { >> - if (ac < 3) >> - return (-1); >> - if (strcmp("device", args[1]) == 0) { >> - if ((size_t)strnvis(bp->vbp_device, args[2], >> - sizeof(bp->vbp_device), VIS_SAFE) >= >> - sizeof(bp->vbp_device)) { >> - log_warnx("invalid device name"); >> - return (-1); >> - } >> - } else if (strcmp("image", args[1]) == 0) { >> - if ((size_t)strnvis(bp->vbp_image, args[2], >> - sizeof(bp->vbp_image), VIS_SAFE) >= >> - sizeof(bp->vbp_image)) { >> - log_warnx("invalid image name"); >> - return (-1); >> - } >> - } >> - } >> - >> - return (0); >> -} >> - >> -int >> -vmboot_bootargs(int ac, char **av, struct vmboot_params *bp) >> -{ >> - char *p; >> - int ch; >> - >> - if (ac < 2) >> - return (0); >> - >> - /* >> - * Syntax is based on boot(8): boot "[hd0a[:/file]] [-asdc]" >> - */ >> - if (*av[1] != '-') { >> - if ((p = strchr(av[1], ':')) != NULL) { >> - *p++ = '\0'; >> - if (!strlen(p)) { >> - log_warnx("invalid file syntax"); >> - return (-1); >> - } >> - if ((size_t)strnvis(bp->vbp_device, av[1], >> - sizeof(bp->vbp_device), VIS_SAFE) >= >> - sizeof(bp->vbp_device)) { >> - log_warnx("invalid device name"); >> - return (-1); >> - } >> - } else { >> - p = av[1]; >> - } >> - if ((size_t)strnvis(bp->vbp_image, p, >> - sizeof(bp->vbp_image), VIS_SAFE) >= sizeof(bp->vbp_image)) { >> - log_warnx("invalid image name"); >> - return (-1); >> - } >> - ac--; >> - av++; >> - } >> - >> - optreset = optind = opterr = 1; >> - while ((ch = getopt(ac, av, "acds")) != -1) { >> - switch (ch) { >> - case 'a': >> - bp->vbp_howto |= RB_ASKNAME; >> - break; >> - case 'c': >> - bp->vbp_howto |= RB_CONFIG; >> - break; >> - case 'd': >> - bp->vbp_howto |= RB_KDB; >> - break; >> - case 's': >> - bp->vbp_howto |= RB_SINGLE; >> - break; >> - default: >> - log_warnx("invalid boot option: %c", ch); >> - return (-1); >> - } >> - } >> - >> - return (0); >> -} >> - >> -uint32_t >> -vmboot_bootdevice(const char *word) >> -{ >> - uint32_t bootdev = 0; >> - int disk, part; >> - >> - if (strlen(word) != strlen("hd0a")) { >> - log_warnx("invalid boot device: %s", word); >> - goto done; >> - } >> - >> - if (strncmp("hd", word, 2) != 0) { >> - log_warnx("unsupported boot device type: %s", word); >> - goto done; >> - } >> - >> - disk = (int)word[2]; >> - part = (int)word[3]; >> - >> - if (!(isdigit(disk) && isalpha(part) && islower(part))) { >> - log_warnx("invalid boot partition: %s", word); >> - goto done; >> - } >> - >> - disk -= '0'; >> - part -= 'a'; >> - >> - if (disk != 0 || part > MAXPARTITIONS) { >> - log_warnx("cannot boot from device: %s", word); >> - goto done; >> - } >> - >> - bootdev = MAKEBOOTDEV(0x4, 0, 0, disk, part); >> - >> - done: >> - /* returns 0 on error */ >> - return (bootdev); >> -} >> - >> -int >> -vmboot_bootconf(char *conf, size_t size, struct vmboot_params *bp) >> -{ >> - char buf[BUFSIZ]; >> - FILE *fp; >> - >> - if ((fp = fmemopen(conf, size, "r")) == NULL) { >> - log_debug("%s: failed to boot.conf memory stream", __func__); >> - return (-1); >> - } >> - >> - while (fgets(buf, sizeof(buf), fp) != NULL) { >> - buf[strcspn(buf, "\n")] = '\0'; >> - vmboot_bootcmd(buf, bp); >> - } >> - fclose(fp); >> - >> - if (strlen(bp->vbp_device)) >> - log_debug("%s: set device %s", __func__, bp->vbp_device); >> - if (strlen(bp->vbp_image)) >> - log_debug("%s: set image %s", __func__, bp->vbp_image); >> - if (bp->vbp_howto) { >> - snprintf(buf, sizeof(buf), "boot -%s%s%s%s", >> - (bp->vbp_howto & RB_ASKNAME) ? "a" : "", >> - (bp->vbp_howto & RB_CONFIG) ? "c" : "", >> - (bp->vbp_howto & RB_KDB) ? "d" : "", >> - (bp->vbp_howto & RB_SINGLE) ? "s" : ""); >> - log_debug("%s: %s", __func__, buf); >> - } >> - >> - return (0); >> -} >> - >> - >> -/* >> - * For ufs.c >> - */ >> - >> -struct devsw vmboot_devsw = { >> - .dv_name = "vmboot", >> - .dv_strategy = vmboot_strategy, >> - /* other fields are not needed */ >> -}; >> - >> -struct open_file vmboot_file = { >> - .f_dev = &vmboot_devsw, >> - .f_devdata = NULL >> -}; >> - >> -int >> -vmboot_strategy(void *devdata, int rw, >> - daddr_t blk, size_t size, void *buf, size_t *rsize) >> -{ >> - struct vmboot_params *vmboot = devdata; >> - struct virtio_backing *vfp = vmboot->vbp_arg; >> - ssize_t rlen; >> - off_t off; >> - >> - if (vfp == NULL) >> - return (EIO); >> - >> - off = (blk + vmboot->vbp_partoff) * DEV_BSIZE; >> - switch (rw) { >> - case F_READ: >> - rlen = vfp->pread(vfp->p, buf, size, off); >> - if (rlen == -1) >> - return (errno); >> - *rsize = (size_t)rlen; >> - break; >> - case F_WRITE: >> - rlen = vfp->pwrite(vfp->p, buf, size, off); >> - if (rlen == -1) >> - return (errno); >> - *rsize = (size_t)rlen; >> - break; >> - default: >> - return (EINVAL); >> - } >> - return (0); >> -} >> - >> -/* >> - * Based on findopenbsd() from biosdev.c that was partially written by me. >> - */ >> -off_t >> -vmboot_findopenbsd(struct open_file *f, off_t mbroff, struct disklabel *dl) >> -{ >> - struct dos_mbr mbr; >> - struct dos_partition *dp; >> - off_t mbr_eoff = DOSBBSECTOR, nextebr; >> - int ret, i; >> - static int maxebr = DOS_MAXEBR; >> - size_t rsize; >> - char buf[DEV_BSIZE], *msg; >> - >> - if (!maxebr--) { >> - log_debug("%s: too many extended partitions", __func__); >> - return (-1); >> - } >> - >> - memset(&mbr, 0, sizeof(mbr)); >> - ret = (f->f_dev->dv_strategy)(f->f_devdata, F_READ, >> - mbroff, sizeof(mbr), &mbr, &rsize); >> - if (ret != 0 || rsize != sizeof(mbr)) { >> - log_debug("%s: failed to read MBR", __func__); >> - return (-1); >> - } >> - >> - if (mbr.dmbr_sign != DOSMBR_SIGNATURE) { >> - log_debug("%s: bad MBR signature", __func__); >> - return (-1); >> - } >> - >> - /* Search for the first OpenBSD partition */ >> - nextebr = 0; >> - for (i = 0; i < NDOSPART; i++) { >> - dp = &mbr.dmbr_parts[i]; >> - if (!dp->dp_size) >> - continue; >> - >> - if (dp->dp_typ == DOSPTYP_OPENBSD) { >> - if (dp->dp_start > (dp->dp_start + mbroff)) >> - continue; >> - >> - /* Load and parse the disk label */ >> - ret = (f->f_dev->dv_strategy)(f->f_devdata, F_READ, >> - dp->dp_start + mbroff + DOS_LABELSECTOR, >> - sizeof(buf), buf, &rsize); >> - if (ret != 0 || rsize != sizeof(buf)) { >> - log_warn("could not load disk label"); >> - return (-1); >> - } >> - if ((msg = getdisklabel(buf, dl)) != NULL) { >> - log_warnx("%s", msg); >> - return (-1); >> - } >> - >> - return (dp->dp_start + mbroff); >> - } >> - >> - if (!nextebr && (dp->dp_typ == DOSPTYP_EXTEND || >> - dp->dp_typ == DOSPTYP_EXTENDL)) { >> - nextebr = dp->dp_start + mbr_eoff; >> - if (nextebr < dp->dp_start) >> - nextebr = -1; >> - if (mbr_eoff == DOSBBSECTOR) >> - mbr_eoff = dp->dp_start; >> - } >> - } >> - >> - if (nextebr && nextebr != -1) { >> - mbroff = nextebr; >> - return (vmboot_findopenbsd(f, mbroff, dl)); >> - } >> - >> - return (-1); >> -} >> - >> -void * >> -vmboot_loadfile(struct open_file *f, char *file, size_t *size) >> -{ >> - char *buf = NULL, *p = NULL; >> - struct stat st; >> - size_t rsize; >> - int ret; >> - >> - *size = 0; >> - >> - if ((ret = ufs_open(file, f)) != 0) >> - return (NULL); >> - >> - if ((ret = ufs_stat(f, &st)) != 0) { >> - log_debug("%s: failed to stat %s", __func__, file); >> - goto done; >> - } >> - >> - if ((buf = calloc(1, roundup(st.st_size, DEV_BSIZE))) == NULL) { >> - log_debug("%s: failed to allocate buffer", __func__); >> - goto done; >> - } >> - >> - if ((ret = ufs_read(f, buf, st.st_size, &rsize)) != 0) { >> - log_debug("%s: failed to read %s", __func__, file); >> - free(buf); >> - goto done; >> - } >> - >> - *size = st.st_size; >> - p = buf; >> - done: >> - ufs_close(f); >> - return (p); >> -} >> - >> -FILE * >> -vmboot_open(int kernel_fd, int *disk_fd, int nfd, unsigned int disk_type, >> - struct vmboot_params *vmboot) >> -{ >> - char file[PATH_MAX]; >> - char *buf = NULL; >> - size_t size; >> - FILE *fp = NULL; >> - struct disklabel dl; >> - struct virtio_backing *vfp; >> - off_t sz; >> - >> - memset(vmboot, 0, sizeof(*vmboot)); >> - memset(&vfp, 0, sizeof(vfp)); >> - memset(&dl, 0, sizeof(dl)); >> - >> - /* First open kernel directly if specified by fd */ >> - if (kernel_fd != -1) >> - return (fdopen(kernel_fd, "r")); >> - >> - if (disk_fd == NULL || nfd < 1) >> - return (NULL); >> - >> - if ((vfp = calloc(1, sizeof(*vfp))) == NULL) >> - goto fail; >> - vmboot->vbp_type = disk_type; >> - vmboot->vbp_arg = vfp; >> - >> - switch (vmboot->vbp_type) { >> - case VMDF_RAW: >> - 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_qcow2_init(vfp, &sz, disk_fd, nfd) == -1) { >> - log_debug("%s: could not open qcow2 disk", __func__); >> - goto fail; >> - } >> - break; >> - } >> - >> - vmboot_file.f_devdata = vmboot; >> - >> - if ((vmboot->vbp_partoff = >> - vmboot_findopenbsd(&vmboot_file, 0, &dl)) == -1) { >> - log_debug("%s: could not find openbsd partition", __func__); >> - goto fail; >> - } >> - >> - /* Set the default kernel boot device and image path */ >> - strlcpy(vmboot->vbp_device, VM_DEFAULT_DEVICE, >> - sizeof(vmboot->vbp_device)); >> - strlcpy(vmboot->vbp_image, VM_DEFAULT_KERNEL, >> - sizeof(vmboot->vbp_image)); >> - >> - /* Try to parse boot.conf to overwrite the default kernel path */ >> - strlcpy(file, VM_BOOT_CONF, sizeof(file)); >> - if ((buf = vmboot_loadfile(&vmboot_file, file, &size)) != NULL) { >> - if (vmboot_bootconf(buf, size, vmboot) == -1) { >> - free(buf); >> - goto fail; >> - } >> - free(buf); >> - } >> - >> - /* Parse boot device and find partition in disk label */ >> - if ((vmboot->vbp_bootdev = >> - vmboot_bootdevice(vmboot->vbp_device)) == 0) >> - goto fail; >> - if (B_PARTITION(vmboot->vbp_bootdev) > dl.d_npartitions) { >> - log_debug("%s: invalid boot partition: %s", >> - __func__, vmboot->vbp_device); >> - goto fail; >> - } >> - vmboot->vbp_partoff = >> - dl.d_partitions[B_PARTITION(vmboot->vbp_bootdev)].p_offset; >> - >> - /* Load the kernel */ >> - if ((buf = vmboot_loadfile(&vmboot_file, >> - vmboot->vbp_image, &size)) == NULL) { >> - log_debug("%s: failed to open kernel %s:%s", __func__, >> - vmboot->vbp_device, vmboot->vbp_image); >> - goto fail; >> - } >> - vmboot->vbp_buf = buf; >> - >> - if ((fp = fmemopen(buf, size, "r")) == NULL) { >> - log_debug("%s: failed to open memory stream", __func__); >> - free(buf); >> - vmboot->vbp_buf = NULL; >> - } else { >> - log_debug("%s: kernel %s:%s", __func__, >> - vmboot->vbp_device, vmboot->vbp_image); >> - } >> - >> - return (fp); >> - fail: >> - vmboot_close(fp, vmboot); >> - return (NULL); >> -} >> - >> -void >> -vmboot_close(FILE *fp, struct vmboot_params *vmboot) >> -{ >> - struct virtio_backing *vfp = vmboot->vbp_arg; >> - >> - if (fp != NULL) >> - fclose(fp); >> - if (vfp != NULL) >> - vfp->close(vfp->p, 1); >> - free(vmboot->vbp_arg); >> - free(vmboot->vbp_buf); >> -} >> Index: vmboot.h >> =================================================================== >> RCS file: vmboot.h >> diff -N vmboot.h >> --- vmboot.h 10 Dec 2020 16:58:03 -0000 1.3 >> +++ /dev/null 1 Jan 1970 00:00:00 -0000 >> @@ -1,75 +0,0 @@ >> -/* $OpenBSD: vmboot.h,v 1.3 2020/12/10 16:58:03 krw Exp $ */ >> - >> -/* >> - * Copyright (c) 2016 Reyk Floeter <r...@openbsd.org> >> - * >> - * Permission to use, copy, modify, and distribute this software for any >> - * purpose with or without fee is hereby granted, provided that the above >> - * copyright notice and this permission notice appear in all copies. >> - * >> - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES >> - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF >> - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR >> - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES >> - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN >> - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF >> - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. >> - */ >> - >> -#include <sys/types.h> >> -#include <sys/stat.h> >> -#include <sys/stdarg.h> >> -#include <sys/stdint.h> >> - >> -#include <errno.h> >> -#include <string.h> >> -#include <stdlib.h> >> -#include <stdio.h> >> - >> -#ifndef VMBOOT_H >> -#define VMBOOT_H >> - >> -#define F_READ 1 >> -#define F_WRITE 2 >> - >> -struct open_file; >> - >> -struct fs_ops { >> - int (*open)(char *, struct open_file *); >> - int (*close)(struct open_file *); >> - int (*read)(struct open_file *, void *, size_t, size_t *); >> - int (*write)(struct open_file *, void *, size_t, size_t *); >> - off_t (*seek)(struct open_file *, off_t, int); >> - int (*stat)(struct open_file *, struct stat *); >> - int (*readdir)(struct open_file *, char *); >> -}; >> - >> -struct devsw { >> - char *dv_name; >> - int (*dv_strategy)(void *, int, daddr_t, size_t, >> - void *, size_t *); >> -}; >> - >> -struct open_file { >> - int f_flags; >> - struct devsw *f_dev; >> - void *f_devdata; >> - struct fs_ops *f_ops; >> - void *f_fsdata; >> - off_t f_offset; >> -}; >> - >> -struct disklabel; >> - >> -u_int dkcksum(struct disklabel *); >> -char *getdisklabel(char *, struct disklabel *); >> - >> -int ufs_open(char *, struct open_file *); >> -int ufs_close(struct open_file *); >> -int ufs_read(struct open_file *, void *, size_t, size_t *); >> -int ufs_write(struct open_file *, void *, size_t, size_t *); >> -off_t ufs_seek(struct open_file *, off_t offset, int); >> -int ufs_stat(struct open_file *, struct stat *); >> -int ufs_readdir(struct open_file *, char *); >> - >> -#endif /* VMBOOT_H */ >> Index: vmd.h >> =================================================================== >> RCS file: /cvs/src/usr.sbin/vmd/vmd.h,v >> retrieving revision 1.101 >> diff -u -p -u -p -r1.101 vmd.h >> --- vmd.h 23 Sep 2020 19:18:18 -0000 1.101 >> +++ vmd.h 11 Mar 2021 22:10:23 -0000 >> @@ -228,8 +228,6 @@ struct vmboot_params { >> off_t vbp_partoff; >> char vbp_device[PATH_MAX]; >> char vbp_image[PATH_MAX]; >> - uint32_t vbp_bootdev; >> - uint32_t vbp_howto; >> unsigned int vbp_type; >> void *vbp_arg; >> char *vbp_buf; >> >