PATCH/HACK : hotplug support for disk and nic

spirit

Distinguished Member
Apr 2, 2010
6,802
990
243
www.groupe-cyllene.com
Hi, this is my first attempt to implement hotplug pci devices (disk and nic).

- i've tested disk hotplug with disk image on lvm and iscsi disk. (no file image)
- disk hotplug only works with virtio and iscsi disks.
- nic hotplug works with all models

For the moment only hotplug works, but not un-hotplug.
so with my patch, you can't remove a disk or nic on a running vm, only when the vm is shutdown.


for unplug, we need to have pci slot id defined for each device, but to do that, we need to add a random slotid in the configuration file for each device (videocard,nic,disk,serial,..)

something like, domain='0x0000' bus='0x00' slot='0x01'. as new attributes.
more info here :
http://fedoraproject.org/wiki/Features/KVM_Stable_PCI_Addresses
http://fedoraproject.org/wiki/KVM_Stable_PCI_Addresses_Design_Notes

code is beta for moment,
I dont verify the return of the hotplug, code can be proper.

I have tried to not modified the soap method, so code is a bit tricky to detect add/remove of a nic in the qm set method. (because when we add a new nic , we resend the vlan of the nic with all nics).

ex:
vlan0: virtio=1E:E8:38:0B:D3:ED,e1000=5A:6C:2B:58:27:70
vlan100: e1000=36:92:44:20:E3:AC

i think it'll be better to have 1 line by nic in conf file
something like:

nic1:vlan=0,mac=1E:E8:38:0B:D3:ED,model=virtio,slot='0x01'
nic2:vlan=0,mac=5A:6C:2B:58:27:70,model=e1000,slot='0x02'
nic3:vlan=100,mac=36:92:44:20:E3:AC,model=e1000,slot='0x03'

more easy to add/remove (and modify) nic.



here the diffs:


/usr/sbin/qm
Code:
--- /root/origprox/qm   2010-11-01 14:51:25.000000000 +0100
+++ /usr/sbin/qm        2010-11-03 10:26:56.000000000 +0100
@@ -260,6 +260,7 @@
                delete ($disk->{format}); # no longer needed
                push @$vollist, $volid;
                $settings->{$ds} = PVE::QemuServer::print_drive ($vmid, $disk);
+               $disk->{path} = PVE::Storage::path ($storecfg, $disk->{file});
            } else {
                my $path;
                if ($disk->{file} =~ m|^/dev/.+|) {
@@ -270,7 +271,9 @@
                if (!(-f $path || -b $path)) {
                    die "image '$path' does not exists\n";
                }
+               $disk->{path}=$path;
            }
+           $qm->vm_pciadd ($vmid,"disk", $disk);
        }
     };
 
@@ -306,6 +309,7 @@
        PVE::QemuServer::check_lock ($conf) if !$skiplock;
 
        my $unset = {};
+       my $cannot_delete_devices=0;
        foreach my $opt (keys %$settings) {
            my $value = $settings->{$opt};
            next if !defined ($value);
@@ -325,14 +329,76 @@
                $unset->{$opt} = 1;
                delete $settings->{$opt};
            }
+
+           #case is a disk, cant delete for the moment
+           if($conf->{diskinfo}->{$opt}){
+             $cannot_delete_devices=1;
+           }
+
+           #case is a vlan nic list
+           if ($opt =~ m/^vlan(\d+|u)$/){
+
+               my $vlanid;
+               if($opt =~ m/(\d+)/) {
+                 $vlanid = int ($1);
+               }
+
+               my $vlan = PVE::QemuServer::parse_vlan ($settings->{$opt});
+               #disable vlan removal for the moment (opt=undef)
+               if (!$vlan){
+                 $cannot_delete_devices=1;
+                 next;
+               }
+               #need to get conf, to compare vlan change (nic add or remove)
+               my $oldvlan=PVE::QemuServer::parse_vlan ($conf->{$opt});
+               next if !$oldvlan;
+
+               my $oldnic_list=$oldvlan->{nics};
+               my $nic_list=$vlan->{nics};
+               my $nic;
+
+               #search nic to add if nic_list sent > niclist from conf)
+               if(@$nic_list > @$oldnic_list){
+                 #check nic hotplug on this vlan
+                 foreach my $nic (@$nic_list) {
+                     foreach my $oldnic (@$oldnic_list) {
+                       if($nic->{macaddr} eq $oldnic->{macaddr}) {
+                           $nic->{exist}=1;
+                       }
+                     }
+                   
+                   if(!$nic->{exist}) {
+                       $nic->{vlanid}=$vlanid;
+                       $qm->vm_pciadd ($vmid,'nic', $nic);
+                   }
+                 }
+               }
+               #search nic to remove if nic_list sent < niclist from conf)
+               elsif(@$nic_list < @$oldnic_list){
+                   $cannot_delete_devices=1;
+                   #check nic hot-unplug  on this vlan
+                   foreach my $oldnic (@$oldnic_list) {
+                       foreach my $nic (@$nic_list) {
+                         if($oldnic->{macaddr} eq $nic->{macaddr}) {
+                             $oldnic->{exist}=1;
+                         }
+
+                       }
+                       if(!$oldnic->{exist}) {
+                         $nic->{vlanid}=$vlanid;
+                         #$qm->vm_pcidel ($vmid,"nic", "pci_id");  #disable for the moment
+                       }
+                   }
+               }
+           }
        }
 
        add_random_macs ($settings);
 
        create_disks ($qm->{storecfg}, $vmid, $settings);
