Page MenuHomeFreeBSD

D51549.diff
No OneTemporary

D51549.diff

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

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)

Event Timeline