Loading
nixos/systemd-boot: atomically update copied destination files
We absolutely do not want to leave an incomplete file behind in /boot since an incomplete initrd would render the machine unbootable. Errors while writing are relatively common, mostly due to full /boot partitions. systemd-boot-builder does never attempt to re-write already existing files which means that such situations are not fixable by re-running nixos-rebuild etc. Instead the user needs to know about internals of the systemd-boot and manually delete the correct file to recover from a partially written kernel or (more commonly) initrd in /boot. Note that this used to be a non issue since systemd-boot-builder used to always delete all kernels and initrds before copying kernels and initrds, so dest.exist() would always return False. This was fixed in f2ca9905, revealing the underlying bad assumption (that copyfile() always succeeds or fails without writing anything). The solution is to write to a temporary file first and move it to the destination path only after this has succeeded. This way, if an error occurs during copying, only a file distinct from dest is left behind which would be cleaned up by subsequent runs of remove_old_entries(). Resolves #444066.