Module Name:    src
Committed By:   manu
Date:           Fri Aug 27 09:58:17 UTC 2010

Modified Files:
        src/lib/libperfuse: ops.c perfuse.c perfuse_if.h perfuse_priv.h
        src/usr.sbin/perfused: msg.c perfused.8 perfused.c perfused.h

Log Message:
- if perfused is not already started (cannot connect to /dev/fuse),
FUSE filesystems will attempt to start it on their own, and will
communicate using a socketpair

- do not advertise NULL file handle as being valid when sending themback to the 
FUSE filesystem.

- unmount if we cannot talk to the FUSE process anymore

- set calling process gid properly

- debug message cleanup


To generate a diff of this commit:
cvs rdiff -u -r1.2 -r1.3 src/lib/libperfuse/ops.c \
    src/lib/libperfuse/perfuse_if.h src/lib/libperfuse/perfuse_priv.h
cvs rdiff -u -r1.1 -r1.2 src/lib/libperfuse/perfuse.c
cvs rdiff -u -r1.1 -r1.2 src/usr.sbin/perfused/msg.c \
    src/usr.sbin/perfused/perfused.h
cvs rdiff -u -r1.2 -r1.3 src/usr.sbin/perfused/perfused.8 \
    src/usr.sbin/perfused/perfused.c

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/lib/libperfuse/ops.c
diff -u src/lib/libperfuse/ops.c:1.2 src/lib/libperfuse/ops.c:1.3
--- src/lib/libperfuse/ops.c:1.2	Thu Aug 26 13:29:01 2010
+++ src/lib/libperfuse/ops.c	Fri Aug 27 09:58:17 2010
@@ -1,4 +1,4 @@
-/*  $NetBSD: ops.c,v 1.2 2010/08/26 13:29:01 manu Exp $ */
+/*  $NetBSD: ops.c,v 1.3 2010/08/27 09:58:17 manu Exp $ */
 
 /*-
  *  Copyright (c) 2010 Emmanuel Dreyfus. All rights reserved.
@@ -667,7 +667,7 @@
 	svfsb->f_fsidx.__fsid_val[1] = 0;
 	svfsb->f_fsid = ps->ps_fsid;
 	svfsb->f_namemax = MAXPATHLEN;	/* XXX */
-	svfsb->f_owner = ps->ps_uid;
+	svfsb->f_owner = ps->ps_owner_uid;
 
 	(void)strlcpy(svfsb->f_mntonname, ps->ps_target, _VFS_NAMELEN);
 
