Re: [libvirt] [PATCH v3 04/13] XML parsing for memory tunables
On Thu, 7 Oct 2010 12:49:29 +0100, Daniel P. Berrange berra...@redhat.com wrote: On Mon, Oct 04, 2010 at 12:47:22PM +0530, Nikunj A. Dadhania wrote: On Mon, 4 Oct 2010 12:16:42 +0530, Balbir Singh bal...@linux.vnet.ibm.com wrote: * Nikunj A. Dadhania nik...@linux.vnet.ibm.com [2010-09-28 15:26:30]: snip +unsigned long hard_limit; +unsigned long soft_limit; +unsigned long min_guarantee; +unsigned long swap_hard_limit; The hard_limit, soft_limit, swap_hard_limit are s64 and the value is in bytes. What is the unit supported in this implementation? Actually if libvirt is built on 32bit these aren't big enough - make them into 'unsigned long long' data types I reckon. I was thinking that as we are having the unit of KB, we would be able to represent 2^42 bytes of memory limit, ie. 4 Terabytes. Won't this suffice in case of 32bit? Nikunj -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
Re: [libvirt] [PATCH v3 04/13] XML parsing for memory tunables
* Nikunj A. Dadhania nik...@linux.vnet.ibm.com [2010-10-08 12:00:44]: On Thu, 7 Oct 2010 12:49:29 +0100, Daniel P. Berrange berra...@redhat.com wrote: On Mon, Oct 04, 2010 at 12:47:22PM +0530, Nikunj A. Dadhania wrote: On Mon, 4 Oct 2010 12:16:42 +0530, Balbir Singh bal...@linux.vnet.ibm.com wrote: * Nikunj A. Dadhania nik...@linux.vnet.ibm.com [2010-09-28 15:26:30]: snip +unsigned long hard_limit; +unsigned long soft_limit; +unsigned long min_guarantee; +unsigned long swap_hard_limit; The hard_limit, soft_limit, swap_hard_limit are s64 and the value is in bytes. What is the unit supported in this implementation? Actually if libvirt is built on 32bit these aren't big enough - make them into 'unsigned long long' data types I reckon. I was thinking that as we are having the unit of KB, we would be able to represent 2^42 bytes of memory limit, ie. 4 Terabytes. Won't this suffice in case of 32bit? How would you represent -1 (2^63 -1) as unlimited or max limit we use today? -- Three Cheers, Balbir -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
Re: [libvirt] Ephemeral VM operation
On Thu, Oct 07, 2010 at 06:49:05PM -0400, Dave Allan wrote: A number of hypervisors have a mode in which changes made to storage are not persisted across a reboot of the VM. qemu uses the -snapshot flag; VMware refers to this functionality as non-persistent disk[1]. Is this functionality something that is interesting to libvirt? yes I think this is an important use case, it allows for example a rather trivial and safe implementation of things like open kiosk you may find in public places (or implement a scratch environment allowing the kids to play without much risk for a more personal/private use :-) !) Daniel -- Daniel Veillard | libxml Gnome XML XSLT toolkit http://xmlsoft.org/ dan...@veillard.com | Rpmfind RPM search engine http://rpmfind.net/ http://veillard.com/ | virtualization library http://libvirt.org/ -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
Re: [libvirt] [PATCH v3 12/13] Adding memtune command to virsh tool
On Thu, 7 Oct 2010 12:59:57 +0100, Daniel P. Berrange berra...@redhat.com wrote: On Tue, Sep 28, 2010 at 03:27:19PM +0530, Nikunj A. Dadhania wrote: +LIBVIRT_0.8.5 { +global: +virDomainSetMemoryParameters; +virDomainGetMemoryParameters; +} LIBVIRT_0.8.2; This chunk should actually be with the change to 'src/libvirt.c' in the second patch. Done Nikunj -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
Re: [libvirt] [PATCH v3 04/13] XML parsing for memory tunables
On Thu, 7 Oct 2010 12:48:26 +0100, Daniel P. Berrange berra...@redhat.com wrote: On Tue, Sep 28, 2010 at 03:26:30PM +0530, Nikunj A. Dadhania wrote: From: Nikunj A. Dadhania nik...@linux.vnet.ibm.com Adding parsing code for memory tunables in the domain xml file v2: + Fix typo min_guarantee Signed-off-by: Nikunj A. Dadhania nik...@linux.vnet.ibm.com --- src/conf/domain_conf.c | 50 +--- src/conf/domain_conf.h | 12 --- src/esx/esx_vmx.c | 30 +- src/lxc/lxc_controller.c |2 +- src/lxc/lxc_driver.c | 12 +-- src/openvz/openvz_driver.c |8 --- src/qemu/qemu_conf.c |8 --- src/qemu/qemu_driver.c | 18 src/test/test_driver.c | 12 +-- src/uml/uml_conf.c |2 +- src/uml/uml_driver.c | 14 ++-- 11 files changed, 104 insertions(+), 64 deletions(-) ACK, looks fine, though it'd be good to add one or two example data files to tests/qemuxml2xmltest.c to ensure that we roundtrip through the XML parser+formatter correctly. Sure, will add the files, and send the updated series Nikunj -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
Re: [libvirt] [PATCH v3 01/13] Adding structure and defines for virDomainSet/GetMemoryParameters
On Thu, 7 Oct 2010 12:45:22 +0100, Daniel P. Berrange berra...@redhat.com wrote: On Tue, Sep 28, 2010 at 03:26:15PM +0530, Nikunj A. Dadhania wrote: + +/* Set memory tunables for the domain*/ +int virDomainSetMemoryParameters(virDomainPtr domain, +virMemoryParameterPtr params, +int nparams); +/* Get memory tunables for the domain, caller allocates the params if nparams + * is zero and params is NULL, the domain returns back number of parameters + * supported by the HV. This could be used by the caller to allocate the + * memory and call with params structure allocated. + */ +int virDomainGetMemoryParameters(virDomainPtr domain, +virMemoryParameterPtr params, +int *nparams); We should add an 'unsigned int flags' parameter to both of these, so we can extend their semantics in the future. I have added this and mentioned it as unused at present. The comment here can be moved to the libvirt.c file so it gets picked up in the API docs. I have already put a detailed comment in libvirt.c for API docs. I am getting rid of this for now. Nikunj -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
Re: [libvirt] [PATCH v3 04/13] XML parsing for memory tunables
On Fri, 8 Oct 2010 14:10:53 +0530, Balbir Singh bal...@linux.vnet.ibm.com wrote: * Nikunj A. Dadhania nik...@linux.vnet.ibm.com [2010-10-08 12:00:44]: On Thu, 7 Oct 2010 12:49:29 +0100, Daniel P. Berrange berra...@redhat.com wrote: On Mon, Oct 04, 2010 at 12:47:22PM +0530, Nikunj A. Dadhania wrote: On Mon, 4 Oct 2010 12:16:42 +0530, Balbir Singh bal...@linux.vnet.ibm.com wrote: * Nikunj A. Dadhania nik...@linux.vnet.ibm.com [2010-09-28 15:26:30]: snip +unsigned long hard_limit; +unsigned long soft_limit; +unsigned long min_guarantee; +unsigned long swap_hard_limit; The hard_limit, soft_limit, swap_hard_limit are s64 and the value is in bytes. What is the unit supported in this implementation? Actually if libvirt is built on 32bit these aren't big enough - make them into 'unsigned long long' data types I reckon. I was thinking that as we are having the unit of KB, we would be able to represent 2^42 bytes of memory limit, ie. 4 Terabytes. Won't this suffice in case of 32bit? How would you represent -1 (2^63 -1) as unlimited or max limit we use today? I think I have answered this question in the thread: this is specific to cgroup that -1 means unlimited, this may not be true for other HVs. Nikunj -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
[libvirt] [PATCH v4 00/13] Implement memory control api
Changelog from v3: * Add unsigned int flags to the public api and make corresponding changes further down till the drivers(qemu, lxc and remote) * Move exporting of the api's to patch two * Added memtune test in tests/qemuxml2xmltest.c * Fix: src/conf/domain_conf.c - print memtune element only if tunable is present * Fix: src/qemu/qemu_driver.c - call cgroup apis only if nonzero * Fix: src/lxc/lxc_controller.c - call cgroup apis only if nonzero Changelog from v2: * Implement virDomainGetMemoryParameters api * Add virDomainGetMemoryParameters to memtune command in virsh * Provide domainGetMemoryParameters implementation for remote, QEmu and LXC drivers * Auto-generate code using rpcgen and remote_generate_stubs.pl * Squash all the changes related to remote driver and remote protocol into one single patch. * Patch re-ordering Changelog from v1: * Patch re-ordering for compilation * Folded python bindings changes to patch 01 * Added defines for string constants for memory tunables * Typo fix: min_guarantee * Moved initialization of function pointers in driver.h patch This patch series implement public api for controlling various memory tunables exported by the OS. This is based on the following RFC[1]. * Implement virDomainSetMemoryParameters api * Provide implementation for remote, QEmu and LXC drivers * Enable memory controller support fro QEmu * virsh command for runtime changes to the memory parameters * Domain configuration parsing for memory control parameters * Cgroup memory controller code for memory hard_limit/soft_limit, swap hard_limit To Do * Python bindings is just a place holder, need to implement 1. https://www.redhat.com/archives/libvir-list/2010-August/msg00607.html 2. https://www.redhat.com/archives/libvir-list/2010-August/msg00699.html --- Nikunj A. Dadhania (13): Adding structure and defines for virDomainSet/GetMemoryParameters Adding virDomainSetMemoryParameters and virDomainGetMemoryParameters API Adds xml entries for memory tunables XML parsing for memory tunables Implement cgroup memory controller tunables Implement driver interface domainSetMemoryParamters for QEmu Implement driver interface domainGetMemoryParamters for QEmu Adding memtunables to qemuSetupCgroup Adding memtunables to libvirt-lxc command Implement driver interface domainSetMemoryParamters for LXC Implement driver interface domainGetMemoryParamters for LXC Adding memtune command to virsh tool Remote protocol changes and implements virDomainSet/GetMemoryParameters daemon/remote.c | 162 + daemon/remote_dispatch_args.h|2 daemon/remote_dispatch_prototypes.h | 16 + daemon/remote_dispatch_ret.h |1 daemon/remote_dispatch_table.h | 10 + docs/schemas/domain.rng | 31 +++ include/libvirt/libvirt.h.in | 63 + python/generator.py |2 python/libvirt-override-api.xml | 12 + python/libvirt-override.c| 14 + src/conf/domain_conf.c | 54 src/conf/domain_conf.h | 12 + src/driver.h | 14 + src/esx/esx_driver.c |2 src/esx/esx_vmx.c| 30 +- src/libvirt.c| 104 + src/libvirt_private.syms |6 src/libvirt_public.syms |6 src/lxc/lxc_controller.c | 32 +++ src/lxc/lxc_driver.c | 215 +- src/openvz/openvz_driver.c | 10 - src/phyp/phyp_driver.c |2 src/qemu/qemu.conf |4 src/qemu/qemu_conf.c | 11 - src/qemu/qemu_driver.c | 265 +- src/remote/remote_driver.c | 151 + src/remote/remote_protocol.c | 88 +++ src/remote/remote_protocol.h | 58 + src/remote/remote_protocol.x | 44 src/test/test_driver.c | 14 + src/uml/uml_conf.c |2 src/uml/uml_driver.c | 16 + src/util/cgroup.c| 106 + src/util/cgroup.h|7 + src/xen/xen_driver.c |2 tests/qemuxml2argvdata/qemuxml2argv-memtune.args |1 tests/qemuxml2argvdata/qemuxml2argv-memtune.xml | 30 ++ tests/qemuxml2xmltest.c |1 tools/virsh.c
[libvirt] [PATCH v4 01/13] Adding structure and defines for virDomainSet/GetMemoryParameters
From: Nikunj A. Dadhania nik...@linux.vnet.ibm.com This patch adds a structure virMemoryParameter, it contains the name of the parameter and the type of the parameter along with a union. v4: + Add unsigned int flags to the public api for future extensions v3: + Protoype for virDomainGetMemoryParameters and dummy python binding. v2: + Includes dummy python bindings for the library to build cleanly. + Define string constants like hard_limit, etc. + re-order this patch. Signed-off-by: Nikunj A. Dadhania nik...@linux.vnet.ibm.com --- include/libvirt/libvirt.h.in| 63 +++ python/generator.py |2 + python/libvirt-override-api.xml | 12 +++ python/libvirt-override.c | 14 + 4 files changed, 91 insertions(+), 0 deletions(-) diff --git a/include/libvirt/libvirt.h.in b/include/libvirt/libvirt.h.in index b45f7ec..75a84fb 100644 --- a/include/libvirt/libvirt.h.in +++ b/include/libvirt/libvirt.h.in @@ -674,6 +674,69 @@ int virDomainGetInfo (virDomainPtr domain, char * virDomainGetSchedulerType(virDomainPtr domain, int *nparams); +/** + * virDomainMemoryParameterType: + * + * A memory parameter field type + */ +typedef enum { +VIR_DOMAIN_MEMORY_FIELD_INT = 1, /* integer case */ +VIR_DOMAIN_MEMORY_FIELD_UINT= 2, /* unsigned integer case */ +VIR_DOMAIN_MEMORY_FIELD_LLONG = 3, /* long long case */ +VIR_DOMAIN_MEMORY_FIELD_ULLONG = 4, /* unsigned long long case */ +VIR_DOMAIN_MEMORY_FIELD_DOUBLE = 5, /* double case */ +VIR_DOMAIN_MEMORY_FIELD_BOOLEAN = 6 /* boolean(character) case */ +} virMemoryParameterType; + +/** + * VIR_DOMAIN_MEMORY_FIELD_LENGTH: + * + * Macro providing the field length of virMemoryParameter + */ + +#define VIR_DOMAIN_MEMORY_FIELD_LENGTH 80 +#define VIR_DOMAIN_MEMORY_HARD_LIMIT hard_limit +#define VIR_DOMAIN_MEMORY_SOFT_LIMIT soft_limit +#define VIR_DOMAIN_MEMORY_MIN_GUARANTEE min_guarantee +#define VIR_DOMAIN_SWAP_HARD_LIMIT swap_hard_limit + +/** + * virDomainMemoryParameter: + * + * a virDomainMemoryParameter is the set of scheduler parameters + */ + +typedef struct _virMemoryParameter virMemoryParameter; + +struct _virMemoryParameter { +char field[VIR_DOMAIN_MEMORY_FIELD_LENGTH]; /* parameter name */ +int type; /* parameter type */ +union { +int i; /* data for integer case */ +unsigned int ui;/* data for unsigned integer case */ +long long int l;/* data for long long integer case */ +unsigned long long int ul; /* data for unsigned long long integer case */ +double d; /* data for double case */ +char b; /* data for char case */ +} value; /* parameter value */ +}; + +/** + * virMemoryParameterPtr: + * + * a virMemoryParameterPtr is a pointer to a virMemoryParameter structure. + */ + +typedef virMemoryParameter *virMemoryParameterPtr; + +/* Set memory tunables for the domain*/ +int virDomainSetMemoryParameters(virDomainPtr domain, +virMemoryParameterPtr params, +int nparams, unsigned int flags); +int virDomainGetMemoryParameters(virDomainPtr domain, +virMemoryParameterPtr params, +int *nparams, unsigned int flags); + /* * Dynamic control of domains */ diff --git a/python/generator.py b/python/generator.py index d876df6..68009b9 100755 --- a/python/generator.py +++ b/python/generator.py @@ -306,6 +306,8 @@ skip_impl = ( 'virDomainGetSchedulerType', 'virDomainGetSchedulerParameters', 'virDomainSetSchedulerParameters', +'virDomainSetMemoryParameters', +'virDomainGetMemoryParameters', 'virDomainGetVcpus', 'virDomainPinVcpu', 'virSecretGetValue', diff --git a/python/libvirt-override-api.xml b/python/libvirt-override-api.xml index ca16993..f209608 100644 --- a/python/libvirt-override-api.xml +++ b/python/libvirt-override-api.xml @@ -162,6 +162,18 @@ arg name='domain' type='virDomainPtr' info='pointer to domain object'/ arg name='params' type='virSchedParameterPtr' info='pointer to scheduler parameter objects'/ /function +function name='virDomainSetMemoryParameters' file='python' + infoChange the memory tunables/info + return type='int' info='-1 in case of error, 0 in case of success.'/ + arg name='domain' type='virDomainPtr' info='pointer to domain object'/ + arg name='params' type='virMemoryParameterPtr' info='pointer to memory tunable objects'/ +/function +function name='virDomainGetMemoryParameters' file='python' + infoGet the memory parameters, the @params array will be filled with the values./info + return type='int' info='-1 in case of error, 0 in case of success.'/ + arg name='domain'
[libvirt] [PATCH v4 04/13] XML parsing for memory tunables
From: Nikunj A. Dadhania nik...@linux.vnet.ibm.com Adding parsing code for memory tunables in the domain xml file v4: * Add memtune in tests/qemuxml2xmltest.c * Fix: insert memtune element only when any of them is set v2: + Fix typo min_guarantee Acked-by: Daniel P. Berrange berra...@redhat.com Signed-off-by: Nikunj A. Dadhania nik...@linux.vnet.ibm.com --- src/conf/domain_conf.c | 54 +++--- src/conf/domain_conf.h | 12 - src/esx/esx_vmx.c| 30 ++-- src/lxc/lxc_controller.c |2 - src/lxc/lxc_driver.c | 12 ++--- src/openvz/openvz_driver.c |8 ++- src/qemu/qemu_conf.c |8 ++- src/qemu/qemu_driver.c | 18 --- src/test/test_driver.c | 12 ++--- src/uml/uml_conf.c |2 - src/uml/uml_driver.c | 14 +++--- tests/qemuxml2argvdata/qemuxml2argv-memtune.args |1 tests/qemuxml2argvdata/qemuxml2argv-memtune.xml | 30 tests/qemuxml2xmltest.c |1 14 files changed, 140 insertions(+), 64 deletions(-) create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-memtune.args create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-memtune.xml diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c index 539d443..146e7a7 100644 --- a/src/conf/domain_conf.c +++ b/src/conf/domain_conf.c @@ -4235,19 +4235,38 @@ static virDomainDefPtr virDomainDefParseXML(virCapsPtr caps, def-description = virXPathString(string(./description[1]), ctxt); /* Extract domain memory */ -if (virXPathULong(string(./memory[1]), ctxt, def-maxmem) 0) { +if (virXPathULong(string(./memory[1]), ctxt, + def-mem.max_balloon) 0) { virDomainReportError(VIR_ERR_INTERNAL_ERROR, %s, _(missing memory element)); goto error; } -if (virXPathULong(string(./currentMemory[1]), ctxt, def-memory) 0) -def-memory = def-maxmem; +if (virXPathULong(string(./currentMemory[1]), ctxt, + def-mem.cur_balloon) 0) +def-mem.cur_balloon = def-mem.max_balloon; node = virXPathNode(./memoryBacking/hugepages, ctxt); if (node) -def-hugepage_backed = 1; - +def-mem.hugepage_backed = 1; + +/* Extract other memory tunables */ +if (virXPathULong(string(./memtune/hard_limit), ctxt, + def-mem.hard_limit) 0) +def-mem.hard_limit = 0; + +if (virXPathULong(string(./memtune/soft_limit[1]), ctxt, + def-mem.soft_limit) 0) +def-mem.soft_limit = 0; + +if (virXPathULong(string(./memtune/min_guarantee[1]), ctxt, + def-mem.min_guarantee) 0) +def-mem.min_guarantee = 0; + +if (virXPathULong(string(./memtune/swap_hard_limit[1]), ctxt, + def-mem.swap_hard_limit) 0) +def-mem.swap_hard_limit = 0; + if (virXPathULong(string(./vcpu[1]), ctxt, def-vcpus) 0) def-vcpus = 1; @@ -6384,10 +6403,29 @@ char *virDomainDefFormat(virDomainDefPtr def, virBufferEscapeString(buf, description%s/description\n, def-description); -virBufferVSprintf(buf, memory%lu/memory\n, def-maxmem); +virBufferVSprintf(buf, memory%lu/memory\n, def-mem.max_balloon); virBufferVSprintf(buf, currentMemory%lu/currentMemory\n, - def-memory); -if (def-hugepage_backed) { + def-mem.cur_balloon); + +/* add memtune only if there are any */ +if(def-mem.hard_limit || def-mem.hard_limit || def-mem.hard_limit) +virBufferVSprintf(buf, memtune\n); +if (def-mem.hard_limit) { +virBufferVSprintf(buf, hard_limit%lu/hard_limit\n, + def-mem.hard_limit); +} +if (def-mem.soft_limit) { +virBufferVSprintf(buf, soft_limit%lu/soft_limit\n, + def-mem.soft_limit); +} +if (def-mem.swap_hard_limit) { +virBufferVSprintf(buf, swap_hard_limit%lu/swap_hard_limit\n, + def-mem.swap_hard_limit); +} +if(def-mem.hard_limit || def-mem.hard_limit || def-mem.hard_limit) +virBufferVSprintf(buf, /memtune\n); + +if (def-mem.hugepage_backed) { virBufferAddLit(buf, memoryBacking\n); virBufferAddLit(buf, hugepages/\n); virBufferAddLit(buf, /memoryBacking\n); diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h index 9bf13d8..7c5215f 100644 --- a/src/conf/domain_conf.h +++ b/src/conf/domain_conf.h @@ -866,9 +866,15 @@ struct _virDomainDef { char *name; char *description; -unsigned long memory; -unsigned long maxmem;
[libvirt] [PATCH v4 02/13] Adding virDomainSetMemoryParameters and virDomainGetMemoryParameters API
From: Nikunj A. Dadhania nik...@linux.vnet.ibm.com Public api to set/get memory tunables supported by the hypervisors. RFC: https://www.redhat.com/archives/libvir-list/2010-August/msg00607.html v4: * Move exporting public API to this patch * Add unsigned int flags to the public api for future extensions v3: * Add domainGetMemoryParamters and NULL in all the driver interface v2: * Initialize domainSetMemoryParameters to NULL in all the driver interface structure. Signed-off-by: Nikunj A. Dadhania nik...@linux.vnet.ibm.com --- src/driver.h | 14 ++ src/esx/esx_driver.c |2 + src/libvirt.c | 104 src/libvirt_public.syms|6 +++ src/lxc/lxc_driver.c |2 + src/openvz/openvz_driver.c |2 + src/phyp/phyp_driver.c |2 + src/qemu/qemu_driver.c |2 + src/remote/remote_driver.c |2 + src/test/test_driver.c |2 + src/uml/uml_driver.c |2 + src/xen/xen_driver.c |2 + 12 files changed, 142 insertions(+), 0 deletions(-) diff --git a/src/driver.h b/src/driver.h index e443c1c..32aeb04 100644 --- a/src/driver.h +++ b/src/driver.h @@ -128,6 +128,18 @@ typedef int (*virDrvDomainSetMemory) (virDomainPtr domain, unsigned long memory); typedef int +(*virDrvDomainSetMemoryParameters) +(virDomainPtr domain, + virMemoryParameterPtr params, + int nparams, + unsigned int flags); +typedef int +(*virDrvDomainGetMemoryParameters) +(virDomainPtr domain, + virMemoryParameterPtr params, + int *nparams, + unsigned int flags); +typedef int (*virDrvDomainGetInfo) (virDomainPtr domain, virDomainInfoPtr info); typedef int @@ -575,6 +587,8 @@ struct _virDriver { virDrvDomainRevertToSnapshot domainRevertToSnapshot; virDrvDomainSnapshotDelete domainSnapshotDelete; virDrvQemuDomainMonitorCommand qemuDomainMonitorCommand; +virDrvDomainSetMemoryParameters domainSetMemoryParameters; +virDrvDomainGetMemoryParameters domainGetMemoryParameters; }; typedef int diff --git a/src/esx/esx_driver.c b/src/esx/esx_driver.c index e382950..e959be2 100644 --- a/src/esx/esx_driver.c +++ b/src/esx/esx_driver.c @@ -4217,6 +4217,8 @@ static virDriver esxDriver = { esxDomainRevertToSnapshot, /* domainRevertToSnapshot */ esxDomainSnapshotDelete, /* domainSnapshotDelete */ NULL,/* qemuDomainMonitorCommand */ +NULL,/* domainSetMemoryParameters */ +NULL,/* domainGetMemoryParameters */ }; diff --git a/src/libvirt.c b/src/libvirt.c index ca383ba..d964a44 100644 --- a/src/libvirt.c +++ b/src/libvirt.c @@ -3000,6 +3000,110 @@ error: } /** + * virDomainSetMemoryParameters: + * @domain: pointer to domain object + * @params: pointer to memory parameter objects + * @nparams: number of memory parameter (this value should be same or + * less than the number of parameters supported) + * @flags: currently unused, for future extension + * + * Change the memory tunables + * This function requires privileged access to the hypervisor. + * + * Returns -1 in case of error, 0 in case of success. + */ +int +virDomainSetMemoryParameters(virDomainPtr domain, +virMemoryParameterPtr params, +int nparams, unsigned int flags) +{ +virConnectPtr conn; +DEBUG(domain=%p, params=%p, nparams=%d, flags=%u, domain, params, nparams, flags); + +virResetLastError(); + +if (!VIR_IS_CONNECTED_DOMAIN(domain)) { +virLibDomainError(NULL, VIR_ERR_INVALID_DOMAIN, __FUNCTION__); +virDispatchError(NULL); +return -1; +} +if (domain-conn-flags VIR_CONNECT_RO) { +virLibDomainError(domain, VIR_ERR_OPERATION_DENIED, __FUNCTION__); +goto error; +} +conn = domain-conn; + +if (conn-driver-domainSetMemoryParameters) { +int ret; +ret = conn-driver-domainSetMemoryParameters (domain, params, nparams, flags); +if (ret 0) +goto error; +return ret; +} + +virLibConnError (conn, VIR_ERR_NO_SUPPORT, __FUNCTION__); + +error: +virDispatchError(domain-conn); +return -1; +} + +/** + * virDomainGetMemoryParameters: + * @domain: pointer to domain object + * @params: pointer to memory parameter object + * (return value, allocated by the caller) + * @nparams: pointer to number of memory parameters + * @flags: currently unused, for future extension + * + * Get the
[libvirt] [PATCH v4 05/13] Implement cgroup memory controller tunables
From: Nikunj A. Dadhania nik...@linux.vnet.ibm.com Provides interfaces for setting/getting memory tunables like hard_limit, soft_limit and swap_hard_limit Acked-by: Balbir Singh bal...@linux.vnet.ibm.com Signed-off-by: Nikunj A. Dadhania nik...@linux.vnet.ibm.com --- src/libvirt_private.syms |6 +++ src/util/cgroup.c| 106 ++ src/util/cgroup.h|7 +++ 3 files changed, 119 insertions(+), 0 deletions(-) diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms index 301b0ef..09b108c 100644 --- a/src/libvirt_private.syms +++ b/src/libvirt_private.syms @@ -77,6 +77,12 @@ virCgroupControllerTypeFromString; virCgroupGetCpuacctUsage; virCgroupGetFreezerState; virCgroupSetFreezerState; +virCgroupSetMemoryHardLimit; +virCgroupGetMemoryHardLimit; +virCgroupSetMemorySoftLimit; +virCgroupGetMemorySoftLimit; +virCgroupSetSwapHardLimit; +virCgroupGetSwapHardLimit; # cpu.h diff --git a/src/util/cgroup.c b/src/util/cgroup.c index 024036a..f94db12 100644 --- a/src/util/cgroup.c +++ b/src/util/cgroup.c @@ -874,6 +874,112 @@ int virCgroupGetMemoryUsage(virCgroupPtr group, unsigned long *kb) } /** + * virCgroupSetMemoryHardLimit: + * + * @group: The cgroup to change memory hard limit for + * @kb: The memory amount in kilobytes + * + * Returns: 0 on success + */ +int virCgroupSetMemoryHardLimit(virCgroupPtr group, unsigned long kb) +{ +return virCgroupSetMemory(group, kb); +} + +/** + * virCgroupGetMemoryHardLimit: + * + * @group: The cgroup to get the memory hard limit for + * @kb: The memory amount in kilobytes + * + * Returns: 0 on success + */ +int virCgroupGetMemoryHardLimit(virCgroupPtr group, unsigned long *kb) +{ +long long unsigned int limit_in_bytes; +int ret; +ret = virCgroupGetValueU64(group, + VIR_CGROUP_CONTROLLER_MEMORY, + memory.limit_in_bytes, limit_in_bytes); +if (ret == 0) +*kb = (unsigned long) limit_in_bytes 10; +return ret; +} + +/** + * virCgroupSetMemorySoftLimit: + * + * @group: The cgroup to change memory soft limit for + * @kb: The memory amount in kilobytes + * + * Returns: 0 on success + */ +int virCgroupSetMemorySoftLimit(virCgroupPtr group, unsigned long kb) +{ +return virCgroupSetValueU64(group, +VIR_CGROUP_CONTROLLER_MEMORY, +memory.soft_limit_in_bytes, +kb 10); +} + + +/** + * virCgroupGetMemorySoftLimit: + * + * @group: The cgroup to get the memory soft limit for + * @kb: The memory amount in kilobytes + * + * Returns: 0 on success + */ +int virCgroupGetMemorySoftLimit(virCgroupPtr group, unsigned long *kb) +{ +long long unsigned int limit_in_bytes; +int ret; +ret = virCgroupGetValueU64(group, + VIR_CGROUP_CONTROLLER_MEMORY, + memory.soft_limit_in_bytes, limit_in_bytes); +if (ret == 0) +*kb = (unsigned long) limit_in_bytes 10; +return ret; +} + +/** + * virCgroupSetSwapHardLimit: + * + * @group: The cgroup to change swap hard limit for + * @kb: The swap amount in kilobytes + * + * Returns: 0 on success + */ +int virCgroupSetSwapHardLimit(virCgroupPtr group, unsigned long kb) +{ +return virCgroupSetValueU64(group, +VIR_CGROUP_CONTROLLER_MEMORY, +memory.memsw.limit_in_bytes, +kb 10); +} + +/** + * virCgroupGetSwapHardLimit: + * + * @group: The cgroup to get swap hard limit for + * @kb: The swap amount in kilobytes + * + * Returns: 0 on success + */ +int virCgroupGetSwapHardLimit(virCgroupPtr group, unsigned long *kb) +{ +long long unsigned int limit_in_bytes; +int ret; +ret = virCgroupGetValueU64(group, + VIR_CGROUP_CONTROLLER_MEMORY, + memory.memsw.limit_in_bytes, limit_in_bytes); +if (ret == 0) +*kb = (unsigned long) limit_in_bytes 10; +return ret; +} + +/** * virCgroupDenyAllDevices: * * @group: The cgroup to deny devices for diff --git a/src/util/cgroup.h b/src/util/cgroup.h index 2bea49f..b8f2d08 100644 --- a/src/util/cgroup.h +++ b/src/util/cgroup.h @@ -43,6 +43,13 @@ int virCgroupAddTask(virCgroupPtr group, pid_t pid); int virCgroupSetMemory(virCgroupPtr group, unsigned long kb); int virCgroupGetMemoryUsage(virCgroupPtr group, unsigned long *kb); +int virCgroupSetMemoryHardLimit(virCgroupPtr group, unsigned long kb); +int virCgroupGetMemoryHardLimit(virCgroupPtr group, unsigned long *kb); +int virCgroupSetMemorySoftLimit(virCgroupPtr group, unsigned long kb); +int virCgroupGetMemorySoftLimit(virCgroupPtr group, unsigned long *kb); +int virCgroupSetSwapHardLimit(virCgroupPtr group, unsigned long kb); +int virCgroupGetSwapHardLimit(virCgroupPtr group, unsigned long *kb); + int virCgroupDenyAllDevices(virCgroupPtr group);
[libvirt] [PATCH v4 03/13] Adds xml entries for memory tunables
From: Nikunj A. Dadhania nik...@linux.vnet.ibm.com The patch adds xml entries to the domain.rng file. v2: + Fix typo min_guarantee Acked-by: Daniel P. Berrange berra...@redhat.com Signed-off-by: Nikunj A. Dadhania nik...@linux.vnet.ibm.com --- docs/schemas/domain.rng | 31 +++ 1 files changed, 31 insertions(+), 0 deletions(-) diff --git a/docs/schemas/domain.rng b/docs/schemas/domain.rng index 2e0457b..6cbace0 100644 --- a/docs/schemas/domain.rng +++ b/docs/schemas/domain.rng @@ -299,6 +299,37 @@ /optional /element /optional + + !-- All the memory/swap related tunables would go in the memtune -- + optional + element name=memtune + !-- Maximum memory the VM can use -- + optional + element name=hard_limit + ref name=memoryKB/ + /element + /optional + !-- Minimum memory ascertained for the VM during contention -- + optional + element name=soft_limit + ref name=memoryKB/ + /element + /optional + !-- Minimum amount of memory required to start the VM -- + optional + element name=min_guarantee + ref name=memoryKB/ + /element + /optional + !-- Maximum swap area the VM can use -- + optional + element name=swap_hard_limit + ref name=memoryKB/ + /element + /optional + /element + /optional + optional element name=vcpu optional -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
[libvirt] [PATCH v4 09/13] Adding memtunables to libvirt-lxc command
From: Nikunj A. Dadhania nik...@linux.vnet.ibm.com v4: * Fix: call cgroup apis only if tunables are non zero v1: libvirt-lxc now configures the hardlimit, softlimit and swaplimit, if specified in the domain xml file or picks up the defaults. Acked-by: Daniel P. Berrange berra...@redhat.com Signed-off-by: Nikunj A. Dadhania nik...@linux.vnet.ibm.com --- src/lxc/lxc_controller.c | 30 ++ 1 files changed, 30 insertions(+), 0 deletions(-) diff --git a/src/lxc/lxc_controller.c b/src/lxc/lxc_controller.c index 82ecce0..258130d 100644 --- a/src/lxc/lxc_controller.c +++ b/src/lxc/lxc_controller.c @@ -109,6 +109,36 @@ static int lxcSetContainerResources(virDomainDefPtr def) def-name); goto cleanup; } + +if(def-mem.hard_limit) { +rc = virCgroupSetMemoryHardLimit(cgroup, def-mem.hard_limit); +if (rc != 0) { +virReportSystemError(-rc, + _(Unable to set memory hard limit for domain %s), + def-name); +goto cleanup; +} +} + +if(def-mem.soft_limit) { +rc = virCgroupSetMemorySoftLimit(cgroup, def-mem.soft_limit); +if (rc != 0) { +virReportSystemError(-rc, + _(Unable to set memory soft limit for domain %s), + def-name); +goto cleanup; +} +} + +if(def-mem.swap_hard_limit) { +rc = virCgroupSetSwapHardLimit(cgroup, def-mem.swap_hard_limit); +if (rc != 0) { +virReportSystemError(-rc, + _(Unable to set swap hard limit for domain %s), + def-name); +goto cleanup; +} +} rc = virCgroupDenyAllDevices(cgroup); if (rc != 0) { -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
[libvirt] [PATCH v4 10/13] Implement driver interface domainSetMemoryParamters for LXC
From: Nikunj A. Dadhania nik...@linux.vnet.ibm.com Add support in the lxc driver for various memory controllable parameters v4: + prototype change: add unsigned int flags v2: + Use #define string constants for hard_limit, etc + fix typo: min_guarantee Acked-by: Daniel P. Berrange berra...@redhat.com Signed-off-by: Nikunj A. Dadhania nik...@linux.vnet.ibm.com --- src/lxc/lxc_driver.c | 91 +- 1 files changed, 90 insertions(+), 1 deletions(-) diff --git a/src/lxc/lxc_driver.c b/src/lxc/lxc_driver.c index 8977835..984a5fa 100644 --- a/src/lxc/lxc_driver.c +++ b/src/lxc/lxc_driver.c @@ -677,6 +677,95 @@ cleanup: return ret; } +static int lxcDomainSetMemoryParameters(virDomainPtr dom, +virMemoryParameterPtr params, +int nparams, +unsigned int flags ATTRIBUTE_UNUSED) +{ +lxc_driver_t *driver = dom-conn-privateData; +int i; +virCgroupPtr cgroup = NULL; +virDomainObjPtr vm = NULL; +int ret = -1; + +lxcDriverLock(driver); +vm = virDomainFindByUUID(driver-domains, dom-uuid); + +if (vm == NULL) { +char uuidstr[VIR_UUID_STRING_BUFLEN]; +virUUIDFormat(dom-uuid, uuidstr); +lxcError(VIR_ERR_NO_DOMAIN, + _(No domain with matching uuid '%s'), uuidstr); +goto cleanup; +} + +if (virCgroupForDomain(driver-cgroup, vm-def-name, cgroup, 0) != 0) { +lxcError(VIR_ERR_INTERNAL_ERROR, + _(Unable to get cgroup for %s), vm-def-name); +goto cleanup; +} + +for (i = 0; i nparams; i++) { +virMemoryParameterPtr param = params[i]; + +if (STREQ(param-field, VIR_DOMAIN_MEMORY_HARD_LIMIT)) { +int rc; +if (param-type != VIR_DOMAIN_MEMORY_FIELD_ULLONG) { +lxcError(VIR_ERR_INVALID_ARG, %s, + _(invalid type for memory hard_limit tunable, expected a 'ullong')); +continue; +} + +rc = virCgroupSetMemoryHardLimit(cgroup, params[i].value.ul); +if (rc != 0) { +virReportSystemError(-rc, %s, + _(unable to set memory hard_limit tunable)); +} +} else if (STREQ(param-field, VIR_DOMAIN_MEMORY_SOFT_LIMIT)) { +int rc; +if (param-type != VIR_DOMAIN_MEMORY_FIELD_ULLONG) { +lxcError(VIR_ERR_INVALID_ARG, %s, + _(invalid type for memory soft_limit tunable, expected a 'ullong')); +continue; +} + +rc = virCgroupSetMemorySoftLimit(cgroup, params[i].value.ul); +if (rc != 0) { +virReportSystemError(-rc, %s, + _(unable to set memory soft_limit tunable)); +} +} else if (STREQ(param-field, VIR_DOMAIN_SWAP_HARD_LIMIT)) { +int rc; +if (param-type != VIR_DOMAIN_MEMORY_FIELD_ULLONG) { +lxcError(VIR_ERR_INVALID_ARG, %s, + _(invalid type for swap_hard_limit tunable, expected a 'ullong')); +continue; +} + +rc = virCgroupSetSwapHardLimit(cgroup, params[i].value.ul); +if (rc != 0) { +virReportSystemError(-rc, %s, + _(unable to set swap_hard_limit tunable)); +} +} else if (STREQ(param-field, VIR_DOMAIN_MEMORY_MIN_GUARANTEE)) { +lxcError(VIR_ERR_INVALID_ARG, + _(Memory tunable `%s' not implemented), param-field); +} else { +lxcError(VIR_ERR_INVALID_ARG, + _(Parameter `%s' not supported), param-field); +} +} +ret = 0; + +cleanup: +if (cgroup) +virCgroupFree(cgroup); +if (vm) +virDomainObjUnlock(vm); +lxcDriverUnlock(driver); +return ret; +} + static char *lxcDomainDumpXML(virDomainPtr dom, int flags) { @@ -2620,7 +2709,7 @@ static virDriver lxcDriver = { NULL, /* domainRevertToSnapshot */ NULL, /* domainSnapshotDelete */ NULL, /* qemuDomainMonitorCommand */ -NULL, /* domainSetMemoryParameters */ +lxcDomainSetMemoryParameters, /* domainSetMemoryParameters */ NULL, /* domainGetMemoryParameters */ }; -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
[libvirt] [PATCH v4 11/13] Implement driver interface domainGetMemoryParamters for LXC
From: Nikunj A. Dadhania nik...@linux.vnet.ibm.com v4: * prototype change: add unsigned int flags Driver interface for getting memory parameters, eg. hard_limit, soft_limit and swap_hard_limit. Signed-off-by: Nikunj A. Dadhania nik...@linux.vnet.ibm.com --- src/lxc/lxc_driver.c | 114 ++ 1 files changed, 113 insertions(+), 1 deletions(-) diff --git a/src/lxc/lxc_driver.c b/src/lxc/lxc_driver.c index 984a5fa..036dedf 100644 --- a/src/lxc/lxc_driver.c +++ b/src/lxc/lxc_driver.c @@ -766,6 +766,118 @@ cleanup: return ret; } +static int lxcDomainGetMemoryParameters(virDomainPtr dom, +virMemoryParameterPtr params, +int *nparams, +unsigned int flags ATTRIBUTE_UNUSED) +{ +lxc_driver_t *driver = dom-conn-privateData; +int i; +virCgroupPtr cgroup = NULL; +virDomainObjPtr vm = NULL; +unsigned long val; +int ret = -1; +int rc; + +lxcDriverLock(driver); +vm = virDomainFindByUUID(driver-domains, dom-uuid); + +if (vm == NULL) { +char uuidstr[VIR_UUID_STRING_BUFLEN]; +virUUIDFormat(dom-uuid, uuidstr); +lxcError(VIR_ERR_NO_DOMAIN, + _(No domain with matching uuid '%s'), uuidstr); +goto cleanup; +} + +if ((*nparams) == 0) { +/* Current number of memory parameters supported by cgroups is 3 + * FIXME: Magic number, need to see where should this go + */ +*nparams = 3; +ret = 0; +goto cleanup; +} +if ((*nparams) != 3) { +lxcError(VIR_ERR_INVALID_ARG, + %s, _(Invalid parameter count)); +goto cleanup; +} + +if (virCgroupForDomain(driver-cgroup, vm-def-name, cgroup, 0) != 0) { +lxcError(VIR_ERR_INTERNAL_ERROR, + _(Unable to get cgroup for %s), vm-def-name); +goto cleanup; +} + +for (i = 0; i *nparams; i++) { +virMemoryParameterPtr param = params[i]; +val = 0; +param-value.ul = 0; +param-type = VIR_DOMAIN_MEMORY_FIELD_ULLONG; + +switch(i) { +case 0: /* fill memory hard limit here */ +rc = virCgroupGetMemoryHardLimit(cgroup, val); +if (rc != 0) { +virReportSystemError(-rc, %s, + _(unable to get memory hard limit)); +continue; +} +if (virStrcpyStatic(param-field, VIR_DOMAIN_MEMORY_HARD_LIMIT) == NULL) { +lxcError(VIR_ERR_INTERNAL_ERROR, + %s, _(Field memory hard limit too long for destination)); +continue; +} +param-value.ul = val; +break; + +case 1: /* fill memory soft limit here */ +rc = virCgroupGetMemorySoftLimit(cgroup, val); +if (rc != 0) { +virReportSystemError(-rc, %s, + _(unable to get memory soft limit)); +continue; +} +if (virStrcpyStatic(param-field, VIR_DOMAIN_MEMORY_SOFT_LIMIT) == NULL) { +lxcError(VIR_ERR_INTERNAL_ERROR, + %s, _(Field memory soft limit too long for destination)); +continue; +} +param-value.ul = val; +break; + +case 2: /* fill swap hard limit here */ +rc = virCgroupGetSwapHardLimit(cgroup, val); +if (rc != 0) { +virReportSystemError(-rc, %s, + _(unable to get swap hard limit)); +continue; +} +if (virStrcpyStatic(param-field, VIR_DOMAIN_SWAP_HARD_LIMIT) == NULL) { +lxcError(VIR_ERR_INTERNAL_ERROR, + %s, _(Field swap hard limit too long for destination)); +continue; +} +param-value.ul = val; +break; + +default: +break; +/* should not hit here */ +} +} +ret = 0; + +cleanup: +if (cgroup) +virCgroupFree(cgroup); +if (vm) +virDomainObjUnlock(vm); +lxcDriverUnlock(driver); +return ret; +} + static char *lxcDomainDumpXML(virDomainPtr dom, int flags) { @@ -2710,7 +2822,7 @@ static virDriver lxcDriver = { NULL, /* domainSnapshotDelete */ NULL, /* qemuDomainMonitorCommand */ lxcDomainSetMemoryParameters, /* domainSetMemoryParameters */ -NULL, /* domainGetMemoryParameters */ +lxcDomainGetMemoryParameters, /* domainGetMemoryParameters */ }; static virStateDriver lxcStateDriver = { -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
[libvirt] [PATCH v4 12/13] Adding memtune command to virsh tool
From: Nikunj A. Dadhania nik...@linux.vnet.ibm.com The command helps to control the memory/swap parameters for the system, for eg. hard_limit (max memory the vm can use), soft_limit (limit during memory contention), swap_hard_limit(max swap the vm can use) v4: + virDomainSet/GetMemoryParameters prototype change + Move exporting of the symbol to patch 2 v3: + Added call to virDomainGetMemoryParameters and print them. + Added virDomainGetMemoryParameters and virDomainSetMemoryParamters to libvirt_public.syms v2: + Use #define string constants for hard_limit, etc Signed-off-by: Nikunj A. Dadhania nik...@linux.vnet.ibm.com --- tools/virsh.c | 130 + 1 files changed, 130 insertions(+), 0 deletions(-) diff --git a/tools/virsh.c b/tools/virsh.c index 85014f2..a9fcc28 100644 --- a/tools/virsh.c +++ b/tools/virsh.c @@ -2614,6 +2614,135 @@ cmdSetmaxmem(vshControl *ctl, const vshCmd *cmd) } /* + * memtune command + */ +static const vshCmdInfo info_memtune[] = { +{help, N_(Get/Set memory paramters)}, +{desc, N_(Get/Set the current memory paramters for the guest domain.\n \ +To get the memory parameters use following command: \n\n \ +virsh # memtune domain)}, +{NULL, NULL} +}; + +static const vshCmdOptDef opts_memtune[] = { +{domain, VSH_OT_DATA, VSH_OFLAG_REQ, N_(domain name, id or uuid)}, +{VIR_DOMAIN_MEMORY_HARD_LIMIT, VSH_OT_STRING, VSH_OFLAG_NONE, N_(Max memory in kilobytes)}, +{VIR_DOMAIN_MEMORY_SOFT_LIMIT, VSH_OT_STRING, VSH_OFLAG_NONE, N_(Memory during contention in kilobytes)}, +{VIR_DOMAIN_SWAP_HARD_LIMIT, VSH_OT_STRING, VSH_OFLAG_NONE, N_(Max swap in kilobytes)}, +{NULL, 0, 0, NULL} +}; + +static int +cmdMemtune(vshControl *ctl, const vshCmd *cmd) +{ +virDomainPtr dom; +int hard_limit, soft_limit, swap_hard_limit; +int nparams = 0; +unsigned int i = 0; +virMemoryParameterPtr params = NULL, temp = NULL; +int ret = FALSE; + +if (!vshConnectionUsability(ctl, ctl-conn)) +return FALSE; + +if (!(dom = vshCommandOptDomain(ctl, cmd, NULL))) +return FALSE; + +hard_limit = vshCommandOptInt(cmd, VIR_DOMAIN_MEMORY_HARD_LIMIT, hard_limit); +if (hard_limit) +nparams++; + +soft_limit = vshCommandOptInt(cmd, VIR_DOMAIN_MEMORY_SOFT_LIMIT, soft_limit); +if (soft_limit) +nparams++; + +swap_hard_limit = vshCommandOptInt(cmd, VIR_DOMAIN_SWAP_HARD_LIMIT, swap_hard_limit); +if (swap_hard_limit) +nparams++; + +if(nparams == 0) { +/* get the number of memory parameters */ +if (virDomainGetMemoryParameters(dom, NULL, nparams, 0) != 0 (nparams != 0)) { +vshError(ctl, %s, _(Unable to get number of memory parameters)); +goto cleanup; +} + +/* now go get all the memory parameters */ +params = vshMalloc(ctl, sizeof(virMemoryParameter)* nparams); +memset(params, 0, sizeof(virMemoryParameter)* nparams); +if (virDomainGetMemoryParameters(dom, params, nparams, 0)) { +vshError(ctl, %s, _(Unable to get memory parameters)); +goto cleanup; +} + +for (i = 0; i nparams; i++){ +switch (params[i].type) { +case VIR_DOMAIN_MEMORY_FIELD_INT: +vshPrint(ctl, %-15s: %d\n, params[i].field, params[i].value.i); +break; +case VIR_DOMAIN_MEMORY_FIELD_UINT: +vshPrint(ctl, %-15s: %u\n, params[i].field, params[i].value.ui); +break; +case VIR_DOMAIN_MEMORY_FIELD_LLONG: +vshPrint(ctl, %-15s: %lld\n, params[i].field, params[i].value.l); +break; +case VIR_DOMAIN_MEMORY_FIELD_ULLONG: +vshPrint(ctl, %-15s: %llu\n, params[i].field, params[i].value.ul); +break; +case VIR_DOMAIN_MEMORY_FIELD_DOUBLE: +vshPrint(ctl, %-15s: %f\n, params[i].field, params[i].value.d); +break; +case VIR_DOMAIN_MEMORY_FIELD_BOOLEAN: +vshPrint(ctl, %-15s: %d\n, params[i].field, params[i].value.b); +break; +default: +vshPrint(ctl, not implemented scheduler parameter type\n); +} +} + +ret = TRUE; +} else { +/* set the memory parameters */ +params = vshMalloc(ctl, sizeof(virMemoryParameter)* nparams); + +memset(params, 0, sizeof(virMemoryParameter)* nparams); +for(i = 0; i nparams; i++) +{ +temp = params[i]; +temp-type = VIR_DOMAIN_MEMORY_FIELD_ULLONG; + +/* + * Some magic here, this is used to fill the params structure with + * the valid arguments passed, after filling the particular + * argument we purposely make them 0, so on the next pass it goes +
[libvirt] [PATCH v4 08/13] Adding memtunables to qemuSetupCgroup
From: Nikunj A. Dadhania nik...@linux.vnet.ibm.com v4: * Fix: call cgroup apis only if tunables are non zero QEmu startup would pick up the memory tunables specified in the domain configuration file. Acked-by: Daniel P. Berrange berra...@redhat.com Signed-off-by: Nikunj A. Dadhania nik...@linux.vnet.ibm.com --- src/qemu/qemu.conf |4 ++-- src/qemu/qemu_conf.c |3 ++- src/qemu/qemu_driver.c | 34 ++ 3 files changed, 38 insertions(+), 3 deletions(-) diff --git a/src/qemu/qemu.conf b/src/qemu/qemu.conf index dc8eb83..bfb9f6a 100644 --- a/src/qemu/qemu.conf +++ b/src/qemu/qemu.conf @@ -111,13 +111,13 @@ # the adminsitrator has mounted cgroups. eg # # mkdir /dev/cgroup -# mount -t cgroup -o devices,cpu none /dev/cgroup +# mount -t cgroup -o devices,cpu,memory none /dev/cgroup # # They can be mounted anywhere, and different controlers # can be mounted in different locations. libvirt will detect # where they are located. # -# cgroup_controllers = [ cpu, devices ] +# cgroup_controllers = [ cpu, devices, memory ] # This is the basic set of devices allowed / required by # all virtual machines. diff --git a/src/qemu/qemu_conf.c b/src/qemu/qemu_conf.c index 731c554..3f5c1ac 100644 --- a/src/qemu/qemu_conf.c +++ b/src/qemu/qemu_conf.c @@ -275,7 +275,8 @@ int qemudLoadDriverConfig(struct qemud_driver *driver, } else { driver-cgroupControllers = (1 VIR_CGROUP_CONTROLLER_CPU) | -(1 VIR_CGROUP_CONTROLLER_DEVICES); +(1 VIR_CGROUP_CONTROLLER_DEVICES) | +(1 VIR_CGROUP_CONTROLLER_MEMORY); } for (i = 0 ; i VIR_CGROUP_CONTROLLER_LAST ; i++) { if (driver-cgroupControllers (1 i)) { diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c index 8eaa762..70b9bac 100644 --- a/src/qemu/qemu_driver.c +++ b/src/qemu/qemu_driver.c @@ -3495,6 +3495,40 @@ static int qemuSetupCgroup(struct qemud_driver *driver, goto cleanup; } +if ((rc = qemuCgroupControllerActive(driver, VIR_CGROUP_CONTROLLER_MEMORY))) { +if (vm-def-mem.hard_limit != 0) { +rc = virCgroupSetMemoryHardLimit(cgroup, vm-def-mem.hard_limit); +if (rc != 0) { +virReportSystemError(-rc, + _(Unable to set memory hard limit for domain %s), + vm-def-name); +goto cleanup; +} +} +if (vm-def-mem.soft_limit != 0) { +rc = virCgroupSetMemorySoftLimit(cgroup, vm-def-mem.soft_limit); +if (rc != 0) { +virReportSystemError(-rc, + _(Unable to set memory soft limit for domain %s), + vm-def-name); +goto cleanup; +} +} + +if (vm-def-mem.swap_hard_limit != 0) { +rc = virCgroupSetSwapHardLimit(cgroup, vm-def-mem.swap_hard_limit); +if (rc != 0) { +virReportSystemError(-rc, + _(Unable to set swap hard limit for domain %s), + vm-def-name); +goto cleanup; +} +} +} else { +VIR_WARN(Memory cgroup is disabled in qemu configuration file: %s, + vm-def-name); +} + done: virCgroupFree(cgroup); return 0; -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
[libvirt] [PATCH v4 07/13] Implement driver interface domainGetMemoryParamters for QEmu
From: Nikunj A. Dadhania nik...@linux.vnet.ibm.com V4: * prototype change: add unsigned int flags Driver interface for getting memory parameters, eg. hard_limit, soft_limit and swap_hard_limit. Signed-off-by: Nikunj A. Dadhania nik...@linux.vnet.ibm.com --- src/qemu/qemu_driver.c | 120 1 files changed, 119 insertions(+), 1 deletions(-) diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c index 471db39..8eaa762 100644 --- a/src/qemu/qemu_driver.c +++ b/src/qemu/qemu_driver.c @@ -9458,6 +9458,124 @@ cleanup: return ret; } +static int qemuDomainGetMemoryParameters(virDomainPtr dom, + virMemoryParameterPtr params, + int *nparams, + unsigned int flags ATTRIBUTE_UNUSED) +{ +struct qemud_driver *driver = dom-conn-privateData; +int i; +virCgroupPtr group = NULL; +virDomainObjPtr vm = NULL; +unsigned long val; +int ret = -1; +int rc; + +qemuDriverLock(driver); + +if (!qemuCgroupControllerActive(driver, VIR_CGROUP_CONTROLLER_MEMORY)) { +qemuReportError(VIR_ERR_NO_SUPPORT, +__FUNCTION__); +goto cleanup; +} + +vm = virDomainFindByUUID(driver-domains, dom-uuid); + +if (vm == NULL) { +qemuReportError(VIR_ERR_INTERNAL_ERROR, +_(No such domain %s), dom-uuid); +goto cleanup; +} + +if ((*nparams) == 0) { +/* Current number of memory parameters supported by cgroups is 3 + * FIXME: Magic number, need to see where should this go + */ +*nparams = 3; +ret = 0; +goto cleanup; +} + +if ((*nparams) != 3) { +qemuReportError(VIR_ERR_INVALID_ARG, +%s, _(Invalid parameter count)); +goto cleanup; +} + +if (virCgroupForDomain(driver-cgroup, vm-def-name, group, 0) != 0) { +qemuReportError(VIR_ERR_INTERNAL_ERROR, +_(cannot find cgroup for domain %s), vm-def-name); +goto cleanup; +} + +for (i = 0; i *nparams; i++) { +virMemoryParameterPtr param = params[i]; +val = 0; +param-value.ul = 0; +param-type = VIR_DOMAIN_MEMORY_FIELD_ULLONG; + +switch(i) { +case 0: /* fill memory hard limit here */ +rc = virCgroupGetMemoryHardLimit(group, val); +if (rc != 0) { +virReportSystemError(-rc, %s, + _(unable to get memory hard limit)); +continue; +} +if (virStrcpyStatic(param-field, VIR_DOMAIN_MEMORY_HARD_LIMIT) == NULL) { +qemuReportError(VIR_ERR_INTERNAL_ERROR, +%s, _(Field memory hard limit too long for destination)); +continue; +} +param-value.ul = val; +break; + +case 1: /* fill memory soft limit here */ +rc = virCgroupGetMemorySoftLimit(group, val); +if (rc != 0) { +virReportSystemError(-rc, %s, + _(unable to get memory soft limit)); +continue; +} +if (virStrcpyStatic(param-field, VIR_DOMAIN_MEMORY_SOFT_LIMIT) == NULL) { +qemuReportError(VIR_ERR_INTERNAL_ERROR, +%s, _(Field memory soft limit too long for destination)); +continue; +} +param-value.ul = val; +break; + +case 2: /* fill swap hard limit here */ +rc = virCgroupGetSwapHardLimit(group, val); +if (rc != 0) { +virReportSystemError(-rc, %s, + _(unable to get swap hard limit)); +continue; +} +if (virStrcpyStatic(param-field, VIR_DOMAIN_SWAP_HARD_LIMIT) == NULL) { +qemuReportError(VIR_ERR_INTERNAL_ERROR, +%s, _(Field swap hard limit too long for destination)); +continue; +} +param-value.ul = val; +break; + +default: +break; +/* should not hit here */ +} +} +ret = 0; + +cleanup: +if (group) +virCgroupFree(group); +if (vm) +virDomainObjUnlock(vm); +qemuDriverUnlock(driver); +return ret; +} + static int qemuSetSchedulerParameters(virDomainPtr dom, virSchedParameterPtr params, int nparams) @@ -12804,7 +12922,7 @@ static virDriver qemuDriver = { qemuDomainSnapshotDelete, /* domainSnapshotDelete */ qemuDomainMonitorCommand, /* qemuDomainMonitorCommand */ qemuDomainSetMemoryParameters, /* domainSetMemoryParameters */ -NULL,
[libvirt] [PATCH v4 13/13] Remote protocol changes and implements virDomainSet/GetMemoryParameters
From: Nikunj A. Dadhania nik...@linux.vnet.ibm.com v4: * prototype change: add unsigned int flags, regenerate files v3: * Squased all the remote driver changes to one single big patch and auto-generated is around 40% * Implements domainSetMemoryParameters and domainGetMemoryParameters for remote driver daemon/remote.c src/remote/remote_driver.c * Auto generate the files using rpcgen and helper scripts in daemon/ directory src/remote/remote_protocol.x daemon/remote_dispatch_args.h daemon/remote_dispatch_prototypes.h daemon/remote_dispatch_ret.h daemon/remote_dispatch_table.h src/remote/remote_protocol.c src/remote/remote_protocol.h Acked-by: Daniel P. Berrange berra...@redhat.com Signed-off-by: Nikunj A. Dadhania nik...@linux.vnet.ibm.com --- daemon/remote.c | 162 +++ daemon/remote_dispatch_args.h |2 daemon/remote_dispatch_prototypes.h | 16 +++ daemon/remote_dispatch_ret.h|1 daemon/remote_dispatch_table.h | 10 ++ src/remote/remote_driver.c | 153 + src/remote/remote_protocol.c| 88 +++ src/remote/remote_protocol.h| 58 + src/remote/remote_protocol.x| 44 +- 9 files changed, 531 insertions(+), 3 deletions(-) diff --git a/daemon/remote.c b/daemon/remote.c index 6b67678..d5a8a9c 100644 --- a/daemon/remote.c +++ b/daemon/remote.c @@ -2332,6 +2332,168 @@ remoteDispatchDomainSetMemory (struct qemud_server *server ATTRIBUTE_UNUSED, } static int +remoteDispatchDomainSetMemoryParameters (struct qemud_server *server ATTRIBUTE_UNUSED, + struct qemud_client *client ATTRIBUTE_UNUSED, + virConnectPtr conn, + remote_message_header *hdr ATTRIBUTE_UNUSED, + remote_error *rerr, + remote_domain_set_memory_parameters_args *args, + void *ret ATTRIBUTE_UNUSED) +{ +virDomainPtr dom; +int i, r, nparams; +virMemoryParameterPtr params; +unsigned int flags; + +nparams = args-params.params_len; +nparams = args-flags; + +if (nparams REMOTE_DOMAIN_MEMORY_PARAMETERS_MAX) { +remoteDispatchFormatError (rerr, %s, _(nparams too large)); +return -1; +} +if (VIR_ALLOC_N(params, nparams) 0) { +remoteDispatchOOMError(rerr); +return -1; +} + +/* Deserialise parameters. */ +for (i = 0; i nparams; ++i) { +if (virStrcpyStatic(params[i].field, args-params.params_val[i].field) == NULL) { +remoteDispatchFormatError(rerr, _(Field %s too big for destination), + args-params.params_val[i].field); +return -1; +} +params[i].type = args-params.params_val[i].value.type; +switch (params[i].type) { +case VIR_DOMAIN_MEMORY_FIELD_INT: +params[i].value.i = args-params.params_val[i].value.remote_memory_param_value_u.i; break; +case VIR_DOMAIN_MEMORY_FIELD_UINT: +params[i].value.ui = args-params.params_val[i].value.remote_memory_param_value_u.ui; break; +case VIR_DOMAIN_MEMORY_FIELD_LLONG: +params[i].value.l = args-params.params_val[i].value.remote_memory_param_value_u.l; break; +case VIR_DOMAIN_MEMORY_FIELD_ULLONG: +params[i].value.ul = args-params.params_val[i].value.remote_memory_param_value_u.ul; break; +case VIR_DOMAIN_MEMORY_FIELD_DOUBLE: +params[i].value.d = args-params.params_val[i].value.remote_memory_param_value_u.d; break; +case VIR_DOMAIN_MEMORY_FIELD_BOOLEAN: +params[i].value.b = args-params.params_val[i].value.remote_memory_param_value_u.b; break; +} +} + +dom = get_nonnull_domain (conn, args-dom); +if (dom == NULL) { +VIR_FREE(params); +remoteDispatchConnError(rerr, conn); +return -1; +} + +r = virDomainSetMemoryParameters (dom, params, nparams, flags); +virDomainFree(dom); +VIR_FREE(params); +if (r == -1) { +remoteDispatchConnError(rerr, conn); +return -1; +} + +return 0; +} + +static int remoteDispatchDomainGetMemoryParameters (struct qemud_server *server, +struct qemud_client *client, +virConnectPtr conn, +remote_message_header *hdr, +remote_error *rerr, + remote_domain_get_memory_parameters_args *args, +
[libvirt] [PATCH] Return a suitable error message if we can't find a matching emulator
Hi, attached patch improves the error message when we can't find a suitable emulator. Otherwise it's simply Unknown failure. O.k. to apply? Cheers, -- Guido From 7092e11363983228d005a45c054f9b3604771b10 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Guido=20G=C3=BCnther?= a...@sigxcpu.org Date: Fri, 8 Oct 2010 14:16:46 +0200 Subject: [PATCH] Return a suitable error message if we can't find a matching emulator --- src/qemu/qemu_conf.c |5 - 1 files changed, 4 insertions(+), 1 deletions(-) diff --git a/src/qemu/qemu_conf.c b/src/qemu/qemu_conf.c index 7a37c70..737b255 100644 --- a/src/qemu/qemu_conf.c +++ b/src/qemu/qemu_conf.c @@ -1519,8 +1519,11 @@ int qemudExtractVersion(struct qemud_driver *driver) { if ((binary = virCapabilitiesDefaultGuestEmulator(driver-caps, hvm, ut.machine, - qemu)) == NULL) + qemu)) == NULL) { +qemuReportError(VIR_ERR_INTERNAL_ERROR, +_(Cannot find suitable emulator for %s), ut.machine); return -1; +} if (stat(binary, sb) 0) { virReportSystemError(errno, -- 1.7.1 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
[libvirt] [PATCH] Pass -n to ip(6)tables
Hi, attached patch passes -n to ip(6)tables to avoid long timeouts waiting for DNS servers. O.k. to apply? Cheers, -- Guido From aa7e3226adb2eb333863e0b1e52e26098a7673dc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Guido=20G=C3=BCnther?= a...@sigxcpu.org Date: Fri, 8 Oct 2010 16:35:03 +0200 Subject: [PATCH] Pass -n to ip(6)tables to avoid long timeouts waiting for DNS servers --- src/nwfilter/nwfilter_ebiptables_driver.c |6 +++--- 1 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/nwfilter/nwfilter_ebiptables_driver.c b/src/nwfilter/nwfilter_ebiptables_driver.c index bcbefa7..e831eb3 100644 --- a/src/nwfilter/nwfilter_ebiptables_driver.c +++ b/src/nwfilter/nwfilter_ebiptables_driver.c @@ -655,7 +655,7 @@ iptablesSetupVirtInPost(const char *iptables_cmd, { const char *match = MATCH_PHYSDEV_IN; virBufferVSprintf(buf, - res=$(%s -L VIRT_IN_POST_CHAIN + res=$(%s -n -L VIRT_IN_POST_CHAIN | grep \\\%s %s\)\n if [ \${res}\ == \\ ]; then CMD_DEF(%s @@ -3662,7 +3662,7 @@ ebiptablesDriverInit(void) iptables_cmd_path = virFindFileInPath(iptables); if (iptables_cmd_path) { virBufferVSprintf(buf, - CMD_DEF(%s -L FORWARD) CMD_SEPARATOR + CMD_DEF(%s -n -L FORWARD) CMD_SEPARATOR CMD_EXEC %s, iptables_cmd_path, @@ -3675,7 +3675,7 @@ ebiptablesDriverInit(void) ip6tables_cmd_path = virFindFileInPath(ip6tables); if (ip6tables_cmd_path) { virBufferVSprintf(buf, - CMD_DEF(%s -L FORWARD) CMD_SEPARATOR + CMD_DEF(%s -n -L FORWARD) CMD_SEPARATOR CMD_EXEC %s, ip6tables_cmd_path, -- 1.7.1 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
[libvirt] [PATCH v4 06/13] Implement driver interface domainSetMemoryParamters for QEmu
From: Nikunj A. Dadhania nik...@linux.vnet.ibm.com Driver interface for setting memory hard_limit, soft_limit and swap hard_limit. v4: + prototype change: include unsigned int flags arg v2: + Use #define string constants for hard_limit, etc. + fix typo: min_guarantee Acked-by: Daniel P. Berrange berra...@redhat.com Signed-off-by: Nikunj A. Dadhania nik...@linux.vnet.ibm.com --- src/qemu/qemu_driver.c | 95 +++- 1 files changed, 94 insertions(+), 1 deletions(-) diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c index bf4373a..471db39 100644 --- a/src/qemu/qemu_driver.c +++ b/src/qemu/qemu_driver.c @@ -9365,6 +9365,99 @@ cleanup: return ret; } + +static int qemuDomainSetMemoryParameters(virDomainPtr dom, + virMemoryParameterPtr params, + int nparams, + unsigned int flags ATTRIBUTE_UNUSED) +{ +struct qemud_driver *driver = dom-conn-privateData; +int i; +virCgroupPtr group = NULL; +virDomainObjPtr vm = NULL; +int ret = -1; + +qemuDriverLock(driver); +if (!qemuCgroupControllerActive(driver, VIR_CGROUP_CONTROLLER_MEMORY)) { +qemuReportError(VIR_ERR_NO_SUPPORT, +__FUNCTION__); +goto cleanup; +} + +vm = virDomainFindByUUID(driver-domains, dom-uuid); + +if (vm == NULL) { +qemuReportError(VIR_ERR_INTERNAL_ERROR, +_(No such domain %s), dom-uuid); +goto cleanup; +} + +if (virCgroupForDomain(driver-cgroup, vm-def-name, group, 0) != 0) { +qemuReportError(VIR_ERR_INTERNAL_ERROR, +_(cannot find cgroup for domain %s), vm-def-name); +goto cleanup; +} + +for (i = 0; i nparams; i++) { +virMemoryParameterPtr param = params[i]; + +if (STREQ(param-field, VIR_DOMAIN_MEMORY_HARD_LIMIT)) { +int rc; +if (param-type != VIR_DOMAIN_MEMORY_FIELD_ULLONG) { +qemuReportError(VIR_ERR_INVALID_ARG, %s, +_(invalid type for memory hard_limit tunable, expected a 'ullong')); +continue; +} + +rc = virCgroupSetMemoryHardLimit(group, params[i].value.ul); +if (rc != 0) { +virReportSystemError(-rc, %s, + _(unable to set memory hard_limit tunable)); +} +} else if (STREQ(param-field, VIR_DOMAIN_MEMORY_SOFT_LIMIT)) { +int rc; +if (param-type != VIR_DOMAIN_MEMORY_FIELD_ULLONG) { +qemuReportError(VIR_ERR_INVALID_ARG, %s, +_(invalid type for memory soft_limit tunable, expected a 'ullong')); +continue; +} + +rc = virCgroupSetMemorySoftLimit(group, params[i].value.ul); +if (rc != 0) { +virReportSystemError(-rc, %s, + _(unable to set memory soft_limit tunable)); +} +} else if (STREQ(param-field, VIR_DOMAIN_SWAP_HARD_LIMIT)) { +int rc; +if (param-type != VIR_DOMAIN_MEMORY_FIELD_ULLONG) { +qemuReportError(VIR_ERR_INVALID_ARG, %s, +_(invalid type for swap_hard_limit tunable, expected a 'ullong')); +continue; +} + +rc = virCgroupSetSwapHardLimit(group, params[i].value.ul); +if (rc != 0) { +virReportSystemError(-rc, %s, + _(unable to set swap_hard_limit tunable)); +} +} else if (STREQ(param-field, VIR_DOMAIN_MEMORY_MIN_GUARANTEE)) { +qemuReportError(VIR_ERR_INVALID_ARG, +_(Memory tunable `%s' not implemented), param-field); +} else { +qemuReportError(VIR_ERR_INVALID_ARG, +_(Parameter `%s' not supported), param-field); +} +} +ret = 0; + +cleanup: +virCgroupFree(group); +if (vm) +virDomainObjUnlock(vm); +qemuDriverUnlock(driver); +return ret; +} + static int qemuSetSchedulerParameters(virDomainPtr dom, virSchedParameterPtr params, int nparams) @@ -12710,7 +12803,7 @@ static virDriver qemuDriver = { qemuDomainRevertToSnapshot, /* domainRevertToSnapshot */ qemuDomainSnapshotDelete, /* domainSnapshotDelete */ qemuDomainMonitorCommand, /* qemuDomainMonitorCommand */ -NULL, /* domainSetMemoryParameters */ +qemuDomainSetMemoryParameters, /* domainSetMemoryParameters */ NULL, /* domainGetMemoryParameters */ }; -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
[libvirt] Mac OS X: dyld: lazy symbol binding failed
Hi, This is a cross-post from libvirt-users since there didn't seem to be anyone there familiar with what is going on and this is a dev issue as well. I'm using the Ruby/FFI libvirt library and getting this consistently on Mac OS X: ruby-1.9.2-p0 FFI::Libvirt.virInitialize dyld: lazy symbol binding failed: Symbol not found: _virThreadInitialize Referenced from: /usr/local/lib/libvirt.dylib Expected in: flat namespace dyld: Symbol not found: _virThreadInitialize Referenced from: /usr/local/lib/libvirt.dylib Expected in: flat namespace Trace/BPT trap I exported DYLD_PRINT_LIBRARIES and it shows that libvirt.dylib is loaded in the process space, but the above still occurs. When I statically link into a C program it works fine, however. Anyone have any idea what could be causing this? See this archive if you'd like to catch up on what was said in libvirt-users (its not a long thread): https://www.redhat.com/archives/libvirt-users/2010-October/msg00050.html Thanks, Mitchell -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list