Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src Use SOCK_SEQPACKET in perfuse if available. This fix file op...



details:   https://anonhg.NetBSD.org/src/rev/fbe16eb642da
branches:  trunk
changeset: 765559:fbe16eb642da
user:      manu <manu%NetBSD.org@localhost>
date:      Mon May 30 14:50:08 2011 +0000

description:
Use SOCK_SEQPACKET in perfuse if available. This fix file operations hangs
where the FUSE filesyste replied to an operation and got an ENOBUFS it did
not handle.

We now are also able to cleanly unmount

diffstat:

 lib/libperfuse/ops.c          |  11 ++++--
 lib/libperfuse/perfuse.c      |  35 ++++++++++++++------
 lib/libperfuse/perfuse_if.h   |   4 +-
 lib/libperfuse/perfuse_priv.h |   3 +-
 usr.sbin/perfused/msg.c       |  41 ++++++++++++++++++++++---
 usr.sbin/perfused/perfused.c  |  69 ++++++++++++++++++++++++++++++++----------
 usr.sbin/perfused/perfused.h  |   3 +-
 7 files changed, 126 insertions(+), 40 deletions(-)

diffs (truncated from 409 to 300 lines):

diff -r a2fc0ef7e2f7 -r fbe16eb642da lib/libperfuse/ops.c
--- a/lib/libperfuse/ops.c      Mon May 30 14:41:26 2011 +0000
+++ b/lib/libperfuse/ops.c      Mon May 30 14:50:08 2011 +0000
@@ -1,4 +1,4 @@
-/*  $NetBSD: ops.c,v 1.27 2011/05/18 15:28:12 manu Exp $ */
+/*  $NetBSD: ops.c,v 1.28 2011/05/30 14:50:08 manu Exp $ */
 
 /*-
  *  Copyright (c) 2010-2011 Emmanuel Dreyfus. All rights reserved.
@@ -844,9 +844,12 @@
                        goto out;
        }
 
-       DPRINTF("%s unmounted, exit\n", ps->ps_target);
-
-       exit(0);
+       ps->ps_umount(pu);
+
+       if (perfuse_diagflags & PDF_MISC)
+               DPRINTF("%s unmounted, exit\n", ps->ps_target);
+
+       return 0;
 out:
        ps->ps_destroy_msg(pm);
        
diff -r a2fc0ef7e2f7 -r fbe16eb642da lib/libperfuse/perfuse.c
--- a/lib/libperfuse/perfuse.c  Mon May 30 14:41:26 2011 +0000
+++ b/lib/libperfuse/perfuse.c  Mon May 30 14:50:08 2011 +0000
@@ -1,4 +1,4 @@
-/*  $NetBSD: perfuse.c,v 1.14 2011/05/18 15:25:19 manu Exp $ */
+/*  $NetBSD: perfuse.c,v 1.15 2011/05/30 14:50:08 manu Exp $ */
 
 /*-
  *  Copyright (c) 2010-2011 Emmanuel Dreyfus. All rights reserved.
@@ -148,15 +148,25 @@
        char *const argv[] = { progname, minus_i, fdstr, NULL};
        uint32_t opt;
        uint32_t optlen;
+       int sock_type = SOCK_SEQPACKET;
 
        if (strcmp(path, _PATH_FUSE) != 0)
                return open(path, flags, mode);
 
-       if ((sv[0] = socket(PF_LOCAL, SOCK_DGRAM, 0)) == -1) {
+       /* 
+        * Try SOCK_SEQPACKET then SOCK_DGRAM if unavailable
+        */
+       if ((sv[0] = socket(PF_LOCAL, SOCK_SEQPACKET, 0)) == -1) {
+               sock_type = SOCK_DGRAM;
+                DWARNX("SEQPACKET local sockets unavailable, using less "
+                      "reliable DGRAM sockets. Expect file operation hangs.");
+
+               if ((sv[0] = socket(PF_LOCAL, SOCK_DGRAM, 0)) == -1) {
 #ifdef PERFUSE_DEBUG
-               DWARN("%s:%d socket failed: %s", __func__, __LINE__);
+                       DWARN("%s:%d socket failed: %s", __func__, __LINE__);
 #endif
-               return -1;
+                       return -1;
+               }
        }
 
        /*
@@ -178,17 +188,16 @@
        sun.sun_family = AF_LOCAL;
        (void)strcpy(sun.sun_path, path);
 
-       if (connect(sv[0], sa, (socklen_t)sun.sun_len) == 0) 
+       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_DGRAM, 0, sv) != 0) {
+       if (socketpair(PF_LOCAL, sock_type, 0, sv) != 0) {
                DWARN("%s:%d: socketpair failed", __func__, __LINE__);
                return -1;
        }
@@ -510,6 +519,7 @@
        ps->ps_get_inpayload = pc->pc_get_inpayload;
        ps->ps_get_outhdr = pc->pc_get_outhdr;
        ps->ps_get_outpayload = pc->pc_get_outpayload;
+       ps->ps_umount = pc->pc_umount;
 
        return pu;
 } 
@@ -558,12 +568,15 @@
        ps = puffs_getspecific(pu);
 
        ps->ps_flags |= PS_INLOOP;
-       if (puffs_mainloop(ps->ps_pu) != 0)
+       if (puffs_mainloop(ps->ps_pu) != 0) {
                DERR(EX_OSERR, "puffs_mainloop failed");
-       DERR(EX_OSERR, "puffs_mainloop exit");
+               return -1;
+       }
 
-       /* NOTREACHED */
-       return -1;
+       /* 
+        * Normal exit after unmount
+        */
+       return 0;
 }
 
 /* ARGSUSED0 */
