坑边闲话:在当今的数据中心和个人计算领域,NVMe(Non-Volatile Memory Express)固态硬盘已经成为高性能存储的事实标准。作为一种基于 PCIe 接口的存储协议,NVMe 相比传统的 SATA 接口提供了更低的延迟、更高的带宽和更强的并发性能。然而,要充分发挥 NVMe 设备的潜力,管理和监控这些设备变得至关重要。这就是 nvme-cli 发挥作用的地方。

1. nvme-cli 的诞生与发展·

nvme-cli 是一个专为 Linux 系统设计的开源 NVMe 管理命令行工具,最初由 Keith Busch(当时就职于 Intel)在 2014-2015 年创建并维护至今。Keith Busch 是 Linux NVMe 驱动开发的核心人物,他不仅开发了内核驱动,还创建了这个用户空间工具来管理 NVMe 设备。

项目托管在 GitHub 上的 linux-nvme 组织下(https://github.com/linux-nvme/nvme-cli),采用 GPLv2 许可证。多年来,这个项目得到了来自 Intel、三星、Western Digital、Solidigm 等众多存储厂商的贡献,已经成为 NVMe 设备管理的行业标准工具。

nvme-cli 的设计哲学是严格遵循 NVMe 规范,所有命令和输出都直接对应规范中定义的数据结构。这意味着用户只需要参考 NVMe 官方规范(可从 nvmexpress.org 获取),就能理解工具输出中的所有缩写和字段含义。从技术架构上看,nvme-cli 通过 Linux 内核的 IOCTL 接口与 NVMe 设备通信,直接发送 NVMe 原生命令到设备。它依赖于 libnvme 库来处理底层的 NVMe 协议通信,支持 Linux 内核 4.15 及更高版本(nvme-cli 2.x 版本)。

2. 项目结构与构建系统·

nvme-cli 采用现代化的构建系统 Meson,同时也提供了 Makefile 包装器以保持向后兼容。项目的核心依赖包括:

  • libnvme/libnvme-mi:必需依赖,处理 NVMe 协议通信
  • json-c:可选依赖,用于 JSON 格式输出和插件支持

项目支持多种构建方式:

  • 使用 Meson 直接构建
  • 使用 Makefile 包装器
  • 使用 samurai 和 muon 构建静态二进制(适用于较旧系统)

构建命令示例:

1
2
3
4
5
6
7
8
9
10
11
# 标准构建
$ meson setup .build
$ meson compile -C .build
# sudo meson install -C .build

# 使用 Makefile
$ make
# sudo make install

# 构建静态二进制
$ make static

2.1 插件架构·

nvme-cli 采用灵活的插件架构,允许硬件厂商添加特定的扩展命令。项目通过宏定义简化了插件开发过程,类似于 Linux 内核的 ftrace 组件。核心概念包括:

  1. 命令定义:在 nvme-builtin.h 中使用 ENTRY 宏定义命令
  2. 插件结构:使用 PLUGINCOMMAND_LIST 宏定义插件及其子命令
  3. 回调函数:实现具体的命令处理逻辑

目前已有众多厂商提供了插件支持,包括 Intel、三星、WDC、Solidigm、Micron 等。

2.2 安装与基本使用·

nvme-cli 已被包含在几乎所有主流 Linux 发行版中,安装非常简单:

1
2
3
4
5
6
7
8
9
10
11
# Debian/Ubuntu
sudo apt-get install nvme-cli

# Fedora/RHEL/CentOS
sudo dnf install nvme-cli

# Arch Linux
sudo pacman -S nvme-cli

# Alpine Linux
sudo apk add nvme-cli

基本使用方法:

1
2
3
4
5
6
7
8
# 查看帮助
nvme help

# 查看手册页
man nvme

# 查看所有 NVMe 设备
nvme list

所有命令遵循统一的返回约定:成功返回 0,失败返回 1。

3. nvme 核心子命令详解·

nvme-cli 提供了丰富的子命令集,涵盖设备识别、健康监控、固件管理、命名空间操作等各个方面。以下是最重要和最常用的命令。

3.1 设备枚举与信息查询·

3.1.1 nvme list·

列出系统中所有 NVMe 设备和命名空间:

1
sudo nvme list

输出示例:

1
2
3
Node             SN                   Model                                    Namespace Usage                      Format           FW Rev  
---------------- -------------------- ---------------------------------------- --------- -------------------------- ---------------- --------
/dev/nvme0n1 S42GMY9M141281 SAMSUNG MZVLB256HAHQ-000L7 1 214.68 GB / 256.06 GB 512 B + 0 B 0L2QEXD7

输出字段说明:

  • Node:设备节点路径
  • SN:序列号
  • Model:设备型号
  • Namespace:命名空间 ID
  • Usage:已用空间/总容量
  • Format:LBA 格式(扇区大小 + 元数据大小)
  • FW Rev:固件版本

3.1.2 nvme list-subsys·

显示 NVMe 子系统信息,包括控制器和命名空间的层次结构:

1
sudo nvme list-subsys

这个命令特别适用于理解 NVMe-oF(NVMe over Fabrics)环境中的拓扑结构。

3.2 设备识别命令·

3.2.1 nvme id-ctrl·

获取控制器的详细信息,这是了解 NVMe 设备能力的核心命令:

1
sudo nvme id-ctrl /dev/nvme0

关键输出字段:

  • vid/ssvid:供应商 ID 和子系统供应商 ID
  • sn:序列号
  • mn:型号名称
  • fr:固件版本
  • mdts:最大数据传输大小
  • oacs:可选管理命令支持位图
  • sqes/cqes:提交/完成队列入口大小
  • nn:命名空间数量
  • oncs:可选 NVM 命令支持
  • fuses:融合操作支持
  • vwc:易失性写缓存

使用 -H 选项可以获得人类可读的格式:

1
sudo nvme id-ctrl -H /dev/nvme0

检查特定功能支持示例:

1
2
# 检查是否支持 Format NVM 命令(OACS bit 1)
sudo nvme id-ctrl -H /dev/nvme0 | grep oacs -A 11

3.2.2 nvme id-ns·

获取命名空间的详细信息:

1
sudo nvme id-ns /dev/nvme0n1

重要字段:

  • nsze:命名空间大小(逻辑块数)
  • ncap:命名空间容量
  • nuse:命名空间使用量
  • nlbaf:支持的 LBA 格式数量
  • flbas:格式化的 LBA 大小
  • dps:端到端数据保护设置
  • nmic:命名空间多路径和共享能力
  • LBA Format:支持的 LBA 格式列表(扇区大小)

查看支持的 LBA 格式:

1
sudo nvme id-ns -H /dev/nvme0n1 | grep "LBA Format"

输出示例:

1
2
3
4
LBA Format  0 : Metadata Size: 0   bytes - Data Size: 512   bytes - Relative Performance: 0 Best (in use)
LBA Format 1 : Metadata Size: 8 bytes - Data Size: 512 bytes - Relative Performance: 0 Best
LBA Format 2 : Metadata Size: 0 bytes - Data Size: 4096 bytes - Relative Performance: 0 Best
LBA Format 3 : Metadata Size: 8 bytes - Data Size: 4096 bytes - Relative Performance: 0 Best

3.3 健康监控与日志·

3.3.1 nvme smart-log·

这是最常用的命令之一,用于监控设备健康状态、温度、磨损程度等:

1
sudo nvme smart-log /dev/nvme0n1

输出示例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
Smart Log for NVME device:nvme0n1 namespace-id:ffffffff
critical_warning : 0
temperature : 21 C
available_spare : 100%
available_spare_threshold : 10%
percentage_used : 2%
data_units_read : 5,749,452
data_units_written : 10,602,948
host_read_commands : 77,809,121
host_write_commands : 153,405,213
controller_busy_time : 756
power_cycles : 1,719
power_on_hours : 1,311
unsafe_shutdowns : 129
media_errors : 0
num_err_log_entries : 1,243
Warning Temperature Time : 0
Critical Composite Temperature Time : 0
Temperature Sensor 1 : 21 C
Temperature Sensor 2 : 22 C

关键字段解读:

  • critical_warning:关键警告位(非零表示有问题)

    • Bit 0: 可用备用空间低于阈值
    • Bit 1: 温度高于或低于阈值
    • Bit 2: 可靠性降级
    • Bit 3: 只读模式
    • Bit 4: 易失性内存备份失败
  • temperature:当前温度(摄氏度)

  • available_spare:可用备用空间百分比

  • percentage_used:磨损程度百分比(0-100%,这是最重要的寿命指标)

  • data_units_read/written:数据读写量(单位:512KB)

  • power_on_hours:通电时长

  • unsafe_shutdowns:非安全关机次数

  • media_errors:介质错误数

使用 -H 选项获得更详细的解释:

1
sudo nvme smart-log -H /dev/nvme0n1

3.3.2 nvme error-log·

获取错误日志页:

1
sudo nvme error-log /dev/nvme0n1

可以使用 grep 过滤特定错误:

1
sudo nvme error-log /dev/nvme0n1 | grep -i error

3.3.3 nvme fw-log·

查看固件更新历史:

1
sudo nvme fw-log /dev/nvme0

3.3.4 nvme get-log·

通用日志页获取命令,可以获取各种日志:

1
2
3
4
5
# 获取遥测日志
sudo nvme get-log /dev/nvme0 --log-id=7 --log-len=512

# 获取特定供应商日志
sudo nvme get-log /dev/nvme0 --log-id=0xC0 --log-len=4096

3.3.5 nvme telemetry-log·

获取主机发起的遥测日志:

1
sudo nvme telemetry-log /dev/nvme0 --output-file=telemetry.bin

3.3.6 nvme endurance-log·

查看耐久性日志(需设备支持):

1
sudo nvme endurance-log /dev/nvme0n1

3.4 固件管理·

3.4.1 nvme fw-download·

下载固件镜像到设备:

1
sudo nvme fw-download /dev/nvme0 --fw=firmware.bin

3.4.2 nvme fw-commit·

激活下载的固件(NVMe 1.2+ 使用此命令):

1
2
3
4
5
6
7
8
# 立即激活(重置后生效)
sudo nvme fw-commit /dev/nvme0 -s 0 -a 1

# 下次重置时激活
sudo nvme fw-commit /dev/nvme0 -s 0 -a 2

# 立即激活(无需重置)
sudo nvme fw-commit /dev/nvme0 -s 0 -a 3

参数说明:

  • -s, --slot:固件槽位(0-7)
  • -a, --action:激活动作
    • 0: 仅下载
    • 1: 下载并在下次重置时激活
    • 2: 激活指定槽位
    • 3: 激活指定槽位(立即生效)

3.4.3 nvme fw-activate·

旧版本(< NVMe 1.2)的固件激活命令。

3.5. 特性管理·

3.5.1 nvme get-feature·

获取设备特性:

1
2
3
4
5
6
7
8
# 获取所有特性
sudo nvme get-feature /dev/nvme0 --feature-id=0 --sel=0

# 获取易失性写缓存状态
sudo nvme get-feature /dev/nvme0 --feature-id=0x06

# 获取温度阈值
sudo nvme get-feature /dev/nvme0 --feature-id=0x04

常用特性 ID:

  • 0x01: Arbitration
  • 0x02: Power Management
  • 0x04: Temperature Threshold
  • 0x05: Error Recovery
  • 0x06: Volatile Write Cache
  • 0x07: Number of Queues
  • 0x0A: Write Atomicity

3.5.2 nvme set-feature·

设置设备特性:

1
2
3
4
5
# 启用易失性写缓存
sudo nvme set-feature /dev/nvme0 --feature-id=0x06 --value=1

# 设置温度阈值(例如 70°C = 343K)
sudo nvme set-feature /dev/nvme0 --feature-id=0x04 --value=343

3.6. 命名空间管理·

3.6.1 nvme create-ns·

创建新的命名空间:

1
sudo nvme create-ns /dev/nvme0 --nsze=2097152 --ncap=2097152 --flbas=0 --dps=0

参数说明:

  • --nsze:命名空间大小(逻辑块数)
  • --ncap:命名空间容量
  • --flbas:格式化 LBA 大小
  • --dps:数据保护设置

3.6.2 nvme delete-ns·

删除命名空间:

1
sudo nvme delete-ns /dev/nvme0 --namespace-id=2

3.6.3 nvme attach-ns·

将命名空间附加到控制器:

1
sudo nvme attach-ns /dev/nvme0 --namespace-id=1 --controllers=0

3.6.4 nvme detach-ns·

从控制器分离命名空间:

1
sudo nvme detach-ns /dev/nvme0 --namespace-id=1 --controllers=0

3.6.5 nvme list-ns·

列出所有命名空间 ID:

1
sudo nvme list-ns /dev/nvme0

3.6.6 nvme get-ns-id·

获取块设备的命名空间 ID:

1
nvme get-ns-id /dev/nvme0n1

3.7 格式化与安全擦除·

3.7.1 nvme format·

格式化命名空间,这是一个危险操作,会删除所有数据!

1
2
3
4
5
6
7
8
9
10
11
# 基本格式化(使用默认 LBA 格式)
sudo nvme format /dev/nvme0n1

# 指定 LBA 格式(例如切换到 4KB 扇区)
sudo nvme format /dev/nvme0n1 --lbaf=2

# 使用块大小指定格式
sudo nvme format /dev/nvme0n1 --block-size=4096

# 格式化时进行安全擦除
sudo nvme format /dev/nvme0n1 --ses=1

安全擦除选项(--ses):

  • 0: 不进行安全擦除(仅 TRIM/解除分配)
  • 1: 用户数据擦除(物理擦除,耗时较长)
  • 2: 加密擦除(更换加密密钥,快速完成)

格式化前检查支持的 LBA 格式:

1
sudo nvme id-ns -H /dev/nvme0n1 | grep "LBA Format"

3.7.2 nvme sanitize·

更彻底的数据清除操作:

1
2
3
4
5
6
7
8
9
10
11
# 块擦除
sudo nvme sanitize /dev/nvme0 --sanact=2

# 覆盖写入
sudo nvme sanitize /dev/nvme0 --sanact=3

# 加密擦除
sudo nvme sanitize /dev/nvme0 --sanact=4

# 退出失败模式
sudo nvme sanitize /dev/nvme0 --sanact=1

检查 sanitize 支持情况:

1
sudo nvme id-ctrl /dev/nvme0 | grep -i sanitize

查看 sanitize 状态:

1
sudo nvme sanitize-log /dev/nvme0

3.8. I/O 操作命令·

3.8.1 nvme read·

从命名空间读取数据:

1
sudo nvme read /dev/nvme0n1 --start-block=0 --block-count=8 --data-size=4096 --data=output.bin

3.8.2 nvme write·

向命名空间写入数据:

1
sudo nvme write /dev/nvme0n1 --start-block=0 --block-count=8 --data-size=4096 --data=input.bin

3.8.3 nvme compare·

比较命名空间数据与缓冲区:

1
sudo nvme compare /dev/nvme0n1 --start-block=0 --block-count=8 --data-size=4096 --data=compare.bin

3.8.4 nvme flush·

刷新易失性写缓存:

1
sudo nvme flush /dev/nvme0n1

3.8.5 nvme dsm·

数据集管理(包括 TRIM/Deallocate):

1
2
# TRIM 操作
sudo nvme dsm /dev/nvme0n1 --ad --slbs=0,1,2,3 --blocks=8,8,8,8

3.9. 性能与电源管理·

3.9.1 nvme reset·

重置 NVMe 控制器:

1
sudo nvme reset /dev/nvme0

3.9.2 nvme subsystem-reset·

重置子系统:

1
sudo nvme subsystem-reset /dev/nvme0

3.9.3 nvme show-regs·

显示控制器寄存器:

1
sudo nvme show-regs /dev/nvme0

可以查看特定寄存器:

1
2
3
4
5
# 控制器配置
sudo nvme get-property /dev/nvme0 --offset=0x14

# 控制器状态
sudo nvme get-property /dev/nvme0 --offset=0x1c

3.10. NVMe over Fabrics (NVMe-oF)·

3.10.1 nvme discover·

发现 NVMe-oF 目标:

1
2
3
4
5
6
7
8
# TCP 传输
sudo nvme discover -t tcp -a 192.168.1.100 -s 4420

# RDMA 传输
sudo nvme discover -t rdma -a 192.168.1.100 -s 4420

# FC 传输
sudo nvme discover -t fc -a nn-0x20000090fa17c141:pn-0x10000090fa17c141

3.10.2 nvme connect·

连接到 NVMe-oF 目标:

1
2
3
4
5
# 连接到 TCP 目标
sudo nvme connect -t tcp -n nqn.2021-08.com.example:subsystem1 -a 192.168.1.100 -s 4420

# 使用主机 NQN
sudo nvme connect -t tcp -n nqn.2021-08.com.example:subsystem1 -a 192.168.1.100 -s 4420 -q nqn.2021-08.com.example:host1

3.10.3 nvme connect-all·

自动连接所有发现的目标:

1
sudo nvme connect-all -t tcp -a 192.168.1.100

3.10.4 nvme disconnect·

断开 NVMe-oF 连接:

1
sudo nvme disconnect -n nqn.2021-08.com.example:subsystem1

断开所有连接:

1
sudo nvme disconnect-all

3.11. 高级和调试命令·

3.11.1 nvme admin-passthru·

发送任意管理命令:

1
sudo nvme admin-passthru /dev/nvme0 --opcode=0x06 --namespace-id=1 --data-len=4096 --cdw10=0 --cdw11=0

3.11.2 nvme io-passthru·

发送任意 I/O 命令:

1
sudo nvme io-passthru /dev/nvme0n1 --opcode=0x02 --namespace-id=1 --data-len=4096

3.11.3 nvme self-test·

执行设备自检:

1
2
3
4
5
# 短自检
sudo nvme device-self-test /dev/nvme0 --namespace-id=0xFFFFFFFF --self-test-code=1

# 长自检
sudo nvme device-self-test /dev/nvme0 --namespace-id=0xFFFFFFFF --self-test-code=2

查看自检日志:

1
sudo nvme self-test-log /dev/nvme0

3.12. 输出格式控制·

nvme-cli 支持多种输出格式,方便不同场景使用:

1
2
3
4
5
6
7
8
# JSON 格式(适合脚本解析)
sudo nvme list -o json

# 标准输出(默认)
sudo nvme list -o normal

# 二进制格式
sudo nvme id-ctrl /dev/nvme0 --raw-binary > id-ctrl.bin

4. 配置文件·

nvme-cli 支持持久化配置,配置文件位置:

  • 持久配置

    • /etc/nvme/discovery.conf(旧格式)
    • /etc/nvme/config.json(新格式,JSON)
  • 临时配置

    • /run/nvme/(易失性配置,用于协调工具间的访问)

JSON 配置示例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
[
{
"hostnqn": "nqn.2014-08.org.nvmexpress:uuid:242d4a24-2484-4a80-8234-d0169409c5e8",
"hostid": "242d4a24-2484-4a80-8234-d0169409c5e8",
"subsystems": [
{
"nqn": "nqn.2021-08.com.example:subsystem1",
"ports": [
{
"transport": "tcp",
"traddr": "192.168.1.100",
"trsvcid": "4420"
}
]
}
]
}
]

5. 供应商特定命令·

nvme-cli 支持众多供应商的扩展命令,通过插件机制实现。常见供应商插件:

5.1 Intel/Solidigm·

1
2
3
4
5
6
7
8
# Intel 温度统计
sudo nvme intel temp-stats /dev/nvme0

# Intel 市场名称
sudo nvme intel market-name /dev/nvme0

# Solidigm 遥测日志解析
sudo nvme solidigm parse-telemetry-log /dev/nvme0

5.2 Western Digital (WDC)·

1
2
3
4
5
6
7
8
# WDC 驱动日志
sudo nvme wdc drive-log /dev/nvme0

# WDC 智能日志
sudo nvme wdc cu-smart-log /dev/nvme0

# WDC 固件激活历史
sudo nvme wdc vs-fw-activate-history /dev/nvme0

5.3 Samsung·

1
2
3
4
5
# Samsung 扩展 SMART 日志
sudo nvme samsung smart-log-add /dev/nvme0

# Samsung 获取日志
sudo nvme samsung get-log /dev/nvme0

5.4 Micron·

1
2
3
4
5
# Micron 选择下载
sudo nvme micron select-download /dev/nvme0

# Micron 清除 PCIe 错误
sudo nvme micron clear-pcie-correctable-errors /dev/nvme0

6. 实用技巧与最佳实践·

6.1 健康监控脚本·

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
#!/bin/bash
# nvme-health-check.sh
DEVICE=$1

if [ -z "$DEVICE" ]; then
echo "Usage: $0 <nvme-device>"
exit 1
fi

echo "=== NVMe Health Check for $DEVICE ==="
echo

# 检查关键警告
CRITICAL_WARNING=$(sudo nvme smart-log $DEVICE | grep critical_warning | awk '{print $3}')
if [ "$CRITICAL_WARNING" != "0" ]; then
echo "WARNING: Critical warning detected: $CRITICAL_WARNING"
fi

# 检查温度
TEMP=$(sudo nvme smart-log $DEVICE | grep "^temperature" | awk '{print $3}')
echo "Current Temperature: ${TEMP}°C"

# 检查磨损程度
PERCENTAGE_USED=$(sudo nvme smart-log $DEVICE | grep percentage_used | awk '{print $3}' | tr -d '%')
echo "Wear Level: ${PERCENTAGE_USED}%"

if [ "$PERCENTAGE_USED" -gt 80 ]; then
echo "WARNING: Device wear level exceeds 80%"
fi

# 检查介质错误
MEDIA_ERRORS=$(sudo nvme smart-log $DEVICE | grep media_errors | awk '{print $3}')
echo "Media Errors: $MEDIA_ERRORS"

if [ "$MEDIA_ERRORS" -gt 0 ]; then
echo "WARNING: Media errors detected"
fi

# 检查非安全关机
UNSAFE_SHUTDOWNS=$(sudo nvme smart-log $DEVICE | grep unsafe_shutdowns | awk '{print $3}')
echo "Unsafe Shutdowns: $UNSAFE_SHUTDOWNS"

6.2 自动化监控集成·

将 nvme-cli 集成到监控系统(如 Prometheus、Nagios):

1
2
# 导出 JSON 格式供监控工具解析
sudo nvme smart-log -o json /dev/nvme0 | jq '.temperature, .percentage_used'

6.3 固件更新流程·

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
#!/bin/bash
# 安全的固件更新流程
DEVICE=/dev/nvme0
FIRMWARE=new_firmware.bin

# 1. 备份当前固件信息
sudo nvme fw-log $DEVICE > fw_log_before.txt

# 2. 下载固件
echo "Downloading firmware..."
sudo nvme fw-download $DEVICE --fw=$FIRMWARE

# 3. 提交并激活(下次重置时)
echo "Committing firmware..."
sudo nvme fw-commit $DEVICE -s 0 -a 1

# 4. 重置控制器
echo "Resetting controller..."
sudo nvme reset $DEVICE

# 5. 等待设备就绪
sleep 10

# 6. 验证固件版本
sudo nvme id-ctrl $DEVICE | grep fr
sudo nvme fw-log $DEVICE > fw_log_after.txt

6.4 性能调优·

1
2
3
4
5
6
7
8
# 检查队列深度
sudo nvme get-feature /dev/nvme0 --feature-id=0x07

# 启用易失性写缓存(提高性能)
sudo nvme set-feature /dev/nvme0 --feature-id=0x06 --value=1

# 设置电源状态(平衡性能和功耗)
sudo nvme set-feature /dev/nvme0 --feature-id=0x02 --value=0

6.5 安全擦除最佳实践·

完整的安全擦除流程:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
# 方法 1: 使用 Sanitize(推荐,2021+ 新设备)
sudo nvme sanitize /dev/nvme0 --sanact=2 # 块擦除

# 方法 2: 使用 Format + 安全擦除
sudo nvme format /dev/nvme0n1 --ses=1 # 用户数据擦除

# 方法 3: 加密擦除(最快)
sudo nvme format /dev/nvme0n1 --ses=2 # 加密擦除

# 方法 4: 完整的命名空间重建流程
# a. 分离命名空间
sudo nvme detach-ns /dev/nvme0 --namespace-id=1 --controllers=0

# b. 删除命名空间
sudo nvme delete-ns /dev/nvme0 --namespace-id=1

# c. 创建新命名空间
sudo nvme create-ns /dev/nvme0 --nsze=0xFFFFFFFF --ncap=0xFFFFFFFF --flbas=0

# d. 附加命名空间
sudo nvme attach-ns /dev/nvme0 --namespace-id=1 --controllers=0

# e. 重置设备
sudo nvme reset /dev/nvme0

6.6 故障排查·

1
2
3
4
5
6
7
8
9
10
11
12
13
14
# 检查设备是否可访问
sudo nvme list

# 查看详细错误信息
sudo nvme error-log /dev/nvme0

# 检查控制器寄存器
sudo nvme show-regs /dev/nvme0

# 查看内核日志
dmesg | grep -i nvme

# 验证驱动版本
modinfo nvme

7. 常见使用场景·

7.1:数据中心设备健康监控·

1
2
3
4
5
6
7
8
9
10
11
# 定期检查所有 NVMe 设备
for device in $(nvme list | grep /dev/nvme | awk '{print $1}'); do
echo "Checking $device"
sudo nvme smart-log -o json $device | jq '{
device: "'$device'",
temperature: .temperature,
percentage_used: .percentage_used,
media_errors: .media_errors,
critical_warning: .critical_warning
}'
done

