File zramon of Package zramservice

#!/bin/bash
# create runtime directory and files
mkdir -p /run/zramservice/
touch /run/zramservice/swap /run/zramservice/mounts
# load zram module with 0 devices, we'll hot add for each configured one
modprobe zram num_devices=0

# get total amount of system RAM, already existing SWAP in M and max swap priority
mem_available=$(( $(grep MemTotal /proc/meminfo | grep -E --only-matching '[[:digit:]]+')/1024 ))
swap_other=$(( $(grep SwapTotal /proc/meminfo | grep -E --only-matching '[[:digit:]]+')/1024 ))
swap_prio_max=$(swapon --show=prio | awk '{if(NR>1)print}' | awk 'BEGIN { max = -inf } { if ($1 > max) { max = $1; line = $0 } } END { print line }' )
swap_prio_max=$(( swap_prio_max > 32767 ? 32767 : swap_prio_max ))  # ceiling for swap priority

# read config and calculate memory pool available for all zram drives
stable_pool=1 # fallback value to 
mem_pool=$((mem_available-500))  # fallback value in case of bad or missing configuration and non existing fallback
while IFS=$': \n\t\r' read -r var val
do
echo " $var : $val "
    case "$var" in
    stable_pool )
        stable_pool=$val
	      ;;
    mem_reserved )
        # calculate usable pool in M
        mem_pool=$(( 0 < val && mem_available > val*2 ? mem_available - val : mem_pool ))
        ;;
    esac
done < /etc/zramservice.conf

if ((1 -eq $val)); then
  # ceiling for mem_pool, depending on available swap. ensures stable config.
  mem_pool=$(( mem_pool > (mem_available/2 + swap_other) ? (mem_available/2 + swap_other) : mem_pool ))
fi

# creating drives
while IFS=$': \n\t\r' read -r var val
do
  if (( 50 > mem_pool )); then break; fi  # not enough memory_pool available for further disks
  case "$var" in
  drive )   drive_name=$val  ;;
  mount )   mount_path=$val  ;;
  fs )      file_system=$val ;;
  size )    drive_size=$(( 0 < val && mem_pool*4 > val ? val : mem_pool*2)) ;;
  max_mem ) fix_val=$(( 0 < val && val < mem_pool-50 ? val : mem_pool))  ;;
    # mem_pool-50 enforces to deplete memory pool, if less then 50M would be left after next init
  max_pool_share ) share_val=$(( 0 < val && val <= 100 ? mem_pool*val/100 : mem_pool))  ;;
  clear ) unset drive_name mount_path file_system drive_size drive_max_mem drive_max_share  ;;
  init )
    if ! [[ -d "$mount_path" || "swap" == "$val" ]]; then  # abort if no mount point or not swap
      echo "bad mount point, drive $drive_name" | systemd-cat -t zramservice -p warning
      break
    fi
    # choose higher memory limit according to configuration
    mem_limit=$(( share_val > fix_val ? share_val : fix_val))
    #check drive_size and fix if needed
    drive_size=$(( 0 < drive_size && mem_available*4 > drive_size ? drive_size : mem_limit*4))

    drive_id=$(cat /sys/class/zram-control/hot_add)  # hot add device
    echo "$drive_size"M > /sys/block/zram"$drive_id"/disksize  # set size and initialize
    echo "$mem_limit"M > /sys/block/zram"$drive_id"/mem_limit  # limit memory usage
    mem_pool=$(( mem_pool-mem_limit ))  # update mem_pool

    case "$val" in
    swap )
      mkswap /dev/zram"$drive_id" # Create swap filesystem
      swapon -p $((swap_prio_max)) /dev/zram"$drive_id" # Switch the swap on
      echo "$drive_id" >> /run/zramservice/swap  # save to runtime
      echo 'zram swap ready' | systemd-cat -t zramservice -p info
      ;;
    mount )
      mkfs."$file_system" /dev/zram"$drive_id"
      mount /dev/zram"$drive_id" "$mount_path"
      unset mount_path
      echo "$drive_id" >> /run/zramservice/mounts  # save to runtime
      echo "drive $drive_name ready" | systemd-cat -t zramservice -p info
      ;;
    esac
    ;;
  esac
done < /etc/zramservice.conf
openSUSE Build Service is sponsored by