mirror of
https://github.com/facebook/sapling.git
synced 2024-10-10 08:47:12 +03:00
f9ba8e3c57
Summary: We're seeing a trivially reproducible deadlock upon upgrading to osxfuse 3.11: ``` task vm_map ipc_space #acts flags pid process io_policy wq_state command 0xffffff802a794358 0xffffff802a6dcf00 0xffffff80214b0980 1 D 1348 0xffffff8024772380 0 0 0 edenfs thread thread_id processor base pri sched_mode io_policy state ast waitq wait_event wmesg thread_name 0xffffff802146f000 0x1d11 0xffffff8080085000 31 31 timeshare WU 0xffffff807f74bb40 0xffffff8019b15af0 fu_ini edenfs_privhelp kernel_stack = 0xffffff80a0800000 stacktop = 0xffffff80a0803590 0xffffff80a0803590 0xffffff800dc0c475 machine_switch_context((thread_t) old = 0xffffff802146f000, (thread_continue_t) continuation = 0x0000000000000000, (thread_t) new = 0xffffff8018963000) 0xffffff80a0803610 0xffffff800dab1134 thread_invoke((thread_t) self = 0xffffff802146f000, (thread_t) thread = 0xffffff8018963000, (ast_t) reason = 0) 0xffffff80a0803670 0xffffff800daaf47c thread_block_reason((thread_continue_t) continuation = <>, , (void *) parameter = <>, , (ast_t) reason = <>, ) 0xffffff80a08036b0 0xffffff800daa0768 thread_block [inlined]((thread_continue_t) continuation = <>, ) 0xffffff80a08036b0 0xffffff800daa075d lck_mtx_sleep((lck_mtx_t *) lck = 0xffffff8027379870, (lck_sleep_action_t) lck_sleep_action = 1, (event_t) event = 0x0000000000000001, (wait_interrupt_t) interruptible = 0) 0xffffff80a0803730 0xffffff800e03239a _sleep((caddr_t) chan = 0xffffff8019b15af0 "\x03", (int) pri = 1024, (const char *) wmsg = 0xffffff7f903025fa "fu_ini", (u_int64_t) abstime = 0, (int (*)(int)) continuation = 0x0000000000000000, (lck_mtx_t *) mtx = 0xffffff8027379870) 0xffffff80a0803770 0xffffff800e032962 msleep((void *) chan = 0xffffff8019b15af0, (lck_mtx_t *) mtx = 0xffffff8027379870, (int) pri = 1024, (const char *) wmsg = 0xffffff7f903025fa "fu_ini", (timespec *) ts = <>, ) 0xffffff80a08037c0 0xffffff7f902fd5b8 fuse_internal_msleep((void *) chan = 0xffffff8019b15af0, (lck_mtx_t *) mtx = 0xffffff8027379870, (int) pri = 1024, (const char *) wmesg = 0xffffff7f903025fa "fu_ini", (timespec *) ts = 0x0000000000000000, (fuse_data *) data = 0xffffff8019b15a00) 0xffffff80a08037f0 0xffffff7f902f01c5 fdata_wait_init_locked [inlined](void) 0xffffff80a08037f0 0xffffff7f902f01ab fuse_ticket_fetch((fuse_data *) data = 0xffffff8019b15a00) 0xffffff80a0803840 0xffffff7f902f07e7 fdisp_make((fuse_dispatcher *) fdip = 0xffffff80a0803860, (fuse_opcode) op = FUSE_STATFS, (fuse_data *) data = <register rdx is not available>, , (uint64_t) nid = 1, (vfs_context_t) context = 0xffffff8020ed8168) 0xffffff80a08038c0 0xffffff7f90301608 fuse_vfsop_getattr [inlined]((vfs_attr *) attr = <>, , (vfs_context_t) context = 0xffffff8020ed8168) 0xffffff80a08038c0 0xffffff7f90301588 fuse_vfsop_biglock_getattr((mount_t) mp = <>, , (vfs_attr *) attr = 0xffffff80a0803928, (vfs_context_t) context = 0xffffff8020ed8168) 0xffffff80a0803b00 0xffffff800dd45f3c vfs_getattr [inlined]((mount_t) mp = <>, , (vfs_attr *) vfa = 0x0000000000000000, (vfs_context_t) ctx = <no location, value may have been optimized out>, ) 0xffffff80a0803b00 0xffffff800dd45f30 mount_common((char *) fstypename = <>, , (vnode_t) pvp = 0xffffff801b03b5d0, (vnode_t) vp = <>, , (componentname *) cnp = <>, , (user_addr_t) fsmountargs = 140728898420737, (int) flags = 8, (uint32_t) internal_flags = 0, (char *) labelstr = 0x0000000000000000, (boolean_t) kernelmount = 0, (vfs_context_t) ctx = 0xffffff8020ed8168) 0xffffff80a0803ef0 0xffffff800dd46d8c __mac_mount((proc *) p = <>, , (__mac_mount_args *) uap = <>, , (int32_t *) retval = <no location, value may have been optimized out>, ) 0xffffff80a0803f30 0xffffff800dd46996 mount((proc_t) p = <>, , (mount_args *) uap = <>, , (int32_t *) retval = <no location, value may have been optimized out>, ) 0xffffff80a0803fa0 0xffffff800e15bc95 unix_syscall64((x86_saved_state_t *) state = 0xffffff80209464c0) 0x0000000000000000 0xffffff800da2a306 kernel.development`hndl_unix_scall64 + 0x16 stackbottom = 0xffffff80a0803fa0 ``` Here we can see that `edenfs_privhelp` called `mount(2)` and that that is trying to call to the FUSE daemon. However, the daemon cannot respond because we cannot return the fuse device fd to the FuseChannel until `mount` returns. This commit farms out the `mount` call to a secondary thread that is free to block. In order to catch invalid parameter errors (eg: bad flags to mount), we'll wait a short grace period to see if the mount yields an errno value and raise that. Otherwise we assume success and return the device to the channel. Reviewed By: rb2k Differential Revision: D22939891 fbshipit-source-id: 1a144486672af8386b31e46345958bc5a99ec233 |
||
---|---|---|
.. | ||
fs | ||
integration | ||
locale | ||
mononoke | ||
scm | ||
scripts | ||
test_support | ||
test-data | ||
win | ||
.clang-format | ||
.gitignore | ||
Eden.project.toml |