Wednesday, November 18, 2020

Using zerofree to reduce Ubuntu/Debian OVA file size

Editor's note [2020-11-21]: this is an update to a 2014 post on the same topic.  Since then, the mount command is also required.

When exporting an OVA file from VirtualBox's "Export Appliance" feature, any disk block that isn't filled with 0 has to be included in the resulting file.  Normally, an OS doesn't create those blocks as it works; when a file is deleted, the space is marked as free, but retains its original contents until it is re-allocated for another file.  If there are a lot of files deleted, a significant amount of non-empty "empty" space can accumulate.

Running the zerofree program writes data of value 0 over all space marked as free, allowing that free space to be excluded from the OVA file again.

The following applies to Ubuntu 18.04 (bionic) and 20.04 (focal) at least; I forget exactly how far back it goes, but the way to get at a command line changed at some point, and there was a period where poweroff didn't actually work in the pre-boot environment.

Regardless, here's how to run zerofree on Debian, Ubuntu, or derivatives.

Before starting, the zerofree package must be installed on the virtual machine.  Then, do all the deletion that you want to do, such as running apt-get clean to remove downloaded package files.  Then, shut down the virtual machine.

  1. Start the machine in graphical mode (Normal Start.)  We want to interrupt the GRUB menu.
  2. Press 'e' to edit the command list.
  3. Scroll down to the one that says "linux ..."; it should be the next-to-last line.
  4. Move to the end of the line, and add break=init to the parameter list (separated by a space from the other parameters.)
  5. Press Ctrl+X or F10 to boot.
  6. Wait for the shell prompt.

Here's where it gets a little complicated.  If you don't know the partition to be cleared, there are some extra commands to discover it.  Run mount and look for a line like /dev/sda2 on /root ...—the /dev/sda2 is the device that will be used in the zerofree command.

To run zerofree, we will use chroot to get into the root filesystem, but first, we need to make /proc visible there.  The program will access the kernel's list of mounted filesystems to avoid running on any filesystem that is mounted in writable mode.

Run the commands:

mount --bind /proc $rootmnt/proc
chroot $rootmnt /usr/sbin/zerofree -v [DEVICE]

Substitute the root partition's device name for [DEVICE]. For instance, to zero the free space on /dev/sda2, the exact command would be:

chroot $rootmnt /usr/sbin/zerofree -v /dev/sda2

The -v option gives a progress display while the command works, and an inscrutable status message at the end.

Once complete, run poweroff to shut the machine down cleanly. It is now ready for export.

No comments: