Last active
October 4, 2025 19:05
-
-
Save davidlohr/aaf6abcd44c304c35b848e13c208ab83 to your computer and use it in GitHub Desktop.
A script to offline a certain percentage of memory from a specific NUMA node.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #!/bin/bash | |
| # A script to offline a certain percentage of memory from a specific NUMA node. | |
| # --- Input Validation --- | |
| if [ "$EUID" -ne 0 ]; then | |
| echo "Please run as root." | |
| exit 1 | |
| fi | |
| if [ "$#" -ne 2 ]; then | |
| echo "Usage: $0 <node_id> <percentage>" | |
| exit 1 | |
| fi | |
| NODE_ID=$1 | |
| PERCENTAGE=$2 | |
| NODE_PATH="/sys/devices/system/node/node${NODE_ID}" | |
| if ! [ -d "${NODE_PATH}" ]; then | |
| echo "Error: Node ${NODE_ID} does not exist." | |
| exit 1 | |
| fi | |
| # --- Calculation (Corrected) --- | |
| # The value is the 4th field in the file, not the 2nd. This is the fix. | |
| MEM_TOTAL_KB=$(grep MemTotal "${NODE_PATH}/meminfo" | awk '{print $4}') | |
| if [ -z "${MEM_TOTAL_KB}" ] || [ "${MEM_TOTAL_KB}" -eq 0 ]; then | |
| echo "Error: Could not parse MemTotal from ${NODE_PATH}/meminfo." | |
| exit 1 | |
| fi | |
| # --- End of Fix --- | |
| BLOCK_SIZE_B=$(cat /sys/devices/system/memory/block_size_bytes) | |
| BLOCK_SIZE_KB=$((BLOCK_SIZE_B / 1024)) | |
| TARGET_OFFLINE_KB=$((MEM_TOTAL_KB * PERCENTAGE / 100)) | |
| offlined_kb=0 | |
| echo "Target Node: ${NODE_ID}" | |
| echo "Total Memory on Node: ${MEM_TOTAL_KB} KB" | |
| echo "Target to Offline: ${TARGET_OFFLINE_KB} KB (${PERCENTAGE}%)" | |
| echo "-------------------------------------" | |
| # --- Offlining Logic --- | |
| for mem_dir in $(ls -d ${NODE_PATH}/memory* 2>/dev/null); do | |
| mem_block_id=$(basename "${mem_dir}") | |
| state_file="/sys/devices/system/memory/${mem_block_id}/state" | |
| if [ "${offlined_kb}" -ge "${TARGET_OFFLINE_KB}" ]; then break; fi | |
| if [ "$(cat "${state_file}")" == "offline" ]; then continue; fi | |
| echo -n "Attempting to offline ${mem_block_id}..." | |
| error_msg=$(echo "offline" > "${state_file}" 2>&1) | |
| if [ $? -eq 0 ]; then | |
| echo " SUCCESS" | |
| offlined_kb=$((offlined_kb + BLOCK_SIZE_KB)) | |
| else | |
| echo " FAILED. Reason: ${error_msg}" | |
| fi | |
| done | |
| echo "-------------------------------------" | |
| echo "Successfully offlined ${offlined_kb} KB of memory from node ${NODE_ID}." |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment