-
-
Notifications
You must be signed in to change notification settings - Fork 1.1k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Docker and io_uring don't work together - add prebuilt binary without liburing #1435
Comments
Please add proper rationale. That commit doesn't explain anything to me. |
@ibc Sorry, the keybinding for submitting an issue without further confirmation got in the way -- I've updated the description! |
Ok, will think about this during this week. |
Just faced this as well (Running mediasoup with a Kernel 6 inside Docker), maybe https://unix.stackexchange.com/a/596284 helps to detect if |
So here is the thing:
In theory this should not crash since, despite the Well, that's the theory... The problem is exactly that: they way in which we check bool DepLibUring::IsRuntimeSupported()
{
// clang-format off
struct utsname buffer{};
// clang-format on
auto err = uname(std::addressof(buffer));
if (err != 0)
{
MS_THROW_ERROR("uname() failed: %s", std::strerror(err));
}
MS_DEBUG_TAG(info, "kernel version: %s", buffer.version);
auto* kernelMayorCstr = buffer.release;
auto kernelMayorLong = strtol(kernelMayorCstr, &kernelMayorCstr, 10);
// liburing `sento` capabilities are supported for kernel versions greather
// than or equal to 6.
return kernelMayorLong >= 6;
} This is, it's literally checking is Kernel version is >= 6 :) so hence the problem because we are in a host that has kernel >= 6 but doesn't have So we need a better runtime way to know if the host supports ìo-uring` or not. |
Off-topic comment, ignore pleaseIn addition to this, I don't really think we are ready to properly run Imagine we are in Linux kernel 5 using a worker with void DepUsrSCTP::Checker::OnTimer(TimerHandle* /*timer*/)
{
MS_TRACE();
auto nowMs = DepLibUV::GetTimeMs();
const int elapsedMs = this->lastCalledAtMs ? static_cast<int>(nowMs - this->lastCalledAtMs) : 0;
#ifdef MS_LIBURING_SUPPORTED
// Activate liburing usage.
// 'usrsctp_handle_timers()' will synchronously call the send/recv
// callbacks for the pending data. If there are multiple messages to be
// sent over the network then we will send those messages within a single
// system call.
DepLibUring::SetActive();
#endif To be clear:
Yes, I know: |
So we need a reliable way to know if io-uring is supported or not.
So we need to fix both cases. Additionally, a new option Some related info: |
NOTE: I'm doing some improvements (but not yet addressing this problem) in this PR: #1440 |
io_uring is often disabled due to numerous security issues found in it over the years, so while supported by the kernel, it may not be allowed for use by apps |
And that's exactly what I meant above: we need a way (in build time in meson.build) and runtime (in DepLibUring.cpp) to check if io-uring is enabled in current host despite it's included in the kernel. We must be able to only build the worker with io-uring support if supported and enabled in current host and we must be able to only enable our DepLibUring class if io-uring if supported and enabled in current host. |
### Details - `createWorker({ disableLiburing: true })` disables LibUring usage despite it's supported by the worker and current host. - Related (still to be fixed) issue which brings lot of context: #1435
I'm adding an That PR is not intended to fix this issue. |
This issue is now mitigated in 3.14.10, see: |
- Fixes #1435 ### Details - Having Kernel >= 6 doesn't guarantee that `io_uring` is enabled. Some systems disable it at kernel layer. - This PR checks if `io_uring` initialization works in launch time, otherwise `io_uring` is disabled. ### TODO - This is another story, but we should rename `WorkerSettings.disableLiburing` to `WorkerSettings.disableIoUring`. That's what we are disabling and not the `io_uring` C wrapper library called `liburing`.
This is not really needed AFAIS. Let me explain: If kernel >=6 then then the machin (in which mediasoup-worker is being built) has
This is done in PR #1445. |
Fixes #1435 ### Details - Having Kernel >= 6 doesn't guarantee that `io_uring` is enabled. Some systems disable it at kernel layer. - This PR checks if `io_uring` initialization works in launch time, otherwise `io_uring` is disabled.
@ibc A little confused by what the way forward is The solution (as of v3.14.11) is to use And, in the future, #1445 (which will probably be deployed with v3.14.12) |
This is to disable io_uring even if it works.
This is to not fail if io_uring is supported by the kernel but is disabled at kernel layer. |
Motivation
When installing mediasoup in a Docker container (on the
linux/amd64
platform) the mediasoup worker will crash with this errorfailure exit: io_uring_queue_init() failed: Operation not permitted
.Containerd has removed support for
io_uring
as it has been deemed unsafe. The rationale for this decision is explained here: containerd/containerd#9048Current Workarounds
There are two options to work around this currently: (1) force the local build of mediasoup without io_uring, and (2) override the default seccomp profile.
Local build
This is the only viable option at the moment. We can force the npm postinstall to build the worker locally by adding these two environment variables before the
npm install
command:However, this obviously slows down the build process fairly significantly. But it works and has no security cost.
Seccomp Profile (BAD idea)
We can manually override the seccomp profile by passing
--security-opt
with thedocker run
command. I have not been able to find the exact syscalls that cause the issue, but allowing all syscalls by default works (as mentioned here moby/moby#39396 (comment)).This will make mediasoup work again, but at a great security cost -- the syscalls were disallowed for a reason.
I DON'T THINK THIS IS A GOOD IDEA. I'm just adding this in case someone stumbles across this solution as I did.
Feature Request
Even though the first method works, it is less than ideal. However, I understand that
io_uring
brings some performance benefit which justifies its use in general. Therefore, another prebuilt binary should exist withoutio_uring
when using Docker.I don't know if it's possible to detect a docker build automatically and reliably (maybe this helps?) but that would obviously be the best case. Otherwise an environment variable to switch between the version with and without
io_uring
would be the next best thing.The text was updated successfully, but these errors were encountered: