Waiting for many things at once with io_uring
mazzo.li
mazzo.li
I'll tell you what I would love to see next: a successor to inotify that does not involve opening one zillion file descriptors to watch a recursive subtree. I'm sure there are valid reasons why it's not easy to just make it happen, but it feels like it will be a major improvement in a lot of use cases. And in many cases, it would probably fix the dreaded problem of users needing to fight against ulimits, especially in text editors like VSCode.
I don't have anything of great substance to say about the actual subject of the article. It feels a bit late to finally get this functionality proper in Linux after NT had it basically forever, but any improvement is welcome. Next time I'm doing something where I want to wait on a bunch of FDs I will have to try this approach.
> In the original fanotify API, only a limited set of events was supported. In particular, there was no support for create, delete, and move events. The support for those events was added in Linux 5.1. (See inotify(7) for details of an API that did notify those events pre Linux 5.1.)
A hack that should be performant enough if properly implemented would be a custom FUSE implementation over the directory. As a one-off it could just do the callbacks you want done, or as a reusable component it could implement the inotify behavior you want.
Even without deadlocks it's common to accidentally create a loop that quickly starts using 100% CPU until you kill it. This isn't theoretical, e.g. I ran across it after encountering a program that used `bash -l` to run scripts (fundamentally wrong, but not the bug here), when my `~/.bash_login` happened to touch the part of the filesystem it was watching.
> In June 2023, Google's security team reported that 60% of the exploits submitted to their bug bounty program in 2022 were exploits of the Linux kernel's io_uring vulnerabilities. As a result, io_uring was disabled for apps in Android, and disabled entirely in ChromeOS as well as Google servers.[11] Docker also consequently disabled io_uring from their default seccomp profile.[12]
Root privilege CVE from earlier this year (2024): https://nvd.nist.gov/vuln/detail/CVE-2024-0582
I don't remember much more than that*, but just dropping it here because I learned a ton more from reading about that, than my Nth io_uring article.
* for example, the article mentioning relevant buffers are shared with the system made me want to say "aHA, yes, that's what the security articles said was a core issue!" -- but I can't actually remember with 100% confidence
Yes, historically it was a big source of security bugs. I think that has tapered off somewhat as the rate of change slows down.
The security issue with io_uring, as I understand it, is that it bypasses a lot of Linux's security auditing mechanisms. The problem is that, like with ioctl, if the kernel called out to a security subsystem with "here's something that the user wants to do with this file," the security subsystem would have to know what "something" means for every driver. Impossible; so do you allow most things? Deny them? If you choose the former, now there are gaping security holes. If you choose the latter, then enabling security will break too many things.
https://erlangforums.com/t/erlang-io-uring-support/765/18?pa...
Highly recommend checking it out: https://mazzo.li/archive.html
https://git.kernel.dk/cgit/liburing/tree/examples
There's also a minimal Rust example for tokio:
On the plus side, this submission somehow reminded me about ACE[1], which is where I first came across the Proactor[2]/Reactor distinction. Good times!
[1] https://www.dre.vanderbilt.edu/~schmidt/ACE.html
[2] https://www.dre.vanderbilt.edu/~schmidt/PDF/Proactor.pdf
Or is it just a matter of conceptual elegance or programmer convenience?
I can't find the comments now, but HN users have written at length about NT IO performance in the past.