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 */