#!/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 |
||