7.2:固件批量更新·

1
2
3
4
5
6
7
8
9
# 批量更新同型号设备
MODEL="SAMSUNG MZVLB256"
FIRMWARE="firmware.bin"

for device in $(nvme list | grep "$MODEL" | awk '{print $1}' | sed 's/n.*//'); do
echo "Updating $device"
sudo nvme fw-download $device --fw=$FIRMWARE
sudo nvme fw-commit $device -s 0 -a 1
done

7.3:性能基准测试准备·

1
2
3
4
5
6
7
8
9
# 1. 确保设备使用最佳 LBA 格式
sudo nvme id-ns -H /dev/nvme0n1 | grep "Relative Performance: 0 Best"

# 2. 启用写缓存
sudo nvme set-feature /dev/nvme0 --feature-id=0x06 --value=1

# 3. 预处理(写入满盘)
sudo fio --name=preconditioning --filename=/dev/nvme0n1 \
--rw=write --bs=128k --iodepth=32 --size=100%

7.4:NVMe-oF 存储部署·

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
# 服务端配置(target)
sudo modprobe nvmet
sudo modprobe nvmet-tcp

# 创建子系统
mkdir -p /sys/kernel/config/nvmet/subsystems/subsys1
echo 1 > /sys/kernel/config/nvmet/subsystems/subsys1/attr_allow_any_host

