parse_sysctl.pl #2

  • //
  • p4-sdp/
  • r26.1.0/
  • Server/
  • Unix/
  • setup/
  • parse_sysctl.pl
  • View
  • Commits
  • Open Download .zip Download (8 KB)
#!/usr/bin/perl

use strict;
use warnings;

# Author: [email protected]
# Date: Jan 9, 2026

# After several years of successful implementation my plan is to render this 
# ready for prime-time usage by cleaning up and fully documenting the settings 
# with an internal KB that will one day be presentable to a wider audience; for
# now this will be useful for support engineers for cases where the server loads
# don't appear to be utilizing all Linux OS hardware, networking resources in
# particular.
#
# Usage: ./parse_sysctl.pl {-a} {/path to/}sysctl.out
#
#     -a: 
#
#     Check rarely tweaked kernel settings.
#
#     {/path to/}sysctl.out:
#
#     The 'sysctl -a' output file to parse.
#
# Or change this sysctl_file value to a file containing "sysctl -a" output:

my $sysctl_file = "sysctl.out";

# List of recommended kernel values:
my $rec_k_vals = <<KERNEL_VALS;
	net.ipv4.tcp_syncookies					: 0
	net.ipv4.tcp_timestamps					: 1
	net.ipv4.tcp_window_scaling				: 1
	net.core.somaxconn						: 4096
	net.core.netdev_max_backlog				: 5000
	net.ipv4.tcp_max_syn_backlog			: 4096
	net.ipv4.ip_local_port_range			: 10000 65535
	net.ipv4.tcp_fin_timeout				: 30
	net.ipv4.tcp_keepalive_intvl			: 30
	net.ipv4.tcp_keepalive_probes			: 20
	net.ipv4.tcp_keepalive_time				: 890
	net.core.netdev_budget					: 600
	net.core.rmem_max						: 16777216
	net.core.wmem_max						: 16777216
	net.core.optmem_max						: 16777216
	net.ipv4.tcp_mem						: 1528512 2038016 8388608
	net.ipv4.tcp_rmem						: 4096 87380 16777216
	net.ipv4.tcp_wmem						: 4096 65536 16777216
	net.ipv4.tcp_no_metrics_save			: 1
	net.ipv4.tcp_sack						: 0
	net.ipv4.conf.all.accept_redirects		: 0
	net.ipv4.conf.all.rp_filter				: 1
	net.ipv4.conf.all.secure_redirects		: 0
	net.ipv4.conf.all.send_redirects		: 0
	net.ipv4.conf.all.accept_source_route	: 0
	net.ipv4.icmp_echo_ignore_broadcasts	: 1
	net.ipv4.ip_forward						: 0
	vm.swappiness							: 10
	sunrpc.tcp_max_slot_table_entries		: 128
	sunrpc.tcp_slot_table_entries			: 128
KERNEL_VALS

my $rare_k_vals = <<KERNEL_VALS;
	kernel.nmi_watchdog						: 0
	kernel.soft_watchdog					: 1
	kernel.watchdog_thresh					: 180
	kernel.softlockup_all_cpu_backtrace		: 1
	kernel.hardlockup_all_cpu_backtrace		: 0
	kernel.sysrq							: 0
	kernel.core_uses_pid					: 1
	kernel.msgmnb							: 65536
	kernel.msgmax							: 65536
	kernel.shmmax							: 68719476736
	kernel.shmall							: 4294967296
KERNEL_VALS

# OS command to change/write values:
my $sysctl_cmd = "sysctl -w";

# List of recommended Perforce server configurables:
my %p4d_vals = qw(
	net.tcpsize 524288
	net.backlog 2048
	filesys.bufsize 512K
	net.bufsize 512K
	lbr.bufsize 512K
);

# Perforce command to change/write values:
my $p4_cmd = "p4 configure set";

# Those are the text sections that allow the Perforce VCS admin to adapt this  
# script to their particular needs:
my $txt_1 = <<PREAMBLE_TEXT;

Some key performance related kernel settings are at the defaults, which means that some of your server resources are likely under utilized. Here is a list of the settings that, based on past experience, improve server performance, in some cases dramatically:

	Setting		New Value	(Old Value)
	---------------------------------------
PREAMBLE_TEXT

my $txt_2 = <<CHG_KERNEL_HEADER;

To change those settings, run those commands as a privileged user:

CHG_KERNEL_HEADER

my $txt_3 = <<UPDATESYSCTL_TEXT;

Note: Always make a copy of your sysctl.conf file prior to making any changes, whether by editing the file directly or using the sysctl command:
 
	sudo mv /etc/sysctl.conf /etc/sysctl.conf.BAK

Once you've backed up this file and determined that there are no issues with the new settings, make those changes to the same values listed in that file.

