pc:test_multiple_nvme_namespaces

複数のNVMe namespaceを試す

NVMeにはNamespace(名前空間)という機能がある。NVMeデバイスの記憶領域を論理的に分割し、それぞれを独立したNVMeストレージのように扱う機能である。

馴染みあるところだとパーティションのようなものだが、ファームウェアレイヤーでの分割となり、名前空間同士には明確な前後関係はなく、OSからは別のデバイスとして見えるのが大きな違い。ハードウェアRAIDの仮想ドライブ、ZFSのデータセットに近い。

名前空間を使うと以下の効能が見込めるとされる。

  • 名前空間ごとに異なる暗号鍵によるセキュリティの向上
  • オーバープロビジョニングによる書き込み性能、耐久性の向上
  • リカバリ領域などの書込み保護

名前空間はオプション機能なので、大半のNVMe SSD製品、特にコンシューマ向けは最大1つの名前空間しかサポートしてなかったりして残念ではあるが、使えれば色々遊べそうな機能だ。個人的には仮想と物理を行き来するような構成でディスク管理の簡単化への期待が高まる(弊宅ではPromoxVEと一部VMのRDM用パーティションが同じSSD上にあり、だいぶ面倒な運用となっている。名前空間でデバイスを割ることができれば、非常にシンプルになるハズ。)

  • ハードウェア
    • Lenovo ThinkServer TS150
    • Supermicro X10SRL-F
    • SAMSUNG PM9A3 (M.2/U.2)
      • 最大32の名前空間に対応
  • ソフトウェア
    • Ubuntu Server 22.04.2 LTS

FreeBSDerのわたくしといたしましては、FreeBSDのnvmecontrolコマンドで試したかったのだけれども、バグで名前空間が作れないという致命的な問題があったので、やむなくLinux環境で試すこととなった。なお、バグは13.2-RELEASEで修正される模様。

まずは現在のNVMe SSDの状態を確認する。

デバイスの認識状況:

$ sudo nvme list
Node                  SN      Model                                    Namespace Usage                      Format           FW Rev
--------------------- ------- ---------------------------------------- --------- -------------------------- ---------------- --------
/dev/nvme0n1          Serial  SAMSUNG MZ1L21T9HCLS-00A07               1           0.00   B /   1.92  TB    512   B +  0 B   GDC7302Q

使用可能なLBAフォーマット:

$ sudo nvme id-ns -H /dev/nvme0n1 | grep ^LBA
LBA Format  0 : Metadata Size: 0   bytes - Data Size: 512 bytes - Relative Performance: 0 Best (in use)
LBA Format  1 : Metadata Size: 0   bytes - Data Size: 4096 bytes - Relative Performance: 0 Best

既存の名前空間から使用可能なLBA形式を取得しておく。

というのも、後ほど名前空間作成時に使うのだけれども、名前空間がない状態でこのリストを取得する術が無さそうなのだ。いざとなれば、てきとーなLBA形式で名前空間作成後、希望の形式で再フォーマットしてやれば済む話だが、二度手間は避けたいので。

NVMeコントローラの一覧:

$ sudo nvme list-ctrl /dev/nvme0
num of ctrls present: 1
[   0]:0x6

NVMeデバイスでは複数のコントローラを持つことができ、名前空間はコントローラに割り当てる形となっている。この値も後ほど使うのでメモっておく。

NVMeコントローラの詳細:

$ sudo nvme id-ctrl /dev/nvme0 | grep -E 'nn|nvmcap'
tnvmcap   : 1920383410176
unvmcap   : 0
nn        : 32

tnvmcapはTotal NVM Capacity、unvmcapはUnallocated NVM Capacityのことで、それぞれNVMeデバイスの合計容量と未確保容量をバイト単位であらわす。

nnはNumber of Namespacesで、本記事の肝であり、デバイスがサポートする名前空間の数である。これが1だと話にならない。

上記の実行結果からは、本SSDは最大32個の名前空間が使えるものの、現在の空き容量が0なのでこれ以上の名前空間の追加は不可ということになる。

nvme delete-nsで既存の名前空間を削除する。

言うまでもないが、削除された名前空間にあったデータは全て消失する。確認プロンプトも出ず、デバイスレベルでの管理情報が消えることとなり、データの復元は個人レベルでは恐らく不可能なので要注意。

$ sudo nvme delete-ns /dev/nvme0 -n 1
delete-ns: Success, deleted nsid:1

unvmcapが増えていることが分かる。

$ sudo nvme id-ctrl /dev/nvme0 | grep nvmcap
tnvmcap   : 1920383410176
unvmcap   : 1920383410176

いよいよ名前空間を追加する。

