Is sysctl.conf last match?

I don’t think there is any such official documentation. sysctl entries are handled by procps and systemd; but neither projects’ documentation address how entries are processed within the same configuration file.

The short version is that the last entry in sysctl.conf wins, even when other files are present (in /etc/sysctl.d or elsewhere), regardless of which system is used to load the settings.

procps

To understand how procps processes entries, we need to look at the source code for sysctl. This shows that later entries are processed without knowledge of earlier entries, so the last one wins (look at the Preload function). When multiple configuration files are given on the command line, these are processed in order, as described in the man page:

Using this option will mean arguments to sysctl are files, which are read in the order they are specified.

Things get a little more complex with the --system option, but at least that’s documented:

Load settings from all system configuration files. Files are read from directories in the following list in given order from top to bottom. Once a file of a given filename is loaded, any file of the same name in subsequent directories is ignored.

  • /run/sysctl.d/*.conf
  • /etc/sysctl.d/*.conf
  • /usr/local/lib/sysctl.d/*.conf
  • /usr/lib/sysctl.d/*.conf
  • /lib/sysctl.d/*.conf
  • /etc/sysctl.conf

The documentation isn’t quite complete. As mentioned above, entries within a given file are applied in order, and overwrite any value given to the same setting previously. In addition, looking at the PreloadSystem function show that files are processed in name order, and that /etc/sysctl.conf is processed unconditionnally (i.e. an identically-named file in an earlier directory doesn’t override it).

systemd

systemd has its own sysctl handler, which is documented in the sysctl.d manpage; that has a section on precedence:

Configuration files are read from directories in /etc/, /run/, and /usr/lib/, in order of precedence. Each configuration file in these configuration directories shall be named in the style of filename.conf. Files in /etc/ override files with the same name in /run/ and /usr/lib/. Files in /run/ override files with the same name in /usr/lib/.

[…] All configuration files are sorted by their filename in lexicographic order, regardless of which of the directories they reside in. If multiple files specify the same option, the entry in the file with the lexicographically latest name will take precedence. It is recommended to prefix all filenames with a two-digit number and a dash, to simplify the ordering of the files.

Again, later entries within a single configuration file override earlier entries.


Doing this assertion in a more practical way:

First things first: Values will not be applied if you prefix the sysctl word on your sysctl.conf entries("manpages are lol" as you said but you didn't seem to have seriously read them). And, it's an easy task to test this: Put the following content at the end of your /etc/sysctl.conf

vm.swappiness = 60
vm.swappiness = 61

I'm using swappines here cause i know that it's a low impact sysctl to mess arround with little difference values depending on your system load (and the default value is 60 on most distros). Apply only this file by typing sysctl -p /etc/sysctl.conf(manpage). Double-check the value with sysctl -a

root@host:~# sysctl -a | grep "vm.swappiness"
vm.swappiness = 61

Voilá.

Now that you know files are read on a top-down approach, it's just a matter of reading sysctl.d manpage to figure out what is the precedence on spread sysctl files across you system. As it's already explained by @Stephen Kitt answer, i'll not repeat this info here.

Also, this sysctl.d directories precedence will depend if the distro you are using is systemd-based or not...

Tags:

Sysctl