[Libvir] Bug in the virDomainGetInfo() API of libvirt 0.1.9 with Xen 3.0.3

The maxMem field of the virDomainInfo structure is given in bytes instead of Kbytes when the domain is 0 (Domain-0). With others domains, the value of maxMem is correct. Exemple with virsh: On a system with 4 GB memory, virsh reports: # virsh dominfo 0 ... Max memory: 4294967292 kB With the same libvirt version 0.1.9 but with an older Xen (not 3.0.3), the maxMem value of Domain-0 is correct.

On Fri, Jan 12, 2007 at 11:47:16AM +0100, Philippe Berthault wrote:
The maxMem field of the virDomainInfo structure is given in bytes instead of Kbytes when the domain is 0 (Domain-0). With others domains, the value of maxMem is correct.
Exemple with virsh: On a system with 4 GB memory, virsh reports: # virsh dominfo 0 ... Max memory: 4294967292 kB
With the same libvirt version 0.1.9 but with an older Xen (not 3.0.3), the maxMem value of Domain-0 is correct.
This sounds like a bug in Xen, rather than a bug in libvirt - we don't have any special handling for Domain-0 - we're just passing back through whatever data we get from Xen. Dan. -- |=- Red Hat, Engineering, Emerging Technologies, Boston. +1 978 392 2496 -=| |=- Perl modules: http://search.cpan.org/~danberr/ -=| |=- Projects: http://freshmeat.net/~danielpb/ -=| |=- GnuPG: 7D3B9505 F3C9 553F A1DA 4AC2 5648 23C1 B3DF F742 7D3B 9505 -=|

Daniel P. Berrange a écrit :
On Fri, Jan 12, 2007 at 11:47:16AM +0100, Philippe Berthault wrote:
The maxMem field of the virDomainInfo structure is given in bytes instead of Kbytes when the domain is 0 (Domain-0). With others domains, the value of maxMem is correct.
Exemple with virsh: On a system with 4 GB memory, virsh reports: # virsh dominfo 0 ... Max memory: 4294967292 kB
With the same libvirt version 0.1.9 but with an older Xen (not 3.0.3), the maxMem value of Domain-0 is correct.
This sounds like a bug in Xen, rather than a bug in libvirt - we don't have any special handling for Domain-0 - we're just passing back through whatever data we get from Xen.
Dan.
This problem seems to be caused by a missing initialization (in Xen or libvirt ? to be determined) because after setting the system memory size by using the "xm mem-max" command on Domain-0, the Max memory value returned by virsh is correct and reflect the value passed to the xm command. This problem of incoherent maxMem value on Domain-0 has been detected after a system reboot.

On Fri, Jan 12, 2007 at 02:42:13PM +0100, Philippe Berthault wrote:
Daniel P. Berrange a écrit :
On Fri, Jan 12, 2007 at 11:47:16AM +0100, Philippe Berthault wrote:
The maxMem field of the virDomainInfo structure is given in bytes instead of Kbytes when the domain is 0 (Domain-0). With others domains, the value of maxMem is correct.
Exemple with virsh: On a system with 4 GB memory, virsh reports: # virsh dominfo 0 ... Max memory: 4294967292 kB
With the same libvirt version 0.1.9 but with an older Xen (not 3.0.3), the maxMem value of Domain-0 is correct.
This sounds like a bug in Xen, rather than a bug in libvirt - we don't have any special handling for Domain-0 - we're just passing back through whatever data we get from Xen.
Dan.
This problem seems to be caused by a missing initialization (in Xen or libvirt ? to be determined) because after setting the system memory size by using the "xm mem-max" command on Domain-0, the Max memory value returned by virsh is correct and reflect the value passed to the xm command.
This problem of incoherent maxMem value on Domain-0 has been detected after a system reboot.
I think Xen just returns -1 when the field is uninitialized, probably meaning 'all physical memory'. Once you use "xm mem-max 0 ..." then it consider the Dom0 domain constrained, but not before. And since there are machine where it's possible to hot plug new memory this is a way to not poll the current physical memory, a bit weird but that can be understood. Daniel -- Red Hat Virtualization group http://redhat.com/virtualization/ Daniel Veillard | virtualization library http://libvirt.org/ veillard@redhat.com | libxml GNOME XML XSLT toolkit http://xmlsoft.org/ http://veillard.com/ | Rpmfind RPM search engine http://rpmfind.net/

Daniel Veillard a écrit :
I think Xen just returns -1 when the field is uninitialized, probably meaning 'all physical memory'. Once you use "xm mem-max 0 ..." then it consider the Dom0 domain constrained, but not before. And since there are machine where it's possible to hot plug new memory this is a way to not poll the current physical memory, a bit weird but that can be understood.
The signed value -1, "casted" in C/C++ in unsigned integer, gives the value 4294967295. The Max memory value returned by virsh is 4294967292. There is a small difference (3), so the value returned by Xen can't be -1.

