Bug 1014503

Summary: Allow QoS change on the fly using updateDeviceFlags
Product: Red Hat Enterprise Linux 7 Reporter: Michal Privoznik <mprivozn>
Component: libvirtAssignee: Michal Privoznik <mprivozn>
Status: CLOSED CURRENTRELEASE QA Contact: Virtualization Bugs <virt-bugs>
Severity: unspecified Docs Contact:
Priority: unspecified    
Version: 7.0CC: acathrow, berrange, clalancette, dallan, dyuan, gsun, honzhang, itamar, jdenemar, jforbes, jiahu, laine, libvirt-maint, lpeer, mprivozn, veillard, virt-maint
Target Milestone: rc   
Target Release: ---   
Hardware: Unspecified   
OS: Unspecified   
Whiteboard:
Fixed In Version: libvirt-1.1.1-9.el7 Doc Type: Bug Fix
Doc Text:
Story Points: ---
Clone Of: 1014200 Environment:
Last Closed: 2014-06-13 13:29:52 UTC Type: Bug
Regression: --- Mount Type: ---
Documentation: --- CRM:
Verified Versions: Category: ---
oVirt Team: --- RHEL 7.3 requirements from Atomic Host:
Cloudforms Team: --- Target Upstream Version:
Embargoed:
Bug Depends On: 1014200    
Bug Blocks:    

Description Michal Privoznik 2013-10-02 08:59:09 UTC
+++ This bug was initially created as a clone of Bug #1014200 +++

+++ This bug was initially created as a clone of Bug #1014198 +++

Description of problem:
Using updateDeviceFlags to change nic with set QoS parameters causes "error: this function is not supported by the connection driver: unable to change config on 'bridge' network type"

Version-Release number of selected component (if applicable):


How reproducible:
always

Steps to Reproduce:
1. set guest domain with nic, running
2. run update-device with settings containing QoS
# virsh update-device <domain> settings_example.xml
# cat settings_example.xml:
<interface type='bridge'>
    <mac address='00:1a:4a:31:ab:2b'/>
    <source bridge='testnetwork'/>
    <target dev='vnet1'/>
    <model type='virtio'/>
    <filterref filter='vdsm-no-mac-spoofing'/>
    <link state='up'/>
    <bandwidth>
        <inbound average='25600' peak='51200' burst='204800'/>
        <outbound average='12800' peak='25600' burst='10240'/>
    </bandwidth>
    <alias name='net1'/>
    <address type='pci' domain='0x0000' bus='0x00' slot='0x03' function='0x0'/>
</interface>

Actual results:
error:this function is not supported by the connection driver: unable to change config on 'bridge' network type

Expected results:
nic is updated properly

Additional info:

--- Additional comment from Michal Privoznik on 2013-10-01 16:46:50 CEST ---

Patch proposed upstream:

https://www.redhat.com/archives/libvir-list/2013-October/msg00024.html

--- Additional comment from Michal Privoznik on 2013-10-02 09:35:21 CEST ---

v2:

https://www.redhat.com/archives/libvir-list/2013-October/msg00062.html

--- Additional comment from Michal Privoznik on 2013-10-02 10:55:27 CEST ---

Aaaand this one is fixed upstream:

commit 9fa10d3901a14997f724fe50ad8a33d7f0d23abe
Author:     Michal Privoznik <mprivozn>
AuthorDate: Tue Oct 1 15:04:48 2013 +0200
Commit:     Michal Privoznik <mprivozn>
CommitDate: Wed Oct 2 10:48:03 2013 +0200

    qemu_hotplug: Allow QoS update in qemuDomainChangeNet
    
    The qemuDomainChangeNet() is called when 'virsh update-device' is
    invoked on a NIC. Currently, we fail to update the QoS even though
    we have routines for that.
    
    Signed-off-by: Michal Privoznik <mprivozn>

commit ee02fbc8e4a24c1347761ceff2ddb2c108e9611c
Author:     Michal Privoznik <mprivozn>
AuthorDate: Wed Oct 2 09:18:02 2013 +0200
Commit:     Michal Privoznik <mprivozn>
CommitDate: Wed Oct 2 10:47:22 2013 +0200

    virNetDevBandwidthEqual: Make it more robust
    
    So far the virNetDevBandwidthEqual() expected both ->in and ->out items
    to be allocated for both @a and @b compared. This is not necessary true
    for all our code. For instance, running 'update-device' twice over a NIC
    with the very same XML results in SIGSEGV-ing in this function.
    
    Signed-off-by: Michal Privoznik <mprivozn>

