Changeset View
Changeset View
Standalone View
Standalone View
sbin/mount_fusefs/mount_fusefs.c
| /*- | /*- | ||||
| * SPDX-License-Identifier: BSD-2-Clause-FreeBSD | * SPDX-License-Identifier: BSD-2-Clause-FreeBSD | ||||
| * | * | ||||
| * Copyright (c) 2005 Jean-Sebastien Pedron | * Copyright (c) 2005 Jean-Sebastien Pedron | ||||
| * Copyright (c) 2005 Csaba Henk | * Copyright (c) 2005 Csaba Henk | ||||
| * All rights reserved. | * All rights reserved. | ||||
| * | * | ||||
| * Copyright (c) 2019 The FreeBSD Foundation | |||||
| * | |||||
| * Portions of this software were developed by BFF Storage Systems under | |||||
| * sponsorship from the FreeBSD Foundation. | |||||
| * | |||||
| * Redistribution and use in source and binary forms, with or without | * Redistribution and use in source and binary forms, with or without | ||||
| * modification, are permitted provided that the following conditions | * modification, are permitted provided that the following conditions | ||||
| * are met: | * are met: | ||||
| * 1. Redistributions of source code must retain the above copyright | * 1. Redistributions of source code must retain the above copyright | ||||
| * notice, this list of conditions and the following disclaimer. | * notice, this list of conditions and the following disclaimer. | ||||
| * 2. Redistributions in binary form must reproduce the above copyright | * 2. Redistributions in binary form must reproduce the above copyright | ||||
| * notice, this list of conditions and the following disclaimer in the | * notice, this list of conditions and the following disclaimer in the | ||||
| * documentation and/or other materials provided with the distribution. | * documentation and/or other materials provided with the distribution. | ||||
| Show All 39 Lines | |||||
| #ifndef FUSE4BSD_VERSION | #ifndef FUSE4BSD_VERSION | ||||
| #define FUSE4BSD_VERSION "0.3.9-pre1" | #define FUSE4BSD_VERSION "0.3.9-pre1" | ||||
| #endif | #endif | ||||
| void __usage_short(void); | void __usage_short(void); | ||||
| void usage(void); | void usage(void); | ||||
| void helpmsg(void); | void helpmsg(void); | ||||
| void showversion(void); | void showversion(void); | ||||
| int init_backgrounded(void); | |||||
| static struct mntopt mopts[] = { | static struct mntopt mopts[] = { | ||||
| #define ALTF_PRIVATE 0x01 | #define ALTF_PRIVATE 0x01 | ||||
| { "private", 0, ALTF_PRIVATE, 1 }, | { "private", 0, ALTF_PRIVATE, 1 }, | ||||
| { "neglect_shares", 0, 0x02, 1 }, | { "neglect_shares", 0, 0x02, 1 }, | ||||
| { "push_symlinks_in", 0, 0x04, 1 }, | { "push_symlinks_in", 0, 0x04, 1 }, | ||||
| { "allow_other", 0, 0x08, 1 }, | { "allow_other", 0, 0x08, 1 }, | ||||
| { "default_permissions", 0, 0x10, 1 }, | { "default_permissions", 0, 0x10, 1 }, | ||||
| #define ALTF_MAXREAD 0x20 | #define ALTF_MAXREAD 0x20 | ||||
| { "max_read=", 0, ALTF_MAXREAD, 1 }, | { "max_read=", 0, ALTF_MAXREAD, 1 }, | ||||
| #define ALTF_SUBTYPE 0x40 | #define ALTF_SUBTYPE 0x40 | ||||
| { "subtype=", 0, ALTF_SUBTYPE, 1 }, | { "subtype=", 0, ALTF_SUBTYPE, 1 }, | ||||
| #define ALTF_SYNC_UNMOUNT 0x80 | |||||
| { "sync_unmount", 0, ALTF_SYNC_UNMOUNT, 1 }, | |||||
| /* | /* | ||||
| * MOPT_AUTOMOUNTED, included by MOPT_STDOPTS, does not fit into | * MOPT_AUTOMOUNTED, included by MOPT_STDOPTS, does not fit into | ||||
| * the 'flags' argument to nmount(2). We have to abuse altflags | * the 'flags' argument to nmount(2). We have to abuse altflags | ||||
| * to pass it, as string, via iovec. | * to pass it, as string, via iovec. | ||||
| */ | */ | ||||
| #define ALTF_AUTOMOUNTED 0x100 | #define ALTF_AUTOMOUNTED 0x100 | ||||
| { "automounted", 0, ALTF_AUTOMOUNTED, 1 }, | { "automounted", 0, ALTF_AUTOMOUNTED, 1 }, | ||||
| #define ALTF_INTR 0x200 | |||||
| { "intr", 0, ALTF_INTR, 1 }, | |||||
| /* Linux specific options, we silently ignore them */ | /* Linux specific options, we silently ignore them */ | ||||
| { "fsname=", 0, 0x00, 1 }, | { "fsname=", 0, 0x00, 1 }, | ||||
| { "fd=", 0, 0x00, 1 }, | { "fd=", 0, 0x00, 1 }, | ||||
| { "rootmode=", 0, 0x00, 1 }, | { "rootmode=", 0, 0x00, 1 }, | ||||
| { "user_id=", 0, 0x00, 1 }, | { "user_id=", 0, 0x00, 1 }, | ||||
| { "group_id=", 0, 0x00, 1 }, | { "group_id=", 0, 0x00, 1 }, | ||||
| { "large_read", 0, 0x00, 1 }, | { "large_read", 0, 0x00, 1 }, | ||||
| /* "nonempty", just the first two chars are stripped off during parsing */ | /* "nonempty", just the first two chars are stripped off during parsing */ | ||||
| { "nempty", 0, 0x00, 1 }, | { "nempty", 0, 0x00, 1 }, | ||||
| { "async", 0, MNT_ASYNC, 0}, | |||||
| { "noasync", 1, MNT_ASYNC, 0}, | |||||
| MOPT_STDOPTS, | MOPT_STDOPTS, | ||||
| MOPT_END | MOPT_END | ||||
| }; | }; | ||||
| struct mntval { | struct mntval { | ||||
| int mv_flag; | int mv_flag; | ||||
| void *mv_value; | void *mv_value; | ||||
| int mv_len; | int mv_len; | ||||
| }; | }; | ||||
| static struct mntval mvals[] = { | static struct mntval mvals[] = { | ||||
| { ALTF_MAXREAD, NULL, 0 }, | { ALTF_MAXREAD, NULL, 0 }, | ||||
| { ALTF_SUBTYPE, NULL, 0 }, | { ALTF_SUBTYPE, NULL, 0 }, | ||||
| { 0, NULL, 0 } | { 0, NULL, 0 } | ||||
| }; | }; | ||||
| #define DEFAULT_MOUNT_FLAGS ALTF_PRIVATE | ALTF_SYNC_UNMOUNT | #define DEFAULT_MOUNT_FLAGS ALTF_PRIVATE | ||||
| int | int | ||||
| main(int argc, char *argv[]) | main(int argc, char *argv[]) | ||||
| { | { | ||||
| struct iovec *iov; | struct iovec *iov; | ||||
| int mntflags, iovlen, verbose = 0; | int mntflags, iovlen, verbose = 0; | ||||
| char *dev = NULL, *dir = NULL, mntpath[MAXPATHLEN]; | char *dev = NULL, *dir = NULL, mntpath[MAXPATHLEN]; | ||||
| char *devo = NULL, *diro = NULL; | char *devo = NULL, *diro = NULL; | ||||
| ▲ Show 20 Lines • Show All 285 Lines • ▼ Show 20 Lines | if (daemon_str) { | ||||
| if (pid == 0) { | if (pid == 0) { | ||||
| execvp(argv[0], argv); | execvp(argv[0], argv); | ||||
| err(1, "failed to exec fuse daemon"); | err(1, "failed to exec fuse daemon"); | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| if (fd >= 0 && ! init_backgrounded() && close(fd) < 0) { | |||||
| if (pid) | |||||
| kill(pid, SIGKILL); | |||||
| err(1, "failed to close fuse device"); | |||||
| } | |||||
| /* Prepare the options vector for nmount(). build_iovec() is declared | /* Prepare the options vector for nmount(). build_iovec() is declared | ||||
| * in mntopts.h. */ | * in mntopts.h. */ | ||||
| sprintf(fdstr, "%d", fd); | sprintf(fdstr, "%d", fd); | ||||
| build_iovec(&iov, &iovlen, "fstype", __DECONST(void *, "fusefs"), -1); | build_iovec(&iov, &iovlen, "fstype", __DECONST(void *, "fusefs"), -1); | ||||
| build_iovec(&iov, &iovlen, "fspath", mntpath, -1); | build_iovec(&iov, &iovlen, "fspath", mntpath, -1); | ||||
| build_iovec(&iov, &iovlen, "from", dev, -1); | build_iovec(&iov, &iovlen, "from", dev, -1); | ||||
| build_iovec(&iov, &iovlen, "fd", fdstr, -1); | build_iovec(&iov, &iovlen, "fd", fdstr, -1); | ||||
| Show All 40 Lines | helpmsg(void) | ||||
| * The main use case of this function is giving info embedded in general | * The main use case of this function is giving info embedded in general | ||||
| * FUSE lib help output. Therefore the style and the content of the output | * FUSE lib help output. Therefore the style and the content of the output | ||||
| * tries to fit there as much as possible. | * tries to fit there as much as possible. | ||||
| */ | */ | ||||
| fprintf(stderr, | fprintf(stderr, | ||||
| " -o allow_other allow access to other users\n" | " -o allow_other allow access to other users\n" | ||||
| /* " -o nonempty allow mounts over non-empty file/dir\n" */ | /* " -o nonempty allow mounts over non-empty file/dir\n" */ | ||||
| " -o default_permissions enable permission checking by kernel\n" | " -o default_permissions enable permission checking by kernel\n" | ||||
| " -o intr interruptible mount\n" | |||||
| /* | /* | ||||
| " -o fsname=NAME set filesystem name\n" | " -o fsname=NAME set filesystem name\n" | ||||
| " -o large_read issue large read requests (2.4 only)\n" | " -o large_read issue large read requests (2.4 only)\n" | ||||
| */ | */ | ||||
| " -o subtype=NAME set filesystem type\n" | " -o subtype=NAME set filesystem type\n" | ||||
| " -o max_read=N set maximum size of read requests\n" | " -o max_read=N set maximum size of read requests\n" | ||||
| " -o noprivate allow secondary mounting of the filesystem\n" | " -o noprivate allow secondary mounting of the filesystem\n" | ||||
| " -o neglect_shares don't report EBUSY when unmount attempted\n" | " -o neglect_shares don't report EBUSY when unmount attempted\n" | ||||
| " in presence of secondary mounts\n" | " in presence of secondary mounts\n" | ||||
| " -o push_symlinks_in prefix absolute symlinks with mountpoint\n" | " -o push_symlinks_in prefix absolute symlinks with mountpoint\n" | ||||
| " -o sync_unmount do unmount synchronously\n" | |||||
| ); | ); | ||||
| exit(EX_USAGE); | exit(EX_USAGE); | ||||
| } | } | ||||
| void | void | ||||
| showversion(void) | showversion(void) | ||||
| { | { | ||||
| puts("mount_fusefs [fuse4bsd] version: " FUSE4BSD_VERSION); | puts("mount_fusefs [fuse4bsd] version: " FUSE4BSD_VERSION); | ||||
| exit(EX_USAGE); | exit(EX_USAGE); | ||||
| } | |||||
| int | |||||
| init_backgrounded(void) | |||||
| { | |||||
| int ibg; | |||||
| size_t len; | |||||
| len = sizeof(ibg); | |||||
| if (sysctlbyname("vfs.fusefs.init_backgrounded", &ibg, &len, NULL, 0)) | |||||
| return (0); | |||||
| return (ibg); | |||||
| } | } | ||||