-
-
Notifications
You must be signed in to change notification settings - Fork 3.6k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
systemctl: switch-root: align behaviour with manual #3958
Conversation
The manual says no state will be passed from one systemd to the next if the path of the next init is specified on the command line. However systemctl tries to detect if the next init is systemd and then pass it's state anyway. Just delete this code.
local-fs.target should be stopped before switching root. If this does not happen, you are probably seeing effect of #3436 |
Sorry, my bad. I turns out that one of the two custom units I added to the initrd indirectly created a dependency link between initrd-switch-root.target and local-fs.target, and hence isolating the initrd-switch-root.target in the initrd did not deactivate the local-fs.target properly. I still think this patch makes sense though. It should be possible to start systemd in the rootfs without transferring state. The default initrd-switch-root.service does not specify the next init, so you'd have to manually override that to notice this change. |
I don't know. Transferring state like this is quite useful as a debug mechanism. I don't we should remove this capability unless there's a concrete reason. |
This doesn't remove the capability to transfer the state at all. You just need to not specify the path to the new init (which initrd-switch-root.service does not do by default). However without this patch it is not possible to disable transferring state if the next init is also systemd. |
No, this really should stay. We should pass all matching state from the initrd to the main system. After all it's highly relevant whether for example an fsck on the root fs failed or not, and "systemctl status" should show that after the system is up. Units in the initrd and on the host that have the same meaning should not really change meaning. It's OK if they change config slightly, but they really should semantically have the same meaning. If they change meaning they should really change name too. Specifically this means in your case local-fs.target should not be used in the initrd (unless you know for sure that no further file systems shall be mounted during runtime, before the services are up). There's initrd-fs.target specifically in order to have a different target for file systems mounted in the initrd. I am pretty sure we should continue to pass as much state as we can, if we know that the destination init system is actually systemd. I hope this makes sense, closing hence. |
If you really want to make it impossible to start systemd in the rootfs without transferring state, then you really should at least document it. It makes things very difficult to debug when the manual explicitly states that when you specify the path to the next init no state is passed, and then it does so anyway. |
I wouldn't call it "making it impossible"... I'd just call it "try hard to transfer the state if we can". But yeah, we should document this. |
…cross As suggested: systemd#3958 (comment) Let's document that we try hard to pass system state from the initrd to the host, and even compare the systemd binary paths.
I posted #3995 which adds a quick note about this behaviour to the systemctl man page. |
If it's not impossible then please tell me how to start systemd in the rootfs without transferring state as the code is now without some hack like renaming /usr/lib/systemd/systemd in the rootfs to /usr/lib/imspartacus. In other words I totally agree that transferring state is a nice feature and should be used when possible. I just don't see why we can't (at least for debugging purposes) have a way to turn it off without resorting to silly name games. |
Well, I didn't say it's not impossible. I just said I wouldn't call it that way, and just focus on the good... I'd be open to maybe add a way how the passing of state can be forcibly disabled. For example, we could add permit that if the init path is prefixed with |
Sure that would work. I just think it would be way easier to implement that "feature" by actually doing what the manual already says -- and that by just removing code. |
I mean the code in question only does anything if the given path is the canonical path to the systemd binary or a link to it. But this is exactly the situation where you might as well not give a path if you want the state transferred. So I think the already documented behaviour makes a lot of sense. |
Well, the reason the code is like it is is because some real-life initrds specified the path explicitly and thus lost state... It's difficult to go back from that now. |
..and when initrds start using ! will you then silently ignore that and pass state anyway? I mean you already documented it so if people pass the path then they probably expected the documented behaviour. I think it'd be much better if the initrd generators were fixed rather than systemd trying to trick them. In most distros on which systemd will be updated the kernel and initrd generators will likely also be updated and initrds regenerated. |
well, the |
Anyway, I'd be happy to take a patch that makes "!" as first char (or only char) in the init parameter to the method call a request to not pass state. |
…cross (#3995) As suggested: #3958 (comment) Let's document that we try hard to pass system state from the initrd to the host, and even compare the systemd binary paths.
"!" sound quite cryptic. Why not have a new switch like '--no-state'? |
well, the question is how to pass that PID 1... there we currently have a single method call SwitchRoot(). We'd have to add SwitchRootNoState() or so, to implement such a switch. Doing that is certainly an alternative, and less cryptic... That said, I am not too concerned if this is a bit cryptic, it appears to me that only folks who know what they do should use this... Moreover I think we should be cosnervative with adding ever more and more new switches to systemctl... If you ask me we probably already have too many. Following the scheme we use in nspawn and friends: maybe we should implement this via an additional env var or so that we check. i.e. consider this a hidden but supported feature, and don't list it in --help, but honour it via an env var, and then add SwitchRootNoState() to implement it. |
Dunno, I have to admit that I haven't had the need to switch-root systemd without passing state. The reason for this RFE was the |
so finally how to solved this problem? |
The manual says no state will be passed from one systemd to the next if the path of the next init
is specified on the command line. However systemctl tries to detect if the next init
is systemd and then pass it's state anyway. Just delete this code.
The specific problem this solves for me is that sometimes systemd in my initrd will pass a state to systemd on my rootfs that says local-fs.target is up. However local-fs.target on my root filesystem has more dependencies than in the initrd, so some filesystems are not mounted before systemd-tmpfiles is run to create files on them.
This patch at least let me work around the problem by specifically telling the initrd to not pass any state to systemd in the rootfs.