# 配置命名空间
mkdir -p /sys/kernel/config/nvmet/subsystems/subsys1/namespaces/1
echo /dev/nvme0n1 > /sys/kernel/config/nvmet/subsystems/subsys1/namespaces/1/device_path
echo 1 > /sys/kernel/config/nvmet/subsystems/subsys1/namespaces/1/enable

# 创建端口
mkdir -p /sys/kernel/config/nvmet/ports/1
echo tcp > /sys/kernel/config/nvmet/ports/1/addr_trtype
echo 192.168.1.100 > /sys/kernel/config/nvmet/ports/1/addr_traddr
echo 4420 > /sys/kernel/config/nvmet/ports/1/addr_trsvcid

# 客户端连接
sudo nvme discover -t tcp -a 192.168.1.100 -s 4420
sudo nvme connect -t tcp -n subsys1 -a 192.168.1.100 -s 4420
1
2
3
4
5
6
7
8
9
10
11
12
# 客户端扫描并发现 nvme target
sudo nvme discover -t tcp -a 10.2.1.33 -s 4420

# 客户端使用 tcp 挂载
sudo nvme connect \
-t tcp \
-a h12-truenas \
-s 4420 \
-n nqn.2019-08.cn.littlenewton:uuid:fe3a0ec3-6085-4231-98ea-1d023f27e2d3:synology-abb

