1/* $NetBSD: rump_nqmfs.c,v 1.2 2010/03/31 14:49:02 pooka Exp $ */ 2 3/* 4 * Copyright (c) 2010 Antti Kantee. All Rights Reserved. 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions 8 * are met: 9 * 1. Redistributions of source code must retain the above copyright 10 * notice, this list of conditions and the following disclaimer. 11 * 2. Redistributions in binary form must reproduce the above copyright 12 * notice, this list of conditions and the following disclaimer in the 13 * documentation and/or other materials provided with the distribution. 14 * 15 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS 16 * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 17 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 18 * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 19 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 20 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 21 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 22 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 23 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 24 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 25 * SUCH DAMAGE. 26 */ 27 28/* 29 * Not Quite MFS. Instead of allocating memory and creating a FFS file system 30 * there, mmap a file (which should contain ffs) and use that as the backend. 31 * You can also give a newly created image as the file ... 32 */ 33 34#include <sys/types.h> 35#include <sys/mman.h> 36#include <sys/mount.h> 37#include <sys/stat.h> 38 39#include <ufs/ufs/ufsmount.h> 40 41#include <err.h> 42#include <mntopts.h> 43#include <puffs.h> 44#include <stdio.h> 45#include <stdlib.h> 46#include <unistd.h> 47 48#include <rump/p2k.h> 49#include <rump/ukfs.h> 50 51const struct mntopt mopts[] = { 52 MOPT_STDOPTS, 53 MOPT_NULL, 54}; 55 56static void 57usage(void) 58{ 59 60 fprintf(stderr, "%s: [-o args] fspec mountpoint\n", getprogname()); 61 exit(1); 62} 63 64static struct mfs_args args; 65static char *mntpath, *mntfile; 66static int mntflags, altflags; 67 68int 69main(int argc, char *argv[]) 70{ 71 struct stat sb; 72 mntoptparse_t mp; 73 void *membase; 74 int ch, fd, rdonly, shared; 75 76 setprogname(argv[0]); 77 puffs_unmountonsignal(SIGINT, true); 78 puffs_unmountonsignal(SIGTERM, true); 79 80 shared = mntflags = altflags = 0; 81 82 memset(&args, 0, sizeof(args)); 83 while ((ch = getopt(argc, argv, "o:s")) != -1) { 84 switch (ch) { 85 case 'o': 86 mp = getmntopts(optarg, mopts, &mntflags, &altflags); 87 if (mp == NULL) 88 err(1, "getmntopts"); 89 freemntopts(mp); 90 break; 91 case 's': 92 shared = 1; 93 break; 94 default: 95 usage(); 96 break; 97 } 98 } 99 argc -= optind; 100 argv += optind; 101 102 if (argc != 2) 103 usage(); 104 mntfile = argv[0]; 105 mntpath = argv[1]; 106 rdonly = mntflags & MNT_RDONLY; 107 108 if (stat(mntfile, &sb) == -1) 109 err(1, "stat fspec"); 110 if (!S_ISREG(sb.st_mode)) 111 errx(1, "fspec must be a regular file"); 112 113 fd = open(mntfile, rdonly ? O_RDONLY: O_RDWR); 114 if (fd == -1) 115 err(1, "open fspec"); 116 117 membase = mmap(NULL, sb.st_size, PROT_READ | (rdonly ? 0 : PROT_WRITE), 118 MAP_FILE | (shared ? MAP_SHARED : MAP_PRIVATE), fd, 0); 119 if (membase == MAP_FAILED) 120 err(1, "cannot mmap fspec"); 121 122 args.fspec = mntfile; 123 args.base = membase; 124 args.size = sb.st_size; 125 126 if (p2k_run_fs(MOUNT_MFS, "/swabbie", mntpath, 127 0, &args, sizeof(args), 0) == -1) 128 err(1, "p2k"); 129 130 return 0; 131} 132