Re: [libvirt] [PATCH 06/11] qemu: Add monitor functions to set IOThread params

2018-10-22 Thread John Ferlan


On 10/22/18 5:16 AM, Michal Prívozník wrote:
> On 10/19/2018 03:09 PM, John Ferlan wrote:
>>
>>
>> On 10/19/18 7:06 AM, Michal Privoznik wrote:
>>> On 10/07/2018 03:00 PM, John Ferlan wrote:
 Add functions to set the IOThreadInfo param data for the live guest.

 Based on code originally posted by Pavel Hrdina ,
 but extracted into a separate patch. Note that qapi expects to receive
 integer parameters rather than unsigned long long or unsigned int's.
 QEMU does save the value in larger signed 64 bit values eventually.

 Signed-off-by: John Ferlan 
 ---
  src/qemu/qemu_monitor.c  | 19 +++
  src/qemu/qemu_monitor.h  |  2 ++
  src/qemu/qemu_monitor_json.c | 33 +
  src/qemu/qemu_monitor_json.h |  4 
  4 files changed, 58 insertions(+)

 diff --git a/src/qemu/qemu_monitor.c b/src/qemu/qemu_monitor.c
 index 7f7013e115..a65d638ab8 100644
 --- a/src/qemu/qemu_monitor.c
 +++ b/src/qemu/qemu_monitor.c
 @@ -4135,6 +4135,25 @@ qemuMonitorGetIOThreads(qemuMonitorPtr mon,
  }
  
  
 +/**
 + * qemuMonitorSetIOThread:
 + * @mon: Pointer to the monitor
 + * @iothreadInfo: filled IOThread info with data
 + *
 + * Alter the specified IOThread's IOThreadInfo values.
 + */
 +int
 +qemuMonitorSetIOThread(qemuMonitorPtr mon,
 +   qemuMonitorIOThreadInfoPtr iothreadInfo)
 +{
 +VIR_DEBUG("iothread=%p", iothreadInfo);
 +
 +QEMU_CHECK_MONITOR(mon);
 +
 +return qemuMonitorJSONSetIOThread(mon, iothreadInfo);
 +}
 +
 +
  /**
   * qemuMonitorGetMemoryDeviceInfo:
   * @mon: pointer to the monitor
 diff --git a/src/qemu/qemu_monitor.h b/src/qemu/qemu_monitor.h
 index c2991e2b16..ef71fc6448 100644
 --- a/src/qemu/qemu_monitor.h
 +++ b/src/qemu/qemu_monitor.h
 @@ -1123,6 +1123,8 @@ struct _qemuMonitorIOThreadInfo {
  };
  int qemuMonitorGetIOThreads(qemuMonitorPtr mon,
  qemuMonitorIOThreadInfoPtr **iothreads);
 +int qemuMonitorSetIOThread(qemuMonitorPtr mon,
 +   qemuMonitorIOThreadInfoPtr iothreadInfo);
  
  typedef struct _qemuMonitorMemoryDeviceInfo qemuMonitorMemoryDeviceInfo;
  typedef qemuMonitorMemoryDeviceInfo *qemuMonitorMemoryDeviceInfoPtr;
 diff --git a/src/qemu/qemu_monitor_json.c b/src/qemu/qemu_monitor_json.c
 index 2e92984b44..bb1d62b844 100644
 --- a/src/qemu/qemu_monitor_json.c
 +++ b/src/qemu/qemu_monitor_json.c
 @@ -7474,6 +7474,39 @@ qemuMonitorJSONGetIOThreads(qemuMonitorPtr mon,
  }
  
  
 +int
 +qemuMonitorJSONSetIOThread(qemuMonitorPtr mon,
 +   qemuMonitorIOThreadInfoPtr iothreadInfo)
 +{
 +int ret = -1;
 +char *path = NULL;
 +qemuMonitorJSONObjectProperty prop;
 +
 +if (virAsprintf(&path, "/objects/iothread%u",
 +iothreadInfo->iothread_id) < 0)
 +goto cleanup;
 +
 +#define VIR_IOTHREAD_SET_PROP(propName, propVal) \
 +memset(&prop, 0, sizeof(qemuMonitorJSONObjectProperty)); \
 +prop.type = QEMU_MONITOR_OBJECT_PROPERTY_INT; \
 +prop.val.iv = propVal; \
 +if (qemuMonitorJSONSetObjectProperty(mon, path, propName, &prop) < 0) 
 \
 +goto cleanup;
 +
 +VIR_IOTHREAD_SET_PROP("poll-max-ns", iothreadInfo->poll_max_ns)
 +VIR_IOTHREAD_SET_PROP("poll-grow", iothreadInfo->poll_grow)
 +VIR_IOTHREAD_SET_PROP("poll-shrink", iothreadInfo->poll_shrink)
>>>
>>> So this is all or nothing approach. All values are set - even though
>>> user might request through public API to change just one. I don't think
>>> it is a good design. Either we need a monitor API that changes just one
>>> value and call it for every typed parameter that user sends to us, or
>>> public API implementation must copy the old values into this struct
>>> (even though it would be ugly).
>>>
>>> Michal
>>>
>>
>> Fair complaint - I tried to reuse as much as possible from the initial
>> series so that I didn't "waste" time implementing something that in the
>> long run wasn't desired. Originally there were lots of checks about what
>> was or wasn't set - I just took the path of least resistance.
>>
>> It should be simple to add flag for each to determine which was set
>> before setting them in the object path.
>>
>> IOW:
>>
>> #define VIR_IOTHREAD_SET_PROP(propName, propVal) \
>> if (iothreadInfo->set_##propVal) { \
> 
> This will fly iff zero value can't be set on the monitor. I have no idea
> whether it can or can not. If it can be set, then we have to go with
> something more clever.
> 
> Michal
> 

Not 100% sure what you meant... The point of the bools is to indicate
when the value was set, doesn't matter if it's zero.

From: $QEMU.GIT/qapi/misc.json:


# @poll-max

Re: [libvirt] [jenkins-ci PATCH 3/3] projects: add libvirt-ocaml project

2018-10-22 Thread Pino Toscano
On Friday, 19 October 2018 11:37:17 CEST Daniel P. Berrangé wrote:
> On Thu, Oct 11, 2018 at 11:19:54AM +0200, Pino Toscano wrote:
> > Not built on Debian 8, as the version of OCaml is not new enough.
> > 
> > Signed-off-by: Pino Toscano 
> > ---
> >  jobs/defaults.yaml  |  2 ++
> >  projects/libvirt-ocaml.yaml | 23 +++
> >  2 files changed, 25 insertions(+)
> >  create mode 100644 projects/libvirt-ocaml.yaml
> > 
> > diff --git a/jobs/defaults.yaml b/jobs/defaults.yaml
> > index 5cf84dc..13cc443 100644
> > --- a/jobs/defaults.yaml
> > +++ b/jobs/defaults.yaml
> > @@ -51,6 +51,8 @@
> >  default: https://github.com/libvirt/libvirt-go-xml.git
> >libvirt-go:
> >  default: https://github.com/libvirt/libvirt-go.git
> > +  libvirt-ocaml:
> > +default: https://github.com/libvirt/libvirt-ocaml.git
> >libvirt-perl:
> >  default: https://github.com/libvirt/libvirt-perl.git
> >libvirt-python:
> > diff --git a/projects/libvirt-ocaml.yaml b/projects/libvirt-ocaml.yaml
> > new file mode 100644
> > index 000..efea09b
> > --- /dev/null
> > +++ b/projects/libvirt-ocaml.yaml
> > @@ -0,0 +1,23 @@
> > +
> > +- project:
> > +name: libvirt-ocaml
> > +# Debian 8 doesn't have a recent enough OCaml
> > +machines:
> > +  - libvirt-centos-7
> > +  - libvirt-debian-9
> > +  - libvirt-fedora-27
> > +  - libvirt-fedora-28
> > +  - libvirt-fedora-rawhide
> > +  - libvirt-freebsd-10
> > +  - libvirt-freebsd-11
> > +title: Libvirt OCaml
> > +archive_format: xz
> > +git_url: '{git_urls[libvirt-ocaml][default]}'
> > +jobs:
> > +  - generic-build-job:
> > +  parent_jobs: 'libvirt-build'
> > +  command: |
> > +autoreconf -vfi
> > +./configure --prefix=$VIRT_PREFIX --with-libvirt=$VIRT_PREFIX
> > +$MAKE
> > +$MAKE opt
> 
> Since this is using autotools, how about tweaking it to follow the normal
> pattern for autotools jobs, so we can use the standard job defintion.

Technically, it does not use autotools, but only autoconf.

> It looks like it would need
> 
>   - An autogen.sh script

It can be added, but it would just call autoreconf.

>   - Fixed VPATH build

Slightly more complicated to fix, and not a priority for now.

>   - Have 'make opt' be part of the default target

'opt' builds the library, and the examples as native using the ocamlopt
compiler.  ocamlopt is not available on all the architecture (since it
requires an ELF generator in the OCaml compiler), and you can choose
which flavour of build you want (i.e. native/optimized, or bytecode).

-- 
Pino Toscano

signature.asc
Description: This is a digitally signed message part.
--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list

[libvirt] [jenkins-ci PATCH v2 3/3] Add libvirt-ocaml project

2018-10-22 Thread Pino Toscano
Not built on Debian 8, as the version of OCaml is not new enough.

Signed-off-by: Pino Toscano 
---
 guests/playbooks/build/jobs/defaults.yml  |  2 ++
 .../build/projects/libvirt-ocaml.yml  | 27 +++
 jobs/defaults.yaml|  2 ++
 projects/libvirt-ocaml.yaml   | 23 
 4 files changed, 54 insertions(+)
 create mode 100644 guests/playbooks/build/projects/libvirt-ocaml.yml
 create mode 100644 projects/libvirt-ocaml.yaml

diff --git a/guests/playbooks/build/jobs/defaults.yml 
b/guests/playbooks/build/jobs/defaults.yml
index 522dd83..81c5fab 100644
--- a/guests/playbooks/build/jobs/defaults.yml
+++ b/guests/playbooks/build/jobs/defaults.yml
@@ -52,6 +52,8 @@ git_urls:
 default: https://github.com/libvirt/libvirt-go-xml.git
   libvirt-go:
 default: https://github.com/libvirt/libvirt-go.git
+  libvirt-ocaml:
+default: https://github.com/libvirt/libvirt-ocaml.git
   libvirt-perl:
 default: https://github.com/libvirt/libvirt-perl.git
   libvirt-python:
diff --git a/guests/playbooks/build/projects/libvirt-ocaml.yml 
b/guests/playbooks/build/projects/libvirt-ocaml.yml
new file mode 100644
index 000..f0dec8b
--- /dev/null
+++ b/guests/playbooks/build/projects/libvirt-ocaml.yml
@@ -0,0 +1,27 @@
+---
+- set_fact:
+name: libvirt-ocaml
+# Debian 8 doesn't have a recent enough OCaml
+machines:
+  - libvirt-centos-7
+  - libvirt-debian-9
+  - libvirt-debian-sid
+  - libvirt-fedora-27
+  - libvirt-fedora-28
+  - libvirt-fedora-rawhide
+  - libvirt-freebsd-10
+  - libvirt-freebsd-11
+  - libvirt-freebsd-current
+  - libvirt-ubuntu-16
+  - libvirt-ubuntu-18
+archive_format: xz
+git_url: '{{ git_urls["libvirt-ocaml"][git_remote] }}'
+
+- include: '{{ playbook_base }}/jobs/prepare.yml'
+- include: '{{ playbook_base }}/jobs/generic-build-job.yml'
+  vars:
+command: |
+  autoreconf -vfi
+  ./configure --prefix=$VIRT_PREFIX
+  $MAKE
+  $MAKE opt
diff --git a/jobs/defaults.yaml b/jobs/defaults.yaml
index 5cf84dc..13cc443 100644
--- a/jobs/defaults.yaml
+++ b/jobs/defaults.yaml
@@ -51,6 +51,8 @@
 default: https://github.com/libvirt/libvirt-go-xml.git
   libvirt-go:
 default: https://github.com/libvirt/libvirt-go.git
+  libvirt-ocaml:
+default: https://github.com/libvirt/libvirt-ocaml.git
   libvirt-perl:
 default: https://github.com/libvirt/libvirt-perl.git
   libvirt-python:
diff --git a/projects/libvirt-ocaml.yaml b/projects/libvirt-ocaml.yaml
new file mode 100644
index 000..e9e3837
--- /dev/null
+++ b/projects/libvirt-ocaml.yaml
@@ -0,0 +1,23 @@
+
+- project:
+name: libvirt-ocaml
+# Debian 8 doesn't have a recent enough OCaml
+machines:
+  - libvirt-centos-7
+  - libvirt-debian-9
+  - libvirt-fedora-27
+  - libvirt-fedora-28
+  - libvirt-fedora-rawhide
+  - libvirt-freebsd-10
+  - libvirt-freebsd-11
+title: Libvirt OCaml
+archive_format: xz
+git_url: '{git_urls[libvirt-ocaml][default]}'
+jobs:
+  - generic-build-job:
+  parent_jobs: 'libvirt-build'
+  command: |
+autoreconf -vfi
+./configure --prefix=$VIRT_PREFIX
+$MAKE
+$MAKE opt
-- 
2.17.2

--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list


[libvirt] [jenkins-ci PATCH v2 1/3] guests: add mappings for OCaml components

2018-10-22 Thread Pino Toscano
Soon to be used by libvirt-ocaml.

Signed-off-by: Pino Toscano 
---
 guests/vars/mappings.yml | 6 ++
 1 file changed, 6 insertions(+)

diff --git a/guests/vars/mappings.yml b/guests/vars/mappings.yml
index 5df918f..cd92bd8 100644
--- a/guests/vars/mappings.yml
+++ b/guests/vars/mappings.yml
@@ -501,6 +501,12 @@ mappings:
 FreeBSD:
 Debian8:
 
+  ocaml:
+default: ocaml
+
+  ocaml-findlib:
+default: ocaml-findlib
+
   openwsman:
 rpm: libwsman-devel
 Ubuntu: libopenwsman-dev
-- 
2.17.2

--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list


[libvirt] [jenkins-ci PATCH v2 2/3] guests: pull dependencies for libvirt-ocaml

2018-10-22 Thread Pino Toscano
Install the packages needed for building libvirt-ocaml; not on Debian 8
though, as the version of OCaml is not new enough there.

Signed-off-by: Pino Toscano 
---
 guests/host_vars/libvirt-centos-7/main.yml| 1 +
 guests/host_vars/libvirt-debian-9/main.yml| 1 +
 guests/host_vars/libvirt-debian-sid/main.yml  | 1 +
 guests/host_vars/libvirt-fedora-27/main.yml   | 1 +
 guests/host_vars/libvirt-fedora-28/main.yml   | 1 +
 guests/host_vars/libvirt-fedora-rawhide/main.yml  | 1 +
 guests/host_vars/libvirt-freebsd-10/main.yml  | 1 +
 guests/host_vars/libvirt-freebsd-11/main.yml  | 1 +
 guests/host_vars/libvirt-freebsd-current/main.yml | 1 +
 guests/host_vars/libvirt-ubuntu-16/main.yml   | 1 +
 guests/host_vars/libvirt-ubuntu-18/main.yml   | 1 +
 guests/vars/projects/libvirt-ocaml.yml| 5 +
 12 files changed, 16 insertions(+)
 create mode 100644 guests/vars/projects/libvirt-ocaml.yml

diff --git a/guests/host_vars/libvirt-centos-7/main.yml 
b/guests/host_vars/libvirt-centos-7/main.yml
index e220849..8be54b6 100644
--- a/guests/host_vars/libvirt-centos-7/main.yml
+++ b/guests/host_vars/libvirt-centos-7/main.yml
@@ -7,6 +7,7 @@ projects:
   - libvirt-glib
   - libvirt-go
   - libvirt-go-xml
+  - libvirt-ocaml
   - libvirt-perl
   - libvirt-python
   - osinfo-db
diff --git a/guests/host_vars/libvirt-debian-9/main.yml 
b/guests/host_vars/libvirt-debian-9/main.yml
index cdc5a57..33476ad 100644
--- a/guests/host_vars/libvirt-debian-9/main.yml
+++ b/guests/host_vars/libvirt-debian-9/main.yml
@@ -6,6 +6,7 @@ projects:
   - libvirt-glib
   - libvirt-go
   - libvirt-go-xml
+  - libvirt-ocaml
   - libvirt-perl
   - libvirt-python
   - libvirt-sandbox
diff --git a/guests/host_vars/libvirt-debian-sid/main.yml 
b/guests/host_vars/libvirt-debian-sid/main.yml
index 5dd887b..f2594e7 100644
--- a/guests/host_vars/libvirt-debian-sid/main.yml
+++ b/guests/host_vars/libvirt-debian-sid/main.yml
@@ -6,6 +6,7 @@ projects:
   - libvirt-glib
   - libvirt-go
   - libvirt-go-xml
+  - libvirt-ocaml
   - libvirt-perl
   - libvirt-python
   - libvirt-sandbox
diff --git a/guests/host_vars/libvirt-fedora-27/main.yml 
b/guests/host_vars/libvirt-fedora-27/main.yml
index f131953..0b4ec2b 100644
--- a/guests/host_vars/libvirt-fedora-27/main.yml
+++ b/guests/host_vars/libvirt-fedora-27/main.yml
@@ -7,6 +7,7 @@ projects:
   - libvirt-glib
   - libvirt-go
   - libvirt-go-xml
+  - libvirt-ocaml
   - libvirt-perl
   - libvirt-python
   - libvirt-sandbox
diff --git a/guests/host_vars/libvirt-fedora-28/main.yml 
b/guests/host_vars/libvirt-fedora-28/main.yml
index f115598..13555af 100644
--- a/guests/host_vars/libvirt-fedora-28/main.yml
+++ b/guests/host_vars/libvirt-fedora-28/main.yml
@@ -7,6 +7,7 @@ projects:
   - libvirt-glib
   - libvirt-go
   - libvirt-go-xml
+  - libvirt-ocaml
   - libvirt-perl
   - libvirt-python
   - libvirt-sandbox
diff --git a/guests/host_vars/libvirt-fedora-rawhide/main.yml 
b/guests/host_vars/libvirt-fedora-rawhide/main.yml
index 4318653..604f57f 100644
--- a/guests/host_vars/libvirt-fedora-rawhide/main.yml
+++ b/guests/host_vars/libvirt-fedora-rawhide/main.yml
@@ -13,6 +13,7 @@ projects:
   - libvirt-glib+mingw64
   - libvirt-go
   - libvirt-go-xml
+  - libvirt-ocaml
   - libvirt-perl
   - libvirt-python
   - libvirt-sandbox
diff --git a/guests/host_vars/libvirt-freebsd-10/main.yml 
b/guests/host_vars/libvirt-freebsd-10/main.yml
index 005acb4..6547ab4 100644
--- a/guests/host_vars/libvirt-freebsd-10/main.yml
+++ b/guests/host_vars/libvirt-freebsd-10/main.yml
@@ -8,6 +8,7 @@ projects:
   - libvirt-glib
   - libvirt-go
   - libvirt-go-xml
+  - libvirt-ocaml
   - libvirt-perl
   - libvirt-python
   - libvirt-tck
diff --git a/guests/host_vars/libvirt-freebsd-11/main.yml 
b/guests/host_vars/libvirt-freebsd-11/main.yml
index dd06fc5..887c9e6 100644
--- a/guests/host_vars/libvirt-freebsd-11/main.yml
+++ b/guests/host_vars/libvirt-freebsd-11/main.yml
@@ -8,6 +8,7 @@ projects:
   - libvirt-glib
   - libvirt-go
   - libvirt-go-xml
+  - libvirt-ocaml
   - libvirt-perl
   - libvirt-python
   - libvirt-tck
diff --git a/guests/host_vars/libvirt-freebsd-current/main.yml 
b/guests/host_vars/libvirt-freebsd-current/main.yml
index 07f3f25..1f3e911 100644
--- a/guests/host_vars/libvirt-freebsd-current/main.yml
+++ b/guests/host_vars/libvirt-freebsd-current/main.yml
@@ -8,6 +8,7 @@ projects:
   - libvirt-glib
   - libvirt-go
   - libvirt-go-xml
+  - libvirt-ocaml
   - libvirt-perl
   - libvirt-python
   - libvirt-tck
diff --git a/guests/host_vars/libvirt-ubuntu-16/main.yml 
b/guests/host_vars/libvirt-ubuntu-16/main.yml
index 4d9914a..6ec1df8 100644
--- a/guests/host_vars/libvirt-ubuntu-16/main.yml
+++ b/guests/host_vars/libvirt-ubuntu-16/main.yml
@@ -6,6 +6,7 @@ projects:
   - libvirt-glib
   - libvirt-go
   - libvirt-go-xml
+  - libvirt-ocaml
   - libvirt-perl
   - libvirt-python
   - libvirt-sandbox
diff --git a/guests/host_vars/libvirt-ubuntu-18/main.yml 
b/guests/host_vars/libvirt-ubuntu-

[libvirt] [jenkins-ci PATCH v2 0/3] Add libvirt-ocaml

2018-10-22 Thread Pino Toscano
Now that the libvirt-ocaml repository is fixed, let's build it in CI.

Changes from v1 to v2:
- split according to Andrea's hints
- removed --with-libvirt as argument for configure, no more needed
  after upstream changes

Pino Toscano (3):
  guests: add mappings for OCaml components
  guests: pull dependencies for libvirt-ocaml
  Add libvirt-ocaml project

 guests/host_vars/libvirt-centos-7/main.yml|  1 +
 guests/host_vars/libvirt-debian-9/main.yml|  1 +
 guests/host_vars/libvirt-debian-sid/main.yml  |  1 +
 guests/host_vars/libvirt-fedora-27/main.yml   |  1 +
 guests/host_vars/libvirt-fedora-28/main.yml   |  1 +
 .../host_vars/libvirt-fedora-rawhide/main.yml |  1 +
 guests/host_vars/libvirt-freebsd-10/main.yml  |  1 +
 guests/host_vars/libvirt-freebsd-11/main.yml  |  1 +
 .../libvirt-freebsd-current/main.yml  |  1 +
 guests/host_vars/libvirt-ubuntu-16/main.yml   |  1 +
 guests/host_vars/libvirt-ubuntu-18/main.yml   |  1 +
 guests/playbooks/build/jobs/defaults.yml  |  2 ++
 .../build/projects/libvirt-ocaml.yml  | 27 +++
 guests/vars/mappings.yml  |  6 +
 guests/vars/projects/libvirt-ocaml.yml|  5 
 jobs/defaults.yaml|  2 ++
 projects/libvirt-ocaml.yaml   | 23 
 17 files changed, 76 insertions(+)
 create mode 100644 guests/playbooks/build/projects/libvirt-ocaml.yml
 create mode 100644 guests/vars/projects/libvirt-ocaml.yml
 create mode 100644 projects/libvirt-ocaml.yaml

-- 
2.17.2

--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list


Re: [libvirt] [Qemu-devel] [PULL 00/45] Machine queue, 2018-10-18

2018-10-22 Thread Markus Armbruster
Igor Mammedov  writes:

> On Fri, 19 Oct 2018 17:23:21 -0300
> Eduardo Habkost  wrote:
>
>> On Fri, Oct 19, 2018 at 09:53:45PM +0200, Igor Mammedov wrote:
>> > On Fri, 19 Oct 2018 15:44:08 -0300
>> > Eduardo Habkost  wrote:
>> > 
>> > > On Fri, Oct 19, 2018 at 03:12:31PM +0100, Peter Maydell wrote:
>> > > > On 18 October 2018 at 21:03, Eduardo Habkost  
>> > > > wrote:
>> > > > > The following changes since commit 
>> > > > > 09558375a634e17cea6cfbfec883ac2376d2dc7f:
>> > > > >
>> > > > >   Merge remote-tracking branch 
>> > > > > 'remotes/pmaydell/tags/pull-target-arm-20181016-1' into staging 
>> > > > > (2018-10-16 17:42:56 +0100)
>> > > > >
>> > > > > are available in the Git repository at:
>> > > > >
>> > > > >   git://github.com/ehabkost/qemu.git tags/machine-next-pull-request
>> > > > >
>> > > > > for you to fetch changes up to 
>> > > > > 6d8e1bcc7dd5e819ce81e6a87fffe23e39c700cc:
>> > > > >
>> > > > >   numa: Clean up error reporting in parse_numa() (2018-10-17 
>> > > > > 16:33:40 -0300)
>> > > > >
>> > > > > 
>> > > > > Machine queue, 2018-10-18
>> > > > >
>> > > > > * sysbus init/realize cleanups
>> > > > >   (Cédric Le Goater, Philippe Mathieu-Daudé)
>> > > > > * memory-device refactoring (David Hildenbrand)
>> > > > > * -smp: deprecate incorrect CPUs topology (Igor Mammedov)
>> > > > > * -numa parsing cleanups (Markus Armbruster)
>> > > > > * Fix hostmem-file memory leak (Zhang Yi)
>> > > > > * Typo fix (Li Qiang)
>> > > > >
>> > > > > 
>> > > > >
>> > > > 
>> > > > Hi. This had some problems in merge testing, I'm afraid:
>> > > > 
>> > > > On aarch64 host, warnings running tests/cpu-plug-test for i386 and 
>> > > > s390 targets:
>> > > > 
>> > > > TEST: tests/cpu-plug-test... (pid=12602)
>> > > >   /i386/cpu-plug/pc-i440fx-3.0/cpu-add/1x3x2&maxcpus=12:
>> > > > qemu-system-i386: warning: Invalid CPU topology deprecated: sockets
>> > > > (1) * cores (3) * threads (2) != maxcpus (12)
>> > > [...]
>> > > > 
>> > > > (plus similar ppc64, x86_64 targets)
>> > > 
>> > > Ouch.  Apologies.
>> > > 
>> > > Can we please do something make sure "make check" will fail on
>> > > these cases?  I'd like to be able to trust CI systems like
>> > > travis-ci.
>> > > 
>> > 
>> > we probably don't want make check fail on warning.
>> 
>> I disagree.  If a warning is blocking a pull request from being
>> merged, it must make CI systems fail too.  Otherwise we're
>> defeating the purpose of CI systems.
>
> When we deprecate options we are bound to trigger warning which are not errors
> and are meant to be there until deprecated options are removed/tested by make 
> check.
> So what would you suggest to do wrt tests that use deprecated features,
> drop testing for it?

We commonly suppress the warning when testing.  Search for
'if (qtest_enabled())'.

--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list

[libvirt] [PATCH] util: Fix typo vcups -> vcpus

2018-10-22 Thread Martin Kletzander
Signed-off-by: Martin Kletzander 
---
Pushed as trivial

 src/util/virnuma.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/util/virnuma.h b/src/util/virnuma.h
index a3ffb6d6c7c9..edc206100f78 100644
--- a/src/util/virnuma.h
+++ b/src/util/virnuma.h
@@ -27,7 +27,7 @@
 # include "virutil.h"
 
 
-char *virNumaGetAutoPlacementAdvice(unsigned short vcups,
+char *virNumaGetAutoPlacementAdvice(unsigned short vcpus,
 unsigned long long balloon);
 
 int virNumaSetupMemoryPolicy(virDomainNumatuneMemMode mode,
-- 
2.19.1

--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list


[libvirt] BugFix - Libvirt Ruby Binding Memory Stats Val Method

2018-10-22 Thread iletisim
Hi libvirt comuninty’s developers. I will try the fast explain. We’re working on kvm for a project and we tried get current machine’s memory usages. The code we tried to use for this operation is as shown in the below. irb(main):002:0> conn = Libvirt::open("qemu:///system")=> #irb(main):003:0> domain = conn.lookup_domain_by_name("2_2").memory_stats=> [#, #]irb(main):004:0> domain.first.valTraceback (most recent call last):16: from /root/.rbenv/versions/2.5.1/bin/bundle:23:in `load'15: from /root/.rbenv/versions/2.5.1/lib/ruby/gems/2.5.0/gems/bundler-1.16.6/exe/bundle:22:in `'14: from /root/.rbenv/versions/2.5.1/lib/ruby/gems/2.5.0/gems/bundler-1.16.6/lib/bundler/friendly_errors.rb:124:in `with_friendly_errors'13: from /root/.rbenv/versions/2.5.1/lib/ruby/gems/2.5.0/gems/bundler-1.16.6/exe/bundle:30:in `block in '12: from /root/.rbenv/versions/2.5.1/lib/ruby/gems/2.5.0/gems/bundler-1.16.6/lib/bundler/cli.rb:18:in `start'11: from /root/.rbenv/versions/2.5.1/lib/ruby/gems/2.5.0/gems/bundler-1.16.6/lib/bundler/vendor/thor/lib/thor/base.rb:466:in `start'10: from /root/.rbenv/versions/2.5.1/lib/ruby/gems/2.5.0/gems/bundler-1.16.6/lib/bundler/cli.rb:27:in `dispatch'9: from /root/.rbenv/versions/2.5.1/lib/ruby/gems/2.5.0/gems/bundler-1.16.6/lib/bundler/vendor/thor/lib/thor.rb:387:in `dispatch'8: from /root/.rbenv/versions/2.5.1/lib/ruby/gems/2.5.0/gems/bundler-1.16.6/lib/bundler/vendor/thor/lib/thor/invocation.rb:126:in `invoke_command'7: from /root/.rbenv/versions/2.5.1/lib/ruby/gems/2.5.0/gems/bundler-1.16.6/lib/bundler/vendor/thor/lib/thor/command.rb:27:in `run'6: from /root/.rbenv/versions/2.5.1/lib/ruby/gems/2.5.0/gems/bundler-1.16.6/lib/bundler/cli.rb:424:in `exec'5: from /root/.rbenv/versions/2.5.1/lib/ruby/gems/2.5.0/gems/bundler-1.16.6/lib/bundler/cli/exec.rb:28:in `run'4: from /root/.rbenv/versions/2.5.1/lib/ruby/gems/2.5.0/gems/bundler-1.16.6/lib/bundler/cli/exec.rb:74:in `kernel_load'3: from /root/.rbenv/versions/2.5.1/lib/ruby/gems/2.5.0/gems/bundler-1.16.6/lib/bundler/cli/exec.rb:74:in `load'2: from bin/console:13:in `'1: from (irb):4NoMethodError (undefined method `val' for #)Did you mean? valueirb(main):005:0> domain.first.value=> nil As you see, when we want the use memory_usage’s val parameter but Libvirt throwing up undefined method error. Our fix proffer is memory_stats function's return @val parameter enough be update as shown in the below.diff --git a/ext/libvirt/domain.c b/ext/libvirt/domain.cindex d665907..d458e98 100644--- a/ext/libvirt/domain.c+++ b/ext/libvirt/domain.c@@ -675,7 +675,7 @@ static VALUE libvirt_domain_memory_stats(int argc, VALUE *argv, VALUE d)for (i = 0; i < r; i++) {tmp = rb_class_new_instance(0, NULL, c_domain_memory_stats);rb_iv_set(tmp, "@tag", INT2NUM(stats[i].tag));- rb_iv_set(tmp, "@val", ULL2NUM(stats[i].val));+ rb_iv_set(tmp, "@value", ULL2NUM(stats[i].val)); rb_ary_store(result, i, tmp);} After that change memory_stats method’s val error will solved as shown in the below. irb(main):002:0> conn = Libvirt::open("qemu:///system")=> #irb(main):003:0> memory_stats = conn.lookup_domain_by_name("2_2").memory_stats=> [#, #]irb(main):004:0> memory_stats.first.value=> 1048576--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list

Re: [libvirt] [PATCH 1/2] syntax-check: revert indentation checks

2018-10-22 Thread Michal Prívozník
On 10/19/2018 10:03 AM, Erik Skultety wrote:
> On Fri, Oct 05, 2018 at 01:48:06PM +0200, Ján Tomko wrote:
>> Recent patches added indentation checks that discovered some cosmetic
>> issues at the cost of making this check last as long as the rest of
>> syntax-check combined on my system. Also, they're moving closer
>> to us implementing yet another C parser (docs/apibuild.py being the
>> other one).
>>
>> Revert the following commits:
>> commit 11e1f11dd34f2688169c63c13ea8d99a64724369
>> syntax-check: Check for incorrect indentation in function body
>> commit 2585a79e32e8b0d994ab35fd7c641eb9b96632e3
>> build-aux:check-spacing: Introduce a new rule to check misaligned stuff 
>> in parenthesises
>> commit a033182f042a07ffbd4b9a50418670778ceddbf3
>> build-aux:check-spacing: Add wrapper function of CheckCurlyBrackets
>> commit 6225626b6f0a4817d1f17de0bc5200c5d7986a3e
>> build-aux:check-spacing: Add wrapper function of CheckWhiteSpaces
>> commit c3875129d9bd094ffe90d54fbec86624ae88c40b
>> build-aux:check-spacing: Add wrapper function of KillComments
>> commit e995904c5691be3c21f4c6dbc1f067fe0c8e8515
>> build-aux:check-spacing: Add wrapper function of CheckFunctionBody
>> commit 11e1f11dd34f2688169c63c13ea8d99a64724369
>> syntax-check: Check for incorrect indentation in function body
>>
>> This brings the speed of the script to a tolerable level and lets it
>> focus on the more visible issues.
>>
>> Signed-off-by: Ján Tomko 
> Reviewed-by: Erik Skultety 
> 

So what alternative do we have? Obviously, we fail at honoring our
formatting rules. Having a check that would fail at `synax-check' time
would help us. Okay, implementing new C parser might not be the best
solution, but it's at least something.

Michal

--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list

Re: [libvirt] [PATCH 06/11] qemu: Add monitor functions to set IOThread params

2018-10-22 Thread Michal Prívozník
On 10/19/2018 03:09 PM, John Ferlan wrote:
> 
> 
> On 10/19/18 7:06 AM, Michal Privoznik wrote:
>> On 10/07/2018 03:00 PM, John Ferlan wrote:
>>> Add functions to set the IOThreadInfo param data for the live guest.
>>>
>>> Based on code originally posted by Pavel Hrdina ,
>>> but extracted into a separate patch. Note that qapi expects to receive
>>> integer parameters rather than unsigned long long or unsigned int's.
>>> QEMU does save the value in larger signed 64 bit values eventually.
>>>
>>> Signed-off-by: John Ferlan 
>>> ---
>>>  src/qemu/qemu_monitor.c  | 19 +++
>>>  src/qemu/qemu_monitor.h  |  2 ++
>>>  src/qemu/qemu_monitor_json.c | 33 +
>>>  src/qemu/qemu_monitor_json.h |  4 
>>>  4 files changed, 58 insertions(+)
>>>
>>> diff --git a/src/qemu/qemu_monitor.c b/src/qemu/qemu_monitor.c
>>> index 7f7013e115..a65d638ab8 100644
>>> --- a/src/qemu/qemu_monitor.c
>>> +++ b/src/qemu/qemu_monitor.c
>>> @@ -4135,6 +4135,25 @@ qemuMonitorGetIOThreads(qemuMonitorPtr mon,
>>>  }
>>>  
>>>  
>>> +/**
>>> + * qemuMonitorSetIOThread:
>>> + * @mon: Pointer to the monitor
>>> + * @iothreadInfo: filled IOThread info with data
>>> + *
>>> + * Alter the specified IOThread's IOThreadInfo values.
>>> + */
>>> +int
>>> +qemuMonitorSetIOThread(qemuMonitorPtr mon,
>>> +   qemuMonitorIOThreadInfoPtr iothreadInfo)
>>> +{
>>> +VIR_DEBUG("iothread=%p", iothreadInfo);
>>> +
>>> +QEMU_CHECK_MONITOR(mon);
>>> +
>>> +return qemuMonitorJSONSetIOThread(mon, iothreadInfo);
>>> +}
>>> +
>>> +
>>>  /**
>>>   * qemuMonitorGetMemoryDeviceInfo:
>>>   * @mon: pointer to the monitor
>>> diff --git a/src/qemu/qemu_monitor.h b/src/qemu/qemu_monitor.h
>>> index c2991e2b16..ef71fc6448 100644
>>> --- a/src/qemu/qemu_monitor.h
>>> +++ b/src/qemu/qemu_monitor.h
>>> @@ -1123,6 +1123,8 @@ struct _qemuMonitorIOThreadInfo {
>>>  };
>>>  int qemuMonitorGetIOThreads(qemuMonitorPtr mon,
>>>  qemuMonitorIOThreadInfoPtr **iothreads);
>>> +int qemuMonitorSetIOThread(qemuMonitorPtr mon,
>>> +   qemuMonitorIOThreadInfoPtr iothreadInfo);
>>>  
>>>  typedef struct _qemuMonitorMemoryDeviceInfo qemuMonitorMemoryDeviceInfo;
>>>  typedef qemuMonitorMemoryDeviceInfo *qemuMonitorMemoryDeviceInfoPtr;
>>> diff --git a/src/qemu/qemu_monitor_json.c b/src/qemu/qemu_monitor_json.c
>>> index 2e92984b44..bb1d62b844 100644
>>> --- a/src/qemu/qemu_monitor_json.c
>>> +++ b/src/qemu/qemu_monitor_json.c
>>> @@ -7474,6 +7474,39 @@ qemuMonitorJSONGetIOThreads(qemuMonitorPtr mon,
>>>  }
>>>  
>>>  
>>> +int
>>> +qemuMonitorJSONSetIOThread(qemuMonitorPtr mon,
>>> +   qemuMonitorIOThreadInfoPtr iothreadInfo)
>>> +{
>>> +int ret = -1;
>>> +char *path = NULL;
>>> +qemuMonitorJSONObjectProperty prop;
>>> +
>>> +if (virAsprintf(&path, "/objects/iothread%u",
>>> +iothreadInfo->iothread_id) < 0)
>>> +goto cleanup;
>>> +
>>> +#define VIR_IOTHREAD_SET_PROP(propName, propVal) \
>>> +memset(&prop, 0, sizeof(qemuMonitorJSONObjectProperty)); \
>>> +prop.type = QEMU_MONITOR_OBJECT_PROPERTY_INT; \
>>> +prop.val.iv = propVal; \
>>> +if (qemuMonitorJSONSetObjectProperty(mon, path, propName, &prop) < 0) \
>>> +goto cleanup;
>>> +
>>> +VIR_IOTHREAD_SET_PROP("poll-max-ns", iothreadInfo->poll_max_ns)
>>> +VIR_IOTHREAD_SET_PROP("poll-grow", iothreadInfo->poll_grow)
>>> +VIR_IOTHREAD_SET_PROP("poll-shrink", iothreadInfo->poll_shrink)
>>
>> So this is all or nothing approach. All values are set - even though
>> user might request through public API to change just one. I don't think
>> it is a good design. Either we need a monitor API that changes just one
>> value and call it for every typed parameter that user sends to us, or
>> public API implementation must copy the old values into this struct
>> (even though it would be ugly).
>>
>> Michal
>>
> 
> Fair complaint - I tried to reuse as much as possible from the initial
> series so that I didn't "waste" time implementing something that in the
> long run wasn't desired. Originally there were lots of checks about what
> was or wasn't set - I just took the path of least resistance.
> 
> It should be simple to add flag for each to determine which was set
> before setting them in the object path.
> 
> IOW:
> 
> #define VIR_IOTHREAD_SET_PROP(propName, propVal) \
> if (iothreadInfo->set_##propVal) { \

This will fly iff zero value can't be set on the monitor. I have no idea
whether it can or can not. If it can be set, then we have to go with
something more clever.

Michal

--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list


Re: [libvirt] [Qemu-devel] [PULL 00/45] Machine queue, 2018-10-18

2018-10-22 Thread Igor Mammedov
On Fri, 19 Oct 2018 17:23:21 -0300
Eduardo Habkost  wrote:

> On Fri, Oct 19, 2018 at 09:53:45PM +0200, Igor Mammedov wrote:
> > On Fri, 19 Oct 2018 15:44:08 -0300
> > Eduardo Habkost  wrote:
> > 
> > > On Fri, Oct 19, 2018 at 03:12:31PM +0100, Peter Maydell wrote:
> > > > On 18 October 2018 at 21:03, Eduardo Habkost  
> > > > wrote:
> > > > > The following changes since commit 
> > > > > 09558375a634e17cea6cfbfec883ac2376d2dc7f:
> > > > >
> > > > >   Merge remote-tracking branch 
> > > > > 'remotes/pmaydell/tags/pull-target-arm-20181016-1' into staging 
> > > > > (2018-10-16 17:42:56 +0100)
> > > > >
> > > > > are available in the Git repository at:
> > > > >
> > > > >   git://github.com/ehabkost/qemu.git tags/machine-next-pull-request
> > > > >
> > > > > for you to fetch changes up to 
> > > > > 6d8e1bcc7dd5e819ce81e6a87fffe23e39c700cc:
> > > > >
> > > > >   numa: Clean up error reporting in parse_numa() (2018-10-17 16:33:40 
> > > > > -0300)
> > > > >
> > > > > 
> > > > > Machine queue, 2018-10-18
> > > > >
> > > > > * sysbus init/realize cleanups
> > > > >   (Cédric Le Goater, Philippe Mathieu-Daudé)
> > > > > * memory-device refactoring (David Hildenbrand)
> > > > > * -smp: deprecate incorrect CPUs topology (Igor Mammedov)
> > > > > * -numa parsing cleanups (Markus Armbruster)
> > > > > * Fix hostmem-file memory leak (Zhang Yi)
> > > > > * Typo fix (Li Qiang)
> > > > >
> > > > > 
> > > > >
> > > > 
> > > > Hi. This had some problems in merge testing, I'm afraid:
> > > > 
> > > > On aarch64 host, warnings running tests/cpu-plug-test for i386 and s390 
> > > > targets:
> > > > 
> > > > TEST: tests/cpu-plug-test... (pid=12602)
> > > >   /i386/cpu-plug/pc-i440fx-3.0/cpu-add/1x3x2&maxcpus=12:
> > > > qemu-system-i386: warning: Invalid CPU topology deprecated: sockets
> > > > (1) * cores (3) * threads (2) != maxcpus (12)
> > > [...]
> > > > 
> > > > (plus similar ppc64, x86_64 targets)
> > > 
> > > Ouch.  Apologies.
> > > 
> > > Can we please do something make sure "make check" will fail on
> > > these cases?  I'd like to be able to trust CI systems like
> > > travis-ci.
> > > 
> > 
> > we probably don't want make check fail on warning.
> 
> I disagree.  If a warning is blocking a pull request from being
> merged, it must make CI systems fail too.  Otherwise we're
> defeating the purpose of CI systems.

When we deprecate options we are bound to trigger warning which are not errors
and are meant to be there until deprecated options are removed/tested by make 
check.
So what would you suggest to do wrt tests that use deprecated features,
drop testing for it?

[...]


--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list

Re: [libvirt] [PATCH v2 2/3] qemu: vfio-ap device support

2018-10-22 Thread Boris Fiuczynski

On 10/19/18 1:56 PM, Thomas Huth wrote:

On 2018-10-18 16:54, Boris Fiuczynski wrote:

Adjusting domain format documentation, adding device address
support and adding command line generation for vfio-ap.
Since only one mediated hostdev with model vfio-ap is supported a check
disallows to define domains with more than one such hostdev device.

Signed-off-by: Boris Fiuczynski 
Reviewed-by: Bjoern Walk 

[...]

+static int
+virDomainDefPostParseHostdev(virDomainDefPtr def)
+{
+size_t i;
+bool vfioap_found = false;
+
+/* verify settings of hostdevs vfio-ap */
+for (i = 0; i < def->nhostdevs; i++) {
+virDomainHostdevDefPtr hostdev = def->hostdevs[i];
+
+if (virHostdevIsMdevDevice(hostdev) &&
+hostdev->source.subsys.u.mdev.model == 
VIR_MDEV_MODEL_TYPE_VFIO_AP) {
+if (vfioap_found) {
+virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
+   _("Only one hostdev of model vfio-ap is "
+ "support"));


s/support/supported/ ?

It should be "supported"... :-)

I hope whoever is going to push this series can fix it before pushing. 
If not please let me know and I am going to send a v3.


Thomas, thanks for your review.



  Thomas

--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list




--
Mit freundlichen Grüßen/Kind regards
   Boris Fiuczynski

IBM Deutschland Research & Development GmbH
Vorsitzender des Aufsichtsrats: Martina Köderitz
Geschäftsführung: Dirk Wittkopp
Sitz der Gesellschaft: Böblingen
Registergericht: Amtsgericht Stuttgart, HRB 243294

--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list

[libvirt] [PATCHv7 14/18] util: Add function for checking if monitor is running

2018-10-22 Thread Wang Huaqiang
Check whether monitor is running by checking the monitor's PIDs status.

Monitor is looked as running normally if the vcpu PID list matches with
the content of monitor's 'tasks' file.

Signed-off-by: Wang Huaqiang 
---
 src/libvirt_private.syms |   1 +
 src/util/virresctrl.c| 102 ++-
 src/util/virresctrl.h|   3 ++
 3 files changed, 105 insertions(+), 1 deletion(-)

diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
index d59ac86..91801ed 100644
--- a/src/libvirt_private.syms
+++ b/src/libvirt_private.syms
@@ -2684,6 +2684,7 @@ virResctrlMonitorAddPID;
 virResctrlMonitorCreate;
 virResctrlMonitorDeterminePath;
 virResctrlMonitorGetID;
+virResctrlMonitorIsRunning;
 virResctrlMonitorNew;
 virResctrlMonitorRemove;
 virResctrlMonitorSetAlloc;
diff --git a/src/util/virresctrl.c b/src/util/virresctrl.c
index b0205bc..fa3e6e9 100644
--- a/src/util/virresctrl.c
+++ b/src/util/virresctrl.c
@@ -359,6 +359,9 @@ struct _virResctrlMonitor {
 /* libvirt-generated path in /sys/fs/resctrl for this particular
  * monitor */
 char *path;
+/* Tracking the tasks' PID associated with this monitor */
+pid_t *pids;
+size_t npids;
 };
 
 
@@ -418,6 +421,7 @@ virResctrlMonitorDispose(void *obj)
 virObjectUnref(monitor->alloc);
 VIR_FREE(monitor->id);
 VIR_FREE(monitor->path);
+VIR_FREE(monitor->pids);
 }
 
 