# 客户端主动断开连接 (需要先 umount)
sudo nvme s -n nqn.2019-08.cn.littlenewton:uuid:fe3a0ec3-6085-4231-98ea-1d023f27e2d3:test-nvme

8. 与 NVMe 规范的对应关系·

nvme-cli 的一大优势是其输出直接对应 NVMe 规范。以下是一些关键映射:

nvme-cli 命令 NVMe 规范对应 Admin Command Opcode
id-ctrl Identify (CNS=01h) 06h
id-ns Identify (CNS=00h) 06h
smart-log Get Log Page (LID=02h) 02h
error-log Get Log Page (LID=01h) 02h
fw-log Get Log Page (LID=03h) 02h
get-feature Get Features 0Ah
set-feature Set Features 09h
format Format NVM 80h
fw-download Firmware Image Download 11h
fw-commit Firmware Commit 10h
create-ns Namespace Management (SEL=0) 0Dh
delete-ns Namespace Management (SEL=1) 0Dh
attach-ns Namespace Attachment (SEL=0) 15h
detach-ns Namespace Attachment (SEL=1) 15h

所有输出字段的缩写都可以在 NVMe 规范中找到对应说明。例如:

  • OACS:Optional Admin Command Support
  • ONCS:Optional NVM Command Support
  • SQES:Submission Queue Entry Size
  • CQES:Completion Queue Entry Size

