[pve-devel] [PATCH qemu-server 1/2] add support for nvme emulation

Oguz Bektas o.bektas at proxmox.com
Wed May 13 17:36:33 CEST 2020


now we can add nvme drives;

nvme0: local-lvm:vm-103-disk-0,size=32G

max number is 8

Signed-off-by: Oguz Bektas <o.bektas at proxmox.com>
---
 PVE/QemuServer.pm       | 20 +++++++++++++++++---
 PVE/QemuServer/Drive.pm | 21 +++++++++++++++++++++
 2 files changed, 38 insertions(+), 3 deletions(-)

diff --git a/PVE/QemuServer.pm b/PVE/QemuServer.pm
index dcf05df..441d209 100644
--- a/PVE/QemuServer.pm
+++ b/PVE/QemuServer.pm
@@ -406,7 +406,7 @@ EODESC
 	optional => 1,
 	type => 'string', format => 'pve-qm-bootdisk',
 	description => "Enable booting from specified disk.",
-	pattern => '(ide|sata|scsi|virtio)\d+',
+	pattern => '(ide|sata|scsi|virtio|nvme)\d+',
     },
     smp => {
 	optional => 1,
@@ -1424,7 +1424,11 @@ sub print_drivedevice_full {
 	    $device .= ",rotation_rate=1";
 	}
 	$device .= ",wwn=$drive->{wwn}" if $drive->{wwn};
-
+    } elsif ($drive->{interface} eq 'nvme') {
+	my $maxdev = $PVE::QemuServer::Drive::MAX_NVME_DISKS;
+	my $path = $drive->{file};
+	$drive->{serial} = "$drive->{interface}$drive->{index}"; # serial is mandatory for nvme
+	$device = "nvme,drive=drive-$drive->{interface}$drive->{index}";
     } elsif ($drive->{interface} eq 'ide' || $drive->{interface} eq 'sata') {
 	my $maxdev = ($drive->{interface} eq 'sata') ? $PVE::QemuServer::Drive::MAX_SATA_DISKS : 2;
 	my $controller = int($drive->{index} / $maxdev);
@@ -2157,7 +2161,7 @@ sub parse_vm_config {
 	    } else {
 		$key = 'ide2' if $key eq 'cdrom';
 		my $fmt = $confdesc->{$key}->{format};
-		if ($fmt && $fmt =~ /^pve-qm-(?:ide|scsi|virtio|sata)$/) {
+		if ($fmt && $fmt =~ /^pve-qm-(?:ide|scsi|virtio|sata|nvme)$/) {
 		    my $v = parse_drive($key, $value);
 		    if (my $volid = filename_to_volume_id($vmid, $v->{file}, $v->{media})) {
 			$v->{file} = $volid;
@@ -3784,7 +3788,17 @@ sub vm_deviceplug {
 	    warn $@ if $@;
 	    die $err;
         }
+    } elsif ($deviceid =~ m/^(nvme)(\d+)$/) {
+
+        qemu_driveadd($storecfg, $vmid, $device);
 
+	my $devicefull = print_drivedevice_full($storecfg, $conf, $vmid, $device, $arch, $machine_type);
+	eval { qemu_deviceadd($vmid, $devicefull); };
+	if (my $err = $@) {
+	    eval { qemu_drivedel($vmid, $deviceid); };
+	    warn $@ if $@;
+	    die $err;
+        }
     } elsif ($deviceid =~ m/^(net)(\d+)$/) {
 
 	return undef if !qemu_netdevadd($vmid, $conf, $arch, $device, $deviceid);
diff --git a/PVE/QemuServer/Drive.pm b/PVE/QemuServer/Drive.pm
index f84333f..b8a553a 100644
--- a/PVE/QemuServer/Drive.pm
+++ b/PVE/QemuServer/Drive.pm
@@ -27,6 +27,7 @@ PVE::JSONSchema::register_standard_option('pve-qm-image-format', {
 
 my $MAX_IDE_DISKS = 4;
 my $MAX_SCSI_DISKS = 31;
+my $MAX_NVME_DISKS = 8;
 my $MAX_VIRTIO_DISKS = 16;
 our $MAX_SATA_DISKS = 6;
 our $MAX_UNUSED_DISKS = 256;
@@ -275,6 +276,20 @@ my $scsidesc = {
 };
 PVE::JSONSchema::register_standard_option("pve-qm-scsi", $scsidesc);
 
+my $nvme_fmt = {
+    %drivedesc_base,
+    %ssd_fmt,
+    %wwn_fmt,
+};
+
+my $nvmedesc = {
+    optional => 1,
+    type => 'string', format => $nvme_fmt,
+    description => "Use volume as NVME disk (n is 0 to " . ($MAX_NVME_DISKS -1) . ").",
+};
+
+PVE::JSONSchema::register_standard_option("pve-qm-nvme", $nvmedesc);
+
 my $sata_fmt = {
     %drivedesc_base,
     %ssd_fmt,
@@ -364,6 +379,11 @@ for (my $i = 0; $i < $MAX_SCSI_DISKS; $i++)  {
     $drivedesc_hash->{"scsi$i"} = $scsidesc;
 }
 
+for (my $i = 0; $i < $MAX_NVME_DISKS; $i++)  {
+    $drivedesc_hash->{"nvme$i"} = $nvmedesc;
+}
+
+
 for (my $i = 0; $i < $MAX_VIRTIO_DISKS; $i++)  {
     $drivedesc_hash->{"virtio$i"} = $virtiodesc;
 }
@@ -380,6 +400,7 @@ sub valid_drive_names {
             (map { "scsi$_" } (0 .. ($MAX_SCSI_DISKS - 1))),
             (map { "virtio$_" } (0 .. ($MAX_VIRTIO_DISKS - 1))),
             (map { "sata$_" } (0 .. ($MAX_SATA_DISKS - 1))),
+            (map { "nvme$_" } (0 .. ($MAX_NVME_DISKS - 1))),
             'efidisk0');
 }
 
-- 
2.20.1




More information about the pve-devel mailing list