Lightnvm的原作者在文档中给出了两种实现方式,第一种是使用真实设备,比如CNEX公司,华为公司的Open-channel SSD,价格昂贵。第二种方式就是本文将要介绍的,使用QEMU的方式,向主机侧提供一个模拟的支持open channel功能的nvme设备。实际上qemu中仅仅是模拟了NVMe specification 1.2.1的HCI的功能逻辑,并且作者增加了支持lightnvm的扩展,让主机端的驱动程序以为下面是一个真实的设备,这样一种方式就提供了一个快速,便捷地体验Lightnvm的方式 : )
下面是我的配置过程。

配置环境

  • host: Centos 7.6
  • guest: ubuntu 18.04 on nvme-qemu.

在主机端安装nvme-qemu

  • 克隆增加lightnvm支持的分支,nvme-qemu(https://github.com/OpenChannelSSD/qemu-nvme)
    $ git clone https://github.com/OpenChannelSSD/qemu-nvme.git

  • 编译QEMU源码,并且安装,需要注意的是 ,qemu需要安装在Linux主机下。在笔者电脑上,发现已安装glusterfs的头文件与nvme-qemu调用的参数不匹配(可能是glusterfs版本不匹配),因而关闭了对glusterfs的支持。

    1
    2
    3
    $ ./configure --python=/usr/bin/python2 --enable-kvm --target-list=x86_64-softmmu --enable-linux-aio --prefix=(安装的目录,如$HOME/qemu-nvme) --disable-glusterfs
    $ make -j8
    $ make install

创建QEMU虚拟机

1. 创建一个空白的磁盘文件

$ qemu-img create -f qcow2 ubuntu.qcow2 20G

虚拟机的最大空间为20G,qcow2格式,空间动态增长

2. 下载新版本的Ubuntu镜像

下载Ubuntu 18.04 64位桌面版。

1
$ wget https://releases.ubuntu.com/18.04.5/ubuntu-18.04.5-desktop-amd64.iso

3. 在该磁盘文件中安装Ubuntu系统。

1
$ qemu-system-x86_64 -m 2G -enable-kvm ubuntu.qcow2 -cdrom ~/ubuntu-18.04.5-desktop-amd64.iso

这一步遇到了一些问题。笔者用xshell连接服务器主机,并在服务器上运行QEMU虚拟机。在这一步出现报错:

1
2
3
4
5
6
7
8
9
10
11
12
ALSA lib pulse.c:243:(pulse_connect) PulseAudio: Unable to connect: Connection refused

alsa: Could not initialize DAC
alsa: Failed to open `default':
alsa: Reason: Connection refused
ALSA lib pulse.c:243:(pulse_connect) PulseAudio: Unable to connect: Connection refused

alsa: Could not initialize DAC
alsa: Failed to open `default':
alsa: Reason: Connection refused
audio: Failed to create voice `pcspk'
qemu-system-x86_64: Initialization of device isa-pcspk failed: Initializing audio voice failed

看注释是找不到音频输出。我在尝试了多个版本后,发现只有最近的master版本有这个问题(commit head = b6fb7eb1e9d708b920f24b559c503e68d0eb0329)。google答案后,修改了环境变量。

1
2
3
4
[root@localhost OCSSD_vm]# export QEMU_AUDIO_DRV=none
[root@localhost OCSSD_vm]# $ qemu-system-x86_64 -m 2G -enable-kvm ubuntu.qcow2 -cdrom ~/ubuntu.iso
VNC server running on ::1:5900

QEMU会默认创建VNC服务,等待客户端连接后,客户端处能够对虚拟机具体操作。因而打开另一个主机的shell窗口,安装vncviewer,使用vncviewer连接。注意,这里连接后会直接打开一个图形窗口,因而正常显示需要安装xmanager

1
$ apt install vncviewer -y

Xmanager 破解版链接:https://pan.baidu.com/s/1AjcVwoh4euAzxe34bPwghw 密码:g8me

打开图形界面后,完成正常的ubuntu安装流程。

加载含有LightNVM模块的内核

这一步笔者查阅了很多博客,尝试使用qemu更换内核,但总会产生奇怪的结果。比如使用qemu加载新内核后无法识别根目录,引入initrd后读取不到系统镜像等等。

经过几天挣扎,最后在快要放弃的时候,发现Ubuntu 18.06原系统的/dev/路径下有一个小小的,不起眼的虚拟设备:lightnvm。

!!????

OK,笔者电脑上Ubuntu18.06的内核(5.4.0-42-generic)已经安装了lightnvm的内核模块,不需要更换。因而直接进入下面流程。(所以不能完全参照博客,很多内容已经过期了)。

创建Virtual OCSSD块设备

这一步大部分博客的方法都过期,可以直接参考github上的说明。

在主机端创建OCSSD镜像。(2 group,每个group有)

1
$ qemu-img create -f ocssd -o num_grp=2,num_pu=4,num_chk=60 ocssd.img

关于create参数的详情,用help查看。

1
$ qemu-img create -f ocssd -o help

创建完成后,添加到虚拟机上并运行

1
$ /usr/qemu-nvme/bin/qemu-system-x86_64 -m 4G -enable-kvm ./ubuntu.qcow2 -blockdev ocssd,node-name=nvme01,file.driver=file,file.filename=ocssd.img -device nvme,drive=nvme01,serial=deadbeef,id=lnvm

继续使用vncviewer打开虚拟机,准备安装liblightnvm。

安装liblightnvm

进入虚拟机,首先安装nvme-cli

1
$ sudo apt-get install nvme-cli

列出所有nvme设备。此处显示我们刚添加的nvme0n1。

1
2
3
$ sudo nvme lnvm list
Device Block manager Version
nvme0n1 gennvm (1,0,0)

接下来安装liblightnvm

1
2
3
4
5
6
$ git clone https://github.com/OpenChannelSSD/liblightnvm.git
$ cd liblightnvm
$ sudo apt install cmake libcunit1-dev
$ make configure
$ make
$ sudo make install

完成安装后,可以使用测试的helloworld代码验证。(代码在liblightnvm/doc/src/quick_start/hello.c文件中)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#include <stdio.h>
#include <liblightnvm.h>

int main(int argc, char **argv)
{
struct nvm_dev *dev = nvm_dev_open("/dev/nvme0n1");
if (!dev) {
perror(“nvm_dev_open”);
return 1;
}
nvm_dev_pr(dev);
nvm_dev_close(dev);

return 0;
}

将上面的代码保存为 hello.c
然后编译:

1
$ gcc hello.c -fopenmp -llightnvm -o hello

并运行

1
$ sudo ./hello

得到输出。该输出与命令行中使用nvme-cli指令一致。

1
$ nvm_dev info /dev/nvme0n1

输出为:

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
42
43
44
45
46
47
48
49
50
# Device information -- nvm_dev_pr
dev_attr:
verid: 0x02
be_id: 0x01
be_name: 'NVM_BE_IOCTL'
name: 'nvme0n1'
path: '/dev/nvme0n1'
fd: 3
ssw: 12
mccap: '00000000000000000000000000000001'
bbts_cached: 0
quirks: '00000000'
dev_geo:
verid: 0x02
npugrp: 8
npunit: 4
nchunk: 1474
nsectr: 6144
nbytes: 4096
nbytes_oob: 16
tbytes: 1187021586432
tmbytes: 1132032
dev_cmd_opts:
mask: '00000000000000000000000011001000'
iomd: 'SYNC'
addr: 'VECTOR'
plod: 'PRP'
dev_vblk_opts:
pmode: 'SNGL'
erase_naddrs_max: 64
read_naddrs_max: 64
write_naddrs_max: 64
meta_mode: 0
dev_ppaf: ~
dev_ppaf_mask: ~
dev_lbaf:
pugrp: 3
punit: 2
chunk: 11
sectr: 13
dev_lbaz:
pugrp: 26
punit: 24
chunk: 13
sectr: 0
dev_lbam:
pugrp: '0000000000000000000000000000000000011100000000000000000000000000'
punit: '0000000000000000000000000000000000000011000000000000000000000000'
chunk: '0000000000000000000000000000000000000000111111111110000000000000'
sectr: '0000000000000000000000000000000000000000000000000001111111111111'

参考:

  1. Ubuntu搭建使用LightNVM开发Open Channel SSD的QEMU虚拟机
  2. Virtual OCSSD实验平台搭建
  3. openchannelssd
  4. liblightnvm
  5. github: qemu-nvme
  6. xmanager 5 破解版,有需要自己下载
  7. xshell远程qemu-kvm虚拟机安装