v1.1.3-13-g9fa10d3

Comment 3 Hu Jianwei 2013-10-16 08:27:06 UTC
I can reproduce it with libvirt-1.1.1-8.el7.x86_64, can not reproduce it with libvirt-1.1.1-9.el7.x86_64.

Version:
libvirt-1.1.1-9.el7.x86_64
qemu-kvm-rhev-1.5.3-9.el7.x86_64
kernel-3.10.0-34.el7.x86_64

Verifying steps:
A. Function testing(testing results are same on 'network' and 'bridge' source network.)
1. Check domain status and interface element.
[root@localhost ~]# virsh list --all
 Id    Name                           State
----------------------------------------------------
 3     r6                             running

[root@localhost ~]# virsh dumpxml r6 | grep interface -A8
    <interface type='network'>
      <mac address='52:54:00:90:06:7a'/>
      <source network='default'/>
      <target dev='vnet0'/>
      <model type='virtio'/>
      <alias name='net0'/>
      <address type='pci' domain='0x0000' bus='0x00' slot='0x03' function='0x0'/>
    </interface>
...

2. Add bandwidth to nic.xml
[root@localhost ~]# cat nic.xml 
<interface type='network'>
      <mac address='52:54:00:90:06:7a'/>
      <source network='default'/>
      <model type='virtio'/>
      <bandwidth>
         <inbound average='1000' peak='5000' burst='1024'/>
         <outbound average='128' peak='256' burst='256'/>
      </bandwidth>
      <address type='pci' domain='0x0000' bus='0x00' slot='0x03' function='0x0'/>
</interface>

3. Update interface of domian using update-device cmd.
[root@localhost ~]# virsh update-device r6 nic.xml
Device updated successfully

4. Check the bandwidth part in domain xml.
[root@localhost ~]# virsh dumpxml r6 | grep interface -A10
    <interface type='network'>
      <mac address='52:54:00:90:06:7a'/>
      <source network='default'/>
      <target dev='vnet0'/>
      <model type='virtio'/>
      <bandwidth>
        <inbound average='1000' peak='5000' burst='1024'/>
        <outbound average='128' peak='256' burst='256'/>
      </bandwidth>
      <alias name='net0'/>
      <address type='pci' domain='0x0000' bus='0x00' slot='0x03' function='0x0'/>
    </interface>
...

5. Check the rules using tc command
[root@localhost ~]# tc filter show dev vnet0 parent ffff:
filter protocol ip pref 49152 u32 
filter protocol ip pref 49152 u32 fh 800: ht divisor 1 
filter protocol ip pref 49152 u32 fh 800::800 order 2048 key ht 800 bkt 0 flowid :1 
  match 00000000/00000000 at 12
 police 0x4 rate 1024Kbit burst 256Kb mtu 64Kb action drop overhead 0b 
ref 1 bind 1

[root@localhost ~]# tc class show dev vnet0
class htb 1:1 root leaf 2: prio 0 rate 8000Kbit ceil 40000Kbit burst 1Mb cburst 1600b 

6. Update existing <bandwidth> using update-device
[root@localhost ~]# virsh dumpxml r6 | grep interface -A10
    <interface type='network'>
      <mac address='52:54:00:90:06:7a'/>
      <source network='default'/>
      <target dev='vnet0'/>
      <model type='virtio'/>
      <bandwidth>
        <inbound average='1000' peak='5000' burst='1024'/>
        <outbound average='128' peak='256' burst='256'/>
      </bandwidth>
      <alias name='net0'/>
      <address type='pci' domain='0x0000' bus='0x00' slot='0x03' function='0x0'/>
    </interface>
...
[root@localhost ~]# cat nic.xml 
<interface type='network'>
      <mac address='52:54:00:90:06:7a'/>
      <source network='default'/>
      <model type='virtio'/>
      <bandwidth>
         <outbound average='128' peak='256' burst='256'/>
      </bandwidth>
      <address type='pci' domain='0x0000' bus='0x00' slot='0x03' function='0x0'/>
</interface>
[root@localhost ~]# virsh update-device r6 nic.xml 
Device updated successfully

