4 ms·
Sure you can. It might be the case that the level of granularity is low enough that you'd need to do it in kernel/supervisor mode itself to access private data
by vezzy-fnord 11y ago
Sure you can. It might be the case that the level of granularity is low enough that you'd need to do it in kernel/supervisor mode itself to access private data structures like the process control block, instead of doing compatibility layers, shims or daemons in user space.
In most cases, the latter is fully feasible. You just generalize by categorizing the functionality of a source kernel and finding the equivalent taxonomy in a target kernel. It's not like any commodity OS kernel these days doesn't have a feature to multiplex I/O on ports, fds, handles or whatever that it's that prohibitive to shim a syscall, or more often than not, substitute it at build-time or just use an existing library/framework that encapsulates the details.
- JoshTriplett 11y ago> It might be the case that the level of granularity is low enough that you'd need to do it in kernel/supervisor mode itself to access private data structures like the process control block, instead of doing compatibility layers, shims or daemons in user space. Not all kernels allow you to do that. Even among those that do, you'd have to have some level of privilege to install it. (I know I'd look very skeptically at any program or library that wanted an out-of-tree kernel module installed.) And even if you manage to get that code submitted upstream, and they accept it (not at all a given), now you depend on the most recent version of that target OS, and you don't run on older versions of it. Which starts you down the same non-portable road you're complaining about. That said, I absolutely think making such changes in upstream kernels/OSes is the right approach. Make your kernel/OS better to accommodate your userspace software, rather than making your userspace software worse to accommodate your kernel/OS.
- vezzy-fnord 11y agoAgain, this would be more if you needed to emulate things like precise kernel thread semantics, page eviction strategies or whatnot. When talking about system calls (the overwhelming majority of cases), then those are usually well-defined, relatively high level "chunks" of resource management that either have corollaries or can be safely reimplemented in a utility library.
- JoshTriplett 11y agoHow would you suggest reimplementing cgroups on every other POSIX OS? In particular, the behavior where an entire tree of child processes can't escape from that group? Some kernels may have an equivalent to this (though the semantics may not match), but others don't. How about prctl's PR_SET_CHILD_SUBREAPER, which makes a process act like PID 1, as the target for reparenting child processes? Or fanotify/inotify/etc? (A polling-based interface doesn't work here: it misses things due to races, and wastes power by waking up too often.) Or mount namespaces, network namespaces, and other unshare/clone flags? You could reimplement those things in another kernel, but almost certainly not in userspace unless a feature with the same semantics already exists in the target kernel.
- vezzy-fnord 11y agounless a feature with the same semantics already exists in the target kernel The point is they do. For instance, Solaris has contracts (direct corollary to cgroups, actually predating cgroups). In Solaris, orphans are adopted by the kernel and init(1M) can be restarted upon a failure condition. Some BSD flavors have procctl(2). Polling-based interfaces can work, since a port does not have to be completely equivalent in terms of benchmarking, it must conform well by a cost-benefit analysis. File system event notifications are something many platforms reliably have, so that even devices with strict power management policy can incur them (or more often than not they'll incur the cost of polling regardless). Most Unixes have converged on rfork(2)-like primitives that can customize process contexts to share reasonably well. I'm not panning systemd for anything, mind you. I'm speaking in general terms. systemd is decidedly unportable, I'm more than well aware and don't have trouble with that aspect.
- JoshTriplett 11y ago> In Solaris, orphans are adopted by the kernel and init(1M) can be restarted upon a failure condition. Some BSD flavors have procctl(2). Neither of which provides the same semantics as PR_SET_CHILD_SUBREAPER. Unless your desired target platform already has equivalent functionality, "porting" can't happen. It's easy enough to look at individual features and say "Solaris has something kinda like that" or "FreeBSD has something kinda like that". But Linux has quite a bit of functionality with no functional equivalent in other OSes. (And, conversely, some other OSes have functionality with no equivalent in Linux.) And I don't think it's unreasonable to make software that uses the full functionality of a target platform, rather than a less capable subset that can be made to work on other platforms. > Polling-based interfaces can work, since a port does not have to be completely equivalent in terms of benchmarking, Race conditions that cause you to miss events aren't OK, though. And even in terms of benchmarking, once people are done complaining about portable software, they complain that it doesn't run well on their platform. And most of the time they don't blame the platform for that.