From 9bb8d54607d536ad7aba6e6a5e554154542269d6 Mon Sep 17 00:00:00 2001 From: zersh Date: Sat, 25 Jan 2025 23:55:19 +0300 Subject: [PATCH] Update softnet.sh In newer versions of bash (>5.1), you might encounter the error: line 37: printf: 0x00000000 00000000 00000000: invalid hex number I have added error handling. I also implemented a check to determine if the server is an LXC container. If it is, then only the allocated (cgroup) CPUs are displayed. --- how-to-receive-a-packet/softnet.sh | 111 ++++++++++++++++++++++++++--- 1 file changed, 100 insertions(+), 11 deletions(-) diff --git a/how-to-receive-a-packet/softnet.sh b/how-to-receive-a-packet/softnet.sh index be26381..09301f9 100755 --- a/how-to-receive-a-packet/softnet.sh +++ b/how-to-receive-a-packet/softnet.sh @@ -24,28 +24,117 @@ Output column definitions: collision # of times that two cpus collided trying to get the device queue lock. EOI - exit 1 + exit 1 } - +if [ "$1" = "-h" ]; then + usage +fi softnet_stats_header() { - printf "%3s %10s %10s %10s %10s %10s %10s\n" cpu total dropped squeezed collision rps flow_limit + printf "%3s %10s %10s %10s %10s %10s %10s\n" cpu total dropped squeezed collision rps flow_limit } softnet_stats_format() { - printf "%3u %10lu %10lu %10lu %10lu %10lu %10lu\n" "$1" "0x$2" "0x$3" "0x$4" "0x$5" "0x$6" "0x$7" + local cpu=$1 + local total_hex=$2 + local dropped_hex=$3 + local squeezed_hex=$4 + local collision_hex=$5 + local rps_hex=$6 + local flow_limit_hex=${7:-0} + + local total_dec=$((16#$total_hex)) + local dropped_dec=$((16#$dropped_hex)) + local squeezed_dec=$((16#$squeezed_hex)) + local collision_dec=$((16#$collision_hex)) + local rps_dec=$((16#$rps_hex)) + local flow_limit_dec=$((16#$flow_limit_hex)) + + printf "%3u %10lu %10lu %10lu %10lu %10lu %10lu\n" "$cpu" "$total_dec" "$dropped_dec" "$squeezed_dec" "$collision_dec" "$rps_dec" "$flow_limit_dec" +} + +is_lxc_container() { + if systemd-detect-virt -c | grep -qi "lxc"; then + return 0 + fi + return 1 } +parse_cpu_ranges() { + local IFS=',' + local range cpu_ranges=$1 + local cpus=() + + for range in $cpu_ranges; do + if [[ $range =~ - ]]; then + IFS='-' read start end <<< "$range" + for ((i=start; i<=end; i++)); do + cpus+=($i) + done + else + cpus+=($range) + fi + done + echo "${cpus[@]}" +} -getopts h flag && usage +get_lxc_cpus() { + local cpus + if [ -f "/sys/fs/cgroup/cpuset/lxc/cpuset.cpus" ]; then + cpus=$(cat "/sys/fs/cgroup/cpuset/lxc/cpuset.cpus") + elif [ -f "/sys/fs/cgroup/cpuset/cpuset.cpus" ]; then + cpus=$(cat "/sys/fs/cgroup/cpuset/cpuset.cpus") + else + echo "Unable to determine allocated CPUs for LXC" + exit 1 + fi + parse_cpu_ranges "$cpus" +} + +process_softnet_line() { + local line=$1 + local cpu_index=$2 + + set -- $line + local total=$1 + local dropped=$2 + local squeezed=$3 + local j1=$4 + local j2=$5 + local j3=$6 + local j4=$7 + local j5=$8 + local collision=$9 + local rps=${10} + local flow_limit_count=${11:-0} + + softnet_stats_format "$cpu_index" "$total" "$dropped" "$squeezed" "$collision" "$rps" "$flow_limit_count" +} cpu=0 +# for normal header +if is_lxc_container; then + echo "Running inside LXC container." + cpus=($(get_lxc_cpus)) # Получаем массив CPU + echo "CPUs allocated to this container: ${cpus[@]}" +fi softnet_stats_header -while read total dropped squeezed j1 j2 j3 j4 j5 collision rps flow_limit_count -do - # the last field does not appear on older kernels - # https://github.com/torvalds/linux/commit/99bbc70741903c063b3ccad90a3e06fc55df9245#diff-5dd540e75b320a50866267e9c52b3289R165 - softnet_stats_format $((cpu++)) "$total" "$dropped" "$squeezed" "$collision" "$rps" "${flow_limit_count:-0}" -done < /proc/net/softnet_stat +if is_lxc_container; then + cpus=($(get_lxc_cpus)) # Получаем массив CPU + while read line + do + if [[ " ${cpus[*]} " =~ " $cpu " ]]; then + process_softnet_line "$line" "$cpu" + fi + ((cpu++)) + done < /proc/net/softnet_stat +else +# echo "Not running inside LXC container." + while read line + do + process_softnet_line "$line" "$cpu" + ((cpu++)) + done < /proc/net/softnet_stat +fi