diff -r a2fc0ef7e2f7 -r fbe16eb642da lib/libperfuse/perfuse_if.h
--- a/lib/libperfuse/perfuse_if.h       Mon May 30 14:41:26 2011 +0000
+++ b/lib/libperfuse/perfuse_if.h       Mon May 30 14:50:08 2011 +0000
@@ -1,4 +1,4 @@
-/*  $NetBSD: perfuse_if.h,v 1.12 2011/05/18 15:22:54 manu Exp $ */
+/*  $NetBSD: perfuse_if.h,v 1.13 2011/05/30 14:50:08 manu Exp $ */
 
 /*-
  *  Copyright (c) 2010-2011 Emmanuel Dreyfus. All rights reserved.
@@ -134,6 +134,7 @@
 typedef struct fuse_in_header *(*perfuse_get_inhdr_fn)(perfuse_msg_t *);
 typedef char *(*perfuse_get_inpayload_fn)(perfuse_msg_t *);
 typedef char *(*perfuse_get_outpayload_fn)(perfuse_msg_t *);
+typedef void (*perfuse_umount_fn)(struct puffs_usermount *);
 
 struct perfuse_callbacks {
        perfuse_new_msg_fn pc_new_msg;
@@ -143,6 +144,7 @@
        perfuse_get_inpayload_fn pc_get_inpayload;
        perfuse_get_outhdr_fn pc_get_outhdr;
        perfuse_get_outpayload_fn pc_get_outpayload;
+       perfuse_umount_fn pc_umount;
 };
 
 /* 
diff -r a2fc0ef7e2f7 -r fbe16eb642da lib/libperfuse/perfuse_priv.h
--- a/lib/libperfuse/perfuse_priv.h     Mon May 30 14:41:26 2011 +0000
+++ b/lib/libperfuse/perfuse_priv.h     Mon May 30 14:50:08 2011 +0000
@@ -1,4 +1,4 @@
-/*  $NetBSD: perfuse_priv.h,v 1.17 2011/04/25 04:54:53 manu Exp $ */
+/*  $NetBSD: perfuse_priv.h,v 1.18 2011/05/30 14:50:08 manu Exp $ */
 
 /*-
  *  Copyright (c) 2010-2011 Emmanuel Dreyfus. All rights reserved.
@@ -65,6 +65,7 @@
        perfuse_get_inpayload_fn ps_get_inpayload;
        perfuse_get_outhdr_fn ps_get_outhdr;
        perfuse_get_outpayload_fn ps_get_outpayload;
+       perfuse_umount_fn ps_umount;
 };
 
 
diff -r a2fc0ef7e2f7 -r fbe16eb642da usr.sbin/perfused/msg.c
--- a/usr.sbin/perfused/msg.c   Mon May 30 14:41:26 2011 +0000
+++ b/usr.sbin/perfused/msg.c   Mon May 30 14:50:08 2011 +0000
@@ -1,4 +1,4 @@
-/*  $NetBSD: msg.c,v 1.12 2011/05/09 08:51:18 manu Exp $ */
+/*  $NetBSD: msg.c,v 1.13 2011/05/30 14:50:08 manu Exp $ */
 
 /*-
  *  Copyright (c) 2010 Emmanuel Dreyfus. All rights reserved.
@@ -56,11 +56,22 @@
        struct sockaddr_un sun;
        const struct sockaddr *sa;
        uint32_t opt;
+       int sock_type = SOCK_SEQPACKET;
 
        (void)unlink(_PATH_FUSE);
 
-       if ((s = socket(AF_LOCAL, SOCK_DGRAM, 0)) == -1)
-               err(EX_OSERR, "socket failed");
+       /*
+        * Try SOCK_SEQPACKET and fallback to SOCK_DGRAM 
+        * if unavaible
+        */
+       if ((s = socket(PF_LOCAL, SOCK_SEQPACKET, 0)) == -1) {
+               warnx("SEQPACKET local sockets unavailable, using less "
+                     "reliable DGRAM sockets. Expect file operation hangs.");
+
+               sock_type = SOCK_DGRAM;
+               if ((s = socket(PF_LOCAL, SOCK_DGRAM, 0)) == -1)
+                       err(EX_OSERR, "socket failed");
+       }
 
        sa = (const struct sockaddr *)(void *)&sun;
        sun.sun_len = sizeof(sun);
