2 * Copyright (c) 2019 Tomohiro Kusumi <tkusumi@netbsd.org>
3 * Copyright (c) 2019 The DragonFly Project
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
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.
15 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
16 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18 * ARE 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
21 * OR 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
28 #include <sys/types.h>
30 #include <vfs/fuse/fuse_mount.h>
41 #define MOPT_FUSE_LINUX_OPTS \
42 { "default_permissions", 0, FUSE_MOUNT_DEFAULT_PERMISSIONS, 1 }, \
43 { "allow_other", 0, FUSE_MOUNT_ALLOW_OTHER, 1 }, \
44 { "max_read=", 0, FUSE_MOUNT_MAX_READ, 1 }, \
45 { "subtype=", 0, FUSE_MOUNT_SUBTYPE, 1 }
48 #define MOPT_FUSE_LINUX_IGNORE_OPTS \
49 { "fsname=", 0, 0, 1 }, \
51 { "rootmode=", 0, 0, 1 }, \
52 { "user_id=", 0, 0, 1 }, \
53 { "group_id=", 0, 0, 1 }, \
55 { "auto_unmount", 0, 0, 1 }, \
56 { "blkdev", 0, 0, 1 }, \
57 { "blksize=", 0, 0, 1 }, \
58 { "context=", 0, 0, 1 }, \
59 { "fscontext=", 0, 0, 1 }, \
60 { "defcontext=", 0, 0, 1 }, \
61 { "rootcontext=", 0, 0, 1 }, \
62 { "user=", 0, 0, 1 }, \
66 { "suid", 0, 0, 1 }, \
67 { "nosuid", 0, 0, 1 }, \
69 { "nodev", 0, 0, 1 }, \
70 { "exec", 0, 0, 1 }, \
71 { "noexec", 0, 0, 1 }, \
72 { "async", 0, 0, 1 }, \
73 { "sync", 0, 0, 1 }, \
74 { "dirsync", 0, 0, 1 }, \
75 { "atime", 0, 0, 1 }, \
76 { "noatime", 0, 0, 1 }
78 static struct mntopt mopts
[] = {
80 MOPT_FUSE_LINUX_IGNORE_OPTS
,
88 fprintf(stderr
, "usage: mount_fusefs [-o options] fd mountpoint\n");
93 get_optval(const char *ptr
)
95 char *ret
= strdup(ptr
);
96 const char *end
= strstr(ptr
, ",");
101 ret
[(int)(end
- ptr
)] = '\0';
107 * argv[0] = "mount_fusefs"
109 * argv[2] = "max_read=...,subtype=hello"
111 * argv[4] = "/mnt/fuse"
115 main(int argc
, char **argv
)
117 struct fuse_mount_info args
;
120 const char *fdstr
, *mntpt
;
121 char *ep
, mntpath
[MAXPATHLEN
], fusedev
[64];
122 int error
, c
, fd
, mntflags
;
125 memset(&args
, 0, sizeof(args
));
127 while ((c
= getopt_long(argc
, argv
, "ho:", NULL
, NULL
)) != -1) {
130 getmntopts(optarg
, mopts
, &mntflags
, &args
.flags
);
131 if (args
.flags
& FUSE_MOUNT_MAX_READ
) {
132 char *p
= strstr(optarg
, "max_read=");
134 p
= get_optval(p
+ 9);
135 args
.max_read
= strtol(p
, NULL
, 0);
139 if (args
.flags
& FUSE_MOUNT_SUBTYPE
) {
140 char *p
= strstr(optarg
, "subtype=");
142 p
= get_optval(p
+ 8);
143 args
.subtype
= strdup(p
);
161 checkpath(mntpt
, mntpath
);
163 fd
= strtol(fdstr
, &ep
, 10);
164 if (fd
<= 0 || *ep
!= '\0')
165 err(1, "Invalid FUSE fd %s", fdstr
);
167 if (fstat(fd
, &st
) == -1)
168 err(1, "Failed to stat FUSE fd %d", fd
);
169 strcpy(fusedev
, "/dev/");
170 devname_r(st
.st_rdev
, S_IFCHR
, fusedev
+ strlen(fusedev
),
171 sizeof(fusedev
) - strlen(fusedev
));
172 if (stat(fusedev
, &st
) == -1)
173 err(1, "Failed to stat FUSE device %s", fusedev
);
174 if (strncmp(fusedev
, "/dev/fuse", 9))
175 err(1, "Invalid FUSE device %s", fusedev
);
177 args
.from
= strdup(fusedev
);
179 error
= getvfsbyname("fuse", &vfc
);
180 if (error
&& vfsisloadable("fuse")) {
182 err(1, "vfsload(%s)", "fuse");
184 error
= getvfsbyname("fuse", &vfc
);
187 errx(1, "%s filesystem not available", "fuse");
189 if (mount(vfc
.vfc_name
, mntpath
, mntflags
, &args
) == -1)