$ sudo nvme create-ns /dev/nvme0 -f 0 -s 209715200 -c 209715200
create-ns: Success, created nsid:1

引数オプションの意味は下表のとおり。

オプション 意味
-f, –flbas LBA形式の指定。nvme id-nsで得られた値を指定する。ここでは512バイトセクタとしている。
-s, –nsze 名前空間の最大サイズ。-fで指定したブロック数単位で指定する。ここでは100GiB÷512バイト=209715200としている。
-c, –ncap 名前空間の確保サイズ。-sのブロック数以下で指定する。最大サイズ未満を指定すればオーバープロビジョニング状態となる。

作成した名前空間はコントローラにアタッチして初めて使えるようになる。

$ sudo nvme attach-ns /dev/nvme0 -n 1 -c 0x6
attach-ns: Success, nsid:1

同じ要領で、もう1つ名前空間を追加する。

$ sudo nvme create-ns /dev/nvme0 -s 209715200 -c 209715200 -f 0
create-ns: Success, created nsid:2

$ sudo nvme attach-ns /dev/nvme0 -n 2 -c 0x6
attach-ns: Success, nsid:2

システムからnvme0n1, nvme0n2として認識されていることが分かる。

$ sudo nvme list
Node                  SN      Model                                    Namespace Usage                      Format           FW Rev
--------------------- ------- ---------------------------------------- --------- -------------------------- ---------------- --------
/dev/nvme0n1          Serial  SAMSUNG MZ1L21T9HCLS-00A07               1         107.37  GB / 107.37  GB    512   B +  0 B   GDC7302Q
/dev/nvme0n2          Serial  SAMSUNG MZ1L21T9HCLS-00A07               2         107.37  GB / 107.37  GB    512   B +  0 B   GDC7302Q

$ lsblk | grep nvme0
nvme0n1 259:0    0   100G  0 disk
nvme0n2 259:1    0   100G  0 disk

それぞれのS.M.A.R.T.はこんな感じ。デバイスが対応していれば、名前空間ごとに固有のS.M.A.R.T.を持つこともできるようだ。

nvme0n1 nvme0n2
$ sudo smartctl -a /dev/nvme0n1
smartctl 7.2 2020-12-30 r5155 [x86_64-linux-5.15.0-60-generic] (local build)
Copyright (C) 2002-20, Bruce Allen, Christian Franke, www.smartmontools.org

=== START OF INFORMATION SECTION ===
Model Number:                       SAMSUNG MZ1L21T9HCLS-00A07
Serial Number:                      S666NE0Rxxxxxx
Firmware Version:                   GDC7302Q
PCI Vendor/Subsystem ID:            0x144d
IEEE OUI Identifier:                0x002538
Total NVM Capacity:                 1,920,383,410,176 [1.92 TB]
Unallocated NVM Capacity:           1,705,635,045,376 [1.70 TB]
Controller ID:                      6
NVMe Version:                       1.4
Number of Namespaces:               32
Namespace 1 Size/Capacity:          107,374,182,400 [107 GB]
Namespace 1 Formatted LBA Size:     512
Local Time is:                      Fri May  5 10:11:28 2023 UTC
Firmware Updates (0x17):            3 Slots, Slot 1 R/O, no Reset required
Optional Admin Commands (0x005f):   Security Format Frmw_DL NS_Mngmt Self_Test MI_Snd/Rec
Optional NVM Commands (0x005f):     Comp Wr_Unc DS_Mngmt Wr_Zero Sav/Sel_Feat Timestmp
Log Page Attributes (0x0e):         Cmd_Eff_Lg Ext_Get_Lg Telmtry_Lg
Maximum Data Transfer Size:         512 Pages
Warning  Comp. Temp. Threshold:     77 Celsius
Critical Comp. Temp. Threshold:     85 Celsius
Namespace 1 Features (0x1a):        NA_Fields No_ID_Reuse NP_Fields

Supported Power States
St Op     Max   Active     Idle   RL RT WL WT  Ent_Lat  Ex_Lat
 0 +     8.25W    8.25W       -    0  0  0  0       70      70

Supported LBA Sizes (NSID 0x1)
Id Fmt  Data  Metadt  Rel_Perf
 0 +     512       0         0
 1 -    4096       0         0

=== START OF SMART DATA SECTION ===
SMART overall-health self-assessment test result: PASSED