@@ -90,8 +101,10 @@
        if (bind(s, sa, (socklen_t )sun.sun_len) == -1)
                err(EX_OSERR, "cannot open \"%s\" socket", _PATH_FUSE);
 
-       if (connect(s, sa, (socklen_t )sun.sun_len) == -1)
-               err(EX_OSERR, "cannot open \"%s\" socket", _PATH_FUSE);
+       if (sock_type == SOCK_DGRAM) {
+               if (connect(s, sa, (socklen_t )sun.sun_len) == -1)
+                       err(EX_OSERR, "cannot open \"%s\" socket", _PATH_FUSE);
+       }
 
        return s;
 }
@@ -580,6 +593,7 @@
                switch(errno) {
                case EAGAIN:
                case ENOBUFS:
+               case EMSGSIZE:
                        return 0;
                        break;
                default:
@@ -676,3 +690,20 @@
        /* NOTREACHED */
        return;
 }
+
+void
+perfuse_umount(pu)
+       struct puffs_usermount *pu;
+{
+       int fd;
+
+       fd = (int)(long)perfuse_getspecific(pu);
+
+       if (shutdown(fd, SHUT_RDWR) != 0)
+               DWARN("shutdown() failed");
+
+       if (perfuse_diagflags & PDF_MISC)
+               DPRINTF("unmount");
+
+       return;
+}
diff -r a2fc0ef7e2f7 -r fbe16eb642da usr.sbin/perfused/perfused.c
--- a/usr.sbin/perfused/perfused.c      Mon May 30 14:41:26 2011 +0000
+++ b/usr.sbin/perfused/perfused.c      Mon May 30 14:50:08 2011 +0000
@@ -1,4 +1,4 @@
-/*  $NetBSD: perfused.c,v 1.12 2011/04/25 04:30:59 manu Exp $ */
+/*  $NetBSD: perfused.c,v 1.13 2011/05/30 14:50:08 manu Exp $ */
 
 /*-
  *  Copyright (c) 2010 Emmanuel Dreyfus. All rights reserved.
@@ -55,7 +55,7 @@
 static int parse_debug(char *);
 static void siginfo_handler(int);
 static int parse_options(int, char **);
-static void get_mount_info(int, struct perfuse_mount_info *);
+static void get_mount_info(int, struct perfuse_mount_info *, int);
 int main(int, char **);
 
 /*
@@ -63,6 +63,7 @@
  */
 #define  PMNT_DEVFUSE  0x0     /* We use /dev/fuse */
 #define  PMNT_SOCKPAIR 0x1     /* We use socketpair */
+#define  PMNT_DGRAM    0x2     /* We use SOCK_DGRAM sockets */
 
 
 static int
@@ -94,9 +95,10 @@
 }
 
 static void
-get_mount_info(fd, pmi)
+get_mount_info(fd, pmi, sock_type)
        int fd;
        struct perfuse_mount_info *pmi;
+       int sock_type;
 {
        struct perfuse_mount_out *pmo;
        struct sockcred cred;
@@ -178,9 +180,9 @@
        pmi->pmi_uid = cred.sc_euid;
 
        /*
-        * Connect to the remote socket, if provided
+        * Connect to the remote socket if provided ans using SOCK_DGRAM
         */
-       if (sock) {
+       if ((sock_type == SOCK_DGRAM) && sock) {
                const struct sockaddr *sa;
                struct sockaddr_un sun;
 
@@ -207,6 +209,7 @@
        int ro_flag;
        pid_t pid;
        int flags;
+       int sock_type;
 
        pid = (perfuse_diagflags & PDF_FOREGROUND) ? 0 : fork();
        switch(pid) {
@@ -224,7 +227,8 @@
        /*
         * Mount information (source, target, mount flags...)
         */
-       get_mount_info(fd, &pmi);
+       sock_type = pmnt_flags & PMNT_DGRAM ? SOCK_DGRAM : SOCK_SEQPACKET;
+       get_mount_info(fd, &pmi, sock_type);
 
        /*
         * Check that peer owns mountpoint and read (and write) on it?
@@ -245,6 +249,7 @@
        pc.pc_get_inpayload = perfuse_get_inpayload;
        pc.pc_get_outhdr = perfuse_get_outhdr;



Home | Main Index | Thread Index | Old Index