FEMU를 활용한 Zoned Namespace 개발 환경 구축
FEMU
FEMU는 USENIX FAST’18에서 처음 소개된 QEMU 기반의 플래시 에뮬레이터로 SSD 연구를 위한 목적으로 개발되었습니다. 주요 특징으로는 기존 QEMU와 Open-Channel SSD를 위한 파생인 qemu-nvme와 달리 디스크에 데이터를 쓰는 것이 아니라 메모리에 씁니다.
기존 QEMU는 NVMe SSD의 에뮬레이션 성능을 측정하기 위해 가상 이미지를 임의 저장 장치에 위치시키면, 성능 평가 결과는 장치의 최소 ~ 최대 성능이 제한됩니다. 장치가 너무 빠른 경우 예측하는 성능보다 의도치 않게 좋게 나오고 느린 경우에는 그 반대의 결과가 나오게 됩니다. 즉, 가상 이미지를 적합한 장치에 위치시키지 않는다면 그 성능 평가의 신뢰도가 떨어질 수 있음을 시사합니다.
FEMU의 경우에는 가상 이미지를 메모리에만 위치 시킵니다. 메모리에 위치 시키기만 하면 성능 평가 결과는 메모리 성능을 따르게 되겠지만, FEMU는 추가적으로 지연 시간을 부여 할 수 있도록 설계하여 목표로 하는 장치 성능을 인위적으로 만들 수 있습니다. 심지어 QEMU와 유사하게 FEMU는 GNU GPLv2에 의거하여 배포되므로 사용에 제약이 거의 없습니다.
이런 유용한 SSD 연구 도구인 FEMU에서 2월부터 ZNS 인터페이스를 지원하기 시작했습니다. 이 글에선 해당 ZNS 인터페이스를 FEMU를 통해 사용해보도록 하겠습니다.
[유의 사항] 현재(2021년 7월 11일 기준) FEMU의 ZNS는 인터페이스만 지원하게 지연 시간은 지원하지 않습니다. 따라서 현재는 이를 I/O 성능 측정을 위해서 사용하기에는 부족한 점이 있습니다.
FEMU의 설치
우분투 이미지의 획득
우분투 이미지를 직접 만드시는 것보다 FEMU VM 이미지를 직접 이 사이트에 요청해서 받는 것이 좋습니다. 그러면 약간의 시간이 흐르고 요청하신 메일로 이미지 파일을 다운을 받을 수 있는 링크를 줍니다. 해당 메일에는 이미지를 해제하고 위치시키는 방법이 적혀있습니다. 해당 내용을 링크만 제외하고 작성하면 아래와 같습니다.
mkdir -p ~/images
cd ~/images
wget $IMAGE_URL
tar -xJvf femu-vm.tar.xz
# 이미지 검증 과정
md5sum u20s.qcow2 > tmp.md5sum
diff tmp.md5sum u20s.md5sum
FEMU 컴파일 및 실행
그리고 FEMU 소스를 깃허브에서 복제하고 문서에서 설명하는 방식을 통해서 빌드를 수행합니다.
git clone https://github.com/ucare-uchicago/femu.git
cd femu
mkdir build-femu
# FEMU 빌드 디렉터리로 변경
cd build-femu
# FEMU 사용에 필요한 스크립트들의 복사 과정
cp ../femu-scripts/femu-copy-scripts.sh .
./femu-copy-scripts.sh .
sudo ./pkgdep.sh # 데비안 및 우분투에서만 수행
./femu-compile.sh
이 과정을 수행하면 X86_64-softmmu/qemu-system-x86_64
라는 바이너리가 나옵니다. 이 바이너리가 사실상 FEMU의 본체라고 할 수 있습니다. 그리고 아래 명령을 수행하면 정상적으로 이미지를 실행할 수 있습니다. 부팅 후 로그인 시에 사용하는 사용자 이름 및 패스워드는 femu. femu입니다.
sudo ./run-zns.sh
해당 스크립트 파일에서 devsz_mb
값을 변경하면 ZNS SSD의 크기를 변경할 수 있습니다.
커널 업데이트
현재(2021년 7월 11일 기준) FEMU 측에서 제공하는 이미지는 Ubuntu 16.04에 커널 4.16.0입니다. 문제는 ZNS SSD를 정상적으로 에뮬레이션을 하기 위해서는 리눅스 커널 5.10 이상이 있어야 합니다.
우분투 16.04에서는 커널 5.10 설치가 어려울 수 있으므로 우분투 버전 업데이트를 먼저 수행해줘야 합니다. 이하 과정은 우분투 16.04를 18.04로 업데이트 하는 명령어 리스트입니다.
sudo sed -i 's/us.archive.ubuntu.com/mirror.kakao.com/g' /etc/apt/sources.list # 패키지 다운 속도가 빠른 곳으로 변경
sudo apt update -y
sudo apt upgrade -y
sudo do-release-upgrade # 우분투 18.04로이 업데이트가 시작됩니다.
설치가 완료되면 아래 명령을 수행해서 5.10 커널을 설치해주도록 합니다.
cd /tmp/
wget -c https://kernel.ubuntu.com/~kernel-ppa/mainline/v5.10/amd64/linux-headers-5.10.0-051000_5.10.0-051000.202012132330_all.deb
wget -c https://kernel.ubuntu.com/~kernel-ppa/mainline/v5.10/amd64/linux-headers-5.10.0-051000-generic_5.10.0-051000.202012132330_amd64.deb
wget -c https://kernel.ubuntu.com/~kernel-ppa/mainline/v5.10/amd64/linux-image-unsigned-5.10.0-051000-generic_5.10.0-051000.202012132330_amd64.deb
wget -c https://kernel.ubuntu.com/~kernel-ppa/mainline/v5.10/amd64/linux-modules-5.10.0-051000-generic_5.10.0-051000.202012132330_amd64.deb
sudo dpkg -i *.deb
sudo update-grub
sudo reboot
재부팅 후에 uname -r
을 해서 5.10이 되었는지 확인해주도록 합니다.
정상 동작 확인
정상 동작 확인 여부를 확인하기 위해서 libzbd를 설치해주도록 합니다.
git clone https://github.com/westerndigitalcorporation/libzbd.git
sudo apt install -y autoconf automake libtool m4 autoconf-archive
cd libzbd
sh ./autogen.sh
./configure
make -j$(nproc)
sudo make install
설치가 완료되고 아래 명령으를 수행해주시길 바랍니다.
sudo zbd report /dev/nvme0n1
이때의 결과가 다음과 같이 나오면 정상적으로 설치된 것입니다.
Zone 00000: swr, ofst 00000000000000, len 00000134217728, cap 00000134217728, wp 00000000000000, em, non_seq 0, reset 0
Zone 00001: swr, ofst 00000134217728, len 00000134217728, cap 00000134217728, wp 00000134217728, em, non_seq 0, reset 0
Zone 00002: swr, ofst 00000268435456, len 00000134217728, cap 00000134217728, wp 00000268435456, em, non_seq 0, reset 0
Zone 00003: swr, ofst 00000402653184, len 00000134217728, cap 00000134217728, wp 00000402653184, em, non_seq 0, reset 0
Zone 00004: swr, ofst 00000536870912, len 00000134217728, cap 00000134217728, wp 00000536870912, em, non_seq 0, reset 0
Zone 00005: swr, ofst 00000671088640, len 00000134217728, cap 00000134217728, wp 00000671088640, em, non_seq 0, reset 0
Zone 00006: swr, ofst 00000805306368, len 00000134217728, cap 00000134217728, wp 00000805306368, em, non_seq 0, reset 0
Zone 00007: swr, ofst 00000939524096, len 00000134217728, cap 00000134217728, wp 00000939524096, em, non_seq 0, reset 0
Zone 00008: swr, ofst 00001073741824, len 00000134217728, cap 00000134217728, wp 00001073741824, em, non_seq 0, reset 0
Zone 00009: swr, ofst 00001207959552, len 00000134217728, cap 00000134217728, wp 00001207959552, em, non_seq 0, reset 0
Zone 00010: swr, ofst 00001342177280, len 00000134217728, cap 00000134217728, wp 00001342177280, em, non_seq 0, reset 0
Zone 00011: swr, ofst 00001476395008, len 00000134217728, cap 00000134217728, wp 00001476395008, em, non_seq 0, reset 0
Zone 00012: swr, ofst 00001610612736, len 00000134217728, cap 00000134217728, wp 00001610612736, em, non_seq 0, reset 0
Zone 00013: swr, ofst 00001744830464, len 00000134217728, cap 00000134217728, wp 00001744830464, em, non_seq 0, reset 0
Zone 00014: swr, ofst 00001879048192, len 00000134217728, cap 00000134217728, wp 00001879048192, em, non_seq 0, reset 0
Zone 00015: swr, ofst 00002013265920, len 00000134217728, cap 00000134217728, wp 00002013265920, em, non_seq 0, reset 0
Zone 00016: swr, ofst 00002147483648, len 00000134217728, cap 00000134217728, wp 00002147483648, em, non_seq 0, reset 0
Zone 00017: swr, ofst 00002281701376, len 00000134217728, cap 00000134217728, wp 00002281701376, em, non_seq 0, reset 0
Zone 00018: swr, ofst 00002415919104, len 00000134217728, cap 00000134217728, wp 00002415919104, em, non_seq 0, reset 0
Zone 00019: swr, ofst 00002550136832, len 00000134217728, cap 00000134217728, wp 00002550136832, em, non_seq 0, reset 0
Zone 00020: swr, ofst 00002684354560, len 00000134217728, cap 00000134217728, wp 00002684354560, em, non_seq 0, reset 0
Zone 00021: swr, ofst 00002818572288, len 00000134217728, cap 00000134217728, wp 00002818572288, em, non_seq 0, reset 0
Zone 00022: swr, ofst 00002952790016, len 00000134217728, cap 00000134217728, wp 00002952790016, em, non_seq 0, reset 0
Zone 00023: swr, ofst 00003087007744, len 00000134217728, cap 00000134217728, wp 00003087007744, em, non_seq 0, reset 0
Zone 00024: swr, ofst 00003221225472, len 00000134217728, cap 00000134217728, wp 00003221225472, em, non_seq 0, reset 0
Zone 00025: swr, ofst 00003355443200, len 00000134217728, cap 00000134217728, wp 00003355443200, em, non_seq 0, reset 0
Zone 00026: swr, ofst 00003489660928, len 00000134217728, cap 00000134217728, wp 00003489660928, em, non_seq 0, reset 0
Zone 00027: swr, ofst 00003623878656, len 00000134217728, cap 00000134217728, wp 00003623878656, em, non_seq 0, reset 0
Zone 00028: swr, ofst 00003758096384, len 00000134217728, cap 00000134217728, wp 00003758096384, em, non_seq 0, reset 0
Zone 00029: swr, ofst 00003892314112, len 00000134217728, cap 00000134217728, wp 00003892314112, em, non_seq 0, reset 0
Zone 00030: swr, ofst 00004026531840, len 00000134217728, cap 00000134217728, wp 00004026531840, em, non_seq 0, reset 0
Zone 00031: swr, ofst 00004160749568, len 00000134217728, cap 00000134217728, wp 00004160749568, em, non_seq 0, reset 0
이제 ZNS SSD 개발 환경이 구축되게 된 것입니다.