1 1.5 pho /* $NetBSD: mount_puffs.c,v 1.5 2016/11/23 14:33:29 pho Exp $ */ 2 1.1 pooka 3 1.1 pooka /* 4 1.1 pooka * Copyright (c) 2010 Antti Kantee. All Rights Reserved. 5 1.1 pooka * 6 1.1 pooka * Redistribution and use in source and binary forms, with or without 7 1.1 pooka * modification, are permitted provided that the following conditions 8 1.1 pooka * are met: 9 1.1 pooka * 1. Redistributions of source code must retain the above copyright 10 1.1 pooka * notice, this list of conditions and the following disclaimer. 11 1.1 pooka * 2. Redistributions in binary form must reproduce the above copyright 12 1.1 pooka * notice, this list of conditions and the following disclaimer in the 13 1.1 pooka * documentation and/or other materials provided with the distribution. 14 1.1 pooka * 15 1.1 pooka * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS 16 1.1 pooka * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 17 1.1 pooka * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 18 1.1 pooka * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 19 1.1 pooka * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 20 1.1 pooka * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 21 1.1 pooka * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 22 1.1 pooka * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 23 1.1 pooka * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 24 1.1 pooka * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 25 1.1 pooka * SUCH DAMAGE. 26 1.1 pooka */ 27 1.1 pooka 28 1.1 pooka /* 29 1.5 pho * This is to support -o getargs without having to replicate it in 30 1.5 pho * every file server. It also allows puffs filesystems to be mounted 31 1.5 pho * via "mount -a". 32 1.1 pooka */ 33 1.1 pooka 34 1.1 pooka #include <sys/cdefs.h> 35 1.1 pooka #ifndef lint 36 1.5 pho __RCSID("$NetBSD: mount_puffs.c,v 1.5 2016/11/23 14:33:29 pho Exp $"); 37 1.1 pooka #endif /* !lint */ 38 1.1 pooka 39 1.1 pooka #include <sys/param.h> 40 1.1 pooka #include <sys/mount.h> 41 1.1 pooka 42 1.1 pooka #include <fs/puffs/puffs_msgif.h> 43 1.1 pooka 44 1.1 pooka #include <err.h> 45 1.1 pooka #include <stdio.h> 46 1.1 pooka #include <stdlib.h> 47 1.5 pho #include <string.h> 48 1.5 pho #include <sys/cdefs.h> 49 1.1 pooka #include <unistd.h> 50 1.5 pho #include <util.h> 51 1.1 pooka 52 1.5 pho static int 53 1.1 pooka usage(void) 54 1.1 pooka { 55 1.1 pooka 56 1.5 pho fprintf(stderr, "usage: %s [-o options] program[#source] mountpoint\n", getprogname()); 57 1.5 pho return 1; 58 1.1 pooka } 59 1.1 pooka 60 1.5 pho static int show_puffs_mount_args(const char *mountpoint) 61 1.1 pooka { 62 1.1 pooka const char *vtypes[] = { VNODE_TYPES }; 63 1.1 pooka struct puffs_kargs kargs; 64 1.1 pooka 65 1.5 pho if (mount(MOUNT_PUFFS, mountpoint, MNT_GETARGS, &kargs, sizeof(kargs)) == -1) 66 1.5 pho err(1, "mount"); 67 1.1 pooka 68 1.3 pooka printf("version=%d, ", kargs.pa_vers); 69 1.1 pooka printf("flags=0x%x, ", kargs.pa_flags); 70 1.1 pooka 71 1.1 pooka printf("root cookie=%p, ", kargs.pa_root_cookie); 72 1.1 pooka printf("root type=%s", vtypes[kargs.pa_root_vtype]); 73 1.1 pooka 74 1.1 pooka if (kargs.pa_root_vtype != VDIR) 75 1.1 pooka printf(", root size=%llu", 76 1.1 pooka (unsigned long long)kargs.pa_root_vsize); 77 1.1 pooka if (kargs.pa_root_vtype == VCHR || kargs.pa_root_vtype == VBLK) 78 1.1 pooka printf(", root rdev=0x%" PRIx64, (uint64_t)kargs.pa_root_rdev); 79 1.1 pooka printf("\n"); 80 1.2 pooka 81 1.2 pooka return 0; 82 1.1 pooka } 83 1.5 pho 84 1.5 pho static int 85 1.5 pho mount_puffs_filesystem(const char *program, const char *opts, 86 1.5 pho const char *source, const char *mountpoint) 87 1.5 pho { 88 1.5 pho int argc = 0; 89 1.5 pho const char **argv; 90 1.5 pho int rv = 0; 91 1.5 pho 92 1.5 pho /* Construct an argument vector: 93 1.5 pho * program [-o opts] [source] mountpoint */ 94 1.5 pho argv = ecalloc(1 + 2 + 1 + 1, sizeof(*argv)); 95 1.5 pho argv[argc++] = program; 96 1.5 pho if (opts != NULL) { 97 1.5 pho argv[argc++] = "-o"; 98 1.5 pho argv[argc++] = opts; 99 1.5 pho } 100 1.5 pho if (source != NULL) { 101 1.5 pho argv[argc++] = source; 102 1.5 pho } 103 1.5 pho argv[argc++] = mountpoint; 104 1.5 pho argv[argc] = NULL; 105 1.5 pho 106 1.5 pho /* We intentionally use execvp(3) here because the program can 107 1.5 pho * actually be a basename. */ 108 1.5 pho if (execvp(program, __UNCONST(argv)) == -1) { 109 1.5 pho warn("Cannot execute %s", program); 110 1.5 pho rv = 1; 111 1.5 pho } 112 1.5 pho 113 1.5 pho free(argv); 114 1.5 pho return rv; 115 1.5 pho } 116 1.5 pho 117 1.5 pho static void add_opt(char **opts, const char *opt) 118 1.5 pho { 119 1.5 pho const size_t orig_len = *opts == NULL ? 0 : strlen(*opts); 120 1.5 pho 121 1.5 pho *opts = erealloc(*opts, orig_len + 1 + strlen(opt) + 1); 122 1.5 pho 123 1.5 pho if (orig_len == 0) { 124 1.5 pho strcpy(*opts, opt); 125 1.5 pho } 126 1.5 pho else { 127 1.5 pho strcat(*opts, ","); 128 1.5 pho strcat(*opts, opt); 129 1.5 pho } 130 1.5 pho } 131 1.5 pho 132 1.5 pho int 133 1.5 pho main(int argc, char *argv[]) 134 1.5 pho { 135 1.5 pho int mntflags = 0; 136 1.5 pho int ch; 137 1.5 pho char *opts = NULL; 138 1.5 pho int rv = 0; 139 1.5 pho 140 1.5 pho while ((ch = getopt(argc, argv, "o:")) != -1) { 141 1.5 pho switch (ch) { 142 1.5 pho case 'o': 143 1.5 pho for (char *opt = optarg; (opt = strtok(opt, ",")) != NULL; opt = NULL) { 144 1.5 pho if (strcmp(opt, "getargs") == 0) { 145 1.5 pho mntflags |= MNT_GETARGS; 146 1.5 pho break; /* No need to parse it any further. */ 147 1.5 pho } 148 1.5 pho else { 149 1.5 pho add_opt(&opts, opt); 150 1.5 pho } 151 1.5 pho } 152 1.5 pho break; 153 1.5 pho default: 154 1.5 pho rv = usage(); 155 1.5 pho goto free_opts; 156 1.5 pho } 157 1.5 pho } 158 1.5 pho argc -= optind; 159 1.5 pho argv += optind; 160 1.5 pho 161 1.5 pho if (argc != 2) { 162 1.5 pho rv = usage(); 163 1.5 pho goto free_opts; 164 1.5 pho } 165 1.5 pho 166 1.5 pho if (mntflags & MNT_GETARGS) { 167 1.5 pho /* Special case for -o getargs: retrieve kernel arguments for 168 1.5 pho * an already mounted filesystem. */ 169 1.5 pho rv = show_puffs_mount_args(argv[1]); 170 1.5 pho } 171 1.5 pho else { 172 1.5 pho /* Split the program name and source. This is to allow 173 1.5 pho * filesystems to be mounted via "mount -a" i.e. /etc/fstab */ 174 1.5 pho char *source = argv[0]; 175 1.5 pho char *program = strsep(&source, "#"); 176 1.5 pho 177 1.5 pho rv = mount_puffs_filesystem(program, opts, source, argv[1]); 178 1.5 pho } 179 1.5 pho 180 1.5 pho free_opts: 181 1.5 pho free(opts); 182 1.5 pho return rv; 183 1.5 pho } 184