On Wed, Aug 13, 2008 at 12:50:33PM +0400, Evgeniy Sokolov wrote:
OpenVZ has several parameters for memory management. All of them can
be
configured independetly.
Patch allow to get configuration of memory from container config and
then calculate total usage of memory.
It is open question how to manage memory?
Basically the 'memory' as shown by libvirt should correspond to
the 'Total' seen inside the guest when running 'free'.
eg
# free
total used free shared buffers cached
Mem: 524288 34676 489612 0 0 0
-/+ buffers/cache: 34676 489612
Swap: 0 0 0
In this case 'memory' is 524288 kb.
This looks to correspond to OpenVZs 'PRIVVMPAGES' pages parameter.
+openvzFreeUbParam(struct openvz_ub_param *ub)
+{
+ if (ub == NULL)
+ return;
+#define FREE_P(x) if (ub->x != NULL) VIR_FREE(ub->x);
This is not required. VIR_FREE is happy to accept a NULL
and will do nothing. Just call VIR_FREE directly without
testing for != NULL.
+/* calculate guaranteed memory for container
+*/
+int
+openvzUb2Memory(struct openvz_ub_param *ub, unsigned long *memory)
+{
+ unsigned long lowmem, mem, allmem;
+
+ if (ub->oomguarpages == NULL ||
+ ub->kmemsize == NULL ||
+ ub->tcpsndbuf == NULL ||
+ ub->tcprcvbuf == NULL ||
+ ub->othersockbuf == NULL ||
+ ub->dgramrcvbuf == NULL ||
+ ub->lockedpages == NULL)
+ return -1;
+
+ lowmem = ub->kmemsize->limit +
+ ub->tcpsndbuf->limit +
+ ub->tcprcvbuf->limit +
+ ub->othersockbuf->limit +
+ ub->dgramrcvbuf->limit +
+ ub->lockedpages->limit * get_pagesize();
+
+ mem = ub->oomguarpages->barrier * get_pagesize();
+ allmem = mem + lowmem; //in bytes
+ *memory = allmem / 1024; //in kb
Summing all the different memory limits together is wrong - this will
make it impossible to implement a 'setMemory' operation because you've
now no way of deciding which parameter to set.
In my testing the total memory inside a OpenVZ container seems to
correspond to the 'lockedpages' parameter, so we should just return
that value.
Since you convert to 'bytes' before converting back into kb, you'll
potentially overflow a 'long' on 32-bit platforms. You should use
'unsigned long long' instead to be safe.
+int
+openvzUb2MaxMemory(struct openvz_ub_param *ub, unsigned long *memory)
+{
+ unsigned long lowmem, mem, allmem;
+
+ if (ub->privvmpages == NULL ||
+ ub->kmemsize == NULL ||
+ ub->tcpsndbuf == NULL ||
+ ub->tcprcvbuf == NULL ||
+ ub->othersockbuf == NULL ||
+ ub->dgramrcvbuf == NULL ||
+ ub->lockedpages == NULL)
+ return -1;
+
+ lowmem = ub->kmemsize->limit +
+ ub->tcpsndbuf->limit +
+ ub->tcprcvbuf->limit +
+ ub->othersockbuf->limit +
+ ub->dgramrcvbuf->limit +
+ ub->lockedpages->limit * get_pagesize();
+
+ mem = ub->privvmpages->barrier * get_pagesize();
+ allmem = mem + lowmem; //in bytes
+ *memory = allmem / 1024; //in kb
Likewise this should simply use the lockedpages parameter I believe.
What is the difference between a 'barrier' and a 'limit' in openvz
config ? Would it make sense to map 'memory' to the 'barrier' and
'maxmemory' to the 'limit' ?
@@ -262,6 +264,10 @@ static int openvzDomainGetInfo(virDomain
}
}
+ openvzGetMemory(dom->conn, strtoI(dom->name), &(info->memory)) ;
+ openvzGetMaxMemory(dom->conn, strtoI(dom->name), &(info->maxMem)) ;
Can't you use 'vm->vpsid' and avoid the strtoI() call ?
It seems it would be more efficient to call openvzReadUbParams()
and openvzUb2Memory() & openvzUb2MaxMemory directly, rather than
calling out to openvzGetMemory() and openvzGetMaxMemory() since
it would avoid reading the config file twice - you can also get
the nrVirtCPUs at the same time.
Regards,
Daniel
--
|: Red Hat, Engineering, London -o-
http://people.redhat.com/berrange/ :|
|:
http://libvirt.org -o-
http://virt-manager.org -o-
http://ovirt.org :|
|:
http://autobuild.org -o-
http://search.cpan.org/~danberr/ :|
|: GnuPG: 7D3B9505 -o- F3C9 553F A1DA 4AC2 5648 23C1 B3DF F742 7D3B 9505 :|