On Wed, Mar 17, 2021 at 10:29:32PM +0100, Klemens Nanni wrote:
> On Sun, Mar 14, 2021 at 11:00:22AM -0400, Dave Voutila wrote:
> > Any takers?
> Yes, I plan to commit the updated diff at the end until friday
> unless someone objects.
>

no objection, thanks everyone.

ok mlarkin

> > Here's an updated diff also removes some logic in config.c related to
> > checking the value sent by vmctl(8)'s -b flag to see if it's the same as
> > the root disk image (-d).
> Both your first and this diff fail to apply, see inline.
>
> I've fixed both and tested the following diff (incl. mail to myself and
> apply from there).
>
> > 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        14 Mar 2021 14:56:06 -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
> You remove disklabel.c here but not with `cvs rm';
> fixed in the diff below.
>
> >  SRCS+=             parse.y atomicio.c vioscsi.c vioraw.c vioqcow2.c 
> > fw_cfg.c
> >
> >  CFLAGS+=   -Wall -I${.CURDIR}
>
> > 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  14 Mar 2021 14:56:06 -0000
>
> > @@ -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);
> > -   }
> This line in the file ends with a single whitespace, but your diff does
> not have it;
> fixed in the diff below.
>
> > -
> >     ba[i++] = 0xFFFFFFFF; /* BOOTARG_END */
> >
> >     write_mem(BOOTARGS_PAGE, ba, PAGE_SIZE);
>
>
>
> Index: Makefile
> ===================================================================
> RCS file: /cvs/src/usr.sbin/vmd/Makefile,v
> retrieving revision 1.24
> diff -u -p -r1.24 Makefile
> --- Makefile  23 Sep 2020 19:18:18 -0000      1.24
> +++ Makefile  17 Mar 2021 21:04:06 -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: config.c
> ===================================================================
> RCS file: /cvs/src/usr.sbin/vmd/config.c,v
> retrieving revision 1.59
> diff -u -p -r1.59 config.c
> --- config.c  28 Feb 2021 22:56:09 -0000      1.59
> +++ config.c  17 Mar 2021 21:04:06 -0000
> @@ -216,7 +216,7 @@ config_setvm(struct privsep *ps, struct
>       struct vmop_create_params *vmc = &vm->vm_params;
>       struct vm_create_params *vcp = &vmc->vmc_params;
>       unsigned int             i, j;
> -     int                      fd = -1, vmboot = 0;
> +     int                      fd = -1;
>       int                      kernfd = -1;
>       int                     *tapfds = NULL;
>       int                      cdromfd = -1;
> @@ -295,16 +295,8 @@ config_setvm(struct privsep *ps, struct
>
>       if (!(vm->vm_state & VM_STATE_RECEIVED)) {
>               if (strlen(vcp->vcp_kernel)) {
> -                     /*
> -                      * Boot kernel from disk image if path matches the
> -                      * root disk.
> -                      */
> -                     if (vcp->vcp_ndisks &&
> -                         strcmp(vcp->vcp_kernel, vcp->vcp_disks[0]) == 0)
> -                             vmboot = 1;
>                       /* Open external kernel for child */
> -                     else if ((kernfd =
> -                         open(vcp->vcp_kernel, O_RDONLY)) == -1) {
> +                     if ((kernfd = open(vcp->vcp_kernel, O_RDONLY)) == -1) {
>                               log_warn("%s: can't open kernel or BIOS "
>                                   "boot image %s", __func__, vcp->vcp_kernel);
>                               goto fail;
> @@ -317,14 +309,14 @@ config_setvm(struct privsep *ps, struct
>                * typically distributed separately due to an incompatible
>                * license.
>                */
> -             if (kernfd == -1 && !vmboot &&
> +             if (kernfd == -1 &&
>                   (kernfd = open(VM_DEFAULT_BIOS, O_RDONLY)) == -1) {
>                       log_warn("can't open %s", VM_DEFAULT_BIOS);
>                       errno = VMD_BIOS_MISSING;
>                       goto fail;
>               }
>
> -             if (!vmboot && vm_checkaccess(kernfd,
> +             if (vm_checkaccess(kernfd,
>                   vmc->vmc_checkaccess & VMOP_CREATE_KERNEL,
>                   uid, R_OK) == -1) {
>                       log_warnx("vm \"%s\" no read access to kernel %s",
> Index: disklabel.c
> ===================================================================
> RCS file: disklabel.c
> diff -N disklabel.c
> --- disklabel.c       29 Aug 2017 21:10:20 -0000      1.2
> +++ /dev/null 1 Jan 1970 00:00:00 -0000
> @@ -1,78 +0,0 @@
> -/*   $OpenBSD: disklabel.c,v 1.2 2017/08/29 21:10:20 deraadt Exp $   */
> -/*   $NetBSD: disklabel.c,v 1.3 1994/10/26 05:44:42 cgd Exp $        */
> -
> -/*-
> - * Copyright (c) 1993
> - *   The Regents of the University of California.  All rights reserved.
> - *
> - * 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.
> - *
> - *   @(#)disklabel.c 8.1 (Berkeley) 6/11/93
> - */
> -
> -#include <sys/param.h>       /* DEV_BSIZE */
> -#include <sys/disklabel.h>
> -#include "vmboot.h"
> -
> -/*
> - * Compute checksum for disk label.
> - */
> -u_int
> -dkcksum(struct disklabel *lp)
> -{
> -     const u_short *start, *end;
> -     u_short sum = 0;
> -
> -     start = (u_short *)lp;
> -     end = (u_short *)&lp->d_partitions[lp->d_npartitions];
> -     while (start < end)
> -             sum ^= *start++;
> -     return (sum);
> -}
> -
> -char *
> -getdisklabel(char *buf, struct disklabel *lp)
> -{
> -     struct disklabel *dlp, *elp;
> -     char *msg = NULL;
> -
> -     elp = (struct disklabel *)(buf + DEV_BSIZE - sizeof(*dlp));
> -     for (dlp = (struct disklabel *)buf; dlp <= elp;
> -         dlp = (struct disklabel *)((char *)dlp + sizeof(long))) {
> -             if (dlp->d_magic != DISKMAGIC || dlp->d_magic2 != DISKMAGIC) {
> -                     if (msg == NULL)
> -                             msg = "no disk label";
> -             } else if (dlp->d_npartitions > MAXPARTITIONS ||
> -                        dkcksum(dlp) != 0)
> -                     msg = "disk label corrupted";
> -             else {
> -                     *lp = *dlp;
> -                     msg = NULL;
> -                     break;
> -             }
> -     }
> -     return (msg);
> -}
> -
> Index: loadfile.h
> ===================================================================
> RCS file: /cvs/src/usr.sbin/vmd/loadfile.h,v
> retrieving revision 1.12
> diff -u -p -r1.12 loadfile.h
> --- loadfile.h        16 May 2019 21:16:04 -0000      1.12
> +++ loadfile.h        17 Mar 2021 21:04:06 -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 -r1.36 loadfile_elf.c
> --- loadfile_elf.c    26 Oct 2020 04:04:31 -0000      1.36
> +++ loadfile_elf.c    17 Mar 2021 21:05:19 -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 -r1.59 vm.c
> --- vm.c      13 Feb 2021 07:56:26 -0000      1.59
> +++ vm.c      17 Mar 2021 21:04:07 -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 -r1.101 vmd.h
> --- vmd.h     23 Sep 2020 19:18:18 -0000      1.101
> +++ vmd.h     17 Mar 2021 21:04:07 -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;
>

Reply via email to