Pre-RFC: target extension (dealing with breaking changes at OS level)

I updated my WIP RFC copy (link “Target extension” in top level comment), and it should be about to be complete now.

Any feedback before submitting it ?

A couple of questions (not necessarily blockers for submission):

  • Does it ever happen that the kinds of changes you’re interested in wrapping with these directives ever get backported to an older release of the operating system?
  • What parts of the environment are covered by this version number? That is, what does “OpenBSD 6.2” mean, precisely? Does it just cover the kernel interfaces? Kernel + libc? All possible libraries you could install on the OS? Just some core set, but beyond libc? File paths? File formats?

I think ideally you’d do a run-time test for a particular feature, but IMO there are a few more interfaces rust needs to provide to make that really viable, plus you run the risk of a performance penalty. Failing that, a build-time test via a build script can do the trick nicely. But that has the downside of not working in a cross-compilation environment.

I’ve seen over the years lots of assumptions built in to version tests that don’t hold true as time passes. It’s a really hard problem, but I’ve become wary of anything but feature testing to do the right thing.

We speak about the interface an operating system provides to userland. They are kernel and libc interface (syscalls, libc functions, system structures…).

With BSDs, the system is provided as a whole: kernel, libc, all system programs installed with the OS (like ls, mount, …). It is the whole that is targeted (but not third-parties programs or libraries, installed after the system).

Regarding Rust, the intented usage of OS or environment version is mostly for libc crate. It is where most of the OS depend code live, and the current code lackes a way to express breaking changes (as example, FreeBSD 12 will be published with a ino_tstruct size change - it is a low level structure used in syscalls - using the wrong struct size makes the program to crash).

For backported changes, I think it will depend of the OS policy, but breaking changes will not be backported (because it will break expectation of running binaries). Speaking about OpenBSD, the changes are published via erratas. There are security, interoperability or reliability fixes only. No new features. A particular version is supported one year only (the RFC mentions deprecating unsupported versions).

About runtime detection, it could be done by replacing the libc crate with binding generation (using rust-bindgen for example). The main drawback, as mentioned, will be cross-compilation, as the host system doesn’t know about the targeted system. I added this alternative to the RFC.

If a backported change would require some adjustment, it would be still possible to express it in straighful way (assuming it isn’t a breaking change): adding new code under conditional compilation directive would be still possible. If it is a breaking change which require change in libc crate, it will require a library major version bump (as it will be also a breaking change in the crate itself), but it isn’t different from what we have now.

1 Like

This topic was automatically closed 90 days after the last reply. New replies are no longer allowed.