On 01/09/2016 21:12, Daniel Kahn Gillmor wrote:
I think we might be approaching diminishing returns on this thread, so please don't take offense if i don't reply too much beyond this.
Are you kidding? We're just getting started. I haven't had a good design discussion for ages! :D
This doesn't allow for the creation of multiple different sockets e.g. for a daemon expected to listen on distinct IPv6 and IPv4 addresses, but not on all available addresses.
Well, hardcoding the fd numbers requires the daemon to use a fixed number of them, yes. It only works in static cases; as soon as you're doing anything fancier, you need something more powerful.
I'd want the map the other way around: from number to use case, if i was going to go for a re-design like this, though i suppose it's roughly equivalent to have udp=3,udp=4,tcp=5 as long as you don't mind having repeated keys. but meh, this is basically equivalent.
No, because the daemon doesn't care about the numbers, it cares about the use case. The daemon doesn't want to know what fd 3 is about, it wants to know what fd it should perform UDP socket operations on. If you want to provide several fds for the same use (i.e. a daemon that listen on several UDP sockets with the same functionality), then you should give a list of fds. "UDP_FD=3,8" for instance. Or, with LISTEN_FDS_MAP, something like "udp=3,8:tcp=5".
this seems no more unwieldy (probably less unwieldy) than the convention to always use FD 6 and FD 7. what if i wanted to have some other fd open on those numbers for some other reason? i'd have to move it out of the way to use the s6 convention.
fds 6 and 7 are only used for UCSPI clients, which are a very minor subset of the programs you'd want to use that mechanism with. And yes, it is a bit unwieldy to have hardcoded fd numbers, that's why I only recommend it for programs that only use a small number of fds - typically UCSPI clients and servers only use two. Fortunately, it's easy to move fds around. The shell redirection operators are getting so little use these days! And for executable chains, execline's "fdmove" can be plugged anywhere. Internally, s6-rc makes heavy use of fdmove.
eh? on the contrary: if your daemon doesn't need to distinguish between any of its sockets -- if all sockets are standard listening sockets (it can still inspect the socket itself to distinguish between datagram and stream) then it doesn't care about anything but LISTEN_FDs.
Maybe it's just aesthetics at this point, but I don't like the idea of having to inspect the fds you're given. If I'm using preopened sockets, I want to be able to trust the caller to pass me the correct socket types (and fail loudly if it doesn't). I don't want the caller to tell me "here's a bunch of fds, you sort them out": that's just laziness.
If the daemon receives some sockets (like a local control socket) that need to be treated differently, then it needs to look at the map. Your proposed LISTEN_FD_MAP looks precisely equivalent to LISTEN_FDNAMES for this purpose, with only minor syntactic differences. The non-syntactic difference, of course, is that multiple daemons written and running today actually already know how to parse LISTEN_FDNAMES, whether because they link to libsystemd or do the simple parsing themselves. if LISTEN_FD_MAP had gotten there first, i would have made listen(8) implement that labeling scheme.
And there are also multiple daemons written and running today that already know how to read an open fd number from an environment variable, and that didn't wait for systemd to bring them God's gift to daemon design. :P Following existing practice for interoperation purposes is a dangerous positive feedback loop: it's only a good thing when the existing practice is already good. And I don't subscribe to the "A bad convention is better than no convention at all" point of view: if a convention is bad, I make it my job to think of a better one instead. This is what we are doing right now, this is why I love design discussions, and I thank you for this opportunity.
I'd still call LISTEN_FDS a "convention" and not a "mechanism", fwiw. I'd be interested in seeing a pointer to anything you write up. Please post it here!
I have started working on it, but I have more urgent stuff on my plate right now; but I'll definitely keep you informed. Also, since it's the second wrapper of its kind, there's a chance it won't be the last, so I'm thinking of gathering those wrappers into a new package, with the theme "how to make your daemons work with the systemd interfaces without having to change them to use the systemd interfaces". Good stuff to come! ;) -- Laurent