Friday, August 15, 2014

Debian/Ubuntu init breakpoints (How to run zerofree and power off correctly afterwards)

Editor's Note [2020-11-21]: If you just want to run zerofree, see my updated post: Using zerofree to reduce Ubuntu/Debian OVA file size.

Most of the Debian information mentions break=init and then says “see the /init source for more options.”  Fortunately, I can use break=init and then dig through /init myself.

Here’s the possible list for Ubuntu 14.04 Trusty Tahr:
  • top: after parsing commandline and setting up most variables, prior to the /scripts/init-top script
  • modules: before loading modules and possibly setting up netconsole
  • premount (default for break without a parameter): prior to the /scripts/init-premount script
  • mount: prior to /scripts/${BOOT} (which is set to "local" in my VM but comments indicate it can be otherwise under casper)
  • mountroot: prior to actually mounting the root filesystem
  • bottom: prior to running /scripts/init-bottom and mounting virtual filesystems within the root
  • init: prior to unsetting all initramfs-related variables and invoking the real init
break=init drops to a busybox shell with the root device filesystem mounted at $rootmnt which is /root on my system.  The virtual filesystems like /proc are also mounted under there, in the device’s root directory, not the initramfs’ root.  This is actually the state I want to be in, and digging out that list of break options was entirely irrelevant.  My apologies for the unintended shaggy-dog story.

From here, to run zerofree /dev/sda1 (your device name may vary) and shut down the system correctly afterwards:
  1. Boot with break=init
  2. chroot $rootmnt /bin/sh
  3. zerofree /dev/sda1
  4. exit
  5. sync
  6. poweroff
I just need to chroot into the disk first, so that zerofree can read the mount table from /proc/mounts (it doesn’t run on a writable filesystem.)  Then to clean up, I return to the initramfs where I can use its working poweroff command.

I used to use init=/bin/sh to get a shell inside the root mount, but then I didn't have a way to shut down the system cleanly.  In the image, shutdown wants to talk to init via dbus, neither of which are actually running, and it simply delivers a cryptic message like “shutdown: Unable to shutdown system”.  Recovery or single-user modes didn't work because the filesystem was already mounted read-write and enough services were up to prevent remounting it as read-only.

No comments: