How to read and change the value of kernel parameters using sysctl

Sysctl is a utility installed by default in all modern Linux distributions. It is used both to read and write the value of kernel parameters at runtime; the available parameters are those listed under the /proc pseudo-filesystem, and specifically under the /proc/sys directory. In this article we learn how to use this utility, how to make changes persist a reboot, and how to load settings from a file “manually”.

In this tutorial you will learn:

  • How to read the value of kernel parameters
  • How to modify the value of kernel parameters at runtime
  • How to make changes persist a reboot
  • How to load settings from a file manually

How to read and change the value of kernel parameters using sysctl

How to read and change the value of kernel parameters using sysctl

Software requirements and conventions used

Software Requirements and Linux Command Line Conventions
Category Requirements, Conventions or Software Version Used
System Distribution independent
Software sysctl
Other Root privileges to modify kernel parameters
Conventions # – requires given linux-commands to be executed with root privileges either directly as a root user or by use of sudo command
$ – requires given linux-commands to be executed as a regular non-privileged user

Reading kernel values

The behavior of the Linux kernel can be changed by modifying the value of some parameters, even at runtime. The available parameters are those which can be accessed via the /proc pseudo-filesystem, under the /proc/sys directory. We can use the tree command to get an idea of its content:

$ tree /proc/sys
/proc/sys
├── abi
│   └── vsyscall32
├── crypto
│   └── fips_enabled
├── debug
│   ├── exception-trace
│   └── kprobes-optimization
├── dev
│   ├── cdrom
│   │   ├── autoclose
│   │   ├── autoeject
│   │   ├── check_media
│   │   ├── debug
│   │   ├── info
│   │   └── lock
│   ├── hpet
│   │   └── max-user-freq
│   ├── i915
│   │   ├── oa_max_sample_rate
│   │   └── perf_stream_paranoid
│   ├── mac_hid
│   │   ├── mouse_button2_keycode
│   │   ├── mouse_button3_keycode
│   │   └── mouse_button_emulation
│   ├── raid
│   │   ├── speed_limit_max
│   │   └── speed_limit_min
│   ├── scsi
│   │   └── logging_level
│   └── tty
│       └── ldisc_autoload
[...]


The output of the command above is truncated for obvious reasons, but it gives an idea of what we are talking about. When sysctl is invoked with the -a option, (short for --all), it prints the value of all the available kernel parameters:

$ sysctl
sysctl -a
abi.vsyscall32 = 1
crypto.fips_enabled = 0
debug.exception-trace = 1
debug.kprobes-optimization = 1
dev.cdrom.autoclose = 1
dev.cdrom.autoeject = 0
dev.cdrom.check_media = 0
[...]

If we want to read the value of a specific parameter, all we have to do is to invoke sysctl and provide the name of the parameter of which we want to check the value as argument. For example, to read the current value of the raid speed_limit_max parameter, which is written in the /proc/sys/dev/raid/speed_limit_max file, we would run:

$ sysctl dev.raid.speed_limit_max
dev.raid.speed_limit_max = 200000

When using sysctl in a script, or when using its output in a pipeline, we may want to run it with the -n option, which is the short form of (--values). This option makes only the current value of a requested parameter to be
returned when a query is performed; the key name is omitted:

$ sysctl -n dev.raid.speed_limit_max
200000

Modifying kernel parameters

Just as we can read kernel parameters, we can change their values at runtime using sysctl. The syntax to use when we want to perform such an action, is very simple:

sysctl variable=value

We simply invoke the command and provide the variable name and the value we want to assign to it. While we don’t need elevated privileges to read the value of kernel parameters, we need to prefix the command with sudo (or run it as the root user directly) to change their values. Just as an example, suppose we want to change the value of dev.cdrom.autoeject and set it to 1; we would write:

$ sudo sysctl dev.cdrom.autoeject=1

When we change the value of a kernel parameter, if the command is executed correctly, the value set is displayed to stdout (standard output). As output of the command used in the example above, we would see:

dev.cdrom.autoeject = 1


Such behavior can be changed by invoking sysctl with the -q option (short for --quiet).

Making changes persist a reboot

The modification we make with sysctl at runtime are not persistent, and will be lost when we reboot the system. To make changes survive such event we need to write them in a file in one of the dedicated directories. What are those
directories? In order of priority:

  • /etc/sysctl.d
  • /run/sysctl.d
  • /usr/lib/sysctl.d

The files hosting the settings must have the .conf extension and are sorted and loaded at boot by the systemd-sysctl service, in lexicographic order, no matter the directory they are placed in.

If a file with the same name exists in multiple directories, only the settings existing in the one placed in the directory with the higher priority will be loaded. This basically means that if we want to override a file completely, we should place a file with the same name in a directory with a higher priority; if we want to change a specific setting, instead, we could choose to write it in a file with a name that will cause it to be loaded after the one where the parameter it is originally set in.



The /usr/lib/sysctl.d directory is meant to host “vendor” settings, we should seldom change its content. In the vast majority of cases we want to place our files inside the /etc/sysctl.d directory, which is reserved for changes made
by the system administrator.

Let’s see an example. Suppose we want to change the kernel swappiness value. As we know, the value of this parameter determines how often the Linux kernel copies the RAM content to the swap space. The range of values which can be assigned to this parameter goes to 0 to 100: an higher value means a more frequent and aggressive swap use. To change the value of this parameter permanently, we create the /etc/sysctl.d/99-swappiness.conf file; inside of it we write:

vm.swappiness = 1

Since, as we said, files are loaded in lexicographic order, due to its name, we can be sure the file will be loaded quite lately, and so the setting will be applied as expected.

Load settings from a file manually

Since here we saw how to change the value of kernel parameters at runtime, and how to make changes persist a reboot by writing them in files with the .conf extension. What if we want to load settings written inside a file “manually”, without the need to reboot the system and without reloading the systemd-sysctl service? All we have to do is to invoke sysctl with the -p option (--load) and pass the path of the file hosting the settings as argument. Just as an example, suppose we want to load the content of the /etc/sysctl.d/99-swappiness.conf file we created in the previous example; we would run:

$ sudo sysctl -p /etc/sysctl.d/99-swappiness.conf

If sysctl is invoked with the -p option, but no arguments are provided, it loads settings from the /etc/sysctl.conf file (a symlink which points to this file, named 99-sysctl.conf exists in the /etc/sysctl.d directory).

Conclusions

In this article we learned how to use the sysctl utility to read and change the value of some kernel parameters at runtime. We also saw how to make changes to this parameters persist a reboot, by writing them in files with the .conf extension, which should placed in specific directories, and how to load settings written in a file “manually”. By changing the value of kernel parameters we can tweak our system and make it work exactly as we need. We can, for example, as we saw in a previous tutorial, enable all or some of the SysRq functions.



Comments and Discussions
Linux Forum