Even unsafe rust is safer than C. Error management, type safety, modern language, etc. There are many reasons to use Rust in place of C, even if your whole code is one giant unsafe blob.
I run eBPF code written in Rust in production, and oh boy how more readable it is compared to C. Even simple stuff like `if let Some`, actual sum types, generics, are enough to warrant using Rust over C. And its endtrypoint is basically unsafe { ... }.
Don't mislead people like this. If you are writing C, oh well. If you are writing big unsafe Rust blocks, genuinely, you are holding it wrong. Rust's strength is that unsafe blocks are minimal and well-isolated, giving both the flexibility and performance of C and the assurances of safe Rust. The default is safe Rust and unsafe authors must ensure their code works when it is eventually contacted by safe Rust. That's why we can say Rust is memory-safe, like Java or C#, even though unsafe is a clearly advertised feature. Unsafe Rust is, at best, on par with C. Nice language features do not fix UB. If you're not taking advantage of safe Rust, you lose the benefits of using unsafe Rust. Rust's main innovation is the borrow checker; use it!
In the specific case where I'm using Rust, unsafe is definitely better. I mostly write eBPF XDP programs for where I write unsafe code.
So yes I agree that I don't get safety benefits. However, it does not mean I don't get increased reliability from it. Just type safety allows APIs to be expressed in ways you cannot hold them wrong. Heck, just getting a Result<u32, u32> instead of a i64 for faillible operations is a godsend.
In the end, this is why I'm a big proponent of Rust for many areas of programming, including areas where memory safety is the least of your concerns. My gRPC APIs are written in Rust, my system daemons are written in Rust, my eBPF probes are written in Rust. Rust is a modern language whose design is deliberate on many levels to address common issues in programming. If you'd ask me, Rust's "marketing" putting memory safety first is quite a disservice as there are many areas where it helps writing correct programs.
Greg KH noted this in his email in another branch of the thread, and I wholeheartedly agree with him.
> So yes I agree that I don't get safety benefits. However, it does not mean I don't get increased reliability from it. Just type safety allows APIs to be expressed in ways you cannot hold them wrong. Heck, just getting a Result<u32, u32> instead of a i64 for faillible operations is a godsend.
Generally, people talk about type system benefits and whatnot on top of safe languages. If you can't ensure safety, UB occurs and that goes out the window. I can't tell how you use unsafe in absolute terms, so I will just hope that you are saying you have an unusually high proportion of unsafe code but still manageable. Otherwise it invites the same "look over everything to make sure nothing can go wrong" practice as with C.
> In the end, this is why I'm a big proponent of Rust for many areas of programming, including areas where memory safety is the least of your concerns.
Memory safety should never be "the least of your concerns". The movement around memory-safe languages is because memory safety is the bedrock on which orthogonal concerns must be placed. Unsafe Rust is well and good because it is (hopefully) used sparingly and with great caution. It is the typical absence of unsafe Rust that characterizes its strengths. I agree that Rust has decent, if not strong, qualities for many other programming sectors, and many Rust critics do make an unreasonable amount of noise about memory safety and unsafe Rust, but Rust is what it is first and foremost because of its approach to memory safety, and everyone can agree to that. Your first comment undermines your stated desire to communicate that Rust should be seen as offering "memory safety plus more goodies".
I haven't written any eBPF programs, but I was under the impression that the eBPF subsystem rules and verifier take care of the "memory safety" aspect, at least to the program boundaries. Is that an incorrect understanding?
That's true, my bad. But in that sense it isn't running unsafe Rust or C. It is more limited and provides a different context of safety. I misjudged @tuetuopay's assurance for safety, but I think my comments are generally correct and important for the audience. Lines like
>> Even unsafe rust is safer than C. Error management, type safety, modern language, etc. There are many reasons to use Rust in place of C, even if your whole code is one giant unsafe blob.
only make sense in the context of eBPF or similar verification environments. That was made more clear in their second comment, so I'm really sorry about that.
>> In the end, this is why I'm a big proponent of Rust for many areas of programming, including areas where memory safety is the least of your concerns. My gRPC APIs are written in Rust, my system daemons are written in Rust, my eBPF probes are written in Rust.
To my understanding, it is only eBPF out of these that has this particular "write all the unsafe you want" quality. Overall, we were on the same page about Rust's guarantees and features this whole time, but I do think @tuetuopay's messaging/"marketing" was pretty confusing, and doesn't help with Rust's marketing that they pointed out.
Arguably unsafe Rust is a bit less safe than C. But fortunately you need much less of it (even in something like a DMA subsystem there's going to be plenty of safe code).
eBPF is such a supertool that is slept on. I have been working on turning my nftables into it, (on low-latency/high-throughput targets) may I ask how you are using it with Rust?
Sure! I use the aya framework (https://aya-rs.dev) that provides the kernel-side bindings to write the probes in Rust, and the userspace tooling to load it in the kernel, interacts with maps, etc. Quite a joy to work with, and has all the niceties you'd expect from using Rust.
We write XDP apps for custom dataplanes where traditionally DPDK would be used (routers and such). Our upcoming network acls are written this way, so close to your netfilter usage.
I do worry about running so much stuff in kernel space though. Imagine a widespread 0day that hits the kernel, or kernel panics causing kernel crashes that require reboots, the user space priv escalation, etc...
Are you doing fail-open or fail-closed? I've been on the fence on that.
What is the current legal status of eBPF? It used to be that loading any non-trivial eBPF into kernel involved GPL-only stuff, and both the eBPF program and the program that used it had to be GPL.
Well, yes, but this only matters if you distribute the compiled probes: you'll have to distribute the source for the probes. And, thankfully, this is not AGPL where network interaction counts, so:
- a cloud provider writing a dataplane using ebpf does not have to provide the source
- a company selling on-prem software (e.g. esxi) that ships with ebpf probes would need to distribute their source
I think the "drama" is that the DMA guys want to write C, only.
However they have opinions about how people are interfacing with their code for DMA from Rust, and the rust developers are maybe bent out of shape about it.
Linus is saying: If you're not doing it, then you don't get to have opinions.
> Linus is saying: If you're not doing it, then you don't get to have opinions.
But eventually he would have to, if those rust interfaces becomes part of kernel. The entire drama is about DMA guys not wanting to deal with this in future.
They're trying to do DMA in C, by calling the existing DMA code that's written in C from new drivers written in Rust. Their attempt to make an interface from Rust to the existing DMA code is what's being rejected by the guy maintaining the existing DMA code.
The question is not the monopoly by itself, it's to conquer other market by abusing it's power. If you own search and mobile os, without régulation, what could you prevent to own mobile service, then fiber, then delivery then car, then train, then whatever ?
Like models, all abstraction are False, but some are usefull. I never found Monad to be usefull : a abstraction shared by async/await and map/list comprehension is for me a bad abstraction, because as a developper I typically want to know if I'm dealing with the former or the later. And want to manually combine them, like with gather.
Aluminum has some interesting properties and if you don't know how to mitigate them can be trouble. I know they can be mitigated, but I also know I'm not an expert in all of them so I won't comment too much. So yes, but only if you are careful in ways most people wouldn't think to be careful.
"at a loss" can be very different depending on :
- is it pure marginal cost ?
- do you include a part of R&D cost ?
- do you factor large capex (factory, stamping press, and silicon fab in related industries )
- how do you compute depreciation ?
When you see the gap between accounting in the West and "accounting" in China, "at a loss" has no meaning at all.