-
+       unless ($cannot_delete_devices == 1 && PVE::QemuServer::check_running($vmid)){
        PVE::QemuServer::change_config_nolock  ($vmid, $settings, $unset, 1);
-
+       }
     });
 
     my $err = $@;


/usr/share/perl5/PVE/QemuServer.pm

Code:
--- /root/origprox/PVE/QemuServer.pm    2010-10-13 11:55:00.000000000 +0200
+++ /usr/share/perl5/PVE/QemuServer.pm  2010-11-03 10:22:33.000000000 +0100
@@ -1964,6 +1964,61 @@
     die $@ if $@;
 }
 
+sub vm_pciadd {
+    my ($self, $vmid,$type, $params) = @_;
+
+    my $filename = PVE::QemuServer::config_file ($vmid);
+
+    return unless -f $filename;
+
+    lock_config ($vmid, sub {
+
+       return if !check_running ($vmid); # do nothing
+
+       my $conf = $self->load_config ($vmid);
+
+       check_lock ($conf);
+
+       if($type eq "disk")
+       {
+               unless ( $params->{interface} eq 'ide'){
+                $self->vm_monitor_command ($vmid, "pci_add auto storage file=".$params->{path}.",if=".$params->{interface}."", 1);
+               }
+       }
+       elsif($type eq "nic")
+       {
+               #pci_add bus nic[[vlan=n][,macaddr=addr][,model=type]]
+               $self->vm_monitor_command ($vmid, "pci_add auto nic vlan=".$params->{vlanid}.",macaddr=".$params->{macaddr}.",model=".$params->{model}."", 1);
+       }
+           
+    });
+
+    die $@ if $@;
+}
+
+sub vm_pcidel {
+    my ($self, $vmid,$pci_id) = @_;
+
+
+    my $filename = PVE::QemuServer::config_file ($vmid);
+
+    return unless -f $filename;
+
+    lock_config ($vmid, sub {
+
+       return if !check_running ($vmid); # do nothing
+
+       my $conf = $self->load_config ($vmid);
+
+       check_lock ($conf);
+
+        $self->vm_monitor_command ($vmid, "pci_del ".$pci_id, 1);
+           
+    });
+
+    die $@ if $@;
+}
+
 sub vm_destroy {
     my ($self, $vmid, $skiplock) = @_;
 
Last edited:
Here the new patchs version: (based on proxmox testing)

things that work:

-hotplug/hot-unplug of virtio disk is working (qemu-kvm >= 0.12.5)
-hotplug/hot-unplug of all model of nic is working (qemu-kvm 0.13 only)

things to do:
- verify hotplug/unplug with info pci qm monitor command
- fix pci slot address

guest tested:

linux guest: need "acpiphp" and "pci_hotplug" modules.
- debian lenny (2.6.26) seem to be not stable when unplug.
- debian squeeze(2.6.32) is stable

windows guest : win2003 x32 and x64 are ok.


notes: for existing vm, new syntax for nic (add nic identifier).

vlan0: virtio=A2:4F:85:A8:AC:AE=nic1,e1000=A2:4F:85:A8:AC:AA=nic2


modified files:

/usr/sbin/qm
/usr/share/perl5/PVE/QemuServer.pm
/usr/share/pve-manager/root/qemu/hardware.htm
/usr/share/pve-manager/root/vmlist/create.htm
 

Attachments

  • proxmox-hotplugpatch-v2.zip
    5.6 KB · Views: 8
Last edited:
Here the V3 patch:

i'm think is almost done, now it's time to test :)

- scsi and virtio disk hotplug/unplug works
- nic hotplug/unplug works (all model)
- pci slots are fixed, so live migration are working now. (please test ;)
- new device syntax for scsi controller,vga controller

notes:
- scsi disks are now limited to 14 disk (2 scsi controllers of 7 disks).
- nics are now limited to 8 nics.

i've fixed pci slots for devices, in /etc/pve/qemu-server.cfg default file.

so for the moment the pci slot is the same for all vm, i need to add to possibility to modify the conf of slots for each vm.

if you want more than 8 nics, you can add more nics in vm config file by hand (nic9,nic10,...) and than add pci slot address in qemu-server.cfg.
pci slot address can be between 2 and 31 for the moment.


Things to do:

- Custom pci slot address for each vm
- Balloning implementation (live memory size change)
- Cpu hotplug
 

Attachments

  • proxmox1.6-hotplug-beta3.zip
    6.5 KB · Views: 7
Hi everybody,

new beta version v4:

- add disk cache (none,writeback,writethough) option in web interface
- cleanup disk hotplug verification
- compatibility with proxmox 1.7 release :)


i'has attached the patchs and also the files already pached.

please test and report me if you encounter problems !

Regards,

SPiRiT
 

Attachments

  • proxmox 1.7-hotplug-patchonly-v4.zip
    7.5 KB · Views: 6
  • proxmox 1.7-hotplug-v4.zip
    33.2 KB · Views: 17
Hi everybody,

new beta version v4:

- add disk cache (none,writeback,writethough) option in web interface
- cleanup disk hotplug verification
- compatibility with proxmox 1.7 release :)


i'has attached the patchs and also the files already pached.

please test and report me if you encounter problems !

Regards,

SPiRiT
Hi,
you are fast ;)

But one issue:
Code:
unzip /root/proxmox_1.7-hotplug-v4.zip

qm start 141
#-> worked
change keyboard-layout to "German" in the web-gui (System/Options)
Code:
qm start 142
Died at /usr/share/perl5/PVE/QemuServer.pm line 1478.

Udo
 
Hi Udo,

Do you use promox 1.7 (you need qemu 0.13 for hotplug)

it's crashing at vga card initialisation, because it doesnt find bus and addr config of the video card.

do you have add my /etc/pve/qemu-server.cfg file ?
could you verify it ? (maybe it was overwrite when you change keyboard language ?)

Regards,

SPiRiT
 
Hi Udo,

Do you use promox 1.7 (you need qemu 0.13 for hotplug)
yes - the actual pvetest
Code:
pveversion -v
pve-manager: 1.7-10 (pve-manager/1.7/5323)
running kernel: 2.6.35-1-pve
proxmox-ve-2.6.35: 1.6-7
pve-kernel-2.6.32-3-pve: 2.6.32-18
pve-kernel-2.6.35-1-pve: 2.6.35-7
qemu-server: 1.1-25
pve-firmware: 1.0-9
libpve-storage-perl: 1.0-16
vncterm: 0.9-2
vzctl: 3.0.24-1pve4
vzdump: 1.2-9
vzprocps: 2.0.11-1dso2
vzquota: 3.0.11-1
pve-qemu-kvm: 0.13.0-2
ksm-control-daemon: 1.0-4
it's crashing at vga card initialisation, because it doesnt find bus and addr config of the video card.

do you have add my /etc/pve/qemu-server.cfg file ?
could you verify it ? (maybe it was overwrite when you change keyboard language ?)

Regards,

SPiRiT
yes, i use your file but it's overwritten:
Code:
pci: device=nic8,bus=0,addr=30
keyboard: de
Now i have add the last line to your file and i can start the vm...
but don't see hot-plugged NICs and HDs....

must take a deeper look.

Udo
 
- Thanks for the info, i'll check for the file overwrite (maybe I'll use a separate config file).

which guest os are you running ?
Hi SPiRiT,
the guest is in this case a devil-linux (1.4RC6) with an 2.6.32.23 kernel. But i don't think that's guest-related is: also after reboot the second nic/disk don't appear. After Stop/Start it's work (like without patch).

Udo
 
you can verify that device is correctly, with qemu monitor. (just type "info pci" , and you must see the device list)

(my code do the verify than the device is correctly added (hardware level), so if hotplug doest work ,you must have an error in webinterface when you plug it)

also ,you need to load acpiphp and pci_hoplug modules in your guest
 
I have to say, spirit thank you for contributing this feature.

I'm glad to see the topic resurface.
 

About

The Proxmox community has been around for many years and offers help and support for Proxmox VE, Proxmox Backup Server, and Proxmox Mail Gateway.
We think our community is one of the best thanks to people like you!

Get your subscription!

The Proxmox team works very hard to make sure you are running the best software and getting stable updates and security enhancements, as well as quick enterprise support. Tens of thousands of happy customers have a Proxmox subscription. Get yours easily in our online shop.

Buy now!