userboot_disk.c revision 223695
1223695Sdfr/*- 2223695Sdfr * Copyright (c) 2011 Google, Inc. 3223695Sdfr * All rights reserved. 4223695Sdfr * 5223695Sdfr * Redistribution and use in source and binary forms, with or without 6223695Sdfr * modification, are permitted provided that the following conditions 7223695Sdfr * are met: 8223695Sdfr * 1. Redistributions of source code must retain the above copyright 9223695Sdfr * notice, this list of conditions and the following disclaimer. 10223695Sdfr * 2. Redistributions in binary form must reproduce the above copyright 11223695Sdfr * notice, this list of conditions and the following disclaimer in the 12223695Sdfr * documentation and/or other materials provided with the distribution. 13223695Sdfr * 14223695Sdfr * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 15223695Sdfr * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16223695Sdfr * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17223695Sdfr * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 18223695Sdfr * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19223695Sdfr * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 20223695Sdfr * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21223695Sdfr * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22223695Sdfr * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23223695Sdfr * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24223695Sdfr * SUCH DAMAGE. 25223695Sdfr */ 26223695Sdfr 27223695Sdfr#include <sys/cdefs.h> 28223695Sdfr__FBSDID("$FreeBSD: head/sys/boot/userboot/userboot/userboot_disk.c 223695 2011-06-30 16:08:56Z dfr $"); 29223695Sdfr 30223695Sdfr/* 31223695Sdfr * Userboot disk image handling. 32223695Sdfr */ 33223695Sdfr 34223695Sdfr#include <stand.h> 35223695Sdfr 36223695Sdfr#include <stdarg.h> 37223695Sdfr#include <uuid.h> 38223695Sdfr 39223695Sdfr#include <bootstrap.h> 40223695Sdfr 41223695Sdfr#include "disk.h" 42223695Sdfr#include "libuserboot.h" 43223695Sdfr 44223695Sdfrint userboot_disk_maxunit = 0; 45223695Sdfr 46223695Sdfrstatic int userdisk_init(void); 47223695Sdfrstatic int userdisk_strategy(void *devdata, int flag, daddr_t dblk, 48223695Sdfr size_t size, char *buf, size_t *rsize); 49223695Sdfrstatic int userdisk_open(struct open_file *f, ...); 50223695Sdfrstatic int userdisk_close(struct open_file *f); 51223695Sdfrstatic void userdisk_print(int verbose); 52223695Sdfr 53223695Sdfrstruct devsw userboot_disk = { 54223695Sdfr "disk", 55223695Sdfr DEVT_DISK, 56223695Sdfr userdisk_init, 57223695Sdfr userdisk_strategy, 58223695Sdfr userdisk_open, 59223695Sdfr userdisk_close, 60223695Sdfr noioctl, 61223695Sdfr userdisk_print, 62223695Sdfr NULL 63223695Sdfr}; 64223695Sdfr 65223695Sdfr/* 66223695Sdfr * Nothing to do here. 67223695Sdfr */ 68223695Sdfrstatic int 69223695Sdfruserdisk_init(void) 70223695Sdfr{ 71223695Sdfr 72223695Sdfr return(0); 73223695Sdfr} 74223695Sdfr 75223695Sdfr/* 76223695Sdfr * Print information about disks 77223695Sdfr */ 78223695Sdfrstatic void 79223695Sdfruserdisk_print(int verbose) 80223695Sdfr{ 81223695Sdfr int i; 82223695Sdfr char line[80]; 83223695Sdfr struct disk_devdesc dev; 84223695Sdfr 85223695Sdfr for (i = 0; i < userboot_disk_maxunit; i++) { 86223695Sdfr sprintf(line, " disk%d: Guest drive image\n", i); 87223695Sdfr pager_output(line); 88223695Sdfr dev.d_dev = &userboot_disk; 89223695Sdfr dev.d_unit = i; 90223695Sdfr dev.d_slice = -1; 91223695Sdfr dev.d_partition = -1; 92223695Sdfr dev.d_offset = 0; 93223695Sdfr sprintf(line, " disk%d", i); 94223695Sdfr disk_print(&dev, line, verbose); 95223695Sdfr } 96223695Sdfr} 97223695Sdfr 98223695Sdfr/* 99223695Sdfr * Attempt to open the disk described by (dev) for use by (f). 100223695Sdfr */ 101223695Sdfrstatic int 102223695Sdfruserdisk_open(struct open_file *f, ...) 103223695Sdfr{ 104223695Sdfr va_list ap; 105223695Sdfr struct disk_devdesc *dev; 106223695Sdfr 107223695Sdfr va_start(ap, f); 108223695Sdfr dev = va_arg(ap, struct disk_devdesc *); 109223695Sdfr va_end(ap); 110223695Sdfr 111223695Sdfr if (dev->d_unit < 0 || dev->d_unit >= userboot_disk_maxunit) 112223695Sdfr return (EIO); 113223695Sdfr 114223695Sdfr return (disk_open(dev)); 115223695Sdfr} 116223695Sdfr 117223695Sdfrstatic int 118223695Sdfruserdisk_close(struct open_file *f) 119223695Sdfr{ 120223695Sdfr 121223695Sdfr return(0); 122223695Sdfr} 123223695Sdfr 124223695Sdfrstatic int 125223695Sdfruserdisk_strategy(void *devdata, int rw, daddr_t dblk, size_t size, 126223695Sdfr char *buf, size_t *rsize) 127223695Sdfr{ 128223695Sdfr struct disk_devdesc *dev = devdata; 129223695Sdfr uint64_t off; 130223695Sdfr size_t resid; 131223695Sdfr int rc; 132223695Sdfr 133223695Sdfr if (rw == F_WRITE) 134223695Sdfr return (EROFS); 135223695Sdfr if (rw != F_READ) 136223695Sdfr return (EINVAL); 137223695Sdfr if (rsize) 138223695Sdfr *rsize = 0; 139223695Sdfr off = (dblk + dev->d_offset) * DISK_SECSIZE; 140223695Sdfr rc = CALLBACK(diskread, dev->d_unit, off, buf, size, &resid); 141223695Sdfr if (rc) 142223695Sdfr return (rc); 143223695Sdfr if (rsize) 144223695Sdfr *rsize = size - resid; 145223695Sdfr return (0); 146223695Sdfr} 147