marcan / takeover.sh

Wipe and reinstall a running Linux system via SSH, without rebooting. You know you want to.
Other
7.1k stars 353 forks source link

Systemd support [idea] #3

Closed JamesTheAwesomeDude closed 7 years ago

JamesTheAwesomeDude commented 7 years ago

Would support for takeover of systemd-based systems be even within the imaginable scope of this? I know it is very much a cluster.

marcan commented 7 years ago

It should be fairly straightforward to add. You need to detect that systemd is the current init system, figure out what binary it re-execs so you can overlay that one instead, and then use systemctl daemon-reexec instead of telinit u. Someone needs to implement it and test it to make sure it works as intended.

chewi commented 7 years ago

If you saw my earlier deleted message, please disregard it. I've had a crack at this, going from openSUSE 42.1 to the latest SystemRescueCd, but not quite managed it.

systemd can be reliably be detected by checking whether /proc/1/exe points to a binary called systemd. This is how Chef does it.

The full path of the binary to re-exec is /usr/lib/systemd/systemd so you must bind mount tmp over this directory instead of /sbin.

You can copy /usr/bin/systemctl or you can just leave it to copy telinit as this is a symlink and the old telinit u syntax still works according to the man page.

When I actually try it, everything seems to work except the pivot_root. I can see from journalctl that systemd has re-exec'd and I can also see that fakeinit has replaced systemd as PID 1. However…

About to take over init. This script will now pause for a few seconds.
If the takeover was successful, you will see output from the new init.
You may then kill the remnants of this session and any remaining
processes from your new SSH session, and umount the old root filesystem.
Init takeover successful
Pivoting root...
pivot_root: Invalid argument
Chrooting and running init...

I have tried changing the pivot_root call to use absolute paths but no dice. My busybox is the latest 1.26.2 official static build. Any ideas?

P.S. This is just a local test, my main aim is to replace Debian with Gentoo on a big ppc64le guest on the other side of the world. :wink:

chewi commented 7 years ago

Got it! I had to run this before pivot_root.

./busybox mount --make-rprivate /

I'll cook this all up into a pull request tomorrow. I haven't managed to umount /old_root though as I can't make it let go of /old_root/dev and /old_root/run. Hmm.

marcan commented 7 years ago

Make sure you kill all remaining daemons, unmount anything under /dev and /run, turn off swap, etc. I forgot to turn off swap the first time and that was a bit confusing until it hit me.

chewi commented 7 years ago

Success! Please see #4 for the changes. It was indeed swap holding onto /dev. Should we swapoff -a in the script? I still couldn't shift /run until I did a lazy umount and then old_root umounted normally. lvs confirmed that the device was no longer in use.