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 > -- > -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; >