Bashでスワップ領域のサイズを確認する方法

Bashでスワップ領域のサイズを確認する方法

スワップが存在することを確認し、存在しない場合はスワップを生成するbashスクリプトがあります。

if free | awk '/^Swap:/ {exit !$2}'; then
    echo "Have swap, skipping"
    sudo swapoff -a
    sudo dd if=/dev/zero of=/swapfile bs=1M count=2048
    sudo mkswap /swapfile
    sudo swapon /swapfile
else
    fallocate -l 2G /swapfile
    chmod 600 /swapfile
    mkswap /swapfile
    swapon /swapfile
    sudo echo -e "/swapfile none swap sw 0 0 \n" >> /etc/fstab
fi

これで、スワップサイズ(すでに存在する場合)を確認するためのチェックも追加したいと思います。スワップがすでに存在し、4GBの場合、スキップするのではなく2GBにダウングレードするためです。

どうすればいいですか?

編集:スクリプトは現在の存在にかかわらず2 GBのスワップファイルを生成するため、4 GBのスワップファイルがある場合は2 GBに変更されますが、2 GBのスワップファイルがある場合はまだ2 GBに再スワップされます。これは良い選択ではないようですが、スワップサイズチェックを追加する必要があるかどうか疑問に思います。

答え1

カーネルがあまり古いものではなく、fallocateシステムコールをサポートしているとします(バージョン2.6.23以降で利用可能、参照)。man fallocate(1)そしてman fallocate(2))、fallocateデータブロックを書き込まないため、速度が速くなる可能性があります。したがって、常に新しいスワップファイルを生成することに大きな問題はありません。条件付きで実行できる唯一のステップはfstab

スワップがまったくないか、パスがあるスワップファイルのみがあるとします/swapfile

swapfile="/swapfile"

# Make sure swap is on
swapon --all

# Check if our assumptions hold
if    [ "$(swapon --show --noheadings | wc -l)" -gt 1 ]         ||
  (   [ "$(swapon --show --noheadings | wc -l)" -eq 1 ]         &&
    ( [ "$(swapon --show=TYPE --noheadings)" != 'file' ]        ||
      [ "$(swapon --show=NAME --noheadings)" != "$swapfile" ]
    )
  );  then
    echo "Unsafe to proceed, exiting."
    exit
fi

# Edit /etc/fstab if our file is not already there
if ! grep -q '^[[:blank:]]*'"$swapfile"'[[:blank:]]\{1,\}none[[:blank:]]\{1,\}swap[[:blank:]]\{1,\}' /etc/fstab;
then
    printf '%s\n' "$swapfile none swap sw 0 0" >> /etc/fstab
fi

# Create/replace the swap file
swapoff --all
[ -f "$swapfile" ] && rm -- "$swapfile"
fallocate -l 2GiB -- "$swapfile"
chmod 600 "$swapfile"
mkswap -- "$swapfile"
swapon --all

それでも不必要にスワップを閉じて開くのを避けたいかもしれません。スワップの大部分が使用されると、動作が遅くなる可能性があり、使用可能なメモリが十分でない場合、望ましくない結果が生じる可能性があります。
これらの問題を部分的に解決し、元の質問に答えるには、上記のコードの最後の部分を条件付きブロックにまとめることができます。

# Check if we want to shrink the swap file i.e. it is bigger than 2 GiB
# (or if we have no swap file)
if  [ "$(free | awk '/^Swap:/ { print $2 }')" = "0" ] ||
    [ "$(free --bytes | awk '/^Swap:/ { print $2 }')" -gt 2147483648 ]; then

    # Create/replace the swap file
    # Same as above...

fi

最後に、カーネルバージョンが3.14以降で提供されているとしますMemAvailable/proc/meminfoその値はavailableby列として報告されます)freeman free(1))、スワップをオフにする前に十分なメモリがあることを確認することもできます。
最終的なコードスニペットは次のとおりです。

# Do we have no swap or more swap than 2GB?
# If yes, do we have more available memory than used swap?
if  ( [ "$(free | awk '/^Swap:/ { print $2 }')" = "0" ] ||
      [ "$(free --bytes | awk '/^Swap:/ { print $2 }')" -gt 2147483648 ]
    ) &&
    [ "$(awk '/MemAvailable:/ { print $2 }' /proc/meminfo)" -gt "$(free | awk '/Swap:/ { print $3 }')" ];
then
    # Create/replace the swap file
    # Same as above...
fi

関連情報