I recently saw a bunch of those warnings when booting Arch Linux:
$ systemctl status swapfile.swap | grep -i invalid
Jun 12 12:34:25 m604 swapon[22623]: swapon: /swapfile: swapon failed: Invalid argument
This was weird since the swapfile worked fine before and the file existed and had secure permissions:
$ stat /swapfile
File: /swapfile
Size: 8589934592 Blocks: 16777224 IO Block: 4096 regular file
Device: fe01h/65025d Inode: 16 Links: 1
Access: (0600/-rw-------) Uid: ( 0/ root) Gid: ( 0/ root)
Access: 2020-06-12 08:52:50.974137402 +0200
Modify: 2019-12-28 10:16:06.886603444 +0100
Change: 2019-12-28 10:16:06.886603444 +0100
Birth: 2016-12-28 12:24:34.180000236 +0100
journalctl
came to my rescue and showed an error message the indicated what was wrong:
$ journalctl --boot --priority 0..3 | grep holes | head -n1
Jun 13 13:10:27 m604 kernel: swapon: swapfile has holes
Never heard of files having holes before, but everyday you learn something knew.
The man pages of swapon
and mkswap
cleared things up:
$ man swapon | grep holes -A4
Files with holes
The swap file implementation in the kernel expects to be able to write to the file directly, without the assistance of the
filesystem. This is a problem on files with holes or on copy-on-write files on filesystems like Btrfs.
Commands like cp(1) or truncate(1) create files with holes. These files will be rejected by swapon.
Preallocated files created by fallocate(1) may be interpreted as files with holes too depending of the filesystem. Preal‐
located swap files are supported on XFS since Linux 4.18.
The most portable solution to create a swap file is to use dd(1) and /dev/zero.
From man mkswap
:
To set up a swap file, it is necessary to create that file before initializing it with mkswap, e.g. using a command like
# dd if=/dev/zero of=swapfile bs=1MiB count=$((8*1024))
to create 8GiB swapfile.
So, you can not use fallocate
to preallocate the space for a swap file on ext4
, at least it is not reliable.
I used this command to recreate the file:
$ sudo dd if=/dev/zero of=swapfile bs=1MiB count=$((8*1024)) status=progress && sync && sudo chmod 0600 /swapfile && sudo mkswap /swapfile