Mike Larkin writes:
> 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 > Any takers? 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). -Dave 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 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 -u -p -r1.59 config.c --- config.c 28 Feb 2021 22:56:09 -0000 1.59 +++ config.c 14 Mar 2021 14:56: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: 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 14 Mar 2021 14:56: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 -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 @@ -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: /cvs/src/usr.sbin/vmd/ufs.c,v retrieving revision 1.6 diff -u -p -u -p -r1.6 ufs.c --- ufs.c 7 Oct 2017 19:48:30 -0000 1.6 +++ ufs.c 14 Mar 2021 14:56:06 -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 14 Mar 2021 14:56:06 -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: /cvs/src/usr.sbin/vmd/vmboot.c,v retrieving revision 1.8 diff -u -p -u -p -r1.8 vmboot.c --- vmboot.c 10 Dec 2020 16:58:03 -0000 1.8 +++ vmboot.c 14 Mar 2021 14:56:06 -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: /cvs/src/usr.sbin/vmd/vmboot.h,v retrieving revision 1.3 diff -u -p -u -p -r1.3 vmboot.h --- vmboot.h 10 Dec 2020 16:58:03 -0000 1.3 +++ vmboot.h 14 Mar 2021 14:56:06 -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 14 Mar 2021 14:56:06 -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;