
Hello, I am trying to use setns system call via FFI gem to switch mount namespace for the running process. I got the code working but it kept failing randomly. Eventually, I managed to find out the cause of the failures - the key is this text from setns(2) man page: "A process can't join a new mount namespace if it is sharing filesystem-related attributes (the attributes whose sharing is controlled by the clone(2) CLONE_FS flag) with another process." Using strace, I found that the interpreter is sometimes spawning a thread using (among others) the flag mentioned above: clone3({flags=CLONE_VM|CLONE_FS|CLONE_FILES|CLONE_SIGHAND|CLONE_THREAD|CLONE_SYSVSEM|CLONE_SETTLS|CLONE_PARENT_SETTID|CLONE_CHILD_CLEARTID... If this thread is running, setns() fails as specified in its man page. If the thread is not running, setns() succeeds. I am not very familiar with Ruby internals so the only thing that came to mind was the garbage collector. However, trying to call GC.disable before calling setns did not help, the code still kept failing randomly. I assume that the thread is either not a GC-related one, or calling disable doesn't terminate it right away. Is there a way to find out, what is the purpose of this thread and how to prevent it from running? For completeness - the application is an IRB process and spawns no threads on its own. Simplified version of it is something like: # made to be a mount point for the mount namespace using # unshare --propagation=unchanged "--mount=/mnt/testmount" true h = File.open('/mnt/testmount', 'r') setns(h.to_i, 0x00020000) # returns -1 and errno is set to EINVAL One more thing to add - my use case actually doesn't need to be able to use setns() at any (arbitrary) point of the application run-time. What I want to do is pretty much this: fork do setns(...) exec(...) end Meaning the process that calls setns() is going to be short-lived and (as far as I know) all its threads will be terminated on the exec call. Thanks for any insights.