1 1.4 yamt /* $NetBSD: mount.c,v 1.4 2013/04/22 13:28:28 yamt Exp $ */ 2 1.1 yamt 3 1.1 yamt /*- 4 1.1 yamt * Copyright (c)2010,2011 YAMAMOTO Takashi, 5 1.1 yamt * All rights reserved. 6 1.1 yamt * 7 1.1 yamt * Redistribution and use in source and binary forms, with or without 8 1.1 yamt * modification, are permitted provided that the following conditions 9 1.1 yamt * are met: 10 1.1 yamt * 1. Redistributions of source code must retain the above copyright 11 1.1 yamt * notice, this list of conditions and the following disclaimer. 12 1.1 yamt * 2. Redistributions in binary form must reproduce the above copyright 13 1.1 yamt * notice, this list of conditions and the following disclaimer in the 14 1.1 yamt * documentation and/or other materials provided with the distribution. 15 1.1 yamt * 16 1.1 yamt * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 17 1.1 yamt * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 18 1.1 yamt * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 19 1.1 yamt * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 20 1.1 yamt * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 21 1.1 yamt * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 22 1.1 yamt * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 23 1.1 yamt * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 24 1.1 yamt * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 25 1.1 yamt * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 26 1.1 yamt * SUCH DAMAGE. 27 1.1 yamt */ 28 1.1 yamt 29 1.1 yamt #include <sys/cdefs.h> 30 1.1 yamt #ifndef lint 31 1.4 yamt __RCSID("$NetBSD: mount.c,v 1.4 2013/04/22 13:28:28 yamt Exp $"); 32 1.1 yamt #endif /* not lint */ 33 1.1 yamt 34 1.1 yamt #include <err.h> 35 1.1 yamt #include <errno.h> 36 1.3 yamt #include <locale.h> 37 1.1 yamt #include <mntopts.h> 38 1.1 yamt #include <paths.h> 39 1.1 yamt #include <puffs.h> 40 1.1 yamt #include <stdbool.h> 41 1.1 yamt #include <stdlib.h> 42 1.1 yamt #include <unistd.h> 43 1.4 yamt #include <util.h> 44 1.1 yamt 45 1.1 yamt #include "pgfs.h" 46 1.1 yamt #include "pgfs_db.h" 47 1.1 yamt 48 1.1 yamt #define PGFS_MNT_ALT_DUMMY 1 49 1.1 yamt #define PGFS_MNT_ALT_DEBUG 2 50 1.1 yamt 51 1.4 yamt static char * 52 1.4 yamt xstrcpy(const char *str) 53 1.4 yamt { 54 1.4 yamt char *n; 55 1.4 yamt size_t len; 56 1.4 yamt 57 1.4 yamt if (str == NULL) { 58 1.4 yamt return NULL; 59 1.4 yamt } 60 1.4 yamt len = strlen(str); 61 1.4 yamt n = emalloc(len + 1); 62 1.4 yamt memcpy(n, str, len + 1); 63 1.4 yamt return n; 64 1.4 yamt } 65 1.4 yamt 66 1.1 yamt int 67 1.1 yamt main(int argc, char *argv[]) 68 1.1 yamt { 69 1.1 yamt extern char *optarg; 70 1.1 yamt extern int optind; 71 1.1 yamt mntoptparse_t mp; 72 1.1 yamt struct puffs_usermount *pu; 73 1.1 yamt struct puffs_ops *pops; 74 1.1 yamt int mntflags; 75 1.1 yamt int altmntflags; 76 1.1 yamt int ch; 77 1.1 yamt int error; 78 1.1 yamt const char *dbname = NULL; 79 1.1 yamt const char *dbuser = NULL; 80 1.1 yamt static const struct mntopt mopts[] = { 81 1.1 yamt MOPT_STDOPTS, 82 1.1 yamt MOPT_SYNC, 83 1.1 yamt { .m_option = "dbname", .m_inverse = 0, 84 1.1 yamt .m_flag = PGFS_MNT_ALT_DUMMY, .m_altloc = 1, }, 85 1.1 yamt { .m_option = "dbuser", .m_inverse = 0, 86 1.1 yamt .m_flag = PGFS_MNT_ALT_DUMMY, .m_altloc = 1, }, 87 1.1 yamt { .m_option = "debug", .m_inverse = 0, 88 1.1 yamt .m_flag = PGFS_MNT_ALT_DEBUG, .m_altloc = 1, }, 89 1.1 yamt { .m_option = "nconn", .m_inverse = 0, 90 1.1 yamt .m_flag = PGFS_MNT_ALT_DUMMY, .m_altloc = 1, }, 91 1.1 yamt MOPT_NULL, 92 1.1 yamt }; 93 1.2 yamt uint32_t pflags = PUFFS_KFLAG_IAONDEMAND; 94 1.1 yamt unsigned int nconn = 8; 95 1.1 yamt bool debug = false; 96 1.1 yamt bool dosync; 97 1.1 yamt 98 1.3 yamt setlocale(LC_ALL, ""); 99 1.3 yamt 100 1.1 yamt mntflags = 0; 101 1.1 yamt altmntflags = 0; 102 1.1 yamt while ((ch = getopt(argc, argv, "o:")) != -1) { 103 1.1 yamt long v; 104 1.1 yamt 105 1.1 yamt switch (ch) { 106 1.1 yamt case 'o': 107 1.1 yamt mp = getmntopts(optarg, mopts, &mntflags, 108 1.1 yamt &altmntflags); 109 1.1 yamt if (mp == NULL) { 110 1.1 yamt err(EXIT_FAILURE, "getmntopts"); 111 1.1 yamt } 112 1.1 yamt getmnt_silent = 1; /* XXX silly api */ 113 1.4 yamt dbname = xstrcpy(getmntoptstr(mp, "dbname")); 114 1.4 yamt dbuser = xstrcpy(getmntoptstr(mp, "dbuser")); 115 1.1 yamt v = getmntoptnum(mp, "nconn"); 116 1.1 yamt getmnt_silent = 0; 117 1.1 yamt if (v != -1) { 118 1.1 yamt nconn = v; 119 1.1 yamt } 120 1.1 yamt if ((altmntflags & PGFS_MNT_ALT_DEBUG) != 0) { 121 1.1 yamt debug = true; 122 1.1 yamt } 123 1.1 yamt freemntopts(mp); 124 1.1 yamt break; 125 1.1 yamt } 126 1.1 yamt } 127 1.1 yamt argc -= optind; 128 1.1 yamt argv += optind; 129 1.1 yamt 130 1.1 yamt PUFFSOP_INIT(pops); 131 1.1 yamt PUFFSOP_SETFSNOP(pops, unmount); 132 1.1 yamt PUFFSOP_SETFSNOP(pops, sync); 133 1.1 yamt PUFFSOP_SET(pops, pgfs, fs, statvfs); 134 1.1 yamt PUFFSOP_SET(pops, pgfs, node, readdir); 135 1.1 yamt PUFFSOP_SET(pops, pgfs, node, getattr); 136 1.1 yamt PUFFSOP_SET(pops, pgfs, node, lookup); 137 1.1 yamt PUFFSOP_SET(pops, pgfs, node, mkdir); 138 1.1 yamt PUFFSOP_SET(pops, pgfs, node, create); 139 1.1 yamt PUFFSOP_SET(pops, pgfs, node, read); 140 1.1 yamt PUFFSOP_SET(pops, pgfs, node, write); 141 1.1 yamt PUFFSOP_SET(pops, pgfs, node, link); 142 1.1 yamt PUFFSOP_SET(pops, pgfs, node, remove); 143 1.1 yamt PUFFSOP_SET(pops, pgfs, node, rmdir); 144 1.1 yamt PUFFSOP_SET(pops, pgfs, node, inactive); 145 1.1 yamt PUFFSOP_SET(pops, pgfs, node, setattr); 146 1.1 yamt PUFFSOP_SET(pops, pgfs, node, rename); 147 1.1 yamt PUFFSOP_SET(pops, pgfs, node, symlink); 148 1.1 yamt PUFFSOP_SET(pops, pgfs, node, readlink); 149 1.1 yamt PUFFSOP_SET(pops, pgfs, node, access); 150 1.1 yamt dosync = (mntflags & MNT_SYNCHRONOUS) != 0; 151 1.1 yamt if (!dosync) { 152 1.1 yamt PUFFSOP_SET(pops, pgfs, node, fsync); 153 1.1 yamt } 154 1.1 yamt if (debug) { 155 1.1 yamt pflags |= PUFFS_FLAG_OPDUMP; 156 1.1 yamt } 157 1.1 yamt pu = puffs_init(pops, _PATH_PUFFS, "pgfs", NULL, pflags); 158 1.1 yamt if (pu == NULL) { 159 1.1 yamt err(EXIT_FAILURE, "puffs_init"); 160 1.1 yamt } 161 1.1 yamt error = pgfs_connectdb(pu, dbname, dbuser, debug, dosync, nconn); 162 1.4 yamt free(__UNCONST(dbname)); 163 1.4 yamt free(__UNCONST(dbuser)); 164 1.1 yamt if (error != 0) { 165 1.1 yamt errno = error; 166 1.1 yamt err(EXIT_FAILURE, "pgfs_connectdb"); 167 1.1 yamt } 168 1.1 yamt if (!debug) { 169 1.1 yamt if (puffs_daemon(pu, 1, 1)) { 170 1.1 yamt err(EXIT_FAILURE, "puffs_daemon"); 171 1.1 yamt } 172 1.1 yamt } 173 1.1 yamt if (puffs_mount(pu, argv[1], mntflags, pgfs_root_cookie()) == -1) { 174 1.1 yamt err(EXIT_FAILURE, "puffs_mount"); 175 1.1 yamt } 176 1.1 yamt if (!debug) { 177 1.1 yamt char tmpl[] = "/tmp/pgfs.XXXXXXXX"; 178 1.1 yamt const char *path; 179 1.1 yamt int fd; 180 1.1 yamt int ret; 181 1.1 yamt 182 1.1 yamt path = mkdtemp(tmpl); 183 1.1 yamt if (path == NULL) { 184 1.1 yamt err(EXIT_FAILURE, "mkdtemp"); 185 1.1 yamt } 186 1.1 yamt fd = open(path, O_RDONLY | O_DIRECTORY); 187 1.1 yamt if (fd == -1) { 188 1.1 yamt err(EXIT_FAILURE, "open %s", path); 189 1.1 yamt } 190 1.1 yamt ret = rmdir(path); 191 1.1 yamt if (ret != 0) { 192 1.1 yamt err(EXIT_FAILURE, "rmdir %s", path); 193 1.1 yamt } 194 1.1 yamt ret = fchroot(fd); 195 1.1 yamt if (ret != 0) { 196 1.1 yamt err(EXIT_FAILURE, "fchroot"); 197 1.1 yamt } 198 1.1 yamt ret = close(fd); 199 1.1 yamt if (ret != 0) { 200 1.1 yamt err(EXIT_FAILURE, "close"); 201 1.1 yamt } 202 1.1 yamt } 203 1.1 yamt if (puffs_mainloop(pu) == -1) { 204 1.1 yamt err(EXIT_FAILURE, "puffs_mainloop"); 205 1.1 yamt } 206 1.1 yamt exit(EXIT_SUCCESS); 207 1.1 yamt } 208