[root@localhost ~]# virsh dumpxml r6 | grep interface -A10
    <interface type='network'>
      <mac address='52:54:00:90:06:7a'/>
      <source network='default'/>
      <target dev='vnet0'/>
      <model type='virtio'/>
      <bandwidth>
        <outbound average='128' peak='256' burst='256'/>
      </bandwidth>
      <alias name='net0'/>
      <address type='pci' domain='0x0000' bus='0x00' slot='0x03' function='0x0'/>
    </interface>
...

[root@localhost ~]# tc filter show dev vnet0 parent ffff:
filter protocol ip pref 49152 u32 
filter protocol ip pref 49152 u32 fh 800: ht divisor 1 
filter protocol ip pref 49152 u32 fh 800::800 order 2048 key ht 800 bkt 0 flowid :1 
  match 00000000/00000000 at 12
 police 0x5 rate 1024Kbit burst 256Kb mtu 64Kb action drop overhead 0b 
ref 1 bind 1

[root@localhost ~]# tc class show dev vnet0          <=== no class for vnet0
[root@localhost ~]#


B. Negative testing
1. Negative value
[root@localhost ~]# cat nic.xml 
<interface type='network'>
      <mac address='52:54:00:90:06:7a'/>
      <source network='default'/>
      <model type='virtio'/>
      <bandwidth>
          <inbound average='-1' peak='5000' burst='1024'/>
      </bandwidth>
      <address type='pci' domain='0x0000' bus='0x00' slot='0x03' function='0x0'/>
</interface>

[root@localhost ~]# virsh update-device r6 nic.xml 
error: Failed to update device from nic.xml
error: internal error: cannot set bandwidth limits on vnet0

2.huge value
[root@localhost ~]# cat nic.xml 
<interface type='network'>
      <mac address='52:54:00:90:06:7a'/>
      <source network='default'/>
      <model type='virtio'/>
      <bandwidth>
          <inbound average='10000000000000000' peak='5000' burst='1024'/>
      </bandwidth>
      <address type='pci' domain='0x0000' bus='0x00' slot='0x03' function='0x0'/>
</interface>
[root@localhost ~]# virsh update-device r6 nic.xml 
error: Failed to update device from nic.xml
error: internal error: cannot set bandwidth limits on vnet0

3. remove mandatory attribute average
[root@localhost ~]# cat nic.xml 
<interface type='network'>
      <mac address='52:54:00:90:06:7a'/>
      <source network='default'/>
      <model type='virtio'/>
      <bandwidth>
          <outbound  peak='5000' burst='1024'/>
      </bandwidth>
...
[root@localhost ~]# virsh update-device r6 nic.xml 
error: Failed to update device from nic.xml
error: Missing mandatory average or floor attributes

Existing issue:
During testing, I think libvirt should check the value range of average element in <outbound> before updating device, also the values of average element in <outbound> should be consistent with <inbound>, libvirt had better report "error: internal error: cannot set bandwidth limits on vnet0". 

This issue also can reproduce on rhel6.5 with libvirt-0.10.2-29.el6.x86_64.

[root@localhost ~]# cat nic.xml 
<interface type='network'>
      <mac address='52:54:00:90:06:7a'/>
      <source network='default'/>
      <model type='virtio'/>
      <bandwidth>
          <outbound average='-1' peak='5000' burst='1024'/>           <===set negative for <outbound>, same value in <inbound> will be failed. See [B. Negative testing]
      </bandwidth>
      <address type='pci' domain='0x0000' bus='0x00' slot='0x03' function='0x0'/>
</interface>
[root@localhost ~]# virsh update-device r6 nic.xml 
Device updated successfully

[root@localhost ~]# virsh dumpxml r6 | grep interface -A10
    <interface type='network'>
      <mac address='52:54:00:90:06:7a'/>
      <source network='default'/>
      <target dev='vnet0'/>
      <model type='virtio'/>
      <bandwidth>
        <outbound average='18446744073709551615' peak='5000' burst='1024'/>        <======libvirt will convert the negative to positive number. 
      </bandwidth>
      <alias name='net0'/>
      <address type='pci' domain='0x0000' bus='0x00' slot='0x03' function='0x0'/>
    </interface>
...