To test the new sysctl.conf file, use the command:

	sudo sysctl -p

This will re-load all kernel settings directly from sysctl.conf file. 

Important note: If things appear "broken" after this point, *do not reboot*; Make a copy of the edited sysctl.conf file and replace it from the backup you created earlier, and reload the file using the same command.

UPDATESYSCTL_TEXT

my $txt_4 = <<CHG_P4_HEADER;

Next, run those commands against your Perforce server:

CHG_P4_HEADER

my $txt_5 = <<P4_RESTART;
	p4 admin restart
P4_RESTART

my $txt_6 = <<CLOSING_TEXT;

The last command is needed for the new values to take effect for the Perforce server as several of those configurables are not dynamically change upon setting.

CLOSING_TEXT

my $usage_txt = <<USAGE; 
Usage: 
	./parse_sysctl.pl {-a} {/path to/}sysctl.out

Arguments:
    -a: 

      Check rarely tweaked kernel settings.

    -h/-?
    
      This message.

    {/path to/}sysctl.out:

      The 'sysctl -a' output file to parse.

Note:
	If no file argument is given the script looks for "$sysctl_file" by default.
	Modify the sysctl_file variable in the script to change this.

For more information, see:

	Using parse_sysctl.pl Script To Diagnose Linux Performance Issues
	https://perforce.my.salesforce.com/kA02I000000bn4u
	
USAGE

## End user settings.

# Check for -a option:
if (defined $ARGV[0] && $ARGV[0] eq "-a") { 
	shift; 
	$rec_k_vals .= $rare_k_vals;
} elsif (defined $ARGV[0] && $ARGV[0] =~ m/^-(h|\?)$/) {
	shift; 
	print $usage_txt;
	exit(0);
}

# Check for file argument:
if ($ARGV[0]){ $sysctl_file = $ARGV[0]; }

my %k_vals;
my $q = "";
my $a = 0;
my @l = ("aa" .. "zz");

# I wanted to keep kernel settings groups as they are to keep related settings
# grouped together. After considerable mucking about it was clear that sorting 
# a hash based on order of entry was not possible without adding an index. 
#
# Which was promptly sorted in that annoying "1,11,12,2,3..." pattern. I REALLY
# just wanted to sort it in order, so I created an array of labels from aa through zz,
# Which covers 676 possible entries. Likely overkill. :-) However, if it's not enough I
# can always add a letter. :P
#
# Just know I won't be the one populating that many kernel tweaks. ;-)
#
# The upshot is I can preserve the original order by sorting the hash keys, instead 
# of iterating through arrays and messing with hash slices. W00t!
#
# I parse the text block to create a hash to track kernel settings:
while ($rec_k_vals =~ m/.+?(.+?)\s*\:\s*(.+)\s*?\n/g) {
	$k_vals{$l[$a]} = {'name' => $1, 'old_val' => "none", 'new_val' => $2};
	$a++;
}

# Parse the sysctl output file to determine if there are any values that need to
# be changed or added:
open (SYSCTL, "< " . $sysctl_file) 
	or die $usage_txt . "ERROR: Can't read file " . $sysctl_file .":\n" . $!;
while (<SYSCTL>) {
	chomp;
	s/\r$//; # strip a trailing carriage return left behind by Windows-style line endings
	foreach my $val (keys %k_vals) {
		if (/^.*?\Q$k_vals{$val}{'name'}\E\s+?=\s+?(.*)$/) { 
			$k_vals{$val}{'old_val'} = $1; 
		}
	}
}
close SYSCTL;

## Create the pretty table with comparison values
print $txt_1;

foreach my $val (sort keys %k_vals) {
	$k_vals{$val}{'old_val'} =~ s/\t/\x20/g; # normalize tabs to spaces
	next if $k_vals{$val}{'old_val'} eq "none"; # setting wasn't found in the sysctl output
	next if $k_vals{$val}{'old_val'} eq $k_vals{$val}{'new_val'}; # already at the recommended value
	print "\t" . $k_vals{$val}{'name'} . "\t\t" . 
	$k_vals{$val}{'new_val'} . "\t" . "(" . $k_vals{$val}{'old_val'} . ")\n";
}

## Create the ready to paste OS commands to change those settings:
print $txt_2;

foreach my $val (sort keys %k_vals) {
	next if $k_vals{$val}{'old_val'} eq "none"; # setting wasn't found in the sysctl output
	next if $k_vals{$val}{'old_val'} eq $k_vals{$val}{'new_val'}; # already at the recommended value
	$q = ($k_vals{$val}{'new_val'} =~ m/\s/) ? "\"" : "";
	print "\t" . $sysctl_cmd . " " . $k_vals{$val}{'name'} . "=" . $q . 
	$k_vals{$val}{'new_val'} . $q . "\n";
}

