The Kernel Build That Ran Out of Disk Before It Ran Out of Time

A kernel build that copies its starting configuration from an already-working system inherits that system's scale along with its settings. This one inherited enough loadable modules to build a kernel for almost any hardware that machine's config file had ever anticipated — not just the one machine actually running it — and the build tree that produced ran out of a dedicated 37G partition before it finished compiling.

What "olddefconfig off a full config" actually builds

Seeding a new kernel's .config from a working host's own config (see the companion piece on why that config needed auditing for other reasons) and migrating it forward with make olddefconfig keeps every option the host config already set, including every driver module the host's config enabled for hardware it might never see — every network card, every filesystem, every device class the distribution's kernel packagers include so the same kernel image can run on effectively any PC. Building all of that produced roughly 6,571 separate =m module entries. The kernel build tree needed to compile all of them reached 22G on its own, and the dedicated LFS root partition set aside for this entire system was 37G total.

Where it actually stopped

The build didn't fail with a clean, early "not enough space" error. It ran until the partition genuinely filled up mid-compile — object files, intermediate build artifacts, and the eventual installed modules all competing for the same 37G with everything else already living on that partition. A kernel build failing this way doesn't point cleanly at its actual cause the way a missing dependency or a syntax error does; the symptom is generic disk exhaustion, and the fix requires recognizing that the real problem is scope, not space.

Trimming to what this machine actually runs

The fix wasn't a bigger partition, or manually deselecting thousands of options by hand. make localmodconfig, seeded with this exact host's own lsmod output, keeps only the modules currently loaded and running on the machine right now, discarding every module the full config enabled for hardware that isn't present. Run after olddefconfig rather than instead of it, this pass doesn't touch built-in features or general kernel options — only the loadable-module list gets trimmed, down from covering "any PC this distribution supports" to covering "this specific machine, as it's actually configured today." The one thing that had to survive the cut was checked explicitly afterward: CONFIG_ATH12K=m, the wifi driver this whole config-inheritance approach existed to preserve, was confirmed still present once the trim finished.

Moving the build tree, not just shrinking it

Trimming modules addressed the config; it didn't address where the build actually happens. The kernel source and build tree moved from the LFS root partition to a separate, much larger one — 92G versus 37G — mounted at /home inside the chroot for exactly this purpose. Only the small final output that actually needs to live on the system's own root partition (the compressed kernel image, the installed modules directory, kernel documentation) gets copied there via the normal install step; the multi-gigabyte build tree that produces them lives somewhere with real headroom instead.

Why both fixes were needed, not just one

Trimming modules without moving the build tree would have shrunk the problem without necessarily solving it — a smaller but still substantial module set, built inside the same undersized partition, given enough future growth in the config or the source tree. Moving the build tree without trimming modules would have solved the immediate space crisis while leaving a kernel that took far longer to build and installed thousands of modules for hardware that will never load them. Together, the two fixes address two different questions that got conflated by a single symptom: how much do I actually need to build, and where should the intermediate mess of building it actually live. A full disk answered neither question on its own — it just made clear that the answer to at least one of them was wrong.

Add new comment

Restricted HTML

  • Allowed HTML tags: <a href hreflang> <em> <strong> <cite> <blockquote cite> <code> <ul type> <ol start type> <li> <dl> <dt> <dd> <h2 id> <h3 id> <h4 id> <h5 id> <h6 id>
  • Lines and paragraphs break automatically.
  • Web page addresses and email addresses turn into links automatically.
Please share this article on your favorite website or platform.