@@ -2540,7 +2544,20 @@ int
 virResctrlMonitorAddPID(virResctrlMonitorPtr monitor,
 pid_t pid)
 {
-return virResctrlAddPID(monitor->path, pid);
+size_t i = 0;
+
+if (virResctrlAddPID(monitor->path, pid) < 0)
+return -1;
+
+for (i = 0; i < monitor->npids; i++) {
+if (pid == monitor->pids[i])
+return 0;
+}
+
+if (VIR_APPEND_ELEMENT(monitor->pids, monitor->npids, pid) < 0)
+return -1;
+
+return 0;
 }
 
 
@@ -2613,3 +2630,86 @@ virResctrlMonitorRemove(virResctrlMonitorPtr monitor)
 
 return ret;
 }
+
+
+static int
+virResctrlPIDSorter(const void *pida, const void *pidb)
+{
+return *(pid_t*)pida - *(pid_t*)pidb;
+}
+
+
+bool
+virResctrlMonitorIsRunning(virResctrlMonitorPtr monitor)
+{
+char *pidstr = NULL;
+char **spids = NULL;
+size_t nspids = 0;
+pid_t *pids = NULL;
+size_t npids = 0;
+size_t i = 0;
+int rv = -1;
+bool ret = false;
+
+/* path is not determined yet, monitor is not running*/
+if (!monitor->path)
+return false;
+
+/* No vcpu PID filled, regard monitor as not running */
+if (monitor->npids == 0)
+return false;
+
+/* If no 'tasks' file found, underlying resctrl directory is not
+ * ready, regard monitor as not running */
+rv = virFileReadValueString(&pidstr, "%s/tasks", monitor->path);
+if (rv < 0)
+goto cleanup;
+
+/* no PID in task file, monitor is not running */
+if (!*pidstr)
+goto cleanup;
+
+/* The tracking monitor PID list is not identical to the
+ * list in current resctrl directory. monitor is corrupted,
+ * report error and un-running state */
+spids = virStringSplitCount(pidstr, "\n", 0, &nspids);
+if (nspids != monitor->npids) {
+VIR_ERROR(_("Monitor %s PID list mismatch in length"), monitor->path);
+goto cleanup;
+}
+
+for (i = 0; i < nspids; i++) {
+unsigned int val = 0;
+pid_t pid = 0;
+
+if (virStrToLong_uip(spids[i], NULL, 0, &val) < 0) {
+virReportError(VIR_ERR_INTERNAL_ERROR,
+   _("Monitor %s failed in parse PID list"),
+   monitor->path);
+goto cleanup;
+}
+
+pid = (pid_t)val;
+
+if (VIR_APPEND_ELEMENT(pids, npids, pid) < 0)
+goto cleanup;
+}
+
+qsort(pids, npids, sizeof(pid_t), virResctrlPIDSorter);
+qsort(monitor->pids, monitor->npids, sizeof(pid_t), virResctrlPIDSorter);
+
+for (i = 0; i < monitor->npids; i++) {
+if (monitor->pids[i] != pids[i]) {
+VIR_ERROR(_("Monitor %s PID list corrupted"), monitor->path);
+goto cleanup;
+}
+}
+
+ret = true;
+ cleanup:
+virStringListFree(spids);
+VIR_FREE(pids);
+VIR_FREE(pidstr);
+
+return ret;
+}
diff --git a/src/util/virresctrl.h b/src/util/virresctrl.h
index 804d6f5..8d8fdc2 100644
--- a/src/util/virresctrl.h
+++ b/src/util/virresctrl.h
@@ -219,4 +219,7 @@ virResctrlMonitorSetAlloc(virResctrlMonitorPtr monitor,
 
 int
 virResctrlMonitorRemove(virResctrlMonitorPtr monitor);
+
+bool
+virResctrlMonitorIsRunning(virResctrlMonitorPtr monitor);
 #endif /*  __VIR_RESCTRL_H__ */
-- 
2.7.4

--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list


[libvirt] [PATCHv7 18/18] qemu: Setting up vcpu and adding pids to resctrl monitor groups during reconnection

2018-10-22 Thread Wang Huaqiang
Invoking qemuProcessSetupVcpus in process of VM reconnection.

The vcpu pid information need to be refilled to resctrl monitor
after a VM reconnection./

Signed-off-by: Wang Huaqiang 
---
 src/qemu/qemu_process.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c
index fba4fb4..ed0330b 100644
--- a/src/qemu/qemu_process.c
+++ b/src/qemu/qemu_process.c
@@ -8008,6 +8008,9 @@ qemuProcessReconnect(void *opaque)
 }
 }
 
