"Fossies" - the Fresh Open Source Software Archive

Member "fuse-3.10.4/doc/html/fuse-3_810_83_2lib_2mount__bsd_8c_source.html" (9 Jun 2021, 46834 Bytes) of package /linux/misc/fuse-3.10.4.tar.xz:


Caution: In this restricted "Fossies" environment the current HTML page may not be correctly presentated and may have some non-functional links. You can here alternatively try to browse the pure source code or just view or download the uninterpreted raw source code. If the rendering is insufficient you may try to find and view the page on the project site itself.

libfuse
mount_bsd.c
1 /*
2  FUSE: Filesystem in Userspace
3  Copyright (C) 2005-2008 Csaba Henk <csaba.henk@creo.hu>
4 
5  Architecture specific file system mounting (FreeBSD).
6 
7  This program can be distributed under the terms of the GNU LGPLv2.
8  See the file COPYING.LIB.
9 */
10 
11 #include "config.h"
12 #include "fuse_i.h"
13 #include "fuse_misc.h"
14 #include "fuse_opt.h"
15 
16 #include <sys/param.h>
17 #include <sys/mount.h>
18 
19 #include <sys/stat.h>
20 #include <sys/wait.h>
21 #include <sys/sysctl.h>
22 #include <sys/user.h>
23 #include <stdio.h>
24 #include <stdlib.h>
25 #include <unistd.h>
26 #include <stddef.h>
27 #include <fcntl.h>
28 #include <errno.h>
29 #include <string.h>
30 #include <paths.h>
31 #include <limits.h>
32 
33 #define FUSERMOUNT_PROG "mount_fusefs"
34 #define FUSE_DEV_TRUNK "/dev/fuse"
35 
36 enum {
37  KEY_RO,
38  KEY_KERN
39 };
40 
41 struct mount_opts {
42  int allow_other;
43  char *kernel_opts;
44  unsigned max_read;
45 };
46 
47 #define FUSE_DUAL_OPT_KEY(templ, key) \
48  FUSE_OPT_KEY(templ, key), FUSE_OPT_KEY("no" templ, key)
49 
50 static const struct fuse_opt fuse_mount_opts[] = {
51  { "allow_other", offsetof(struct mount_opts, allow_other), 1 },
52  { "max_read=%u", offsetof(struct mount_opts, max_read), 1 },
53  FUSE_OPT_KEY("-r", KEY_RO),
54  /* standard FreeBSD mount options */
55  FUSE_DUAL_OPT_KEY("dev", KEY_KERN),
56  FUSE_DUAL_OPT_KEY("async", KEY_KERN),
57  FUSE_DUAL_OPT_KEY("atime", KEY_KERN),
58  FUSE_DUAL_OPT_KEY("dev", KEY_KERN),
59  FUSE_DUAL_OPT_KEY("exec", KEY_KERN),
60  FUSE_DUAL_OPT_KEY("suid", KEY_KERN),
61  FUSE_DUAL_OPT_KEY("symfollow", KEY_KERN),
62  FUSE_DUAL_OPT_KEY("rdonly", KEY_KERN),
63  FUSE_DUAL_OPT_KEY("sync", KEY_KERN),
64  FUSE_DUAL_OPT_KEY("union", KEY_KERN),
65  FUSE_DUAL_OPT_KEY("userquota", KEY_KERN),
66  FUSE_DUAL_OPT_KEY("groupquota", KEY_KERN),
67  FUSE_DUAL_OPT_KEY("clusterr", KEY_KERN),
68  FUSE_DUAL_OPT_KEY("clusterw", KEY_KERN),
69  FUSE_DUAL_OPT_KEY("suiddir", KEY_KERN),
70  FUSE_DUAL_OPT_KEY("snapshot", KEY_KERN),
71  FUSE_DUAL_OPT_KEY("multilabel", KEY_KERN),
72  FUSE_DUAL_OPT_KEY("acls", KEY_KERN),
73  FUSE_DUAL_OPT_KEY("force", KEY_KERN),
74  FUSE_DUAL_OPT_KEY("update", KEY_KERN),
75  FUSE_DUAL_OPT_KEY("ro", KEY_KERN),
76  FUSE_DUAL_OPT_KEY("rw", KEY_KERN),
77  FUSE_DUAL_OPT_KEY("auto", KEY_KERN),
78  FUSE_DUAL_OPT_KEY("automounted", KEY_KERN),
79  /* options supported under both Linux and FBSD */
80  FUSE_DUAL_OPT_KEY("allow_other", KEY_KERN),
81  FUSE_DUAL_OPT_KEY("default_permissions",KEY_KERN),
82  FUSE_OPT_KEY("max_read=", KEY_KERN),
83  FUSE_OPT_KEY("subtype=", KEY_KERN),
84  /* FBSD FUSE specific mount options */
85  FUSE_DUAL_OPT_KEY("private", KEY_KERN),
86  FUSE_DUAL_OPT_KEY("neglect_shares", KEY_KERN),
87  FUSE_DUAL_OPT_KEY("push_symlinks_in", KEY_KERN),
88  FUSE_OPT_KEY("nosync_unmount", KEY_KERN),
89 #if __FreeBSD_version >= 1200519
90  FUSE_DUAL_OPT_KEY("intr", KEY_KERN),
91 #endif
92  /* stock FBSD mountopt parsing routine lets anything be negated... */
93  /*
94  * Linux specific mount options, but let just the mount util
95  * handle them
96  */
97  FUSE_OPT_KEY("fsname=", KEY_KERN),
99 };
100 
101 void fuse_mount_version(void)
102 {
103  system(FUSERMOUNT_PROG " --version");
104 }
105 
106 unsigned get_max_read(struct mount_opts *o)
107 {
108  return o->max_read;
109 }
110 
111 static int fuse_mount_opt_proc(void *data, const char *arg, int key,
112  struct fuse_args *outargs)
113 {
114  (void) outargs;
115  struct mount_opts *mo = data;
116 
117  switch (key) {
118  case KEY_RO:
119  arg = "ro";
120  /* fall through */
121 
122  case KEY_KERN:
123  return fuse_opt_add_opt(&mo->kernel_opts, arg);
124  }
125 
126  /* Pass through unknown options */
127  return 1;
128 }
129 
130 void fuse_kern_unmount(const char *mountpoint, int fd)
131 {
132  close(fd);
133  unmount(mountpoint, MNT_FORCE);
134 }
135 
136 /* Check if kernel is doing init in background */
137 static int init_backgrounded(void)
138 {
139  unsigned ibg;
140  size_t len;
141 
142  len = sizeof(ibg);
143 
144  if (sysctlbyname("vfs.fuse.init_backgrounded", &ibg, &len, NULL, 0))
145  return 0;
146 
147  return ibg;
148 }
149 
150 
151 static int fuse_mount_core(const char *mountpoint, const char *opts)
152 {
153  const char *mountprog = FUSERMOUNT_PROG;
154  int fd;
155  char *fdnam, *dev;
156  pid_t pid, cpid;
157  int status;
158 
159  fdnam = getenv("FUSE_DEV_FD");
160 
161  if (fdnam) {
162  char *ep;
163 
164  fd = strtol(fdnam, &ep, 10);
165 
166  if (*ep != '\0') {
167  fuse_log(FUSE_LOG_ERR, "invalid value given in FUSE_DEV_FD\n");
168  return -1;
169  }
170 
171  if (fd < 0)
172  return -1;
173 
174  goto mount;
175  }
176 
177  dev = getenv("FUSE_DEV_NAME");
178 
179  if (! dev)
180  dev = (char *)FUSE_DEV_TRUNK;
181 
182  if ((fd = open(dev, O_RDWR)) < 0) {
183  perror("fuse: failed to open fuse device");
184  return -1;
185  }
186 
187 mount:
188  if (getenv("FUSE_NO_MOUNT") || ! mountpoint)
189  goto out;
190 
191  pid = fork();
192  cpid = pid;
193 
194  if (pid == -1) {
195  perror("fuse: fork() failed");
196  close(fd);
197  return -1;
198  }
199 
200  if (pid == 0) {
201  if (! init_backgrounded()) {
202  /*
203  * If init is not backgrounded, we have to
204  * call the mount util backgrounded, to avoid
205  * deadlock.
206  */
207 
208  pid = fork();
209 
210  if (pid == -1) {
211  perror("fuse: fork() failed");
212  close(fd);
213  exit(1);
214  }
215  }
216 
217  if (pid == 0) {
218  const char *argv[32];
219  int a = 0;
220  int ret = -1;
221 
222  if (! fdnam)
223  {
224  ret = asprintf(&fdnam, "%d", fd);
225  if(ret == -1)
226  {
227  perror("fuse: failed to assemble mount arguments");
228  close(fd);
229  exit(1);
230  }
231  }
232 
233  argv[a++] = mountprog;
234  if (opts) {
235  argv[a++] = "-o";
236  argv[a++] = opts;
237  }
238  argv[a++] = fdnam;
239  argv[a++] = mountpoint;
240  argv[a++] = NULL;
241  execvp(mountprog, (char **) argv);
242  perror("fuse: failed to exec mount program");
243  free(fdnam);
244  exit(1);
245  }
246 
247  exit(0);
248  }
249 
250  if (waitpid(cpid, &status, 0) == -1 || WEXITSTATUS(status) != 0) {
251  perror("fuse: failed to mount file system");
252  close(fd);
253  return -1;
254  }
255 
256 out:
257  return fd;
258 }
259 
260 struct mount_opts *parse_mount_opts(struct fuse_args *args)
261 {
262  struct mount_opts *mo;
263 
264  mo = (struct mount_opts*) malloc(sizeof(struct mount_opts));
265  if (mo == NULL)
266  return NULL;
267 
268  memset(mo, 0, sizeof(struct mount_opts));
269 
270  if (args &&
271  fuse_opt_parse(args, mo, fuse_mount_opts, fuse_mount_opt_proc) == -1)
272  goto err_out;
273 
274  return mo;
275 
276 err_out:
277  destroy_mount_opts(mo);
278  return NULL;
279 }
280 
281 void destroy_mount_opts(struct mount_opts *mo)
282 {
283  free(mo->kernel_opts);
284  free(mo);
285 }
286 
287 int fuse_kern_mount(const char *mountpoint, struct mount_opts *mo)
288 {
289  /* mount util should not try to spawn the daemon */
290  setenv("MOUNT_FUSEFS_SAFE", "1", 1);
291  /* to notify the mount util it's called from lib */
292  setenv("MOUNT_FUSEFS_CALL_BY_LIB", "1", 1);
293 
294  return fuse_mount_core(mountpoint, mo->kernel_opts);
295 }
#define FUSE_OPT_KEY(templ, key)
Definition: fuse_opt.h:98
int fuse_opt_add_opt(char **opts, const char *opt)
Definition: fuse_opt.c:139
#define FUSE_OPT_END
Definition: fuse_opt.h:104
void fuse_log(enum fuse_log_level level, const char *fmt,...)
Definition: fuse_log.c:33
int fuse_opt_parse(struct fuse_args *args, void *data, const struct fuse_opt opts[], fuse_opt_proc_t proc)
Definition: fuse_opt.c:398