SMART/Health Information (NVMe Log 0x02)
Critical Warning:                   0x00
Temperature:                        51 Celsius
Available Spare:                    100%
Available Spare Threshold:          10%
Percentage Used:                    13%
Data Units Read:                    3,211,446,954 [1.64 PB]
Data Units Written:                 3,198,599,733 [1.63 PB]
Host Read Commands:                 7,123,174,983
Host Write Commands:                3,057,480,670
Controller Busy Time:               35,138
Power Cycles:                       183
Power On Hours:                     8,877
Unsafe Shutdowns:                   106
Media and Data Integrity Errors:    0
Error Information Log Entries:      14
Warning  Comp. Temperature Time:    0
Critical Comp. Temperature Time:    0
Temperature Sensor 1:               51 Celsius
Temperature Sensor 2:               80 Celsius

Error Information (NVMe Log 0x01, 16 of 64 entries)
Num   ErrCount  SQId   CmdId  Status  PELoc          LBA  NSID    VS
  0         14     0  0xb007  0x4238  0x000            0     1     -
  1         13     0  0x8007  0x4238  0x000            0     1     -
  2         12     0  0x8006  0x4238  0x000            0     1     -
  3         11     0  0x7007  0x422a  0x000            0     0     -
$ sudo smartctl -a /dev/nvme0n2
smartctl 7.2 2020-12-30 r5155 [x86_64-linux-5.15.0-60-generic] (local build)
Copyright (C) 2002-20, Bruce Allen, Christian Franke, www.smartmontools.org

=== START OF INFORMATION SECTION ===
Model Number:                       SAMSUNG MZ1L21T9HCLS-00A07
Serial Number:                      S666NE0Rxxxxxx
Firmware Version:                   GDC7302Q
PCI Vendor/Subsystem ID:            0x144d
IEEE OUI Identifier:                0x002538
Total NVM Capacity:                 1,920,383,410,176 [1.92 TB]
Unallocated NVM Capacity:           1,705,635,045,376 [1.70 TB]
Controller ID:                      6
NVMe Version:                       1.4
Number of Namespaces:               32
Namespace 2 Size/Capacity:          107,374,182,400 [107 GB]
Namespace 2 Formatted LBA Size:     512
Local Time is:                      Fri May  5 10:12:01 2023 UTC
Firmware Updates (0x17):            3 Slots, Slot 1 R/O, no Reset required
Optional Admin Commands (0x005f):   Security Format Frmw_DL NS_Mngmt Self_Test MI_Snd/Rec
Optional NVM Commands (0x005f):     Comp Wr_Unc DS_Mngmt Wr_Zero Sav/Sel_Feat Timestmp
Log Page Attributes (0x0e):         Cmd_Eff_Lg Ext_Get_Lg Telmtry_Lg
Maximum Data Transfer Size:         512 Pages
Warning  Comp. Temp. Threshold:     77 Celsius
Critical Comp. Temp. Threshold:     85 Celsius
Namespace 2 Features (0x1a):        NA_Fields No_ID_Reuse NP_Fields

Supported Power States
St Op     Max   Active     Idle   RL RT WL WT  Ent_Lat  Ex_Lat
 0 +     8.25W    8.25W       -    0  0  0  0       70      70

Supported LBA Sizes (NSID 0x2)
Id Fmt  Data  Metadt  Rel_Perf
 0 +     512       0         0
 1 -    4096       0         0

=== START OF SMART DATA SECTION ===
SMART overall-health self-assessment test result: PASSED

SMART/Health Information (NVMe Log 0x02)
Critical Warning:                   0x00
Temperature:                        51 Celsius
Available Spare:                    100%
Available Spare Threshold:          10%
Percentage Used:                    13%
Data Units Read:                    3,211,446,954 [1.64 PB]
Data Units Written:                 3,198,599,733 [1.63 PB]
Host Read Commands:                 7,123,174,983
Host Write Commands:                3,057,480,670
Controller Busy Time:               35,138
Power Cycles:                       183
Power On Hours:                     8,877
Unsafe Shutdowns:                   106
Media and Data Integrity Errors:    0
Error Information Log Entries:      14
Warning  Comp. Temperature Time:    0
Critical Comp. Temperature Time:    0
Temperature Sensor 1:               51 Celsius
Temperature Sensor 2:               80 Celsius

Error Information (NVMe Log 0x01, 16 of 64 entries)
Num   ErrCount  SQId   CmdId  Status  PELoc          LBA  NSID    VS
  0         14     0  0xb007  0x4238  0x000            0     1     -
  1         13     0  0x8007  0x4238  0x000            0     1     -
  2         12     0  0x8006  0x4238  0x000            0     1     -
  3         11     0  0x7007  0x422a  0x000            0     0     -

実はここからが本題。