+if (qemuProcessSetupVcpus(obj) < 0)
+goto error;
+
 /* update domain state XML with possibly updated state in virDomainObj */
 if (virDomainSaveStatus(driver->xmlopt, cfg->stateDir, obj, driver->caps) 
< 0)
 goto error;
-- 
2.7.4

--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list


[libvirt] [PATCHv7 09/18] util: Add more interfaces for resctrl monitor

2018-10-22 Thread Wang Huaqiang
Add interfaces monitor group to support operations such
as add PID, set ID, remove group ... etc.

Signed-off-by: Wang Huaqiang 
---
 src/libvirt_private.syms |  5 +
 src/util/virresctrl.c| 47 +++
 src/util/virresctrl.h| 14 ++
 3 files changed, 66 insertions(+)

diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
index a878083..d59ac86 100644
--- a/src/libvirt_private.syms
+++ b/src/libvirt_private.syms
@@ -2683,7 +2683,12 @@ virResctrlInfoNew;
 virResctrlMonitorAddPID;
 virResctrlMonitorCreate;
 virResctrlMonitorDeterminePath;
+virResctrlMonitorGetID;
 virResctrlMonitorNew;
+virResctrlMonitorRemove;
+virResctrlMonitorSetAlloc;
+virResctrlMonitorSetID;
+
 
 
 # util/virrotatingfile.h
diff --git a/src/util/virresctrl.c b/src/util/virresctrl.c
index 9f42065..b0205bc 100644
--- a/src/util/virresctrl.c
+++ b/src/util/virresctrl.c
@@ -2566,3 +2566,50 @@ virResctrlMonitorCreate(virResctrlMonitorPtr monitor,
 virResctrlUnlock(lockfd);
 return ret;
 }
