aboutsummaryrefslogtreecommitdiff
path: root/util
diff options
context:
space:
mode:
authorGravatar Max Krasnyansky <maxk@kernel.org>2011-03-11 22:59:14 -0800
committerGravatar Max Krasnyansky <maxk@kernel.org>2011-04-15 15:14:49 -0700
commit22ccf0576c432e42767a622d68ae5e14ce1aeafe (patch)
tree0bb8983a8b9fb998490fa8507fea4306960124a8 /util
parent9ca8283f6f4ba78019978d3a5e423ca3e66f58ba (diff)
fusermount: Added support for auto_unmount option
When this option is specified fusermount will become a daemon and wait for the parent to exit or die, which causes control fd to get closed. It will then try to unmount the original mountpoint.
Diffstat (limited to 'util')
-rw-r--r--util/fusermount.c63
1 files changed, 49 insertions, 14 deletions
diff --git a/util/fusermount.c b/util/fusermount.c
index 85292fb..21e55f1 100644
--- a/util/fusermount.c
+++ b/util/fusermount.c
@@ -60,6 +60,8 @@ static const char *progname;
static int user_allow_other = 0;
static int mount_max = 1000;
+static int auto_unmount = 0;
+
static const char *get_user_name(void)
{
struct passwd *pw = getpwuid(getuid());
@@ -746,6 +748,8 @@ static int do_mount(const char *mnt, char **typep, mode_t rootmode,
blkdev = 1;
} else if (opt_eq(s, len, "nonempty")) {
check_empty = 0;
+ } else if (opt_eq(s, len, "auto_unmount")) {
+ auto_unmount = 1;
} else if (!begins_with(s, "fd=") &&
!begins_with(s, "rootmode=") &&
!begins_with(s, "user_id=") &&
@@ -1158,6 +1162,7 @@ static void show_version(void)
int main(int argc, char *argv[])
{
+ sigset_t sigset;
int ch;
int fd;
int res;
@@ -1246,20 +1251,8 @@ int main(int argc, char *argv[])
exit(1);
umask(033);
- if (unmount) {
- if (geteuid() == 0)
- res = unmount_fuse(mnt, quiet, lazy);
- else {
- res = umount2(mnt, lazy ? UMOUNT_DETACH : 0);
- if (res == -1 && !quiet)
- fprintf(stderr,
- "%s: failed to unmount %s: %s\n",
- progname, mnt, strerror(errno));
- }
- if (res == -1)
- exit(1);
- return 0;
- }
+ if (unmount)
+ goto do_unmount;
commfd = getenv(FUSE_COMMFD_ENV);
if (commfd == NULL) {
@@ -1276,6 +1269,48 @@ int main(int argc, char *argv[])
res = send_fd(cfd, fd);
if (res == -1)
exit(1);
+ close(fd);
+
+ if (!auto_unmount)
+ return 0;
+
+ /* Decome a daemon and wait for the parent to exit or die.
+ ie For the control socket to get closed.
+ btw We don't want to use daemon() function here because
+ it forks and messes with the file descriptors. */
+ setsid();
+ chdir("/");
+
+ sigfillset(&sigset);
+ sigprocmask(SIG_BLOCK, &sigset, NULL);
+ lazy = 1;
+ quiet = 1;
+
+ while (1) {
+ unsigned char buf[16];
+ int n = recv(cfd, buf, sizeof(buf), 0);
+ if (!n)
+ break;
+
+ if (n < 0) {
+ if (errno == EINTR)
+ continue;
+ break;
+ }
+ }
+
+do_unmount:
+ if (geteuid() == 0)
+ res = unmount_fuse(mnt, quiet, lazy);
+ else {
+ res = umount2(mnt, lazy ? UMOUNT_DETACH : 0);
+ if (res == -1 && !quiet)
+ fprintf(stderr,
+ "%s: failed to unmount %s: %s\n",
+ progname, mnt, strerror(errno));
+ }
+ if (res == -1)
+ exit(1);
return 0;
}