複数の名前空間が持てるのは良いが、UEFI (BIOS)やOSから2つ目以降の名前空間はどのように認識されるのだろうか。NVMe Namespaceはハードウェアに近いレイヤーでのデバイス分割技術ではあるものの、PCIデバイスとしてはあくまで1つである。名前空間の実現には、ホストのNVMeドライバに拠るところが大きい気がして、特にPCのUEFI (BIOS)での対応状況が気になるところ。

それぞれのNVMe名前空間からシステムを自由にブートできれば夢が広がリングなのだが、情報がさっぱり見当たらないので実際に試してみた。

Linuxの場合、これまで見てきたとおり名前空間は/dev/nvme0n1, /dev/nvme0n2という感じで独立したデバイスのように見える。インストール先の選択肢にも上がっており、任意の名前空間にインストールが可能である。

FreeBSDでは/dev/nvme0ns1, /dev/nvme0ns1のように見える(さらに言うと対応する汎用ディスクレイヤーのデバイスとして/dev/nvd0, /dev/nvd1が生えてくる)。こちらも任意の名前空間にインストールが可能である。

WindowsではLUN違いのデバイスとして見えるようだ。

インストーラーでも別ドライブとして認識されており、インストールできると思われる。

WindowsとNVMe→USB変換器経由で複数名前空間を持つSSDをつないだ時の認識のされ方。

変換チップ 認識のされ方
ASM2362 最初の名前空間のみドライブとして認識される
JMS583 全く認識されない。名前空間が1つのみのSSDなら問題なく認識されるので、複数名前空間があるとダメっぽい。

UEFIからの見え方は、恐らくマザボごとにまちまちである可能性が高い。NVMe対応UEFIは必須として、そのUEFIが持つNVMeドライバの対応状況次第だと思う。

ThinkServer TS150

比較的初期のNVMe対応品であると思われるTS150では、名前空間IDが1にあるESPを優先的にブートデバイスとして扱うようだ(あるいは、UEFIの最初のブートエントリが優先されてるのかも)。なお、NSID 1にはUbuntu Server、NSID 2にはFreeBSDをインストールした状態である。

UEFIのブートエントリは以下のような感じで、名前空間2にインストールしたFreeBSDも、正しく登録されているようだ。

$ efibootmgr -v
BootCurrent: 0000
Timeout: 1 seconds
BootOrder: 0000,0002,0003
Boot0000* ubuntu        HD(1,GPT,0066403c-e597-4cfa-aa56-ad2f79960c92,0x800,0x219800)/File(\EFI\UBUNTU\SHIMX64.EFI)
Boot0002* FreeBSD       HD(1,GPT,a0fad4cc-eb36-11ed-bb5d-4ccc6acb7c47,0x28,0x82000)/File(\EFI\FREEBSD\LOADER.EFI)
Boot0003* UEFI OS       HD(1,GPT,a0fad4cc-eb36-11ed-bb5d-4ccc6acb7c47,0x28,0x82000)/File(\EFI\BOOT\BOOTX64.EFI)..BO

$ sudo blkid
/dev/nvme0n1p1:                  UUID="8030-A0AE" BLOCK_SIZE="512" TYPE="vfat"                      PARTUUID="0066403c-e597-4cfa-aa56-ad2f79960c92"
/dev/nvme0n2p1: SEC_TYPE="msdos" UUID="C23B-12F9" BLOCK_SIZE="512" TYPE="vfat" PARTLABEL="efiboot0" PARTUUID="a0fad4cc-eb36-11ed-bb5d-4ccc6acb7c47"

ここでefibootmgr -n 0003とし次のブートデバイスをFreeBSDにすると、しっかりFreeBSDが立ち上がってくる。ただしUEFI上でのブートデバイスとしての認識は「ubuntu」のままだった。

一方で、efibootmgr -o 0003,0002,0000としてブートオーダーをFreeBSD優先にしても、相変わらずUbuntuが立ち上がってきた。

いまいち釈然としない挙動だが、とりあえず名前空間が分かれていてもブート自体は可能なことは分った。恒常的に起動OSを切り替えたいなら、rEFIndCloverBootloaderあたりを名前空間1に入れておけば良いだろう。

Supermicro X10SRL-F

SupermicroのマザボX10SRL-Fでは、正しいESPさえあれば名前空間問わずブートデバイスとして検出してくれる模様。

どちらも「UEFI OS」となっていて分かりづらいが、上が名前空間1のESPにあるFreeBSDのブートローダ、下が名前空間2のESPにあるProxmox VEのブートローダである。ブートオーダーはPVEが優先となっており、問題なくPVEが起動する。さすがSupermicro。

  • pc/test_multiple_nvme_namespaces.txt
  • 最終更新: 2023-06-08 23:28
  • by Decomo