[libvirt] [libvirt-perl PATCHv2 0/2] Add virDomainGetIOThreads and virDomainPinIOThread bindings

v1: http://www.redhat.com/archives/libvir-list/2015-March/msg00352.html Since I essentially copied the vcpuinfo.pl example to create the iothreadsinfo.pl example, I figured I'd resend the patches again with the changes that ended up working which are slightly different than the review comment. The major difference being I needed to limit the unpack bits format. Instead of "b*", I found "b$nodeinfo->{cpus}" would print the just the cpu count bits. Made the same change to the vcpuinfo.pl example. I didn't modify the Virt.xs Safefree(info) check although it seems it would be possible if desired. John Ferlan (2): Add virDomainGetIOThreads and virDomainPinIOThread bindings Update the vcpuinfo.pl example Changes | 3 ++- Virt.xs | 42 ++++++++++++++++++++++++++++++++++++++++++ examples/iothreadsinfo.pl | 33 +++++++++++++++++++++++++++++++++ examples/vcpuinfo.pl | 6 ++---- lib/Sys/Virt/Domain.pm | 17 +++++++++++++++++ 5 files changed, 96 insertions(+), 5 deletions(-) create mode 100644 examples/iothreadsinfo.pl -- 2.1.0

Test results in the following output: $ perl examples/iothreadsinfo.pl Addr VMM type: QEMU ... Domain: { ID: 2 'f18iothr' UUID: fb9f7826-b5d7-4f74-b962-7181ef3fc9ec IOThread: { affinity: 0010 number: 1 } IOThread: { affinity: 0001 number: 2 } IOThread: { affinity: 1100 number: 3 } } Signed-off-by: John Ferlan <jferlan@redhat.com> --- Changes | 2 +- Virt.xs | 42 ++++++++++++++++++++++++++++++++++++++++++ examples/iothreadsinfo.pl | 33 +++++++++++++++++++++++++++++++++ lib/Sys/Virt/Domain.pm | 17 +++++++++++++++++ 4 files changed, 93 insertions(+), 1 deletion(-) create mode 100644 examples/iothreadsinfo.pl diff --git a/Changes b/Changes index b62ee24..88f648c 100644 --- a/Changes +++ b/Changes @@ -2,7 +2,7 @@ Revision history for perl module Sys::Virt 1.2.14 2015-00-00 - - XXX + - Add virDomainGetIOThreads and virDomainPinIOThread API bindings 1.2.13 2015-03-05 diff --git a/Virt.xs b/Virt.xs index f9ec7a4..56e143d 100644 --- a/Virt.xs +++ b/Virt.xs @@ -5014,6 +5014,48 @@ get_emulator_pin_info(dom, flags=0) RETVAL +void +get_iothread_info(dom, flags=0) + virDomainPtr dom; + unsigned int flags; + PREINIT: + virDomainIOThreadInfoPtr *iothrinfo; + int niothreads; + int i; + PPCODE: + if ((niothreads = virDomainGetIOThreadsInfo(dom, &iothrinfo, + flags)) < 0) + _croak_error(); + + EXTEND(SP, niothreads); + for (i = 0 ; i < niothreads ; i++) { + HV *rec = newHV(); + (void)hv_store(rec, "number", 6, + newSViv(iothrinfo[i]->iothread_id), 0); + (void)hv_store(rec, "affinity", 8, + newSVpvn((char*)iothrinfo[i]->cpumap, + iothrinfo[i]->cpumaplen), 0); + PUSHs(newRV_noinc((SV *)rec)); + } + + Safefree(iothrinfo); + + +void +pin_iothread(dom, iothread_id, mask, flags=0) + virDomainPtr dom; + unsigned int iothread_id; + SV *mask; + unsigned int flags; +PREINIT: + STRLEN masklen; + unsigned char *maps; + PPCODE: + maps = (unsigned char *)SvPV(mask, masklen); + if (virDomainPinVcpuFlags(dom, iothread_id, maps, masklen, flags) < 0) + _croak_error(); + + int num_of_snapshots(dom, flags=0) virDomainPtr dom; diff --git a/examples/iothreadsinfo.pl b/examples/iothreadsinfo.pl new file mode 100644 index 0000000..97c5eb6 --- /dev/null +++ b/examples/iothreadsinfo.pl @@ -0,0 +1,33 @@ +# -*- perl -*- +use strict; +use warnings; +use Sys::Virt; + +my $addr = @ARGV ? shift @ARGV : ""; +print "Addr $addr\n"; +my $con = Sys::Virt->new(address => $addr, readonly => 1); + +print "VMM type: ", $con->get_type(), "\n"; + +foreach my $dom (sort { $a->get_id <=> $b->get_id } $con->list_all_domains) { + print "Domain: {\n"; + print " ID: ", $dom->get_id(), " '" , $dom->get_name(), "'\n"; + print " UUID: ", $dom->get_uuid_string(), "\n"; + my $nodeinfo = $con->get_node_info; + my @info = $dom->get_iothread_info(Sys::Virt::Domain::AFFECT_CONFIG); + + foreach my $info (@info) { + print " IOThread: {\n"; + foreach (sort { $a cmp $b } keys %{$info}) { + if ($_ eq "affinity") { + print " ", $_, ": "; + my @bits = split(//, unpack("b$nodeinfo->{cpus}", $info->{$_})); + print join ("", @bits), "\n"; + } else { + print " ", $_, ": ", $info->{$_}, "\n"; + } + } + print " }\n"; + } + print "}\n"; +} diff --git a/lib/Sys/Virt/Domain.pm b/lib/Sys/Virt/Domain.pm index 5c8ef47..062c012 100644 --- a/lib/Sys/Virt/Domain.pm +++ b/lib/Sys/Virt/Domain.pm @@ -1216,6 +1216,23 @@ the physical CPUa, 8 cpus per character. To create a suitable bitstring, use the C<vec> function with a value of C<1> for the C<BITS> parameter. +=item @iothreadinfo = $dom->get_iothread_info($flags=0) + +Obtain information about the state of all IOThreads in a running +guest domain. The returned list will have one element for each IOThread, +where each elements contains a hash reference. The keys in the hash +are, C<number> the IOThread number and C<affinity> giving the allowed +schedular placement. The value for C<affinity> is a +string representing a bitmask against physical CPUs, 8 cpus per +character. To extract the bits use the C<unpack> function with +the C<b*> template. + +=item $dom->pin_iothread($iothread, $mask) + +Pin the IOThread given by index C<$iothread> to physical CPUs +given by C<$mask>. The C<$mask> is a string representing a bitmask +against physical CPUs, 8 cpus per character. + =item my @stats = $dom->get_cpu_stats($startCpu, $numCpus, $flags=0) Requests the guests host physical CPU usage statistics, starting -- 2.1.0

On Tue, Mar 10, 2015 at 11:04:00AM -0400, John Ferlan wrote:
Test results in the following output:
$ perl examples/iothreadsinfo.pl Addr VMM type: QEMU ... Domain: { ID: 2 'f18iothr' UUID: fb9f7826-b5d7-4f74-b962-7181ef3fc9ec IOThread: { affinity: 0010 number: 1 } IOThread: { affinity: 0001 number: 2 } IOThread: { affinity: 1100 number: 3 } }
Signed-off-by: John Ferlan <jferlan@redhat.com> --- Changes | 2 +- Virt.xs | 42 ++++++++++++++++++++++++++++++++++++++++++ examples/iothreadsinfo.pl | 33 +++++++++++++++++++++++++++++++++ lib/Sys/Virt/Domain.pm | 17 +++++++++++++++++ 4 files changed, 93 insertions(+), 1 deletion(-) create mode 100644 examples/iothreadsinfo.pl
diff --git a/Changes b/Changes index b62ee24..88f648c 100644 --- a/Changes +++ b/Changes @@ -2,7 +2,7 @@ Revision history for perl module Sys::Virt
1.2.14 2015-00-00
- - XXX + - Add virDomainGetIOThreads and virDomainPinIOThread API bindings
1.2.13 2015-03-05
diff --git a/Virt.xs b/Virt.xs index f9ec7a4..56e143d 100644 --- a/Virt.xs +++ b/Virt.xs @@ -5014,6 +5014,48 @@ get_emulator_pin_info(dom, flags=0) RETVAL
+void +get_iothread_info(dom, flags=0) + virDomainPtr dom; + unsigned int flags; + PREINIT: + virDomainIOThreadInfoPtr *iothrinfo; + int niothreads; + int i; + PPCODE: + if ((niothreads = virDomainGetIOThreadsInfo(dom, &iothrinfo, + flags)) < 0) + _croak_error(); + + EXTEND(SP, niothreads); + for (i = 0 ; i < niothreads ; i++) { + HV *rec = newHV(); + (void)hv_store(rec, "number", 6, + newSViv(iothrinfo[i]->iothread_id), 0); + (void)hv_store(rec, "affinity", 8, + newSVpvn((char*)iothrinfo[i]->cpumap, + iothrinfo[i]->cpumaplen), 0); + PUSHs(newRV_noinc((SV *)rec)); + } + + Safefree(iothrinfo); + + +void +pin_iothread(dom, iothread_id, mask, flags=0) + virDomainPtr dom; + unsigned int iothread_id; + SV *mask; + unsigned int flags; +PREINIT: + STRLEN masklen; + unsigned char *maps; + PPCODE: + maps = (unsigned char *)SvPV(mask, masklen); + if (virDomainPinVcpuFlags(dom, iothread_id, maps, masklen, flags) < 0) + _croak_error(); + + int num_of_snapshots(dom, flags=0) virDomainPtr dom; diff --git a/examples/iothreadsinfo.pl b/examples/iothreadsinfo.pl new file mode 100644 index 0000000..97c5eb6 --- /dev/null +++ b/examples/iothreadsinfo.pl @@ -0,0 +1,33 @@ +# -*- perl -*- +use strict; +use warnings; +use Sys::Virt; + +my $addr = @ARGV ? shift @ARGV : ""; +print "Addr $addr\n"; +my $con = Sys::Virt->new(address => $addr, readonly => 1); + +print "VMM type: ", $con->get_type(), "\n"; + +foreach my $dom (sort { $a->get_id <=> $b->get_id } $con->list_all_domains) { + print "Domain: {\n"; + print " ID: ", $dom->get_id(), " '" , $dom->get_name(), "'\n"; + print " UUID: ", $dom->get_uuid_string(), "\n"; + my $nodeinfo = $con->get_node_info; + my @info = $dom->get_iothread_info(Sys::Virt::Domain::AFFECT_CONFIG); + + foreach my $info (@info) { + print " IOThread: {\n"; + foreach (sort { $a cmp $b } keys %{$info}) { + if ($_ eq "affinity") { + print " ", $_, ": "; + my @bits = split(//, unpack("b$nodeinfo->{cpus}", $info->{$_})); + print join ("", @bits), "\n"; + } else { + print " ", $_, ": ", $info->{$_}, "\n"; + } + } + print " }\n"; + } + print "}\n"; +} diff --git a/lib/Sys/Virt/Domain.pm b/lib/Sys/Virt/Domain.pm index 5c8ef47..062c012 100644 --- a/lib/Sys/Virt/Domain.pm +++ b/lib/Sys/Virt/Domain.pm @@ -1216,6 +1216,23 @@ the physical CPUa, 8 cpus per character. To create a suitable bitstring, use the C<vec> function with a value of C<1> for the C<BITS> parameter.
+=item @iothreadinfo = $dom->get_iothread_info($flags=0) + +Obtain information about the state of all IOThreads in a running +guest domain. The returned list will have one element for each IOThread, +where each elements contains a hash reference. The keys in the hash +are, C<number> the IOThread number and C<affinity> giving the allowed +schedular placement. The value for C<affinity> is a +string representing a bitmask against physical CPUs, 8 cpus per +character. To extract the bits use the C<unpack> function with +the C<b*> template. + +=item $dom->pin_iothread($iothread, $mask) + +Pin the IOThread given by index C<$iothread> to physical CPUs +given by C<$mask>. The C<$mask> is a string representing a bitmask +against physical CPUs, 8 cpus per character. + =item my @stats = $dom->get_cpu_stats($startCpu, $numCpus, $flags=0)
Requests the guests host physical CPU usage statistics, starting --
ACK Regards, Daniel -- |: http://berrange.com -o- http://www.flickr.com/photos/dberrange/ :| |: http://libvirt.org -o- http://virt-manager.org :| |: http://autobuild.org -o- http://search.cpan.org/~danberr/ :| |: http://entangle-photo.org -o- http://live.gnome.org/gtk-vnc :|

On Tue, Mar 10, 2015 at 11:04:00AM -0400, John Ferlan wrote:
Test results in the following output:
$ perl examples/iothreadsinfo.pl Addr VMM type: QEMU ... Domain: { ID: 2 'f18iothr' UUID: fb9f7826-b5d7-4f74-b962-7181ef3fc9ec IOThread: { affinity: 0010 number: 1 } IOThread: { affinity: 0001 number: 2 } IOThread: { affinity: 1100 number: 3 } }
Signed-off-by: John Ferlan <jferlan@redhat.com> --- Changes | 2 +- Virt.xs | 42 ++++++++++++++++++++++++++++++++++++++++++ examples/iothreadsinfo.pl | 33 +++++++++++++++++++++++++++++++++ lib/Sys/Virt/Domain.pm | 17 +++++++++++++++++ 4 files changed, 93 insertions(+), 1 deletion(-) create mode 100644 examples/iothreadsinfo.pl
diff --git a/Changes b/Changes index b62ee24..88f648c 100644 --- a/Changes +++ b/Changes @@ -2,7 +2,7 @@ Revision history for perl module Sys::Virt
1.2.14 2015-00-00
- - XXX + - Add virDomainGetIOThreads and virDomainPinIOThread API bindings
1.2.13 2015-03-05
diff --git a/Virt.xs b/Virt.xs index f9ec7a4..56e143d 100644 --- a/Virt.xs +++ b/Virt.xs @@ -5014,6 +5014,48 @@ get_emulator_pin_info(dom, flags=0) RETVAL
+void +get_iothread_info(dom, flags=0) + virDomainPtr dom; + unsigned int flags; + PREINIT: + virDomainIOThreadInfoPtr *iothrinfo; + int niothreads; + int i; + PPCODE: + if ((niothreads = virDomainGetIOThreadsInfo(dom, &iothrinfo, + flags)) < 0) + _croak_error(); + + EXTEND(SP, niothreads); + for (i = 0 ; i < niothreads ; i++) { + HV *rec = newHV(); + (void)hv_store(rec, "number", 6, + newSViv(iothrinfo[i]->iothread_id), 0); + (void)hv_store(rec, "affinity", 8, + newSVpvn((char*)iothrinfo[i]->cpumap, + iothrinfo[i]->cpumaplen), 0); + PUSHs(newRV_noinc((SV *)rec)); + } + + Safefree(iothrinfo);
Opps, we should have been calling virDomainIOThreadsInfoFree on each element of iothrinfo, and then using free() rather than Safefree(), since the memory was allocated by Libvirt rather than by Perl.
+void +pin_iothread(dom, iothread_id, mask, flags=0) + virDomainPtr dom; + unsigned int iothread_id; + SV *mask; + unsigned int flags; +PREINIT: + STRLEN masklen; + unsigned char *maps; + PPCODE: + maps = (unsigned char *)SvPV(mask, masklen); + if (virDomainPinVcpuFlags(dom, iothread_id, maps, masklen, flags) < 0) + _croak_error();
And s/VcpuFlags/IOThreads/ here. BTW, I noticed these mistakes by running the API coverage test suite make test TEST_MAINTAINER=1 which reports anything in libvirt*.h that is not used from the Perl code. I've pushed the obvious fixes. Regards, Daniel -- |: http://berrange.com -o- http://www.flickr.com/photos/dberrange/ :| |: http://libvirt.org -o- http://virt-manager.org :| |: http://autobuild.org -o- http://search.cpan.org/~danberr/ :| |: http://entangle-photo.org -o- http://live.gnome.org/gtk-vnc :|

Based on the review of my iothreadsinfo.pl example which I took from vcpuinfo.pl, this patch updates the vcpuinfo.pl to follow the changes made in iothreadsinfo.pl Signed-off-by: John Ferlan <jferlan@redhat.com> --- Changes | 1 + examples/vcpuinfo.pl | 6 ++---- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/Changes b/Changes index 88f648c..124b798 100644 --- a/Changes +++ b/Changes @@ -3,6 +3,7 @@ Revision history for perl module Sys::Virt 1.2.14 2015-00-00 - Add virDomainGetIOThreads and virDomainPinIOThread API bindings + - Update the vcpuinfo.pl example to use unpack 1.2.13 2015-03-05 diff --git a/examples/vcpuinfo.pl b/examples/vcpuinfo.pl index 6b07433..79dcf89 100644 --- a/examples/vcpuinfo.pl +++ b/examples/vcpuinfo.pl @@ -21,10 +21,8 @@ foreach my $dom (sort { $a->get_id <=> $b->get_id } $con->list_all_domains) { foreach (sort { $a cmp $b } keys %{$info}) { if ($_ eq "affinity") { print " ", $_, ": "; - my @mask = split //, $info->{$_}; - for (my $p = 0 ; $p < $nodeinfo->{cpus} ; $p++) { - print ((ord($mask[$p/8]) & (1 << ($p % 8))) ? 1 : 0); - } + my @mask = split(//, unpack("b$nodeinfo->{cpus}", $info->{$_})); + print join ("", @mask), "\n"; print "\n"; } else { print " ", $_, ": ", $info->{$_}, "\n"; -- 2.1.0

On Tue, Mar 10, 2015 at 11:04:01AM -0400, John Ferlan wrote:
Based on the review of my iothreadsinfo.pl example which I took from vcpuinfo.pl, this patch updates the vcpuinfo.pl to follow the changes made in iothreadsinfo.pl
Signed-off-by: John Ferlan <jferlan@redhat.com> --- Changes | 1 + examples/vcpuinfo.pl | 6 ++---- 2 files changed, 3 insertions(+), 4 deletions(-)
ACK Regards, Daniel -- |: http://berrange.com -o- http://www.flickr.com/photos/dberrange/ :| |: http://libvirt.org -o- http://virt-manager.org :| |: http://autobuild.org -o- http://search.cpan.org/~danberr/ :| |: http://entangle-photo.org -o- http://live.gnome.org/gtk-vnc :|

On 03/10/2015 11:03 AM, John Ferlan wrote:
v1: http://www.redhat.com/archives/libvir-list/2015-March/msg00352.html
Since I essentially copied the vcpuinfo.pl example to create the iothreadsinfo.pl example, I figured I'd resend the patches again with the changes that ended up working which are slightly different than the review comment. The major difference being I needed to limit the unpack bits format. Instead of "b*", I found "b$nodeinfo->{cpus}" would print the just the cpu count bits.
Made the same change to the vcpuinfo.pl example. I didn't modify the Virt.xs Safefree(info) check although it seems it would be possible if desired.
John Ferlan (2): Add virDomainGetIOThreads and virDomainPinIOThread bindings Update the vcpuinfo.pl example
Changes | 3 ++- Virt.xs | 42 ++++++++++++++++++++++++++++++++++++++++++ examples/iothreadsinfo.pl | 33 +++++++++++++++++++++++++++++++++ examples/vcpuinfo.pl | 6 ++---- lib/Sys/Virt/Domain.pm | 17 +++++++++++++++++ 5 files changed, 96 insertions(+), 5 deletions(-) create mode 100644 examples/iothreadsinfo.pl
Pushed - thanks John
participants (2)
-
Daniel P. Berrange
-
John Ferlan