static int oo_ioctl_debug_op(ci_private_t *priv, void *arg) { ci_debug_onload_op_t *op = arg; int rc; if( !ci_is_sysadmin() ) return -EPERM; switch( op->what ) { case __CI_DEBUG_OP_DUMP_INODE__: rc = efab_linux_dump_inode(op->u.fd); break; case __CI_DEBUG_OP_TRAMPOLINE__: rc = efab_linux_trampoline_debug(&op->u.tramp_debug); break; case __CI_DEBUG_OP_FDS_DUMP__: rc = efab_fds_dump(op->u.fds_dump_pid); break; case __CI_DEBUG_OP_DUMP_STACK__: rc = tcp_helper_dump_stack(op->u.dump_stack.stack_id, op->u.dump_stack.orphan_only, CI_USER_PTR_GET(op->u.dump_stack.user_buf), op->u.dump_stack.user_buf_len); break; case __CI_DEBUG_OP_KILL_STACK__: rc = tcp_helper_kill_stack_by_id(op->u.stack_id); break; default: rc = -EINVAL; break; } return rc; }
/* Kill an orphan stack in the thc * * You must hold the thc_mutex before calling this function. * * You cannot hold the THR_TABLE.lock when calling this function. */ static void thc_kill_an_orphan(tcp_helper_cluster_t* thc) { tcp_helper_resource_t* thr = NULL; int rc; rc = thc_get_an_orphan(thc, &thr); ci_assert_equal(rc, 0); /* This is generally called when the stack is being freed. But as * we are holding the thc_mutex, we will deadlock if we took that * path. So we remove thr from the thc now. */ thc_remove_thr(thc, thr); LOG_U(ci_log("Clustering: Killing orphan stack %d", thr->id)); rc = tcp_helper_kill_stack_by_id(thr->id); #ifndef NDEBUG if( rc != 0 && rc != -EBUSY ) LOG_U(ci_log("%s: tcp_helper_kill_stack_by_id(%d): failed %d", __FUNCTION__, thr->id, rc)); #endif }