Replace the fork+exec of /usr/bin/kexec in load_kexec_kernel() with a direct kexec_file_load() syscall, removing the runtime dependency on kexec-tools for systemctl kexec. The kexec_file_load() syscall (available since Linux 3.17) accepts kernel and initrd file descriptors directly, letting the kernel handle image parsing, segment setup, and purgatory internally. This is much simpler than the older kexec_load() syscall which requires complex userspace setup of memory segments and boot protocol structures — that complexity is the raison d'être of kexec-tools. The implementation follows the established libc wrapper pattern: a missing_kexec_file_load() fallback in src/libc/kexec.c calls the syscall directly when glibc doesn't provide a wrapper (which is currently always the case). The syscall is not available on all architectures — alpha, i386, ia64, m68k, mips, sh, and sparc lack __NR_kexec_file_load — so the wrapper and caller are guarded with HAVE_KEXEC_FILE_LOAD_SYSCALL to compile cleanly everywhere. When kexec_file_load() rejects the kernel image with ENOEXEC (e.g. the image is compressed or wrapped in a PE container that the kernel's kexec handler doesn't understand natively), we attempt to unwrap/decompress and retry. This is effectively the same decompression and extraction logic that already lives in src/ukify/ukify.py (maybe_decompress() and get_zboot_kernel()), now implemented in C so that systemctl can handle it natively without shelling out to external tools: - Compressed kernels (Image.gz, Image.zst, Image.xz, Image.lz4): the format is detected by magic bytes (per RFC 1952, RFC 8878, tukaani.org xz spec, and lz4 frame format spec) and decompressed to a memfd using the existing decompress_stream_*() infrastructure plus the new gzip support from the previous commit. This is primarily needed on arm64 where kexec_file_load() only accepts raw Image files. On x86_64, bzImage is already the native format and works directly. - EFI ZBOOT PE images (vmlinuz.efi): detected by "MZ" + "zimg" magic at the start of the file. The compressed payload offset, size, and compression type are read from the ZBOOT header defined in linux/drivers/firmware/efi/libstub/zboot-header.S. - Unified Kernel Images (UKI): detected as PE files with a .linux section via the existing pe_is_uki() infrastructure. The .linux section (kernel) and optionally .initrd section are extracted to memfds. When a UKI provides an embedded initrd and the boot entry doesn't specify one separately, the embedded initrd is used. The try-first-then-decompress approach means we never decompress unnecessarily: on x86_64 the first kexec_file_load() call succeeds immediately with the raw bzImage, and on architectures where the kernel's kexec handler natively understands PE (like LoongArch with kexec_efi_ops), ZBOOT/UKI images work without decompression too. If kexec_file_load() is unavailable (architectures without the syscall) or all attempts fail, we fall back to forking+execing the kexec binary. This preserves compatibility on architectures like i386 and mips where only the older kexec_load() syscall exists and kexec-tools is needed to handle the complex userspace setup. Co-developed-by: Claude Opus 4.6 <noreply@anthropic.com>
System and Service Manager
Details
Most documentation is available on systemd's web site.
Assorted, older, general information about systemd can be found in the systemd Wiki.
Information about build requirements is provided in the README file.
Consult our NEWS file for information about what's new in the most recent systemd versions.
Please see the Code Map for information about this repository's layout and content.
Please see the Hacking guide for information on how to hack on systemd and test your modifications.
Please see our Contribution Guidelines for more information about filing GitHub Issues and posting GitHub Pull Requests.
When preparing patches for systemd, please follow our Coding Style Guidelines.
If you are looking for support, please contact our mailing list, join our IRC channel #systemd on libera.chat or Matrix channel
Stable branches with backported patches are available in the stable repo.
We have a security bug bounty program sponsored by the Sovereign Tech Fund hosted on YesWeHack
Repositories with distribution packages built from git main are available on OBS, and also repositories with packages built from the latest stable release