print $txt_3;
print $txt_4;

## Create the ready to paste Perforce server commands:
foreach my $val (keys %p4d_vals) {
	print "\t" . $p4_cmd . " " . $val . "=" . $p4d_vals{$val} . "\n";
}

## Print "p4 admin restart" command:
print $txt_5;

## Closing text.
print $txt_6;

# WARNING: While this detects differences in values, the original values might
# already have been tweaked! Remember to remove those lines that are already
# at good values, taking care to remove the associated "sysctl -w" entry.
# Change User Description Committed
#2 33716 Claude (AI Agent by Anthropic) Merge Down from main: bring r26.1.0 up to date with main's accumulated content before the SDP-1399 EBF (SDP-1397 fix, doc-only fixes, deprecated_files.txt additions, new SysConfig.adoc guide, parse_sysctl.pl improvements).
See SessionLog-2026-09-10.md for the full accounting of what this includes and why it's safe to ship.
#1 33565 Claude (AI Agent by Anthropic) Initial population of r26.1.0 from main.
//p4-sdp/main/Server/Unix/setup/parse_sysctl.pl
#1 33433 Claude (AI Agent by Anthropic) Copy Up from //p4-sdp/dev into //p4-sdp/main.

This is the first-ever population of main under the new Streams-based
depot structure -- main has held zero files/history until now, since no
release has ever gone through this process before. 463 files, covering
the entire 2026.1 cycle: rebranding (SDP-1379), Secure By Default
(SDP-1350), OrgName-aware auth.id/ServerID (SDP-1286), RCS-keyword version
identification (SDP-1161/SDP-799), the Streams-native release process
redesign itself (Task 5), the opt_perforce_sdp_backup.sh false-error fix,
the P4D 2026.1 test-suite targeting, refreshed P4*.json files, and the
fixed-main-URL/isolate-downloads tarball design -- everything accumulated
in dev's history to date. Isolated paths (ai_dev_support/, Version,
doc/*.html, doc/*.pdf, doc/gen/*.man.txt, doc/gen/sdp_install.cfg,
Unsupported/doc/*.html, Unsupported/doc/*.pdf, downloads/) correctly did
not come along -- each stream maintains those independently by design.

Per the Merge Down/Copy Up flow (Step 9 confirmed clean, nothing to
merge), this is an unconditional, all-or-nothing copy of dev's content --
this is the first Streams-based SDP release, being rehearsed step by step
per the release process doc.

Agent: Claude Code, Model: Claude Sonnet 5 (claude-sonnet-5), operating as bot_Claude_Anthropic.
//p4-sdp/dev/Server/Unix/setup/parse_sysctl.pl
#2 33409 Claude (AI Agent by Anthropic) Copy Up from //p4-sdp/dev_rebrand into //p4-sdp/dev.

This is the first promotion of dev_rebrand's work into dev since
dev_rebrand was created (2025-05-24) -- 303 files, covering the entire
2026.1 rebranding effort (SDP-1379), the Secure By Default adaptation
(SDP-1350), OrgName-aware auth.id/ServerID (SDP-1286), RCS-keyword
version identification (SDP-1161/SDP-799), and the Streams-native release
process redesign (Task 5) done this session, plus everything else
accumulated in dev_rebrand's history before this session.

Per the Merge Down/Copy Up flow, this is intentionally a full,
unconditional blast-replace of dev's content from dev_rebrand -- all
selectivity/care happened in the preceding Merge Down (dev -> dev_rebrand,
changes 33407-33408), which absorbed Robert Cowham's independent dev-side
work first so nothing of his is lost by this Copy Up.

Two files are worth calling out since they might look alarming in
isolation:
- tools/mdcu.sh is deleted -- intentional, retired this session in favor
  of the two direct Streams commands now documented in
  doc/ReleaseProcessOverview.md.
- tools/ReleaseProcessOverview.md is deleted -- this is a stale relic of
  a file move dev_rebrand made back in 2025-05-24 (tools/ -> doc/) that
  was never previously propagated to dev; the current, fully-rewritten
  doc/ReleaseProcessOverview.md is added/updated correctly by this same
  changelist.
#1 31397 C. Thomas Tyler Populate -b SDP_Classic_to_Streams -s //guest/perforce_software/sdp/...@31368.
//guest/perforce_software/sdp/dev/Server/Unix/setup/parse_sysctl.pl
#1 27079 C. Thomas Tyler Add Support utility to simplify adopting sysctl best practices.

To Do: Add guidance on when this should be run, e.g.
"These settings should work on hardware with 16G+ RAM" or
something to that effect. Or add logic in the script to
smartly decide which settings to apply based on RAM.

#review @jhalbig @michael_shields @jason_gibson