diff options
Diffstat (limited to 'contrib/fuse-util')
| -rw-r--r-- | contrib/fuse-util/Makefile.am | 8 | ||||
| -rw-r--r-- | contrib/fuse-util/fusermount.c | 565 | ||||
| -rw-r--r-- | contrib/fuse-util/mount_util.c | 64 | ||||
| -rw-r--r-- | contrib/fuse-util/mount_util.h | 17 |
4 files changed, 527 insertions, 127 deletions
diff --git a/contrib/fuse-util/Makefile.am b/contrib/fuse-util/Makefile.am index 42609a6883d..abbc10eb6d9 100644 --- a/contrib/fuse-util/Makefile.am +++ b/contrib/fuse-util/Makefile.am @@ -1,9 +1,11 @@ bin_PROGRAMS = fusermount-glusterfs -fusermount_glusterfs_SOURCES = fusermount.c $(CONTRIBDIR)/fuse-lib/mount.c -noinst_HEADERS = mount_util.h +fusermount_glusterfs_SOURCES = fusermount.c mount_util.c $(CONTRIBDIR)/fuse-lib/mount-common.c +noinst_HEADERS = $(CONTRIBDIR)/fuse-include/mount_util.h -AM_CFLAGS = -Wall -D_FILE_OFFSET_BITS=64 -DFUSE_UTIL $(GF_CFLAGS) +AM_CPPFLAGS = $(GF_CPPFLAGS) -DFUSE_UTIL -I$(CONTRIBDIR)/fuse-include -I$(CONTRIBDIR)/fuse-lib + +AM_CFLAGS = -Wall $(GF_CFLAGS) install-exec-hook: -chown root $(DESTDIR)$(bindir)/fusermount-glusterfs diff --git a/contrib/fuse-util/fusermount.c b/contrib/fuse-util/fusermount.c index c3ecc86cc44..ff743f75a21 100644 --- a/contrib/fuse-util/fusermount.c +++ b/contrib/fuse-util/fusermount.c @@ -10,6 +10,11 @@ #include <config.h> #include "mount_util.h" + +#ifndef HAVE_UMOUNT2 +#include "mount-gluster-compat.h" +#endif + #include <stdio.h> #include <stdlib.h> #include <string.h> @@ -19,14 +24,24 @@ #include <errno.h> #include <fcntl.h> #include <pwd.h> +#include <limits.h> +#if !defined(__NetBSD__) && !defined(GF_DARWIN_HOST_OS) #include <mntent.h> +#endif /* __NetBSD__ */ #include <sys/wait.h> #include <sys/stat.h> -#include <sys/mount.h> +#ifdef HAVE_SET_FSID #include <sys/fsuid.h> +#endif +#ifdef GF_DARWIN_HOST_OS +#include <sys/param.h> +#endif +#include <sys/mount.h> #include <sys/socket.h> #include <sys/utsname.h> +#include <sched.h> +#define FUSE_DEVFD_ENV "_FUSE_DEVFD" #define FUSE_COMMFD_ENV "_FUSE_COMMFD" #define FUSE_DEV_OLD "/proc/fs/fuse/dev" @@ -37,6 +52,12 @@ #ifndef MS_DIRSYNC #define MS_DIRSYNC 128 #endif +#ifndef MS_REC +#define MS_REC 16384 +#endif +#ifndef MS_PRIVATE +#define MS_PRIVATE (1<<18) +#endif static const char *progname; @@ -54,97 +75,378 @@ static const char *get_user_name(void) } } +#ifdef HAVE_SET_FSID static uid_t oldfsuid; static gid_t oldfsgid; +#endif static void drop_privs(void) { if (getuid() != 0) { +#ifdef HAVE_SET_FSID oldfsuid = setfsuid(getuid()); oldfsgid = setfsgid(getgid()); +#else + fprintf(stderr, "%s: Implement alternative setfsuid/gid \n", progname); +#endif } } static void restore_privs(void) { if (getuid() != 0) { +#ifdef HAVE_SET_FSID setfsuid(oldfsuid); setfsgid(oldfsgid); +#else + fprintf(stderr, "%s: Implement alternative setfsuid/gid \n", progname); +#endif } } #ifndef IGNORE_MTAB +/* + * Make sure that /etc/mtab is checked and updated atomically + */ +static int lock_umount(void) +{ + const char *mtab_lock = _PATH_MOUNTED ".fuselock"; + int mtablock; + int res; + struct stat mtab_stat; + + /* /etc/mtab could be a symlink to /proc/mounts */ + if (lstat(_PATH_MOUNTED, &mtab_stat) == 0 && S_ISLNK(mtab_stat.st_mode)) + return -1; + + mtablock = open(mtab_lock, O_RDWR | O_CREAT, 0600); + if (mtablock == -1) { + fprintf(stderr, "%s: unable to open fuse lock file: %s\n", + progname, strerror(errno)); + return -1; + } + res = lockf(mtablock, F_LOCK, 0); + if (res < 0) { + fprintf(stderr, "%s: error getting lock: %s\n", progname, + strerror(errno)); + close(mtablock); + return -1; + } + + return mtablock; +} + +static void unlock_umount(int mtablock) +{ + if (mtablock >= 0) { + int res; + + res = lockf(mtablock, F_ULOCK, 0); + if (res < 0) { + fprintf(stderr, "%s: error releasing lock: %s\n", + progname, strerror(errno)); + } + close(mtablock); + } +} + static int add_mount(const char *source, const char *mnt, const char *type, const char *opts) { return fuse_mnt_add_mount(progname, source, mnt, type, opts); } -static int unmount_fuse(const char *mnt, int quiet, int lazy) +static int may_unmount(const char *mnt, int quiet) { - if (getuid() != 0) { - struct mntent *entp; - FILE *fp; - const char *user = NULL; - char uidstr[32]; - unsigned uidlen = 0; - int found; - const char *mtab = _PATH_MOUNTED; - - user = get_user_name(); - if (user == NULL) - return -1; + struct mntent *entp; + FILE *fp; + const char *user = NULL; + char uidstr[32]; + unsigned uidlen = 0; + int found; + const char *mtab = _PATH_MOUNTED; - fp = setmntent(mtab, "r"); - if (fp == NULL) { - fprintf(stderr, - "%s: failed to open %s: %s\n", progname, mtab, - strerror(errno)); - return -1; - } + user = get_user_name(); + if (user == NULL) + return -1; - uidlen = sprintf(uidstr, "%u", getuid()); - - found = 0; - while ((entp = getmntent(fp)) != NULL) { - if (!found && strcmp(entp->mnt_dir, mnt) == 0 && - (strcmp(entp->mnt_type, "fuse") == 0 || - strcmp(entp->mnt_type, "fuseblk") == 0 || - strncmp(entp->mnt_type, "fuse.", 5) == 0 || - strncmp(entp->mnt_type, "fuseblk.", 8) == 0)) { - char *p = strstr(entp->mnt_opts, "user="); - if (p && - (p == entp->mnt_opts || *(p-1) == ',') && - strcmp(p + 5, user) == 0) { - found = 1; - break; - } - /* /etc/mtab is a link pointing to - /proc/mounts: */ - else if ((p = - strstr(entp->mnt_opts, "user_id=")) && - (p == entp->mnt_opts || - *(p-1) == ',') && - strncmp(p + 8, uidstr, uidlen) == 0 && - (*(p+8+uidlen) == ',' || - *(p+8+uidlen) == '\0')) { - found = 1; - break; - } + fp = setmntent(mtab, "r"); + if (fp == NULL) { + fprintf(stderr, "%s: failed to open %s: %s\n", progname, mtab, + strerror(errno)); + return -1; + } + + uidlen = sprintf(uidstr, "%u", getuid()); + + found = 0; + while ((entp = getmntent(fp)) != NULL) { + if (!found && strcmp(entp->mnt_dir, mnt) == 0 && + (strcmp(entp->mnt_type, "fuse") == 0 || + strcmp(entp->mnt_type, "fuseblk") == 0 || + strncmp(entp->mnt_type, "fuse.", 5) == 0 || + strncmp(entp->mnt_type, "fuseblk.", 8) == 0)) { + char *p = strstr(entp->mnt_opts, "user="); + if (p && + (p == entp->mnt_opts || *(p-1) == ',') && + strcmp(p + 5, user) == 0) { + found = 1; + break; + } + /* /etc/mtab is a link pointing to + /proc/mounts: */ + else if ((p = + strstr(entp->mnt_opts, "user_id=")) && + (p == entp->mnt_opts || + *(p-1) == ',') && + strncmp(p + 8, uidstr, uidlen) == 0 && + (*(p+8+uidlen) == ',' || + *(p+8+uidlen) == '\0')) { + found = 1; + break; } } - endmntent(fp); + } + endmntent(fp); - if (!found) { - if (!quiet) - fprintf(stderr, - "%s: entry for %s not found in %s\n", - progname, mnt, mtab); - return -1; + if (!found) { + if (!quiet) + fprintf(stderr, + "%s: entry for %s not found in %s\n", + progname, mnt, mtab); + return -1; + } + + return 0; +} + +/* + * Check whether the file specified in "fusermount -u" is really a + * mountpoint and not a symlink. This is necessary otherwise the user + * could move the mountpoint away and replace it with a symlink + * pointing to an arbitrary mount, thereby tricking fusermount into + * unmounting that (umount(2) will follow symlinks). + * + * This is the child process running in a separate mount namespace, so + * we don't mess with the global namespace and if the process is + * killed for any reason, mounts are automatically cleaned up. + * + * First make sure nothing is propagated back into the parent + * namespace by marking all mounts "private". + * + * Then bind mount parent onto a stable base where the user can't move + * it around. + * + * Finally check /proc/mounts for an entry matching the requested + * mountpoint. If it's found then we are OK, and the user can't move + * it around within the parent directory as rename() will return + * EBUSY. Be careful to ignore any mounts that existed before the + * bind. + */ +static int check_is_mount_child(void *p) +{ + const char **a = p; + const char *last = a[0]; + const char *mnt = a[1]; + int res; + const char *procmounts = "/proc/mounts"; + int found; + FILE *fp; + struct mntent *entp; + int count; + + res = mount("", "/", "", MS_PRIVATE | MS_REC, NULL); + if (res == -1) { + fprintf(stderr, "%s: failed to mark mounts private: %s\n", + progname, strerror(errno)); + return 1; + } + + fp = setmntent(procmounts, "r"); + if (fp == NULL) { + fprintf(stderr, "%s: failed to open %s: %s\n", progname, + procmounts, strerror(errno)); + return 1; + } + + count = 0; + while (getmntent(fp) != NULL) + count++; + endmntent(fp); + + fp = setmntent(procmounts, "r"); + if (fp == NULL) { + fprintf(stderr, "%s: failed to open %s: %s\n", progname, + procmounts, strerror(errno)); + return 1; + } + + res = mount(".", "/", "", MS_BIND | MS_REC, NULL); + if (res == -1) { + fprintf(stderr, "%s: failed to bind parent to /: %s\n", + progname, strerror(errno)); + return 1; + } + + found = 0; + while ((entp = getmntent(fp)) != NULL) { + if (count > 0) { + count--; + continue; + } + if (entp->mnt_dir[0] == '/' && + strcmp(entp->mnt_dir + 1, last) == 0) { + found = 1; + break; } } + endmntent(fp); + + if (!found) { + fprintf(stderr, "%s: %s not mounted\n", progname, mnt); + return 1; + } - return fuse_mnt_umount(progname, mnt, lazy); + return 0; +} + +static pid_t clone_newns(void *a) +{ + char buf[131072]; + char *stack = buf + (sizeof(buf) / 2 - ((size_t) buf & 15)); + +#ifdef __ia64__ + extern int __clone2(int (*fn)(void *), + void *child_stack_base, size_t stack_size, + int flags, void *arg, pid_t *ptid, + void *tls, pid_t *ctid); + + return __clone2(check_is_mount_child, stack, sizeof(buf) / 2, + CLONE_NEWNS, a, NULL, NULL, NULL); +#else + return clone(check_is_mount_child, stack, CLONE_NEWNS, a); +#endif +} + +static int check_is_mount(const char *last, const char *mnt) +{ + pid_t pid, p; + int status; + const char *a[2] = { last, mnt }; + + pid = clone_newns((void *) a); + if (pid == (pid_t) -1) { + fprintf(stderr, "%s: failed to clone namespace: %s\n", + progname, strerror(errno)); + return -1; + } + p = waitpid(pid, &status, __WCLONE); + if (p == (pid_t) -1) { + fprintf(stderr, "%s: waitpid failed: %s\n", + progname, strerror(errno)); + return -1; + } + if (!WIFEXITED(status)) { + fprintf(stderr, "%s: child terminated abnormally (status %i)\n", + progname, status); + return -1; + } + if (WEXITSTATUS(status) != 0) + return -1; + + return 0; +} + +static int chdir_to_parent(char *copy, const char **lastp) +{ + char *tmp; + const char *parent; + char buf[65536]; + int res; + + tmp = strrchr(copy, '/'); + if (tmp == NULL || tmp[1] == '\0') { + fprintf(stderr, "%s: internal error: invalid abs path: <%s>\n", + progname, copy); + return -1; + } + if (tmp != copy) { + *tmp = '\0'; + parent = copy; + *lastp = tmp + 1; + } else if (tmp[1] != '\0') { + *lastp = tmp + 1; + parent = "/"; + } else { + *lastp = "."; + parent = "/"; + } + + res = chdir(parent); + if (res == -1) { + fprintf(stderr, "%s: failed to chdir to %s: %s\n", + progname, parent, strerror(errno)); + return -1; + } + + if (getcwd(buf, sizeof(buf)) == NULL) { + fprintf(stderr, "%s: failed to obtain current directory: %s\n", + progname, strerror(errno)); + return -1; + } + if (strcmp(buf, parent) != 0) { + fprintf(stderr, "%s: mountpoint moved (%s -> %s)\n", progname, + parent, buf); + return -1; + + } + + return 0; +} + +static int unmount_fuse_locked(const char *mnt, int quiet, int lazy) +{ + char *copy; + const char *last; + int res; + + if (getuid() != 0) { + res = may_unmount(mnt, quiet); + if (res == -1) + return -1; + } + + copy = strdup(mnt); + if (copy == NULL) { + fprintf(stderr, "%s: failed to allocate memory\n", progname); + return -1; + } + + res = chdir_to_parent(copy, &last); + if (res == -1) + goto out; + + res = check_is_mount(last, mnt); + if (res == -1) + goto out; + + res = fuse_mnt_umount(progname, mnt, last, lazy); + +out: + free(copy); + + return res; +} + +static int unmount_fuse(const char *mnt, int quiet, int lazy) +{ + int res; + int mtablock = lock_umount(); + + res = unmount_fuse_locked(mnt, quiet, lazy); + unlock_umount(mtablock); + + return res; } static int count_fuse_fs(void) @@ -186,7 +488,7 @@ static int add_mount(const char *source, const char *mnt, const char *type, static int unmount_fuse(const char *mnt, int quiet, int lazy) { - return fuse_mnt_umount(progname, mnt, lazy); + return fuse_mnt_umount(progname, mnt, mnt, lazy); } #endif /* IGNORE_MTAB */ @@ -218,20 +520,22 @@ static void parse_line(char *line, int linenum) static void read_conf(void) { + int len; FILE *fp = fopen(FUSE_CONF, "r"); if (fp != NULL) { int linenum = 1; char line[256]; int isnewline = 1; while (fgets(line, sizeof(line), fp) != NULL) { + len = strlen (line); if (isnewline) { - if (line[strlen(line)-1] == '\n') { + if (len && line[len-1] == '\n') { strip_line(line); parse_line(line, linenum); } else { isnewline = 0; } - } else if(line[strlen(line)-1] == '\n') { + } else if (len && line[len-1] == '\n') { fprintf(stderr, "%s: reading %s: line %i too long\n", progname, FUSE_CONF, linenum); isnewline = 1; @@ -326,7 +630,7 @@ static int add_option(char **optsp, const char *opt, unsigned expand) static int get_mnt_opts(int flags, char *opts, char **mnt_optsp) { int i; - int l; + size_t l; if (!(flags & MS_RDONLY) && add_option(mnt_optsp, "rw", 0) == -1) return -1; @@ -341,7 +645,7 @@ static int get_mnt_opts(int flags, char *opts, char **mnt_optsp) return -1; /* remove comma from end of opts*/ l = strlen(*mnt_optsp); - if ((*mnt_optsp)[l-1] == ',') + if (l && (*mnt_optsp)[l-1] == ',') (*mnt_optsp)[l-1] = '\0'; if (getuid() != 0) { const char *user = get_user_name(); @@ -366,18 +670,26 @@ static int opt_eq(const char *s, unsigned len, const char *opt) static int get_string_opt(const char *s, unsigned len, const char *opt, char **val) { + int i; unsigned opt_len = strlen(opt); + char *d; - if (*val) - free(*val); + free(*val); *val = (char *) malloc(len - opt_len + 1); if (!*val) { fprintf(stderr, "%s: failed to allocate memory\n", progname); return 0; } - memcpy(*val, s + opt_len, len - opt_len); - (*val)[len - opt_len] = '\0'; + d = *val; + s += opt_len; + len -= opt_len; + for (i = 0; i < len; i++) { + if (s[i] == '\\' && i + 1 < len) + i++; + *d++ = s[i]; + } + *d = '\0'; return 1; } @@ -408,7 +720,12 @@ static int do_mount(const char *mnt, char **typep, mode_t rootmode, unsigned len; const char *fsname_str = "fsname="; const char *subtype_str = "subtype="; - for (len = 0; s[len] && s[len] != ','; len++); + for (len = 0; s[len]; len++) { + if (s[len] == '\\' && s[len + 1]) + len++; + else if (s[len] == ',') + break; + } if (begins_with(s, fsname_str)) { if (!get_string_opt(s, len, fsname_str, &fsname)) goto err; @@ -526,15 +843,14 @@ static int do_mount(const char *mnt, char **typep, mode_t rootmode, fprintf(stderr, "%s: mount failed: %s\n", progname, strerror(errno_save)); goto err; - } else { - *sourcep = source; - *typep = type; - *mnt_optsp = mnt_opts; } + *sourcep = source; + *typep = type; + *mnt_optsp = mnt_opts; free(fsname); free(optbuf); - return res; + return 0; err: free(fsname); @@ -577,8 +893,7 @@ static int check_version(const char *dev) return 0; } -static int check_perm(const char **mntp, struct stat *stbuf, int *currdir_fd, - int *mountpoint_fd) +static int check_perm(const char **mntp, struct stat *stbuf, int *mountpoint_fd) { int res; const char *mnt = *mntp; @@ -596,13 +911,6 @@ static int check_perm(const char **mntp, struct stat *stbuf, int *currdir_fd, return 0; if (S_ISDIR(stbuf->st_mode)) { - *currdir_fd = open(".", O_RDONLY); - if (*currdir_fd == -1) { - fprintf(stderr, - "%s: failed to open current directory: %s\n", - progname, strerror(errno)); - return -1; - } res = chdir(mnt); if (res == -1) { fprintf(stderr, @@ -719,8 +1027,36 @@ static int open_fuse_device(char **devp) return -1; } +static int check_fuse_device(char *devfd, char **devp) +{ + int res; + char *devlink; -static int mount_fuse(const char *mnt, const char *opts) + res = asprintf(&devlink, "/proc/self/fd/%s", devfd); + if (res == -1) { + fprintf(stderr, "%s: failed to allocate memory\n", progname); + return -1; + } + + *devp = (char *) calloc(1, PATH_MAX + 1); + if (!*devp) { + fprintf(stderr, "%s: failed to allocate memory\n", progname); + free(devlink); + return -1; + } + + res = readlink (devlink, *devp, PATH_MAX); + free (devlink); + if (res == -1) { + fprintf(stderr, "%s: specified fuse fd is invalid\n", + progname); + return -1; + } + + return atoi(devfd); +} + +static int mount_fuse(const char *mnt, const char *opts, char *devfd) { int res; int fd; @@ -730,10 +1066,9 @@ static int mount_fuse(const char *mnt, const char *opts) char *source = NULL; char *mnt_opts = NULL; const char *real_mnt = mnt; - int currdir_fd = -1; int mountpoint_fd = -1; - fd = open_fuse_device(&dev); + fd = devfd ? check_fuse_device(devfd, &dev) : open_fuse_device(&dev); if (fd == -1) return -1; @@ -744,15 +1079,13 @@ static int mount_fuse(const char *mnt, const char *opts) int mount_count = count_fuse_fs(); if (mount_count >= mount_max) { fprintf(stderr, "%s: too many FUSE filesystems mounted; mount_max=N can be set in /etc/fuse.conf\n", progname); - close(fd); - return -1; + goto fail_close_fd; } } res = check_version(dev); if (res != -1) { - res = check_perm(&real_mnt, &stbuf, &currdir_fd, - &mountpoint_fd); + res = check_perm(&real_mnt, &stbuf, &mountpoint_fd); restore_privs(); if (res != -1) res = do_mount(real_mnt, &type, stbuf.st_mode & S_IFMT, @@ -761,33 +1094,38 @@ static int mount_fuse(const char *mnt, const char *opts) } else restore_privs(); - if (currdir_fd != -1) { - fchdir(currdir_fd); - close(currdir_fd); - } if (mountpoint_fd != -1) close(mountpoint_fd); + if (res == -1) + goto fail_close_fd; + + res = chdir("/"); if (res == -1) { - close(fd); - return -1; + fprintf(stderr, "%s: failed to chdir to '/'\n", progname); + goto fail_close_fd; } if (geteuid() == 0) { res = add_mount(source, mnt, type, mnt_opts); if (res == -1) { - umount2(mnt, 2); /* lazy umount */ - close(fd); - return -1; + /* Can't clean up mount in a non-racy way */ + goto fail_close_fd; } } +out_free: free(source); free(type); free(mnt_opts); free(dev); return fd; + +fail_close_fd: + close(fd); + fd = -1; + goto out_free; } static int send_fd(int sock_fd, int fd) @@ -857,6 +1195,7 @@ int main(int argc, char *argv[]) static int unmount = 0; static int lazy = 0; static int quiet = 0; + char *devfd; char *commfd; int cfd; const char *opts = ""; @@ -925,6 +1264,13 @@ int main(int argc, char *argv[]) drop_privs(); mnt = fuse_mnt_resolve_path(progname, origmnt); + if (mnt != NULL) { + res = chdir("/"); + if (res == -1) { + fprintf(stderr, "%s: failed to chdir to '/'\n", progname); + exit(1); + } + } restore_privs(); if (mnt == NULL) exit(1); @@ -945,21 +1291,26 @@ int main(int argc, char *argv[]) return 0; } - commfd = getenv(FUSE_COMMFD_ENV); - if (commfd == NULL) { - fprintf(stderr, "%s: old style mounting not supported\n", - progname); - exit(1); + devfd = getenv(FUSE_DEVFD_ENV); + if (devfd == NULL) { + commfd = getenv(FUSE_COMMFD_ENV); + if (commfd == NULL) { + fprintf(stderr, "%s: old style mounting not supported\n", + progname); + exit(1); + } } - fd = mount_fuse(mnt, opts); + fd = mount_fuse(mnt, opts, devfd); if (fd == -1) exit(1); - cfd = atoi(commfd); - res = send_fd(cfd, fd); - if (res == -1) - exit(1); + if (devfd == NULL) { + cfd = atoi(commfd); + res = send_fd(cfd, fd); + if (res == -1) + exit(1); + } return 0; } diff --git a/contrib/fuse-util/mount_util.c b/contrib/fuse-util/mount_util.c new file mode 100644 index 00000000000..911b84445e9 --- /dev/null +++ b/contrib/fuse-util/mount_util.c @@ -0,0 +1,64 @@ +/* + FUSE: Filesystem in Userspace + Copyright (C) 2001-2007 Miklos Szeredi <miklos@szeredi.hu> + + This program can be distributed under the terms of the GNU LGPLv2. + See the file COPYING.LIB. +*/ + +#include <dirent.h> +#include <stdio.h> +#include <string.h> +#include <errno.h> +#include <sys/types.h> +#include <sys/stat.h> + +int fuse_mnt_check_empty(const char *progname, const char *mnt, + mode_t rootmode, off_t rootsize) +{ + int isempty = 1; + + if (S_ISDIR(rootmode)) { + struct dirent *ent; + DIR *dp = opendir(mnt); + if (dp == NULL) { + fprintf(stderr, + "%s: failed to open mountpoint for reading: %s\n", + progname, strerror(errno)); + return -1; + } + while ((ent = readdir(dp)) != NULL) { + if (strcmp(ent->d_name, ".") != 0 && + strcmp(ent->d_name, "..") != 0) { + isempty = 0; + break; + } + } + closedir(dp); + } else if (rootsize) + isempty = 0; + + if (!isempty) { + fprintf(stderr, "%s: mountpoint is not empty\n", progname); + fprintf(stderr, "%s: if you are sure this is safe, use the 'nonempty' mount option\n", progname); + return -1; + } + return 0; +} + +int fuse_mnt_check_fuseblk(void) +{ + char buf[256]; + FILE *f = fopen("/proc/filesystems", "r"); + if (!f) + return 1; + + while (fgets(buf, sizeof(buf), f)) + if (strstr(buf, "fuseblk\n")) { + fclose(f); + return 1; + } + + fclose(f); + return 0; +} diff --git a/contrib/fuse-util/mount_util.h b/contrib/fuse-util/mount_util.h deleted file mode 100644 index cf54d9d0d02..00000000000 --- a/contrib/fuse-util/mount_util.h +++ /dev/null @@ -1,17 +0,0 @@ -/* - FUSE: Filesystem in Userspace - Copyright (C) 2001-2007 Miklos Szeredi <miklos@szeredi.hu> - - This program can be distributed under the terms of the GNU LGPLv2. - See the file COPYING.LIB. -*/ - -#include <sys/types.h> - -int fuse_mnt_add_mount(const char *progname, const char *fsname, - const char *mnt, const char *type, const char *opts); -int fuse_mnt_umount(const char *progname, const char *mnt, int lazy); -char *fuse_mnt_resolve_path(const char *progname, const char *orig); -int fuse_mnt_check_empty(const char *progname, const char *mnt, - mode_t rootmode, off_t rootsize); -int fuse_mnt_check_fuseblk(void); |