On Fri, Jan 12, 2007 at 03:04:57PM +0100, Philippe Berthault wrote:
Daniel Veillard a écrit :
I think Xen just returns -1 when the field is uninitialized, probably meaning 'all physical memory'. Once you use "xm mem-max 0 ..." then it consider the Dom0 domain constrained, but not before. And since there are machine where it's possible to hot plug new memory this is a way to not poll the current physical memory, a bit weird but that can be understood.
The signed value -1, "casted" in C/C++ in unsigned integer, gives the value 4294967295. The Max memory value returned by virsh is 4294967292. There is a small difference (3), so the value returned by Xen can't be -1.
I think it's just a side effect of the conversion from pages number to kilobytes (assuming you're on a 4k page machine) 4294967292 is (((2^32 -1) /4 ) * 4) xen has -1, but the interface with xen usually count in page tables, and libvirt just multiplies later to get back to kB, leading to this rounding. Daniel -- Red Hat Virtualization group http://redhat.com/virtualization/ Daniel Veillard | virtualization library http://libvirt.org/ veillard@redhat.com | libxml GNOME XML XSLT toolkit http://xmlsoft.org/ http://veillard.com/ | Rpmfind RPM search engine http://rpmfind.net/

On Fri, Jan 12, 2007 at 03:04:57PM +0100, Philippe Berthault wrote:
Daniel Veillard a écrit :
I think Xen just returns -1 when the field is uninitialized, probably meaning 'all physical memory'. Once you use "xm mem-max 0 ..." then it consider the Dom0 domain constrained, but not before. And since there are machine where it's possible to hot plug new memory this is a way to not poll the current physical memory, a bit weird but that can be understood.
The signed value -1, "casted" in C/C++ in unsigned integer, gives the value 4294967295. The Max memory value returned by virsh is 4294967292. There is a small difference (3), so the value returned by Xen can't be -1.
You're forgetting though, that xen measures this in terms of pages. Libvirt converts that to bytes. The virsh converts it to KB when printing it. $cat > demo.c <<EOF #include <stdio.h> int main() { unsigned int max_pages = ~0U; unsigned long long mem = (unsigned long long)max_pages * 4096ull; unsigned long memkb = mem / 1024; printf("%u %llu %lu\n", max_pages, mem, memkb); } EOF $ gcc -o demo demo.c $ ./demo 4294967295 17592186040320 4294967292 Regards, Dan. -- |=- Red Hat, Engineering, Emerging Technologies, Boston. +1 978 392 2496 -=| |=- Perl modules: http://search.cpan.org/~danberr/ -=| |=- Projects: http://freshmeat.net/~danielpb/ -=| |=- GnuPG: 7D3B9505 F3C9 553F A1DA 4AC2 5648 23C1 B3DF F742 7D3B 9505 -=|

On Fri, Jan 12, 2007 at 02:24:12PM +0000, Daniel P. Berrange wrote:
On Fri, Jan 12, 2007 at 03:04:57PM +0100, Philippe Berthault wrote:
Daniel Veillard a écrit :
I think Xen just returns -1 when the field is uninitialized, probably meaning 'all physical memory'. Once you use "xm mem-max 0 ..." then it consider the Dom0 domain constrained, but not before. And since there are machine where it's possible to hot plug new memory this is a way to not poll the current physical memory, a bit weird but that can be understood.
The signed value -1, "casted" in C/C++ in unsigned integer, gives the value 4294967295. The Max memory value returned by virsh is 4294967292. There is a small difference (3), so the value returned by Xen can't be -1.
You're forgetting though, that xen measures this in terms of pages. Libvirt converts that to bytes. The virsh converts it to KB when printing it.
$cat > demo.c <<EOF
#include <stdio.h>
int main() { unsigned int max_pages = ~0U; unsigned long long mem = (unsigned long long)max_pages * 4096ull; unsigned long memkb = mem / 1024;
printf("%u %llu %lu\n", max_pages, mem, memkb); }
EOF $ gcc -o demo demo.c $ ./demo 4294967295 17592186040320 4294967292
Oh wait, a minute, this is bogus - the last figure should be *4 the first figure - which it clearly isn't. Well, it works on 64-bit platforms, but on 32-bit platforms the 'unsigned long memkb = mem/1024' bit is overflowing. It should be reporting 17179869180 kB. Still, this is just a bug in virsh when printing out the data - the raw data from virDomainGetInfo() is the correct value. Dan. -- |=- Red Hat, Engineering, Emerging Technologies, Boston. +1 978 392 2496 -=| |=- Perl modules: http://search.cpan.org/~danberr/ -=| |=- Projects: http://freshmeat.net/~danielpb/ -=| |=- GnuPG: 7D3B9505 F3C9 553F A1DA 4AC2 5648 23C1 B3DF F742 7D3B 9505 -=|
participants (3)
-
Daniel P. Berrange
-
Daniel Veillard
-
Philippe Berthault