Bug 1221504

Summary: 2 corner issue around memory device
Product: Red Hat Enterprise Linux 7 Reporter: Luyao Huang <lhuang>
Component: libvirtAssignee: Peter Krempa <pkrempa>
Status: CLOSED ERRATA QA Contact: Virtualization Bugs <virt-bugs>
Severity: low Docs Contact:
Priority: low    
Version: 7.2CC: dyuan, honzhang, mzhan, rbalakri
Target Milestone: rc   
Target Release: ---   
Hardware: x86_64   
OS: Linux   
Whiteboard:
Fixed In Version: libvirt-1.2.16-1.el7 Doc Type: Bug Fix
Doc Text:
Story Points: ---
Clone Of: Environment:
Last Closed: 2015-11-19 06:31:12 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:

Description Luyao Huang 2015-05-14 08:29:29 UTC
Description of problem:
2 orner issue around memory device:
1. attach a memory device with invalid address will make guest have invalid settings

2. set maxmemory to max value will make guest have broken settings

Version-Release number of selected component (if applicable):
libvirt-1.2.15-2.el7.x86_64

How reproducible:
100%

Step to reproduce:
First issue:

1. # cat memdevice.xml
    <memory model='dimm'>
      <target>
        <size unit='m'>500</size>
        <node>1</node>
      </target>
<address type='pci' slot='1'/>
    </memory>

2.
# virsh attach-device test3 memdevice.xml --config
Device attached successfully

3. recheck the xml:
    <memory model='dimm'>
      <target>
        <size unit='KiB'>512000</size>
        <node>1</node>
      </target>
      <address type='pci' domain='0x0000' bus='0x00' slot='0x01' function='0x0'/>
    </memory>

4. try to edit guest will always get error:

#  virsh edit test3
error: internal error: Attempted double use of PCI slot 0000:00:01.0 (may need "multifunction='on'" for device on function 0)
Failed. Try again? [y,n,i,f,?]: 


Second Issue:

1. modify or add a maxmemmory like this:

  <maxMemory slots='16' unit='b'>9223372036854775807</maxMemory>

2. recheck xml :

# virsh dumpxml test3
...
  <maxMemory slots='16' unit='KiB'>9007199254740992</maxMemory>
...

3. restart libvirtd:

# service libvirtd restart
Redirecting to /bin/systemctl restart  libvirtd.service

# virsh dumpxml test3
error: failed to get domain 'test3'
error: Domain not found: no domain with matching name 'test3'



Actual results:
1. attach a memory device with invalid address will make guest have invalid settings

2. set maxmemory to max value will make guest have broken settings

Expected results:
1. should not have this invalid address
2. guest should not disappear

Additional info:

for issue two:

libvirt use VIR_DIV_UP to change 9223372036854775807 to kiB, but VIR_DIV_UP will make this value to an upper one, but 9007199254740992 exceed 9007199254740991. i think this issue will happen in some other place. such as memory, current memory...

Comment 1 Peter Krempa 2015-05-19 13:39:31 UTC
(In reply to Luyao Huang from comment #0)
> Description of problem:
> 2 orner issue around memory device:
> 1. attach a memory device with invalid address will make guest have invalid
> settings
> 
> 2. set maxmemory to max value will make guest have broken settings
> 
> Version-Release number of selected component (if applicable):
> libvirt-1.2.15-2.el7.x86_64
> 
> How reproducible:
> 100%
> 
> Step to reproduce:
> First issue:
> 
> 1. # cat memdevice.xml
>     <memory model='dimm'>
>       <target>
>         <size unit='m'>500</size>
>         <node>1</node>
>       </target>
> <address type='pci' slot='1'/>
>     </memory>
> 
> 2.
> # virsh attach-device test3 memdevice.xml --config
> Device attached successfully
> 
> 3. recheck the xml:
>     <memory model='dimm'>
>       <target>
>         <size unit='KiB'>512000</size>
>         <node>1</node>
>       </target>
>       <address type='pci' domain='0x0000' bus='0x00' slot='0x01'
> function='0x0'/>
>     </memory>
> 
> 4. try to edit guest will always get error:
> 
> #  virsh edit test3
> error: internal error: Attempted double use of PCI slot 0000:00:01.0 (may
> need "multifunction='on'" for device on function 0)
> Failed. Try again? [y,n,i,f,?]: 

For memory devices only addresses of type _NONE and _DIMM are supported so this issue is separate. The address that gets generated is duplicate and thus can't be used.

Comment 2 Peter Krempa 2015-05-20 12:34:11 UTC
Issue 2 fixed upstream with:

commit bc89ebe564e80387d4f6a766e0c0869a981e2fa7
Author: Peter Krempa <pkrempa>
Date:   Tue May 19 16:58:24 2015 +0200

    conf: Catch memory size overflow earlier
    
    virDomainParseMemory parses the size and then rounds up while converting
    it to kibibytes. Since the number is limit-checked before the rounding
    it's possible to use a number that would be correctly parsed the first
    time, but not the second time. For numbers not limited to 32 bit systems
    the magic is 9223372036854775807 bytes. That number then can't be parsed
    back in kibibytes.
    
    To solve the issue add a second overflow check for the few values that
    would cause the problem. Since virDomainParseMemory is used in config
    parsing, this avoids vanishing VMs.

Since issue 1 is a missconfiguration, the patch above should be enough to fix this bug.

Comment 3 Luyao Huang 2015-05-28 08:50:42 UTC
(In reply to Peter Krempa from comment #2)
> Issue 2 fixed upstream with:
> 
> commit bc89ebe564e80387d4f6a766e0c0869a981e2fa7
> Author: Peter Krempa <pkrempa>
> Date:   Tue May 19 16:58:24 2015 +0200
> 
>     conf: Catch memory size overflow earlier
>     
>     virDomainParseMemory parses the size and then rounds up while converting
>     it to kibibytes. Since the number is limit-checked before the rounding
>     it's possible to use a number that would be correctly parsed the first
>     time, but not the second time. For numbers not limited to 32 bit systems
>     the magic is 9223372036854775807 bytes. That number then can't be parsed
>     back in kibibytes.
>     
>     To solve the issue add a second overflow check for the few values that
>     would cause the problem. Since virDomainParseMemory is used in config
>     parsing, this avoids vanishing VMs.
> 
> Since issue 1 is a missconfiguration, the patch above should be enough to
> fix this bug.

Hi peter,

Thanks you patch and i found some other place need fix:

when start a vm which maxmemory is 9007199254740991Kib, maxmemory will change to 9007199254740992Kib after qemuDomainAlignMemorySizes, this will make guest status change to shut off after restart libvirtd.

Comment 5 Luyao Huang 2015-08-20 02:56:25 UTC
Verify this bug with libvirt-1.2.17-5.el7.x86_64:

The second issue:

1. try to add thos line to guest xml:

<maxMemory slots='16' unit='b'>9223372036854775807</maxMemory>


2. will get error during save it:
# virsh edit test4
error: numerical overflow: size value too large
Failed. Try again? [y,n,i,f,?]: 

3. also test with memory:

  <memory unit='b'>9223372036854775807</memory>

# virsh edit test4
error: numerical overflow: size value too large
Failed. Try again? [y,n,i,f,?]:

Comment 7 errata-xmlrpc 2015-11-19 06:31:12 UTC
Since the problem described in this bug report should be
resolved in a recent advisory, it has been closed with a
resolution of ERRATA.

For information on the advisory, and where to find the updated
files, follow the link below.

If the solution does not work for you, open a new bug report.

https://rhn.redhat.com/errata/RHBA-2015-2202.html