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로 다운그레이드하기 때문입니다.

어떻게 해야 하나요?

편집: 스크립트는 현재 존재 여부에 관계없이 2GB 스왑 파일을 생성하므로 4GB 스왑 파일이 있으면 2GB로 변경되지만 2GB 스왑 파일도 있으면 여전히 2GB로 다시 스왑됩니다. 이것이 좋은 선택이 아닌 것 같은데, 그래서 스왑 크기 확인을 추가해야 하는지 궁금합니다.

답변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 열로 보고됩니다 free.man 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

관련 정보