[pve-devel] [PATCH] add virtio-scsi controller and disks

Alexandre Derumier aderumier at odiso.com
Fri Jul 20 14:37:45 CEST 2012


This add the new virtio-scsi controller support.
http://wiki.qemu.org/Features/VirtioSCSI

Guest need kernel >= 3.4 to support. Windows drivers are also available in last virtio-win

Advantages :

- true scsi controller.(like lsi but a lot faster, around 5% slower than virtio-blk)
- multiples disk by controller (I set 100 max disk, but it could be more in theory)
- scsi passthrough
- discard support (great for ssd or thinp storages)
- bootable

Hotplug is not yet available in 1.1. (already available in git)

proxmox vm config syntax:

virtioscsi0:
virtioscsi1:
virtioscsi2:
virtioscsin:

lun assignement on the virtio-scsi controller is mapped on drive index.
virtioscsi0 = lun0 , virtioscsi1 = lun1, ...

Signed-off-by: Alexandre Derumier <aderumier at odiso.com>
---
 PVE/QemuServer.pm |   27 +++++++++++++++++++++++++--
 1 files changed, 25 insertions(+), 2 deletions(-)

diff --git a/PVE/QemuServer.pm b/PVE/QemuServer.pm
index 1a4daac..7c59f10 100644
--- a/PVE/QemuServer.pm
+++ b/PVE/QemuServer.pm
@@ -396,6 +396,7 @@ while (my ($k, $v) = each %$confdesc) {
 my $MAX_IDE_DISKS = 4;
 my $MAX_SCSI_DISKS = 14;
 my $MAX_VIRTIO_DISKS = 6;
+my $MAX_VIRTIOSCSI_DISKS = 100;
 my $MAX_SATA_DISKS = 6;
 my $MAX_USB_DEVICES = 5;
 my $MAX_NETS = 6;
@@ -475,6 +476,14 @@ my $virtiodesc = {
 };
 PVE::JSONSchema::register_standard_option("pve-qm-virtio", $virtiodesc);
 
+my $virtioscsidesc = {
+    optional => 1,
+    type => 'string', format => 'pve-qm-drive',
+    typetext => '[volume=]volume,] [,media=cdrom|disk] [,cyls=c,heads=h,secs=s[,trans=t]] [,snapshot=on|off] [,cache=none|writethrough|writeback|unsafe|directsync] [,format=f] [,backup=yes|no] [,rerror=ignore|report|stop] [,werror=enospc|ignore|report|stop] [,aio=native|threads]',
+    description => "Use volume as VIRTIO hard disk (n is 0 to 256).",
+};
+PVE::JSONSchema::register_standard_option("pve-qm-virtioscsi", $virtioscsidesc);
+
 my $usbdesc = {
     optional => 1,
     type => 'string', format => 'pve-qm-usb-device',
@@ -570,6 +579,11 @@ for (my $i = 0; $i < $MAX_VIRTIO_DISKS; $i++)  {
     $confdesc->{"virtio$i"} = $virtiodesc;
 }
 
+for (my $i = 0; $i < $MAX_VIRTIOSCSI_DISKS; $i++)  {
+    $drivename_hash->{"virtioscsi$i"} = 1;
+    $confdesc->{"virtioscsi$i"} = $virtioscsidesc;
+}
+
 for (my $i = 0; $i < $MAX_USB_DEVICES; $i++)  {
     $confdesc->{"usb$i"} = $usbdesc;
 }
@@ -627,6 +641,7 @@ sub disknames {
     return ((map { "ide$_" } (0 .. ($MAX_IDE_DISKS - 1))),
             (map { "scsi$_" } (0 .. ($MAX_SCSI_DISKS - 1))),
             (map { "virtio$_" } (0 .. ($MAX_VIRTIO_DISKS - 1))),
+            (map { "virtioscsi$_" } (0 .. ($MAX_VIRTIOSCSI_DISKS - 1))),
             (map { "sata$_" } (0 .. ($MAX_SATA_DISKS - 1))));
 }
 
@@ -970,7 +985,7 @@ sub print_drivedevice_full {
     if ($drive->{interface} eq 'virtio') {
 	my $pciaddr = print_pci_addr("$drive->{interface}$drive->{index}");
 	$device = "virtio-blk-pci,drive=drive-$drive->{interface}$drive->{index},id=$drive->{interface}$drive->{index}$pciaddr";
-    } elsif ($drive->{interface} eq 'scsi') {
+    } elsif ($drive->{interface} eq 'scsi' || $drive->{interface} eq 'virtioscsi') {
 	$maxdev = 7;
 	my $controller = int($drive->{index} / $maxdev);
 	my $unit = $drive->{index} % $maxdev;
@@ -987,7 +1002,8 @@ sub print_drivedevice_full {
 	      $devicetype = 'block' if path_is_scsi($path);
          }
 
-	$device = "scsi-$devicetype,bus=lsi$controller.0,scsi-id=$unit,drive=drive-$drive->{interface}$drive->{index},id=$drive->{interface}$drive->{index}";
+	$device = "scsi-$devicetype,bus=lsi$controller.0,scsi-id=$unit,drive=drive-$drive->{interface}$drive->{index},id=$drive->{interface}$drive->{index}" if $drive->{interface} eq 'scsi';
+	$device = "scsi-$devicetype,bus=virtioscsipci0.0,channel=0,scsi-id=0,lun=$drive->{index},drive=drive-$drive->{interface}$drive->{index},id=$drive->{interface}$drive->{index}" if $drive->{interface} eq 'virtioscsi';
     } elsif ($drive->{interface} eq 'ide'){
 	$maxdev = 2;
 	my $controller = int($drive->{index} / $maxdev);
@@ -2266,6 +2282,7 @@ sub config_to_command {
 
     my $vollist = [];
     my $scsicontroller = {};
+    my $virtioscsicontroller = undef;
     my $ahcicontroller = {};
 
     foreach_drive($conf, sub {
@@ -2297,6 +2314,11 @@ sub config_to_command {
            $scsicontroller->{$controller}=1;
         }
 
+        if ($drive->{interface} eq 'virtioscsi') {
+           push @$cmd, '-device', "virtio-scsi-pci,id=virtioscsipci0$pciaddr" if !$virtioscsicontroller;
+           $virtioscsicontroller = 1;
+        }
+
         if ($drive->{interface} eq 'sata') {
            my $controller = int($drive->{index} / $MAX_SATA_DISKS);
            $pciaddr = print_pci_addr("ahci$controller");
@@ -3027,6 +3049,7 @@ sub print_pci_addr {
 	lsi0 => { bus => 0, addr => 5 },
 	lsi1 => { bus => 0, addr => 6 },
 	ahci0 => { bus => 0, addr => 7 },
+	virtioscsipci0 => { bus => 0, addr => 8 },
 	virtio0 => { bus => 0, addr => 10 },
 	virtio1 => { bus => 0, addr => 11 },
 	virtio2 => { bus => 0, addr => 12 },
-- 
1.7.2.5




More information about the pve-devel mailing list