You are not logged in.
I was chasing some bug in my UKI and at some point was unsure if I had even booted the right image. The image seemed way out of date but it turned out that it was indeeed "fresh." Long story short, why is the filesystem timestamp on the UKI December 19th when inside it there is actually a Linux kernel from Dec 27th and the whole thing was created on Dec 29?
~# ls -l /boot/EFI/Linux/arch-linux.efi
-rwxr-xr-x 1 root root 40977408 Dec 19 22:36 /boot/EFI/Linux/arch-linux.efi
~# strings /boot/EFI/Linux/arch-linux.efi | grep linux@archlinux
6.12.7-arch1-1 (linux@archlinux) #1 SMP PREEMPT_DYNAMIC Fri, 27 Dec 2024 14:24:37 +0000
6.12.7-arch1-1 (linux@archlinux) (gcc (GCC) 14.2.1 20240910, GNU ld (GNU Binutils) 2.43.0) #1 SMP PREEMPT_DYNAMIC Fri, 27 Dec 2024 14:24:37 +0000
~# ls -l /boot/vmlinuz-linux
-rwxr-xr-x 1 root root 13812224 Dec 29 21:27 /boot/vmlinuz-linux
I can delete boot/EFI/Linux/arch-linux.efi, then do mkinitcpio, and it's right back there with an mtime from 10 days ago. Weird.
Offline
What are mount options for /boot?
$ mount -l | grep /boot
$ grep /boot /etc/fstab
Does mtime become correct after
# touch /boot/EFI/Linux/arch-linux.efi
?
Offline
This is interesting: stat shows the correct creation time (birth) of the file. I can change all other dates using touch, but the mkinitcpio process deliberately "backdates" the created UKI. See shell session below.
~# mount -l | grep boot
/dev/nvme0n1p1 on /boot type vfat (rw,relatime,fmask=0022,dmask=0022,codepage=437,iocharset=ascii,shortname=mixed,utf8,errors=remount-ro) [BOOT]
~# stat /boot/EFI/Linux/arch-linux.efi
File: /boot/EFI/Linux/arch-linux.efi
Size: 40977408 Blocks: 80040 IO Block: 4096 regular file
Device: 259,1 Inode: 13 Links: 1
Access: (0755/-rwxr-xr-x) Uid: ( 0/ root) Gid: ( 0/ root)
Access: 2024-12-29 01:00:00.000000000 +0100
Modify: 2024-12-19 22:36:14.000000000 +0100
Change: 2024-12-19 22:36:14.000000000 +0100
Birth: 2024-12-29 21:27:21.240000000 +0100
~# touch /boot/EFI/Linux/arch-linux.efi
~# stat /boot/EFI/Linux/arch-linux.efi
File: /boot/EFI/Linux/arch-linux.efi
Size: 40977408 Blocks: 80040 IO Block: 4096 regular file
Device: 259,1 Inode: 13 Links: 1
Access: (0755/-rwxr-xr-x) Uid: ( 0/ root) Gid: ( 0/ root)
Access: 2024-12-31 01:00:00.000000000 +0100
Modify: 2024-12-31 13:25:16.000000000 +0100
Change: 2024-12-31 13:25:16.000000000 +0100
Birth: 2024-12-29 21:27:21.240000000 +0100
~# mkinitcpio -P linux
==> Building image from preset: /etc/mkinitcpio.d/linux.preset: 'default'
[...]
==> Unified kernel image generation successful
~# stat /boot/EFI/Linux/arch-linux.efi
File: /boot/EFI/Linux/arch-linux.efi
Size: 40977408 Blocks: 80040 IO Block: 4096 regular file
Device: 259,1 Inode: 29 Links: 1
Access: (0755/-rwxr-xr-x) Uid: ( 0/ root) Gid: ( 0/ root)
Access: 2024-12-31 01:00:00.000000000 +0100
Modify: 2024-12-19 22:36:14.000000000 +0100
Change: 2024-12-19 22:36:14.000000000 +0100
Birth: 2024-12-31 13:26:02.320000000 +0100
~#
Offline
the mkinitcpio process deliberately "backdates" the created UKI.
Interesting. Mkinitcpio doesn't generate .efi by itself, it invokes ukify. Signing tool also may be involved, some additional ALPM hooks as well.
Out of curiosity I'd play with strace or bpftrace to watch processes which may do syscalls affecting modification time.
Offline
According to the Wiki, mkinitcpio and ukify are alternatives to make the UKI (I don't have systemd-ukify installed). "strace mkinitcpio" hasn't turned up anything interesting yet because most action seems to be done by subprocesses. I may lose interest in this topc before I get to the root of it...
Offline
If systemd-ukify is not installed mkinitcpio will use objcopy instead: https://gitlab.archlinux.org/archlinux/ … heads#L529
No idea about the timestamps though, that is strange
EDIT: systemd-ukify is just a Python wrapper for objcopy & sbsign.
Last edited by Head_on_a_Stick (2025-01-01 11:17:41)
Para todos todo, para nosotros nada
Offline
mkinitramfs uses objcopy with -p, and I found this in objcopy's manpage:
-p
--preserve-dates
Set the access and modification dates of the output file to
be the same as those of the input file.
This option also copies the date stored in a PE format file's
header, unless the SOURCE_DATE_EPOCH environment variable is
defined. If it is defined then this variable will be used as
the date stored in the header, interpreted as the number of
seconds since the Unix epoch.
So there's something about timestamps that is important with respect to initramfs which seems to have to do with determinism. If you do the same thing twice you want the bit-exact same output, so if you package a whole filesystem including timestamps in one file, that file will differ depending on when you did that unless you reset all timestamps inside the filesystem to the same value each time. But I wouldn't have thought that that also applies to the initramfs file itself, living in an "external" fs. I have decided to terminate my research at this point.
Offline
mkinitcpio runs objcopy with /usr/lib/systemd/boot/efi/linuxx64.efi.stub (or /usr/lib/systemd/boot/efi/linuxia32.efi.stub) as the input file. The kernel and etc. are simply added as sections.
Check the timestamps of that file instead.
Offline