Skip to content

Instantly share code, notes, and snippets.

@corporatepiyush
Created July 28, 2024 09:14
Show Gist options
  • Save corporatepiyush/a9a1d55a5c13d703aa85e06633dd0a65 to your computer and use it in GitHub Desktop.
Save corporatepiyush/a9a1d55a5c13d703aa85e06633dd0a65 to your computer and use it in GitHub Desktop.
Memory allocation control for Linux OS process and managing overflow with swap files
#!/bin/bash
# Configuration
NODE_APP="your-app.js"
CGROUP_NAME="nodejs_group"
MEMORY_LIMIT="4G"
SWAP_SIZE="8G"
SWAPFILE="/swapfile"
SWAPPINESS=60
ZSWAP_ENABLED=1
ZSWAP_COMPRESSOR="lz4"
ZSWAP_MAX_POOL_PERCENT=20
# Function to log messages
log() {
echo "[$(date +'%Y-%m-%d %H:%M:%S')] $1"
}
# Check if running as root
if [ "$(id -u)" != "0" ]; then
log "This script must be run as root"
exit 1
fi
# Function to convert sizes to bytes
to_bytes() {
local size=$1
case ${size: -1} in
G|g) echo $((${size::-1} * 1024 * 1024 * 1024)) ;;
M|m) echo $((${size::-1} * 1024 * 1024)) ;;
K|k) echo $((${size::-1} * 1024)) ;;
*) echo $size ;;
esac
}
# Setup cgroup
setup_cgroup() {
log "Setting up cgroup..."
if mount | grep "cgroup2" > /dev/null; then
# cgroup v2
mkdir -p /sys/fs/cgroup/$CGROUP_NAME
echo "+memory" > /sys/fs/cgroup/$CGROUP_NAME/cgroup.subtree_control
echo $(to_bytes $MEMORY_LIMIT) > /sys/fs/cgroup/$CGROUP_NAME/memory.max
log "Cgroup v2 created with memory limit: $MEMORY_LIMIT"
else
# cgroup v1
cgcreate -g memory:$CGROUP_NAME
echo $(to_bytes $MEMORY_LIMIT) > /sys/fs/cgroup/memory/$CGROUP_NAME/memory.limit_in_bytes
log "Cgroup v1 created with memory limit: $MEMORY_LIMIT"
fi
}
# Setup swap space with compression
setup_swap() {
log "Setting up swap space with compression..."
# Enable zswap
if [ -d "/sys/module/zswap" ]; then
echo $ZSWAP_ENABLED > /sys/module/zswap/parameters/enabled
echo $ZSWAP_COMPRESSOR > /sys/module/zswap/parameters/compressor
echo $ZSWAP_MAX_POOL_PERCENT > /sys/module/zswap/parameters/max_pool_percent
log "zswap enabled with compressor: $ZSWAP_COMPRESSOR, max pool: $ZSWAP_MAX_POOL_PERCENT%"
else
log "zswap module not available. Proceeding without swap compression."
fi
if [ -f $SWAPFILE ]; then
log "Swapfile already exists. Skipping creation."
else
log "Creating swapfile..."
if ! fallocate -l $SWAP_SIZE $SWAPFILE; then
log "Failed to create swapfile. Trying dd method..."
if ! dd if=/dev/zero of=$SWAPFILE bs=1G count=${SWAP_SIZE%G} status=progress; then
log "Failed to create swapfile"
return 1
fi
fi
chmod 600 $SWAPFILE
if ! mkswap $SWAPFILE; then
log "Failed to set up swap area"
return 1
fi
fi
if swapon $SWAPFILE; then
log "Swap space activated: $SWAP_SIZE"
else
log "Failed to activate swap space"
return 1
fi
# Set swappiness
if sysctl -w vm.swappiness=$SWAPPINESS; then
log "Swappiness set to $SWAPPINESS"
else
log "Failed to set swappiness"
return 1
fi
return 0
}
# Run Node.js application
run_node_app() {
log "Starting Node.js application..."
if mount | grep "cgroup2" > /dev/null; then
# cgroup v2
systemd-run --unit=nodejs_app --scope -p MemoryMax=$(to_bytes $MEMORY_LIMIT) node $NODE_APP
else
# cgroup v1
cgexec -g memory:$CGROUP_NAME node $NODE_APP
fi
}
# Main execution
setup_cgroup
if ! setup_swap; then
log "Failed to set up swap. Exiting."
exit 1
fi
run_node_app
# Cleanup (uncomment if needed)
# log "Cleaning up..."
# swapoff $SWAPFILE
# rm $SWAPFILE
# if mount | grep "cgroup2" > /dev/null; then
# rmdir /sys/fs/cgroup/$CGROUP_NAME
# else
# cgdelete memory:$CGROUP_NAME
# fi
log "Script completed."
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment