{"id":2915,"date":"2023-12-18T10:32:37","date_gmt":"2023-12-18T15:32:37","guid":{"rendered":"https:\/\/www.both.org\/?p=2915"},"modified":"2024-02-23T08:15:40","modified_gmt":"2024-02-23T13:15:40","slug":"how-to-tune-the-linux-kernel-with-the-proc-filesystem","status":"publish","type":"post","link":"https:\/\/www.both.org\/?p=2915","title":{"rendered":"How to tune the Linux kernel with the \/proc filesystem"},"content":{"rendered":"<div class=\"pld-like-dislike-wrap pld-template-1\">\r\n    <div class=\"pld-like-wrap  pld-common-wrap\">\r\n    <a href=\"javascript:void(0)\" class=\"pld-like-trigger pld-like-dislike-trigger  \" title=\"\" data-post-id=\"2915\" data-trigger-type=\"like\" data-restriction=\"cookie\" data-already-liked=\"0\">\r\n                        <i class=\"fas fa-thumbs-up\"><\/i>\r\n                <\/a>\r\n    <span class=\"pld-like-count-wrap pld-count-wrap\">    <\/span>\r\n<\/div><\/div>\n<p class=\"has-small-font-size\">Image by David Both: CC-by-SA 4.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">The Linux kernel is a tunable marvel that allows you to make changes to its parameters while it is running and without requiring a reboot.<\/h2>\n\n\n\n<p>Linux is an amazing and powerful operating system. More specifically, the Linux kernel is the source of many of its superpowers. <\/p>\n\n\n\n<p>I&#8217;ve been using Linux for 25 years and have used a lot of versions of the Linux kernel. I have even compiled the kernel a time or two in class and a few times just for grins. Most users and even sysadmins never need to compile the kernel. In most distributions, the default compile is perfectly fine for most use cases. But there are times when a bit of tuning is in order. The good news is that the kernel can be tuned easily without recompiling it or even rebooting.<\/p>\n\n\n\n<p>This article is not intended to be a detailed exposure of all the kernel data available for viewing or modification. It is an homage to an incredible piece of software that allows the flexibility to make significant functional changes while it&#8217;s in use.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"what-is-the-proc-filesystem\">What is the \/proc filesystem?<\/h2>\n\n\n\n<p>The <code>\/proc<\/code> filesystem is one of the most critical components of the kernel. It is a virtual filesystem that exists only in memory. The <code>\/proc<\/code> filesystem is defined by the <a href=\"https:\/\/en.wikipedia.org\/wiki\/Filesystem_Hierarchy_Standard\" target=\"_blank\" rel=\"noreferrer noopener\">Linux Filesystem Hierarchical Standard<\/a> (FHS) as the location for Linux to store information about the system, the kernel, and all processes running on the host. It is intended to be a place for the kernel to expose information about itself to facilitate access to data about the system for programmers, developers, and sysadmins.<\/p>\n\n\n\n<p>Collecting this data does not impact the overall performance of a Linux host. The Linux kernel is designed to continuously collect and store the performance data that can be accessed and displayed by any and all performance monitoring tools. The tools access that data to read it and then manipulate and display it in a meaningful format. Because this data is already stored in the <code>\/proc<\/code> filesystem, it avoids complex and time-consuming function calls to the kernel&#8217;s internals.<\/p>\n\n\n\n<p>Some of the data in the <code>\/proc<\/code> filesystem is used to tune the kernel. The values in those files can be easily changed by simple and familiar Linux tools.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"viewing-the-data\">Viewing the data<\/h2>\n\n\n\n<p>When used as a window into the state of the operating system and its view of the system and hardware, the kernel provides easy access to virtually every bit of information you might want as a sysadmin. All the cool tools that sysadmins use to view the status of the operating system and the kernel, access that data from the <code>\/proc<\/code> filesystem.<\/p>\n\n\n\n<p>Start by viewing some of the available data. First, make <code>\/proc<\/code> the present working directory (PWD) and list the contents. Many of these are directories and others are files. I use the <a href=\"https:\/\/opensource.com\/article\/21\/5\/linux-terminal-multiplexer\" data-type=\"link\" data-id=\"https:\/\/opensource.com\/article\/21\/5\/linux-terminal-multiplexer\" target=\"_blank\" rel=\"noreferrer noopener\">Konsole terminal emulator<\/a>. The default color for directories is blue, and the files are the terminal text color, which I set to amber. Symbolic links are cyan.<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter\"><img decoding=\"async\" src=\"https:\/\/www.redhat.com\/sysadmin\/sites\/default\/files\/styles\/embed_large\/public\/2022-08\/Listing-of-proc.png?itok=WcR8WLmR\" alt=\"Listing of the \/proc filesystem\"\/><figcaption class=\"wp-element-caption\"><br>Figure 1: A listing of the \/proc directory. (David Both, CC BY-SA 4.0)<\/figcaption><\/figure>\n<\/div>\n\n\n<p><a href=\"https:\/\/www.redhat.com\/en\/engage\/system-administrator-guide-s-202107300146?intcmp=701f20000012ngPAAQ\" target=\"_blank\" rel=\"noreferrer noopener\"><\/a>All the numeric directories represent the process ID (PID) of a process and contain the data required for the kernel to manage that process. The named files\u2014as opposed to named directories\u2014contain data pertaining to the file&#8217;s name. The named directories usually contain a series of files and subdirectories related to the directory&#8217;s name.<\/p>\n\n\n\n<p>One example is the <code>stat<\/code> file. This file contains the statistical data pertaining to the system&#8217;s CPUs. You can use the <code>cat<\/code> command to view that file. Do that multiple times, or use the following command as root to watch the file as it changes:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code># watch cat \/proc\/stat<\/code><\/pre>\n\n\n\n<p>The <code>watch<\/code> command repeats the command every two seconds by default until you use <strong>Ctrl+C<\/strong> to break out. You could also specify a different interval. Read the man page for that information.<\/p>\n\n\n\n<p>Another interesting file is <code>proc\/meminfo<\/code>. Try watching that one for a few minutes. All of my favorite problem determination and monitoring tools use the contents of <code>\/proc<\/code> to obtain their data. Look at the <code>free<\/code> command, for instance:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code># free\n               total        used        free      shared  buff\/cache   available\nMem:        32726880      727108    31104776        1560      894996    31610372\nSwap:       16777208           0    16777208<\/code><\/pre>\n\n\n\n<p>This next command displays the results of the <code>free<\/code> command as well as the <code>meminfo<\/code> file at the same time. Be sure to get the single and double quotes correct. The line of <code>#<\/code> symbols provides a bit of visual separation between the outputs of the two commands and can be as long as you need it to be to provide enough of a visual clue for yourself. I shortened it here so that it all shows up on a single line.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code># watch 'free ; echo \"###########\" ; cat \/proc\/meminfo | head -20'<\/code><\/pre>\n\n\n\n<p>Interpreting the data that is output from these commands is outside the scope of this article but can be found in Section 1.14, the <a href=\"https:\/\/tldp.org\/LDP\/Linux-Filesystem-Hierarchy\/html\/proc.html\" target=\"_blank\" rel=\"noreferrer noopener\">\/proc page of the LFSH description<\/a>, on the <a href=\"https:\/\/tldp.org\/\" target=\"_blank\" rel=\"noreferrer noopener\">Linux Documentation Project<\/a> website. The <code>man 5 proc<\/code> page also has good descriptions of the contents of all of the <code>\/proc<\/code> files.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"kool-kernel-tools\">Kool kernel tools<\/h2>\n\n\n\n<p>The <code>free<\/code> command is just one of the many tools that allow you to view the status of the running kernel in real time.<\/p>\n\n\n\n<p>Others I like are <code>top<\/code>, <code>htop<\/code>, and <code>glances<\/code>, which all show a comprehensive view of the running system. Using somewhat different layouts and varying options to configure how the data is displayed, they can all show memory and swap usage; individual and total CPU usage; a list of system and user processes; and data about each process such as memory, CPU usage, total run time for the process, the PID and the parent process ID (PPID).<\/p>\n\n\n\n<p>These three tools, along with the <code>renice<\/code> command, can also renice or kill running processes. Renicing a process changes the data in the <code>\/proc\/PID\/stat<\/code> file. The data in this file are complex, and the file is not writable by editors or redirection, so it&#8217;s necessary to use the renice tools that are available.&nbsp;<\/p>\n\n\n\n<p>Other tools I use frequently are <code>lsblk<\/code>, <code>iptop<\/code>, <code>lsusb<\/code>, <code>lspci<\/code>, and other related tools that list and manage hardware.&nbsp;Any of the many tools that manage processes, memory, networking, attached hardware, and everything else use the <code>\/proc<\/code> filesystem to do so.&nbsp;<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"making-changes-to-the-running-kernel\">Making changes to the running kernel<\/h2>\n\n\n\n<p>The <code>\/proc<\/code> filesystem is also designed to provide access to modify many configuration values when necessary to allow you to tune the running system without needing to perform reboots after making changes. This is an incredibly powerful tool.<\/p>\n\n\n\n<p>One of the first things I need to tune on the Linux host I use for a router is to enable it to be a router. This is accomplished by setting the contents of the file <code>\/proc\/sys\/net\/ipv4\/ip_forward<\/code> to <code>1<\/code>. There are multiple methods for making changes to the kernel-tuning variables, and all of them simply change the value present in the <code>\/proc<\/code> filesystem. The first two methods are only temporary and must be performed after every reboot.<\/p>\n\n\n\n<p>First, I can use the command:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code># echo 1 &gt; \/proc\/sys\/net\/ipv4\/ip_forward<\/code><\/pre>\n\n\n\n<p>The <code>sysctl<\/code> command does exactly the same thing: it sets the value of that file to 1:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>#  sysctl -w net.ipv4.ip_forward = 1<\/code><\/pre>\n\n\n\n<p>You can check the value of any file:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code># sysctl net.ipv4.ip_forward\nnet.ipv4.ip_forward = 1<\/code><\/pre>\n\n\n\n<p>or:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code># cat sysctl net.ipv4.ip_forward\nnet.ipv4.ip_forward = 1<\/code><\/pre>\n\n\n\n<p>But all of these changes are only transient, and they reset to their default values at each boot.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"making-the-changes-permanent\">Making the changes permanent<\/h2>\n\n\n\n<p>Making these changes permanent is quite easy. Just add the following lines to the <code>\/etc\/sysctl.conf<\/code> file or to a new file in <code>\/etc\/sysctl.d<\/code>. These files are read and used to set kernel parameters at boot time. You can see some of the other kernel options I have set to meet my needs in this file:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>################################################################################\n#                            Local-sysctl.conf                                 #\n#                                                                              #\n# Local kernel option settings.                                                #\n# Install this file in the \/etc\/sysctl.d directory.                            #\n#                                                                              #\n# Use the command: sysctl -p \/etc\/sysctl.d\/local-sysctl.conf to activate.      #\n#                                                                              #\n################################################################################\n################################################################################\n# Local Network settings - Specifically to disable IPV6                        #\n################################################################################\nnet.ipv6.conf.all.disable_ipv6 = 1\nnet.ipv6.conf.default.disable_ipv6 = 1\n################################################################################\n# And to make this a router                                                    #\n################################################################################\nnet.ipv4.ip_forward = 1\n################################################################################\n# Virtual Memory Swappiness                                                    #     \n################################################################################\n# Set swappiness\nvm.swappiness = 13<\/code><\/pre>\n\n\n\n<p>For more details about performing these tasks, see my Opensource.com article, <a href=\"https:\/\/www.both.org\/?p=4192\" data-type=\"link\" data-id=\"https:\/\/www.both.org\/?p=4192\" target=\"_blank\" rel=\"noreferrer noopener\">How I disabled IPv6 on Linux<\/a>.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"final-thoughts\">Final thoughts<\/h2>\n\n\n\n<p>The <code>\/proc<\/code> filesystem is the &#8220;single point of truth&#8221; (SPOT) for obtaining information about the running system and changing the kernel-tuning variables. I use it frequently, either directly or indirectly, using the common GNU utilities and other tools already provided in every Linux distribution.<\/p>\n\n\n\n<p>The ability to tune the Linux kernel while it is running is one of the most powerful aspects of using Linux. It enables making changes to the kernel parameters while it is running and without requiring a reboot.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"resources\">Resources<\/h2>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Section 1.14, the <a href=\"https:\/\/tldp.org\/LDP\/Linux-Filesystem-Hierarchy\/html\/proc.html\" target=\"_blank\" rel=\"noreferrer noopener\">\/proc page of the LFSH description<\/a>, at the <a href=\"https:\/\/tldp.org\/\" target=\"_blank\" rel=\"noreferrer noopener\">Linux Documentation Project<\/a> website.<\/li>\n\n\n\n<li>The <code>man 5 proc<\/code> page also has good descriptions of the contents of all of the <code>\/proc<\/code> files.<\/li>\n\n\n\n<li><a href=\"https:\/\/kernel.org\/\" target=\"_blank\" rel=\"noreferrer noopener\">Kernel.org<\/a> has a long list of kernel parameters and a huge amount of other information about the Linux kernel.<\/li>\n<\/ul>\n","protected":false},"excerpt":{"rendered":"<p>Image by David Both: CC-by-SA 4. The Linux kernel is a tunable marvel that allows you to make changes to its parameters while it is running and without requiring a reboot. Linux is an amazing and powerful operating system. More specifically, the Linux kernel is the source of many of its superpowers. I&rsquo;ve been using [&hellip;]<\/p>\n","protected":false},"author":2,"featured_media":2929,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_lmt_disableupdate":"","_lmt_disable":"","footnotes":""},"categories":[5],"tags":[126,125],"class_list":["post-2915","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-linux","tag-proc","tag-kernel"],"modified_by":"David Both","_links":{"self":[{"href":"https:\/\/www.both.org\/index.php?rest_route=\/wp\/v2\/posts\/2915","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.both.org\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.both.org\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.both.org\/index.php?rest_route=\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/www.both.org\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=2915"}],"version-history":[{"count":17,"href":"https:\/\/www.both.org\/index.php?rest_route=\/wp\/v2\/posts\/2915\/revisions"}],"predecessor-version":[{"id":4201,"href":"https:\/\/www.both.org\/index.php?rest_route=\/wp\/v2\/posts\/2915\/revisions\/4201"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.both.org\/index.php?rest_route=\/wp\/v2\/media\/2929"}],"wp:attachment":[{"href":"https:\/\/www.both.org\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=2915"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.both.org\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=2915"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.both.org\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=2915"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}