The systemd-love overlay at https://github.com/Sabayon/systemd-love contains a set of slighly modified ebuilds that add support for app-admin/eselect-init. eselect-init (and its init.eclass) is an eselect module that makes possible to switch between sysvinit compatible implementations, like sysvinit itself and systemd. The wider idea is to make possible to switch between openrc and systemd at runtime (consolekit will be handled in a second bug). There are many advantages brought by this: - it allows to smoothly migrate systems from openrc to systemd (and vice versa) in a more gentle way - it allows to roll out (at some point) an official [official, from the systemd@ pov] migration path from openrc to systemd - it allows to debug and benchmark openrc and systemd without being forced to setup separate chroots - it allows to support even other sysvinit replacements like upstart with just some tweaks to the upstart ebuild (i see an ebuild in the chromiumos overlay) - it is the first step towards putting some love between openrc and systemd camps - it is binpkgs friendly (a binpkg repo will be able to contain both systemd and openrc, when I'm done with the remaining stuff) This bug is about app-admin/eselect-init, I will open separate bugs about sysvinit and systemd when this is worked out. I would like to commit this ebuild into the tree with initial p.masking. Comments and code reviews are <3. With love. Reproducible: Always
Created attachment 344940 [details] current init.eclass
Created attachment 344942 [details] eselect-init-0.1.ebuild
Created attachment 344944 [details] init-0.1.eselect eselect module
eselect-init design: All the sysvinit implementations that aim to be compatible with eselect-init must install their files (defined inside ${INIT_PARTS}) into /sbin/init.d/<implementation name>/. eselect-init will be able to tweak the symlinks in /sbin/ basing on the content of /sbin/init.d/<implementation name>. This makes possible to programmatically change executables like /sbin/init (thus without touching the crufty bootloader configuration), /sbin/poweroff, /sbin/halt and /sbin/reboot.
Created attachment 344960 [details] eselect-sysvinit-0.1.ebuild I renamed eselect-init into eselect-sysvinit
Created attachment 344962 [details] eselect module
Created attachment 344964 [details] sysvinit eclass
To be honest, I'm not really convinced to this. I can see the benefits, especially that it is easier to switch /sbin/init symlink than edit bootloader config and commit it (think of lilo). And I think that you're overestimating the advantages. The point of switching init for lifetime is correct but for things like 'debugging and benchmarking' just changing init= is much better. Especially that with a non-booting system you won't get to run eselect :). That said, you can even put two bootloader menu entries with different init= lines and possibly other arguments which eselect won't help with. By the way; $ tar -tf /usr/local/portage/packages/*/systemd*-sy*19* bzip2: (stdin): trailing garbage after EOF ignored ./ ./sbin/ ./sbin/init ./sbin/telinit ./sbin/shutdown ./sbin/runlevel ./sbin/reboot ./sbin/poweroff ./sbin/halt ./usr/ ./usr/share/ ./usr/share/man/ ./usr/share/man/man8/ ./usr/share/man/man8/halt.8.bz2 ./usr/share/man/man8/poweroff.8.bz2 ./usr/share/man/man8/reboot.8.bz2 ./usr/share/man/man8/runlevel.8.bz2 ./usr/share/man/man8/shutdown.8.bz2 ./usr/share/man/man8/telinit.8.bz2 ./usr/share/man/man8/init.8.bz2 With all the binaries being symlinks to systemctl. I'm not sure I'd really want to install a tree of symlinks just for eselect module to symlink them further. Plus there are different manpages.
The way it is designed doesn't prelude you from using init= or real_init=, which is a non-goal. Besides that, if you want I can handle the man pages as well, that's no big deal. Wrt symlinks, have you ever seen what binutils-config or gcc-config does? ;-) That's much much much worse. All in all, we should really work towards making systemd more accessible to users by lowering the bar and saving them from some debatable decisions (nss-myhostname blocker, the current openrc-settingsd collisions workaround, the unclear semantics of USE=systemd). Making possible to switch between systemd and openrc would be good for both and would also allow other players to have an easier life in portage ;-)
(In reply to comment #9) > The way it is designed doesn't prelude you from using init= or real_init=, > which is a non-goal. I'm just criticizing listing 'debugging' as a benefit while init= serves the goal much better. > Wrt symlinks, have you ever seen what binutils-config or gcc-config does? > ;-) That's much much much worse. Others doing bad things doesn't mean you're supposed to repeat those. That said, I suggest the following idea: eselect-init which gets a bunch of variables for common stuff switched with init. For a start, it'd be enough to just handle the 'init' symlink. Each init variant installs a config file to a well-known location. eselect-init sources the files, gets variables reassigned to new symlink targets. Does sanity check (all set? all correct?) and links the files. That said, there'd be /usr/share/eselect/init/sysvinit: init=/sbin/sysvinit and /usr/share/eselect/init/systemd: init=/usr/lib/systemd/systemd Possibly for other init replacements too. In the future we can extend that with additional tools if needed. Then eselect module itself would default: reboot=/sbin/sysv-reboot halt=/sbin/sysv-halt and systemd would override those: reboot=/usr/bin/systemctl ... Just make sure to replace symlinks the safe way. That is 'ln -s ${target} /sbin/init.tmp; mv /sbin/init{.tmp,}' (ln is not atomic, mv is). And preferably create initial /sbin/init symlink in sysvinit postinst() directly. Just to be on the safe side.
> For a start, it'd be enough to just handle the 'init' symlink. It's not much effort to support the others, I think. Or, is it? > In the future we can extend that with additional tools if needed. Then > eselect module itself would default: > > reboot=/sbin/sysv-reboot > halt=/sbin/sysv-halt > > and systemd would override those: > > reboot=/usr/bin/systemctl > ... 1) Boot with openrc. 2) `eselect init set systemd` 3) `reboot` 4) System fails to reboot since it wasn't booted with systemd. 5) User can't start reboot with openrc because systemd is in place. How can we solve this situation? Maybe it should correct the symlinks on boot?
(In reply to comment #11) > > For a start, it'd be enough to just handle the 'init' symlink. > > It's not much effort to support the others, I think. Or, is it? > > > In the future we can extend that with additional tools if needed. Then > > eselect module itself would default: > > > > reboot=/sbin/sysv-reboot > > halt=/sbin/sysv-halt > > > > and systemd would override those: > > > > reboot=/usr/bin/systemctl > > ... > > 1) Boot with openrc. > 2) `eselect init set systemd` > 3) `reboot` > 4) System fails to reboot since it wasn't booted with systemd. > 5) User can't start reboot with openrc because systemd is in place. eselect-sysvinit can do little in case of individual init systems boot failures. However, we could just store the old init symlink into /sbin/init.old or something like that. > > How can we solve this situation? Maybe it should correct the symlinks on > boot?
@mgorny: thanks for spotting the ln -s atomicity issue. I'm saying, as a good practice, let's start with the simplest approach and see where to go from there. I think that the real requirements will only arise when the thing gets deployed.
(In reply to comment #12) > eselect-sysvinit can do little in case of individual init systems boot > failures. > However, we could just store the old init symlink into /sbin/init.old or > something like that. No, not boot failures, rather failures to even start to shutdown.
(In reply to comment #13) > I'm saying, as a good practice, let's start with the simplest approach and > see where to go from there. I think that the real requirements will only > arise when the thing gets deployed. Just please take a look at the existing modules. Maybe we could reuse one of them. (In reply to comment #14) > (In reply to comment #12) > > eselect-sysvinit can do little in case of individual init systems boot > > failures. > > However, we could just store the old init symlink into /sbin/init.old or > > something like that. > > No, not boot failures, rather failures to even start to shutdown. That's somehow the issue with OpenRC design -- it all falls apart when anything changes...
seems like over engineering to a problem that doesn't exist and an edge case which is rare -- changing init systems. few (if any) do this regularly ... rather they do it once and then that's it.
(In reply to comment #16) Exactly my thoughts.
It's a common approach to the problem of dealing with file collisions with packages, I don't think it's over engineering. It's just a way to make the Gentoo experience a bit smoother and simpler for the end user, but if we look at the convolution of some design decisions in other places of the distro, I understand why developers don't get it.
What I want here is just swapping some symlinks to avoid placing nonsensical blocker conflicts in the ebuild dependencies. That's the same thing we do, and other distros do (eg. the MTA, which we don't), for many other things.
(In reply to comment #16) > seems like over engineering to a problem that doesn't exist and an edge case > which is rare -- changing init systems. few (if any) do this regularly ... > rather they do it once and then that's it. Please try to read the whole bug and the code attached to it (and perhaps the overlay ebuilds on github), it looks like you did not.
(In reply to comment #19) > What I want here is just swapping some symlinks to avoid placing nonsensical > blocker conflicts in the ebuild dependencies. That's the same thing we do, > and other distros do (eg. the MTA, which we don't), for many other things. Except that in the systemd ebuild, there are no non-sensical blockers. systemd does not collide currently with sysvinit. There are several init systems in the tree, and we do not need somethinglike this for them. I am in the same camp as comment #16 and comment #17.
I have been able to fix the problem of calling init after having changed it. After an eselect sysvinit set, init calls are still routed to the currently running init. You can find the fixes in the latest eselect-sysvinit-0.2 ebuild. This new ebuild also requires systemd and sysvinit to be re-emerged. In particular, in sysvinit I changed #define INIT from /sbin/init to /sbin/init.d/sysvinit/init to make the routing work as expected.
(In reply to comment #21) > (In reply to comment #19) > > What I want here is just swapping some symlinks to avoid placing nonsensical > > blocker conflicts in the ebuild dependencies. That's the same thing we do, > > and other distros do (eg. the MTA, which we don't), for many other things. > > Except that in the systemd ebuild, there are no non-sensical blockers. > systemd does not collide currently with sysvinit. That is not really true, try to emerge systemd on an openrc system. Furthermore, the way USE=systemd is handled in most packages cause other nonsensical blockers as well. > There are several init systems in the tree, and we do not need somethinglike > this for them. This is not a good reason not to have something like this. If we want to prepare a possible migration path from openrc to systemd, the eselect-sysvinit idea makes it possible without writing month-long instructions on how to boot with systemd, depending on the bootloader you use, the initramfs you use, etc. > > I am in the same camp as comment #16 and comment #17.
(In reply to comment #22) > I have been able to fix the problem of calling init after having changed it. > After an eselect sysvinit set, init calls are still routed to the currently > running init. You can find the fixes in the latest eselect-sysvinit-0.2 > ebuild. > This new ebuild also requires systemd and sysvinit to be re-emerged. In > particular, in sysvinit I changed #define INIT from /sbin/init to > /sbin/init.d/sysvinit/init to make the routing work as expected. Probably we should also change the search path for the inittab as well. (To be on record I consider the idea good since I'm expecting lots of people trying one or the other out of curiosity and then move to the other once they figure which works for them)
Is the point to allow switching init without rebooting? I hope not. It's nearly impossible to describe to users howto get a clean environment for eg. ConsoleKit, systemd-logind, DMs And if that's not the point, then the whole idea is pointless since you can control it by kernel commandline which is more flexible (you can even pass it from the grub commandline itself before booting to the system) /me shudders when thinking about the bugs this would cause...
I have been able to prepare a system with both openrc and systemd that are switchable at runtime through eselect-sysvinit and eselect-settingsd. Both seem to work as intended (I'm not saying that I may have uncovered some bugs that would need fixing). The solution was simple, through the ebuilds available in the systemd-love overlay I have been able to swap sys-fs/udev with sys-apps/systemd which became the new device manager. Then, to make systemd fully working, I just added USE=systemd to global USE flags and rebuilt the installed packages with IUSE=systemd. As far as I remember, Lennart at FOSDEM told that systemd is expected to work fine on a system with consolekit running and that seems to be true here. Making this possible is just a matter of wanting it, and fix the bugs that arise. As I said multiple times, you cannot say that editing kernel parameters is easy for some Gentoo users coming from Sabayon and lowering the bar is never a bad thing. Swapping symlinks is much more reliable of understanding and handling bootloader syntax.
(In reply to comment #23) > That is not really true, try to emerge systemd on an openrc system. > Furthermore, the way USE=systemd is handled in most packages cause other > nonsensical blockers as well. > No idea what you're talking about here; I do not recall any collisions between the systemd and openrc when I converted my main workstation.
(In reply to comment #25) > And if that's not the point, then the whole idea is pointless since you can > control it by kernel commandline which is more flexible (you can even pass > it from the grub commandline itself before booting to the system) > > /me shudders when thinking about the bugs this would cause... Indeed. If a user wants to switch init systems it's better if he keeps separate entries in his bootloader. This eselect module looks shiny and pretty but I don't think it makes sense for the majority of people
Let's sum up this a bit. We can make a minimal or full init switching module here. Minimal would just switch /sbin/init, full would switch all sysvinit-related files. For now, minimal is enough and causes less issues so I'd guess we should keep discussing that. It should be noted, however, that at some point systemd may drop more sysv compat, and then the remaining issues will come live. Pros are quite clear: 1. it's easier to use for user, 2. you can change init without writing to boot sector or modifying bootloader configs -- theoretically safer, 3. Luca mentioned EFI systems have trouble changing kernel command-line. Cons: 1. we're switching files which the init may require. For example, if OpenRC called 'init' and 'init' became some other RC in an OpenRC session, the results are hard to guess. While in the worst case it would probably require just a dirty reboot, that doesn't look like a properly made solution to me. 2. if the other init doesn't work, system doesn't boot. Ends up hoping that user knows the path to the other init, so he could use 'init=' to rescue the system. So far, I'm mostly concerned about 1. This is a pretty bad thing. For one, systemd can handle it -- it supports being symlinked as 'init', and deferring calls on non-systemd boot to other executable. I have no idea how others handle that.
eselect-sysvinit-0.3 and sys-apps/systemd, sys-apps/sysvinit on the systemd-love overlay do exactly that, only /sbin/init is swapped.
I'm still not sold on this, especially with the cons that mgorny has raised. I am mostly concerned about the first one as well, e.g. 1. boot with openrc/sysvinit: 2. eselect sysvinit set systemd 3. Now how do you shut down cleanly? 4. once you manage that, how do you shut down under systemd? I really think an eselect module is not an appropriate solution where init= works best. As I've said before, gentoo users know how to edit configuration files, so I don't feel that asking them to edit their boot loader configuration (and remember to run lilo if that's what they use) is too much.
(In reply to comment #31) > I'm still not sold on this, especially with the cons that mgorny has raised. > > I am mostly concerned about the first one as well, e.g. > [...] I ask you to test the ebuilds yourself. You would realize that there is no such problem. Moreover, since version 0.2, there is also an exec.sh wrapper installed into /lib/init.d/ that can be used to redirect calls to the currently running init system. However, version 0.3 just handles /sbin/init (while reboot, halt, poweroff are no longer handled) and for that, there is no need of wrappers. systemd and sysvinit (which boots openrc) can be swapped without problems. The /sbin/init symlink is now handled in an atomic way (as mgorny@ suggested). There are systems that don't allow you to change the kernel cmdline. If we keep thinking that the average user can do this and that, we're just living in our little world.
people have to be able to handle modifying their kernel command line. they can't even boot their system if they can't get that far. having them add their own init= line to try a different init system is not a problem. the only systems that can't change the command line are ones with both a locked and non-interactive boot loader and signed kernel. are those systems realistically running Gentoo ? i doubt it.
I think there is some point in having an eselect-sysvinit module. But it better leave /sbin/init as it is now. Instead, it could switch a symlink called /sbin/einit (or any other suitable name). Users who want the switch feature would have to specify init=/sbin/einit only once during installation, which makes it compatible with EFI Stub kernels that have a non-variable kernel command line. Users who don't want to switch will not see any changes or suffer from additional complexity.
More ideas came from gentoo-dev ML for symlink locations: /bin/init (suggested by lu_zero) /sbin/gentoo-init (suggested by slyfox) Both seem ok, but I guess /bin/init has a higher chance of causing trouble with a future sbin->bin move.
I would vote against /bin/init, because eventually sysvinit will move there if we do the sbin->bin move. I would suggest either /bin/einit or /bin/Gentoo-init.
Looks like this would be WONTFIX after re-reading all the stuff and from the discussions I remember in the past :/