Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F143117104
D51549.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
4 KB
Referenced Files
None
Subscribers
None
D51549.diff
View Options
diff --git a/sbin/mount_fusefs/mount_fusefs.c b/sbin/mount_fusefs/mount_fusefs.c
--- a/sbin/mount_fusefs/mount_fusefs.c
+++ b/sbin/mount_fusefs/mount_fusefs.c
@@ -34,10 +34,12 @@
*/
#include <sys/param.h>
+#include <sys/event.h>
#include <sys/mount.h>
-#include <sys/uio.h>
#include <sys/stat.h>
#include <sys/sysctl.h>
+#include <sys/uio.h>
+#include <sys/user.h>
#include <err.h>
#include <stdio.h>
@@ -112,6 +114,112 @@
};
#define DEFAULT_MOUNT_FLAGS ALTF_PRIVATE
+#define AUTO_UNMOUNT_OPTION 128
+
+static int
+resolve_pid(pid_t pid, struct kinfo_proc *out)
+{
+ int mib[4];
+ size_t size = sizeof(struct kinfo_proc);
+
+ mib[0] = CTL_KERN;
+ mib[1] = KERN_PROC;
+ mib[2] = KERN_PROC_PID;
+ mib[3] = pid;
+ return (sysctl(mib, 4, out, &size, NULL, 0));
+}
+
+static int
+auto_unmount_main(const char *mountpoint, const char *args)
+{
+ pid_t parent_pid;
+ struct timeval parent_start;
+ fsid_t fsid;
+ int parsed;
+ struct kinfo_proc proc_info;
+ struct statfs stat_buf;
+ int kq;
+ struct kevent kev;
+
+ /*
+ * The caller should pass the following info for auto unmount to work:
+ * parent's PID to monitor
+ * parent PID's starting time to avoid races
+ * fsid values to let us be sure we're unmounting the right FS
+ */
+ parsed = sscanf(args, "%d,%ld,%ld,%d,%d", &parent_pid,
+ &parent_start.tv_sec, &parent_start.tv_usec,
+ &fsid.val[0], &fsid.val[1]);
+ if (parsed != 5) {
+ warnx("fail to parse auto-unmount args");
+ return (1);
+ }
+
+ kq = kqueue();
+ if (kq == -1) {
+ warn("fail to create kqueue");
+ return (1);
+ }
+
+ EV_SET(&kev, parent_pid, EVFILT_PROC, EV_ADD | EV_ENABLE, NOTE_EXIT,
+ 0, NULL);
+ if (kevent(kq, &kev, 1, NULL, 0, NULL) == -1) {
+ warn("fail to setup process monitor");
+ close(kq);
+ return (1);
+ }
+
+ /* If the process is already gone, unmount immediately and exit. */
+ if (resolve_pid(parent_pid, &proc_info) != 0)
+ goto unmount;
+
+ /*
+ * It might be a different process with the same PID, so
+ * check starting times.
+ */
+ if (proc_info.ki_start.tv_sec != parent_start.tv_sec ||
+ proc_info.ki_start.tv_usec != parent_start.tv_usec)
+ goto unmount;
+
+ /* Wait for the parent process to die. */
+ if (kevent(kq, NULL, 0, &kev, 1, NULL) == -1) {
+ warn("failure while waiting for process to die");
+ close(kq)
+ return (1);
+ }
+ if ((kev.fflags & NOTE_EXIT) == 0) {
+ warnx("unknown event while waiting for process to die");
+ close(kq);
+ return (1);
+ }
+
+unmount:
+ close(kq);
+
+ if (statfs(mountpoint, &stat_buf) != 0) {
+ warn("fail to statfs the mountpoint");
+ return (1);
+ }
+ /*
+ * Do not unmount if fsid's differ - otherwise we'll unmount
+ * someone's else FS.
+ */
+ if (stat_buf.f_fsid.val[0] != fsid.val[0] ||
+ stat_buf.f_fsid.val[1] != fsid.val[1])
+ return (1);
+ /* Refuse to unmount anything other than fuse. */
+ if (strncmp(stat_buf.f_fstypename, "fusefs", 6))
+ return (1);
+ /*
+ * For usermount case we should only unmount filesystems
+ * mounted by the same user.
+ */
+ if (stat_buf.f_owner != proc_info.ki_ruid)
+ return (1);
+
+ unmount(mountpoint, 0);
+ return (0);
+}
int
main(int argc, char *argv[])
@@ -136,12 +244,14 @@
{"mountpath", required_argument, NULL, 'm'},
{"version", no_argument, NULL, 'V'},
{"help", no_argument, NULL, 'h'},
+ {"auto-unmount", required_argument, NULL, AUTO_UNMOUNT_OPTION},
{0,0,0,0}
};
- int pid = 0;
+ pid_t pid = 0;
int fd = -1, fdx;
char *ep;
char *daemon_str = NULL, *daemon_opts = NULL;
+ char *auto_unmount_args = NULL;
/*
* We want a parsing routine which is not sensitive to
@@ -238,6 +348,11 @@
case 'V':
showversion();
break;
+ case AUTO_UNMOUNT_OPTION:
+ if (auto_unmount_args)
+ errx(1, "auto-unmount args specified inconsistently");
+ auto_unmount_args = optarg;
+ break;
case '\0':
break;
case '?':
@@ -277,6 +392,9 @@
if (! (dev && dir))
errx(1, "missing special and/or mountpoint");
+ if (auto_unmount_args)
+ return (auto_unmount_main(dir, auto_unmount_args));
+
for (mo = mopts; mo->m_flag; ++mo) {
if (altflags & mo->m_flag) {
int iov_done = 0;
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Tue, Jan 27, 4:45 AM (11 h, 37 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
28050576
Default Alt Text
D51549.diff (4 KB)
Attached To
Mode
D51549: fusefs: Support for the auto_unmount FUSE option
Attached
Detach File
Event Timeline
Log In to Comment