+
+
+int
+virResctrlMonitorSetID(virResctrlMonitorPtr monitor,
+   const char *id)
+{
+if (!id) {
+virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+   _("Resctrl monitor 'id' cannot be NULL"));
+return -1;
+}
+
+return VIR_STRDUP(monitor->id, id);
+}
+
+
+const char *
+virResctrlMonitorGetID(virResctrlMonitorPtr monitor)
+{
+return monitor->id;
+}
+
+
+void
+virResctrlMonitorSetAlloc(virResctrlMonitorPtr monitor,
+  virResctrlAllocPtr alloc)
+{
+monitor->alloc = virObjectRef(alloc);
+}
+
+
+int
+virResctrlMonitorRemove(virResctrlMonitorPtr monitor)
+{
+int ret = 0;
+
+if (!monitor->path)
+return 0;
+
+VIR_DEBUG("Removing resctrl monitor%s", monitor->path);
+if (rmdir(monitor->path) != 0 && errno != ENOENT) {
+ret = -errno;
+VIR_ERROR(_("Unable to remove %s (%d)"), monitor->path, errno);
+}
+
+return ret;
+}
diff --git a/src/util/virresctrl.h b/src/util/virresctrl.h
index 76e40a2..804d6f5 100644
--- a/src/util/virresctrl.h
+++ b/src/util/virresctrl.h
@@ -205,4 +205,18 @@ virResctrlMonitorAddPID(virResctrlMonitorPtr monitor,
 int
 virResctrlMonitorCreate(virResctrlMonitorPtr monitor,
 const char *machinename);
+
+int
+virResctrlMonitorSetID(virResctrlMonitorPtr monitor,
+   const char *id);
+
+const char *
+virResctrlMonitorGetID(virResctrlMonitorPtr monitor);
+
+void
+virResctrlMonitorSetAlloc(virResctrlMonitorPtr monitor,
+  virResctrlAllocPtr alloc);
+
+int
+virResctrlMonitorRemove(virResctrlMonitorPtr monitor);
 #endif /*  __VIR_RESCTRL_H__ */
-- 
2.7.4

--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list


[libvirt] [PATCHv7 12/18] conf: Introduce cache monitor element in cachetune

2018-10-22 Thread Wang Huaqiang
Introducing  element under  to represent
a cache monitor.

Signed-off-by: Wang Huaqiang 
---
 docs/formatdomain.html.in  |  26 +++
 docs/schemas/domaincommon.rng  |  10 +
 src/conf/domain_conf.c | 234 -
 src/conf/domain_conf.h |  11 +
 tests/genericxml2xmlindata/cachetune-cdp.xml   |   3 +
 .../cachetune-colliding-monitor.xml|  30 +++
 tests/genericxml2xmlindata/cachetune-small.xml |   7 +
 tests/genericxml2xmltest.c |   2 +
 8 files changed, 322 insertions(+), 1 deletion(-)
 create mode 100644 tests/genericxml2xmlindata/cachetune-colliding-monitor.xml

diff --git a/docs/formatdomain.html.in b/docs/formatdomain.html.in
index b1651e3..2fd665c 100644
--- a/docs/formatdomain.html.in
+++ b/docs/formatdomain.html.in
@@ -759,6 +759,12 @@
 
   
   
+  
+  
+
+
+  
+  
 
 
   
@@ -978,6 +984,26 @@
   
 
   
+  monitor
+  
+The optional element monitor creates the cache
+monitor(s) for current cache allocation and has the following
+required attributes:
+
+  level
+  
+Host cache level the monitor belongs to.
+  
+  vcpus
+  
+vCPU list the monitor applies to. A monitor's vCPU list
+can only be the member(s) of the vCPU list of associating
+allocation. The default monitor has the same vCPU list as the
+associating allocation. For non-default monitors, there
+are no vCPU overlap permitted.
+  
+
+  
 
   
 
diff --git a/docs/schemas/domaincommon.rng b/docs/schemas/domaincommon.rng
index 5c533d6..7ce49d3 100644
--- a/docs/schemas/domaincommon.rng
+++ b/docs/schemas/domaincommon.rng
@@ -981,6 +981,16 @@
 
   
 
+
+  
+
+  
+
+
+  
+
+  
+
   
 
 
diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
index a068d4d..01f795f 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -2955,13 +2955,31 @@ virDomainLoaderDefFree(virDomainLoaderDefPtr loader)
 
 
 static void
+virDomainResctrlMonDefFree(virDomainResctrlMonDefPtr domresmon)
+{
+if (!domresmon)
+return;
+
+virBitmapFree(domresmon->vcpus);
+virObjectUnref(domresmon->instance);
+VIR_FREE(domresmon);
+}
+
+
+static void
 virDomainResctrlDefFree(virDomainResctrlDefPtr resctrl)
 {
+size_t i = 0;
+
 if (!resctrl)
 return;
 
+for (i = 0; i < resctrl->nmonitors; i++)
+virDomainResctrlMonDefFree(resctrl->monitors[i]);
+
 virObjectUnref(resctrl->alloc);
 virBitmapFree(resctrl->vcpus);
+VIR_FREE(resctrl->monitors);
 VIR_FREE(resctrl);
 }
 
@@ -18920,6 +18938,177 @@ virDomainCachetuneDefParseCache(xmlXPathContextPtr 
ctxt,
 }
 
 
+/* Checking if the monitor's vcpus is conflicted with existing allocation
+ * and monitors.
+ *
+ * Returns 1 if @vcpus equals to @resctrl->vcpus, then the monitor will
+ * share the underlying resctrl group with @resctrl->alloc. Returns - 1
+ * if any conflict found. Returns 0 if no conflict and @vcpus is not equal
+ * to @resctrl->vcpus.
+ */
+static int
+virDomainResctrlMonValidateVcpus(virDomainResctrlDefPtr resctrl,
+virBitmapPtr vcpus)
+{
+size_t i = 0;
+int vcpu = -1;
+size_t mons_same_alloc_vcpus = 0;
+
+if (virBitmapIsAllClear(vcpus)) {
+virReportError(VIR_ERR_INVALID_ARG, "%s",
+   _("vcpus is empty"));
+return -1;
+}
+
+while ((vcpu = virBitmapNextSetBit(vcpus, vcpu)) >= 0) {
+if (!virBitmapIsBitSet(resctrl->vcpus, vcpu)) {
+virReportError(VIR_ERR_INVALID_ARG, "%s",
+   _("Monitor vcpus conflicts with allocation"));
+return -1;
+}
+}
+
+if (virBitmapEqual(vcpus, resctrl->vcpus))
+return 1;
+
+for (i = 0; i < resctrl->nmonitors; i++) {
+if (virBitmapEqual(resctrl->vcpus, resctrl->monitors[i]->vcpus)) {
+mons_same_alloc_vcpus++;
+continue;
+}
+
+if (virBitmapOverlaps(vcpus, resctrl->monitors[i]->vcpus)) {
+virReportError(VIR_ERR_INVALID_ARG, "%s",
+

[libvirt] [PATCHv7 08/18] util: Add interface for creating monitor group

2018-10-22 Thread Wang Huaqiang
Add interface for creating the resource monitoring group according
to '@virResctrlMonitor->path'.

Signed-off-by: Wang Huaqiang 
---
 src/libvirt_private.syms |  1 +
 src/util/virresctrl.c| 24 
 src/util/virresctrl.h|  4 
 3 files changed, 29 insertions(+)

diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
index e175c8b..a878083 100644
--- a/src/libvirt_private.syms
+++ b/src/libvirt_private.syms
@@ -2681,6 +2681,7 @@ virResctrlInfoGetMonitorPrefix;
 virResctrlInfoMonFree;
 virResctrlInfoNew;
 virResctrlMonitorAddPID;
+virResctrlMonitorCreate;
 virResctrlMonitorDeterminePath;
 virResctrlMonitorNew;
 
diff --git a/src/util/virresctrl.c b/src/util/virresctrl.c
index 5b984d9..9f42065 100644
--- a/src/util/virresctrl.c
+++ b/src/util/virresctrl.c
@@ -2542,3 +2542,27 @@ virResctrlMonitorAddPID(virResctrlMonitorPtr monitor,
 {
 return virResctrlAddPID(monitor->path, pid);
 }
+
+
+int
+virResctrlMonitorCreate(virResctrlMonitorPtr monitor,
+const char *machinename)
+{
+int lockfd = -1;
+int ret = -1;
+
+if (!monitor)
+return 0;
+
+if (virResctrlMonitorDeterminePath(monitor, machinename) < 0)
+return -1;
+
+lockfd = virResctrlLockWrite();
+if (lockfd < 0)
+return -1;
+
+ret = virResctrlCreateGroupPath(monitor->path);
+
+virResctrlUnlock(lockfd);
+return ret;
+}
diff --git a/src/util/virresctrl.h b/src/util/virresctrl.h
index 52d283a..76e40a2 100644
--- a/src/util/virresctrl.h
+++ b/src/util/virresctrl.h
@@ -201,4 +201,8 @@ virResctrlMonitorDeterminePath(virResctrlMonitorPtr monitor,
 int
 virResctrlMonitorAddPID(virResctrlMonitorPtr monitor,
 pid_t pid);
+
+int
+virResctrlMonitorCreate(virResctrlMonitorPtr monitor,
+const char *machinename);
 #endif /*  __VIR_RESCTRL_H__ */
-- 
2.7.4

--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list


[libvirt] [PATCHv7 16/18] qemu: refactor qemuDomainGetStatsCpu

2018-10-22 Thread Wang Huaqiang
Refactoring qemuDomainGetStatsCpu, make it possible to add
more CPU statistics.

Signed-off-by: Wang Huaqiang 
---
 src/qemu/qemu_driver.c | 45 ++---
 1 file changed, 22 insertions(+), 23 deletions(-)

diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index a52e249..12a5f8f 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -19711,30 +19711,29 @@ qemuDomainGetStatsCpu(virQEMUDriverPtr driver 
ATTRIBUTE_UNUSED,
 unsigned long long sys_time = 0;
 int err = 0;
 
-if (!priv->cgroup)
-return 0;
-
-err = virCgroupGetCpuacctUsage(priv->cgroup, &cpu_time);
-if (!err && virTypedParamsAddULLong(&record->params,
-&record->nparams,
-maxparams,
-"cpu.time",
-cpu_time) < 0)
-return -1;
+if (priv->cgroup) {
+err = virCgroupGetCpuacctUsage(priv->cgroup, &cpu_time);
+if (!err && virTypedParamsAddULLong(&record->params,
+&record->nparams,
+maxparams,
+"cpu.time",
+cpu_time) < 0)
+return -1;
 
-err = virCgroupGetCpuacctStat(priv->cgroup, &user_time, &sys_time);
-if (!err && virTypedParamsAddULLong(&record->params,
-&record->nparams,
-maxparams,
-"cpu.user",
-user_time) < 0)
-return -1;
-if (!err && virTypedParamsAddULLong(&record->params,
-&record->nparams,
-maxparams,
-"cpu.system",
-sys_time) < 0)
-return -1;
+err = virCgroupGetCpuacctStat(priv->cgroup, &user_time, &sys_time);
+if (!err && virTypedParamsAddULLong(&record->params,
+&record->nparams,
+maxparams,
+"cpu.user",
+user_time) < 0)
+return -1;
+if (!err && virTypedParamsAddULLong(&record->params,
+&record->nparams,
+maxparams,
+"cpu.system",
+sys_time) < 0)
+return -1;
+}
 
 return 0;
 }
-- 
2.7.4

--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list


[libvirt] [PATCHv7 10/18] conf: Remove virDomainResctrlAppend and introduce virDomainResctrlNew

2018-10-22 Thread Wang Huaqiang
Introduced virDomainResctrlNew to do the most part of virDomainResctrlAppend
and move the operation of appending resctrl to @def->resctrls out of
function.

Rather than rely on virDomainResctrlAppend to perform the allocation, move
the onus to the caller and make use of virBitmapNewCopy for @vcpus and
virObjectRef for @alloc, thus removing the need to set each to NULL after the
call.

Signed-off-by: Wang Huaqiang 
---
 src/conf/domain_conf.c | 60 +-
 1 file changed, 35 insertions(+), 25 deletions(-)

diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
index e8e0adc..39bd396 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -18920,26 +18920,22 @@ virDomainCachetuneDefParseCache(xmlXPathContextPtr 
ctxt,
 }
 
 
-static int
-virDomainResctrlAppend(virDomainDefPtr def,
-   xmlNodePtr node,
-   virResctrlAllocPtr alloc,
-   virBitmapPtr vcpus,
-   unsigned int flags)
+static virDomainResctrlDefPtr
+virDomainResctrlNew(xmlNodePtr node,
+virResctrlAllocPtr *alloc,
+virBitmapPtr *vcpus,
+unsigned int flags)
 {
 char *vcpus_str = NULL;
 char *alloc_id = NULL;
-virDomainResctrlDefPtr tmp_resctrl = NULL;
-int ret = -1;
-
-if (VIR_ALLOC(tmp_resctrl) < 0)
-goto cleanup;
+virDomainResctrlDefPtr resctrl = NULL;
+virDomainResctrlDefPtr ret = NULL;
 
 /* We need to format it back because we need to be consistent in the naming
  * even when users specify some "sub-optimal" string there. */
-vcpus_str = virBitmapFormat(vcpus);
+vcpus_str = virBitmapFormat(*vcpus);
 if (!vcpus_str)
-goto cleanup;
+return NULL;
 
 if (!(flags & VIR_DOMAIN_DEF_PARSE_INACTIVE))
 alloc_id = virXMLPropString(node, "id");
@@ -18954,18 +18950,23 @@ virDomainResctrlAppend(virDomainDefPtr def,
 goto cleanup;
 }
 
-if (virResctrlAllocSetID(alloc, alloc_id) < 0)
+if (virResctrlAllocSetID(*alloc, alloc_id) < 0)
 goto cleanup;
 
-tmp_resctrl->vcpus = vcpus;
-tmp_resctrl->alloc = alloc;
+if (VIR_ALLOC(resctrl) < 0)
+goto cleanup;
 
-if (VIR_APPEND_ELEMENT(def->resctrls, def->nresctrls, tmp_resctrl) < 0)
+if (!(resctrl->vcpus = virBitmapNewCopy(*vcpus))) {
+virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+   _("failed to copy 'vcpus'"));
 goto cleanup;
+}
 
-ret = 0;
+resctrl->alloc = virObjectRef(*alloc);
+
+VIR_STEAL_PTR(ret, resctrl);
  cleanup:
-virDomainResctrlDefFree(tmp_resctrl);
+virDomainResctrlDefFree(resctrl);
 VIR_FREE(alloc_id);
 VIR_FREE(vcpus_str);
 return ret;
@@ -18982,6 +18983,7 @@ virDomainCachetuneDefParse(virDomainDefPtr def,
 xmlNodePtr *nodes = NULL;
 virBitmapPtr vcpus = NULL;
 virResctrlAllocPtr alloc = NULL;
+virDomainResctrlDefPtr resctrl = NULL;
 ssize_t i = 0;
 int n;
 int ret = -1;
@@ -19025,14 +19027,17 @@ virDomainCachetuneDefParse(virDomainDefPtr def,
 goto cleanup;
 }
 
-if (virDomainResctrlAppend(def, node, alloc, vcpus, flags) < 0)
+resctrl = virDomainResctrlNew(node, &alloc, &vcpus, flags);
+if (!resctrl)
+goto cleanup;
+
+if (VIR_APPEND_ELEMENT(def->resctrls, def->nresctrls, resctrl) < 0)
 goto cleanup;
-vcpus = NULL;
-alloc = NULL;
 
 ret = 0;
  cleanup:
 ctxt->node = oldnode;
+virDomainResctrlDefFree(resctrl);
 virObjectUnref(alloc);
 virBitmapFree(vcpus);
 VIR_FREE(nodes);
@@ -19190,6 +19195,8 @@ virDomainMemorytuneDefParse(virDomainDefPtr def,
 xmlNodePtr *nodes = NULL;
 virBitmapPtr vcpus = NULL;
 virResctrlAllocPtr alloc = NULL;
+virDomainResctrlDefPtr resctrl = NULL;
+
 ssize_t i = 0;
 int n;
 int ret = -1;
@@ -19234,15 +19241,18 @@ virDomainMemorytuneDefParse(virDomainDefPtr def,
  * just update the existing alloc information, which is done in above
  * virDomainMemorytuneDefParseMemory */
 if (new_alloc) {
-if (virDomainResctrlAppend(def, node, alloc, vcpus, flags) < 0)
+resctrl = virDomainResctrlNew(node, &alloc, &vcpus, flags);
+if (!resctrl)
+goto cleanup;
+
+if (VIR_APPEND_ELEMENT(def->resctrls, def->nresctrls, resctrl) < 0)
 goto cleanup;
-vcpus = NULL;
-alloc = NULL;
 }
 
 ret = 0;
  cleanup:
 ctxt->node = oldnode;
+virDomainResctrlDefFree(resctrl);
 virObjectUnref(alloc);
 virBitmapFree(vcpus);
 VIR_FREE(nodes);
-- 
2.7.4

--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list


[libvirt] [PATCHv7 11/18] conf: move virResctrlAllocIsEmpty to a place a litter lower

2018-10-22 Thread Wang Huaqiang
This refactor allows to add some code between virDomainResctrlNew
and virResctrlAllocIsEmpty to extend the scope of resctrl.

Signed-off-by: Wang Huaqiang 
---
 src/conf/domain_conf.c | 8 
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
index 39bd396..a068d4d 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -19022,15 +19022,15 @@ virDomainCachetuneDefParse(virDomainDefPtr def,
 goto cleanup;
 }
 
+resctrl = virDomainResctrlNew(node, &alloc, &vcpus, flags);
+if (!resctrl)
+goto cleanup;
+
 if (virResctrlAllocIsEmpty(alloc)) {
 ret = 0;
 goto cleanup;
 }
 
-resctrl = virDomainResctrlNew(node, &alloc, &vcpus, flags);
-if (!resctrl)
-goto cleanup;
-
 if (VIR_APPEND_ELEMENT(def->resctrls, def->nresctrls, resctrl) < 0)
 goto cleanup;
 
-- 
2.7.4

--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list


[libvirt] [PATCHv7 13/18] qemu: enable resctrl monitor in qemu

2018-10-22 Thread Wang Huaqiang
Add functions for creating, destroying, reconnecting resctrl
monitor in qemu according to the configuration in domain XML.

Signed-off-by: Wang Huaqiang 
---
 src/qemu/qemu_process.c | 66 -
 1 file changed, 65 insertions(+), 1 deletion(-)

diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c
index e9c7618..fba4fb4 100644
--- a/src/qemu/qemu_process.c
+++ b/src/qemu/qemu_process.c
@@ -2611,10 +2611,21 @@ qemuProcessResctrlCreate(virQEMUDriverPtr driver,
 return -1;
 
 for (i = 0; i < vm->def->nresctrls; i++) {
+size_t j = 0;
 if (virResctrlAllocCreate(caps->host.resctrl,
   vm->def->resctrls[i]->alloc,
   priv->machineName) < 0)
 goto cleanup;
+
+for (j = 0; j < vm->def->resctrls[i]->nmonitors; j++) {
+virDomainResctrlMonDefPtr mon = NULL;
+
+mon = vm->def->resctrls[i]->monitors[j];
+if (virResctrlMonitorCreate(mon->instance,
+priv->machineName) < 0)
+goto cleanup;
+
+}
 }
 
 ret = 0;
@@ -5430,6 +5441,7 @@ qemuProcessSetupVcpu(virDomainObjPtr vm,
 {
 pid_t vcpupid = qemuDomainGetVcpuPid(vm, vcpuid);
 virDomainVcpuDefPtr vcpu = virDomainDefGetVcpu(vm->def, vcpuid);
+virDomainResctrlMonDefPtr mon = NULL;
 size_t i = 0;
 
 if (qemuProcessSetupPid(vm, vcpupid, VIR_CGROUP_THREAD_VCPU,
@@ -5440,11 +5452,42 @@ qemuProcessSetupVcpu(virDomainObjPtr vm,
 return -1;
 
 for (i = 0; i < vm->def->nresctrls; i++) {
+size_t j = 0;
 virDomainResctrlDefPtr ct = vm->def->resctrls[i];
 
 if (virBitmapIsBitSet(ct->vcpus, vcpuid)) {
 if (virResctrlAllocAddPID(ct->alloc, vcpupid) < 0)
 return -1;
+
+/* The order of invoking virResctrlMonitorAddPID matters, it is
+ * required to invoke this function first for monitor that has
+ * the same vcpus setting as the allocation in same def->resctrl.
+ * Otherwise, some other monitor's pid may be removed from its
+ * resource group's 'tasks' file.*/
+for (j = 0; j < vm->def->resctrls[i]->nmonitors; j++) {
+mon = vm->def->resctrls[i]->monitors[j];
+
+if (!virBitmapEqual(ct->vcpus, mon->vcpus))
+continue;
+
+if (virBitmapIsBitSet(mon->vcpus, vcpuid)) {
+if (virResctrlMonitorAddPID(mon->instance, vcpupid) < 0)
+return -1;
+}
+break;
+}
+
+for (j = 0; j < vm->def->resctrls[i]->nmonitors; j++) {
+mon = vm->def->resctrls[i]->monitors[j];
+
+if (virBitmapEqual(ct->vcpus, mon->vcpus))
+continue;
+
+if (virBitmapIsBitSet(mon->vcpus, vcpuid)) {
+if (virResctrlMonitorAddPID(mon->instance, vcpupid) < 0)
+return -1;
+}
+}
 break;
 }
 }
@@ -7207,8 +7250,18 @@ void qemuProcessStop(virQEMUDriverPtr driver,
 /* Remove resctrl allocation after cgroups are cleaned up which makes it
  * kind of safer (although removing the allocation should work even with
  * pids in tasks file */
-for (i = 0; i < vm->def->nresctrls; i++)
+for (i = 0; i < vm->def->nresctrls; i++) {
+size_t j = 0;
+
+for (j = 0; j < vm->def->resctrls[i]->nmonitors; j++) {
+virDomainResctrlMonDefPtr mon = NULL;
+
+mon = vm->def->resctrls[i]->monitors[j];
+virResctrlMonitorRemove(mon->instance);
+}
+
 virResctrlAllocRemove(vm->def->resctrls[i]->alloc);
+}
 
 qemuProcessRemoveDomainStatus(driver, vm);
 
@@ -7939,9 +7992,20 @@ qemuProcessReconnect(void *opaque)
 goto error;
 
 for (i = 0; i < obj->def->nresctrls; i++) {
+size_t j = 0;
+
 if (virResctrlAllocDeterminePath(obj->def->resctrls[i]->alloc,
  priv->machineName) < 0)
 goto error;
+
+for (j = 0; j < obj->def->resctrls[i]->nmonitors; j++) {
+virDomainResctrlMonDefPtr mon = NULL;
+
+mon = obj->def->resctrls[i]->monitors[j];
+if (virResctrlMonitorDeterminePath(mon->instance,
+   priv->machineName) < 0)
+goto error;
+}
 }
 
 /* update domain state XML with possibly updated state in virDomainObj */
-- 
2.7.4

--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list


[libvirt] [PATCHv7 04/18] util: Add interface to determine monitor path

2018-10-22 Thread Wang Huaqiang
Add interface for resctrl monitor to determine the path.

Signed-off-by: Wang Huaqiang 
---
 src/libvirt_private.syms |  1 +
 src/util/virresctrl.c| 55 
 src/util/virresctrl.h|  5 -
 3 files changed, 60 insertions(+), 1 deletion(-)

diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
index d2573c5..5235046 100644
--- a/src/libvirt_private.syms
+++ b/src/libvirt_private.syms
@@ -2680,6 +2680,7 @@ virResctrlInfoGetCache;
 virResctrlInfoGetMonitorPrefix;
 virResctrlInfoMonFree;
 virResctrlInfoNew;
+virResctrlMonitorDeterminePath;
 virResctrlMonitorNew;
 
 
diff --git a/src/util/virresctrl.c b/src/util/virresctrl.c
index 956aca8..1d0eb01 100644
--- a/src/util/virresctrl.c
+++ b/src/util/virresctrl.c
@@ -2462,3 +2462,58 @@ virResctrlMonitorNew(void)
 
 return virObjectNew(virResctrlMonitorClass);
 }
+
+
+/*
+ * virResctrlMonitorDeterminePath
+ *
+ * @monitor: Pointer to a resctrl monitor
+ * @machinename: Name string of the VM
+ *
+ * Determines the directory path that the underlying resctrl group will be
+ * created with.
+ *
+ * A monitor represents a directory under resource control file system,
+ * its directory path could be the same path as @monitor->alloc, could be a
+ * path of directory under 'mon_groups' of @monitor->alloc, or a path of
+ * directory under '/sys/fs/resctrl/mon_groups' if @monitor->alloc is NULL.
+ *
+ * Returns 0 on success, -1 on error.
+ */
+int
+virResctrlMonitorDeterminePath(virResctrlMonitorPtr monitor,
+   const char *machinename)
+{
+VIR_AUTOFREE(char *) parentpath = NULL;
+
+if (!monitor) {
+virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+   _("Invalid resctrl monitor"));
+return -1;
+}
+
+if (monitor->path) {
+virReportError(VIR_ERR_INTERNAL_ERROR,
+   _("Resctrl monitor path is already set to '%s'"),
+   monitor->path);
+return -1;
+}
+
+if (monitor->id && monitor->alloc && monitor->alloc->id) {
+if (STREQ(monitor->id, monitor->alloc->id)) {
+if (VIR_STRDUP(monitor->path, monitor->alloc->path) < 0)
+return -1;
+return 0;
+}
+}
+
+if (virAsprintf(&parentpath, "%s/mon_groups", monitor->alloc->path) < 0)
+return -1;
+
+monitor->path = virResctrlDeterminePath(parentpath, machinename,
+monitor->id);
+if (!monitor->path)
+return -1;
+
+return 0;
+}
diff --git a/src/util/virresctrl.h b/src/util/virresctrl.h
index eaa077d..baae554 100644
--- a/src/util/virresctrl.h
+++ b/src/util/virresctrl.h
@@ -191,7 +191,10 @@ virResctrlInfoGetMonitorPrefix(virResctrlInfoPtr resctrl,
 typedef struct _virResctrlMonitor virResctrlMonitor;
 typedef virResctrlMonitor *virResctrlMonitorPtr;
 
-
 virResctrlMonitorPtr
 virResctrlMonitorNew(void);
+
+int
+virResctrlMonitorDeterminePath(virResctrlMonitorPtr monitor,
+   const char *machinename);
 #endif /*  __VIR_RESCTRL_H__ */
-- 
2.7.4

--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list


[libvirt] [PATCHv7 05/18] util: Refactor code for adding PID to the resource group

2018-10-22 Thread Wang Huaqiang
The code of adding PID to the allocation could be reused, refactor it
for later reuse.

Signed-off-by: Wang Huaqiang 
---
 src/util/virresctrl.c | 30 +++---
 1 file changed, 19 insertions(+), 11 deletions(-)

diff --git a/src/util/virresctrl.c b/src/util/virresctrl.c
index 1d0eb01..5fc8772 100644
--- a/src/util/virresctrl.c
+++ b/src/util/virresctrl.c
@@ -2390,26 +2390,21 @@ virResctrlAllocCreate(virResctrlInfoPtr resctrl,
 }
 
 
-int
-virResctrlAllocAddPID(virResctrlAllocPtr alloc,
-  pid_t pid)
+static int
+virResctrlAddPID(const char *path,
+ pid_t pid)
 {
 char *tasks = NULL;
 char *pidstr = NULL;
 int ret = 0;
 
-/* If the allocation is empty, then it is impossible to add a PID to
- * allocation  due to lacking of its 'tasks' file. Just return */
-if (virResctrlAllocIsEmpty(alloc))
-return 0;
-
-if (!alloc->path) {
+if (!path) {
 virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
-   _("Cannot add pid to non-existing resctrl allocation"));
+   _("Cannot add pid to non-existing resctrl group"));
 return -1;
 }
 
-if (virAsprintf(&tasks, "%s/tasks", alloc->path) < 0)
+if (virAsprintf(&tasks, "%s/tasks", path) < 0)
 return -1;
 
 if (virAsprintf(&pidstr, "%lld", (long long int) pid) < 0)
@@ -2431,6 +2426,19 @@ virResctrlAllocAddPID(virResctrlAllocPtr alloc,
 
 
 int
+virResctrlAllocAddPID(virResctrlAllocPtr alloc,
+  pid_t pid)
+{
+/* If allocation is empty, then no resctrl directory and the 'tasks' file
+ * exists, just return */
+if (virResctrlAllocIsEmpty(alloc))
+return 0;
+
+return virResctrlAddPID(alloc->path, pid);
+}
+
+
+int
 virResctrlAllocRemove(virResctrlAllocPtr alloc)
 {
 int ret = 0;
-- 
2.7.4

--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list


[libvirt] [PATCHv7 06/18] util: Add interface for adding PID to the monitor

2018-10-22 Thread Wang Huaqiang
Add interface for adding task PID to the monitor.

Signed-off-by: Wang Huaqiang 
---
 src/libvirt_private.syms | 1 +
 src/util/virresctrl.c| 8 
 src/util/virresctrl.h| 4 
 3 files changed, 13 insertions(+)

diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
index 5235046..e175c8b 100644
--- a/src/libvirt_private.syms
+++ b/src/libvirt_private.syms
@@ -2680,6 +2680,7 @@ virResctrlInfoGetCache;
 virResctrlInfoGetMonitorPrefix;
 virResctrlInfoMonFree;
 virResctrlInfoNew;
+virResctrlMonitorAddPID;
 virResctrlMonitorDeterminePath;
 virResctrlMonitorNew;
 
diff --git a/src/util/virresctrl.c b/src/util/virresctrl.c
index 5fc8772..93b5e70 100644
--- a/src/util/virresctrl.c
+++ b/src/util/virresctrl.c
@@ -2525,3 +2525,11 @@ virResctrlMonitorDeterminePath(virResctrlMonitorPtr 
monitor,
 
 return 0;
 }
+
+
+int
+virResctrlMonitorAddPID(virResctrlMonitorPtr monitor,
+pid_t pid)
+{
+return virResctrlAddPID(monitor->path, pid);
+}
diff --git a/src/util/virresctrl.h b/src/util/virresctrl.h
index baae554..52d283a 100644
--- a/src/util/virresctrl.h
+++ b/src/util/virresctrl.h
@@ -197,4 +197,8 @@ virResctrlMonitorNew(void);
 int
 virResctrlMonitorDeterminePath(virResctrlMonitorPtr monitor,
const char *machinename);
+
+int
+virResctrlMonitorAddPID(virResctrlMonitorPtr monitor,
+pid_t pid);
 #endif /*  __VIR_RESCTRL_H__ */
-- 
2.7.4

--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list


[libvirt] [PATCHv7 00/18] Introduce x86 Cache Monitoring Technology (CMT)

2018-10-22 Thread Wang Huaqiang
This series of patches and the series already been merged introduce
the x86 Cache Monitoring Technology (CMT) to libvirt by interacting
with kernel resource control (resctrl) interface. CMT is one of the
Intel(R) x86 CPU feature which belongs to the Resource Director
Technology (RDT). CMT reports the occupancy of the last level cache,
which is shared by all CPU cores.

In the v1 series, an original and complete feature for CMT was introduced
The v2 and v3 patches address the feature for the host capability of CMT.
v4 is addressing the feature for monitoring VM vcpu thread set cache
occupancy and reporting it through a virsh command.

We have serval discussion about the enabling of CMT, please refer to
following links for the RFCs.
RFCv3
https://www.redhat.com/archives/libvir-list/2018-August/msg01213.html
RFCv2
https://www.redhat.com/archives/libvir-list/2018-July/msg00409.html
https://www.redhat.com/archives/libvir-list/2018-July/msg01241.html
RFCv1
https://www.redhat.com/archives/libvir-list/2018-June/msg00674.html

And the merged commits are list as below, for host capability of CMT.
6af8417415508c31f8ce71234b573b4999f35980
8f6887998bf63594ae26e3db18d4d5896c5f2cb4
58fcee6f3a2b7e89c21c1fb4ec21429c31a0c5b8
12093f1feaf8f5023dcd9d65dff111022842183d
a5d293c18831dcf69ec6195798387fbb70c9f461


1. About reason why CMT is necessary in libvirt?
The perf events of 'CMT, MBML, MBMT' have been phased out since Linux
kernel commit c39a0e2c8850f08249383f2425dbd8dbe4baad69, in libvirt
the perf based cmt,mbm will not work with the latest linux kernel. These
patches add CMT feature to libvirt through kernel resctrlfs interface.

2 Create cache monitoring group (cache monitor).

The main interface for creating monitoring group is through XML file. The
proposed configuration is like:

  

  
  
+ 


+ 

  

In above XML, created 2 cache resctrl allocation groups and 2 resctrl
monitoring groups.
The changes of cache monitor will be effective in next booting of VM.

2 Show CMT result through command 'domstats'

Adding the interface in qemu to report this information for resource
monitor group through command 'virsh domstats --cpu-total'.
Below is a typical output:

 # virsh domstats 1 --cpu-total
 Domain: 'ubuntu16.04-base'
 ...
   cpu.cache.monitor.count=2
   cpu.cache.monitor.0.name=vcpus_1
   cpu.cache.monitor.0.vcpus=1
   cpu.cache.monitor.0.bank.count=2
   cpu.cache.monitor.0.bank.0.id=0
   cpu.cache.monitor.0.bank.0.bytes=4505600
   cpu.cache.monitor.0.bank.1.id=1
   cpu.cache.monitor.0.bank.1.bytes=5586944
   cpu.cache.monitor.1.name=vcpus_4-6
   cpu.cache.monitor.1.vcpus=4,5,6
   cpu.cache.monitor.1.bank.count=2
   cpu.cache.monitor.1.bank.0.id=0
   cpu.cache.monitor.1.bank.0.bytes=17571840
   cpu.cache.monitor.1.bank.1.id=1
   cpu.cache.monitor.1.bank.1.bytes=29106176

Changes in v7:
- Add several lines removed by mistake.

Changes in v6:
- Addressing John's review comments for v5.
- Removed and cleaned the concepts of 'default allocation' and
'default monitor'.
- qemu: virsh domstats --cpu-total output for CMT, add identifier
'monitor' for each itm.

Changes in v5:
- qemu: Setting up vcpu and adding pids to resctrl monitor groups during
re-connection.
- Add the document for domain configuration related to resctrl monitor.

Changes in v4:
v4 is addressing the feature for monitoring VM vcpu
thread set cache occupancy and reporting it through a
virsh command.
- Introduced resctrl default allocation
- Introduced resctrl monitor and default monitor

Changes in v3:
- Addressed John Ferlan's review.
- Typo fixed.
- Removed VIR_ENUM_DECL(virMonitor);

Changes in v2:
- Introduced MBM capability.
- Capability layout changed
* Moved  from cahe  to 
* Renamed  to 
- Document for 'reuseThreshold' changed.
- Introduced API virResctrlInfoGetMonitorPrefix
- Added more tests, covering standalone CMT, fake new
  feature.
- Creating CMT resource control group will be
  subsequent job.

Wang Huaqiang (18):
  docs,util: Refactor schemas and virresctrl to support optional cache
  util: Introduce resctrl monitor for CMT
  util: Refactor code for determining allocation path
  util: Add interface to determine monitor path
  util: Refactor code for adding PID to the resource group
  util: Add interface for adding PID to the monitor
  util: Refactor code for creating resctrl group
  util: Add interface for creating monitor group
  util: Add more interfaces for resctrl monitor
  conf: Remove virDomainResctrlAppend and introduce virDomainResctrlNew
  conf: move virResctrlAllocIsEmpty to a place a litter lower
  conf: Introduce cache monitor element in cachetune
  qemu: enable resctrl monitor in qemu
  util: Add function for checking if monitor is running
  conf: Add 'id' to virDomainResctrlDef
  qemu: refactor qemuDomainGetStatsCpu
  qemu: Report cache occupancy (CMT) with domstats
  qemu: 

[libvirt] [PATCHv7 02/18] util: Introduce resctrl monitor for CMT

2018-10-22 Thread Wang Huaqiang
Cache Monitoring Technology (aka CMT) provides the capability
to report cache utilization information of system task.

This patch introduces the concept of resctrl monitor through
data structure virResctrlMonitor.

Signed-off-by: Wang Huaqiang 
---
 src/libvirt_private.syms |  1 +
 src/util/virresctrl.c| 79 
 src/util/virresctrl.h|  9 ++
 3 files changed, 83 insertions(+), 6 deletions(-)

diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
index 335210c..d2573c5 100644
--- a/src/libvirt_private.syms
+++ b/src/libvirt_private.syms
@@ -2680,6 +2680,7 @@ virResctrlInfoGetCache;
 virResctrlInfoGetMonitorPrefix;
 virResctrlInfoMonFree;
 virResctrlInfoNew;
+virResctrlMonitorNew;
 
 
 # util/virrotatingfile.h
diff --git a/src/util/virresctrl.c b/src/util/virresctrl.c
index 91bd341..6530801 100644
--- a/src/util/virresctrl.c
+++ b/src/util/virresctrl.c
@@ -36,9 +36,9 @@ VIR_LOG_INIT("util.virresctrl")
 
 
 /* Resctrl is short for Resource Control.  It might be implemented for various
- * resources. Currently this supports cache allocation technology (aka CAT) and
- * memory bandwidth allocation (aka MBA). More resources technologies may be
- * added in the future.
+ * resources. Currently this supports cache allocation technology (aka CAT),
+ * memory bandwidth allocation (aka MBA) and cache monitoring technology (aka
+ * CMT). More resources technologies may be added in the future.
  */
 
 
@@ -105,6 +105,7 @@ typedef virResctrlAllocMemBW *virResctrlAllocMemBWPtr;
 /* Class definitions and initializations */
 static virClassPtr virResctrlInfoClass;
 static virClassPtr virResctrlAllocClass;
+static virClassPtr virResctrlMonitorClass;
 
 
 /* virResctrlInfo */
@@ -224,11 +225,16 @@ virResctrlInfoMonFree(virResctrlInfoMonPtr mon)
 }
 
 
-/* virResctrlAlloc */
+/* virResctrlAlloc and virResctrlMonitor*/
 
 /*
- * virResctrlAlloc represents one allocation (in XML under cputune/cachetune 
and
- * consequently a directory under /sys/fs/resctrl).  Since it can have multiple
+ * virResctrlAlloc and virResctrlMonitor are representing a resource control
+ * group (in XML under cputune/cachetune and consequently a directory under
+ * /sys/fs/resctrl). virResctrlAlloc is the data structure for resource
+ * allocation, while the virResctrlMonitor represents the resource monitoring
+ * part.
+ *
+ * virResctrlAlloc represents one allocation. Since it can have multiple
  * parts of multiple caches allocated it is represented as bunch of nested
  * sparse arrays (by sparse I mean array of pointers so that each might be NULL
  * in case there is no allocation for that particular cache allocation (level,
@@ -275,6 +281,18 @@ virResctrlInfoMonFree(virResctrlInfoMonPtr mon)
  * a sparse array to represent whether a memory bandwidth allocation happens
  * on corresponding node. The available memory controller number is collected
  * in 'virResctrlInfo'.
+ *
+ * =Cache monitoring technology (CMT)=
+ *
+ * Cache monitoring technology is used to perceive how many cache the process
+ * is using actually. virResctrlMonitor represents the resource control
+ * monitoring group, it is supported to monitor resource utilization
+ * information on granularity of vcpu.
+ *
+ * From hardware perspective, cache monitoring technology (CMT), memory
+ * bandwidth technology (MBM), as well as the CAT and MBA, are all orthogonal
+ * features. The monitor will be created under the scope of default resctl
+ * group if no specific CAT or MBA entries are provided for the guest."
  */
 struct _virResctrlAllocPerType {
 /* There could be bool saying whether this is set or not, but since 
everything
@@ -320,6 +338,29 @@ struct _virResctrlAlloc {
 char *path;
 };
 
+/*
+ * virResctrlMonitor is the data structure for resctrl monitor. Resctrl
+ * monitor represents a resctrl monitoring group, which can be used to
+ * monitor the resource utilization information for either cache or
+ * memory bandwidth.
+ */
+struct _virResctrlMonitor {
+virObject parent;
+
+/* In resctrl, each monitor is associated with one specific allocation,
+ * either the allocation under / sys / fs / resctrl or allocation of the
+ * root directory itself. This pointer points to the allocation
+ * this monitor associated with. */
+virResctrlAllocPtr alloc;
+/* The monitor identifier. For a monitor has the same @path name as its
+ * @alloc, the @id will be set to the same value as it is in @alloc->id.
+ */
+char *id;
+/* libvirt-generated path in /sys/fs/resctrl for this particular
+ * monitor */
+char *path;
+};
+
 
 static void
 virResctrlAllocDispose(void *obj)
@@ -369,6 +410,17 @@ virResctrlAllocDispose(void *obj)
 }
 
 
+static void
+virResctrlMonitorDispose(void *obj)
+{
+virResctrlMonitorPtr monitor = obj;
+
+virObjectUnref(monitor->alloc);
+VIR_FREE(monitor->id);
+VIR_FREE(monitor->path);
+}
+
+
 /* Global initialization for classe

[libvirt] [PATCHv7 01/18] docs, util: Refactor schemas and virresctrl to support optional cache

2018-10-22 Thread Wang Huaqiang
Refactor schemas and virresctrl to support optional  element
in .

Later, the monitor entry will be introduced and to be placed
under . Either cache entry or monitor entry is
an optional element of .

An cachetune has no  element is taking the default resource
allocating policy defined in '/sys/fs/resctrl/schemata'.

Signed-off-by: Wang Huaqiang 
---
 docs/formatdomain.html.in |  4 ++--
 docs/schemas/domaincommon.rng |  4 ++--
 src/util/virresctrl.c | 28 
 3 files changed, 32 insertions(+), 4 deletions(-)

diff --git a/docs/formatdomain.html.in b/docs/formatdomain.html.in
index 8189959..b1651e3 100644
--- a/docs/formatdomain.html.in
+++ b/docs/formatdomain.html.in
@@ -943,8 +943,8 @@
 
   cache
   
-This element controls the allocation of CPU cache and has the
-following attributes:
+This optional element controls the allocation of CPU cache and has
+the following attributes:
 
   level
   
diff --git a/docs/schemas/domaincommon.rng b/docs/schemas/domaincommon.rng
index 099a949..5c533d6 100644
--- a/docs/schemas/domaincommon.rng
+++ b/docs/schemas/domaincommon.rng
@@ -956,7 +956,7 @@
 
   
 
-
+
   
 
   
@@ -980,7 +980,7 @@
   
 
   
-
+
   
 
 
diff --git a/src/util/virresctrl.c b/src/util/virresctrl.c
index 5d811a2..91bd341 100644
--- a/src/util/virresctrl.c
+++ b/src/util/virresctrl.c
@@ -234,6 +234,11 @@ virResctrlInfoMonFree(virResctrlInfoMonPtr mon)
  * in case there is no allocation for that particular cache allocation (level,
  * cache, ...) or memory allocation for particular node).
  *
+ * Allocation corresponding to root directory, /sys/fs/sysctrl/, defines the
+ * default resource allocating policy, which is created immediately after
+ * mounting, and owns all the tasks and cpus in the system. Cache or memory
+ * bandwidth resource will be shared for tasks in this allocation.
+ *
  * =Cache allocation technology (CAT)=
  *
  * Since one allocation can be made for caches on different levels, the first
@@ -2215,6 +2220,15 @@ virResctrlAllocDeterminePath(virResctrlAllocPtr alloc,
 return -1;
 }
 
+/* If the allocation is empty, then the path will be SYSFS_RESCTRL_PATH */
+if (virResctrlAllocIsEmpty(alloc)) {
+if (!alloc->path &&
+VIR_STRDUP(alloc->path, SYSFS_RESCTRL_PATH) < 0)
+return -1;
+
+return 0;
+}
+
 if (!alloc->path &&
 virAsprintf(&alloc->path, "%s/%s-%s",
 SYSFS_RESCTRL_PATH, machinename, alloc->id) < 0)
@@ -2248,6 +2262,11 @@ virResctrlAllocCreate(virResctrlInfoPtr resctrl,
 if (virResctrlAllocDeterminePath(alloc, machinename) < 0)
 return -1;
 
+/* If the allocation is empty, then do not create directory in underlying
+ * resctrl file system */
+if (virResctrlAllocIsEmpty(alloc))
+return 0;
+
 if (virFileExists(alloc->path)) {
 virReportError(VIR_ERR_INTERNAL_ERROR,
_("Path '%s' for resctrl allocation exists"),
@@ -2302,6 +2321,11 @@ virResctrlAllocAddPID(virResctrlAllocPtr alloc,
 char *pidstr = NULL;
 int ret = 0;
 
+/* If the allocation is empty, then it is impossible to add a PID to
+ * allocation  due to lacking of its 'tasks' file. Just return */
+if (virResctrlAllocIsEmpty(alloc))
+return 0;
+
 if (!alloc->path) {
 virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
_("Cannot add pid to non-existing resctrl allocation"));
@@ -2334,6 +2358,10 @@ virResctrlAllocRemove(virResctrlAllocPtr alloc)
 {
 int ret = 0;
 
+/* No directory have ever been created. Just return */
+if (virResctrlAllocIsEmpty(alloc))
+return 0;
+
 if (!alloc->path)
 return 0;
 
-- 
2.7.4

--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list


[libvirt] [PATCHv7 17/18] qemu: Report cache occupancy (CMT) with domstats

2018-10-22 Thread Wang Huaqiang
Adding the interface in qemu to report CMT statistic information
through command 'virsh domstats --cpu-total'.

Below is a typical output:

 # virsh domstats 1 --cpu-total
 Domain: 'ubuntu16.04-base'
   ...
   cpu.cache.monitor.count=2
   cpu.cache.monitor.0.name=vcpus_1
   cpu.cache.monitor.0.vcpus=1
   cpu.cache.monitor.0.bank.count=2
   cpu.cache.monitor.0.bank.0.id=0
   cpu.cache.monitor.0.bank.0.bytes=4505600
   cpu.cache.monitor.0.bank.1.id=1
   cpu.cache.monitor.0.bank.1.bytes=5586944
   cpu.cache.monitor.1.name=vcpus_4-6
   cpu.cache.monitor.1.vcpus=4,5,6
   cpu.cache.monitor.1.bank.count=2
   cpu.cache.monitor.1.bank.0.id=0
   cpu.cache.monitor.1.bank.0.bytes=17571840
   cpu.cache.monitor.1.bank.1.id=1
   cpu.cache.monitor.1.bank.1.bytes=29106176

Signed-off-by: Wang Huaqiang 
---
 src/libvirt-domain.c |   9 ++
 src/libvirt_private.syms |   1 +
 src/qemu/qemu_driver.c   | 229 +++
 src/util/virresctrl.c| 130 +++
 src/util/virresctrl.h|  12 +++
 5 files changed, 381 insertions(+)

diff --git a/src/libvirt-domain.c b/src/libvirt-domain.c
index 7690339..4895f9f 100644
--- a/src/libvirt-domain.c
+++ b/src/libvirt-domain.c
@@ -11345,6 +11345,15 @@ virConnectGetDomainCapabilities(virConnectPtr conn,
  * "cpu.user" - user cpu time spent in nanoseconds as unsigned long long.
  * "cpu.system" - system cpu time spent in nanoseconds as unsigned long
  *long.
+ * "cpu.cache.monitor.count" - tocal cache monitoring groups
+ * "cpu.cache.monitor.M.name" - name of cache monitoring group 'M'
+ * "cpu.cache.monitor.M.vcpus" - vcpus for cache monitoring group 'M'
+ * "cpu.cache.monitor.M.bank.count" - total bank number of cache monitoring
+ *group 'M'
+ * "cpu.cache.monitor.M.bank.N.id" - OS assigned cache bank id for cache
+ *'N' in cache monitoring group 'M'
+ * "cpu.cache.monitor.M.bank.N.bytes" - monitor's cache occupancy of cache
+ *bank 'N' in cache monitoring group 'M'
  *
  * VIR_DOMAIN_STATS_BALLOON:
  * Return memory balloon device information.
diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
index 91801ed..4551767 100644
--- a/src/libvirt_private.syms
+++ b/src/libvirt_private.syms
@@ -2683,6 +2683,7 @@ virResctrlInfoNew;
 virResctrlMonitorAddPID;
 virResctrlMonitorCreate;
 virResctrlMonitorDeterminePath;
+virResctrlMonitorGetCacheOccupancy;
 virResctrlMonitorGetID;
 virResctrlMonitorIsRunning;
 virResctrlMonitorNew;
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index 12a5f8f..9828118 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -102,6 +102,7 @@
 #include "virnuma.h"
 #include "dirname.h"
 #include "netdev_bandwidth_conf.h"
+#include "c-ctype.h"
 
 #define VIR_FROM_THIS VIR_FROM_QEMU
 
@@ -19698,6 +19699,230 @@ typedef enum {
 #define HAVE_JOB(flags) ((flags) & QEMU_DOMAIN_STATS_HAVE_JOB)
 
 
+/* In terms of the output of virBitmapFormat, both '1-3' and '1,3' are valid
+ * outputs and represent different vcpu set. But it is not easy to
+ * differentiate these two vcpu set formats at first glance.
+ *
+ * This function could be used to clear this ambiguity, it substitutes all '-'
+ * with ',' while generates semantically correct vcpu set.
+ * e.g. vcpu set string '1-3' will be replaced by string '1,2,3'. */
+static char *
+qemuDomainVcpuFormatHelper(const char *vcpus)
+{
+size_t i = 0;
+int last = 0;
+int start = 0;
+char * tmp = NULL;
+bool firstnum = true;
+const char *cur = vcpus;
+virBuffer buf = VIR_BUFFER_INITIALIZER;
+char *ret = NULL;
+
+if (virStringIsEmpty(cur))
+return NULL;
+
+while (*cur != '\0') {
+if (!c_isdigit(*cur))
+goto cleanup;
+
+if (virStrToLong_i(cur, &tmp, 10, &start) < 0)
+goto cleanup;
+if (start < 0)
+goto cleanup;
+
+cur = tmp;
+
+virSkipSpaces(&cur);
+
+if (*cur == ',' || *cur == 0) {
+if (!firstnum)
+virBufferAddChar(&buf, ',');
+virBufferAsprintf(&buf, "%d", start);
+firstnum = false;
+} else if (*cur == '-') {
+cur++;
+virSkipSpaces(&cur);
+
+if (virStrToLong_i(cur, &tmp, 10, &last) < 0)
+goto cleanup;
+
+if (last < start)
+goto cleanup;
+cur = tmp;
+
+for (i = start; i <= last; i++) {
+if (!firstnum)
+
+virBufferAddChar(&buf, ',');
+virBufferAsprintf(&buf, "%ld", i);
+firstnum = 0;
+}
+
+virSkipSpaces(&cur);
+}
+
+if (*cur == ',') {
+cur++;
+virSkipSpaces(&cur);
+

[libvirt] [PATCHv7 15/18] conf: Add 'id' to virDomainResctrlDef

2018-10-22 Thread Wang Huaqiang
Adding element 'id' to virDomainResctrlDef tracking resource group
id, it reflects the attribute 'id' of of element  in XML.

virResctrlAlloc.id is a copy from virDomanResctrlDef.id.

Signed-off-by: Wang Huaqiang 
---
 src/conf/domain_conf.c | 20 
 src/conf/domain_conf.h |  1 +
 2 files changed, 9 insertions(+), 12 deletions(-)

diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
index 01f795f..1aecd8c 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -2980,6 +2980,7 @@ virDomainResctrlDefFree(virDomainResctrlDefPtr resctrl)
 virObjectUnref(resctrl->alloc);
 virBitmapFree(resctrl->vcpus);
 VIR_FREE(resctrl->monitors);
+VIR_FREE(resctrl->id);
 VIR_FREE(resctrl);
 }
 
@@ -19145,6 +19146,9 @@ virDomainResctrlNew(xmlNodePtr node,
 if (VIR_ALLOC(resctrl) < 0)
 goto cleanup;
 
+if (VIR_STRDUP(resctrl->id, alloc_id) < 0)
+goto cleanup;
+
 if (!(resctrl->vcpus = virBitmapNewCopy(*vcpus))) {
 virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
_("failed to copy 'vcpus'"));
@@ -27323,13 +27327,9 @@ virDomainCachetuneDefFormat(virBufferPtr buf,
 
 virBufferAsprintf(buf, "alloc);
-if (!alloc_id)
-goto cleanup;
+if (!(flags & VIR_DOMAIN_DEF_FORMAT_INACTIVE))
+virBufferAsprintf(buf, " id='%s'", resctrl->id);
 
-virBufferAsprintf(buf, " id='%s'", alloc_id);
-}
 virBufferAddLit(buf, ">\n");
 
 virBufferAddBuffer(buf, &childrenBuf);
@@ -27386,13 +27386,9 @@ virDomainMemorytuneDefFormat(virBufferPtr buf,
 
 virBufferAsprintf(buf, "alloc);
-if (!alloc_id)
-goto cleanup;
+if (!(flags & VIR_DOMAIN_DEF_FORMAT_INACTIVE))
+virBufferAsprintf(buf, " id='%s'", resctrl->id);
 
-virBufferAsprintf(buf, " id='%s'", alloc_id);
-}
 virBufferAddLit(buf, ">\n");
 
 virBufferAddBuffer(buf, &childrenBuf);
diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h
index 60f6464..e190aa2 100644
--- a/src/conf/domain_conf.h
+++ b/src/conf/domain_conf.h
@@ -2248,6 +2248,7 @@ typedef struct _virDomainResctrlDef virDomainResctrlDef;
 typedef virDomainResctrlDef *virDomainResctrlDefPtr;
 
 struct _virDomainResctrlDef {
+char *id;
 virBitmapPtr vcpus;
 virResctrlAllocPtr alloc;
 
-- 
2.7.4

--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list


[libvirt] [PATCHv7 07/18] util: Refactor code for creating resctrl group

2018-10-22 Thread Wang Huaqiang
The code for creating resctrl allocation group could be reused
for monitoring group, refactor it for reuse in the later patch.

Signed-off-by: Wang Huaqiang 
---
 src/util/virresctrl.c | 37 +++--
 1 file changed, 23 insertions(+), 14 deletions(-)

diff --git a/src/util/virresctrl.c b/src/util/virresctrl.c
index 93b5e70..5b984d9 100644
--- a/src/util/virresctrl.c
+++ b/src/util/virresctrl.c
@@ -2315,6 +2315,26 @@ virResctrlAllocDeterminePath(virResctrlAllocPtr alloc,
 }
 
 
+/* This function creates a resctrl directory in resource control file system,
+ * and the directory path is specified by @path. */
+static int
+virResctrlCreateGroupPath(const char *path)
+{
+/* Directory exists, return */
+if (virFileExists(path))
+return 0;
+
+if (virFileMakePath(path) < 0) {
+virReportSystemError(errno,
+ _("Cannot create resctrl directory '%s'"),
+ path);
+return -1;
+}
+
+return 0;
+}
+
+
 /* This checks if the directory for the alloc exists.  If not it tries to 
create
  * it and apply appropriate alloc settings. */
 int
@@ -2344,13 +2364,6 @@ virResctrlAllocCreate(virResctrlInfoPtr resctrl,
 if (virResctrlAllocIsEmpty(alloc))
 return 0;
 
-if (virFileExists(alloc->path)) {
-virReportError(VIR_ERR_INTERNAL_ERROR,
-   _("Path '%s' for resctrl allocation exists"),
-   alloc->path);
-goto cleanup;
-}
-
 lockfd = virResctrlLockWrite();
 if (lockfd < 0)
 goto cleanup;
@@ -2358,6 +2371,9 @@ virResctrlAllocCreate(virResctrlInfoPtr resctrl,
 if (virResctrlAllocAssign(resctrl, alloc) < 0)
 goto cleanup;
 
+if (virResctrlCreateGroupPath(alloc->path) < 0)
+goto cleanup;
+
 alloc_str = virResctrlAllocFormat(alloc);
 if (!alloc_str)
 goto cleanup;
@@ -2365,13 +2381,6 @@ virResctrlAllocCreate(virResctrlInfoPtr resctrl,
 if (virAsprintf(&schemata_path, "%s/schemata", alloc->path) < 0)
 goto cleanup;
 
-if (virFileMakePath(alloc->path) < 0) {
-virReportSystemError(errno,
- _("Cannot create resctrl directory '%s'"),
- alloc->path);
-goto cleanup;
-}
-
 VIR_DEBUG("Writing resctrl schemata '%s' into '%s'", alloc_str, 
schemata_path);
 if (virFileWriteStr(schemata_path, alloc_str, 0) < 0) {
 rmdir(alloc->path);
-- 
2.7.4

--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list


[libvirt] [PATCHv7 03/18] util: Refactor code for determining allocation path

2018-10-22 Thread Wang Huaqiang
The code for determining resctrl allocation path could be reused
for monitor. Refactor it for reuse.

Signed-off-by: Wang Huaqiang 
---
 src/util/virresctrl.c | 38 ++
 1 file changed, 30 insertions(+), 8 deletions(-)

diff --git a/src/util/virresctrl.c b/src/util/virresctrl.c
index 6530801..956aca8 100644
--- a/src/util/virresctrl.c
+++ b/src/util/virresctrl.c
@@ -2265,28 +2265,50 @@ virResctrlAllocAssign(virResctrlInfoPtr resctrl,
 }
 
 
+static char *
+virResctrlDeterminePath(const char *parentpath,
+const char *prefix,
+const char *id)
+{
+char *path = NULL;
+
+if (!id) {
+virReportError(VIR_ERR_INTERNAL_ERROR,
+   _("Resctrl ID must be set before determining resctrl "
+ "parentpath='%s'"), parentpath);
+return NULL;
+}
+
+if (virAsprintf(&path, "%s/%s-%s", parentpath, prefix, id) < 0)
+return NULL;
+
+return path;
+}
+
+
 int
 virResctrlAllocDeterminePath(virResctrlAllocPtr alloc,
  const char *machinename)
 {
-if (!alloc->id) {
-virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
-   _("Resctrl Allocation ID must be set before creation"));
+if (alloc->path) {
+virReportError(VIR_ERR_INTERNAL_ERROR,
+   _("Resctrl allocation path is already set to '%s'"),
+   alloc->path);
 return -1;
 }
 
 /* If the allocation is empty, then the path will be SYSFS_RESCTRL_PATH */
 if (virResctrlAllocIsEmpty(alloc)) {
-if (!alloc->path &&
-VIR_STRDUP(alloc->path, SYSFS_RESCTRL_PATH) < 0)
+if (VIR_STRDUP(alloc->path, SYSFS_RESCTRL_PATH) < 0)
 return -1;
 
 return 0;
 }
 
-if (!alloc->path &&
-virAsprintf(&alloc->path, "%s/%s-%s",
-SYSFS_RESCTRL_PATH, machinename, alloc->id) < 0)
+alloc->path = virResctrlDeterminePath(SYSFS_RESCTRL_PATH,
+  machinename, alloc->id);
+
+if (!alloc->path)
 return -1;
 
 return 0;
-- 
2.7.4

--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list


Re: [libvirt] [PATCH] qemu: Restore lost shutdown reason

2018-10-22 Thread Nikolay Shirokovskiy



On 18.10.2018 18:28, John Ferlan wrote:
> When qemuProcessReconnectHelper was introduced (commit d38897a5d)
> reconnection failure used VIR_DOMAIN_SHUTOFF_FAILED; however, that
> was changed in commit bda2f17d to either VIR_DOMAIN_SHUTOFF_CRASHED
> or VIR_DOMAIN_SHUTOFF_UNKNOWN.
> 
> When QEMU_CAPS_NO_SHUTDOWN checking was removed in commit fe35b1ad6
> the conditional state was just left at VIR_DOMAIN_SHUTOFF_CRASHED.
> 
> Restore the logic adjustment using the same conditions as command
> line building and alter the comment to describe the reasoning.
> 
> Signed-off-by: John Ferlan 
> ---
> 
>  This was "discovered" while reviewing Nikolay's patch related
>  to adding "DAEMON" as the shutdown reason:
> 
> https://www.redhat.com/archives/libvir-list/2018-October/msg00493.html
> 
>  While working through the iterations of that - figured I'd at
>  least post this.
> 
> 
>  src/qemu/qemu_process.c | 15 ++-
>  1 file changed, 10 insertions(+), 5 deletions(-)
> 
> diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c
> index 3955eda17c..4a39111d51 100644
> --- a/src/qemu/qemu_process.c
> +++ b/src/qemu/qemu_process.c
> @@ -7985,11 +7985,16 @@ qemuProcessReconnect(void *opaque)
>  if (virDomainObjIsActive(obj)) {
>  /* We can't get the monitor back, so must kill the VM
>   * to remove danger of it ending up running twice if
> - * user tries to start it again later
> - * If we couldn't get the monitor since QEMU supports
> - * no-shutdown, we can safely say that the domain
> - * crashed ... */
> -state = VIR_DOMAIN_SHUTOFF_CRASHED;
> + * user tries to start it again later.
> + *
> + * If we cannot get to the monitor when the QEMU command
> + * line used -no-shutdown, then we can safely say that the
> + * domain crashed; otherwise we don't really know. */
> +if (priv->monJSON && priv->allowReboot == VIR_TRISTATE_BOOL_YES)
> +state = VIR_DOMAIN_SHUTOFF_CRASHED;
> +else
> +state = VIR_DOMAIN_SHUTOFF_UNKNOWN;
> +
>  /* If BeginJob failed, we jumped here without a job, let's hope 
> another
>   * thread didn't have a chance to start playing with the domain yet
>   * (it's all we can do anyway).
> 

This is reasonable but not complete. This is only applied to case when we do 
connect(2)
to qemu and it is failed with ECONNREFUSED which means qemu process does not 
exists
(in which case it is either crashed if was configured with -no-shutdown or 
terminated
for unknown reason) or just closed monitor connection (in this case we are going
to terminate it by ourselves).

But there are other cases. For example we can jump to error path even before 
connect(2)
or after successfull connect. See discussion of such cases in [1].

[1] https://www.redhat.com/archives/libvir-list/2018-October/msg01031.html

Nikolay

--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list


Re: [libvirt] [PATCH 1/4] nwfilter: add nwfilter hash

2018-10-22 Thread Nikolay Shirokovskiy



On 19.10.2018 18:33, Laine Stump wrote:
> On 10/18/18 2:49 AM, Nikolay Shirokovskiy wrote:
>> For filter without references to other filters hash is just sha-256 of 
>> filter's
>> xml. For filters with references hash is sha-256 of string consisting of
>> filter's self hash and hashes of directly referenced filters.
> 
> 
> I didn't read the entire patch, but if you're just comparing hashes of
> the filters' XML, then you aren't actually checking to see if *someone
> else* outside libvirt has modified the actual rules in ebtables/iptables
> (and someday not *too* far away nbtables, or maybe firewalld "rich
> rules"). That is the really important thing we need to check for. One of
> the reasons for a libvirtd restart to delete and reload all the rules is
> to clean up after some third party has "moved our cheese" and our filter
> rules no longer work as expected, and just checking that our own
> internal data is unchanged doesn't help that problem.

Agree. I mentioned the same issue in the cover letter. Need to rework
series)

> 
> 
> (BTW, on a slightly related topic - since I've lately been thinking
> about making libvirt work properly on systems with nbtables and in
> particular firewalld with an nbtables backend, I've been wondering if
> our whole model of "deleting old rules" based on our current idea of the
> libvirt xml ==> eb/iptables backend isn't improper. Maybe we should be
> saving the actual rules that we sent out in the status, and undoing
> those. The rules we need to delete could be *very* different from what
> the new libvirtd is generating (e.g. we decided we didn't need one of
> the rules anymore so it's no longer generated, or we're now using
> nbtables/ebpf/sub-etha-senso-tables or whatever).

The approach of not keeping firewall rules status is that libvirt keeps
all rules in 4 chains: libvirt-O-$IFACE, libvirt-I-$IFACE, libvirt-J-$IFACE,
libvirt-O-$IFACE (the last two are temporary) and their subchains. This
names are fixed so we can always cleanup all rules installed by libvirt.
Not sure of nbtables though - can we clean chains installed thru 
iptables/ebtables
thru nbtables.

Nikolay

> 
> 
>>
>> If filter is not complete that is some of filters it's referencing directly 
>> or
>> indirectly are missing the hash is set to NULL as well as if there was OOM on
>> hash caculation. So having NULL hash is regular situation.
>>
>> Signed-off-by: Nikolay Shirokovskiy 
>> ---
>>  src/conf/virnwfilterobj.c  | 145 
>> +
>>  src/conf/virnwfilterobj.h  |   9 ++
>>  src/libvirt_private.syms   |   3 +
>>  src/nwfilter/nwfilter_driver.c |   3 +
>>  src/nwfilter/nwfilter_gentech_driver.c |   2 +
>>  5 files changed, 162 insertions(+)
>>
>> diff --git a/src/conf/virnwfilterobj.c b/src/conf/virnwfilterobj.c
>> index 0136a0d..4cc81df 100644
>> --- a/src/conf/virnwfilterobj.c
>> +++ b/src/conf/virnwfilterobj.c
>> @@ -28,6 +28,7 @@
>>  #include "virlog.h"
>>  #include "virnwfilterobj.h"
>>  #include "virstring.h"
>> +#include "vircrypto.h"
>>  
>>  #define VIR_FROM_THIS VIR_FROM_NWFILTER
>>  
>> @@ -40,6 +41,8 @@ struct _virNWFilterObj {
>>  
>>  virNWFilterDefPtr def;
>>  virNWFilterDefPtr newDef;
>> +
>> +char *hash;
>>  };
>>  
>>  struct _virNWFilterObjList {
>> @@ -82,6 +85,13 @@ virNWFilterObjGetNewDef(virNWFilterObjPtr obj)
>>  }
>>  
>>  
>> +char*
>> +virNWFilterObjGetHash(virNWFilterObjPtr obj)
>> +{
>> +return obj->hash;
>> +}
>> +
>> +
>>  bool
>>  virNWFilterObjWantRemoved(virNWFilterObjPtr obj)
>>  {
>> @@ -307,6 +317,139 @@ virNWFilterDefEqual(const virNWFilterDef *def1,
>>  }
>>  
>>  
>> +static void
>> +virNWFilterObjInvalidateHash(virNWFilterObjListPtr nwfilters,
>> + virNWFilterObjPtr obj)
>> +{
>> +virNWFilterDefPtr def = obj->def;
>> +size_t i;
>> +
>> +if (!obj->hash)
>> +return;
>> +
>> +if (obj->newDef) {
>> +VIR_FREE(obj->hash);
>> +return;
>> +}
>> +
>> +for (i = 0; i < def->nentries; i++) {
>> +virNWFilterObjPtr child;
>> +char *filterref;
>> +
>> +if (def->filterEntries[i]->rule ||
>> +!def->filterEntries[i]->include)
>> +continue;
>> +
>> +filterref = def->filterEntries[i]->include->filterref;
>> +
>> +if (!(child = virNWFilterObjListFindByName(nwfilters, filterref))) {
>> +VIR_FREE(obj->hash);
>> +return;
>> +}
>> +
>> +virNWFilterObjInvalidateHash(nwfilters, child);
>> +
>> +if (!child->hash) {
>> +VIR_FREE(obj->hash);
>> +virNWFilterObjUnlock(child);
>> +return;
>> +}
>> +
>> +virNWFilterObjUnlock(child);
>> +}
>> +}
>> +
>> +
>> +void
>> +virNWFilterObjListInvalidateHash(virNWFilterObjListPtr nwfilters)
>> +{
>> +size_t i;
>> +virNWFilterObjPtr obj;
>> +
>> +for (i = 0; i < nwfilters->count; i++) {
>> +obj = nwfilters

[libvirt] [PATCHv6 14/18] util: Add function for checking if monitor is running

2018-10-22 Thread Wang Huaqiang
Check whether monitor is running by checking the monitor's PIDs status.

Monitor is looked as running normally if the vcpu PID list matches with
the content of monitor's 'tasks' file.

Signed-off-by: Wang Huaqiang 
---
 src/libvirt_private.syms |   1 +
 src/util/virresctrl.c| 102 ++-
 src/util/virresctrl.h|   3 ++
 3 files changed, 105 insertions(+), 1 deletion(-)

diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
index 239b979..cbc86ce 100644
--- a/src/libvirt_private.syms
+++ b/src/libvirt_private.syms
@@ -2684,6 +2684,7 @@ virResctrlMonitorAddPID;
 virResctrlMonitorCreate;
 virResctrlMonitorDeterminePath;
 virResctrlMonitorGetID;
+virResctrlMonitorIsRunning;
 virResctrlMonitorNew;
 virResctrlMonitorRemove;
 virResctrlMonitorSetAlloc;
diff --git a/src/util/virresctrl.c b/src/util/virresctrl.c
index b4b63b6..fa4c05e 100644
--- a/src/util/virresctrl.c
+++ b/src/util/virresctrl.c
@@ -359,6 +359,9 @@ struct _virResctrlMonitor {
 /* libvirt-generated path in /sys/fs/resctrl for this particular
  * monitor */
 char *path;
+/* Tracking the tasks' PID associated with this monitor */
+pid_t *pids;
+size_t npids;
 };
 
 
@@ -418,6 +421,7 @@ virResctrlMonitorDispose(void *obj)
 virObjectUnref(monitor->alloc);
 VIR_FREE(monitor->id);
 VIR_FREE(monitor->path);
+VIR_FREE(monitor->pids);
 }
 
 
@@ -2537,7 +2541,20 @@ int
 virResctrlMonitorAddPID(virResctrlMonitorPtr monitor,
 pid_t pid)
 {
-return virResctrlAddPID(monitor->path, pid);
+size_t i = 0;
+
+if (virResctrlAddPID(monitor->path, pid) < 0)
+return -1;
+
+for (i = 0; i < monitor->npids; i++) {
+if (pid == monitor->pids[i])
+return 0;
+}
+
+if (VIR_APPEND_ELEMENT(monitor->pids, monitor->npids, pid) < 0)
+return -1;
+
+return 0;
 }
 
 
@@ -2610,3 +2627,86 @@ virResctrlMonitorRemove(virResctrlMonitorPtr monitor)
 
 return ret;
 }
+
+
+static int
+virResctrlPIDSorter(const void *pida, const void *pidb)
+{
+return *(pid_t*)pida - *(pid_t*)pidb;
+}
+
+
+bool
+virResctrlMonitorIsRunning(virResctrlMonitorPtr monitor)
+{
+char *pidstr = NULL;
+char **spids = NULL;
+size_t nspids = 0;
+pid_t *pids = NULL;
+size_t npids = 0;
+size_t i = 0;
+int rv = -1;
+bool ret = false;
+
+/* path is not determined yet, monitor is not running*/
+if (!monitor->path)
+return false;
+
+/* No vcpu PID filled, regard monitor as not running */
+if (monitor->npids == 0)
+return false;
+
+/* If no 'tasks' file found, underlying resctrl directory is not
+ * ready, regard monitor as not running */
+rv = virFileReadValueString(&pidstr, "%s/tasks", monitor->path);
+if (rv < 0)
+goto cleanup;
+
+/* no PID in task file, monitor is not running */
+if (!*pidstr)
+goto cleanup;
+
+/* The tracking monitor PID list is not identical to the
+ * list in current resctrl directory. monitor is corrupted,
+ * report error and un-running state */
+spids = virStringSplitCount(pidstr, "\n", 0, &nspids);
+if (nspids != monitor->npids) {
+VIR_ERROR(_("Monitor %s PID list mismatch in length"), monitor->path);
+goto cleanup;
+}
+
+for (i = 0; i < nspids; i++) {
+unsigned int val = 0;
+pid_t pid = 0;
+
+if (virStrToLong_uip(spids[i], NULL, 0, &val) < 0) {
+virReportError(VIR_ERR_INTERNAL_ERROR,
+   _("Monitor %s failed in parse PID list"),
+   monitor->path);
+goto cleanup;
+}
+
+pid = (pid_t)val;
+
+if (VIR_APPEND_ELEMENT(pids, npids, pid) < 0)
+goto cleanup;
+}
+
+qsort(pids, npids, sizeof(pid_t), virResctrlPIDSorter);
+qsort(monitor->pids, monitor->npids, sizeof(pid_t), virResctrlPIDSorter);
+
+for (i = 0; i < monitor->npids; i++) {
+if (monitor->pids[i] != pids[i]) {
+VIR_ERROR(_("Monitor %s PID list corrupted"), monitor->path);
+goto cleanup;
+}
+}
+
+ret = true;
+ cleanup:
+virStringListFree(spids);
+VIR_FREE(pids);
+VIR_FREE(pidstr);
+
+return ret;
+}
diff --git a/src/util/virresctrl.h b/src/util/virresctrl.h
index 804d6f5..8d8fdc2 100644
--- a/src/util/virresctrl.h
+++ b/src/util/virresctrl.h
@@ -219,4 +219,7 @@ virResctrlMonitorSetAlloc(virResctrlMonitorPtr monitor,
 
 int
 virResctrlMonitorRemove(virResctrlMonitorPtr monitor);
+
+bool
+virResctrlMonitorIsRunning(virResctrlMonitorPtr monitor);
 #endif /*  __VIR_RESCTRL_H__ */
-- 
2.7.4

--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list


[libvirt] [PATCHv6 04/18] util: Add interface to determine monitor path

2018-10-22 Thread Wang Huaqiang
Add interface for resctrl monitor to determine the path.

Signed-off-by: Wang Huaqiang 
---
 src/libvirt_private.syms |  1 +
 src/util/virresctrl.c| 55 
 src/util/virresctrl.h|  5 -
 3 files changed, 60 insertions(+), 1 deletion(-)

diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
index 9577b70..19004bb 100644
--- a/src/libvirt_private.syms
+++ b/src/libvirt_private.syms
@@ -2680,6 +2680,7 @@ virResctrlInfoGetCache;
 virResctrlInfoGetMonitorPrefix;
 virResctrlInfoMonFree;
 virResctrlInfoNew;
+virResctrlMonitorDeterminePath;
 virResctrlMonitorNew;
 
 # util/virrotatingfile.h
diff --git a/src/util/virresctrl.c b/src/util/virresctrl.c
index 404b26c..794de87 100644
--- a/src/util/virresctrl.c
+++ b/src/util/virresctrl.c
@@ -2459,3 +2459,58 @@ virResctrlMonitorNew(void)
 
 return virObjectNew(virResctrlMonitorClass);
 }
+
+
+/*
+ * virResctrlMonitorDeterminePath
+ *
+ * @monitor: Pointer to a resctrl monitor
+ * @machinename: Name string of the VM
+ *
+ * Determines the directory path that the underlying resctrl group will be
+ * created with.
+ *
+ * A monitor represents a directory under resource control file system,
+ * its directory path could be the same path as @monitor->alloc, could be a
+ * path of directory under 'mon_groups' of @monitor->alloc, or a path of
+ * directory under '/sys/fs/resctrl/mon_groups' if @monitor->alloc is NULL.
+ *
+ * Returns 0 on success, -1 on error.
+ */
+int
+virResctrlMonitorDeterminePath(virResctrlMonitorPtr monitor,
+   const char *machinename)
+{
+VIR_AUTOFREE(char *) parentpath = NULL;
+
+if (!monitor) {
+virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+   _("Invalid resctrl monitor"));
+return -1;
+}
+
+if (monitor->path) {
+virReportError(VIR_ERR_INTERNAL_ERROR,
+   _("Resctrl monitor path is already set to '%s'"),
+   monitor->path);
+return -1;
+}
+
+if (monitor->id && monitor->alloc && monitor->alloc->id) {
+if (STREQ(monitor->id, monitor->alloc->id)) {
+if (VIR_STRDUP(monitor->path, monitor->alloc->path) < 0)
+return -1;
+return 0;
+}
+}
+
+if (virAsprintf(&parentpath, "%s/mon_groups", monitor->alloc->path) < 0)
+return -1;
+
+monitor->path = virResctrlDeterminePath(parentpath, machinename,
+monitor->id);
+if (!monitor->path)
+return -1;
+
+return 0;
+}
diff --git a/src/util/virresctrl.h b/src/util/virresctrl.h
index eaa077d..baae554 100644
--- a/src/util/virresctrl.h
+++ b/src/util/virresctrl.h
@@ -191,7 +191,10 @@ virResctrlInfoGetMonitorPrefix(virResctrlInfoPtr resctrl,
 typedef struct _virResctrlMonitor virResctrlMonitor;
 typedef virResctrlMonitor *virResctrlMonitorPtr;
 
-
 virResctrlMonitorPtr
 virResctrlMonitorNew(void);
+
+int
+virResctrlMonitorDeterminePath(virResctrlMonitorPtr monitor,
+   const char *machinename);
 #endif /*  __VIR_RESCTRL_H__ */
-- 
2.7.4

--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list


[libvirt] [PATCHv6 11/18] conf: move virResctrlAllocIsEmpty to a place a litter lower

2018-10-22 Thread Wang Huaqiang
This refactor allows to add some code between virDomainResctrlNew
and virResctrlAllocIsEmpty to extend the scope of resctrl.

Signed-off-by: Wang Huaqiang 
---
 src/conf/domain_conf.c | 8 
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
index 39bd396..a068d4d 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -19022,15 +19022,15 @@ virDomainCachetuneDefParse(virDomainDefPtr def,
 goto cleanup;
 }
 
+resctrl = virDomainResctrlNew(node, &alloc, &vcpus, flags);
+if (!resctrl)
+goto cleanup;
+
 if (virResctrlAllocIsEmpty(alloc)) {
 ret = 0;
 goto cleanup;
 }
 
-resctrl = virDomainResctrlNew(node, &alloc, &vcpus, flags);
-if (!resctrl)
-goto cleanup;
-
 if (VIR_APPEND_ELEMENT(def->resctrls, def->nresctrls, resctrl) < 0)
 goto cleanup;
 
-- 
2.7.4

--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list


[libvirt] [PATCHv6 16/18] qemu: refactor qemuDomainGetStatsCpu

2018-10-22 Thread Wang Huaqiang
Refactoring qemuDomainGetStatsCpu, make it possible to add
more CPU statistics.

Signed-off-by: Wang Huaqiang 
---
 src/qemu/qemu_driver.c | 45 ++---
 1 file changed, 22 insertions(+), 23 deletions(-)

diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index a52e249..12a5f8f 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -19711,30 +19711,29 @@ qemuDomainGetStatsCpu(virQEMUDriverPtr driver 
ATTRIBUTE_UNUSED,
 unsigned long long sys_time = 0;
 int err = 0;
 
-if (!priv->cgroup)
-return 0;
-
-err = virCgroupGetCpuacctUsage(priv->cgroup, &cpu_time);
-if (!err && virTypedParamsAddULLong(&record->params,
-&record->nparams,
-maxparams,
-"cpu.time",
-cpu_time) < 0)
-return -1;
+if (priv->cgroup) {
+err = virCgroupGetCpuacctUsage(priv->cgroup, &cpu_time);
+if (!err && virTypedParamsAddULLong(&record->params,
+&record->nparams,
+maxparams,
+"cpu.time",
+cpu_time) < 0)
+return -1;
 
-err = virCgroupGetCpuacctStat(priv->cgroup, &user_time, &sys_time);
-if (!err && virTypedParamsAddULLong(&record->params,
-&record->nparams,
-maxparams,
-"cpu.user",
-user_time) < 0)
-return -1;
-if (!err && virTypedParamsAddULLong(&record->params,
-&record->nparams,
-maxparams,
-"cpu.system",
-sys_time) < 0)
-return -1;
+err = virCgroupGetCpuacctStat(priv->cgroup, &user_time, &sys_time);
+if (!err && virTypedParamsAddULLong(&record->params,
+&record->nparams,
+maxparams,
+"cpu.user",
+user_time) < 0)
+return -1;
+if (!err && virTypedParamsAddULLong(&record->params,
+&record->nparams,
+maxparams,
+"cpu.system",
+sys_time) < 0)
+return -1;
+}
 
 return 0;
 }
-- 
2.7.4

--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list


[libvirt] [PATCHv6 13/18] qemu: enable resctrl monitor in qemu

2018-10-22 Thread Wang Huaqiang
Add functions for creating, destroying, reconnecting resctrl
monitor in qemu according to the configuration in domain XML.

Signed-off-by: Wang Huaqiang 
---
 src/qemu/qemu_process.c | 66 -
 1 file changed, 65 insertions(+), 1 deletion(-)

diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c
index e9c7618..fba4fb4 100644
--- a/src/qemu/qemu_process.c
+++ b/src/qemu/qemu_process.c
@@ -2611,10 +2611,21 @@ qemuProcessResctrlCreate(virQEMUDriverPtr driver,
 return -1;
 
 for (i = 0; i < vm->def->nresctrls; i++) {
+size_t j = 0;
 if (virResctrlAllocCreate(caps->host.resctrl,
   vm->def->resctrls[i]->alloc,
   priv->machineName) < 0)
 goto cleanup;
+
+for (j = 0; j < vm->def->resctrls[i]->nmonitors; j++) {
+virDomainResctrlMonDefPtr mon = NULL;
+
+mon = vm->def->resctrls[i]->monitors[j];
+if (virResctrlMonitorCreate(mon->instance,
+priv->machineName) < 0)
+goto cleanup;
+
+}
 }
 
 ret = 0;
@@ -5430,6 +5441,7 @@ qemuProcessSetupVcpu(virDomainObjPtr vm,
 {
 pid_t vcpupid = qemuDomainGetVcpuPid(vm, vcpuid);
 virDomainVcpuDefPtr vcpu = virDomainDefGetVcpu(vm->def, vcpuid);
+virDomainResctrlMonDefPtr mon = NULL;
 size_t i = 0;
 
 if (qemuProcessSetupPid(vm, vcpupid, VIR_CGROUP_THREAD_VCPU,
@@ -5440,11 +5452,42 @@ qemuProcessSetupVcpu(virDomainObjPtr vm,
 return -1;
 
 for (i = 0; i < vm->def->nresctrls; i++) {
+size_t j = 0;
 virDomainResctrlDefPtr ct = vm->def->resctrls[i];
 
 if (virBitmapIsBitSet(ct->vcpus, vcpuid)) {
 if (virResctrlAllocAddPID(ct->alloc, vcpupid) < 0)
 return -1;
+
+/* The order of invoking virResctrlMonitorAddPID matters, it is
+ * required to invoke this function first for monitor that has
+ * the same vcpus setting as the allocation in same def->resctrl.
+ * Otherwise, some other monitor's pid may be removed from its
+ * resource group's 'tasks' file.*/
+for (j = 0; j < vm->def->resctrls[i]->nmonitors; j++) {
+mon = vm->def->resctrls[i]->monitors[j];
+
+if (!virBitmapEqual(ct->vcpus, mon->vcpus))
+continue;
+
+if (virBitmapIsBitSet(mon->vcpus, vcpuid)) {
+if (virResctrlMonitorAddPID(mon->instance, vcpupid) < 0)
+return -1;
+}
+break;
+}
+
+for (j = 0; j < vm->def->resctrls[i]->nmonitors; j++) {
+mon = vm->def->resctrls[i]->monitors[j];
+
+if (virBitmapEqual(ct->vcpus, mon->vcpus))
+continue;
+
+if (virBitmapIsBitSet(mon->vcpus, vcpuid)) {
+if (virResctrlMonitorAddPID(mon->instance, vcpupid) < 0)
+return -1;
+}
+}
 break;
 }
 }
@@ -7207,8 +7250,18 @@ void qemuProcessStop(virQEMUDriverPtr driver,
 /* Remove resctrl allocation after cgroups are cleaned up which makes it
  * kind of safer (although removing the allocation should work even with
  * pids in tasks file */
-for (i = 0; i < vm->def->nresctrls; i++)
+for (i = 0; i < vm->def->nresctrls; i++) {
+size_t j = 0;
+
+for (j = 0; j < vm->def->resctrls[i]->nmonitors; j++) {
+virDomainResctrlMonDefPtr mon = NULL;
+
+mon = vm->def->resctrls[i]->monitors[j];
+virResctrlMonitorRemove(mon->instance);
+}
+
 virResctrlAllocRemove(vm->def->resctrls[i]->alloc);
+}
 
 qemuProcessRemoveDomainStatus(driver, vm);
 
@@ -7939,9 +7992,20 @@ qemuProcessReconnect(void *opaque)
 goto error;
 
 for (i = 0; i < obj->def->nresctrls; i++) {
+size_t j = 0;
+
 if (virResctrlAllocDeterminePath(obj->def->resctrls[i]->alloc,
  priv->machineName) < 0)
 goto error;
+
+for (j = 0; j < obj->def->resctrls[i]->nmonitors; j++) {
+virDomainResctrlMonDefPtr mon = NULL;
+
+mon = obj->def->resctrls[i]->monitors[j];
+if (virResctrlMonitorDeterminePath(mon->instance,
+   priv->machineName) < 0)
+goto error;
+}
 }
 
 /* update domain state XML with possibly updated state in virDomainObj */
-- 
2.7.4

--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list


[libvirt] [PATCHv6 03/18] util: Refactor code for determining allocation path

2018-10-22 Thread Wang Huaqiang
The code for determining resctrl allocation path could be reused
for monitor. Refactor it for reuse.

Signed-off-by: Wang Huaqiang 
---
 src/util/virresctrl.c | 38 ++
 1 file changed, 30 insertions(+), 8 deletions(-)

diff --git a/src/util/virresctrl.c b/src/util/virresctrl.c
index 578a52c..404b26c 100644
--- a/src/util/virresctrl.c
+++ b/src/util/virresctrl.c
@@ -2265,28 +2265,50 @@ virResctrlAllocAssign(virResctrlInfoPtr resctrl,
 }
 
 
+static char *
+virResctrlDeterminePath(const char *parentpath,
+const char *prefix,
+const char *id)
+{
+char *path = NULL;
+
+if (!id) {
+virReportError(VIR_ERR_INTERNAL_ERROR,
+   _("Resctrl ID must be set before determining resctrl "
+ "parentpath='%s'"), parentpath);
+return NULL;
+}
+
+if (virAsprintf(&path, "%s/%s-%s", parentpath, prefix, id) < 0)
+return NULL;
+
+return path;
+}
+
+
 int
 virResctrlAllocDeterminePath(virResctrlAllocPtr alloc,
  const char *machinename)
 {
-if (!alloc->id) {
-virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
-   _("Resctrl Allocation ID must be set before creation"));
+if (alloc->path) {
+virReportError(VIR_ERR_INTERNAL_ERROR,
+   _("Resctrl allocation path is already set to '%s'"),
+   alloc->path);
 return -1;
 }
 
 /* If the allocation is empty, then the path will be SYSFS_RESCTRL_PATH */
 if (virResctrlAllocIsEmpty(alloc)) {
-if (!alloc->path &&
-VIR_STRDUP(alloc->path, SYSFS_RESCTRL_PATH) < 0)
+if (VIR_STRDUP(alloc->path, SYSFS_RESCTRL_PATH) < 0)
 return -1;
 
 return 0;
 }
 
-if (!alloc->path &&
-virAsprintf(&alloc->path, "%s/%s-%s",
-SYSFS_RESCTRL_PATH, machinename, alloc->id) < 0)
+alloc->path = virResctrlDeterminePath(SYSFS_RESCTRL_PATH,
+  machinename, alloc->id);
+
+if (!alloc->path)
 return -1;
 
 return 0;
-- 
2.7.4

--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list


[libvirt] [PATCHv6 10/18] conf: Remove virDomainResctrlAppend and introduce virDomainResctrlNew

2018-10-22 Thread Wang Huaqiang
Introduced virDomainResctrlNew to do the most part of virDomainResctrlAppend
and move the operation of appending resctrl to @def->resctrls out of
function.

Rather than rely on virDomainResctrlAppend to perform the allocation, move
the onus to the caller and make use of virBitmapNewCopy for @vcpus and
virObjectRef for @alloc, thus removing the need to set each to NULL after the
call.

Signed-off-by: Wang Huaqiang 
---
 src/conf/domain_conf.c | 60 +-
 1 file changed, 35 insertions(+), 25 deletions(-)

diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
index e8e0adc..39bd396 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -18920,26 +18920,22 @@ virDomainCachetuneDefParseCache(xmlXPathContextPtr 
ctxt,
 }
 
 
-static int
-virDomainResctrlAppend(virDomainDefPtr def,
-   xmlNodePtr node,
-   virResctrlAllocPtr alloc,
-   virBitmapPtr vcpus,
-   unsigned int flags)
+static virDomainResctrlDefPtr
+virDomainResctrlNew(xmlNodePtr node,
+virResctrlAllocPtr *alloc,
+virBitmapPtr *vcpus,
+unsigned int flags)
 {
 char *vcpus_str = NULL;
 char *alloc_id = NULL;
-virDomainResctrlDefPtr tmp_resctrl = NULL;
-int ret = -1;
-
-if (VIR_ALLOC(tmp_resctrl) < 0)
-goto cleanup;
+virDomainResctrlDefPtr resctrl = NULL;
+virDomainResctrlDefPtr ret = NULL;
 
 /* We need to format it back because we need to be consistent in the naming
  * even when users specify some "sub-optimal" string there. */
-vcpus_str = virBitmapFormat(vcpus);
+vcpus_str = virBitmapFormat(*vcpus);
 if (!vcpus_str)
-goto cleanup;
+return NULL;
 
 if (!(flags & VIR_DOMAIN_DEF_PARSE_INACTIVE))
 alloc_id = virXMLPropString(node, "id");
@@ -18954,18 +18950,23 @@ virDomainResctrlAppend(virDomainDefPtr def,
 goto cleanup;
 }
 
-if (virResctrlAllocSetID(alloc, alloc_id) < 0)
+if (virResctrlAllocSetID(*alloc, alloc_id) < 0)
 goto cleanup;
 
-tmp_resctrl->vcpus = vcpus;
-tmp_resctrl->alloc = alloc;
+if (VIR_ALLOC(resctrl) < 0)
+goto cleanup;
 
-if (VIR_APPEND_ELEMENT(def->resctrls, def->nresctrls, tmp_resctrl) < 0)
+if (!(resctrl->vcpus = virBitmapNewCopy(*vcpus))) {
+virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+   _("failed to copy 'vcpus'"));
 goto cleanup;
+}
 
-ret = 0;
+resctrl->alloc = virObjectRef(*alloc);
+
+VIR_STEAL_PTR(ret, resctrl);
  cleanup:
-virDomainResctrlDefFree(tmp_resctrl);
+virDomainResctrlDefFree(resctrl);
 VIR_FREE(alloc_id);
 VIR_FREE(vcpus_str);
 return ret;
@@ -18982,6 +18983,7 @@ virDomainCachetuneDefParse(virDomainDefPtr def,
 xmlNodePtr *nodes = NULL;
 virBitmapPtr vcpus = NULL;
 virResctrlAllocPtr alloc = NULL;
+virDomainResctrlDefPtr resctrl = NULL;
 ssize_t i = 0;
 int n;
 int ret = -1;
@@ -19025,14 +19027,17 @@ virDomainCachetuneDefParse(virDomainDefPtr def,
 goto cleanup;
 }
 
-if (virDomainResctrlAppend(def, node, alloc, vcpus, flags) < 0)
+resctrl = virDomainResctrlNew(node, &alloc, &vcpus, flags);
+if (!resctrl)
+goto cleanup;
+
+if (VIR_APPEND_ELEMENT(def->resctrls, def->nresctrls, resctrl) < 0)
 goto cleanup;
-vcpus = NULL;
-alloc = NULL;
 
 ret = 0;
  cleanup:
 ctxt->node = oldnode;
+virDomainResctrlDefFree(resctrl);
 virObjectUnref(alloc);
 virBitmapFree(vcpus);
 VIR_FREE(nodes);
@@ -19190,6 +19195,8 @@ virDomainMemorytuneDefParse(virDomainDefPtr def,
 xmlNodePtr *nodes = NULL;
 virBitmapPtr vcpus = NULL;
 virResctrlAllocPtr alloc = NULL;
+virDomainResctrlDefPtr resctrl = NULL;
+
 ssize_t i = 0;
 int n;
 int ret = -1;
@@ -19234,15 +19241,18 @@ virDomainMemorytuneDefParse(virDomainDefPtr def,
  * just update the existing alloc information, which is done in above
  * virDomainMemorytuneDefParseMemory */
 if (new_alloc) {
-if (virDomainResctrlAppend(def, node, alloc, vcpus, flags) < 0)
+resctrl = virDomainResctrlNew(node, &alloc, &vcpus, flags);
+if (!resctrl)
+goto cleanup;
+
+if (VIR_APPEND_ELEMENT(def->resctrls, def->nresctrls, resctrl) < 0)
 goto cleanup;
-vcpus = NULL;
-alloc = NULL;
 }
 
 ret = 0;
  cleanup:
 ctxt->node = oldnode;
+virDomainResctrlDefFree(resctrl);
 virObjectUnref(alloc);
 virBitmapFree(vcpus);
 VIR_FREE(nodes);
-- 
2.7.4

--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list


[libvirt] [PATCHv6 07/18] util: Refactor code for creating resctrl group

2018-10-22 Thread Wang Huaqiang
The code for creating resctrl allocation group could be reused
for monitoring group, refactor it for reuse in the later patch.

Signed-off-by: Wang Huaqiang 
---
 src/util/virresctrl.c | 37 +++--
 1 file changed, 23 insertions(+), 14 deletions(-)

diff --git a/src/util/virresctrl.c b/src/util/virresctrl.c
index 4489ef9..cffacd3 100644
--- a/src/util/virresctrl.c
+++ b/src/util/virresctrl.c
@@ -2315,6 +2315,26 @@ virResctrlAllocDeterminePath(virResctrlAllocPtr alloc,
 }
 
 
+/* This function creates a resctrl directory in resource control file system,
+ * and the directory path is specified by @path. */
+static int
+virResctrlCreateGroupPath(const char *path)
+{
+/* Directory exists, return */
+if (virFileExists(path))
+return 0;
+
+if (virFileMakePath(path) < 0) {
+virReportSystemError(errno,
+ _("Cannot create resctrl directory '%s'"),
+ path);
+return -1;
+}
+
+return 0;
+}
+
+
 /* This checks if the directory for the alloc exists.  If not it tries to 
create
  * it and apply appropriate alloc settings. */
 int
@@ -2341,13 +2361,6 @@ virResctrlAllocCreate(virResctrlInfoPtr resctrl,
 if (virResctrlAllocIsEmpty(alloc))
 return 0;
 
-if (virFileExists(alloc->path)) {
-virReportError(VIR_ERR_INTERNAL_ERROR,
-   _("Path '%s' for resctrl allocation exists"),
-   alloc->path);
-goto cleanup;
-}
-
 lockfd = virResctrlLockWrite();
 if (lockfd < 0)
 goto cleanup;
@@ -2355,6 +2368,9 @@ virResctrlAllocCreate(virResctrlInfoPtr resctrl,
 if (virResctrlAllocAssign(resctrl, alloc) < 0)
 goto cleanup;
 
+if (virResctrlCreateGroupPath(alloc->path) < 0)
+goto cleanup;
+
 alloc_str = virResctrlAllocFormat(alloc);
 if (!alloc_str)
 goto cleanup;
@@ -2362,13 +2378,6 @@ virResctrlAllocCreate(virResctrlInfoPtr resctrl,
 if (virAsprintf(&schemata_path, "%s/schemata", alloc->path) < 0)
 goto cleanup;
 
-if (virFileMakePath(alloc->path) < 0) {
-virReportSystemError(errno,
- _("Cannot create resctrl directory '%s'"),
- alloc->path);
-goto cleanup;
-}
-
 VIR_DEBUG("Writing resctrl schemata '%s' into '%s'", alloc_str, 
schemata_path);
 if (virFileWriteStr(schemata_path, alloc_str, 0) < 0) {
 rmdir(alloc->path);
-- 
2.7.4

--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list


[libvirt] [PATCHv6 08/18] util: Add interface for creating monitor group

2018-10-22 Thread Wang Huaqiang
Add interface for creating the resource monitoring group according
to '@virResctrlMonitor->path'.

Signed-off-by: Wang Huaqiang 
---
 src/libvirt_private.syms |  1 +
 src/util/virresctrl.c| 24 
 src/util/virresctrl.h|  4 
 3 files changed, 29 insertions(+)

diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
index 01cd155..b47b60d 100644
--- a/src/libvirt_private.syms
+++ b/src/libvirt_private.syms
@@ -2681,6 +2681,7 @@ virResctrlInfoGetMonitorPrefix;
 virResctrlInfoMonFree;
 virResctrlInfoNew;
 virResctrlMonitorAddPID;
+virResctrlMonitorCreate;
 virResctrlMonitorDeterminePath;
 virResctrlMonitorNew;
 
diff --git a/src/util/virresctrl.c b/src/util/virresctrl.c
index cffacd3..e97127c 100644
--- a/src/util/virresctrl.c
+++ b/src/util/virresctrl.c
@@ -2539,3 +2539,27 @@ virResctrlMonitorAddPID(virResctrlMonitorPtr monitor,
 {
 return virResctrlAddPID(monitor->path, pid);
 }
+
+
+int
+virResctrlMonitorCreate(virResctrlMonitorPtr monitor,
+const char *machinename)
+{
+int lockfd = -1;
+int ret = -1;
+
+if (!monitor)
+return 0;
+
+if (virResctrlMonitorDeterminePath(monitor, machinename) < 0)
+return -1;
+
+lockfd = virResctrlLockWrite();
+if (lockfd < 0)
+return -1;
+
+ret = virResctrlCreateGroupPath(monitor->path);
+
+virResctrlUnlock(lockfd);
+return ret;
+}
diff --git a/src/util/virresctrl.h b/src/util/virresctrl.h
index 52d283a..76e40a2 100644
--- a/src/util/virresctrl.h
+++ b/src/util/virresctrl.h
@@ -201,4 +201,8 @@ virResctrlMonitorDeterminePath(virResctrlMonitorPtr monitor,
 int
 virResctrlMonitorAddPID(virResctrlMonitorPtr monitor,
 pid_t pid);
+
+int
+virResctrlMonitorCreate(virResctrlMonitorPtr monitor,
+const char *machinename);
 #endif /*  __VIR_RESCTRL_H__ */
-- 
2.7.4

--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list


[libvirt] [PATCHv6 09/18] util: Add more interfaces for resctrl monitor

2018-10-22 Thread Wang Huaqiang
Add interfaces monitor group to support operations such
as add PID, set ID, remove group ... etc.

Signed-off-by: Wang Huaqiang 
---
 src/libvirt_private.syms |  5 +
 src/util/virresctrl.c| 47 +++
 src/util/virresctrl.h| 14 ++
 3 files changed, 66 insertions(+)

diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
index b47b60d..239b979 100644
--- a/src/libvirt_private.syms
+++ b/src/libvirt_private.syms
@@ -2683,7 +2683,12 @@ virResctrlInfoNew;
 virResctrlMonitorAddPID;
 virResctrlMonitorCreate;
 virResctrlMonitorDeterminePath;
+virResctrlMonitorGetID;
 virResctrlMonitorNew;
+virResctrlMonitorRemove;
+virResctrlMonitorSetAlloc;
+virResctrlMonitorSetID;
+
 
 # util/virrotatingfile.h
 virRotatingFileReaderConsume;
diff --git a/src/util/virresctrl.c b/src/util/virresctrl.c
index e97127c..b4b63b6 100644
--- a/src/util/virresctrl.c
+++ b/src/util/virresctrl.c
@@ -2563,3 +2563,50 @@ virResctrlMonitorCreate(virResctrlMonitorPtr monitor,
 virResctrlUnlock(lockfd);
 return ret;
 }
+
+
+int
+virResctrlMonitorSetID(virResctrlMonitorPtr monitor,
+   const char *id)
+{
+if (!id) {
+virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+   _("Resctrl monitor 'id' cannot be NULL"));
+return -1;
+}
+
+return VIR_STRDUP(monitor->id, id);
+}
+
+
+const char *
+virResctrlMonitorGetID(virResctrlMonitorPtr monitor)
+{
+return monitor->id;
+}
+
+
+void
+virResctrlMonitorSetAlloc(virResctrlMonitorPtr monitor,
+  virResctrlAllocPtr alloc)
+{
+monitor->alloc = virObjectRef(alloc);
+}
+
+
+int
+virResctrlMonitorRemove(virResctrlMonitorPtr monitor)
+{
+int ret = 0;
+
+if (!monitor->path)
+return 0;
+
+VIR_DEBUG("Removing resctrl monitor%s", monitor->path);
+if (rmdir(monitor->path) != 0 && errno != ENOENT) {
+ret = -errno;
+VIR_ERROR(_("Unable to remove %s (%d)"), monitor->path, errno);
+}
+
+return ret;
+}
diff --git a/src/util/virresctrl.h b/src/util/virresctrl.h
index 76e40a2..804d6f5 100644
--- a/src/util/virresctrl.h
+++ b/src/util/virresctrl.h
@@ -205,4 +205,18 @@ virResctrlMonitorAddPID(virResctrlMonitorPtr monitor,
 int
 virResctrlMonitorCreate(virResctrlMonitorPtr monitor,
 const char *machinename);
+
+int
+virResctrlMonitorSetID(virResctrlMonitorPtr monitor,
+   const char *id);
+
+const char *
+virResctrlMonitorGetID(virResctrlMonitorPtr monitor);
+
+void
+virResctrlMonitorSetAlloc(virResctrlMonitorPtr monitor,
+  virResctrlAllocPtr alloc);
+
+int
+virResctrlMonitorRemove(virResctrlMonitorPtr monitor);
 #endif /*  __VIR_RESCTRL_H__ */
-- 
2.7.4

--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list


[libvirt] [PATCHv6 00/18] Introduce x86 Cache Monitoring Technology (CMT)

2018-10-22 Thread Wang Huaqiang
This series of patches and the series already been merged introduce
the x86 Cache Monitoring Technology (CMT) to libvirt by interacting
with kernel resource control (resctrl) interface. CMT is one of the
Intel(R) x86 CPU feature which belongs to the Resource Director
Technology (RDT). CMT reports the occupancy of the last level cache,
which is shared by all CPU cores.

In the v1 series, an original and complete feature for CMT was introduced
The v2 and v3 patches address the feature for the host capability of CMT.
v4 is addressing the feature for monitoring VM vcpu thread set cache
occupancy and reporting it through a virsh command.

We have serval discussion about the enabling of CMT, please refer to
following links for the RFCs.
RFCv3
https://www.redhat.com/archives/libvir-list/2018-August/msg01213.html
RFCv2
https://www.redhat.com/archives/libvir-list/2018-July/msg00409.html
https://www.redhat.com/archives/libvir-list/2018-July/msg01241.html
RFCv1
https://www.redhat.com/archives/libvir-list/2018-June/msg00674.html

And the merged commits are list as below, for host capability of CMT.
6af8417415508c31f8ce71234b573b4999f35980
8f6887998bf63594ae26e3db18d4d5896c5f2cb4
58fcee6f3a2b7e89c21c1fb4ec21429c31a0c5b8
12093f1feaf8f5023dcd9d65dff111022842183d
a5d293c18831dcf69ec6195798387fbb70c9f461


1. About reason why CMT is necessary in libvirt?
The perf events of 'CMT, MBML, MBMT' have been phased out since Linux
kernel commit c39a0e2c8850f08249383f2425dbd8dbe4baad69, in libvirt
the perf based cmt,mbm will not work with the latest linux kernel. These
patches add CMT feature to libvirt through kernel resctrlfs interface.

2 Create cache monitoring group (cache monitor).

The main interface for creating monitoring group is through XML file. The
proposed configuration is like:

  

  
  
+ 


+ 

  

In above XML, created 2 cache resctrl allocation groups and 2 resctrl
monitoring groups.
The changes of cache monitor will be effective in next booting of VM.

2 Show CMT result through command 'domstats'

Adding the interface in qemu to report this information for resource
monitor group through command 'virsh domstats --cpu-total'.
Below is a typical output:

 # virsh domstats 1 --cpu-total
 Domain: 'ubuntu16.04-base'
 ...
   cpu.cache.monitor.count=2
   cpu.cache.monitor.0.name=vcpus_1
   cpu.cache.monitor.0.vcpus=1
   cpu.cache.monitor.0.bank.count=2
   cpu.cache.monitor.0.bank.0.id=0
   cpu.cache.monitor.0.bank.0.bytes=4505600
   cpu.cache.monitor.0.bank.1.id=1
   cpu.cache.monitor.0.bank.1.bytes=5586944
   cpu.cache.monitor.1.name=vcpus_4-6
   cpu.cache.monitor.1.vcpus=4,5,6
   cpu.cache.monitor.1.bank.count=2
   cpu.cache.monitor.1.bank.0.id=0
   cpu.cache.monitor.1.bank.0.bytes=17571840
   cpu.cache.monitor.1.bank.1.id=1
   cpu.cache.monitor.1.bank.1.bytes=29106176

Changes in v6:
- Addressing John's review comments for v5.
- Removed and cleaned the concepts of 'default allocation' and
'default monitor'.
- qemu: virsh domstats --cpu-total output for CMT, add identifier
'monitor' for each itm.

Changes in v5:
- qemu: Setting up vcpu and adding pids to resctrl monitor groups during
re-connection.
- Add the document for domain configuration related to resctrl monitor.

Changes in v4:
v4 is addressing the feature for monitoring VM vcpu
thread set cache occupancy and reporting it through a
virsh command.
- Introduced resctrl default allocation
- Introduced resctrl monitor and default monitor

Changes in v3:
- Addressed John Ferlan's review.
- Typo fixed.
- Removed VIR_ENUM_DECL(virMonitor);

Changes in v2:
- Introduced MBM capability.
- Capability layout changed
* Moved  from cahe  to 
* Renamed  to 
- Document for 'reuseThreshold' changed.
- Introduced API virResctrlInfoGetMonitorPrefix
- Added more tests, covering standalone CMT, fake new
  feature.
- Creating CMT resource control group will be
  subsequent job.



Wang Huaqiang (18):
  docs,util: Refactor schemas and virresctrl to support optional cache
  util: Introduce resctrl monitor for CMT
  util: Refactor code for determining allocation path
  util: Add interface to determine monitor path
  util: Refactor code for adding PID to the resource group
  util: Add interface for adding PID to the monitor
  util: Refactor code for creating resctrl group
  util: Add interface for creating monitor group
  util: Add more interfaces for resctrl monitor
  conf: Remove virDomainResctrlAppend and introduce virDomainResctrlNew
  conf: move virResctrlAllocIsEmpty to a place a litter lower
  conf: Introduce cache monitor element in cachetune
  qemu: enable resctrl monitor in qemu
  util: Add function for checking if monitor is running
  conf: Add 'id' to virDomainResctrlDef
  qemu: refactor qemuDomainGetStatsCpu
  qemu: Report cache occupancy (CMT) with domstats
  qemu: Setting up vcpu and adding pids to resctrl monitor gro

[libvirt] [PATCHv6 06/18] util: Add interface for adding PID to the monitor

2018-10-22 Thread Wang Huaqiang
Add interface for adding task PID to the monitor.

Signed-off-by: Wang Huaqiang 
---
 src/libvirt_private.syms | 1 +
 src/util/virresctrl.c| 8 
 src/util/virresctrl.h| 4 
 3 files changed, 13 insertions(+)

diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
index 19004bb..01cd155 100644
--- a/src/libvirt_private.syms
+++ b/src/libvirt_private.syms
@@ -2680,6 +2680,7 @@ virResctrlInfoGetCache;
 virResctrlInfoGetMonitorPrefix;
 virResctrlInfoMonFree;
 virResctrlInfoNew;
+virResctrlMonitorAddPID;
 virResctrlMonitorDeterminePath;
 virResctrlMonitorNew;
 
diff --git a/src/util/virresctrl.c b/src/util/virresctrl.c
index 014c2fc..4489ef9 100644
--- a/src/util/virresctrl.c
+++ b/src/util/virresctrl.c
@@ -2522,3 +2522,11 @@ virResctrlMonitorDeterminePath(virResctrlMonitorPtr 
monitor,
 
 return 0;
 }
+
+
+int
+virResctrlMonitorAddPID(virResctrlMonitorPtr monitor,
+pid_t pid)
+{
+return virResctrlAddPID(monitor->path, pid);
+}
diff --git a/src/util/virresctrl.h b/src/util/virresctrl.h
index baae554..52d283a 100644
--- a/src/util/virresctrl.h
+++ b/src/util/virresctrl.h
@@ -197,4 +197,8 @@ virResctrlMonitorNew(void);
 int
 virResctrlMonitorDeterminePath(virResctrlMonitorPtr monitor,
const char *machinename);
+
+int
+virResctrlMonitorAddPID(virResctrlMonitorPtr monitor,
+pid_t pid);
 #endif /*  __VIR_RESCTRL_H__ */
-- 
2.7.4

--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list


[libvirt] [PATCHv6 15/18] conf: Add 'id' to virDomainResctrlDef

2018-10-22 Thread Wang Huaqiang
Adding element 'id' to virDomainResctrlDef tracking resource group
id, it reflects the attribute 'id' of of element  in XML.

virResctrlAlloc.id is a copy from virDomanResctrlDef.id.

Signed-off-by: Wang Huaqiang 
---
 src/conf/domain_conf.c | 20 
 src/conf/domain_conf.h |  1 +
 2 files changed, 9 insertions(+), 12 deletions(-)

diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
index 01f795f..1aecd8c 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -2980,6 +2980,7 @@ virDomainResctrlDefFree(virDomainResctrlDefPtr resctrl)
 virObjectUnref(resctrl->alloc);
 virBitmapFree(resctrl->vcpus);
 VIR_FREE(resctrl->monitors);
+VIR_FREE(resctrl->id);
 VIR_FREE(resctrl);
 }
 
@@ -19145,6 +19146,9 @@ virDomainResctrlNew(xmlNodePtr node,
 if (VIR_ALLOC(resctrl) < 0)
 goto cleanup;
 
+if (VIR_STRDUP(resctrl->id, alloc_id) < 0)
+goto cleanup;
+
 if (!(resctrl->vcpus = virBitmapNewCopy(*vcpus))) {
 virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
_("failed to copy 'vcpus'"));
@@ -27323,13 +27327,9 @@ virDomainCachetuneDefFormat(virBufferPtr buf,
 
 virBufferAsprintf(buf, "alloc);
-if (!alloc_id)
-goto cleanup;
+if (!(flags & VIR_DOMAIN_DEF_FORMAT_INACTIVE))
+virBufferAsprintf(buf, " id='%s'", resctrl->id);
 
-virBufferAsprintf(buf, " id='%s'", alloc_id);
-}
 virBufferAddLit(buf, ">\n");
 
 virBufferAddBuffer(buf, &childrenBuf);
@@ -27386,13 +27386,9 @@ virDomainMemorytuneDefFormat(virBufferPtr buf,
 
 virBufferAsprintf(buf, "alloc);
-if (!alloc_id)
-goto cleanup;
+if (!(flags & VIR_DOMAIN_DEF_FORMAT_INACTIVE))
+virBufferAsprintf(buf, " id='%s'", resctrl->id);
 
-virBufferAsprintf(buf, " id='%s'", alloc_id);
-}
 virBufferAddLit(buf, ">\n");
 
 virBufferAddBuffer(buf, &childrenBuf);
diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h
index 60f6464..e190aa2 100644
--- a/src/conf/domain_conf.h
+++ b/src/conf/domain_conf.h
@@ -2248,6 +2248,7 @@ typedef struct _virDomainResctrlDef virDomainResctrlDef;
 typedef virDomainResctrlDef *virDomainResctrlDefPtr;
 
 struct _virDomainResctrlDef {
+char *id;
 virBitmapPtr vcpus;
 virResctrlAllocPtr alloc;
 
-- 
2.7.4

--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list


[libvirt] [PATCHv6 18/18] qemu: Setting up vcpu and adding pids to resctrl monitor groups during reconnection

2018-10-22 Thread Wang Huaqiang
Invoking qemuProcessSetupVcpus in process of VM reconnection.

The vcpu pid information need to be refilled to resctrl monitor
after a VM reconnection./

Signed-off-by: Wang Huaqiang 
---
 src/qemu/qemu_process.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c
index fba4fb4..ed0330b 100644
--- a/src/qemu/qemu_process.c
+++ b/src/qemu/qemu_process.c
@@ -8008,6 +8008,9 @@ qemuProcessReconnect(void *opaque)
 }
 }
 
+if (qemuProcessSetupVcpus(obj) < 0)
+goto error;
+
 /* update domain state XML with possibly updated state in virDomainObj */
 if (virDomainSaveStatus(driver->xmlopt, cfg->stateDir, obj, driver->caps) 
< 0)
 goto error;
-- 
2.7.4

--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list


[libvirt] [PATCHv6 17/18] qemu: Report cache occupancy (CMT) with domstats

2018-10-22 Thread Wang Huaqiang
Adding the interface in qemu to report CMT statistic information
through command 'virsh domstats --cpu-total'.

Below is a typical output:

 # virsh domstats 1 --cpu-total
 Domain: 'ubuntu16.04-base'
   ...
   cpu.cache.monitor.count=2
   cpu.cache.monitor.0.name=vcpus_1
   cpu.cache.monitor.0.vcpus=1
   cpu.cache.monitor.0.bank.count=2
   cpu.cache.monitor.0.bank.0.id=0
   cpu.cache.monitor.0.bank.0.bytes=4505600
   cpu.cache.monitor.0.bank.1.id=1
   cpu.cache.monitor.0.bank.1.bytes=5586944
   cpu.cache.monitor.1.name=vcpus_4-6
   cpu.cache.monitor.1.vcpus=4,5,6
   cpu.cache.monitor.1.bank.count=2
   cpu.cache.monitor.1.bank.0.id=0
   cpu.cache.monitor.1.bank.0.bytes=17571840
   cpu.cache.monitor.1.bank.1.id=1
   cpu.cache.monitor.1.bank.1.bytes=29106176

Signed-off-by: Wang Huaqiang 
---
 src/libvirt-domain.c |   9 ++
 src/libvirt_private.syms |   1 +
 src/qemu/qemu_driver.c   | 229 +++
 src/util/virresctrl.c| 130 +++
 src/util/virresctrl.h|  12 +++
 5 files changed, 381 insertions(+)

diff --git a/src/libvirt-domain.c b/src/libvirt-domain.c
index 7690339..4895f9f 100644
--- a/src/libvirt-domain.c
+++ b/src/libvirt-domain.c
@@ -11345,6 +11345,15 @@ virConnectGetDomainCapabilities(virConnectPtr conn,
  * "cpu.user" - user cpu time spent in nanoseconds as unsigned long long.
  * "cpu.system" - system cpu time spent in nanoseconds as unsigned long
  *long.
+ * "cpu.cache.monitor.count" - tocal cache monitoring groups
+ * "cpu.cache.monitor.M.name" - name of cache monitoring group 'M'
+ * "cpu.cache.monitor.M.vcpus" - vcpus for cache monitoring group 'M'
+ * "cpu.cache.monitor.M.bank.count" - total bank number of cache monitoring
+ *group 'M'
+ * "cpu.cache.monitor.M.bank.N.id" - OS assigned cache bank id for cache
+ *'N' in cache monitoring group 'M'
+ * "cpu.cache.monitor.M.bank.N.bytes" - monitor's cache occupancy of cache
+ *bank 'N' in cache monitoring group 'M'
  *
  * VIR_DOMAIN_STATS_BALLOON:
  * Return memory balloon device information.
diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
index cbc86ce..64ff1d0 100644
--- a/src/libvirt_private.syms
+++ b/src/libvirt_private.syms
@@ -2683,6 +2683,7 @@ virResctrlInfoNew;
 virResctrlMonitorAddPID;
 virResctrlMonitorCreate;
 virResctrlMonitorDeterminePath;
+virResctrlMonitorGetCacheOccupancy;
 virResctrlMonitorGetID;
 virResctrlMonitorIsRunning;
 virResctrlMonitorNew;
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index 12a5f8f..9828118 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -102,6 +102,7 @@
 #include "virnuma.h"
 #include "dirname.h"
 #include "netdev_bandwidth_conf.h"
+#include "c-ctype.h"
 
 #define VIR_FROM_THIS VIR_FROM_QEMU
 
@@ -19698,6 +19699,230 @@ typedef enum {
 #define HAVE_JOB(flags) ((flags) & QEMU_DOMAIN_STATS_HAVE_JOB)
 
 
+/* In terms of the output of virBitmapFormat, both '1-3' and '1,3' are valid
+ * outputs and represent different vcpu set. But it is not easy to
+ * differentiate these two vcpu set formats at first glance.
+ *
+ * This function could be used to clear this ambiguity, it substitutes all '-'
+ * with ',' while generates semantically correct vcpu set.
+ * e.g. vcpu set string '1-3' will be replaced by string '1,2,3'. */
+static char *
+qemuDomainVcpuFormatHelper(const char *vcpus)
+{
+size_t i = 0;
+int last = 0;
+int start = 0;
+char * tmp = NULL;
+bool firstnum = true;
+const char *cur = vcpus;
+virBuffer buf = VIR_BUFFER_INITIALIZER;
+char *ret = NULL;
+
+if (virStringIsEmpty(cur))
+return NULL;
+
+while (*cur != '\0') {
+if (!c_isdigit(*cur))
+goto cleanup;
+
+if (virStrToLong_i(cur, &tmp, 10, &start) < 0)
+goto cleanup;
+if (start < 0)
+goto cleanup;
+
+cur = tmp;
+
+virSkipSpaces(&cur);
+
+if (*cur == ',' || *cur == 0) {
+if (!firstnum)
+virBufferAddChar(&buf, ',');
+virBufferAsprintf(&buf, "%d", start);
+firstnum = false;
+} else if (*cur == '-') {
+cur++;
+virSkipSpaces(&cur);
+
+if (virStrToLong_i(cur, &tmp, 10, &last) < 0)
+goto cleanup;
+
+if (last < start)
+goto cleanup;
+cur = tmp;
+
+for (i = start; i <= last; i++) {
+if (!firstnum)
+
+virBufferAddChar(&buf, ',');
+virBufferAsprintf(&buf, "%ld", i);
+firstnum = 0;
+}
+
+virSkipSpaces(&cur);
+}
+
+if (*cur == ',') {
+cur++;
+virSkipSpaces(&cur);
+

[libvirt] [PATCHv6 05/18] util: Refactor code for adding PID to the resource group

2018-10-22 Thread Wang Huaqiang
The code of adding PID to the allocation could be reused, refactor it
for later reuse.

Signed-off-by: Wang Huaqiang 
---
 src/util/virresctrl.c | 30 +++---
 1 file changed, 19 insertions(+), 11 deletions(-)

diff --git a/src/util/virresctrl.c b/src/util/virresctrl.c
index 794de87..014c2fc 100644
--- a/src/util/virresctrl.c
+++ b/src/util/virresctrl.c
@@ -2387,26 +2387,21 @@ virResctrlAllocCreate(virResctrlInfoPtr resctrl,
 }
 
 
-int
-virResctrlAllocAddPID(virResctrlAllocPtr alloc,
-  pid_t pid)
+static int
+virResctrlAddPID(const char *path,
+ pid_t pid)
 {
 char *tasks = NULL;
 char *pidstr = NULL;
 int ret = 0;
 
-/* If the allocation is empty, then it is impossible to add a PID to
- * allocation  due to lacking of its 'tasks' file. Just return */
-if (virResctrlAllocIsEmpty(alloc))
-return 0;
-
-if (!alloc->path) {
+if (!path) {
 virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
-   _("Cannot add pid to non-existing resctrl allocation"));
+   _("Cannot add pid to non-existing resctrl group"));
 return -1;
 }
 
-if (virAsprintf(&tasks, "%s/tasks", alloc->path) < 0)
+if (virAsprintf(&tasks, "%s/tasks", path) < 0)
 return -1;
 
 if (virAsprintf(&pidstr, "%lld", (long long int) pid) < 0)
@@ -2428,6 +2423,19 @@ virResctrlAllocAddPID(virResctrlAllocPtr alloc,
 
 
 int
+virResctrlAllocAddPID(virResctrlAllocPtr alloc,
+  pid_t pid)
+{
+/* If allocation is empty, then no resctrl directory and the 'tasks' file
+ * exists, just return */
+if (virResctrlAllocIsEmpty(alloc))
+return 0;
+
+return virResctrlAddPID(alloc->path, pid);
+}
+
+
+int
 virResctrlAllocRemove(virResctrlAllocPtr alloc)
 {
 int ret = 0;
-- 
2.7.4

--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list


[libvirt] [PATCHv6 01/18] docs, util: Refactor schemas and virresctrl to support optional cache

2018-10-22 Thread Wang Huaqiang
Refactor schemas and virresctrl to support optional  element
in .

Later, the monitor entry will be introduced and to be placed
under . Either cache entry or monitor entry is
an optional element of .

An cachetune has no  element is taking the default resource
allocating policy defined in '/sys/fs/resctrl/schemata'.

Signed-off-by: Wang Huaqiang 
---
 docs/formatdomain.html.in |  4 ++--
 docs/schemas/domaincommon.rng |  4 ++--
 src/util/virresctrl.c | 31 ---
 3 files changed, 32 insertions(+), 7 deletions(-)

diff --git a/docs/formatdomain.html.in b/docs/formatdomain.html.in
index 8189959..b1651e3 100644
--- a/docs/formatdomain.html.in
+++ b/docs/formatdomain.html.in
@@ -943,8 +943,8 @@
 
   cache
   
-This element controls the allocation of CPU cache and has the
-following attributes:
+This optional element controls the allocation of CPU cache and has
+the following attributes:
 
   level
   
diff --git a/docs/schemas/domaincommon.rng b/docs/schemas/domaincommon.rng
index 099a949..5c533d6 100644
--- a/docs/schemas/domaincommon.rng
+++ b/docs/schemas/domaincommon.rng
@@ -956,7 +956,7 @@
 
   
 
-
+
   
 
   
@@ -980,7 +980,7 @@
   
 
   
-
+
   
 
 
diff --git a/src/util/virresctrl.c b/src/util/virresctrl.c
index 5d811a2..d54d85f 100644
--- a/src/util/virresctrl.c
+++ b/src/util/virresctrl.c
@@ -234,6 +234,11 @@ virResctrlInfoMonFree(virResctrlInfoMonPtr mon)
  * in case there is no allocation for that particular cache allocation (level,
  * cache, ...) or memory allocation for particular node).
  *
+ * Allocation corresponding to root directory, /sys/fs/sysctrl/, defines the
+ * default resource allocating policy, which is created immediately after
+ * mounting, and owns all the tasks and cpus in the system. Cache or memory
+ * bandwidth resource will be shared for tasks in this allocation.
+ *
  * =Cache allocation technology (CAT)=
  *
  * Since one allocation can be made for caches on different levels, the first
@@ -2215,6 +2220,15 @@ virResctrlAllocDeterminePath(virResctrlAllocPtr alloc,
 return -1;
 }
 
+/* If the allocation is empty, then the path will be SYSFS_RESCTRL_PATH */
+if (virResctrlAllocIsEmpty(alloc)) {
+if (!alloc->path &&
+VIR_STRDUP(alloc->path, SYSFS_RESCTRL_PATH) < 0)
+return -1;
+
+return 0;
+}
+
 if (!alloc->path &&
 virAsprintf(&alloc->path, "%s/%s-%s",
 SYSFS_RESCTRL_PATH, machinename, alloc->id) < 0)
@@ -2236,9 +2250,6 @@ virResctrlAllocCreate(virResctrlInfoPtr resctrl,
 int ret = -1;
 int lockfd = -1;
 
-if (!alloc)
-return 0;
-
 if (virResctrlInfoIsEmpty(resctrl)) {
 virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
_("Resource control is not supported on this host"));
@@ -2248,6 +2259,11 @@ virResctrlAllocCreate(virResctrlInfoPtr resctrl,
 if (virResctrlAllocDeterminePath(alloc, machinename) < 0)
 return -1;
 
+/* If the allocation is empty, then do not create directory in underlying
+ * resctrl file system */
+if (virResctrlAllocIsEmpty(alloc))
+return 0;
+
 if (virFileExists(alloc->path)) {
 virReportError(VIR_ERR_INTERNAL_ERROR,
_("Path '%s' for resctrl allocation exists"),
@@ -2302,6 +2318,11 @@ virResctrlAllocAddPID(virResctrlAllocPtr alloc,
 char *pidstr = NULL;
 int ret = 0;
 
+/* If the allocation is empty, then it is impossible to add a PID to
+ * allocation  due to lacking of its 'tasks' file. Just return */
+if (virResctrlAllocIsEmpty(alloc))
+return 0;
+
 if (!alloc->path) {
 virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
_("Cannot add pid to non-existing resctrl allocation"));
@@ -2334,6 +2355,10 @@ virResctrlAllocRemove(virResctrlAllocPtr alloc)
 {
 int ret = 0;
 
+/* No directory have ever been created. Just return */
+if (virResctrlAllocIsEmpty(alloc))
+return 0;
+
 if (!alloc->path)
 return 0;
 
-- 
2.7.4

--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list


[libvirt] [PATCHv6 12/18] conf: Introduce cache monitor element in cachetune

2018-10-22 Thread Wang Huaqiang
Introducing  element under  to represent
a cache monitor.

Signed-off-by: Wang Huaqiang 
---
 docs/formatdomain.html.in  |  26 +++
 docs/schemas/domaincommon.rng  |  10 +
 src/conf/domain_conf.c | 234 -
 src/conf/domain_conf.h |  11 +
 tests/genericxml2xmlindata/cachetune-cdp.xml   |   3 +
 .../cachetune-colliding-monitor.xml|  30 +++
 tests/genericxml2xmlindata/cachetune-small.xml |   7 +
 tests/genericxml2xmltest.c |   2 +
 8 files changed, 322 insertions(+), 1 deletion(-)
 create mode 100644 tests/genericxml2xmlindata/cachetune-colliding-monitor.xml

diff --git a/docs/formatdomain.html.in b/docs/formatdomain.html.in
index b1651e3..2fd665c 100644
--- a/docs/formatdomain.html.in
+++ b/docs/formatdomain.html.in
@@ -759,6 +759,12 @@
 
   
   
+  
+  
+
+
+  
+  
 
 
   
@@ -978,6 +984,26 @@
   
 
   
+  monitor
+  
+The optional element monitor creates the cache
+monitor(s) for current cache allocation and has the following
+required attributes:
+
+  level
+  
+Host cache level the monitor belongs to.
+  
+  vcpus
+  
+vCPU list the monitor applies to. A monitor's vCPU list
+can only be the member(s) of the vCPU list of associating
+allocation. The default monitor has the same vCPU list as the
+associating allocation. For non-default monitors, there
+are no vCPU overlap permitted.
+  
+
+  
 
   
 
diff --git a/docs/schemas/domaincommon.rng b/docs/schemas/domaincommon.rng
index 5c533d6..7ce49d3 100644
--- a/docs/schemas/domaincommon.rng
+++ b/docs/schemas/domaincommon.rng
@@ -981,6 +981,16 @@
 
   
 
+
+  
+
+  
+
+
+  
+
+  
+
   
 
 
diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
index a068d4d..01f795f 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -2955,13 +2955,31 @@ virDomainLoaderDefFree(virDomainLoaderDefPtr loader)
 
 
 static void
+virDomainResctrlMonDefFree(virDomainResctrlMonDefPtr domresmon)
+{
+if (!domresmon)
+return;
+
+virBitmapFree(domresmon->vcpus);
+virObjectUnref(domresmon->instance);
+VIR_FREE(domresmon);
+}
+
+
+static void
 virDomainResctrlDefFree(virDomainResctrlDefPtr resctrl)
 {
+size_t i = 0;
+
 if (!resctrl)
 return;
 
+for (i = 0; i < resctrl->nmonitors; i++)
+virDomainResctrlMonDefFree(resctrl->monitors[i]);
+
 virObjectUnref(resctrl->alloc);
 virBitmapFree(resctrl->vcpus);
+VIR_FREE(resctrl->monitors);
 VIR_FREE(resctrl);
 }
 
@@ -18920,6 +18938,177 @@ virDomainCachetuneDefParseCache(xmlXPathContextPtr 
ctxt,
 }
 
 
+/* Checking if the monitor's vcpus is conflicted with existing allocation
+ * and monitors.
+ *
+ * Returns 1 if @vcpus equals to @resctrl->vcpus, then the monitor will
+ * share the underlying resctrl group with @resctrl->alloc. Returns - 1
+ * if any conflict found. Returns 0 if no conflict and @vcpus is not equal
+ * to @resctrl->vcpus.
+ */
+static int
+virDomainResctrlMonValidateVcpus(virDomainResctrlDefPtr resctrl,
+virBitmapPtr vcpus)
+{
+size_t i = 0;
+int vcpu = -1;
+size_t mons_same_alloc_vcpus = 0;
+
+if (virBitmapIsAllClear(vcpus)) {
+virReportError(VIR_ERR_INVALID_ARG, "%s",
+   _("vcpus is empty"));
+return -1;
+}
+
+while ((vcpu = virBitmapNextSetBit(vcpus, vcpu)) >= 0) {
+if (!virBitmapIsBitSet(resctrl->vcpus, vcpu)) {
+virReportError(VIR_ERR_INVALID_ARG, "%s",
+   _("Monitor vcpus conflicts with allocation"));
+return -1;
+}
+}
+
+if (virBitmapEqual(vcpus, resctrl->vcpus))
+return 1;
+
+for (i = 0; i < resctrl->nmonitors; i++) {
+if (virBitmapEqual(resctrl->vcpus, resctrl->monitors[i]->vcpus)) {
+mons_same_alloc_vcpus++;
+continue;
+}
+
+if (virBitmapOverlaps(vcpus, resctrl->monitors[i]->vcpus)) {
+virReportError(VIR_ERR_INVALID_ARG, "%s",
+

[libvirt] [PATCHv6 02/18] util: Introduce resctrl monitor for CMT

2018-10-22 Thread Wang Huaqiang
Cache Monitoring Technology (aka CMT) provides the capability
to report cache utilization information of system task.

This patch introduces the concept of resctrl monitor through
data structure virResctrlMonitor.

Signed-off-by: Wang Huaqiang 
---
 src/libvirt_private.syms |  2 +-
 src/util/virresctrl.c| 79 
 src/util/virresctrl.h|  9 ++
 3 files changed, 83 insertions(+), 7 deletions(-)

diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
index 335210c..9577b70 100644
--- a/src/libvirt_private.syms
+++ b/src/libvirt_private.syms
@@ -2680,7 +2680,7 @@ virResctrlInfoGetCache;
 virResctrlInfoGetMonitorPrefix;
 virResctrlInfoMonFree;
 virResctrlInfoNew;
-
+virResctrlMonitorNew;
 
 # util/virrotatingfile.h
 virRotatingFileReaderConsume;
diff --git a/src/util/virresctrl.c b/src/util/virresctrl.c
index d54d85f..578a52c 100644
--- a/src/util/virresctrl.c
+++ b/src/util/virresctrl.c
@@ -36,9 +36,9 @@ VIR_LOG_INIT("util.virresctrl")
 
 
 /* Resctrl is short for Resource Control.  It might be implemented for various
- * resources. Currently this supports cache allocation technology (aka CAT) and
- * memory bandwidth allocation (aka MBA). More resources technologies may be
- * added in the future.
+ * resources. Currently this supports cache allocation technology (aka CAT),
+ * memory bandwidth allocation (aka MBA) and cache monitoring technology (aka
+ * CMT). More resources technologies may be added in the future.
  */
 
 
@@ -105,6 +105,7 @@ typedef virResctrlAllocMemBW *virResctrlAllocMemBWPtr;
 /* Class definitions and initializations */
 static virClassPtr virResctrlInfoClass;
 static virClassPtr virResctrlAllocClass;
+static virClassPtr virResctrlMonitorClass;
 
 
 /* virResctrlInfo */
@@ -224,11 +225,16 @@ virResctrlInfoMonFree(virResctrlInfoMonPtr mon)
 }
 
 
-/* virResctrlAlloc */
+/* virResctrlAlloc and virResctrlMonitor*/
 
 /*
- * virResctrlAlloc represents one allocation (in XML under cputune/cachetune 
and
- * consequently a directory under /sys/fs/resctrl).  Since it can have multiple
+ * virResctrlAlloc and virResctrlMonitor are representing a resource control
+ * group (in XML under cputune/cachetune and consequently a directory under
+ * /sys/fs/resctrl). virResctrlAlloc is the data structure for resource
+ * allocation, while the virResctrlMonitor represents the resource monitoring
+ * part.
+ *
+ * virResctrlAlloc represents one allocation. Since it can have multiple
  * parts of multiple caches allocated it is represented as bunch of nested
  * sparse arrays (by sparse I mean array of pointers so that each might be NULL
  * in case there is no allocation for that particular cache allocation (level,
@@ -275,6 +281,18 @@ virResctrlInfoMonFree(virResctrlInfoMonPtr mon)
  * a sparse array to represent whether a memory bandwidth allocation happens
  * on corresponding node. The available memory controller number is collected
  * in 'virResctrlInfo'.
+ *
+ * =Cache monitoring technology (CMT)=
+ *
+ * Cache monitoring technology is used to perceive how many cache the process
+ * is using actually. virResctrlMonitor represents the resource control
+ * monitoring group, it is supported to monitor resource utilization
+ * information on granularity of vcpu.
+ *
+ * From hardware perspective, cache monitoring technology (CMT), memory
+ * bandwidth technology (MBM), as well as the CAT and MBA, are all orthogonal
+ * features. The monitor will be created under the scope of default resctl
+ * group if no specific CAT or MBA entries are provided for the guest."
  */
 struct _virResctrlAllocPerType {
 /* There could be bool saying whether this is set or not, but since 
everything
@@ -320,6 +338,29 @@ struct _virResctrlAlloc {
 char *path;
 };
 
+/*
+ * virResctrlMonitor is the data structure for resctrl monitor. Resctrl
+ * monitor represents a resctrl monitoring group, which can be used to
+ * monitor the resource utilization information for either cache or
+ * memory bandwidth.
+ */
+struct _virResctrlMonitor {
+virObject parent;
+
+/* In resctrl, each monitor is associated with one specific allocation,
+ * either the allocation under / sys / fs / resctrl or allocation of the
+ * root directory itself. This pointer points to the allocation
+ * this monitor associated with. */
+virResctrlAllocPtr alloc;
+/* The monitor identifier. For a monitor has the same @path name as its
+ * @alloc, the @id will be set to the same value as it is in @alloc->id.
+ */
+char *id;
+/* libvirt-generated path in /sys/fs/resctrl for this particular
+ * monitor */
+char *path;
+};
+
 
 static void
 virResctrlAllocDispose(void *obj)
@@ -369,6 +410,17 @@ virResctrlAllocDispose(void *obj)
 }
 
 
+static void
+virResctrlMonitorDispose(void *obj)
+{
+virResctrlMonitorPtr monitor = obj;
+
+virObjectUnref(monitor->alloc);
+VIR_FREE(monitor->id);
+VIR_FREE(monitor->path);
+}
+
+
 /*