9. 社区与贡献·

nvme-cli 是一个活跃的开源项目:

贡献方式:

  1. 提交 Pull Request 到 GitHub
  2. 发送补丁到邮件列表
  3. 遵循 Linux 内核贡献指南

10. 总结·

nvme-cli 是 Linux 下管理 NVMe 设备的标准工具,具有以下特点:

优势

  • 完全符合 NVMe 规范,输出直接对应规范定义
  • 功能全面,涵盖设备管理的方方面面
  • 活跃的社区支持和持续更新
  • 主流发行版内置支持
  • 支持供应商扩展插件
  • 多种输出格式(人类可读、JSON、二进制)
  • 支持 NVMe-oF(网络存储)

关键应用场景

  • 日常设备健康监控
  • 固件更新管理
  • 性能调优配置
  • 数据安全擦除
  • 命名空间管理
  • 故障诊断与日志分析
  • NVMe-oF 存储部署

最佳实践

  • 定期检查 SMART 日志,监控设备健康
  • 谨慎使用 format 和 sanitize 命令
  • 固件更新前做好备份和验证
  • 将监控集成到自动化系统
  • 参考 NVMe 规范理解输出含义
  • 使用 JSON 输出便于脚本化处理

无论是数据中心管理员、系统工程师还是存储开发者,nvme-cli 都是不可或缺的工具。通过深入掌握其功能,可以更好地发挥 NVMe 设备的性能潜力,确保存储系统的稳定可靠运行。

参考资源·

  1. 官方文档

    • nvme-cli GitHub: https://github.com/linux-nvme/nvme-cli
    • NVMe 规范: https://nvmexpress.org
    • Linux 内核文档: https://www.kernel.org/doc/html/latest/
  2. 手册页

    • man nvme
    • man nvme-<command> (例如:man nvme-smart-log
  3. 社区资源

    • Linux NVMe 邮件列表: [email protected]
    • NVMe Express 组织: https://nvmexpress.org
    • GitHub Issues: https://github.com/linux-nvme/nvme-cli/issues
  4. 相关工具

    • libnvme: NVMe 协议库
    • fio: I/O 性能测试工具
    • blktrace: 块设备追踪工具
    • smartmontools: SMART 监控工具

本文基于 nvme-cli 2.x 版本编写,具体命令输出和可用选项可能因版本而异。建议使用 nvme help 和相应的手册页获取最新信息。