{"id":18497836,"url":"https://github.com/containers/initoverlayfs","last_synced_at":"2025-10-07T16:03:15.805Z","repository":{"id":203321395,"uuid":"709325757","full_name":"containers/initoverlayfs","owner":"containers","description":null,"archived":false,"fork":false,"pushed_at":"2024-06-06T18:06:25.000Z","size":642,"stargazers_count":42,"open_issues_count":15,"forks_count":8,"subscribers_count":16,"default_branch":"main","last_synced_at":"2025-10-07T16:02:54.062Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"C","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"gpl-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/containers.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":".github/CODEOWNERS","security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2023-10-24T13:47:06.000Z","updated_at":"2025-09-23T19:46:32.000Z","dependencies_parsed_at":null,"dependency_job_id":"5e539034-2230-47db-8dc7-d3f079480b26","html_url":"https://github.com/containers/initoverlayfs","commit_stats":null,"previous_names":["containers/initoverlayfs"],"tags_count":19,"template":false,"template_full_name":null,"purl":"pkg:github/containers/initoverlayfs","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/containers%2Finitoverlayfs","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/containers%2Finitoverlayfs/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/containers%2Finitoverlayfs/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/containers%2Finitoverlayfs/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/containers","download_url":"https://codeload.github.com/containers/initoverlayfs/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/containers%2Finitoverlayfs/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":278802803,"owners_count":26048567,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-10-07T02:00:06.786Z","response_time":59,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-11-06T13:36:11.964Z","updated_at":"2025-10-07T16:03:15.773Z","avatar_url":"https://github.com/containers.png","language":"C","funding_links":[],"categories":["Minimal rootfs","C"],"sub_categories":[],"readme":"# initoverlayfs\n\nA scalable solution for initial filesystems focused on minimal resource usage, suitable for both critical and non-critical environments.\n\n- [What is initoverlayfs?](#what-is-initoverlayfs)\n- [Why use initoverlayfs?](#why-use-initoverlayfs)\n- [Dependencies](#dependencies)\n- [Installation](#installation)\n\t* [Step 1 - Deploy the software](#step-1---deploy-the-software)\n\t* [Step 2 - Run initoverlayfs-install](#step-2---run-initoverlayfs-install)\n\t* [Step 3 - Reboot to test](#step-3---reboot-to-test)\n\t* [Step 4 - Validating the boot](#step-4---validating-the-boot)\n\n# What is initoverlayfs?\n\ninitoverlayfs is a solution that uses transient overlays as an initial filesystem rather than soley an initramfs. If compression is used, it relies on transparent decompression, rather than upfront decompression. This results in more scalable, maintainable initial filesystems.\n\nHere we see a traditional boot sequence:\n\n```\nfw -\u003e bootloader -\u003e kernel -\u003e initramfs ---------------------------------------\u003e rootfs\n\nfw -\u003e bootloader -\u003e kernel -\u003e init ---------------------------------------------------\u003e\n```\n\nHere is the boot sequence with initoverlayfs integrated, the mini-initramfs contains just enough to get storage drivers loaded and storage devices initialized. storage-init is a process that is not designed to replace init, it does just enough to initialize storage, switch-root's to initoverlayfs and continues as normal.\n\n```\nfw -\u003e bootloader -\u003e kernel -\u003e mini-initramfs --------------\u003e initoverlayfs -\u003e rootfs\n\nfw -\u003e bootloader -\u003e kernel -\u003e init ------------------------------------------------\u003e\n                                    |\n                                    `-initoverlayfs-+\n```\n\n# Why use initoverlayfs?\n\nAn initramfs (Initial RAM File System) image is a fundamental component in preparing Linux systems during the boot process, preceding the initiation of the init process.\n\nTypically, generating an initramfs involves assembling all available kernel modules and necessary files to boot and support any hardware using the specific Linux kernel version XYZ. This may also include some initialization that's not hardware specific, such as disk encryption, disk verification, early graphics, early camera input, ostree prepare root, etc.\n\nHowever, this conventional approach presents a significant challenge: loading such a voluminous image into memory during boot is time-consuming and can be problematic in critical scenarios where time to boot is critical. Edge devices commonly need to boot as quickly as possible such as healthcare, automotive and aviation.\n\nConversely, the initoverlayfs approach proposes a solution: dividing the initramfs image into two parts, relying on transparent decompression rather than upfront decompression.\n\nThis division entails segregating the initramfs image into two distinct components.\n\nThe first component (initramfs) contains init, kernel modules, udev-rules and an initoverlayfs tool, responsible for setting up and mounting initoverlayfs. Then we switches to the second component (initoverlayfs), containing all additional kernel modules and essential files required to support the Linux boot process.\n\nThis scalable approach moves a significant portion on the initial filesystem content to initoverlayfs which is more scalable as it does on-demand decompression.\n\nFor illustration, consider a comparison of the sizes using dracut versus initoverlayfs:\n\n**Using dracut only**:\n``` bash\n# dracut -f\n# du -sh /boot/initramfs-6.5.5-300.fc39.x86_64.img\n36M\t/boot/initramfs-6.5.5-300.fc39.x86_64.img\n```\n\n**Using dracut + initoverlayfs**:\n``` bash\n# /usr/bin/initoverlayfs-install -f\n# du -sh /boot/initramfs-6.5.5-300.fc39.x86_64.img\n13M\t/boot/initramfs-6.5.5-300.fc39.x86_64.img\n^^ \u003c--- from 36M to 13M\n```\n\nThe advantages of adopting the initoverlayfs approach are evident in the substantial reduction in the size of the initramfs image, thereby significantly expediting the boot process, making it especially appealing in resource-constrained and time-sensitive scenarios.\n\nThis is a graphic comparing the boot time effect of increasing initramfs size vs the effect of increasing initoverlayfs size, initoverlayfs is only effected by bytes you use:\n\n![initramfs-vs-initoverlayfs-scale](https://github.com/containers/initoverlayfs/assets/1694275/6f339016-7bcf-4129-af0e-a3f0be7c9be0)\n\nThis is a graphic comparing the systemd start time using initramfs only vs using initramfs + initoverlayfs on Raspberry Pi 4 with NVMe drive over USB:\n\n![image](https://github.com/containers/initoverlayfs/assets/1694275/f18db634-1c51-4ff7-9c68-423abee0fce4)\n\n# Dependencies\n\n- EROFS - Initoverlayfs uses erofs as the underlying filesystem.\n- dracut - As the initramfs and initoverlayfs composing tool.\n- systemd - As the init system.\n\nNote: none of the above dependencies are strictly needed, all the tools could be swapped out for other similar tools.\n\n# Installation\n\n### Step 1 - Deploy the software\n\nCurrently, RPM packages are available through the Copr Packages repository.\n\n``` bash\ndnf copr enable -y @centos-automotive-sig/next\ndnf install initoverlayfs\nCopr repo for next owned by @centos-automotive-sig  2.4 kB/s | 3.3 kB   00:01\nDependencies resolved.\n=============================================================================\n Package            Arch        Version           Repository            Size\n=============================================================================\nInstalling:\n initoverlayfs      x86_64      0.96-1.fc39       @commandline          22 k\nInstalling dependencies:\n libdeflate         x86_64      1.9-7.fc39        fedora                55 k\nInstalling weak dependencies:\n erofs-utils        x86_64      1.7.1-1.fc39      updates-testing      140 k\n\nTransaction Summary\n=============================================================================\nInstall  3 Packages\n\nTotal size: 217 k\nTotal download size: 195 k\nInstalled size: 487 k\nIs this ok [y/N]: y\n\n# rpm -qa | grep -i initoverlayfs\ninitoverlayfs-0.96-1.fc39.x86_64\n```\n\n**Note:**\ncentos-stream-9 requires package from epel-release\n\n```\ndnf install -y epel-release\n```\n\n### Step 2 - Run initoverlayfs-install\nOnce the deployment is completed, the next step is to execute the /usr/bin/initoverlayfs-install tool. This tool is responsible for generating both the initramfs and initoverlayfs images, along with the essential initoverlayfs.conf configuration.\n\n``` bash\n# /usr/bin/initoverlayfs-install -f\n\u003cSNIP\u003e\ninitoverlayfs\nkernel-modules\nudev-rules\ndracut: Skipping udev rule: 40-redhat.rules\ndracut: Skipping udev rule: 50-firmware.rules\ndracut: Skipping udev rule: 50-udev.rules\ndracut: Skipping udev rule: 91-permissions.rules\ndracut: Skipping udev rule: 80-drivers-modprobe.rules\ndracut: *** Including modules done ***\ndracut: *** Installing kernel module dependencies ***\ndracut: *** Installing kernel module dependencies done ***\ndracut: *** Resolving executable dependencies ***\ndracut: *** Resolving executable dependencies done ***\ndracut: *** Hardlinking files ***\ndracut: Mode:                     real\ndracut: Method:                   sha256\ndracut: Files:                    819\ndracut: Linked:                   0 files\ndracut: Compared:                 0 xattrs\ndracut: Compared:                 77 files\ndracut: Saved:                    0 B\ndracut: Duration:                 0.007777 seconds\ndracut: *** Hardlinking files done ***\ndracut: *** Generating early-microcode cpio image ***\ndracut: *** Constructing AuthenticAMD.bin ***\ndracut: *** Constructing GenuineIntel.bin ***\ndracut: *** Store current command line parameters ***\ndracut: *** Stripping files ***\ndracut: *** Stripping files done ***\ndracut: *** Creating image file '/boot/initramfs-6.5.5-300.fc39.x86_64.img' ***\ndracut: Using auto-determined compression method 'pigz'\ndracut: *** Creating initramfs image file '/boot/initramfs-6.5.5-300.fc39.x86_64.img' done ***\n```\n\nExcellent! Now, let's proceed to compare the size of the newly generated initramfs image\nwith the existing ones in the filesystem.\n\n``` bash\n# uname -r\n6.5.5-300.fc39.x86_64\n\n# du -sh /boot/init*\n81M\t /boot/initramfs-0-rescue-285b2edb8ad94c7381215fd5720afd54.img\n34M\t /boot/initramfs-6.4.12-200.fc38.x86_64.img\n34M\t /boot/initramfs-6.5.5-200.fc38.x86_64.img\n\n13M  /boot/initramfs-6.5.5-300.fc39.x86_64.img     \u003c- first image to load (storage drivers only)\n149M /boot/initoverlayfs-6.5.5-300.fc39.x86_64.img \u003c- second image (extra kernel mods and files)\n```\n\n### Step 3 - Reboot to test\n\nTo load the new generated **initramfs and initoverlayfs** images a reboot of the system is necessary.\n``` bash\n# reboot\n```\n\n### Step 4 - Validating the boot\n\nTo validate whether the new image has been successfully loaded after the reboot, you can execute the following journalctl command and search for the keyword initoverlayfs:\n\n``` bash\n# journalctl -b -o short-monotonic | grep -i initoverlayfs\n[    4.949129] fedora systemd[1]: Queued start job for default target pre-initoverlayfs.target.\n[    5.526459] fedora systemd[1]: Starting pre-initoverlayfs.service - pre-initoverlayfs initialization...\n[    9.179469] fedora initoverlayfs[193]: bootfs: {\"UUID=1a3a6db4-a7c2-43e5-bed5-9385f26c68ff\", \"bootfs UUID=1a3a6db4-a7c2-43e5-bed5-9385f26c68ff\"}, bootfstype: {\"ext4\", \"bootfstype ext4\"}, fs: {\"(null)\", \"(null)\"}, fstype: {\"(null)\", \"(null)\"}\n[    9.179469] fedora initoverlayfs[193]: fork_execlp(\"udevadm\")\n[    9.179469] fedora initoverlayfs[193]: forked 199 fork_execlp\n[    9.179469] fedora initoverlayfs[193]: mount(\"/boot\", \"/initoverlayfs/boot\", \"ext4\", MS_MOVE, NULL) 2 (No such file or directory)\n[    9.216158] fedora systemd[1]: Finished pre-initoverlayfs.service - pre-initoverlayfs initialization.\n[    9.235546] fedora systemd[1]: Starting pre-initoverlayfs-switch-root.service - Switch Root pre-initoverlayfs...\n[   12.207906] fedora systemd[1]: pre-initoverlayfs-switch-root.service: Deactivated successfully.\n[   12.232609] fedora systemd[1]: Stopped pre-initoverlayfs-switch-root.service.\n[   12.375125] fedora systemd[1]: pre-initoverlayfs.service: Deactivated successfully.\n[   12.393613] fedora systemd[1]: Stopped pre-initoverlayfs.service.\n```\n\nThat's fantastic news! The system is up and running smoothly.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcontainers%2Finitoverlayfs","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fcontainers%2Finitoverlayfs","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcontainers%2Finitoverlayfs/lists"}