[root@localhost ~]# cat nic.xml 
<interface type='network'>
      <mac address='52:54:00:90:06:7a'/>
      <source network='default'/>
      <model type='virtio'/>
      <bandwidth>
          <outbound average='10000000000000000' peak='5000' burst='1024'/>   <===========set a huge value for average of <outbound>, same value in <inbound> will be failed. See [B. Negative testing]
      </bandwidth>
      <address type='pci' domain='0x0000' bus='0x00' slot='0x03' function='0x0'/>
</interface>
[root@localhost ~]# virsh update-device r6 nic.xml 
Device updated successfully

[root@localhost ~]# virsh dumpxml r6 | grep interface -A10
    <interface type='network'>
      <mac address='52:54:00:90:06:7a'/>
      <source network='default'/>
      <target dev='vnet0'/>
      <model type='virtio'/>
      <bandwidth>
        <outbound average='10000000000000000' peak='5000' burst='1024'/>
      </bandwidth>
...

Comment 4 Hu Jianwei 2013-10-22 06:43:01 UTC
Any suggestion/update for below problem?

> Existing issue:
> During testing, I think libvirt should check the value range of average
> element in <outbound> before updating device, also the values of average
> element in <outbound> should be consistent with <inbound>, libvirt had
> better report "error: internal error: cannot set bandwidth limits on vnet0". 
> 
> This issue also can reproduce on rhel6.5 with libvirt-0.10.2-29.el6.x86_64.
> 
> [root@localhost ~]# cat nic.xml 
> <interface type='network'>
>       <mac address='52:54:00:90:06:7a'/>
>       <source network='default'/>
>       <model type='virtio'/>
>       <bandwidth>
>           <outbound average='-1' peak='5000' burst='1024'/>          
> <===set negative for <outbound>, same value in <inbound> will be failed. See
> [B. Negative testing]
>       </bandwidth>
>       <address type='pci' domain='0x0000' bus='0x00' slot='0x03'
> function='0x0'/>
> </interface>
> [root@localhost ~]# virsh update-device r6 nic.xml 
> Device updated successfully
> 
> [root@localhost ~]# virsh dumpxml r6 | grep interface -A10
>     <interface type='network'>
>       <mac address='52:54:00:90:06:7a'/>
>       <source network='default'/>
>       <target dev='vnet0'/>
>       <model type='virtio'/>
>       <bandwidth>
>         <outbound average='18446744073709551615' peak='5000' burst='1024'/> 
> <======libvirt will convert the negative to positive number. 
>       </bandwidth>
>       <alias name='net0'/>
>       <address type='pci' domain='0x0000' bus='0x00' slot='0x03'
> function='0x0'/>
>     </interface>
> ...
> 
> [root@localhost ~]# cat nic.xml 
> <interface type='network'>
>       <mac address='52:54:00:90:06:7a'/>
>       <source network='default'/>
>       <model type='virtio'/>
>       <bandwidth>
>           <outbound average='10000000000000000' peak='5000' burst='1024'/>  
> <===========set a huge value for average of <outbound>, same value in
> <inbound> will be failed. See [B. Negative testing]
>       </bandwidth>
>       <address type='pci' domain='0x0000' bus='0x00' slot='0x03'
> function='0x0'/>
> </interface>
> [root@localhost ~]# virsh update-device r6 nic.xml 
> Device updated successfully
> 
> [root@localhost ~]# virsh dumpxml r6 | grep interface -A10
>     <interface type='network'>
>       <mac address='52:54:00:90:06:7a'/>
>       <source network='default'/>
>       <target dev='vnet0'/>
>       <model type='virtio'/>
>       <bandwidth>
>         <outbound average='10000000000000000' peak='5000' burst='1024'/>
>       </bandwidth>
> ...

Comment 5 Michal Privoznik 2013-10-22 11:01:53 UTC
Okay, these are bugs. I am moving this bug back to ASSIGNED and I'll propose a patch.

Comment 6 Jiri Denemark 2013-10-22 13:13:01 UTC
Actually, I think the issues will better be covered by a separate bug report as it seems not to be limited to just device-update. Hu, could you please create a new bug for these issues?

Comment 7 Hu Jianwei 2013-10-23 01:50:47 UTC
Thanks for your suggestion, filed a new one, bug 1022292.

Comment 8 Hu Jianwei 2013-10-23 01:53:07 UTC
According to comment 3, changed to verified.

Comment 9 Ludek Smid 2014-06-13 13:29:52 UTC
This request was resolved in Red Hat Enterprise Linux 7.0.

Contact your manager or support representative in case you have further questions about the request.