基本的にはFedora28以上を入れておくのが一番簡単かと思います. Linuxカーネルはバージョンが4.17.19以上である必要があります. Linuxカーネルは以下のコンフィグが有効になっている必要があります. 最近の一般的なディストリビューションだと有効になっていることが多いとは思いますが, 自前でカーネルをビルドする場合や機能が有効にならない場合は有効化・確認をする必要があります.
CONFIG_BLK_DEV_RAM_DAX=y
CONFIG_FS_DAX=y
CONFIG_X86_PMEM_LEGACY=y
CONFIG_LIBNVDIMM=y
CONFIG_BLK_DEV_PMEM=m
CONFIG_ARCH_HAS_PMEM_API=y
CONFIG_TRANSPARENT_HUGEPAGE=y
CONFIG_MEMORY_HOTPLUG=y
CONFIG_MEMORY_HOTREMOVE=y
CONFIG_ZONE_DEVICE=y
CONFIG_FS_DAX_PMD=y
NVDIMMをエミュレートする方法は2つあります.一つは完全に仮想環境上で,一つは実機上でできます. とりあえずQEMUを使用しておくのが簡単だと思います.
QEMUがファイルをバックエンドにNVDIMMをエミュレートしてくれます. 僕は以下のシェルスクリプトで仮想環境を立ち上げています.
#/bin/sh
RAM_SIZE=16G
NVDIMM_SIZE=64G
ePATH=.
DISTRO=fedora.qcow2
GRAPHIC=-nographic
MAX_SIZE=300G
CPU=host
CORE=16
run() {
qemu-system-x86_64 -enable-kvm $GRAPHIC -s \
-drive file=$DISTRO,index=0,media=disk,cache=none \
-machine pc,nvdimm \
-m $RAM_SIZE,slots=4,maxmem=$MAX_SIZE \
-smp $CORE -cpu $CPU \
-net nic,model=virtio \
-net user,hostfwd=tcp::2222-:22 \
-object memory-backend-file,share,id=mem1,share=on,mem-path=$ePATH,size=$NVDIMM_SIZE \
-device nvdimm,id=nvdimm1,memdev=mem1 &
}
connect() {
ssh -p 2222 -i ~/.ssh/nvm_rsa pmem@localhost
}
case "$1" in
run)
run
;;
r)
run
;;
connect)
connect
;;
c)
connect
;;
*)
;;
esac
exit 0
これをそのまま真似るだけでも64GBの/dev/pmem0
が認識された仮想環境が立ち上がるはずです.
普段は適宜引数を変えることで仮想環境上のNVDIMMやDRAMのサイズを調節しています.
参考サイトはこちらになります.
日本語ソースだと自作OSでできる!NVDIMMのつかいかたを読むのが分かりやすくて良いかと思います.
DRAMの一部を使用してNVDIMMをエミュレートすることも可能です.これはカーネルパラメータを追加してやることで可能になります.
仮想環境の必要なしに行うことができますが,仮想環境上でやることをおすすめします.
Fedora(Ubuntuも同様であると確認済み)だと/etc/default/
以下にgrub
というファイルがあります.
GRUB_TIMEOUT=5
GRUB_DISTRIBUTOR="$(sed 's, release .*$,,g' /etc/system-release)"
GRUB_DEFAULT=0
GRUB_DISABLE_SUBMENU=true
GRUB_TERMINAL_OUTPUT="console"
GRUB_CMDLINE_LINUX="resume=/dev/mapper/fedora_localhost--live-swap rd.lvm.lv=fedora_localhost-live/root rd.lvm.lv=fedora_localhost-live/swap rhgb quiet crashkernel=128M memmap=8G!8G"
GRUB_DISABLE_RECOVERY="true"
僕のFedora28環境だと上のようになっています.このうちmemmap=8G!8G!
というのがNVDIMMエミュレートするためのカーネルパラメータです.
**注意事項として,これはメモリが16GBだった時の環境上でのみ通用するパラメータです.**パラメータの設定方法は後述します.
パラメータを追加し,grub2-mkconfig -o /boot/grub2/grub.cfg
と叩いてgrubを更新してシステムを再起動すると8G
の/dev/pmem0
をシステムが
認識します.
簡単に言ってしまうとメモリ8Gから先の8GをNVDIMMとしてエミュレートするというパラメータになります.最初の8G
がどのくらいのサイズの
NVDIMMをエミュレートするか,次の8G
がメモリのどこからエミュレートするかということを表します.
このエミュレーション方法はいくつか制約があります.一つはシステムに与えられたメモリを超えた指定を行えないことです.また,システムが
予約しているメモリ領域をNVDIMMとして使う指定をすることはできません.
詳細はPersistent Memory WikiのQuick Setup Guidにあります.このエミュレーション方法を利用したい場合は読むことをおすすめします.
この方法は設定が少々わかりにくいですが一つ利点があります.それはDRAMを利用したエミュレーションであるため,NVDIMM-Nをディスクとして使用する際の
ベンチマークをある程度正確に採ることが出来ます.これは個人的に非常に興味深かった点ですがQEMUを用いたエミュレーションによって
ベンチマークを採るとNOVAとAEONは全く性能が出ません.一方,DRAMを用いたエミュレーションでは先行論文から得られる結果を含めた期待通りの
スコアを概ね得ることができます.これは個人的に割と面白い知見でした.
両方同時に使うこともできます.僕は普段はDRAMを用いたエミュレーションで開発しており,テスト時に複数のデバイスが必要になる場合にQEMUのオプションを 追加して(厳密に言うとコメントアウトを外している)複数を扱っています.もっともQEMUだけで複数のデバイスをエミュレーションすることも可能です.
NVDIMMが無事エミュレートできたらマウントしてAEONを試すことができます.
AEONを手元に持ってきてmake
でビルドしてください.もしビルドできなかったらissue立ててください...
aeon.ko
というバイナリができます.以下のコマンドでカーネルに組み込んでください.
# insmod aeon.ko
次に,NVDIMMをFSDAXモードに変更します./dev/pmem0
に対するコマンドは以下になります.
# ndctl create-namespace -e "namespace0.0" -m memory -f
これで,マウントに移ることができます.
# mount -t aeon -o init,dax /dev/pmem0 /mnt
マウント先は任意です.最初のマウントはinit
をつける必要があります.またdax
は常に必ずつけてください.
ファイルとか色々作った後にファイルシステムをアンマウントする時は,
次のコマンドで行います.
# umount /mnt
以降,init
なしにマウントできます.作ったファイルも認識されるはずです.(ちなみにデモのmkfs.aeon
は単に
このコマンド群を組み合わせたシェルスクリプトです.近いうちにC/C++でmkfs
コマンドを作ろうと考えています.)
ただし,実機がない場合は,システムを落としたらinit
からやり直してください.作ったファイルはなくなります.
これら一連の流れは同梱のrun.sh
を使用して
$ make -j
$ ./run.sh set
$ ./run.sh
とやるのが簡単です.(普段はこれで開発をしています.)
Fedora28だと通常zsdモジュールがインストールされていないので透過圧縮モードでAEONをマウントすることはできません.
# modprobe zstd_compress
# modprobe zstd_decompress
これで,使えるはずです.ただし僕はカーネル自前ビルドしてzstd使っているのでもしかしたらできないかも... また確認します.
また,AEONを透過圧縮のコンフィグをオンにした状態でビルドしたものを使う必要があります.
Makefile中の
CONFIG_AEON_FS_COMPRESSION
とCONFIG_AEON_FS_AEON_RW
をコメントアウトしてビルドしてください.
(いまのところ透過圧縮はまだ解決すべき課題がいくつかあるのですぐバグります.ある程度まともに動くようになるまで少し時間がかかると思います)
マウント時にマウントオプションにdata=compressed
を追加してください.run.sh
を用いて
$ ./run.sh compression
でも良いです.
CONFIG_AEON_FS_XATTR
とCONFIG_AEON_FS_SECURITY
はsetfattr
コマンドやgetfattr
コマンドを使用する際に必要になります.
CONFIG_AEON_FS_COMPRESSION
はCONFIG_AEON_FS_AEON_RW
と一緒に有効化する必要があります.
CONFIG_AEON_FS_AEON_RW
は自前の読み書きメソッド実装モードになります.これ単体でビルドした場合はLinuxカーネルの共通関数を用いた読み書きではなく全て自前実装の読み書きメソッドが使われます.
CONFIG_AEON_FS_DEBUG_MODE
は
デバッグ用にログをたくさん吐くようになります.残り3つのオプションは内部の管理方法が変わりますが,CONFIG_AEON_FS_NUMA
に関しては
masterブランチのものでは実際にはNUMAのためのモードになりません.もっともNUMA構成のNVDIMMをエミュレートする手段がない(はず)のですが...
いくつかバグを確認していますが,確認できていないバグがある可能性は十分にあると思いますので,issueにバグレポートのテンプレ用意しておきましたので, もし見つけたら立てていただければ嬉しいです.