Systemd for Developers I (2011)(0pointer.net)
0pointer.net
Systemd for Developers I (2011)
http://0pointer.net/blog/projects/socket-activation.html
2 comments
I think it's unfortunate that Lennart didn't continue this series. The last installment was III in October 2012.
These articles actually provided some valuable insight into the internals of systemd, rather than the highly abstract and inconsistent descriptions that have generally been given for systemd throughout the years.
I actually remember seeing an infographic comparison that was taken from Ohloh, showing systemd, Upstart and OpenRC. systemd trumped the other two in SLOC, contributor counts, repository activity, but it was absolutely devastated in one area... source code comments.
The systemd codebase is quite opaque to follow. I guess you could say most codebases are, as we have yet to develop any sufficiently advanced tools to assist in reading and instrumenting source code beyond scoping and IDE-style symbol relation trees. But it's still excessively inaccessible, I find.
That said, systemd has changed radically since 2012, now using its own homegrown kdbus layer called sd-bus which currently communicates through a shim that translates kdbus calls into dbus1. There's been new generators, networkd, resolved, prerequisites for kmscon, additions to journald like compression, and so much more. It really is a beast.
Instead, they seem to have thrown their hands in the air and said it "Fuck it, we're doing a second kernel." (as this year's GNOME Asia talk elucidated).
For those who say systemd is well documented because "look at all the damn manpages", those manpages are often inconsistent, incomplete, vague or otherwise unhelpful to understanding systemd on a level beyond that of a cursory end user.
Which is probably why both systemd proponents and opponents are all totally confused in the entire mess, both thinking they've grokked it and all of them looking like fools. I guess when you have PR like Red Hat alternately calling systemd a "service manager", "system manager", "init daemon", "basic userspace building block to make a Linux-based OS from", "a general system framework to unify Linux work" and whatnot, you get a whole bunch of chaos.
These articles actually provided some valuable insight into the internals of systemd, rather than the highly abstract and inconsistent descriptions that have generally been given for systemd throughout the years.
I actually remember seeing an infographic comparison that was taken from Ohloh, showing systemd, Upstart and OpenRC. systemd trumped the other two in SLOC, contributor counts, repository activity, but it was absolutely devastated in one area... source code comments.
The systemd codebase is quite opaque to follow. I guess you could say most codebases are, as we have yet to develop any sufficiently advanced tools to assist in reading and instrumenting source code beyond scoping and IDE-style symbol relation trees. But it's still excessively inaccessible, I find.
That said, systemd has changed radically since 2012, now using its own homegrown kdbus layer called sd-bus which currently communicates through a shim that translates kdbus calls into dbus1. There's been new generators, networkd, resolved, prerequisites for kmscon, additions to journald like compression, and so much more. It really is a beast.
Instead, they seem to have thrown their hands in the air and said it "Fuck it, we're doing a second kernel." (as this year's GNOME Asia talk elucidated).
For those who say systemd is well documented because "look at all the damn manpages", those manpages are often inconsistent, incomplete, vague or otherwise unhelpful to understanding systemd on a level beyond that of a cursory end user.
Which is probably why both systemd proponents and opponents are all totally confused in the entire mess, both thinking they've grokked it and all of them looking like fools. I guess when you have PR like Red Hat alternately calling systemd a "service manager", "system manager", "init daemon", "basic userspace building block to make a Linux-based OS from", "a general system framework to unify Linux work" and whatnot, you get a whole bunch of chaos.
I can't speak for other systemd opponents, but I don't care much for it because it's so mind-bogglingly complex. I used to be of the opinion that it was particularly dangerous for pid 1 to accrete complexity, as more complexity created more spaces for bugs to hide, and a process-gunning bug in pid 1 can take down your whole system. With sysvinit, you could understand pid 1 with a few hours' study. With systemd, it's bloody near impossible no matter how much time you set aside. So accordingly, the attitude of Lennart & co. parallels Nancy Pelosi: "All distros should adopt systemd in order to find out what it does."
Systemd has a pretty compelling feature set, but I don't care if it fucking turns water into wine at this point; I've an allergic reaction to software complexity and abstruseness, and systemd gives me every reason to not trust it.
Systemd has a pretty compelling feature set, but I don't care if it fucking turns water into wine at this point; I've an allergic reaction to software complexity and abstruseness, and systemd gives me every reason to not trust it.
That doesn't surprise me; PulseAudio had the same complete lack of source code comments last time I looked. (Was trying to track down a crash in the resampling code. In the end I think I concluded that what the code was doing made no sense, it was unlikely it had ever worked properly, several important variable names were misleading in a way that had probably tricked a developer, and it wasn't worth trying to figure out a fix.)
This comparison?: https://www.openhub.net/p/compare?project_0=Upstart&project_...
The systemd LoC count is much higher than for the other two...
The systemd LoC count is much higher than for the other two...
> it was absolutely devastated in one area... source code comments.
It is arguable whether this is a downside. I think that comments mean that source code itself is not readable enough. Comments should be used sparingly - only in exceptional conditions.
It is arguable whether this is a downside. I think that comments mean that source code itself is not readable enough. Comments should be used sparingly - only in exceptional conditions.
In systemd's case, it is. Everything is buried through layers of obscure abstraction, and understanding the code can be a difficult task, indeed.
On the other hand, Upstart makes heavy use of libnih (it's like glib, but nowhere near as heavy) and is actually very easy to follow. Compared to systemd, it certainly is, at least. Many of the comments are actually annotations for the automated documentation generator, from what I recall.
OpenRC makes use of source code comments in a more conventional way, but they actually do tend to help with adding insight into what was going on in the author's head, and the code is still understandable (though not as clean as Upstart's), regardless. Its small size obviously also helps.
On the other hand, Upstart makes heavy use of libnih (it's like glib, but nowhere near as heavy) and is actually very easy to follow. Compared to systemd, it certainly is, at least. Many of the comments are actually annotations for the automated documentation generator, from what I recall.
OpenRC makes use of source code comments in a more conventional way, but they actually do tend to help with adding insight into what was going on in the author's head, and the code is still understandable (though not as clean as Upstart's), regardless. Its small size obviously also helps.
"I think that comments mean that source code itself is not readable enough"
Or that the author understands something about architecture. From an internal code base that I can't cut and paste, there's a nice discussion in comment form that paraphrasing is something like "you'd really like to implement an AVL tree here because we do lots of lookups and AVLs are faster than RBs at lookups, but actual performance testing on the test cluster shows that under our real world workload, the slightly better writing performance of the RB outweighs the slightly faster reads, or TLDR do not blindly change this to a AVL thinking you'll win, because you won't".
(Oh and obviously business logic. I find nothing inherently technologically wrong with the concept of say, floats for currency, perhaps in a hard sci fi novel, although as a business logic concept that is widely considered horrifically wrong, and there's nothing wrong with documenting business logic in comments although float currency is a ridiculous extreme example... how bout, and this GIGO filter forbids negative interest rates or something, which makes math sense and computer sense but from a business logic perspective might be quite icky)
I agree with you WRT comments for regex looking like line noise or programming 101 style syntax comments "x = 1 // this step sets the variable x to contain the integer number 1"
Or that the author understands something about architecture. From an internal code base that I can't cut and paste, there's a nice discussion in comment form that paraphrasing is something like "you'd really like to implement an AVL tree here because we do lots of lookups and AVLs are faster than RBs at lookups, but actual performance testing on the test cluster shows that under our real world workload, the slightly better writing performance of the RB outweighs the slightly faster reads, or TLDR do not blindly change this to a AVL thinking you'll win, because you won't".
(Oh and obviously business logic. I find nothing inherently technologically wrong with the concept of say, floats for currency, perhaps in a hard sci fi novel, although as a business logic concept that is widely considered horrifically wrong, and there's nothing wrong with documenting business logic in comments although float currency is a ridiculous extreme example... how bout, and this GIGO filter forbids negative interest rates or something, which makes math sense and computer sense but from a business logic perspective might be quite icky)
I agree with you WRT comments for regex looking like line noise or programming 101 style syntax comments "x = 1 // this step sets the variable x to contain the integer number 1"
>It is arguable whether this is a downside or not.
No it isn't. Software developers have been saying for 30-40 years "the code is readable as is", yet we keep coming up with easier to read languages, and comments are still in the spec of all these languages.
Comments are important, it's not worth arguing if the code is readable or not. It's a waste of time that could be spent better documenting what ever you consider readable. Because your co-workers, or co-contributors may have a different definition of what readable is.
No it isn't. Software developers have been saying for 30-40 years "the code is readable as is", yet we keep coming up with easier to read languages, and comments are still in the spec of all these languages.
Comments are important, it's not worth arguing if the code is readable or not. It's a waste of time that could be spent better documenting what ever you consider readable. Because your co-workers, or co-contributors may have a different definition of what readable is.
> Because your co-workers, or co-contributors may have a different definition of what readable is.
The same could be said about comments. You can always say they are not enough. As I said - comments have their use - in my opinion for the cases where language is not flexible enough to express intent in a readable way.
The same could be said about comments. You can always say they are not enough. As I said - comments have their use - in my opinion for the cases where language is not flexible enough to express intent in a readable way.
Or you're implementing an odd algorithm where a pointer to the paper, etc, describing it is located so that co-workers, etc, know what's going on. Or you're working around architectural limitations, such as doing work on microcontrollers, where you don't always have your preferred integer size to work with. Or working around bugs and/or poor naming conventions in other peoples' software. Yes, your code may be beautiful and cause angels to sing, but it's going to be working with code belched from the deep bowels of hell, and giving others clues as to why you're doing things in non-intuitive manners is not just useful, but needed.
"How, what, why"
Use code for describing how your program does what it does, function-level comments for what it does in cases where you cannot put that in the name of a type or identifier (getFoo typically does not need a comment, but strtok does) and sprinkle in comments why your program does what it does in the way it does where that may not be clear to the expected reader of your code (as in the example of the AVL tree in a sister comment)
Use code for describing how your program does what it does, function-level comments for what it does in cases where you cannot put that in the name of a type or identifier (getFoo typically does not need a comment, but strtok does) and sprinkle in comments why your program does what it does in the way it does where that may not be clear to the expected reader of your code (as in the example of the AVL tree in a sister comment)
In my experience - yours may be different - there is something you could call the Goldilocks zone for comments. Too many comments can obscure the code, and lead to those horrible moments where the code and the comments disagree. But using them too sparsely can be a problem, too, especially if you're looking at a 1000 line file with three comments that all go "// ???" (I have used these question mark comments myself as a reminder, "if this change breaks something, I should start looking here", but I was always careful to remove them as soon as possible).
The best advice I've been given on comments was somewhere in the coding guidelines for the Linux kernel - if you have to write a comment to explain what your code does, consider rewriting it so it will be obvious; but it's often a good idea to write a comment explaining why your code does something in a particular way.
I have, on occasion, seen code that seemed horribly convoluted or inefficient, only to find out the hard way that there was a good reason for it being that way, often having to do with idiosyncrasies or bugs in the OS or external libraries. In those cases, I found it extremely helpful to write a short comment explaining what mess you are trying to work around. Not only will this keep others (or yourself, a year from now) from trying to mess with that code, it will also encourage people to fix it if the reasons you state in your comment no longer apply (maybe the OS/library/compiler has been fixed, maybe you're on a different platform, ...).
If, for some reason, I find myself writing a longer-than-recommended function/method, I to insert comments to make the structure of the code clear, so if I find out later that there is a bug in the code that, say, creates the database connection, I can find that code more easily. Of course, factoring that code into several functions/methods and call them from a short top-level one would be better, but just having to read through a couple of screens of code without any sign posts is worse.
(Much of the same applies to documentation, of course. I you need to explain what a function/method does, because its name does not tell you, you might want to rename it. But if there are any caveats you should be aware of - e.g. "Don't ever pass a NULL pointer to this function, because it does not check for those and will segfault the program" - the docs should point them out to you.)
(I am, of course, writing all this from a more general point of view, I have never looked at the systemd sources, and I'm not sure I want to.)
I have, on occasion, seen code that seemed horribly convoluted or inefficient, only to find out the hard way that there was a good reason for it being that way, often having to do with idiosyncrasies or bugs in the OS or external libraries. In those cases, I found it extremely helpful to write a short comment explaining what mess you are trying to work around. Not only will this keep others (or yourself, a year from now) from trying to mess with that code, it will also encourage people to fix it if the reasons you state in your comment no longer apply (maybe the OS/library/compiler has been fixed, maybe you're on a different platform, ...).
If, for some reason, I find myself writing a longer-than-recommended function/method, I to insert comments to make the structure of the code clear, so if I find out later that there is a bug in the code that, say, creates the database connection, I can find that code more easily. Of course, factoring that code into several functions/methods and call them from a short top-level one would be better, but just having to read through a couple of screens of code without any sign posts is worse.
(Much of the same applies to documentation, of course. I you need to explain what a function/method does, because its name does not tell you, you might want to rename it. But if there are any caveats you should be aware of - e.g. "Don't ever pass a NULL pointer to this function, because it does not check for those and will segfault the program" - the docs should point them out to you.)
(I am, of course, writing all this from a more general point of view, I have never looked at the systemd sources, and I'm not sure I want to.)
I think you're right. If the code isn't clear enough without comments, the code needs to be improved. I manage a number of projects written in C, and all of them have very low comments because I enforce a policy of clean and understandable code.
Comments are used to explain strange things in your code. A small number of comments in a good codebase is an indicator of strange things being sparse - a good thing.
Comments are used to explain strange things in your code. A small number of comments in a good codebase is an indicator of strange things being sparse - a good thing.
[deleted]
So, for example, I have no problems with "systemctl --host [email protected] status httpd.service". But I would _like_ to be able to do "systemctl --host [email protected] --port 2255". The manpages seems to only show "--host" as an option with no ability to specify "--port". Grepping through the code left me no wiser, so was hoping someone in the know could confirm/deny.
(The specific case is that I have a bunch of VMs controlled by VirtualBox and am redirecting localhost ports e.g. 2255 to guest port 22. I can of course run "ssh -l me -p 2255 localhost "systemctl status httpd.service".)