You gave the VM a 40G disk. The login banner says Usage of /: 40.4% of 18.01GB. Where did the other 22G go? When a disk fills up at 3am, the first question is always "which disk, which piece of it, and how big is it really" - this lesson teaches you to read that stack.
What you need to know already: 1.3 The tree (mount points), 1.15 Who's in charge (boot, initramfs).
The layers, bottom to top
- Disk - the raw storage device. Linux shows disks as files in
/dev(the directory of devices), e.g./dev/vda. - Partition - a disk cut into fixed sections, each used separately.
- Filesystem - the structure written onto a partition that turns raw space into files and directories (Ubuntu's usual one is called ext4). "Formatting" means creating a filesystem.
- Mount - attaching a filesystem at a directory of the tree, its mount point. After mounting, the filesystem's files appear under that directory.
Ubuntu adds one more layer in between, LVM (below).
40G on paper, 18G to use
lsblk (list block devices - disks and anything built on them) draws that stack as a tree:
$ lsblk
NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINTS
vda 253:0 0 40G 0 disk
├─vda1 253:1 0 1G 0 part /boot/efi
├─vda2 253:2 0 2G 0 part /boot
└─vda3 253:3 0 36.9G 0 part
└─ubuntu--vg-ubuntu--lv 252:0 0 18G 0 lvm /
vdb 253:16 0 50G 0 disk
└─vdb1 253:17 0 50G 0 part /data
...
The columns: NAME (indented under what it sits on), MAJ:MIN (the kernel's internal device numbers - ignore), RM (removable? 0 = no), SIZE, RO (read-only? 0 = no), TYPE (disk, part = partition, lvm = logical volume), and MOUNTPOINTS (where it is attached, if anywhere).
vda is the virtual disk UTM gave the VM. The "v" is for virtio: a virtual device the guest knows is virtual, so it talks to the hypervisor directly instead of pretending to drive real hardware - much faster. vda1, vda2, vda3 are its three partitions: two small ones for boot files (/boot/efi for the firmware, /boot for the kernel), and one big one.
LVM: the flexible layer
LVM (Logical Volume Manager) puts a flexible layer between partitions and filesystems. Three words:
- PV (physical volume) - a partition handed to LVM. Here:
vda3. - VG (volume group) - a pool made from one or more PVs. Here:
ubuntu-vg, about 37G. - LV (logical volume) - a slice cut from the pool, used like a partition but it can be grown later, even while in use. Here:
ubuntu-lv, 18G, mounted at/.
(In lsblk and df the name shows as ubuntu--vg-ubuntu--lv: the VG and LV names joined by -, with the dashes inside each name doubled so they can be told apart.)
The part that surprises everyone: Ubuntu's guided install gives the root LV only half the pool by default (on disks between about 20G and 200G; above that the root LV is capped at 100G). The rest stays free in the VG, so you can grow / later without repartitioning:
sudo vgs list VGs; the VFree column = pool space not yet handed out
sudo lvextend -l +100%FREE /dev/ubuntu-vg/ubuntu-lv grow the LV by all the free space
sudo resize2fs /dev/ubuntu-vg/ubuntu-lv grow the ext4 filesystem to fill it
(Two steps, because the LV and the filesystem on it are separate layers: first make the volume bigger, then tell the filesystem it may use the new room.)
That is why df -h / says ~19G while the disk says 40G. Nothing is wrong.
df: how full is each filesystem
df (disk free) reports every mounted filesystem; -h = human sizes:
$ df -h /
Filesystem Size Used Avail Use% Mounted on
/dev/mapper/ubuntu--vg-ubuntu--lv 19G 7.7G 9.5G 45% /
Filesystem is the device it lives on (/dev/mapper/... is how LVM volumes appear), then total Size, Used, Available, Use%, and the mount point. Used + Avail is a bit less than Size: ext4 keeps about 5% back for root (chapter 4).
df -h with no path lists every mounted filesystem. Lines of type tmpfs are filesystems that live in memory, not on disk (/run holds files that only matter until the next reboot) - you can ignore them for now.
Thin vs thick provisioning
You told UTM "40G". It did not take 40G from your Mac. The VM's whole disk is one file on the Mac, in a format called qcow2, which starts at a few hundred MB and grows as the guest writes - thin provisioning.
- Thin: allocate space when it is first written. Saves space, and you can over-commit (three 40G VMs on a 100G Mac). The risk: the host fills up, and every guest gets write errors at once.
- Thick: take it all up front. Predictable, no nasty surprise, but you pay for the space immediately.
Note also that qcow2 does not shrink when you delete files inside the guest. Freeing 10G in the VM does not give 10G back to macOS until the image is compacted (rewritten without the empty space).
No LUKS
You chose guided storage without encryption. LUKS is Linux's standard disk encryption: everything on the volume is scrambled until you type a passphrase at boot. That protects a stolen disk - and means the box cannot boot unattended. Correct choice for a lab VM, wrong choice for a laptop.
What you can now do
- Read
lsblk: disk, partitions, the LVM layers, and where each is mounted. - Say what PV, VG and LV are, and why
/is 18G on a 40G disk. - Read
df -h, and explain thin vs thick provisioning.