@@ -1206,7 +1206,8 @@
 	if (PERFUSE_NODE_DATA(opc)->pnd_flags & PND_OPEN) {
 		fh = perfuse_get_fh(opc);
 		fsi->fh = fh;
-		fsi->valid |= FUSE_FATTR_FH;
+		if (fh != FUSE_UNKNOWN_FH)
+			fsi->valid |= FUSE_FATTR_FH;
 	}
 
 	if (vap->va_size != (u_quad_t)PUFFS_VNOVAL) {
Index: src/lib/libperfuse/perfuse_if.h
diff -u src/lib/libperfuse/perfuse_if.h:1.2 src/lib/libperfuse/perfuse_if.h:1.3
--- src/lib/libperfuse/perfuse_if.h:1.2	Thu Aug 26 13:29:01 2010
+++ src/lib/libperfuse/perfuse_if.h	Fri Aug 27 09:58:17 2010
@@ -1,4 +1,4 @@
-/*  $NetBSD: perfuse_if.h,v 1.2 2010/08/26 13:29:01 manu Exp $ */
+/*  $NetBSD: perfuse_if.h,v 1.3 2010/08/27 09:58:17 manu Exp $ */
 
 /*-
  *  Copyright (c) 2010 Emmanuel Dreyfus. All rights reserved.
@@ -29,6 +29,7 @@
 #define _REFUSE_PERFUSE_H
 
 #define _PATH_FUSE "/dev/fuse"
+#define _PATH_PERFUSED "/usr/sbin/perfused"
 #define FUSE_COMMFD_ENV "_FUSE_COMMFD" 
 #define PERFUSE_MOUNT_MAGIC "noFuseRq"
 #define PERFUSE_UNKNOWN_INO 0xffffffff
@@ -201,5 +202,6 @@
 const char *perfuse_opname(int);
 void perfuse_fs_init(struct puffs_usermount *);
 int perfuse_mainloop(struct puffs_usermount *);
+int perfuse_unmount(struct puffs_usermount *);
 
 #endif /* _REFUSE_PERFUSE_H */
Index: src/lib/libperfuse/perfuse_priv.h
diff -u src/lib/libperfuse/perfuse_priv.h:1.2 src/lib/libperfuse/perfuse_priv.h:1.3
--- src/lib/libperfuse/perfuse_priv.h:1.2	Thu Aug 26 13:29:01 2010
+++ src/lib/libperfuse/perfuse_priv.h	Fri Aug 27 09:58:17 2010
@@ -1,4 +1,4 @@
-/*  $NetBSD: perfuse_priv.h,v 1.2 2010/08/26 13:29:01 manu Exp $ */
+/*  $NetBSD: perfuse_priv.h,v 1.3 2010/08/27 09:58:17 manu Exp $ */
 
 /*-
  *  Copyright (c) 2010 Emmanuel Dreyfus. All rights reserved.
@@ -41,9 +41,7 @@
 	void *ps_private;	/* Private field for libperfuse user */
 	struct puffs_usermount *ps_pu;
 	struct puffs_node *ps_root;
-	uid_t ps_uid;
-	gid_t ps_gid;
-	pid_t ps_pid;
+	uid_t ps_owner_uid;
 	int ps_flags;
 #define PS_NO_ACCESS	0x0001	/* access is unimplemented; */
 #define PS_NO_FSYNC	0x0002	/* fsync is unimplemented */

Index: src/lib/libperfuse/perfuse.c
diff -u src/lib/libperfuse/perfuse.c:1.1 src/lib/libperfuse/perfuse.c:1.2
--- src/lib/libperfuse/perfuse.c:1.1	Wed Aug 25 07:16:00 2010
+++ src/lib/libperfuse/perfuse.c	Fri Aug 27 09:58:17 2010
@@ -1,4 +1,4 @@
-/*  $NetBSD: perfuse.c,v 1.1 2010/08/25 07:16:00 manu Exp $ */
+/*  $NetBSD: perfuse.c,v 1.2 2010/08/27 09:58:17 manu Exp $ */
 
 /*-
  *  Copyright (c) 2010 Emmanuel Dreyfus. All rights reserved.
@@ -101,16 +101,21 @@
 	int flags;
 	mode_t mode;
 {
-	int s;
+	int sv[2];
 	struct sockaddr_un sun;
 	struct sockaddr *sa;
+	char progname[] = _PATH_PERFUSED;
+	char minus_i[] = "-i";
+	char fdstr[16];
+	char *const argv[] = { progname, minus_i, fdstr, NULL};
+	char *const envp[] = { NULL };
 
 	if (strcmp(path, _PATH_FUSE) != 0)
 		return open(path, flags, mode);
 
-	if ((s = socket(PF_LOCAL, SOCK_STREAM, 0)) == -1) {
+	if ((sv[0] = socket(PF_LOCAL, SOCK_STREAM, 0)) == -1) {
 #ifdef PERFUSE_DEBUG
-		printf("%s:%d socket failed: %s", 
+		printf("%s:%d socket failed: %s\n", 
 		       __func__, __LINE__, strerror(errno));
 #endif
 		return -1;
@@ -121,16 +126,49 @@
 	sun.sun_family = AF_LOCAL;
 	(void)strcpy(sun.sun_path, path);
 
-	if (connect(s, sa, (socklen_t)sun.sun_len) == -1) {
+	if (connect(sv[0], sa, (socklen_t)sun.sun_len) == 0) 
+		return sv[0];
+
+
+	/*
+	 * Attempt to run perfused on our own
+	 * if it does not run yet; In that case
+	 * we will talk using a socketpair 
+	 * instead of /dev/fuse.
+	 */
+	if (socketpair(PF_LOCAL, SOCK_STREAM, 0, sv) != 0) {
 #ifdef PERFUSE_DEBUG
-		printf("%s:%d connect failed: %s", 
+		printf("%s:%d: socketpair failed: %s\n",
 		       __func__, __LINE__, strerror(errno));
 #endif
-		close(s);
 		return -1;
 	}
 
-	return s;
+	(void)sprintf(fdstr, "%d", sv[1]);
+
+	switch(fork()) {
+	case -1:
+#ifdef PERFUSE_DEBUG
+		printf("%s:%d: fork failed: %s\n",
+		       __func__, __LINE__, strerror(errno));
+#endif
+		return -1;
+		/* NOTREACHED */
+		break;
+	case 0:
+		(void)execve(argv[0], argv, envp);
+#ifdef PERFUSE_DEBUG
+		printf("%s:%d: execve failed: %s\n",
+		       __func__, __LINE__, strerror(errno));
+#endif
+		return -1;
+		/* NOTREACHED */
+		break;
+	default:
+		break;
+	}
+	
+	return sv[0];
 }
 
 
@@ -188,7 +226,7 @@
 
 	if (write(s, &pmo, sizeof(pmo)) != sizeof(pmo)) {
 #ifdef PERFUSE_DEBUG
-		printf("%s:%d short write", __func__, __LINE__);
+		printf("%s:%d short write\n", __func__, __LINE__);
 #endif
 		return -1;
 	}
@@ -197,7 +235,7 @@
 		len = pmo.pmo_source_len;
 		if (write(s, source, len) != (ssize_t)len) {
 #ifdef PERFUSE_DEBUG
-			printf("%s:%d short write", __func__, __LINE__);
+			printf("%s:%d short write\n", __func__, __LINE__);
 #endif
 			return -1;
 		}
@@ -207,7 +245,7 @@
 		len = pmo.pmo_target_len;
 		if (write(s, target, len) != (ssize_t)len) {
 #ifdef PERFUSE_DEBUG
-			printf("%s:%d short write", __func__, __LINE__);
+			printf("%s:%d short write\n", __func__, __LINE__);
 #endif
 			return -1;
 		}
@@ -217,7 +255,7 @@
 		len = pmo.pmo_filesystemtype_len;
 		if (write(s, filesystemtype, len) != (ssize_t)len) {
 #ifdef PERFUSE_DEBUG
-			printf("%s:%d short write", __func__, __LINE__);
+			printf("%s:%d short write\n", __func__, __LINE__);
 #endif
 			return -1;
 		}
@@ -227,7 +265,7 @@
 		len = pmo.pmo_data_len;
 		if (write(s, data, len) != (ssize_t)len) {
 #ifdef PERFUSE_DEBUG
-			printf("%s:%d short write", __func__, __LINE__);
+			printf("%s:%d short write\n", __func__, __LINE__);
 #endif
 			return -1;
 		}
@@ -262,7 +300,7 @@
 	struct puffs_pathobj *po_root;
 
 	ps = init_state();
-	ps->ps_uid = pmi->pmi_uid;
+	ps->ps_owner_uid = pmi->pmi_uid;
 
 	if (pmi->pmi_source)
 		ps->ps_source = strdup(pmi->pmi_source);
@@ -274,7 +312,7 @@
 	/*
 	 * Some options are forbidden for non root users
 	 */
-	if (ps->ps_uid != 0)
+	if (ps->ps_owner_uid != 0)
 	    ps->ps_mountflags |= MNT_NOSUID|MNT_NODEV;
 
 	PUFFSOP_INIT(pops);
@@ -414,3 +452,14 @@
 {
 	return PERFUSE_NODE_DATA(opc)->pnd_ino;
 }
+
+int
+perfuse_unmount(pu)
+	struct puffs_usermount *pu;
+{
+	struct perfuse_state *ps;
+
+	ps = puffs_getspecific(pu);
+
+	return unmount(ps->ps_target, MNT_FORCE);
+}

Index: src/usr.sbin/perfused/msg.c
diff -u src/usr.sbin/perfused/msg.c:1.1 src/usr.sbin/perfused/msg.c:1.2
--- src/usr.sbin/perfused/msg.c:1.1	Wed Aug 25 07:18:01 2010
+++ src/usr.sbin/perfused/msg.c	Fri Aug 27 09:58:17 2010
@@ -1,4 +1,4 @@
-/*  $NetBSD: msg.c,v 1.1 2010/08/25 07:18:01 manu Exp $ */
+/*  $NetBSD: msg.c,v 1.2 2010/08/27 09:58:17 manu Exp $ */
 
 /*-
  *  Copyright (c) 2010 Emmanuel Dreyfus. All rights reserved.
@@ -137,7 +137,7 @@
 	fih->pid = 0;
 	if (cred != NULL) {
 		(void)puffs_cred_getuid(cred, &fih->uid);
-		(void)puffs_cred_getuid(cred, &fih->uid);
+		(void)puffs_cred_getgid(cred, &fih->gid);
 	}
 	if ((pcc = puffs_cc_getcc(pu)) != NULL)
 		(void)puffs_cc_getcaller(pcc, (pid_t *)&fih->pid, NULL);
@@ -597,3 +597,31 @@
 	return;	
 }
 
+void
+perfuse_fdnotify(pu, fd, what)
+	struct puffs_usermount *pu;
+	int fd;
+	int what;
+{
+	if (fd != (int)perfuse_getspecific(pu))
+		DERRX(EX_SOFTWARE, "%s: unexpected notification for fd = %d",
+		      __func__, fd); 
+
+	if ((what != PUFFS_FBIO_READ) && (what != PUFFS_FBIO_WRITE))
+		DERRX(EX_SOFTWARE, "%s: unexpected notification what = 0x%x",
+		      __func__, what); 
+
+	if (perfuse_unmount(pu) != 0)
+		DWARN("unmount() failed");
+
+	if (shutdown(fd, SHUT_RDWR) != 0)
+		DWARN("shutdown() failed");
+
+	if (perfuse_diagflags & PDF_MISC)
+		DPRINTF("Exit");
+	
+	exit(0);
+	
+	/* NOTREACHED */
+	return;
+}
Index: src/usr.sbin/perfused/perfused.h
diff -u src/usr.sbin/perfused/perfused.h:1.1 src/usr.sbin/perfused/perfused.h:1.2
--- src/usr.sbin/perfused/perfused.h:1.1	Wed Aug 25 07:18:01 2010
+++ src/usr.sbin/perfused/perfused.h	Fri Aug 27 09:58:17 2010
@@ -1,4 +1,4 @@
-/*  $NetBSD: perfused.h,v 1.1 2010/08/25 07:18:01 manu Exp $ */
+/*  $NetBSD: perfused.h,v 1.2 2010/08/27 09:58:17 manu Exp $ */
 
 /*-
  *  Copyright (c) 2010 Emmanuel Dreyfus. All rights reserved.
@@ -52,6 +52,7 @@
 int perfuse_cmpframe(struct puffs_usermount *, 
      struct puffs_framebuf *, struct puffs_framebuf *, int *);
 void perfuse_gotframe(struct puffs_usermount *, struct puffs_framebuf *);
+void perfuse_fdnotify(struct puffs_usermount *, int, int);
 
 struct fuse_out_header *perfuse_get_outhdr(perfuse_msg_t *);
 struct fuse_in_header *perfuse_get_inhdr(perfuse_msg_t *);

Index: src/usr.sbin/perfused/perfused.8
diff -u src/usr.sbin/perfused/perfused.8:1.2 src/usr.sbin/perfused/perfused.8:1.3
--- src/usr.sbin/perfused/perfused.8:1.2	Thu Aug 26 13:29:02 2010
+++ src/usr.sbin/perfused/perfused.8	Fri Aug 27 09:58:17 2010
@@ -1,4 +1,4 @@
-.\" $NetBSD: perfused.8,v 1.2 2010/08/26 13:29:02 manu Exp $
+.\" $NetBSD: perfused.8,v 1.3 2010/08/27 09:58:17 manu Exp $
 .\"
 .\" Copyright (c) 2010 Emmanuel Dreyfus. All rights reserved.
 .\"
@@ -34,6 +34,7 @@
 .Op Fl f
 .Op Fl d Ar types
 .Op Fl s
+.Op Fl i fd
 .Sh DESCRIPTION
 .Nm
 is a userland daemon mplementing the FUSE kernel level API. It creates a
@@ -106,6 +107,15 @@
 .El
 .It Fl s
 Enable debug output only when receiving SIGINFO.
+.It Fl i Ar fd
+Do not open
+.Pa /dev/fuse
+but use the socket available from file descriptor
+.Ar fd .
+This is used when 
+.Nm 
+is started from 
+.Xr libperfuse 3 .
 .El
 .Sh ERRORS
 The program logs to the syslog daemon as facility
Index: src/usr.sbin/perfused/perfused.c
diff -u src/usr.sbin/perfused/perfused.c:1.2 src/usr.sbin/perfused/perfused.c:1.3
--- src/usr.sbin/perfused/perfused.c:1.2	Thu Aug 26 13:29:02 2010
+++ src/usr.sbin/perfused/perfused.c	Fri Aug 27 09:58:17 2010
@@ -1,4 +1,4 @@
-/*  $NetBSD: perfused.c,v 1.2 2010/08/26 13:29:02 manu Exp $ */
+/*  $NetBSD: perfused.c,v 1.3 2010/08/27 09:58:17 manu Exp $ */
 
 /*-
  *  Copyright (c) 2010 Emmanuel Dreyfus. All rights reserved.
@@ -52,10 +52,10 @@
 
 static int getpeerid(int, pid_t *, uid_t *, gid_t *);
 static int access_mount(const char *, uid_t, int);
-static int accept_new_mount(int);
+static void new_mount(int);
 static int parse_debug(char *);
 static void siginfo_handler(int);
-static void parse_options(int, char **);
+static int parse_options(int, char **);
 static void get_mount_info(int, struct perfuse_mount_info *);
 int main(int, char **);
 
@@ -171,32 +171,17 @@
 	return;
 }
 
-static int
-accept_new_mount(s)
-	int s;
+static void
+new_mount(fd)
+	int fd;
 {
 	struct puffs_usermount *pu;
-	struct sockaddr_storage ss;
-	socklen_t ss_len;
-	struct sockaddr *sa;
 	struct perfuse_mount_info pmi;
 	struct perfuse_callbacks pc;
 	int ro_flag;
 	pid_t pid;
-	int fd;
 	int flags;
 
-#ifdef PERFUSE_DEBUG
-	DPRINTF("waiting connexion\n");
-#endif
-	sa = (struct sockaddr *)(void *)&ss;
-	ss_len = sizeof(ss);
-	if ((fd = accept(s, sa, &ss_len)) == -1)
-		DERR(EX_OSERR,  "accept failed");
-
-#ifdef PERFUSE_DEBUG
-	DPRINTF("connexion accepted\n");
-#endif
 
 	pid = (perfuse_diagflags & PDF_FOREGROUND) ? 0 : fork();
 	switch(pid) {
@@ -206,7 +191,7 @@
 	case 0:
 		break;
 	default:
-		return fd;
+		return;
 		/* NOTREACHED */
 		break;
 	}
@@ -245,7 +230,7 @@
 	pu = perfuse_init(&pc, &pmi);
 	
 	puffs_framev_init(pu, perfuse_readframe, perfuse_writeframe, 
-			  perfuse_cmpframe, perfuse_gotframe, NULL);
+			  perfuse_cmpframe, perfuse_gotframe, perfuse_fdnotify);
 
 	if (puffs_framev_addfd(pu, fd, PUFFS_FBIO_READ|PUFFS_FBIO_WRITE) == -1)
 		DERR(EX_SOFTWARE, "puffs_framev_addfd failed");
@@ -269,7 +254,12 @@
 	/*
 	 * Hand over control to puffs main loop.
 	 */
-	return perfuse_mainloop(pu);
+	(void)perfuse_mainloop(pu);
+
+	DERRX(EX_SOFTWARE, "perfuse_mainloop exit");
+
+	/* NOTREACHED */
+	return;
 }
 
 static int 
@@ -325,17 +315,18 @@
 	return;
 }
 
-static void
+static int
 parse_options(argc, argv)
 	int argc;
 	char **argv;
 {
 	int ch;
 	int foreground = 0;
+	int retval = -1;
 
 	perfuse_diagflags = PDF_FOREGROUND | PDF_SYSLOG;
 
-	while ((ch = getopt(argc, argv, "d:fs")) != -1) {
+	while ((ch = getopt(argc, argv, "d:fsi:")) != -1) {
 		switch (ch) {
 		case 'd':
 			perfuse_diagflags |= parse_debug(optarg);
@@ -347,8 +338,12 @@
 		case 'f':
 			foreground = 1;
 			break;
+		case 'i':
+			retval = atoi(optarg);
+			foreground = 1;
+			break;
 		default:
-			DERR(EX_USAGE, "%s [-d level] [-s] [-f]", argv[0]);
+			DERR(EX_USAGE, "%s [-d level] [-s] [-f] [-i fd]", argv[0]);
 			break;
 		}
 	}
@@ -356,7 +351,7 @@
 	if (!foreground)
 		perfuse_diagflags &= ~PDF_FOREGROUND;
 
-	return; 
+	return retval; 
 }
 
 int
@@ -366,7 +361,7 @@
 {
 	int s;
 
-	parse_options(argc, argv);
+	s = parse_options(argc, argv);
 
 	if (perfuse_diagflags & PDF_SYSLOG)
 		openlog("perfused", 0, LOG_DAEMON);
@@ -375,10 +370,32 @@
 		if (daemon(0, 0) != 0)
 			DERR(EX_OSERR, "daemon failed");
 
+	if (s != -1) {
+		new_mount(s);
+		DERRX(EX_SOFTWARE, "new_mount exit while -i is used");
+	}
+
 	s = perfuse_open_sock();
 	
 	do {
-		(void)accept_new_mount(s);
+		struct sockaddr *sa;
+		struct sockaddr_storage ss;
+		socklen_t ss_len;
+		int fd;
+
+#ifdef PERFUSE_DEBUG
+		if (perfuse_diagflags & PDF_MISC)
+			DPRINTF("waiting connexion\n");
+#endif
+		sa = (struct sockaddr *)(void *)&ss;
+		ss_len = sizeof(ss);
+		if ((fd = accept(s, sa, &ss_len)) == -1)
+			DERR(EX_OSERR,  "accept failed");
+#ifdef PERFUSE_DEBUG
+		if (perfuse_diagflags & PDF_MISC)
+			DPRINTF("connexion accepted\n");
+#endif
+		new_mount(fd);
 	} while (1 /* CONSTCOND */);
 		
 	/* NOTREACHED */

Reply via email to