nathans pushed to pcp (el5). "Initial changes to support python3 as default (1194323)"

notifications at fedoraproject.org notifications at fedoraproject.org
Thu Apr 16 02:27:56 UTC 2015


>From 7674f7200aa7f856168ac5cb6500d110387f7358 Mon Sep 17 00:00:00 2001
From: Nathan Scott <nathans at redhat.com>
Date: Mon, 23 Feb 2015 22:09:10 +1100
Subject: Initial changes to support python3 as default (1194323)


diff --git a/bz1194324.patch b/bz1194324.patch
new file mode 100644
index 0000000..55cedb3
--- /dev/null
+++ b/bz1194324.patch
@@ -0,0 +1,3411 @@
+diff -Naurp pcp-3.10.2.orig/configure pcp-3.10.2/configure
+--- pcp-3.10.2.orig/configure	2015-01-24 07:23:07.000000000 +1100
++++ pcp-3.10.2/configure	2015-02-23 21:24:36.653658342 +1100
+@@ -798,6 +798,7 @@ qmake
+ enable_qt
+ qt_release
+ QMAKE
++pcp_python_prog
+ enable_python3
+ enable_python
+ PYTHON3
+@@ -6229,6 +6230,14 @@ done
+ fi
+ 
+ 
++if test "$enable_python3" = "true"
++then
++    pcp_python_prog=$PYTHON3
++else
++    pcp_python_prog=$PYTHON
++fi
++
++
+ qmake=$QMAKE
+ enable_qt=false
+ qt_release=release
+diff -Naurp pcp-3.10.2.orig/configure.ac pcp-3.10.2/configure.ac
+--- pcp-3.10.2.orig/configure.ac	2015-01-24 07:23:07.000000000 +1100
++++ pcp-3.10.2/configure.ac	2015-02-23 21:24:36.655658340 +1100
+@@ -534,6 +534,15 @@ AS_IF([test "x$do_python3" != "xno"], [
+ ])
+ AC_SUBST(enable_python3)
+ 
++dnl choose the prefered python executable (py2 -> py3 transtion)
++if test "$enable_python3" = "true"
++then
++    pcp_python_prog=$PYTHON3
++else
++    pcp_python_prog=$PYTHON
++fi
++AC_SUBST(pcp_python_prog)
++
+ qmake=$QMAKE
+ enable_qt=false
+ qt_release=release
+diff -Naurp pcp-3.10.2.orig/man/man1/pmatop.1 pcp-3.10.2/man/man1/pmatop.1
+--- pcp-3.10.2.orig/man/man1/pmatop.1	2015-01-21 02:18:01.000000000 +1100
++++ pcp-3.10.2/man/man1/pmatop.1	2015-02-23 21:21:18.198838491 +1100
+@@ -1,45 +1,50 @@
++'\"macro stdmacro
++.\"
++.\" Copyright (c) 2014-2015 Red Hat.
++.\" 
++.\" This program is free software; you can redistribute it and/or modify it
++.\" under the terms of the GNU General Public License as published by the
++.\" Free Software Foundation; either version 2 of the License, or (at your
++.\" option) any later version.
++.\" 
++.\" This program is distributed in the hope that it will be useful, but
++.\" WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
++.\" or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
++.\" for more details.
++.\"
+ .TH PMATOP 1 "PCP" "Performance Co-Pilot"
+ .SH NAME
+-.B pmatop 
+-\- System & Process Monitor
++\f3pmatop\f1 \- System and Process Monitor
+ .SH SYNOPSIS
+ Interactive usage:
+ .P
+ .B pmatop
+-[\-g|\-m] [\-L linelen] [\-h host]
+-[
+-.I interval
+-[
+-.I samples
+-]]
++[\-g|\-m] [\-L \f2linelen\f1] [\-h \f2host\f1 | \-a \f2archive\f1]
++[\f2interval\f1 [\f2samples\f1]]
+ .P
+-Writing and reading raw logfiles:
++Writing and reading PCP archive folios:
+ .P
+-.B pmatop
+-\-w
+-.I rawfile
+-[
+-.I interval
+-[
+-.I samples
+-]]
++.BR pmatop
++\-w \f2rawfile\f1 [\f2interval\f1 [\f2samples\f1]]
+ .br
+ .B pmatop
+-\-r [
+-.I rawfile
+-] [\-g|\-m] [\-L linelen] [\-h host]
++\-r [\f2rawfile\f1] [\-g|\-m] [\-L \f2linelen\f1]
+ .SH DESCRIPTION
+ The program
+-.I pmatop
++.B pmatop
+ is an interactive monitor to view the load on a Linux system.
+ It shows the occupation of the most critical hardware resources 
+ (from a performance point of view) on system level, i.e. cpu, memory, disk
+ and network.  By default metrics from the local host are
+ displayed, but a different host may be specified with the 
+-.I [-h host]
+-option.  It is modeled after
++.IR \-h/\-\-host
++option, or from a PCP archive using the
++.IR \-a/\-\-archive
++option.
++.PP
++It is modeled on
+ .BR atop (1)
+-and provides a showcase for the variety of data available via
++and provides a showcase for the variety of data available from
+ .BR pmcd (1).
+ .br
+ .PP
+@@ -57,33 +62,33 @@ The intervals are repeated till the numb
+ in interactive mode.
+ .PP
+ When 
+-.I pmatop
++.B pmatop
+ is started, it checks whether the standard output channel is connected to a
+ screen, or to a file/pipe. In the first case it produces screen control 
+ codes (via the ncurses library) and behaves interactively; in the second case
+ it produces flat ASCII-output.
+ .PP
+ In interactive mode, the output of 
+-.I pmatop
++.B pmatop
+ scales dynamically to the current dimensions of the screen/window.
+ .PP
+ Furthermore in interactive mode the output of 
+-.I pmatop
++.B pmatop
+ can be controlled by pressing particular keys.
+ However it is also possible to specify such key as
+-.B flag
++.I flag
+ on the command line. In that case
+-.I pmatop
++.B pmatop
+ switches to the indicated mode on beforehand; this mode can 
+ be modified again interactively. Specifying such key as flag is especially
+ useful when running
+-.I pmatop
++.B pmatop
+ with output to a pipe or file (non-interactively).
+ These flags are the same as the keys that can be pressed in interactive
+ mode (see section INTERACTIVE COMMANDS).
+ .SH OUTPUT FORMAT
+ The output of 
+-.I pmatop
++.B pmatop
+ consists of system level and process level information.  The system
+ level information consists of the following output lines:
+ .PP
+@@ -146,7 +151,7 @@ The remaining lines are one line per pro
+ described below.
+ .SH INTERACTIVE COMMANDS
+ When running
+-.I pmatop
++.B pmatop
+ interactively (no output redirection), keys can be pressed to control the
+ output.
+ .PP
+@@ -191,16 +196,16 @@ Request for help information (also the k
+ .B z
+ The pause key can be used to freeze the current situation in order to
+ investigate the output on the screen. While 
+-.I pmatop
++.B pmatop
+ is paused, the keys described above can be pressed to show other
+ information about the current list of processes.
+ Whenever the pause key is pressed again,
+-pmatop will continue with a next sample.
++.B pmatop
++will continue with a next sample.
+ .PP
+ .SH "SEE ALSO"
+ .BR PCPIntro (1),
+-.BR collectl (1),
+-.BR perl (1),
++.BR atop (1),
+ .BR python (1),
+ .BR pmlogger (1),
+ .BR pmcd (1),
+@@ -209,4 +214,3 @@ pmatop will continue with a next sample.
+ .BR PMAPI (3),
+ and
+ .BR pcp.conf (5).
+-
+diff -Naurp pcp-3.10.2.orig/qa/553 pcp-3.10.2/qa/553
+--- pcp-3.10.2.orig/qa/553	2015-01-21 02:18:01.000000000 +1100
++++ pcp-3.10.2/qa/553	2015-02-23 21:24:36.655658340 +1100
+@@ -10,6 +10,7 @@ echo "QA output created by $seq"
+ 
+ . ./common.python
+ 
++python_path=`which $python`
+ pmda_path="$PCP_PMDAS_DIR/gluster"
+ pmda_script="$pmda_path/pmdagluster.python"
+ test -f "$pmda_script" || _notrun "pmdagluster not supported"
+@@ -27,6 +28,9 @@ _filter()
+ 	-e "s;$PCP_PMDAS_DIR;\$PCP_PMDAS_DIR;" \
+         -e '/pmResult/s/ .* numpmid/ ... numpmid/' \
+         -e '/[0-9][0-9]:[0-9][0-9]:[0-9][0-9]/s/[^ ]*/TIMESTAMP/' \
++	-e "s;$python_path;\$PCP_PYTHON_PROG;" \
++	-e "s;$python;python;" \
++    #end
+ 
+     test -f gluster.log && cat gluster.log >> $seq.full
+ }
+@@ -49,13 +53,13 @@ PCP_PYTHON_PMNS=root $python "$pmda_scri
+ 
+ echo "== Testing volume instance domain" | tee -a $seq.full
+ $sudo dbpmda -n $tmp.root -ie <<End-of-File 2>&1 | _filter
+-open pipe $python $pmda_script
++open pipe $python_path $pmda_script
+ instance $domain.0
+ End-of-File
+ 
+ echo "== Testing volume information metrics" | tee -a $seq.full
+ $sudo dbpmda -n $tmp.root -ie <<End-of-File 2>&1 | _filter
+-open pipe $python $pmda_script
++open pipe $python_path $pmda_script
+ getdesc on
+ desc gluster.volume.dist.count
+ desc gluster.volume.stripe.count
+@@ -68,7 +72,7 @@ End-of-File
+ echo "== Testing volume control metric store" | tee -a $seq.full
+ $sudo rm -f $tmp.start $tmp.stop
+ $sudo dbpmda -n $tmp.root -ie <<End-of-File 2>&1 | _filter
+-open pipe $python $pmda_script
++open pipe $python_path $pmda_script
+ getdesc on
+ desc gluster.volume.profile
+ fetch gluster.volume.profile
+@@ -81,13 +85,13 @@ $sudo rm -f $tmp.start $tmp.stop
+ 
+ echo "== Testing brick instance domain" | tee -a $seq.full
+ $sudo dbpmda -n $tmp.root -ie <<End-of-File 2>&1 | _filter
+-open pipe $python $pmda_script
++open pipe $python_path $pmda_script
+ instance $domain.1
+ End-of-File
+ 
+ echo "== Testing brick throughput metrics" | tee -a $seq.full
+ $sudo dbpmda -n $tmp.root -ie <<End-of-File 2>&1 | _filter
+-open pipe $python $pmda_script
++open pipe $python_path $pmda_script
+ getdesc on
+ desc gluster.brick.read_bytes
+ fetch gluster.brick.read_bytes
+@@ -97,7 +101,7 @@ End-of-File
+ 
+ echo "== Testing brick file operation latency metrics" | tee -a $seq.full
+ $sudo dbpmda -n $tmp.root -ie <<End-of-File 2>&1 | _filter
+-open pipe $python $pmda_script
++open pipe $python_path $pmda_script
+ getdesc on
+ desc gluster.brick.latency.getxattr.avg
+ desc gluster.brick.latency.getxattr.min
+diff -Naurp pcp-3.10.2.orig/qa/553.out pcp-3.10.2/qa/553.out
+--- pcp-3.10.2.orig/qa/553.out	2015-01-21 02:18:01.000000000 +1100
++++ pcp-3.10.2/qa/553.out	2015-02-23 21:24:36.656658340 +1100
+@@ -1,14 +1,14 @@
+ QA output created by 553
+ == Testing volume instance domain
+-dbpmda> open pipe /usr/bin/python $PCP_PMDAS_DIR/gluster/pmdagluster.python
+-Start python PMDA: /usr/bin/python $PCP_PMDAS_DIR/gluster/pmdagluster.python
++dbpmda> open pipe $PCP_PYTHON_PROG $PCP_PMDAS_DIR/gluster/pmdagluster.python
++Start python PMDA: $PCP_PYTHON_PROG $PCP_PMDAS_DIR/gluster/pmdagluster.python
+ dbpmda> instance 118.0
+ pmInDom: 118.0
+ [  0] inst: 0 name: "gv0"
+ dbpmda> 
+ == Testing volume information metrics
+-dbpmda> open pipe /usr/bin/python $PCP_PMDAS_DIR/gluster/pmdagluster.python
+-Start python PMDA: /usr/bin/python $PCP_PMDAS_DIR/gluster/pmdagluster.python
++dbpmda> open pipe $PCP_PYTHON_PROG $PCP_PMDAS_DIR/gluster/pmdagluster.python
++Start python PMDA: $PCP_PYTHON_PROG $PCP_PMDAS_DIR/gluster/pmdagluster.python
+ dbpmda> getdesc on
+ dbpmda> desc gluster.volume.dist.count
+ PMID: 118.2.1
+@@ -39,8 +39,8 @@ pmResult ... numpmid: 1
+     inst [0 or ???] value 3
+ dbpmda> 
+ == Testing volume control metric store
+-dbpmda> open pipe /usr/bin/python $PCP_PMDAS_DIR/gluster/pmdagluster.python
+-Start python PMDA: /usr/bin/python $PCP_PMDAS_DIR/gluster/pmdagluster.python
++dbpmda> open pipe $PCP_PYTHON_PROG $PCP_PMDAS_DIR/gluster/pmdagluster.python
++Start python PMDA: $PCP_PYTHON_PROG $PCP_PMDAS_DIR/gluster/pmdagluster.python
+ dbpmda> getdesc on
+ dbpmda> desc gluster.volume.profile
+ PMID: 118.2.0
+@@ -67,15 +67,15 @@ dbpmda>
+ start gv0 - test 553
+ stop gv0 - test 553
+ == Testing brick instance domain
+-dbpmda> open pipe /usr/bin/python $PCP_PMDAS_DIR/gluster/pmdagluster.python
+-Start python PMDA: /usr/bin/python $PCP_PMDAS_DIR/gluster/pmdagluster.python
++dbpmda> open pipe $PCP_PYTHON_PROG $PCP_PMDAS_DIR/gluster/pmdagluster.python
++Start python PMDA: $PCP_PYTHON_PROG $PCP_PMDAS_DIR/gluster/pmdagluster.python
+ dbpmda> instance 118.1
+ pmInDom: 118.1
+ [  0] inst: 0 name: "smash.scott.net.au:/export/brick1/glusterdev1"
+ dbpmda> 
+ == Testing brick throughput metrics
+-dbpmda> open pipe /usr/bin/python $PCP_PMDAS_DIR/gluster/pmdagluster.python
+-Start python PMDA: /usr/bin/python $PCP_PMDAS_DIR/gluster/pmdagluster.python
++dbpmda> open pipe $PCP_PYTHON_PROG $PCP_PMDAS_DIR/gluster/pmdagluster.python
++Start python PMDA: $PCP_PYTHON_PROG $PCP_PMDAS_DIR/gluster/pmdagluster.python
+ dbpmda> getdesc on
+ dbpmda> desc gluster.brick.read_bytes
+ PMID: 118.0.0
+@@ -97,8 +97,8 @@ pmResult ... numpmid: 1
+     inst [0 or ???] value 24
+ dbpmda> 
+ == Testing brick file operation latency metrics
+-dbpmda> open pipe /usr/bin/python $PCP_PMDAS_DIR/gluster/pmdagluster.python
+-Start python PMDA: /usr/bin/python $PCP_PMDAS_DIR/gluster/pmdagluster.python
++dbpmda> open pipe $PCP_PYTHON_PROG $PCP_PMDAS_DIR/gluster/pmdagluster.python
++Start python PMDA: $PCP_PYTHON_PROG $PCP_PMDAS_DIR/gluster/pmdagluster.python
+ dbpmda> getdesc on
+ dbpmda> desc gluster.brick.latency.getxattr.avg
+ PMID: 118.1.74
+diff -Naurp pcp-3.10.2.orig/qa/718 pcp-3.10.2/qa/718
+--- pcp-3.10.2.orig/qa/718	2015-01-21 02:18:01.000000000 +1100
++++ pcp-3.10.2/qa/718	2015-02-23 21:24:36.656658340 +1100
+@@ -2,35 +2,40 @@
+ # PCP QA Test No. 718
+ # Exercise dbpmda use with the Python implementation of pmdasimple.
+ #
+-# Copyright (c) 2013 Red Hat.
++# Copyright (c) 2013,2015 Red Hat.
+ #
+ 
+ seq=`basename $0`
+ echo "QA output created by $seq"
+ 
+ . ./common.python
++
+ $python -c "from pcp import pmda" >/dev/null 2>&1
+ [ $? -eq 0 ] || _notrun "python pcp pmda module not installed"
+ test -f "$PCP_PMDAS_DIR/simple/pmdasimple.python"
+ [ $? -eq 0 ] || _notrun "python simple pmda not yet installed"
+ 
++python_path=`which $python`
+ trap "rm -f $tmp.*; exit" 0 1 2 3 15
+ 
+ _filter()
+ {
+     sed \
+ 	-e "s;$PCP_PMDAS_DIR;\$PCP_PMDAS_DIR;" \
++	-e "s;$python_path;\$PCP_PYTHON_PROG;" \
++	-e "s;$python;python;" \
+     | _filter_dumpresult
+ }
+ 
+ domain=253
++
+ # ensure help text exists
+ cd "$PCP_PMDAS_DIR/simple"
+ $sudo ./Install </dev/null >/dev/null 2>&1
+ 
+ # real QA test starts here
+ $sudo dbpmda -n root -ie <<End-of-File 2>&1 | _filter
+-open pipe $python pmdasimple.python
++open pipe $python_path pmdasimple.python
+ getdesc on
+ desc simple.numfetch
+ fetch simple.numfetch
+diff -Naurp pcp-3.10.2.orig/qa/718.out pcp-3.10.2/qa/718.out
+--- pcp-3.10.2.orig/qa/718.out	2015-01-21 02:18:01.000000000 +1100
++++ pcp-3.10.2/qa/718.out	2015-02-23 21:24:36.656658340 +1100
+@@ -1,6 +1,6 @@
+ QA output created by 718
+-dbpmda> open pipe /usr/bin/python pmdasimple.python
+-Start python PMDA: /usr/bin/python pmdasimple.python
++dbpmda> open pipe $PCP_PYTHON_PROG pmdasimple.python
++Start python PMDA: $PCP_PYTHON_PROG pmdasimple.python
+ dbpmda> getdesc on
+ dbpmda> desc simple.numfetch
+ PMID: 253.0.0
+diff -Naurp pcp-3.10.2.orig/qa/722 pcp-3.10.2/qa/722
+--- pcp-3.10.2.orig/qa/722	2015-01-21 02:18:01.000000000 +1100
++++ pcp-3.10.2/qa/722	2015-02-23 21:21:18.199838490 +1100
+@@ -2,7 +2,7 @@
+ # PCP QA Test No. 722
+ # Exercise the python pmatop implementation
+ #
+-# Copyright (c) 2013-2014 Red Hat.
++# Copyright (c) 2013-2015 Red Hat.
+ #
+ 
+ seq=`basename $0`
+@@ -68,18 +68,44 @@ if [ $? -ne 0 ]; then
+ fi
+ 
+ # real QA test starts here
+-$PMATOP -r $here/src/pmatop-log.folio -m 1 1 2>&1 | tee -a $tmp.out | redact_header | remove_extra_whitespace
+-$PMATOP -r $here/src/pmatop-log.folio -g 1 1 2>&1 | tee -a $tmp.out | redact_header | remove_extra_whitespace
++rm -f test.pmatop $tmp.folio $tmp.direct
+ 
+-rm -f test.pmatop
++# verify mkaf(1) archive folios
++echo "generic metrics mode" >> $tmp.folio
++$PMATOP -r $here/src/pmatop-log.folio -m 1 1 2>&1 | tee -a $tmp.folio | redact_header | remove_extra_whitespace
++echo "memory metrics mode" >> $tmp.folio
++$PMATOP -r $here/src/pmatop-log.folio -g 1 1 2>&1 | tee -a $tmp.folio | redact_header | remove_extra_whitespace
++cat $tmp.folio >> $here/seq.full
++echo "== Archive folio testing complete"
++
++# verify pmlogger archive logs
++echo "generic metrics mode" >> $tmp.direct
++$PMATOP -a $here/src/pmatop-log -m 1 1 2>&1 | tee -a $tmp.direct | redact_header | remove_extra_whitespace
++echo "memory metrics mode" >> $tmp.direct
++$PMATOP -a $here/src/pmatop-log -g 1 1 2>&1 | tee -a $tmp.direct | redact_header | remove_extra_whitespace
++cat $tmp.direct >> $here/seq.full
++echo "== Direct archive testing complete"
++
++echo "== Comparing direct to folio output"
++diff $tmp.folio $tmp.direct
++if [ $? -eq 0 ]; then
++    echo "  Output compares exactly - good"
++else
++    echo "  Folio differs to direct access - bad"
++fi
++echo "== Output comparisons all completed"
++
++# verify creating archive folios
+ $PMATOP -w test.pmatop 0.2 10
+ if pmafm test.pmatop  check | grep -q OK
+-then echo pmatop log creation OK | tee -a $tmp.out 2>&1
+-else echo pmatop log creation FAILED | tee -a $tmp.out 2>&1; fi
++then echo pmatop log creation OK | tee -a $tmp.write 2>&1
++else echo pmatop log creation FAILED | tee -a $tmp.write 2>&1; fi
++cat $tmp.write >> $here/seq.full
++echo "== Live writer testing complete"
+ 
+-cat $tmp.out >>$here/$seq.full
++# finished, clean up
++eval `pmafm test.pmatop remove`
+ 
+ # success, all done
+-eval `pmafm test.pmatop remove`
+ status=0
+ exit
+diff -Naurp pcp-3.10.2.orig/qa/722.out pcp-3.10.2/qa/722.out
+--- pcp-3.10.2.orig/qa/722.out	2015-01-21 02:18:01.000000000 +1100
++++ pcp-3.10.2/qa/722.out	2015-02-23 21:21:18.200838489 +1100
+@@ -447,4 +447,458 @@ PID SYSCPU USRCPU VGROW RGROW RUID THR S
+ 9 9s 9s 9 9 root 9 -- - S 9% kworker/9:9
+ 9 9s 9s 9 9 root 9 -- - S 9% kworker/9:9
+ 9 9s 9s 9K 9 root 9 -- - S 9% ssh-agent
++== Archive folio testing complete
++ATOP - Day Month 9 9:9:9 9 9:9:9 elapsed
++PRC | sys 9h9m | user 9d | #proc 9 | #zombie 9
++CPU | sys 9% | user 9% | irq 9% | idle 9% | wait 9% |
++cpu | sys 9% | user 9% | irq 9% | idle 9% | cpu9 9% |
++cpu | sys 9% | user 9% | irq 9% | idle 9% | cpu9 9% |
++cpu | sys 9% | user 9% | irq 9% | idle 9% | cpu9 9% |
++cpu | sys 9% | user 9% | irq 9% | idle 9% | cpu9 9% |
++CPL | avg9 .9 | avg9 .9 | avg9 .9 | csw 9 | intr 9 |
++MEM | tot 9G | free 9M | cache 9G | buff 9M | slab 9G |
++SWP | tot 9G | free 9G | | vmcom 9G | vmlim 9G |
++PAG | scan 9 | steal 9 | stall 9 | swin 9 | swout 9 |
++LVM | x | | read 9 | write 9 |
++LVM | x | | read 9 | write 9 |
++LVM | x | | read 9 | write 9 |
++LVM | x | | read 9 | write 9 |
++LVM | x | | read 9 | write 9 |
++DSK | sda | busy 9% | read 9 | write 9 | avio 9 ms |
++NET | transport | tcpi 9M | tcpo 9M | udpi 9M | udpo 9M |
++NET | network | ipi 9M | ipo 9M | ipfrw 9M | deliv 9M |
++NET | lo | pcki 9M | pcko 9M | si 9 Kbps | so 9 Kpbs |
++NET | em9 | pcki 9M | pcko 9M | si 9 Kbps | so 9 Kpbs |
++NET | wlan9 | pcki 9M | pcko 9M | si 9 Kbps | so 9 Kpbs |
++PID VDATA VSTACK VGROW RGROW VSIZE RSIZE MEM CMD
++9 9G 9K 9G 9M 9G 9M 9% firefox
++9 9M 9K 9G 9M 9G 9M 9% plugin-containe
++9 9K 9K 9M 9K 9M 9K 9% Xorg
++9 9G 9K 9G 9M 9G 9M 9% gnome-shell
++9 9G 9K 9G 9M 9G 9M 9% thunderbird
++9 9M 9K 9M 9K 9M 9K 9% ibus-daemon
++9 9M 9K 9M 9K 9M 9K 9% pulseaudio
++9 9K 9K 9M 9K 9M 9K 9% ibus-x9
++9 9M 9K 9M 9M 9M 9M 9% emacs
++9 9M 9K 9M 9K 9M 9K 9% xchat
++9 9M 9K 9M 9K 9M 9K 9% polkitd
++9 9M 9K 9M 9K 9M 9K 9% vino-server
++9 9M 9K 9M 9K 9M 9K 9% gnome-terminal
++9 9M 9K 9G 9K 9G 9K 9% gnome-settings-
++9 9K 9K 9K 9K 9K 9K 9% dbus-daemon
++9 9 9 9 9 9 9 9% irq/9-iwlwifi
++9 9M 9K 9M 9K 9M 9K 9% NetworkManager
++9 9K 9K 9M 9K 9M 9K 9% ibus-engine-sim
++9 9 9 9 9 9 9 9% rcu_sched
++9 9K 9K 9K 9K 9K 9K 9% cups-polld
++9 9M 9K 9M 9K 9M 9K 9% ibus-ui-gtk9
++9 9K 9K 9M 9K 9M 9K 9% cupsd
++9 9M 9K 9M 9K 9M 9K 9% nm-applet
++9 9K 9K 9K 9K 9K 9K 9% irqbalance
++9 9M 9K 9M 9K 9M 9K 9% upowerd
++9 9M 9K 9M 9K 9M 9K 9% udisksd
++9 9M 9K 9M 9K 9M 9K 9% SpiderOakBlue
++9 9M 9K 9M 9K 9M 9K 9% SpiderOakBlue
++9 9M 9K 9M 9K 9M 9K 9% mission-control
++9 9M 9K 9M 9K 9M 9K 9% evince
++9 9M 9K 9M 9K 9M 9K 9% gnome-screensav
++9 9K 9K 9K 9K 9K 9K 9% systemd-journal
++9 9K 9K 9K 9K 9K 9K 9% acpid
++9 9M 9K 9M 9K 9M 9K 9% gnome-session
++9 9 9 9 9 9 9 9% khugepaged
++9 9K 9K 9K 9K 9K 9K 9% wpa_supplicant
++9 9K 9K 9K 9 9K 9 9% gpm
++9 9 9 9 9 9 9 9% flush-9:9
++9 9M 9K 9M 9K 9M 9K 9% deja-dup-monito
++9 9M 9K 9M 9K 9M 9K 9% evolution-calen
++9 9M 9K 9M 9K 9M 9K 9% evolution-addre
++9 9 9 9 9 9 9 9% jbd9/dm-9-9
++9 9 9 9 9 9 9 9% ksoftirqd/9
++9 9M 9K 9M 9K 9M 9K 9% tracker-miner-f
++9 9K 9K 9K 9K 9K 9K 9% systemd-logind
++9 9K 9K 9M 9K 9M 9K 9% crond
++9 9 9 9 9 9 9 9% kswapd9
++9 9K 9K 9K 9K 9K 9K 9% systemd
++9 9 9 9 9 9 9 9% kworker/9:9
++9 9M 9K 9M 9K 9M 9K 9% rtkit-daemon
++9 9 9 9 9 9 9 9% ksoftirqd/9
++9 9 9 9 9 9 9 9% ksoftirqd/9
++9 9 9 9 9 9 9 9% flush-9:9
++9 9 9 9 9 9 9 9% jbd9/dm-9-9
++9 9K 9K 9M 9K 9M 9K 9% bash
++9 9 9 9 9 9 9 9% ksoftirqd/9
++9 9K 9K 9K 9K 9K 9K 9% pmie
++9 9M 9K 9M 9K 9M 9K 9% gvfs-udisks9-vo
++9 9M 9K 9M 9K 9M 9K 9% accounts-daemon
++9 9M 9K 9M 9K 9M 9K 9% gdm-session-wor
++9 9M 9K 9M 9K 9M 9K 9% rsyslogd
++9 9M 9K 9M 9K 9M 9K 9% gnote
++9 9K 9K 9K 9K 9K 9K 9% dbus-daemon
++9 9 9 9 9 9 9 9% migration/9
++9 9K 9K 9K 9K 9K 9K 9% pmdaproc
++9 9K 9K 9M 9K 9M 9K 9% bash
++9 9 9 9 9 9 9 9% migration/9
++9 9K 9K 9K 9K 9K 9K 9% auditd
++9 9K 9K 9M 9K 9M 9K 9% bash
++9 9K 9K 9M 9K 9M 9K 9% abrt-watch-log
++9 9M 9K 9M 9K 9M 9K 9% evolution-alarm
++9 9K 9K 9K 9K 9K 9K 9% dhclient
++9 9 9 9 9 9 9 9% kworker/9:9
++9 9 9 9 9 9 9 9% watchdog/9
++9 9M 9K 9M 9K 9M 9K 9% gnome-shell-cal
++9 9 9 9 9 9 9 9% watchdog/9
++9 9K 9K 9M 9K 9M 9K 9% abrt-applet
++9 9 9 9 9 9 9 9% watchdog/9
++9 9 9 9 9 9 9 9% watchdog/9
++9 9 9 9 9 9 9 9% migration/9
++9 9K 9K 9M 9K 9M 9K 9% modem-manager
++9 9 9 9 9 9 9 9% kworker/9:9
++9 9 9 9 9 9 9 9% kworker/9:9H
++9 9K 9K 9M 9K 9M 9K 9% gdm-binary
++9 9M 9K 9M 9K 9M 9K 9% colord
++9 9 9 9 9 9 9 9% migration/9
++9 9K 9K 9K 9K 9K 9K 9% avahi-daemon
++9 9 9 9 9 9 9 9% kworker/9:9
++9 9M 9K 9M 9K 9M 9K 9% tracker-store
++9 9K 9K 9K 9K 9K 9K 9% rpcbind
++9 9K 9K 9K 9K 9K 9K 9% chronyd
++9 9K 9K 9M 9K 9M 9K 9% pmcd
++9 9 9 9 9 9 9 9% kauditd
++9 9K 9K 9K 9K 9K 9K 9% dhclient
++9 9K 9K 9K 9K 9K 9K 9% udevd
++9 9K 9K 9M 9K 9M 9K 9% bash
++9 9 9 9 9 9 9 9% kworker/u:9
++9 9 9 9 9 9 9 9% kthreadd
++9 9M 9K 9M 9K 9M 9K 9% gnome-keyring-d
++9 9K 9K 9M 9K 9M 9K 9% bash
++9 9 9 9 9 9 9 9% jbd9/dm-9-9
++9 9 9 9 9 9 9 9% kworker/9:9H
++9 9M 9K 9M 9K 9M 9K 9% gsd-printer
++9 9K 9K 9K 9K 9K 9K 9% smartd
++9 9K 9K 9M 9K 9M 9K 9% gvfsd
++9 9M 9K 9M 9K 9M 9K 9% colord-sane
++9 9K 9K 9M 9K 9M 9K 9% gvfsd-trash
++9 9K 9K 9M 9K 9M 9K 9% pmatop.py
++9 9K 9K 9M 9K 9M 9K 9% abrtd
++9 9M 9K 9M 9K 9M 9K 9% dconf-service
++9 9 9 9 9 9 9 9% kworker/u:9
++9 9 9 9 9 9 9 9% bdi-default
++9 9 9 9 9 9 9 9% kworker/u:9
++9 9 9 9 9 9 9 9% khubd
++9 9 9 9 9 9 9 9% kworker/9:9H
++9 9K 9K 9K 9K 9K 9K 9% atd
++9 9K 9K 9M 9K 9M 9K 9% gvfsd-metadata
++9 9K 9K 9K 9K 9K 9K 9% udevd
++9 9K 9K 9K 9K 9K 9K 9% bluetoothd
++9 9M 9K 9M 9K 9M 9K 9% imsettings-daem
++9 9K 9K 9M 9K 9M 9K 9% abrt-watch-log
++9 9K 9K 9K 9K 9K 9K 9% rpc.statd
++9 9K 9K 9K 9K 9K 9K 9% pmlogger
++9 9 9 9 9 9 9 9% fsnotify_mark
++9 9K 9K 9M 9K 9M 9K 9% gdm-simple-slav
++9 9K 9K 9M 9K 9M 9K 9% gvfs-gphoto9-vo
++9 9 9 9 9 9 9 9% kdevtmpfs
++9 9K 9K 9M 9K 9M 9K 9% ibus-dconf
++9 9M 9K 9M 9K 9M 9K 9% gvfsd-http
++9 9K 9K 9K 9K 9K 9K 9% pmlogger
++9 9 9 9 9 9 9 9% kworker/9:9H
++9 9K 9K 9K 9K 9K 9K 9% sshd
++9 9K 9K 9M 9K 9M 9K 9% gconfd-9
++9 9M 9K 9M 9K 9M 9K 9% goa-daemon
++9 9K 9K 9M 9K 9M 9K 9% ibus-engine-pin
++9 9M 9K 9M 9K 9M 9K 9% evinced
++9 9 9 9 9 9 9 9% kworker/9:9H
++9 9 9 9 9 9 9 9% rcu_bh
++9 9 9 9 9 9 9 9% kworker/9:9H
++9 9 9 9 9 9 9 9% kworker/9:9H
++9 9 9 9 9 9 9 9% kworker/9:9H
++9 9 9 9 9 9 9 9% khelper
++9 9 9 9 9 9 9 9% netns
++9 9 9 9 9 9 9 9% kintegrityd
++9 9 9 9 9 9 9 9% kblockd
++9 9 9 9 9 9 9 9% ata_sff
++9 9 9 9 9 9 9 9% md
++9 9 9 9 9 9 9 9% ksmd
++9 9 9 9 9 9 9 9% crypto
++9 9 9 9 9 9 9 9% kthrotld
++9 9 9 9 9 9 9 9% scsi_eh_9
++9 9 9 9 9 9 9 9% scsi_eh_9
++9 9 9 9 9 9 9 9% scsi_eh_9
++9 9 9 9 9 9 9 9% scsi_eh_9
++9 9 9 9 9 9 9 9% scsi_eh_9
++9 9 9 9 9 9 9 9% scsi_eh_9
++9 9 9 9 9 9 9 9% kpsmoused
++9 9 9 9 9 9 9 9% deferwq
++9 9 9 9 9 9 9 9% kdmflush
++9 9 9 9 9 9 9 9% kdmflush
++9 9K 9K 9M 9K 9M 9K 9% gvfsd-burn
++9 9 9 9 9 9 9 9% ext9-dio-unwrit
++9 9 9 9 9 9 9 9% kvm-irqfd-clean
++9 9 9 9 9 9 9 9% ktpacpid
++9 9 9 9 9 9 9 9% hd-audio9
++9 9 9 9 9 9 9 9% cfg9
++9 9 9 9 9 9 9 9% kdmflush
++9 9 9 9 9 9 9 9% kdmflush
++9 9 9 9 9 9 9 9% kdmflush
++9 9 9 9 9 9 9 9% iwlwifi
++9 9 9 9 9 9 9 9% jbd9/dm-9-9
++9 9 9 9 9 9 9 9% ext9-dio-unwrit
++9 9 9 9 9 9 9 9% ext9-dio-unwrit
++9 9 9 9 9 9 9 9% ext9-dio-unwrit
++9 9K 9K 9K 9K 9K 9K 9% avahi-daemon
++9 9K 9K 9K 9 9K 9 9% system-setup-ke
++9 9K 9K 9K 9K 9K 9K 9% mcelog
++9 9 9 9 9 9 9 9% krfcommd
++9 9 9 9 9 9 9 9% rpciod
++9 9K 9K 9K 9K 9K 9K 9% dbus-launch
++9 9M 9K 9M 9K 9M 9K 9% gvfs-fuse-daemo
++9 9K 9K 9M 9K 9M 9K 9% gvfs-afc-volume
++9 9M 9K 9M 9K 9M 9K 9% at-spi-bus-laun
++9 9K 9K 9K 9K 9K 9K 9% gnome-pty-helpe
++9 9K 9K 9K 9K 9K 9K 9% emacsclient
++9 9K 9K 9M 9K 9M 9K 9% tools.sh
++9 9 9 9 9 9 9 9% kworker/9:9
++9 9 9 9 9 9 9 9% kworker/9:9
++9 9 9 9 9 9 9 9% kworker/u:9H
++9 9K 9K 9K 9K 9K 9K 9% emacsclient
++9 9K 9K 9K 9K 9K 9K 9% emacsclient
++9 9 9 9 9 9 9 9% irq/9-mei
++9 9 9 9 9 9 9 9% hci9
++9 9 9 9 9 9 9 9% hci9
++9 9 9 9 9 9 9 9% kworker/u:9H
++9 9K 9K 9K 9K 9K 9K 9% udevd
++9 9K 9K 9K 9K 9K 9K 9% pmdaxfs
++9 9 9 9 9 9 9 9% kworker/9:9
++9 9 9 9 9 9 9 9% kworker/9:9
++9 9 9 9 9 9 9 9% kworker/9:9
++9 9K 9K 9K 9K 9K 9K 9% ssh-agent
++ATOP - Day Month 9 9:9:9 9 9:9:9 elapsed
++PRC | sys 9h9m | user 9d | #proc 9 | #zombie 9
++CPU | sys 9% | user 9% | irq 9% | idle 9% | wait 9% |
++cpu | sys 9% | user 9% | irq 9% | idle 9% | cpu9 9% |
++cpu | sys 9% | user 9% | irq 9% | idle 9% | cpu9 9% |
++cpu | sys 9% | user 9% | irq 9% | idle 9% | cpu9 9% |
++cpu | sys 9% | user 9% | irq 9% | idle 9% | cpu9 9% |
++CPL | avg9 .9 | avg9 .9 | avg9 .9 | csw 9 | intr 9 |
++MEM | tot 9G | free 9M | cache 9G | buff 9M | slab 9G |
++SWP | tot 9G | free 9G | | vmcom 9G | vmlim 9G |
++PAG | scan 9 | steal 9 | stall 9 | swin 9 | swout 9 |
++LVM | x | | read 9 | write 9 |
++LVM | x | | read 9 | write 9 |
++LVM | x | | read 9 | write 9 |
++LVM | x | | read 9 | write 9 |
++LVM | x | | read 9 | write 9 |
++DSK | sda | busy 9% | read 9 | write 9 | avio 9 ms |
++NET | transport | tcpi 9M | tcpo 9M | udpi 9M | udpo 9M |
++NET | network | ipi 9M | ipo 9M | ipfrw 9M | deliv 9M |
++NET | lo | pcki 9M | pcko 9M | si 9 Kbps | so 9 Kpbs |
++NET | em9 | pcki 9M | pcko 9M | si 9 Kbps | so 9 Kpbs |
++NET | wlan9 | pcki 9M | pcko 9M | si 9 Kbps | so 9 Kpbs |
++PID SYSCPU USRCPU VGROW RGROW RUID THR ST EXC S CPU CMD
++9 9h9m 9h9m 9K 9K scox 9 -- - S 9% firefox
++9 9h9m 9h9m 9K 9K scox 9 -- - S 9% plugin-containe
++9 9h9m 9h9m 9K 9K root 9 -- - S 9% Xorg
++9 9m9s 9h9m 9K 9K scox 9 -- - S 9% gnome-shell
++9 9m9s 9h9m 9K 9K scox 9 -- - S 9% thunderbird
++9 9m9s 9m9s 9K 9K scox 9 -- - S 9% ibus-daemon
++9 9m9s 9m9s 9K 9K scox 9 -- - S 9% pulseaudio
++9 9m9s 9m9s 9K 9K scox 9 -- - S 9% ibus-x9
++9 9m9s 9m9s 9K 9K scox 9 -- - S 9% emacs
++9 9m9s 9m9s 9K 9K scox 9 -- - S 9% xchat
++9 9m9s 9m9s 9K 9K root 9 -- - S 9% polkitd
++9 9m9s 9m9s 9K 9K scox 9 -- - S 9% vino-server
++9 9m9s 9m9s 9K 9K scox 9 -- - S 9% gnome-terminal
++9 9m9s 9m9s 9K 9K scox 9 -- - S 9% gnome-settings-
++9 9m9s 9m9s 9K 9K dbus 9 -- - S 9% dbus-daemon
++9 9m9s 9s 9 9 root 9 -- - S 9% irq/9-iwlwifi
++9 9s 9m9s 9K 9K root 9 -- - S 9% NetworkManager
++9 9s 9m9s 9K 9K scox 9 -- - S 9% ibus-engine-sim
++9 9m9s 9s 9 9 root 9 -- - S 9% rcu_sched
++9 9m9s 9m9s 9K 9K lp 9 -- - S 9% cups-polld
++9 9s 9m9s 9K 9K scox 9 -- - S 9% ibus-ui-gtk9
++9 9s 9m9s 9K 9K root 9 -- - S 9% cupsd
++9 9s 9m9s 9K 9K scox 9 -- - S 9% nm-applet
++9 9m9s 9s 9K 9 root 9 -- - S 9% irqbalance
++9 9s 9m9s 9K 9K root 9 -- - S 9% upowerd
++9 9s 9m9s 9K 9K root 9 -- - S 9% udisksd
++9 9s 9m9s 9K 9K scox 9 -- - S 9% SpiderOakBlue
++9 9s 9s 9K 9K scox 9 -- - S 9% SpiderOakBlue
++9 9s 9s 9K 9K scox 9 -- - S 9% mission-control
++9 9s 9s 9K 9K scox 9 -- - S 9% evince
++9 9s 9s 9K 9K scox 9 -- - S 9% gnome-screensav
++9 9s 9s 9K 9 root 9 -- - S 9% systemd-journal
++9 9s 9s 9K 9 root 9 -- - S 9% acpid
++9 9s 9s 9K 9K scox 9 -- - S 9% gnome-session
++9 9s 9s 9 9 root 9 -- - S 9% khugepaged
++9 9s 9s 9K 9K root 9 -- - S 9% wpa_supplicant
++9 9s 9s 9K 9 root 9 -- - S 9% gpm
++9 9s 9s 9 9 root 9 -- - S 9% flush-9:9
++9 9s 9s 9K 9K scox 9 -- - S 9% deja-dup-monito
++9 9s 9s 9K 9K scox 9 -- - S 9% evolution-calen
++9 9s 9s 9K 9K scox 9 -- - S 9% evolution-addre
++9 9s 9s 9 9 root 9 -- - D 9% jbd9/dm-9-9
++9 9s 9s 9 9 root 9 -- - S 9% ksoftirqd/9
++9 9s 9s 9K 9K scox 9 -- - S 9% tracker-miner-f
++9 9s 9s 9K 9K root 9 -- - S 9% systemd-logind
++9 9s 9s 9K 9 root 9 -- - S 9% crond
++9 9s 9s 9 9 root 9 -- - S 9% kswapd9
++9 9s 9s 9K 9K root 9 -- - S 9% systemd
++9 9s 9s 9 9 root 9 -- - S 9% kworker/9:9
++9 9s 9s 9K 9 rtkit 9 -- - S 9% rtkit-daemon
++9 9s 9s 9 9 root 9 -- - S 9% ksoftirqd/9
++9 9s 9s 9 9 root 9 -- - S 9% ksoftirqd/9
++9 9s 9s 9 9 root 9 -- - S 9% flush-9:9
++9 9s 9s 9 9 root 9 -- - S 9% jbd9/dm-9-9
++9 9s 9s 9K 9K scox 9 -- - S 9% bash
++9 9s 9s 9 9 root 9 -- - S 9% ksoftirqd/9
++9 9s 9s 9K 9K pcp 9 -- - S 9% pmie
++9 9s 9s 9K 9K scox 9 -- - S 9% gvfs-udisks9-vo
++9 9s 9s 9K 9K root 9 -- - S 9% accounts-daemon
++9 9s 9s 9K 9K root 9 -- - S 9% gdm-session-wor
++9 9s 9s 9K 9K root 9 -- - S 9% rsyslogd
++9 9s 9s 9K 9K scox 9 -- - S 9% gnote
++9 9s 9s 9K 9K scox 9 -- - S 9% dbus-daemon
++9 9s 9s 9 9 root 9 -- - S 9% migration/9
++9 9s 9s 9K 9K root 9 -- - R 9% pmdaproc
++9 9s 9s 9K 9K scox 9 -- - S 9% bash
++9 9s 9s 9 9 root 9 -- - S 9% migration/9
++9 9s 9s 9K 9 root 9 -- - S 9% auditd
++9 9s 9s 9K 9K scox 9 -- - S 9% bash
++9 9s 9s 9K 9 root 9 -- - S 9% abrt-watch-log
++9 9s 9s 9K 9K scox 9 -- - S 9% evolution-alarm
++9 9s 9s 9K 9K root 9 -- - S 9% dhclient
++9 9s 9s 9 9 root 9 -- - S 9% kworker/9:9
++9 9s 9s 9 9 root 9 -- - S 9% watchdog/9
++9 9s 9s 9K 9K scox 9 -- - S 9% gnome-shell-cal
++9 9s 9s 9 9 root 9 -- - S 9% watchdog/9
++9 9s 9s 9K 9K scox 9 -- - S 9% abrt-applet
++9 9s 9s 9 9 root 9 -- - S 9% watchdog/9
++9 9s 9s 9 9 root 9 -- - S 9% watchdog/9
++9 9s 9s 9 9 root 9 -- - S 9% migration/9
++9 9s 9s 9K 9K root 9 -- - S 9% modem-manager
++9 9s 9s 9 9 root 9 -- - S 9% kworker/9:9
++9 9s 9s 9 9 root 9 -- - S 9% kworker/9:9H
++9 9s 9s 9K 9 root 9 -- - S 9% gdm-binary
++9 9s 9s 9K 9K colord 9 -- - S 9% colord
++9 9s 9s 9 9 root 9 -- - S 9% migration/9
++9 9s 9s 9K 9 avahi 9 -- - S 9% avahi-daemon
++9 9s 9s 9 9 root 9 -- - S 9% kworker/9:9
++9 9s 9s 9K 9K scox 9 -- - S 9% tracker-store
++9 9s 9s 9K 9 rpc 9 -- - S 9% rpcbind
++9 9s 9s 9K 9 chrony 9 -- - S 9% chronyd
++9 9s 9s 9K 9K pcp 9 -- - S 9% pmcd
++9 9s 9s 9 9 root 9 -- - S 9% kauditd
++9 9s 9s 9K 9K root 9 -- - S 9% dhclient
++9 9s 9s 9K 9 root 9 -- - S 9% udevd
++9 9s 9s 9K 9K scox 9 -- - S 9% bash
++9 9s 9s 9 9 root 9 -- - S 9% kworker/u:9
++9 9s 9s 9 9 root 9 -- - S 9% kthreadd
++9 9s 9s 9K 9K scox 9 -- - S 9% gnome-keyring-d
++9 9s 9s 9K 9K scox 9 -- - S 9% bash
++9 9s 9s 9 9 root 9 -- - S 9% jbd9/dm-9-9
++9 9s 9s 9 9 root 9 -- - S 9% kworker/9:9H
++9 9s 9s 9K 9K scox 9 -- - S 9% gsd-printer
++9 9s 9s 9K 9 root 9 -- - S 9% smartd
++9 9s 9s 9K 9 scox 9 -- - S 9% gvfsd
++9 9s 9s 9K 9 colord 9 -- - S 9% colord-sane
++9 9s 9s 9K 9K scox 9 -- - S 9% gvfsd-trash
++9 9s 9s 9K 9K scox 9 -- - S 9% pmatop.py
++9 9s 9s 9K 9 root 9 -- - S 9% abrtd
++9 9s 9s 9K 9K scox 9 -- - S 9% dconf-service
++9 9s 9s 9 9 root 9 -- - S 9% kworker/u:9
++9 9s 9s 9 9 root 9 -- - S 9% bdi-default
++9 9s 9s 9 9 root 9 -- - S 9% kworker/u:9
++9 9s 9s 9 9 root 9 -- - S 9% khubd
++9 9s 9s 9 9 root 9 -- - S 9% kworker/9:9H
++9 9s 9s 9K 9 root 9 -- - S 9% atd
++9 9s 9s 9K 9K scox 9 -- - S 9% gvfsd-metadata
++9 9s 9s 9K 9K root 9 -- - S 9% udevd
++9 9s 9s 9K 9K root 9 -- - S 9% bluetoothd
++9 9s 9s 9K 9 scox 9 -- - S 9% imsettings-daem
++9 9s 9s 9K 9 root 9 -- - S 9% abrt-watch-log
++9 9s 9s 9K 9 rpcuse 9 -- - S 9% rpc.statd
++9 9s 9s 9K 9K scox 9 -- - S 9% pmlogger
++9 9s 9s 9 9 root 9 -- - S 9% fsnotify_mark
++9 9s 9s 9K 9 root 9 -- - S 9% gdm-simple-slav
++9 9s 9s 9K 9 scox 9 -- - S 9% gvfs-gphoto9-vo
++9 9s 9s 9 9 root 9 -- - S 9% kdevtmpfs
++9 9s 9s 9K 9K scox 9 -- - S 9% ibus-dconf
++9 9s 9s 9K 9K scox 9 -- - S 9% gvfsd-http
++9 9s 9s 9K 9K pcp 9 -- - S 9% pmlogger
++9 9s 9s 9 9 root 9 -- - S 9% kworker/9:9H
++9 9s 9s 9K 9 root 9 -- - S 9% sshd
++9 9s 9s 9K 9 scox 9 -- - S 9% gconfd-9
++9 9s 9s 9K 9K scox 9 -- - S 9% goa-daemon
++9 9s 9s 9K 9 scox 9 -- - S 9% ibus-engine-pin
++9 9s 9s 9K 9K scox 9 -- - S 9% evinced
++9 9s 9s 9 9 root 9 -- - S 9% kworker/9:9H
++9 9s 9s 9 9 root 9 -- - S 9% rcu_bh
++9 9s 9s 9 9 root 9 -- - S 9% kworker/9:9H
++9 9s 9s 9 9 root 9 -- - S 9% kworker/9:9H
++9 9s 9s 9 9 root 9 -- - S 9% kworker/9:9H
++9 9s 9s 9 9 root 9 -- - S 9% khelper
++9 9s 9s 9 9 root 9 -- - S 9% netns
++9 9s 9s 9 9 root 9 -- - S 9% kintegrityd
++9 9s 9s 9 9 root 9 -- - S 9% kblockd
++9 9s 9s 9 9 root 9 -- - S 9% ata_sff
++9 9s 9s 9 9 root 9 -- - S 9% md
++9 9s 9s 9 9 root 9 -- - S 9% ksmd
++9 9s 9s 9 9 root 9 -- - S 9% crypto
++9 9s 9s 9 9 root 9 -- - S 9% kthrotld
++9 9s 9s 9 9 root 9 -- - S 9% scsi_eh_9
++9 9s 9s 9 9 root 9 -- - S 9% scsi_eh_9
++9 9s 9s 9 9 root 9 -- - S 9% scsi_eh_9
++9 9s 9s 9 9 root 9 -- - S 9% scsi_eh_9
++9 9s 9s 9 9 root 9 -- - S 9% scsi_eh_9
++9 9s 9s 9 9 root 9 -- - S 9% scsi_eh_9
++9 9s 9s 9 9 root 9 -- - S 9% kpsmoused
++9 9s 9s 9 9 root 9 -- - S 9% deferwq
++9 9s 9s 9 9 root 9 -- - S 9% kdmflush
++9 9s 9s 9 9 root 9 -- - S 9% kdmflush
++9 9s 9s 9K 9 scox 9 -- - S 9% gvfsd-burn
++9 9s 9s 9 9 root 9 -- - S 9% ext9-dio-unwrit
++9 9s 9s 9 9 root 9 -- - S 9% kvm-irqfd-clean
++9 9s 9s 9 9 root 9 -- - S 9% ktpacpid
++9 9s 9s 9 9 root 9 -- - S 9% hd-audio9
++9 9s 9s 9 9 root 9 -- - S 9% cfg9
++9 9s 9s 9 9 root 9 -- - S 9% kdmflush
++9 9s 9s 9 9 root 9 -- - S 9% kdmflush
++9 9s 9s 9 9 root 9 -- - S 9% kdmflush
++9 9s 9s 9 9 root 9 -- - S 9% iwlwifi
++9 9s 9s 9 9 root 9 -- - S 9% jbd9/dm-9-9
++9 9s 9s 9 9 root 9 -- - S 9% ext9-dio-unwrit
++9 9s 9s 9 9 root 9 -- - S 9% ext9-dio-unwrit
++9 9s 9s 9 9 root 9 -- - S 9% ext9-dio-unwrit
++9 9s 9s 9K 9 avahi 9 -- - S 9% avahi-daemon
++9 9s 9s 9K 9 root 9 -- - S 9% system-setup-ke
++9 9s 9s 9K 9 root 9 -- - S 9% mcelog
++9 9s 9s 9 9 root 9 -- - S 9% krfcommd
++9 9s 9s 9 9 root 9 -- - S 9% rpciod
++9 9s 9s 9K 9 scox 9 -- - S 9% dbus-launch
++9 9s 9s 9K 9 scox 9 -- - S 9% gvfs-fuse-daemo
++9 9s 9s 9K 9 scox 9 -- - S 9% gvfs-afc-volume
++9 9s 9s 9K 9 scox 9 -- - S 9% at-spi-bus-laun
++9 9s 9s 9K 9 scox 9 -- - S 9% gnome-pty-helpe
++9 9s 9s 9K 9 scox 9 -- - S 9% emacsclient
++9 9s 9s 9K 9 scox 9 -- - S 9% tools.sh
++9 9s 9s 9 9 root 9 -- - S 9% kworker/9:9
++9 9s 9s 9 9 root 9 -- - S 9% kworker/9:9
++9 9s 9s 9 9 root 9 -- - S 9% kworker/u:9H
++9 9s 9s 9K 9 scox 9 -- - T 9% emacsclient
++9 9s 9s 9K 9 scox 9 -- - T 9% emacsclient
++9 9s 9s 9 9 root 9 -- - S 9% irq/9-mei
++9 9s 9s 9 9 root 9 -- - S 9% hci9
++9 9s 9s 9 9 root 9 -- - S 9% hci9
++9 9s 9s 9 9 root 9 -- - S 9% kworker/u:9H
++9 9s 9s 9K 9K root 9 -- - S 9% udevd
++9 9s 9s 9K 9K root 9 -- - S 9% pmdaxfs
++9 9s 9s 9 9 root 9 -- - S 9% kworker/9:9
++9 9s 9s 9 9 root 9 -- - S 9% kworker/9:9
++9 9s 9s 9 9 root 9 -- - S 9% kworker/9:9
++9 9s 9s 9K 9 root 9 -- - S 9% ssh-agent
++== Direct archive testing complete
++== Comparing direct to folio output
++  Output compares exactly - good
++== Output comparisons all completed
+ pmatop log creation OK
++== Live writer testing complete
+diff -Naurp pcp-3.10.2.orig/qa/729 pcp-3.10.2/qa/729
+--- pcp-3.10.2.orig/qa/729	2015-01-21 02:18:01.000000000 +1100
++++ pcp-3.10.2/qa/729	2015-02-23 21:24:36.657658339 +1100
+@@ -24,7 +24,7 @@ fname = 'src/bug_v2'
+ context = pcp.pmapi.pmContext(c_api.PM_CONTEXT_ARCHIVE, fname)
+ pmids = context.pmLookupName(['proc.nprocs'])
+ descs = context.pmLookupDescs(pmids[0])
+-print '%s%s' % (descs[0].contents.units, 'Completed safely')
++print('%s%s' % (descs[0].contents.units, 'Completed safely'))
+ EOF
+ 
+ cat > $tmp.parse << EOF
+@@ -32,8 +32,8 @@ import pcp.pmapi
+ context = pcp.pmapi.pmContext(target='local:')
+ try:
+   print(context.pmParseInterval(''))
+-except pcp.pmapi.pmErr, error:
+-  print 'Completed safely'
++except pcp.pmapi.pmErr as error:
++  print('Completed safely')
+ EOF
+ 
+ # real QA test starts here
+diff -Naurp pcp-3.10.2.orig/qa/754 pcp-3.10.2/qa/754
+--- pcp-3.10.2.orig/qa/754	2015-01-24 07:23:07.000000000 +1100
++++ pcp-3.10.2/qa/754	2015-02-23 21:24:36.657658339 +1100
+@@ -2,7 +2,7 @@
+ # PCP QA Test No. 754
+ # Exercise the Unbound PMDA.
+ #
+-# Copyright (c) 2014 Red Hat.
++# Copyright (c) 2014-2015 Red Hat.
+ #
+ 
+ seq=`basename $0`
+@@ -10,6 +10,7 @@ echo "QA output created by $seq"
+ 
+ . ./common.python
+ 
++python_path=`which $python`
+ pmda_path="$PCP_PMDAS_DIR/unbound"
+ pmda_script="$pmda_path/pmdaunbound.python"
+ test -f "$pmda_script" || _notrun "pmdaunbound not supported"
+@@ -31,12 +32,12 @@ _filter()
+ {
+     tee -a $seq.full | \
+     sed \
+-	-e "s;$python;\$PYTHON;" \
+ 	-e "s;$PCP_PMDAS_DIR;\$PCP_PMDAS_DIR;" \
+ 	-e '/pmResult/s/ .* numpmid/ ... numpmid/' \
+ 	-e '/[0-9][0-9]:[0-9][0-9]:[0-9][0-9]/s/[^ ]*/TIMESTAMP/' \
+-
+-    test -f unbound.log && cat unbound.log >> $seq.full
++	-e "s;$python_path;\$PCP_PYTHON_PROG;" \
++	-e "s;$python;python;" \
++    #end
+ }
+ 
+ _filter_result()
+@@ -46,7 +47,7 @@ _filter_result()
+ 
+ domain=132
+ test="$here/unbound"
+-$sudo rm -f /tmp/unbound-qa.txt		# from test.sh
++$sudo rm -f unbound.log /tmp/unbound-qa.txt	 # the latter from test.sh
+ export UNBOUND_STATS="$here/unbound/test.sh"
+ 
+ # real QA test starts here
+@@ -54,7 +55,7 @@ PCP_PYTHON_PMNS=root $python "$pmda_scri
+ 
+ echo "== Testing unbound metric values" | tee -a $seq.full
+ cat > $tmp.fetch <<End-of-File
+-open pipe $python $pmda_script
++open pipe $python_path $pmda_script
+ getdesc on
+ End-of-File
+ cat $here/unbound/metrics.list | \
+@@ -62,7 +63,8 @@ while read metric
+ do
+     echo fetch $metric >> $tmp.fetch
+ done
+-$sudo dbpmda -n $tmp.root -ie < $tmp.fetch 2>&1 | _filter
++dbpmda -n $tmp.root -ie < $tmp.fetch 2>&1 | _filter
++test -f unbound.log && cat unbound.log >> $seq.full
+ 
+ status=0
+ exit
+diff -Naurp pcp-3.10.2.orig/qa/754.out pcp-3.10.2/qa/754.out
+--- pcp-3.10.2.orig/qa/754.out	2015-01-24 07:23:07.000000000 +1100
++++ pcp-3.10.2/qa/754.out	2015-02-23 21:24:36.658658338 +1100
+@@ -1,7 +1,7 @@
+ QA output created by 754
+ == Testing unbound metric values
+-dbpmda> open pipe $PYTHON $PCP_PMDAS_DIR/unbound/pmdaunbound.python
+-Start python PMDA: $PYTHON $PCP_PMDAS_DIR/unbound/pmdaunbound.python
++dbpmda> open pipe $PCP_PYTHON_PROG $PCP_PMDAS_DIR/unbound/pmdaunbound.python
++Start python PMDA: $PCP_PYTHON_PROG $PCP_PMDAS_DIR/unbound/pmdaunbound.python
+ dbpmda> getdesc on
+ dbpmda> fetch unbound.histogram.262144_000000_to_524288_000000
+ PMID(s): 132.0.139
+diff -Naurp pcp-3.10.2.orig/qa/972 pcp-3.10.2/qa/972
+--- pcp-3.10.2.orig/qa/972	2015-01-21 02:18:01.000000000 +1100
++++ pcp-3.10.2/qa/972	2015-02-23 21:24:36.658658338 +1100
+@@ -2,28 +2,20 @@
+ # PCP QA Test No. 972
+ # Exercise the zswap compressed swap PMDA using dbpmda.
+ #
+-# Copyright (c) 2014 Red Hat.
++# Copyright (c) 2014-2015 Red Hat.
+ #
+ 
+ seq=`basename $0`
+ echo "QA output created by $seq"
+ 
+-# get standard environment, filters and checks
+-. ./common.product
+-. ./common.filter
+-. ./common.check
++. ./common.python
+ 
++python_path=`which $python`
+ pmda_path="$PCP_PMDAS_DIR/zswap"
+ pmda_script="$pmda_path/pmdazswap.python"
+ test -f "$pmda_script" || _notrun "pmdazswap not supported"
+-python -c "from pcp import pmda" >/dev/null 2>&1
++$python -c "from pcp import pmda" >/dev/null 2>&1
+ [ $? -eq 0 ] || _notrun "python pcp pmda module not installed"
+-case `python -V 2>&1 | sed -e 's/Python //'`
+-in
+-    0.*.*|1.*.*|2.0.*|2.1.*|2.3.*|2.4.*)
+-	_notrun "need python 2.5 or later"
+-	;;
+-esac
+ 
+ status=1	# failure is the default!
+ $sudo rm -rf $tmp.* $seq.full
+@@ -34,10 +26,12 @@ _filter()
+     tee -a $seq.full | \
+     sed \
+ 	-e "s;$PCP_PMDAS_DIR;\$PCP_PMDAS_DIR;" \
++	-e "s;$PCP_PMDAS_DIR;\$PCP_PMDAS_DIR;" \
+         -e '/pmResult/s/ .* numpmid/ ... numpmid/' \
+         -e '/[0-9][0-9]:[0-9][0-9]:[0-9][0-9]/s/[^ ]*/TIMESTAMP/' \
+-
+-    test -f zswap.log && cat zswap.log >> $seq.full
++	-e "s;$python_path;\$PCP_PYTHON_PROG;" \
++	-e "s;$python;python;" \
++    #end
+ }
+ 
+ _setup_zswap_values()
+@@ -54,6 +48,8 @@ _setup_zswap_values()
+     echo 2     > reject_reclaim_fail
+     echo 89123 > stored_pages
+     echo 12435 > written_back_pages
++
++    cd $here
+ }
+ 
+ domain=125
+@@ -62,11 +58,11 @@ export ZSWAP_STATS_PATH="$tmp.zswap"
+ 
+ # real QA test starts here
+ _setup_zswap_values
+-PCP_PYTHON_PMNS=root python "$pmda_script" > $tmp.root
++PCP_PYTHON_PMNS=root $python "$pmda_script" > $tmp.root
+ 
+ echo "== Testing zswap metrics" | tee -a $seq.full
+-$sudo dbpmda -n $tmp.root -ie <<End-of-File 2>&1 | _filter
+-open pipe /usr/bin/python $pmda_script
++dbpmda -n $tmp.root -ie <<End-of-File 2>&1 | _filter
++open pipe $python_path $pmda_script
+ getdesc on
+ desc zswap.pool_limit_hit
+ desc zswap.reject_reclaim_fail
+@@ -87,6 +83,7 @@ fetch zswap.duplicate_entry
+ fetch zswap.pool_pages
+ fetch zswap.stored_pages
+ End-of-File
++test -f zswap.log && cat zswap.log >> $seq.full
+ 
+ status=0
+ exit
+diff -Naurp pcp-3.10.2.orig/qa/972.out pcp-3.10.2/qa/972.out
+--- pcp-3.10.2.orig/qa/972.out	2015-01-21 02:18:01.000000000 +1100
++++ pcp-3.10.2/qa/972.out	2015-02-23 21:24:36.658658338 +1100
+@@ -1,7 +1,7 @@
+ QA output created by 972
+ == Testing zswap metrics
+-dbpmda> open pipe /usr/bin/python $PCP_PMDAS_DIR/zswap/pmdazswap.python
+-Start python PMDA: /usr/bin/python $PCP_PMDAS_DIR/zswap/pmdazswap.python
++dbpmda> open pipe $PCP_PYTHON_PROG $PCP_PMDAS_DIR/zswap/pmdazswap.python
++Start python PMDA: $PCP_PYTHON_PROG $PCP_PMDAS_DIR/zswap/pmdazswap.python
+ dbpmda> getdesc on
+ dbpmda> desc zswap.pool_limit_hit
+ PMID: 125.0.0
+diff -Naurp pcp-3.10.2.orig/qa/985 pcp-3.10.2/qa/985
+--- pcp-3.10.2.orig/qa/985	2015-01-21 02:18:01.000000000 +1100
++++ pcp-3.10.2/qa/985	2015-02-23 21:24:36.659658337 +1100
+@@ -2,28 +2,20 @@
+ # PCP QA Test No. 985
+ # Exercise the dmcache PMDA using dbpmda.
+ #
+-# Copyright (c) 2014 Red Hat.
++# Copyright (c) 2014-2015 Red Hat.
+ #
+ 
+ seq=`basename $0`
+ echo "QA output created by $seq"
+ 
+-# get standard environment, filters and checks
+-. ./common.product
+-. ./common.filter
+-. ./common.check
++. ./common.python
+ 
++python_path=`which $python`
+ pmda_path="$PCP_PMDAS_DIR/dmcache"
+ pmda_script="$pmda_path/pmdadmcache.python"
+ test -f "$pmda_script" || _notrun "pmdadmcache not supported"
+-python -c "from pcp import pmda" >/dev/null 2>&1
++$python -c "from pcp import pmda" >/dev/null 2>&1
+ [ $? -eq 0 ] || _notrun "python pcp pmda module not installed"
+-case `python -V 2>&1 | sed -e 's/Python //'`
+-in
+-    0.*.*|1.*.*|2.0.*|2.1.*|2.3.*|2.4.*)
+-	_notrun "need python 2.5 or later"
+-	;;
+-esac
+ 
+ status=1	# failure is the default!
+ $sudo rm -rf $tmp.* $seq.full
+@@ -36,7 +28,9 @@ _filter()
+ 	-e "s;$PCP_PMDAS_DIR;\$PCP_PMDAS_DIR;" \
+ 	-e '/pmResult/s/ .* numpmid/ ... numpmid/' \
+ 	-e '/[0-9][0-9]:[0-9][0-9]:[0-9][0-9]/s/[^ ]*/TIMESTAMP/' \
+-
++	-e "s;$python_path;\$PCP_PYTHON_PROG;" \
++	-e "s;$python;python;" \
++    #end
+     test -f dmcache.log && cat dmcache.log >> $seq.full
+ }
+ 
+@@ -53,11 +47,11 @@ export DM_STATUS=$tmp.dmcache.sh
+ 
+ # real QA test starts here
+ echo "== Finding dmcache metrics" | tee -a $seq.full
+-PCP_PYTHON_PMNS=root python "$pmda_script" 2>/dev/null > $tmp.root
++PCP_PYTHON_PMNS=root $python "$pmda_script" 2>/dev/null > $tmp.root
+ 
+ echo "== Testing dmcache metrics" | tee -a $seq.full
+ $sudo dbpmda -n $tmp.root -ie <<End-of-File 2>&1 | _filter
+-open pipe /usr/bin/python $pmda_script
++open pipe $python_path $pmda_script
+ getdesc on
+ instance $domain.0
+ desc dmcache.size
+diff -Naurp pcp-3.10.2.orig/qa/985.out pcp-3.10.2/qa/985.out
+--- pcp-3.10.2.orig/qa/985.out	2015-01-21 02:18:01.000000000 +1100
++++ pcp-3.10.2/qa/985.out	2015-02-23 21:24:36.659658337 +1100
+@@ -1,8 +1,8 @@
+ QA output created by 985
+ == Finding dmcache metrics
+ == Testing dmcache metrics
+-dbpmda> open pipe /usr/bin/python $PCP_PMDAS_DIR/dmcache/pmdadmcache.python
+-Start python PMDA: /usr/bin/python $PCP_PMDAS_DIR/dmcache/pmdadmcache.python
++dbpmda> open pipe $PCP_PYTHON_PROG $PCP_PMDAS_DIR/dmcache/pmdadmcache.python
++Start python PMDA: $PCP_PYTHON_PROG $PCP_PMDAS_DIR/dmcache/pmdadmcache.python
+ dbpmda> getdesc on
+ dbpmda> instance 129.0
+ pmInDom: 129.0
+diff -Naurp pcp-3.10.2.orig/qa/986 pcp-3.10.2/qa/986
+--- pcp-3.10.2.orig/qa/986	2015-01-21 02:18:01.000000000 +1100
++++ pcp-3.10.2/qa/986	2015-02-23 21:24:36.659658337 +1100
+@@ -2,24 +2,21 @@
+ # PCP QA Test No. 986
+ # Exercise the dmcache PMDA using the running kernel.
+ #
+-# Copyright (c) 2014 Red Hat.
++# Copyright (c) 2014-2015 Red Hat.
+ #
+ 
+ seq=`basename $0`
+ echo "QA output created by $seq"
+ 
+-# get standard environment, filters and checks
+-. ./common.product
+-. ./common.filter
+-. ./common.check
++. ./common.python
+ 
+ status=1	# failure is the default!
+ $sudo rm -f $tmp.* $seq.full
+ 
+ which dmsetup >/dev/null 2>&1
+ test $? -eq 0 || _notrun "Device Mapper 'dmsetup' binary not found"
+-python -c 'from pcp import pmda' 2>/dev/null
+-test $? -eq 0 || _notrun 'Python pcp pmda module is not installed'
++$python -c 'from pcp import pmda' 2>/dev/null
++test $? -eq 0 || _notrun "$python pcp pmda module is not installed"
+ 
+ _filter_dmcache()
+ {
+diff -Naurp pcp-3.10.2.orig/qa/common.python pcp-3.10.2/qa/common.python
+--- pcp-3.10.2.orig/qa/common.python	2015-01-21 02:18:01.000000000 +1100
++++ pcp-3.10.2/qa/common.python	2015-02-23 21:24:36.660658336 +1100
+@@ -8,8 +8,8 @@
+ . ./common.filter
+ . ./common.check
+ 
+-# allow alternate versions of python to be used
+-python=${PYTHON:-/usr/bin/python}
++python=${PCP_PYTHON_PROG:-python}
++eval $python -c exit 2>/dev/null || _notrun "$python unavailable"
+ 
+ # verify output from unittest indicates successful testing
+ _check_unittest()
+diff -Naurp pcp-3.10.2.orig/qa/pmdas/memory_python/pmdamemory_python.python pcp-3.10.2/qa/pmdas/memory_python/pmdamemory_python.python
+--- pcp-3.10.2.orig/qa/pmdas/memory_python/pmdamemory_python.python	2015-01-21 02:18:01.000000000 +1100
++++ pcp-3.10.2/qa/pmdas/memory_python/pmdamemory_python.python	2015-02-23 21:24:36.660658336 +1100
+@@ -42,7 +42,7 @@ class MemoryPMDA(PMDA):
+         # At this point if all goes well, the PMDA internal
+         # _metric_names dictionary will contain the metric we just
+         # added. If not, memory has become corrupted.
+-        if not self._metric_names.has_key(self.metric_pmid):
++        if not self.metric_pmid in self._metric_names:
+             self.memory_valid = 0
+             msg = '_metric_names has no matching pmid'
+             self.log(msg)
+@@ -66,14 +66,14 @@ class MemoryPMDA(PMDA):
+         self.memory_valid = 1
+         self.metric_name = name + '.memory_valid'
+         self.metric_pmid = self.pmid(0, 0)
+-	self.metric_obj = pmdaMetric(self.metric_pmid, c_api.PM_TYPE_64,
++        self.metric_obj = pmdaMetric(self.metric_pmid, c_api.PM_TYPE_64,
+                                      c_api.PM_INDOM_NULL, c_api.PM_SEM_COUNTER,
+                                      pmUnits(0, 0, 0, 0, 0, 0))
+         self.metric_oneline = "test metric"
+         self.add_metric(self.metric_name, self.metric_obj, self.metric_oneline)
+ 
+         # Make sure the PMDA's internal dictionary is in a good state.
+-        if not self._metric_names.has_key(self.metric_pmid):
++        if not self.metric_pmid in self._metric_names:
+             self.memory_valid = 0
+             msg = '_metric_names has no matching pmid'
+             self.log(msg)
+diff -Naurp pcp-3.10.2.orig/qa/pmdas/slow_python/pmdaslow_python.python pcp-3.10.2/qa/pmdas/slow_python/pmdaslow_python.python
+--- pcp-3.10.2.orig/qa/pmdas/slow_python/pmdaslow_python.python	2015-01-21 02:18:01.000000000 +1100
++++ pcp-3.10.2/qa/pmdas/slow_python/pmdaslow_python.python	2015-02-23 21:24:36.660658336 +1100
+@@ -32,33 +32,33 @@ class SlowPMDA(PMDA):
+     '''
+ 
+     def slow_fetch_callback(self, cluster, item, inst):
+-	global fetch_delay
++        global fetch_delay
+ 
+-	if int(fetch_delay) < 0:
+-	    time.sleep(-1*int(fetch_delay))
++        if int(fetch_delay) < 0:
++            time.sleep(-1*int(fetch_delay))
+ 
+-	if int(fetch_delay) > 0:
+-	    time.sleep(int(fetch_delay))
++        if int(fetch_delay) > 0:
++            time.sleep(int(fetch_delay))
+ 
+         if cluster == 0 and item == 0:
+             return [13, 1]
+         return [c_api.PM_ERR_PMID, 0]
+ 
+     def __init__(self, name, domain):
+-	global start_delay
++        global start_delay
+ 
+         PMDA.__init__(self, name, domain)
+ 
+         self.configfile = PCP.pmGetConfig('PCP_PMDAS_DIR')
+         self.configfile += '/' + name + '/' + name + '.conf'
+ 
+-	if int(start_delay) > 0:
+-	    self.connect_pmcd()
++        if int(start_delay) > 0:
++            self.connect_pmcd()
+ 
+-	if int(start_delay) < 0:
+-	    time.sleep(-1*int(start_delay))
+-	if int(start_delay) > 0:
+-	    time.sleep(int(start_delay))
++        if int(start_delay) < 0:
++            time.sleep(-1*int(start_delay))
++        if int(start_delay) > 0:
++            time.sleep(int(start_delay))
+ 
+         self.add_metric(name + '.thirteen', pmdaMetric(self.pmid(0, 0),
+                 c_api.PM_TYPE_32, c_api.PM_INDOM_NULL, c_api.PM_SEM_INSTANT,
+diff -Naurp pcp-3.10.2.orig/qa/src/test_pcp.python pcp-3.10.2/qa/src/test_pcp.python
+--- pcp-3.10.2.orig/qa/src/test_pcp.python	2015-01-24 07:23:07.000000000 +1100
++++ pcp-3.10.2/qa/src/test_pcp.python	2015-02-23 21:24:36.661658335 +1100
+@@ -30,7 +30,7 @@ def dump_seq(name_p, seq_p):
+ 
+ def dump_array_ptrs(name_p, arr_p):
+     print(name_p)
+-    for i in xrange(len(arr_p)):
++    for i in range(len(arr_p)):
+         if (i > 0):
+             print(" ", arr_p[i].contents)
+         else:
+@@ -38,7 +38,7 @@ def dump_array_ptrs(name_p, arr_p):
+ 
+ def dump_array(name_p, arr_p):
+     print(name_p)
+-    for i in xrange(len(arr_p)):
++    for i in range(len(arr_p)):
+         if (i > 0):
+             print(" ", hex(arr_p[i]))
+         else:
+@@ -72,8 +72,9 @@ def test_pcp(self):
+     source = 'localhost'
+     try:
+         (rsltp, errmsg) = ctx.pmParseMetricSpec("kernel.all.load", 0, source)
+-        print("pmParseMetricSpec:", rsltp.contents.source)
+-        self.assertTrue(rsltp.contents.source == source)
++        result = rsltp.contents.source.decode()
++        print("pmParseMetricSpec:", result)
++        self.assertTrue(result == source)
+     except pmapi.pmErr as error:
+         print("pmParseMetricSpec error: ", error)
+ 
+@@ -124,7 +125,7 @@ def test_pcp(self):
+                               api.PM_TYPE_STRING)
+     machine_vp = atom.vp
+     self.assertTrue(machine_u32 != machine_vp)
+-    self.assertTrue(type(atom.cp) == type(''))
++    self.assertTrue(type(atom.cp) == type('') or type(atom.cp) == type(b''))
+ 
+     # pmGetChildren
+     if not self.archive_type:
+@@ -179,16 +180,27 @@ def test_pcp(self):
+     dump_array("pmLookupName", self.metric_ids)
+     self.assertTrue(len(self.metric_ids) == 4)
+ 
+-    for i in xrange(len(metrics)):
++    for i in range(len(metrics)):
+         # pmNameAll
++        # one of the returned names should be the same as metrics[i]
+         nameall = ctx.pmNameAll(self.metric_ids[i])
+-        print("pmNameAll:", nameall[0])
+-        self.assertTrue(nameall[0] == metrics[i])
++        match = 0
++        for j in range(len(nameall)):
++            print("pmNameAll:", nameall[j])
++            if (nameall[j] == metrics[i]):
++                match = 1
++        self.assertTrue(match)
+ 
+         # pmNameID
++        # result will be one of the names from pmNameAll and we've
++        # already established that one of these is the same as metrics[i]
+         name = ctx.pmNameID(self.metric_ids[i])
+-        print("pmNameID:", name)
+-        self.assertTrue(name == metrics[i])
++        print("pmNameID:", name);
++        match = 0
++        for j in range(len(nameall)):
++            if (nameall[j] == name):
++                match = 1
++        self.assertTrue(match)
+ 
+         # pmLookupDesc
+         descs = ctx.pmLookupDescs(self.metric_ids[i])
+@@ -317,7 +329,7 @@ def test_pcp(self):
+         (units,mult) = ctx.pmParseUnitsStr(5) # type-checking non-string
+         print("pmParseUnitsStr:", units, mult)
+         self.assertTrue(False)
+-    except AssertionError as error:
++    except pmapi.pmErr as error:
+         print("pmParseUnitsStr: ", error)
+         self.assertTrue(True)
+ 
+@@ -346,10 +358,10 @@ def test_pcp(self):
+         print("pmStore: ", error)
+         self.assertTrue(True)
+ 
+-    for i in xrange(results.contents.numpmid):
++    for i in range(results.contents.numpmid):
+         if (results.contents.get_pmid(i) != self.metric_ids[1]):
+             continue
+-        for val in xrange(9):
++        for val in range(9):
+             # sample.bin - each instance in turn
+             atom = ctx.pmExtractValue(results.contents.get_valfmt(i),
+                                       results.contents.get_vlist(i, val),
+@@ -359,7 +371,7 @@ def test_pcp(self):
+             self.assertTrue(99*(val+1) <= atom.f and atom.f <= 101*(val+1))
+ 
+     # pmExtractValue 
+-    for i in xrange(results.contents.numpmid):
++    for i in range(results.contents.numpmid):
+         if (results.contents.get_pmid(i) != self.metric_ids[3]):
+             continue
+         # mem.freemem
+@@ -438,7 +450,10 @@ def test_pcp(self):
+     # pmPrintValue
+     if not self.archive_type:
+         print("pmPrintValue:")
+-        ctx.pmPrintValue(sys.__stdout__, results, descs[0], 0, 0, 8)
++        if sys.version >= '3':
++            print('Not yet implemented')
++        else:
++            ctx.pmPrintValue(sys.__stdout__, results, descs[0], 0, 0, 8)
+         print('')
+ 
+     # pmReconnectContext
+diff -Naurp pcp-3.10.2.orig/qa/src/test_pmcc.python pcp-3.10.2/qa/src/test_pmcc.python
+--- pcp-3.10.2.orig/qa/src/test_pmcc.python	2015-01-21 02:18:01.000000000 +1100
++++ pcp-3.10.2/qa/src/test_pmcc.python	2015-02-23 21:24:36.661658335 +1100
+@@ -1,6 +1,6 @@
+ """ Test metric value extraction/reporting using the pcp.pmcc module """
+ #
+-# Copyright (C) 2013-2014 Red Hat Inc.
++# Copyright (C) 2013-2015 Red Hat Inc.
+ #
+ # This program is free software; you can redistribute it and/or modify it
+ # under the terms of the GNU General Public License as published by the
+@@ -13,9 +13,14 @@
+ # for more details.
+ #
+ 
++import sys
+ import unittest
+ from pcp import pmcc, pmapi
+ 
++if sys.version >= '3':
++    import functools
++    reduce = functools.reduce
++
+ CPU_METRICS = [ "kernel.all.cpu.sys", "kernel.all.cpu.user",
+                 "kernel.all.cpu.nice", "kernel.all.cpu.idle", ]
+ MEM_METRICS = [ "mem.physmem", "mem.freemem", ]
+diff -Naurp pcp-3.10.2.orig/src/include/pcp.conf.in pcp-3.10.2/src/include/pcp.conf.in
+--- pcp-3.10.2.orig/src/include/pcp.conf.in	2015-01-21 02:18:01.000000000 +1100
++++ pcp-3.10.2/src/include/pcp.conf.in	2015-02-23 21:24:36.662658334 +1100
+@@ -1,5 +1,5 @@
+ #
+-# Copyright (c) 2013-2014 Red Hat.
++# Copyright (c) 2013-2015 Red Hat.
+ # Copyright (c) 2000-2001,2003 Silicon Graphics, Inc.  All Rights Reserved.
+ # 
+ # This program is free software; you can redistribute it and/or modify it
+@@ -176,6 +176,9 @@ PCP_PS_PROG=@pcp_ps_prog@
+ PCP_PS_HAVE_BSD=@pcp_ps_have_bsd@
+ PCP_PS_ALL_FLAGS=@pcp_ps_all_flags@
+ 
++# preferred python executable
++PCP_PYTHON_PROG=@pcp_python_prog@
++
+ # locate executables
+ PCP_WHICH_PROG=@which@
+ 
+diff -Naurp pcp-3.10.2.orig/src/pcp/dmcache/pcp-dmcache.py pcp-3.10.2/src/pcp/dmcache/pcp-dmcache.py
+--- pcp-3.10.2.orig/src/pcp/dmcache/pcp-dmcache.py	2015-01-21 02:18:01.000000000 +1100
++++ pcp-3.10.2/src/pcp/dmcache/pcp-dmcache.py	2015-02-23 21:24:36.662658334 +1100
+@@ -1,6 +1,6 @@
+ #!/usr/bin/python
+ #
+-# Copyright (C) 2014 Red Hat.
++# Copyright (C) 2014-2015 Red Hat.
+ #
+ # This program is free software; you can redistribute it and/or modify it
+ # under the terms of the GNU General Public License as published by the
+@@ -18,6 +18,9 @@
+ import sys
+ from pcp import pmapi, pmcc
+ 
++if sys.version >= '3':
++    long = int  # python2 to python3 portability (no long() in python3)
++
+ CACHE_METRICS = ['dmcache.cache.used', 'dmcache.cache.total',
+                  'dmcache.metadata.used', 'dmcache.metadata.total',
+                  'dmcache.read_hits', 'dmcache.read_misses',
+diff -Naurp pcp-3.10.2.orig/src/pcp/free/pcp-free.py pcp-3.10.2/src/pcp/free/pcp-free.py
+--- pcp-3.10.2.orig/src/pcp/free/pcp-free.py	2015-01-21 02:18:01.000000000 +1100
++++ pcp-3.10.2/src/pcp/free/pcp-free.py	2015-02-23 21:24:36.662658334 +1100
+@@ -1,6 +1,6 @@
+ #!/usr/bin/python
+ #
+-# Copyright (C) 2014 Red Hat.
++# Copyright (C) 2014-2015 Red Hat.
+ #
+ # This program is free software; you can redistribute it and/or modify it
+ # under the terms of the GNU General Public License as published by the
+@@ -19,6 +19,9 @@ import sys
+ from pcp import pmapi
+ from cpmapi import PM_TYPE_U64, PM_CONTEXT_ARCHIVE, PM_SPACE_KBYTE
+ 
++if sys.version >= '3':
++    long = int  # python2 to python3 portability (no long() in python3)
++
+ class Free(object):
+     """ Gives a short summary of kernel virtual memory information,
+         in a variety of formats, possibly sampling in a loop.
+diff -Naurp pcp-3.10.2.orig/src/pcp/numastat/pcp-numastat.py pcp-3.10.2/src/pcp/numastat/pcp-numastat.py
+--- pcp-3.10.2.orig/src/pcp/numastat/pcp-numastat.py	2015-01-21 02:18:01.000000000 +1100
++++ pcp-3.10.2/src/pcp/numastat/pcp-numastat.py	2015-02-23 21:24:36.663658333 +1100
+@@ -1,6 +1,6 @@
+ #!/usr/bin/python
+ #
+-# Copyright (C) 2014 Red Hat.
++# Copyright (C) 2014-2015 Red Hat.
+ #
+ # This program is free software; you can redistribute it and/or modify it
+ # under the terms of the GNU General Public License as published by the
+@@ -20,6 +20,9 @@ import sys
+ from pcp import pmapi
+ from cpmapi import PM_TYPE_U64
+ 
++if sys.version >= '3':
++    long = int  # python2 to python3 portability (no long() in python3)
++
+ class NUMAStat(object):
+     """ Gives a short summary of per-node NUMA memory information.
+ 
+@@ -103,7 +106,7 @@ class NUMAStat(object):
+             print("No NUMA nodes found, exiting")
+             sys.exit(1)
+         self.resize()
+-        maxnodes = (self.width - 16) / 16
++        maxnodes = int((self.width - 16) / 16)
+         if maxnodes > len(nodes):        # just an initial header suffices
+             header = '%-16s' % ''
+             for node in nodes:
+diff -Naurp pcp-3.10.2.orig/src/pmatop/pmatop.py pcp-3.10.2/src/pmatop/pmatop.py
+--- pcp-3.10.2.orig/src/pmatop/pmatop.py	2015-01-24 07:23:07.000000000 +1100
++++ pcp-3.10.2/src/pmatop/pmatop.py	2015-02-23 21:21:18.201838488 +1100
+@@ -1,9 +1,6 @@
+ #!/usr/bin/python
+-
+-#
+-# pmatop.py
+ #
+-# Copyright (C) 2013, 2014 Red Hat Inc.
++# Copyright (C) 2013-2015 Red Hat.
+ #
+ # This program is free software; you can redistribute it and/or modify it
+ # under the terms of the GNU General Public License as published by the
+@@ -445,25 +442,19 @@ class _DiskPrint(_AtopPrint):
+     replay_archive = property(None, replay_archive_write, None, None)
+ 
+     def disk(self, context):
++        desc = self.ss.metric_descs[self.ss.metrics_dict['disk.partitions.read']]
+         try:
+-            (inst, iname) = context.pmGetInDom(self.ss.metric_descs[self.ss.metrics_dict['disk.partitions.read']])
++            (inst, iname) = context.pmGetInDom(desc)
+         except pmapi.pmErr as e:
+             iname = iname = "X"
+ 
+-# Missing: LVM avq (average queue depth)
+-
+-        lvms = dict(map(lambda x: (os.path.realpath("/dev/mapper/" + x)[5:], x),
+-                         (os.listdir("/dev/mapper"))))
++        # Missing: LVM avq (average queue depth)
++        # TODO: switch to using disk.dm metrics?
+ 
+         for j in xrange(self.ss.get_len(self.ss.get_metric_value('disk.partitions.read'))):
+-            if self._replay_archive == True:
+-                if iname[j][:2] != "dm":
+-                    continue
+-                lvm = iname[j]
+-            else:
+-                if iname[j] not in lvms:
+-                    continue
+-                lvm = lvms[iname[j]]
++            if iname[j][:2] != "dm":
++                continue
++            lvm = iname[j]
+             partitions_read = self.ss.get_scalar_value('disk.partitions.read', j)
+             partitions_write = self.ss.get_scalar_value('disk.partitions.write', j)
+             if partitions_read == 0 and partitions_write == 0:
+@@ -701,10 +692,8 @@ class _ProcPrint(_AtopPrint):
+ 
+ class _Options(object):
+     def __init__(self):
+-        self.input_file = ""
+         self.output_file = ""
+         self.output_type = "g"
+-        self.host = "local:"
+         self.create_archive = False
+         self.replay_archive = False
+         self.have_interval_arg = False
+@@ -719,16 +708,28 @@ class _Options(object):
+         opts.pmSetOptionCallback(self.option_callback)
+         opts.pmSetOverrideCallback(self.override)
+         # leading - returns args that are not options with leading ^A
+-        opts.pmSetShortOptions("-gmw:r:L:h:V?")
+-        opts.pmSetLongOptionHeader("Options")
++        opts.pmSetShortOptions("-gmw:r:L:h:a:V?")
++        opts.pmSetLongOptionText("Interactive: [-g|-m] [-L linelen] [-h host | -a archive] [ interval [ samples ]]")
++        opts.pmSetLongOptionText("Write folio: pmatop -w folio [ interval [ samples ]]")
++        opts.pmSetLongOptionText("Read folio: pmatop -r folio [-g|-m] [-L linelen] [-h host]")
++        opts.pmSetLongOptionHeader("Reporting Options")
+         opts.pmSetLongOption("generic", 0, 'g', '', "Display generic metrics")
+         opts.pmSetLongOption("memory", 0, 'm', '', "Display memory metrics")
+-        opts.pmSetLongOption("write", 1, 'w', 'FILENAME', "Write metric data to file")
+-        opts.pmSetLongOption("read", 1, 'r', 'FILENAME', "Read metric data from file")
+         opts.pmSetLongOption("width", 1, 'L', 'WIDTH', "Width of the output")
+-        opts.pmSetShortUsage("[options]\nInteractive: [-g|-m] [-L linelen] [-h host] [ interval [ samples ]]\nWrite raw logfile: pmatop -w rawfile [ interval [ samples ]]\nRead raw logfile: pmatop -r [ rawfile ] [-g|-m] [-L linelen] [-h host]")
++        opts.pmSetLongOptionHeader("Folio Options")
++        opts.pmSetLongOption("write", 1, 'w', 'FILENAME', "Write metric data to PCP archive folio")
++        opts.pmSetLongOption("read", 1, 'r', 'FILENAME', "Read metric data from PCP archive folio")
++        opts.pmSetLongOptionHeader("General Options")
++        opts.pmSetLongOptionAlign()
++        opts.pmSetLongOptionArchive()
++        opts.pmSetLongOptionDebug()
+         opts.pmSetLongOptionHost()
++        opts.pmSetLongOptionOrigin()
++        opts.pmSetLongOptionStart()
++        opts.pmSetLongOptionFinish()
+         opts.pmSetLongOptionVersion()
++        opts.pmSetLongOptionTimeZone()
++        opts.pmSetLongOptionHostZone()
+         opts.pmSetLongOptionHelp()
+         return opts
+ 
+@@ -738,6 +739,8 @@ class _Options(object):
+         # pylint: disable=R0201
+         if opt == 'g':
+             return 1
++        elif opt == "a":
++            self.replay_archive = True
+         elif opt == 'L':
+             return 1
+         return 0
+@@ -755,12 +758,9 @@ class _Options(object):
+             self.create_archive = True
+         elif opt == "r":
+             self.opts.pmSetOptionArchiveFolio(optarg)
+-            self.input_file = optarg
+             self.replay_archive = True
+         elif opt == "L":
+             self.width = int(optarg)
+-        elif opt == 'h':
+-            self.host = optarg
+         elif opt == "":
+             if self.have_interval_arg == False:
+                 self.interval_arg = optarg
+@@ -796,14 +796,12 @@ def main(stdscr_p):
+     stdscr.width = opts.width
+ 
+     pmc = pmapi.pmContext.fromOptions(opts.opts, sys.argv)
++    (delta, errmsg) = pmc.pmParseInterval(str(opts.interval_arg) + " seconds")
+     if pmc.type == c_api.PM_CONTEXT_ARCHIVE:
+-        pmc.pmSetMode(c_api.PM_MODE_FORW, pmapi.timeval(0, 0), 0)
+-
++        pmc.pmSetMode(c_api.PM_MODE_FORW, delta, 0)
+ 
+     host = pmc.pmGetContextHostName()
+ 
+-    (delta, errmsg) = pmc.pmParseInterval(str(opts.interval_arg) + " seconds")
+-
+     ss.setup_metrics(pmc)
+ 
+     if opts.create_archive:
+@@ -831,10 +829,10 @@ def main(stdscr_p):
+         elapsed = ss.get_metric_value('kernel.all.uptime')
+         while (i_samples < opts.n_samples) or (opts.n_samples == 0):
+             ss.get_stats(pmc)
++            stamp = pmc.pmCtime(ss.timestamp)
+             stdscr.move(0, 0)
+             stdscr.addstr('ATOP - %s                %s elapsed\n\n' % (
+-                    time.strftime("%c"),
+-                    datetime.timedelta(0, elapsed)))
++                    stamp.rstrip(), datetime.timedelta(0, elapsed)))
+             elapsed = delta.tv_sec
+             stdscr.move(2, 0)
+ 
+diff -Naurp pcp-3.10.2.orig/src/pmcd/pmdaproc.sh pcp-3.10.2/src/pmcd/pmdaproc.sh
+--- pcp-3.10.2.orig/src/pmcd/pmdaproc.sh	2015-01-24 07:23:07.000000000 +1100
++++ pcp-3.10.2/src/pmcd/pmdaproc.sh	2015-02-23 21:24:36.664658332 +1100
+@@ -3,7 +3,7 @@
+ #
+ # Copyright (c) 1995-2001,2003 Silicon Graphics, Inc.  All Rights Reserved.
+ # Portions Copyright (c) 2008 Aconex.  All Rights Reserved.
+-# Portions Copyright (c) 2013-2014 Red Hat.
++# Portions Copyright (c) 2013-2015 Red Hat.
+ # 
+ # This program is free software; you can redistribute it and/or modify it
+ # under the terms of the GNU General Public License as published by the
+@@ -891,17 +891,18 @@ _setup()
+     #
+     if $python_opt
+     then
++	python=${PCP_PYTHON_PROG:-python}
+ 	python_name="${pmda_dir}/pmda${iam}.python"
+ 	[ -f "$python_name" ] || python_name="${pmda_dir}/pmda${iam}.py"
+ 	if [ -f "$python_name" ]
+ 	then
+ 	    python_pmns="${pmda_dir}/pmns.python"
+ 	    python_dom="${pmda_dir}/domain.h.python"
+-	    python -c 'from pcp import pmda' 2>/dev/null
++	    $python -c 'from pcp import pmda' 2>/dev/null
+ 	    if test $? -eq 0
+ 	    then
+-		eval PCP_PYTHON_DOMAIN=1 python "$python_name" > "$python_dom"
+-		eval PCP_PYTHON_PMNS=1 python "$python_name" > "$python_pmns"
++		eval PCP_PYTHON_DOMAIN=1 $python "$python_name" > "$python_dom"
++		eval PCP_PYTHON_PMNS=1 $python "$python_name" > "$python_pmns"
+ 	    elif $dso_opt || $daemon_opt
+ 	    then
+ 		:	# we have an alternative, so continue on
+@@ -1080,7 +1081,7 @@ _install()
+ 		    fi
+ 		elif [ "X$pmda_type" = Xpython ]
+ 		then
+-		    python -c 'from pcp import pmda' 2>/dev/null
++		    $python -c 'from pcp import pmda' 2>/dev/null
+ 		    if test $? -ne 0
+ 		    then
+ 			echo 'Python pcp pmda module is not installed, install it and try again'
+@@ -1102,7 +1103,7 @@ _install()
+ 	    args=""
+ 	elif [ "$pmda_type" = python ]
+ 	then
+-	    type="pipe	binary		python $python_name $python_args"
++	    type="pipe	binary		$python $python_name $python_args"
+ 	    args=""
+ 	else
+ 	    type="dso	$dso_entry	$dso_name"
+diff -Naurp pcp-3.10.2.orig/src/pmcollectl/pmcollectl.py pcp-3.10.2/src/pmcollectl/pmcollectl.py
+--- pcp-3.10.2.orig/src/pmcollectl/pmcollectl.py	2015-01-21 02:18:01.000000000 +1100
++++ pcp-3.10.2/src/pmcollectl/pmcollectl.py	2015-02-23 21:24:36.665658331 +1100
+@@ -1,9 +1,6 @@
+ #!/usr/bin/python
+-
+-#
+-# pmcollectl.py
+ #
+-# Copyright (C) 2012-2014 Red Hat Inc.
++# Copyright (C) 2012-2015 Red Hat.
+ #
+ # This program is free software; you can redistribute it and/or modify it
+ # under the terms of the GNU General Public License as published by the
+@@ -58,7 +55,7 @@ def scale(value, magnitude):
+ 
+ def record(context, config, duration, path, host):
+     if os.path.exists(path):
+-        print ME + "archive %s already exists\n" % path
++        print(ME + "archive %s already exists\n" % path)
+         sys.exit(1)
+     # Non-graphical application using libpcp_gui services - never want
+     # to see popup dialogs from pmlogger(1) here, so force the issue.
+@@ -99,7 +96,7 @@ class _CollectPrint(object):
+             self.print_header1_detail()
+         elif self.verbosity == "verbose":
+             self.print_header1_verbose()
+-	sys.stdout.flush()
++        sys.stdout.flush()
+     def print_header2(self):
+         if self.verbosity == "brief":
+             self.print_header2_brief()
+@@ -107,7 +104,7 @@ class _CollectPrint(object):
+             self.print_header2_detail()
+         elif self.verbosity == "verbose":
+             self.print_header2_verbose()
+-	sys.stdout.flush()
++        sys.stdout.flush()
+     def print_header1_brief(self):
+         True                        # pylint: disable-msg=W0104
+     def print_header2_brief(self):
+@@ -149,37 +146,38 @@ class _cpuCollectPrint(_CollectPrint):
+     def print_header1_brief(self):
+         sys.stdout.write('#<--------CPU-------->')
+     def print_header1_detail(self):
+-        print '# SINGLE CPU STATISTICS'
++        print('# SINGLE CPU STATISTICS')
+     def print_header1_verbose(self):
+-        print '# CPU SUMMARY (INTR, CTXSW & PROC /sec)'
++        print('# CPU SUMMARY (INTR, CTXSW & PROC /sec)')
+ 
+     def print_header2_brief(self):
+         sys.stdout.write('#cpu sys inter  ctxsw')
+     def print_header2_detail(self):
+-        print '#   Cpu  User Nice  Sys Wait IRQ  Soft Steal Idle'
++        print('#   Cpu  User Nice  Sys Wait IRQ  Soft Steal Idle')
+     def print_header2_verbose(self):
+-        print '#User  Nice   Sys  Wait   IRQ  Soft Steal  Idle  CPUs  Intr  Ctxsw  Proc  RunQ   Run   Avg1  Avg5 Avg15 RunT BlkT'
++        print('#User  Nice   Sys  Wait   IRQ  Soft Steal  Idle  CPUs  Intr  Ctxsw  Proc  RunQ   Run   Avg1  Avg5 Avg15 RunT BlkT')
+ 
+     def print_brief(self):
+-        print "%4d" % (100 * (self.ss.get_metric_value('kernel.all.cpu.nice') +
+-                              self.ss.get_metric_value('kernel.all.cpu.user') +
+-                              self.ss.get_metric_value('kernel.all.cpu.intr') +
+-                              self.ss.get_metric_value('kernel.all.cpu.sys') +
+-                              self.ss.get_metric_value('kernel.all.cpu.steal') +
+-                              self.ss.get_metric_value('kernel.all.cpu.irq.hard') +
+-                              self.ss.get_metric_value('kernel.all.cpu.irq.soft')) /
+-                       ss.cpu_total),
+-        print "%3d" % (100 * (self.ss.get_metric_value('kernel.all.cpu.intr') +
+-                              self.ss.get_metric_value('kernel.all.cpu.sys') +
+-                              self.ss.get_metric_value('kernel.all.cpu.steal') +
+-                              self.ss.get_metric_value('kernel.all.cpu.irq.hard') +
+-                              self.ss.get_metric_value('kernel.all.cpu.irq.soft')) /
+-                       ss.cpu_total),
+-        print "%5d %6d" % (self.ss.get_metric_value('kernel.all.intr'),
+-                           self.ss.get_metric_value('kernel.all.pswitch')),
++        sys.stdout.write("%4d %3d %5d %6d" % (
++            100 * (self.ss.get_metric_value('kernel.all.cpu.nice') +
++                   self.ss.get_metric_value('kernel.all.cpu.user') +
++                   self.ss.get_metric_value('kernel.all.cpu.intr') +
++                   self.ss.get_metric_value('kernel.all.cpu.sys') +
++                   self.ss.get_metric_value('kernel.all.cpu.steal') +
++                   self.ss.get_metric_value('kernel.all.cpu.irq.hard') +
++                   self.ss.get_metric_value('kernel.all.cpu.irq.soft')) /
++                   ss.cpu_total,
++            100 * (self.ss.get_metric_value('kernel.all.cpu.intr') +
++                   self.ss.get_metric_value('kernel.all.cpu.sys') +
++                   self.ss.get_metric_value('kernel.all.cpu.steal') +
++                   self.ss.get_metric_value('kernel.all.cpu.irq.hard') +
++                   self.ss.get_metric_value('kernel.all.cpu.irq.soft')) /
++                   ss.cpu_total,
++            self.ss.get_metric_value('kernel.all.intr'),
++            self.ss.get_metric_value('kernel.all.pswitch')))
+     def print_detail(self):
+         for k in range(self.ss.get_len(self.ss.get_metric_value('kernel.percpu.cpu.user'))):
+-            print "    %3d  %4d %4d  %3d %4d %3d  %4d %5d %4d" % (
++            print("    %3d  %4d %4d  %3d %4d %3d  %4d %5d %4d" % (
+                 k,
+                 (100 * (self.ss.get_scalar_value('kernel.percpu.cpu.nice', k) +
+                         self.ss.get_scalar_value('kernel.percpu.cpu.user', k) +
+@@ -200,10 +198,10 @@ class _cpuCollectPrint(_CollectPrint):
+             self.ss.get_scalar_value('kernel.percpu.cpu.irq.hard', k),
+             self.ss.get_scalar_value('kernel.percpu.cpu.irq.soft', k),
+             self.ss.get_scalar_value('kernel.percpu.cpu.steal', k),
+-                self.ss.get_scalar_value('kernel.percpu.cpu.idle', k) / 10)
++                self.ss.get_scalar_value('kernel.percpu.cpu.idle', k) / 10))
+     def print_verbose(self):
+         ncpu = self.ss.get_metric_value('hinv.ncpu')
+-        print "%4d %6d %5d %4d %4d %5d " % (
++        print("%4d %6d %5d %4d %4d %5d %6d %6d %5d %5d %6d %5d %5d %5d %5.2f %5.2f %5.2f %4d %4d" % (
+             (100 * (self.ss.get_metric_value('kernel.all.cpu.nice') +
+                     self.ss.get_metric_value('kernel.all.cpu.user') +
+                     self.ss.get_metric_value('kernel.all.cpu.intr') +
+@@ -221,16 +219,12 @@ class _cpuCollectPrint(_CollectPrint):
+              ss.cpu_total),
+             self.ss.get_metric_value('kernel.all.cpu.wait.total'),
+             self.ss.get_metric_value('kernel.all.cpu.irq.hard'),
+-            self.ss.get_metric_value('kernel.all.cpu.irq.soft')
+-            ),
+-        print "%6d %6d %5d %5d %6d" % (
++            self.ss.get_metric_value('kernel.all.cpu.irq.soft'),
+             self.ss.get_metric_value('kernel.all.cpu.steal'),
+             self.ss.get_metric_value('kernel.all.cpu.idle') / (10 * ncpu),
+             ncpu,
+             self.ss.get_metric_value('kernel.all.intr'),
+-            self.ss.get_metric_value('kernel.all.pswitch')
+-            ),
+-        print "%5d %5d %5d %5.2f %5.2f %5.2f %4d %4d" % (
++            self.ss.get_metric_value('kernel.all.pswitch'),
+             self.ss.get_metric_value('kernel.all.nprocs'),
+             self.ss.get_metric_value('kernel.all.runnable'),
+             self.ss.get_metric_value('proc.runq.runnable'),
+@@ -238,7 +232,7 @@ class _cpuCollectPrint(_CollectPrint):
+             self.ss.get_metric_value('kernel.all.load')[1],
+             self.ss.get_metric_value('kernel.all.load')[2],
+             self.ss.get_metric_value('kernel.all.runnable'),
+-            self.ss.get_metric_value('proc.runq.blocked'))
++            self.ss.get_metric_value('proc.runq.blocked')))
+ 
+ 
+ # _interruptCollectPrint ---------------------------------------------
+@@ -254,26 +248,26 @@ class _interruptCollectPrint(_CollectPri
+         for k in range(ndashes):
+             hdr += "-"
+         hdr += ">"
+-        print hdr,
++        sys.stdout.write(hdr)
+     def print_header1_detail(self):
+-        print '# INTERRUPT DETAILS'
+-        print '# Int    ',
++        print('# INTERRUPT DETAILS')
++        sys.stdout.write('# Int    ')
+         for k in range(self.ss.get_len(self.ss.get_metric_value('kernel.percpu.interrupts.THR'))):
+-            print 'Cpu%d ' % k,
+-        print 'Type            Device(s)'
++            sys.stdout.write('Cpu%d ' % k)
++        print('Type            Device(s)')
+     def print_header1_verbose(self):
+-        print '# INTERRUPT SUMMARY'
++        print('# INTERRUPT SUMMARY')
+     def print_header2_brief(self):
+         for k in range(self.ss.get_len(self.ss.get_metric_value('kernel.percpu.interrupts.THR'))):
+             if k == 0:
+-                print '#Cpu%d ' % k,
++                sys.stdout.write('#Cpu%d ' % k)
+             else:
+-                print 'Cpu%d ' % k,
++                sys.stdout.write('Cpu%d ' % k)
+     def print_header2_verbose(self):
+-        print '#    ',
++        sys.stdout.write('#    ')
+         for k in range(self.ss.get_len(self.ss.get_metric_value('kernel.percpu.interrupts.THR'))):
+-            print 'Cpu%d ' % k,
+-        print
++            sys.stdout.write('Cpu%d ' % k)
++        print('')
+     def print_brief(self):
+         int_count = []
+         for k in range(self.ss.get_len(self.ss.get_metric_value('kernel.percpu.interrupts.THR'))):
+@@ -283,7 +277,7 @@ class _interruptCollectPrint(_CollectPri
+                     int_count[k] += self.ss.get_scalar_value(self.ss.metrics_dict[j], k)
+ 
+         for k in range(self.ss.get_len(self.ss.get_metric_value('kernel.percpu.interrupts.THR'))):
+-            print "%4d " % (int_count[k]),
++            sys.stdout.write("%4d " % (int_count[k]))
+     def print_detail(self):
+         for j in ss.metrics:
+             if j[0:24] != 'kernel.percpu.interrupts':
+@@ -297,16 +291,16 @@ class _interruptCollectPrint(_CollectPri
+                     continue
+             if have_nonzero_value:
+                 # pcp does not give the interrupt # so print spaces
+-                print "%-8s" % self.ss.metrics[j_i].split(".")[3],
++                sys.stdout.write("%-8s" % self.ss.metrics[j_i].split(".")[3])
+                 for i in range(self.ss.get_len(self.ss.get_metric_value('kernel.percpu.interrupts.THR'))):
+-                    print "%4d " % (self.ss.get_scalar_value(j_i, i)),
++                    sys.stdout.write("%4d " % (self.ss.get_scalar_value(j_i, i)))
+                 text = (pm.pmLookupText(self.ss.metric_pmids[j_i], c_api.PM_TEXT_ONELINE))
+-                print "%-18s %s" % (text[:(str.index(text, " "))],
+-                                 text[(str.index(text, " ")):])
++                print("%-18s %s" % (text[:(str.index(text, " "))],
++                                 text[(str.index(text, " ")):]))
+     def print_verbose(self):
+-        print "     ",
++        sys.stdout.write("     ")
+         self.print_brief()
+-        print
++        print('')
+ 
+ 
+ # _diskCollectPrint --------------------------------------------------
+@@ -316,14 +310,14 @@ class _diskCollectPrint(_CollectPrint):
+     def print_header1_brief(self):
+         sys.stdout.write('<----------Disks----------->')
+     def print_header1_detail(self):
+-        print '# DISK STATISTICS (/sec)'
++        print('# DISK STATISTICS (/sec)')
+     def print_header1_verbose(self):
+-        print '\n\n# DISK SUMMARY (/sec)'
++        print('\n\n# DISK SUMMARY (/sec)')
+     def print_header2_brief(self):
+         sys.stdout.write(' KBRead  Reads KBWrit Writes')
+     def print_header2_detail(self):
+-        print '#          <---------reads---------><---------writes---------><--------averages--------> Pct'
+-        print '#Name       KBytes Merged  IOs Size  KBytes Merged  IOs Size  RWSize  QLen  Wait SvcTim Util'
++        print('#          <---------reads---------><---------writes---------><--------averages--------> Pct')
++        print('#Name       KBytes Merged  IOs Size  KBytes Merged  IOs Size  RWSize  QLen  Wait SvcTim Util')
+     def print_header2_verbose(self):
+         sys.stdout.write('#KBRead RMerged  Reads SizeKB  KBWrite WMerged Writes SizeKB\n')
+     def print_brief(self):
+@@ -333,17 +327,17 @@ class _diskCollectPrint(_CollectPrint):
+             self.ss.get_metric_value('disk.all.write_bytes'),
+             self.ss.get_metric_value('disk.all.write')))
+     def print_detail(self):
+-        for j in xrange(len(self.ss.metric_pmids)):
++        for j in range(len(self.ss.metric_pmids)):
+             try:
+-		if self.ss.metrics[j] == 'disk.dev.read':
+-		    (inst, iname) = pm.pmGetInDom(self.ss.metric_descs[j])
+-		    break
+-            except pmapi.pmErr, e:
++                if self.ss.metrics[j] == 'disk.dev.read':
++                    (inst, iname) = pm.pmGetInDom(self.ss.metric_descs[j])
++                    break
++            except pmapi.pmErr as e:
+                 iname = "X"
+ 
+         # metric values may be scalars or arrays depending on # of disks
+-        for j in xrange(len(iname)):
+-            print "%-10s %6d %6d %4d %4d  %6d %6d %4d %4d  %6d %6d %4d %6d %4d" % (
++        for j in range(len(iname)):
++            print("%-10s %6d %6d %4d %4d  %6d %6d %4d %4d  %6d %6d %4d %6d %4d" % (
+                 iname[j],
+                 self.ss.get_scalar_value('disk.dev.read_bytes', j),
+                 self.ss.get_scalar_value('disk.dev.read_merge', j),
+@@ -353,7 +347,7 @@ class _diskCollectPrint(_CollectPrint):
+                 self.ss.get_scalar_value('disk.dev.write_merge', j),
+                 self.ss.get_scalar_value('disk.dev.write', j),
+                 self.ss.get_scalar_value('disk.dev.blkwrite', j),
+-                0, 0, 0, 0, 0)
++                0, 0, 0, 0, 0))
+ # ??? replace 0 with required fields
+ 
+     def print_verbose(self):
+@@ -365,7 +359,7 @@ class _diskCollectPrint(_CollectPrint):
+             avgwrsz = self.ss.get_metric_value('disk.all.write_bytes')
+             avgwrsz /= self.ss.get_metric_value('disk.all.write')
+ 
+-        print '%6d %6d %6d %6d %7d %8d %6d %6d' % (
++        print('%6d %6d %6d %6d %7d %8d %6d %6d' % (
+             avgrdsz,
+             self.ss.get_metric_value('disk.all.read_merge'),
+             self.ss.get_metric_value('disk.all.read'),
+@@ -373,7 +367,7 @@ class _diskCollectPrint(_CollectPrint):
+             avgwrsz,
+             self.ss.get_metric_value('disk.all.write_merge'),
+             self.ss.get_metric_value('disk.all.write'),
+-            0)
++            0))
+ 
+ 
+ # _memoryCollectPrint ------------------------------------------------
+@@ -383,22 +377,22 @@ class _memoryCollectPrint(_CollectPrint)
+     def print_header1_brief(self):
+         sys.stdout.write('#<-----------Memory----------->')
+     def print_header1_verbose(self):
+-        print '# MEMORY SUMMARY'
++        print('# MEMORY SUMMARY')
+     def print_header2_brief(self):
+-        print '#Free Buff Cach Inac Slab  Map'
++        print('#Free Buff Cach Inac Slab  Map')
+     def print_header2_verbose(self):
+-        print '#<-------------------------------Physical Memory--------------------------------------><-----------Swap------------><-------Paging------>'
+-        print '#   Total    Used    Free    Buff  Cached    Slab  Mapped    Anon  Commit  Locked Inact Total  Used  Free   In  Out Fault MajFt   In  Out'
++        print('#<-------------------------------Physical Memory--------------------------------------><-----------Swap------------><-------Paging------>')
++        print('#   Total    Used    Free    Buff  Cached    Slab  Mapped    Anon  Commit  Locked Inact Total  Used  Free   In  Out Fault MajFt   In  Out')
+     def print_brief(self):
+-        print "%4dM %3dM %3dM %3dM %3dM %3dM " % (
++        sys.stdout.write("%4dM %3dM %3dM %3dM %3dM %3dM " % (
+             scale(self.ss.get_metric_value('mem.freemem'), 1000),
+             scale(self.ss.get_metric_value('mem.util.bufmem'), 1000),
+             scale(self.ss.get_metric_value('mem.util.cached'), 1000),
+             scale(self.ss.get_metric_value('mem.util.inactive'), 1000),
+             scale(self.ss.get_metric_value('mem.util.slab'), 1000),
+-            scale(self.ss.get_metric_value('mem.util.mapped'), 1000)),
++            scale(self.ss.get_metric_value('mem.util.mapped'), 1000)))
+     def print_verbose(self):
+-        print "%8dM %6dM %6dM %6dM %6dM %6dM %6dM %6dM %6dM %6dM %5dM %5dM %5dM %5dM %6d %6d %6d %6d %6d %6d " % (
++        print("%8dM %6dM %6dM %6dM %6dM %6dM %6dM %6dM %6dM %6dM %5dM %5dM %5dM %5dM %6d %6d %6d %6d %6d %6d " % (
+             scale(self.ss.get_metric_value('mem.physmem'), 1000),
+             scale(self.ss.get_metric_value('mem.util.used'), 1000),
+             scale(self.ss.get_metric_value('mem.freemem'), 1000),
+@@ -419,7 +413,7 @@ class _memoryCollectPrint(_CollectPrint)
+                   self.ss.get_metric_value('mem.vmstat.pgmajfault'), 1000),
+             scale(self.ss.get_metric_value('mem.vmstat.pgmajfault'), 1000),
+             scale(self.ss.get_metric_value('mem.vmstat.pgpgin'), 1000),
+-            scale(self.ss.get_metric_value('mem.vmstat.pgpgout'), 1000))
++            scale(self.ss.get_metric_value('mem.vmstat.pgpgout'), 1000)))
+ 
+ 
+ # _netCollectPrint --------------------------------------------------
+@@ -429,21 +423,21 @@ class _netCollectPrint(_CollectPrint):
+     def print_header1_brief(self):
+         sys.stdout.write('<----------Network---------->')
+     def print_header1_detail(self):
+-        print '# NETWORK STATISTICS (/sec)'
++        print('# NETWORK STATISTICS (/sec)')
+     def print_header1_verbose(self):
+-        print '\n\n# NETWORK SUMMARY (/sec)'
++        print('\n\n# NETWORK SUMMARY (/sec)')
+     def print_header2_brief(self):
+         sys.stdout.write(' KBIn  PktIn  KBOut  PktOut')
+     def print_header2_detail(self):
+-        print '#Num    Name   KBIn  PktIn SizeIn  MultI   CmpI  ErrsI  KBOut PktOut  SizeO   CmpO ErrsO'
++        print('#Num    Name   KBIn  PktIn SizeIn  MultI   CmpI  ErrsI  KBOut PktOut  SizeO   CmpO ErrsO')
+     def print_header2_verbose(self):
+-        print '# KBIn  PktIn SizeIn  MultI   CmpI  ErrsI  KBOut PktOut  SizeO   CmpO  ErrsO'
++        print('# KBIn  PktIn SizeIn  MultI   CmpI  ErrsI  KBOut PktOut  SizeO   CmpO  ErrsO')
+     def print_brief(self):
+-        print "%5d %6d %6d %6d" % (
++        sys.stdout.write("%5d %6d %6d %6d" % (
+             sum(self.ss.get_metric_value('network.interface.in.bytes')) / 1024,
+             sum(self.ss.get_metric_value('network.interface.in.packets')),
+             sum(self.ss.get_metric_value('network.interface.out.bytes')) / 1024,
+-            sum(self.ss.get_metric_value('network.interface.out.packets'))),
++            sum(self.ss.get_metric_value('network.interface.out.packets'))))
+     def average_packet_size(self, bytes, packets):
+         # calculate mean packet size safely (note that divisor may be zero)
+         result = 0
+@@ -456,7 +450,7 @@ class _netCollectPrint(_CollectPrint):
+         # don't include loopback; TODO: pmDelProfile would be more appropriate
+         self.ss.get_metric_value('network.interface.in.bytes')[0] = 0
+         self.ss.get_metric_value('network.interface.out.bytes')[0] = 0
+-        print '%6d %5d %6d %6d %6d %6d %6d %6d %6d %6d %7d' % (
++        print('%6d %5d %6d %6d %6d %6d %6d %6d %6d %6d %7d' % (
+             sum(self.ss.get_metric_value('network.interface.in.bytes')) / 1024,
+             sum(self.ss.get_metric_value('network.interface.in.packets')),
+             self.average_packet_size('in.bytes', 'in.packets'),
+@@ -467,18 +461,18 @@ class _netCollectPrint(_CollectPrint):
+             sum(self.ss.get_metric_value('network.interface.out.packets')),
+             self.average_packet_size('out.bytes', 'out.packets'),
+             sum(self.ss.get_metric_value('network.interface.total.mcasts')),
+-            sum(self.ss.get_metric_value('network.interface.out.errors')))
++            sum(self.ss.get_metric_value('network.interface.out.errors'))))
+     def print_detail(self):
+-        for j in xrange(len(self.ss.metric_pmids)):
++        for j in range(len(self.ss.metric_pmids)):
+             try:
+-		if self.ss.metrics[j] == 'network.interface.in.bytes':
+-		    (inst, iname) = pm.pmGetInDom(self.ss.metric_descs[j])
+-		    break
+-            except pmapi.pmErr, e: # pylint: disable-msg=C0103
++                if self.ss.metrics[j] == 'network.interface.in.bytes':
++                    (inst, iname) = pm.pmGetInDom(self.ss.metric_descs[j])
++                    break
++            except pmapi.pmErr as e: # pylint: disable-msg=C0103
+                 iname = "X"
+ 
+-        for j in xrange(len(iname)):
+-            print '%4d %-7s %6d %5d %6d %6d %6d %6d %6d %6d %6d %6d %7d' % (
++        for j in range(len(iname)):
++            print('%4d %-7s %6d %5d %6d %6d %6d %6d %6d %6d %6d %6d %7d' % (
+                 j, iname[j],
+                 self.ss.get_metric_value('network.interface.in.bytes')[j] / 1024,
+                 self.ss.get_metric_value('network.interface.in.packets')[j],
+@@ -493,7 +487,7 @@ class _netCollectPrint(_CollectPrint):
+                 self.ss.get_metric_value('network.interface.out.packets')[j]) / 1024,
+                     self.ss.get_metric_value('network.interface.total.mcasts')[j],
+                     self.ss.get_metric_value(
+-                    'network.interface.out.compressed')[j])
++                    'network.interface.out.compressed')[j]))
+ 
+ class _Options(object):
+     def __init__(self):
+@@ -532,11 +526,11 @@ class _Options(object):
+ 
+ 
+     def override(self, opt):
+-	""" Override a few standard PCP options to match free(1) """
+-	# pylint: disable=R0201
+-	if opt == 's' or opt == 'i' or opt == 'h' or opt == "p":
+-	    return 1
+-	return 0
++        """ Override a few standard PCP options to match free(1) """
++        # pylint: disable=R0201
++        if opt == 's' or opt == 'i' or opt == 'h' or opt == "p":
++            return 1
++        return 0
+ 
+     def option_callback(self, opt, optarg, index):
+         """ Perform setup for an individual command line option """
+@@ -550,13 +544,13 @@ class _Options(object):
+ 
+         # pylint: disable=W0613
+         if opt == 's':
+-            for ssx in xrange(len(optarg)):
++            for ssx in range(len(optarg)):
+                 self.subsys_arg = optarg[ssx:ssx+1]
+                 try:
+                     subsys.append(s_options[self.subsys_arg][0])
+                 except KeyError:
+-                    print sys.argv[0] + \
+-                    ": Unimplemented subsystem -s" + self.subsys_arg
++                    print(sys.argv[0] + \
++                    ": Unimplemented subsystem -s" + self.subsys_arg)
+                     sys.exit(1)
+                 if self.subsys_arg.isupper():
+                     self.verbosity = s_options[self.subsys_arg][1]
+@@ -651,14 +645,14 @@ if __name__ == '__main__':
+     try:
+         ss.setup_metrics(pm)
+         ss.get_stats(pm)
+-    except pmapi.pmErr, e:
++    except pmapi.pmErr as e:
+         if opts.replay_archive:
+             import textwrap
+-            print "One of the following metrics is required " + \
++            print("One of the following metrics is required " + \
+                   "but absent in " + input_file + "\n" + \
+-                  textwrap.fill(str(ss.metrics))
++                  textwrap.fill(str(ss.metrics)))
+         else:
+-            print "unable to setup metrics"
++            print("unable to setup metrics")
+             sys.exit(1)
+ 
+     for ssx in subsys:
+@@ -670,20 +664,20 @@ if __name__ == '__main__':
+             if ssx == 0:
+                 continue
+             ssx.print_header1()
+-        print
++        print('')
+         for ssx in subsys:
+             if ssx == 0:
+                 continue
+             ssx.print_header2()
+-        print
++        print('')
+ 
+     try:
+         i_samples = 0
+         while (i_samples < opts.n_samples) or (opts.n_samples == 0):
+             pm.pmtimevalSleep(delta)
+             if opts.verbosity != "brief" and len(subsys) > 1:
+-                print "\n### RECORD %d >>> %s <<< %s ###" % \
+-                      (i_samples+1, host, time.strftime("%a %b %d %H:%M:%S %Y"))
++                print("\n### RECORD %d >>> %s <<< %s ###" % \
++                     (i_samples+1, host, time.strftime("%a %b %d %H:%M:%S %Y")))
+ 
+             try:
+                 ss.get_stats(pm)
+@@ -698,9 +692,9 @@ if __name__ == '__main__':
+                     ssx.print_line()
+                 if opts.verbosity == "brief":
+                     print
+-            except pmapi.pmErr, e:
++            except pmapi.pmErr as e:
+                 if str(e).find("PM_ERR_EOL") != -1:
+-                    print str(e)
++                    print(str(e))
+                 break
+ 
+             i_samples += 1
+diff -Naurp pcp-3.10.2.orig/src/pmdas/dmcache/pmdadmcache.python pcp-3.10.2/src/pmdas/dmcache/pmdadmcache.python
+--- pcp-3.10.2.orig/src/pmdas/dmcache/pmdadmcache.python	2015-01-24 07:23:07.000000000 +1100
++++ pcp-3.10.2/src/pmdas/dmcache/pmdadmcache.python	2015-02-23 21:24:36.665658331 +1100
+@@ -2,7 +2,7 @@
+ Performance Metrics Domain Agent exporting Device Mapper Cache metrics.
+ '''
+ #
+-# Copyright (c) 2014 Red Hat.
++# Copyright (c) 2014-2015 Red Hat.
+ # 
+ # This program is free software; you can redistribute it and/or modify it
+ # under the terms of the GNU General Public License as published by the
+@@ -23,6 +23,10 @@ from cpmapi import (PM_SEM_DISCRETE, PM_
+ from subprocess import PIPE, Popen
+ from os import getenv
+ 
++import sys
++if sys.version >= '3':
++    long = int	# python2 to python3 portability (no long() in python3)
++
+ IOMODES = { 'writeback': 1, 'writethrough': 2, 'passthrough': 3 }
+ 
+ class DmCacheStats(Structure):
+@@ -65,18 +69,18 @@ class DmCacheStats(Structure):
+ 
+         self.size = long(data[2]) - long(data[1])
+         self.metadata_block_size = mbsize
+-        self.metadata_used  = long(data[5]) * mbsize / 1024
+-        self.metadata_total = long(data[6]) * mbsize / 1024
++        self.metadata_used  = long(data[5]) * int(mbsize / 1024)
++        self.metadata_total = long(data[6]) * int(mbsize / 1024)
+         self.cache_block_size = cbsize
+-        self.cache_used = long(data[8]) * cbsize / 1024
+-        self.cache_total = long(data[9]) * cbsize / 1024
++        self.cache_used = long(data[8]) * int(cbsize / 1024)
++        self.cache_total = long(data[9]) * int(cbsize / 1024)
+         self.read_hits = long(data[10])
+         self.read_misses = long(data[11])
+         self.write_hits = long(data[12])
+         self.write_misses = long(data[13])
+         self.demotions = long(data[14])
+         self.promotions = long(data[15])
+-        self.dirty = long(data[16]) * cbsize / 1024
++        self.dirty = long(data[16]) * int(cbsize / 1024)
+         self.iomode = IOMODES[data[18]]
+ 
+     def io_mode(self):
+@@ -206,7 +210,7 @@ class DmCachePMDA(PMDA):
+             output, errors = pipe.communicate()
+             if errors:
+                 self.err("refresh: %s error: %s" % (self.dmstatus, errors))
+-            for line in output.splitlines():
++            for line in output.decode().splitlines():
+                 if 'No devices found' in line:
+                     continue
+                 name = line[:line.find(':')]            # extract cache name
+diff -Naurp pcp-3.10.2.orig/src/pmdas/gluster/pmdagluster.python pcp-3.10.2/src/pmdas/gluster/pmdagluster.python
+--- pcp-3.10.2.orig/src/pmdas/gluster/pmdagluster.python	2015-01-21 02:18:01.000000000 +1100
++++ pcp-3.10.2/src/pmdas/gluster/pmdagluster.python	2015-02-23 21:24:36.666658330 +1100
+@@ -2,7 +2,7 @@
+ Performance Metrics Domain Agent exporting Gluster filesystem metrics.
+ '''
+ #
+-# Copyright (c) 2013-2014 Red Hat.
++# Copyright (c) 2013-2015 Red Hat.
+ # 
+ # This program is free software; you can redistribute it and/or modify it
+ # under the terms of the GNU General Public License as published by the
+@@ -30,6 +30,10 @@ import subprocess
+ 
+ import threading
+ 
++import sys
++if sys.version >= '3':
++    long = int	# python2 to python3 portability (no long() in python3)
++
+ VOL_INFO_COMMAND = 'gluster --xml volume info'
+ VOL_STOP_COMMAND = 'gluster --xml volume profile %s stop'
+ VOL_START_COMMAND = 'gluster --xml volume profile %s start'
+@@ -233,8 +237,8 @@ class GlusterPMDA(PMDA):
+             return [c_api.PM_ERR_INST, 0]
+         cache = cast(voidp, POINTER(GlusterBrick))
+         brick = cache.contents
+-        fileop = item / 4
+-        index = item % 4
++        fileop = int(item / 4)
++        index = int(item % 4)
+         if (index == 0):
+             return [brick.mintime[fileop], 1]
+         elif (index == 1):
+diff -Naurp pcp-3.10.2.orig/src/pmdas/simple/pmdasimple.python pcp-3.10.2/src/pmdas/simple/pmdasimple.python
+--- pcp-3.10.2.orig/src/pmdas/simple/pmdasimple.python	2015-01-21 02:18:01.000000000 +1100
++++ pcp-3.10.2/src/pmdas/simple/pmdasimple.python	2015-02-23 21:24:36.666658330 +1100
+@@ -2,7 +2,7 @@
+ Python implementation of the "simple" Performance Metrics Domain Agent.
+ '''
+ #
+-# Copyright (c) 2013 Red Hat.
++# Copyright (c) 2013,2015 Red Hat.
+ # 
+ # This program is free software; you can redistribute it and/or modify it
+ # under the terms of the GNU General Public License as published by the
+@@ -206,7 +206,7 @@ class SimplePMDA(PMDA):
+         self.configfile = PCP.pmGetConfig('PCP_PMDAS_DIR')
+         self.configfile += '/' + name + '/' + name + '.conf'
+ 
+-	self.connect_pmcd();
++        self.connect_pmcd()
+ 
+         self.color_indom = self.indom(0)
+         self.add_indom(pmdaIndom(self.color_indom, self.colors))
+diff -Naurp pcp-3.10.2.orig/src/pmdas/unbound/pmdaunbound.python pcp-3.10.2/src/pmdas/unbound/pmdaunbound.python
+--- pcp-3.10.2.orig/src/pmdas/unbound/pmdaunbound.python	2015-01-24 07:23:07.000000000 +1100
++++ pcp-3.10.2/src/pmdas/unbound/pmdaunbound.python	2015-02-23 21:24:36.667658329 +1100
+@@ -20,7 +20,10 @@ from pcp.pmapi import pmUnits
+ from pcp.pmda import PMDA, pmdaMetric, pmdaIndom
+ from subprocess import Popen, PIPE
+ from os import getenv
+-import string, shlex
++import shlex
++import sys
++if sys.version >= '3':
++    long = int	# python2 to python3 portability (no long() in python3)
+ 
+ class UnboundPMDA(PMDA):
+     '''
+@@ -40,9 +43,9 @@ class UnboundPMDA(PMDA):
+         p.wait()
+         try:
+             stdout, stderr = p.communicate()
+-            stdoutlines = string.split(stdout.strip(), '\n')
+-            for line in stdoutlines:
+-                keyval = string.split(line, '=')
++            stdoutlines = stdout.decode().strip()
++            for line in stdoutlines.split('\n'):
++                keyval = line.split('=')
+                 if keyval[0].startswith( 'histogram' ):
+                     # Replace "." with "_" to avoid splitting metric name in multiple sub sections
+                     keyval[0] = "histogram." + "_".join(str(v) for v in keyval[0].split(".")[1:])
+diff -Naurp pcp-3.10.2.orig/src/pmdas/zswap/pmdazswap.python pcp-3.10.2/src/pmdas/zswap/pmdazswap.python
+--- pcp-3.10.2.orig/src/pmdas/zswap/pmdazswap.python	2015-01-21 02:18:01.000000000 +1100
++++ pcp-3.10.2/src/pmdas/zswap/pmdazswap.python	2015-02-23 21:24:36.667658329 +1100
+@@ -2,7 +2,7 @@
+ Performance Metrics Domain Agent exporting Linux compressed swap metrics.
+ '''
+ #
+-# Copyright (c) 2014 Red Hat.
++# Copyright (c) 2014-2015 Red Hat.
+ # 
+ # This program is free software; you can redistribute it and/or modify it
+ # under the terms of the GNU General Public License as published by the
+@@ -20,6 +20,9 @@ from pcp.pmapi import pmUnits
+ from pcp.pmda import PMDA, pmdaMetric, pmdaIndom
+ from resource import getpagesize
+ from os import getenv, listdir
++import sys
++if sys.version >= '3':
++    long = int	# python2 to python3 portability (no long() in python3)
+ 
+ ZSWAP_PAGESIZE = getpagesize()
+ ZSWAP_STATS_PATH = '/sys/kernel/debug/zswap'
+diff -Naurp pcp-3.10.2.orig/src/pmiostat/pmiostat.py pcp-3.10.2/src/pmiostat/pmiostat.py
+--- pcp-3.10.2.orig/src/pmiostat/pmiostat.py	2015-01-21 02:18:01.000000000 +1100
++++ pcp-3.10.2/src/pmiostat/pmiostat.py	2015-02-23 21:24:36.667658329 +1100
+@@ -1,6 +1,6 @@
+ #!/usr/bin/python
+ #
+-# Copyright (C) 2014 Red Hat.
++# Copyright (C) 2014-2015 Red Hat.
+ #
+ # This program is free software; you can redistribute it and/or modify it
+ # under the terms of the GNU General Public License as published by the
+@@ -19,19 +19,19 @@ import sys
+ from pcp import pmapi, pmcc
+ from cpmapi import PM_TYPE_U64, PM_CONTEXT_ARCHIVE, PM_SPACE_KBYTE
+ 
+-IOSTAT_SD_METRICS = [ b'disk.dev.read', b'disk.dev.read_bytes',
+-                 b'disk.dev.write', b'disk.dev.write_bytes',
+-                 b'disk.dev.read_merge', b'disk.dev.write_merge',
+-                 b'disk.dev.blkread', b'disk.dev.blkwrite',
+-                 b'disk.dev.read_rawactive', b'disk.dev.write_rawactive',
+-                 b'disk.dev.avactive']
+-
+-IOSTAT_DM_METRICS = [ b'disk.dm.read', b'disk.dm.read_bytes',
+-                 b'disk.dm.write', b'disk.dm.write_bytes',
+-                 b'disk.dm.read_merge', b'disk.dm.write_merge',
+-                 b'disk.dm.blkread', b'disk.dm.blkwrite',
+-                 b'disk.dm.read_rawactive', b'disk.dm.write_rawactive',
+-                 b'disk.dm.avactive']
++IOSTAT_SD_METRICS = [ 'disk.dev.read', 'disk.dev.read_bytes',
++                 'disk.dev.write', 'disk.dev.write_bytes',
++                 'disk.dev.read_merge', 'disk.dev.write_merge',
++                 'disk.dev.blkread', 'disk.dev.blkwrite',
++                 'disk.dev.read_rawactive', 'disk.dev.write_rawactive',
++                 'disk.dev.avactive']
++
++IOSTAT_DM_METRICS = [ 'disk.dm.read', 'disk.dm.read_bytes',
++                 'disk.dm.write', 'disk.dm.write_bytes',
++                 'disk.dm.read_merge', 'disk.dm.write_merge',
++                 'disk.dm.blkread', 'disk.dm.blkwrite',
++                 'disk.dm.read_rawactive', 'disk.dm.write_rawactive',
++                 'disk.dm.avactive']
+ 
+ class IostatReport(pmcc.MetricGroupPrinter):
+     Hcount = 0
+@@ -51,45 +51,45 @@ class IostatReport(pmcc.MetricGroupPrint
+ 
+     def report(self, manager):
+         if 'dm' in IostatOptions.xflag:
+-            subtree = b'disk.dm'
++            subtree = 'disk.dm'
+         else:
+-            subtree = b'disk.dev'
++            subtree = 'disk.dev'
+         group = manager["iostat"]
+ 
+-        if group[subtree + b'.read_merge'].netPrevValues == None:
++        if group[subtree + '.read_merge'].netPrevValues == None:
+             # need two fetches to report rate converted counter metrics
+             return
+ 
+-        instlist = self.instlist(group, subtree + b'.read')
++        instlist = self.instlist(group, subtree + '.read')
+         dt = self.timeStampDelta(group)
+         timestamp = group.contextCache.pmCtime(int(group.timestamp)).rstrip()
+ 
+-        c_rrqm = self.curVals(group, subtree + b'.read_merge')
+-        p_rrqm = self.prevVals(group, subtree + b'.read_merge')
++        c_rrqm = self.curVals(group, subtree + '.read_merge')
++        p_rrqm = self.prevVals(group, subtree + '.read_merge')
+ 
+-        c_wrqm = self.curVals(group, subtree + b'.write_merge')
+-        p_wrqm = self.prevVals(group, subtree + b'.write_merge')
++        c_wrqm = self.curVals(group, subtree + '.write_merge')
++        p_wrqm = self.prevVals(group, subtree + '.write_merge')
+ 
+-        c_r = self.curVals(group, subtree + b'.read')
+-        p_r = self.prevVals(group, subtree + b'.read')
++        c_r = self.curVals(group, subtree + '.read')
++        p_r = self.prevVals(group, subtree + '.read')
+ 
+-        c_w = self.curVals(group, subtree + b'.write')
+-        p_w = self.prevVals(group, subtree + b'.write')
++        c_w = self.curVals(group, subtree + '.write')
++        p_w = self.prevVals(group, subtree + '.write')
+ 
+-        c_rkb = self.curVals(group, subtree + b'.read_bytes')
+-        p_rkb = self.prevVals(group, subtree + b'.read_bytes')
++        c_rkb = self.curVals(group, subtree + '.read_bytes')
++        p_rkb = self.prevVals(group, subtree + '.read_bytes')
+ 
+-        c_wkb = self.curVals(group, subtree + b'.write_bytes')
+-        p_wkb = self.prevVals(group, subtree + b'.write_bytes')
++        c_wkb = self.curVals(group, subtree + '.write_bytes')
++        p_wkb = self.prevVals(group, subtree + '.write_bytes')
+ 
+-        c_ractive = self.curVals(group, subtree + b'.read_rawactive')
+-        p_ractive = self.prevVals(group, subtree + b'.read_rawactive')
++        c_ractive = self.curVals(group, subtree + '.read_rawactive')
++        p_ractive = self.prevVals(group, subtree + '.read_rawactive')
+ 
+-        c_wactive = self.curVals(group, subtree + b'.write_rawactive')
+-        p_wactive = self.prevVals(group, subtree + b'.write_rawactive')
++        c_wactive = self.curVals(group, subtree + '.write_rawactive')
++        p_wactive = self.prevVals(group, subtree + '.write_rawactive')
+ 
+-        c_avactive = self.curVals(group, subtree + b'.avactive')
+-        p_avactive = self.prevVals(group, subtree + b'.avactive')
++        c_avactive = self.curVals(group, subtree + '.avactive')
++        p_avactive = self.prevVals(group, subtree + '.avactive')
+ 
+         # check availability
+         if p_rrqm == {} or p_wrqm == {} or p_r == {} or p_w == {} or p_rkb == {} \
+@@ -151,7 +151,7 @@ class IostatReport(pmcc.MetricGroupPrint
+             if tot_active:
+                     util = 100.0 * tot_active / dt
+ 
+-            device = inst.decode('utf-8')	# prepare name for printing
++            device = inst	# prepare name for printing
+             if "t" in IostatOptions.xflag:
+                 print("%-24s %-12s %7.1f %7.1f %6.1f %6.1f %8.1f %8.1f %8.2f %8.2f %7.1f %7.1f %7.1f %5.1f" \
+                 % (timestamp, device, rrqm, wrqm, r, w, rkb, wkb, avgrqsz, avgqsz, await, r_await, w_await, util))
+diff -Naurp pcp-3.10.2.orig/src/python/pcp/mmv.py pcp-3.10.2/src/python/pcp/mmv.py
+--- pcp-3.10.2.orig/src/python/pcp/mmv.py	2015-01-21 02:18:01.000000000 +1100
++++ pcp-3.10.2/src/python/pcp/mmv.py	2015-02-23 21:24:36.668658329 +1100
+@@ -1,7 +1,7 @@
+ # pylint: disable=C0103
+ """Wrapper module for libpcp_mmv - PCP Memory Mapped Values library
+ #
+-# Copyright (C) 2013 Red Hat.
++# Copyright (C) 2013,2015 Red Hat.
+ #
+ # This file is part of the "pcp" module, the python interfaces for the
+ # Performance Co-Pilot toolkit.
+@@ -85,6 +85,13 @@ class mmv_instance(Structure):
+     _fields_ = [("internal", c_int),
+                 ("external", c_char * MMV_NAMEMAX)]
+ 
++    def __init__(self, inst, name):
++        Structure.__init__(self)
++        if type(name) != type(b''):
++            name = name.encode('utf-8')
++        self.external = name
++        self.internal = inst
++
+ class mmv_indom(Structure):
+     """ Represents an instance domain (for set valued metrics)
+         Instance domains have associated instances - integer/string pairs.
+@@ -96,6 +103,16 @@ class mmv_indom(Structure):
+                 ("shorttext", c_char_p),
+                 ("helptext", c_char_p)]
+ 
++    def __init__(self, serial, shorttext = '', helptext = ''):
++        Structure.__init__(self)
++        if type(helptext) != type(b''):
++            helptext = helptext.encode('utf-8')
++        if type(shorttext) != type(b''):
++            shorttext = shorttext.encode('utf-8')
++        self.shorttext = shorttext
++        self.helptext = shorttext
++        self.serial = serial
++
+     def set_instances(self, instances):
+         """ Update the instances and counts fields for this indom """
+         self.count = len(instances)
+@@ -118,6 +135,20 @@ class mmv_metric(Structure):
+                 ("shorttext", c_char_p),
+                 ("helptext", c_char_p)]
+ 
++    def __init__(self, name, item, typeof, semantics, dimension, indom = 0, shorttext = '', helptext = ''):
++        Structure.__init__(self)
++        if type(name) != type(b''):
++            name = name.encode('utf-8')
++        if type(helptext) != type(b''):
++            helptext = helptext.encode('utf-8')
++        if type(shorttext) != type(b''):
++            shorttext = shorttext.encode('utf-8')
++        self.shorttext = shorttext
++        self.helptext = shorttext
++        self.typeof = typeof
++        self.indom = indom
++        self.item = item
++
+ ##
+ # PCP Memory Mapped Value Services
+ 
+@@ -185,6 +216,8 @@ class MemoryMappedValues(object):
+     """
+ 
+     def __init__(self, name, flags = 0, cluster = 42):
++        if type(name) != type(b''):
++            name = name.encode('utf-8')
+         self._name = name
+         self._cluster = cluster  # PMID cluster number (domain is MMV)
+         self._flags = flags      # MMV_FLAGS_* flags
+@@ -263,6 +296,10 @@ class MemoryMappedValues(object):
+             a convenience only for situations where performance will not
+             be affected by repeated (linear) name/inst lookups.
+         """
++        if type(name) != type(b''):
++            name = name.encode('utf-8')
++        if type(inst) != type(b''):
++            inst = inst.encode('utf-8')
+         return LIBPCP_MMV.mmv_lookup_value_desc(self._handle, name, inst)
+ 
+     def add(self, mapping, value):
+@@ -279,6 +316,8 @@ class MemoryMappedValues(object):
+ 
+     def set_string(self, mapping, value):
+         """ Set the string mapped metric to a given value """
++        if type(value) != type(b''):
++            value = value.encode('utf-8')
+         LIBPCP_MMV.mmv_set_string(self._handle, mapping, value, len(value))
+ 
+     def interval_start(self, mapping):
+@@ -294,25 +333,47 @@ class MemoryMappedValues(object):
+ 
+     def lookup_add(self, name, inst, value):
+         """ Lookup the named metric[instance] and add a value to it """
++        if type(name) != type(b''):
++            name = name.encode('utf-8')
++        if type(inst) != type(b''):
++            inst = inst.encode('utf-8')
+         LIBPCP_MMV.mmv_stats_add(self._handle, name, inst, value)
+ 
+     def lookup_inc(self, name, inst):
+         """ Lookup the named metric[instance] and add one to it """
++        if type(name) != type(b''):
++            name = name.encode('utf-8')
++        if type(inst) != type(b''):
++            inst = inst.encode('utf-8')
+         LIBPCP_MMV.mmv_stats_inc(self._handle, name, inst)
+ 
+     def lookup_set(self, name, inst, value):
+         """ Lookup the named metric[instance] and set its value """
++        if type(name) != type(b''):
++            name = name.encode('utf-8')
++        if type(inst) != type(b''):
++            inst = inst.encode('utf-8')
+         LIBPCP_MMV.mmv_stats_set(self._handle, name, inst, value)
+ 
+     def lookup_interval_start(self, name, inst):
+         """ Lookup the named metric[instance] and start an interval
+             The opaque handle returned is passed to interval_end().
+         """
++        if type(name) != type(b''):
++            name = name.encode('utf-8')
++        if type(inst) != type(b''):
++            inst = inst.encode('utf-8')
+         return LIBPCP_MMV.mmv_stats_interval_start(self._handle,
+                                                    None, name, inst)
+ 
+     def lookup_set_string(self, name, inst, s):
+         """ Lookup the named metric[instance] and set its string value """
++        if type(name) != type(b''):
++            name = name.encode('utf-8')
++        if type(inst) != type(b''):
++            inst = inst.encode('utf-8')
++        if type(s) != type(b''):
++            s = s.encode('utf-8')
+         LIBPCP_MMV.mmv_stats_set_strlen(self._handle, name, inst, s, len(s))
+ 
+     def lookup_add_fallback(self, name, inst, fall, value):
+@@ -321,6 +382,10 @@ class MemoryMappedValues(object):
+             One example use is: add value to bucketN else use a catch-all
+                                 bucket such as "other"
+         """
++        if type(name) != type(b''):
++            name = name.encode('utf-8')
++        if type(inst) != type(b''):
++            inst = inst.encode('utf-8')
+         LIBPCP_MMV.mmv_stats_add_fallback(self._handle, name, inst, fall, value)
+ 
+     def lookup_inc_fallback(self, name, inst, fallback):
+@@ -328,5 +393,9 @@ class MemoryMappedValues(object):
+             If instance is not found, fallback to using a second instance
+             One sample use is: inc value of BucketA, else inc a catch-all
+         """
++        if type(name) != type(b''):
++            name = name.encode('utf-8')
++        if type(inst) != type(b''):
++            inst = inst.encode('utf-8')
+         LIBPCP_MMV.mmv_stats_inc_fallback(self._handle, name, inst, fallback)
+ 
+diff -Naurp pcp-3.10.2.orig/src/python/pcp/pmapi.py pcp-3.10.2/src/python/pcp/pmapi.py
+--- pcp-3.10.2.orig/src/python/pcp/pmapi.py	2015-01-24 07:23:07.000000000 +1100
++++ pcp-3.10.2/src/python/pcp/pmapi.py	2015-02-23 21:24:36.669658327 +1100
+@@ -100,18 +100,18 @@ LIBC = CDLL(find_library("c"))
+ #
+ import sys
+ 
+-if sys.version > '3':
++if sys.version >= '3':
+     integer_types = (int,)
+     long = int
+ else:
+     integer_types = (int, long,)
+ 
+ def pyFileToCFile(fileObj):
+-    if sys.version > '3':
++    if sys.version >= '3':
+         from os import fdopen
+         ctypes.pythonapi.PyObject_AsFileDescriptor.restype = ctypes.c_int
+         ctypes.pythonapi.PyObject_AsFileDescriptor.argtypes = [ctypes.py_object]
+-        return fdopen(ctypes.pythonapi.PyObject_AsFileDescriptor(pyfile), "r")
++        return fdopen(ctypes.pythonapi.PyObject_AsFileDescriptor(fileObj), "r", closefd=False)
+     else:
+         ctypes.pythonapi.PyFile_AsFile.restype = ctypes.c_void_p
+         ctypes.pythonapi.PyFile_AsFile.argtypes = [ctypes.py_object]
+@@ -138,8 +138,8 @@ class pmErr(Exception):
+         errStr = create_string_buffer(c_api.PM_MAXERRMSGLEN)
+         errStr = LIBPCP.pmErrStr_r(self.args[0], errStr, c_api.PM_MAXERRMSGLEN)
+         for index in range(1, len(self.args)):
+-            errStr += " " + str(self.args[index])
+-        return errStr
++            errStr += b" " + str(self.args[index]).encode('utf-8')
++        return str(errStr.decode())
+ 
+     def progname(self):
+         return c_char_p.in_dll(LIBPCP, "pmProgname").value
+@@ -177,6 +177,8 @@ class timeval(Structure):
+         """ Construct timeval from a string using pmParseInterval """
+         tvp = builder()
+         errmsg = c_char_p()
++        if type(interval) != type(b''):
++            interval = interval.encode('utf-8')
+         status = LIBPCP.pmParseInterval(interval, byref(tvp), byref(errmsg))
+         if status < 0:
+             raise pmErr(status, errmsg)
+@@ -288,7 +290,8 @@ class pmUnits(Structure):
+ 
+     def __str__(self):
+         unitstr = ctypes.create_string_buffer(64)
+-        return str(LIBPCP.pmUnitsStr_r(self, unitstr, 64))
++        result = LIBPCP.pmUnitsStr_r(self, unitstr, 64)
++        return str(result.decode())
+ 
+ class pmValueBlock(Structure):
+     """Value block bitfields for different compilers
+@@ -454,7 +457,7 @@ class pmMetricSpec(Structure):
+                  ("ninst", c_int),
+                  ("inst",  POINTER(c_char_p)) ]
+     def __str__(self):
+-        insts = map(lambda x: str(self.inst[x]), range(self.ninst))
++        insts = list(map(lambda x: str(self.inst[x]), range(self.ninst)))
+         fields = (addressof(self), self.isarch, self.source, insts)
+         return "pmMetricSpec@%#lx src=%s metric=%s insts=" % fields
+ 
+@@ -464,6 +467,8 @@ class pmMetricSpec(Structure):
+         errmsg = c_char_p()
+         if type(source) != type(b''):
+             source = source.encode('utf-8')
++        if type(string) != type(b''):
++            string = string.encode('utf-8')
+         status = LIBPCP.pmParseMetricSpec(string, isarch, source,
+                                         byref(result), byref(errmsg))
+         if status < 0:
+@@ -1094,11 +1099,13 @@ class pmContext(object):
+         status = LIBPCP.pmUseContext(self.ctx)
+         if status < 0:
+             raise pmErr(status)
++        if type(name) != type(b''):
++            name = name.encode('utf-8')
+         status = LIBPCP.pmGetChildren(name, byref(offspring))
+         if status < 0:
+             raise pmErr(status)
+         if status > 0:
+-            childL = map(lambda x: str(offspring[x]), range(status))
++            childL = list(map(lambda x: str(offspring[x]), range(status)))
+             LIBC.free(offspring)
+         else:
+             return None
+@@ -1113,13 +1120,15 @@ class pmContext(object):
+         status = LIBPCP.pmUseContext(self.ctx)
+         if status < 0:
+             raise pmErr(status)
++        if type(name) != type(b''):
++            name = name.encode('utf-8')
+         status = LIBPCP.pmGetChildrenStatus(name,
+                         byref(offspring), byref(childstat))
+         if status < 0:
+             raise pmErr(status)
+         if status > 0:
+-            childL = map(lambda x: str(offspring[x]), range(status))
+-            statL = map(lambda x: int(childstat[x]), range(status))
++            childL = list(map(lambda x: str(offspring[x]), range(status)))
++            statL = list(map(lambda x: int(childstat[x]), range(status)))
+             LIBC.free(offspring)
+             LIBC.free(childstat)
+         else:
+@@ -1145,6 +1154,8 @@ class pmContext(object):
+         status = LIBPCP.pmUseContext(self.ctx)
+         if status < 0:
+             raise pmErr(status)
++        if type(filename) != type(b''):
++            filename = filename.encode('utf-8')
+         status = LIBPCP.pmLoadNameSpace(filename)
+         if status < 0:
+             raise pmErr(status)
+@@ -1156,21 +1167,25 @@ class pmContext(object):
+         c_uint pmid [] = pmLookupName("MetricName")
+         c_uint pmid [] = pmLookupName(("MetricName1", "MetricName2", ...))
+         """
+-        if type(nameA) == type(""):
++        status = LIBPCP.pmUseContext(self.ctx)
++        if status < 0:
++            raise pmErr(status)
++        if type(nameA) == type('') or type(nameA) == type(b''):
+             n = 1
+         else:
+             n = len(nameA)
+         names = (c_char_p * n)()
+-        if type(nameA) == type(""):
++        if type(nameA) == type(''):
++            names[0] = c_char_p(nameA.encode('utf-8'))
++        elif type(nameA) == type(b''):
+             names[0] = c_char_p(nameA)
+         else:
+             for i in range(len(nameA)):
+-                names[i] = c_char_p(nameA[i])
+-
++                if type(nameA[i]) == type(b''):
++                    names[i] = c_char_p(nameA[i])
++                else:
++                    names[i] = c_char_p(nameA[i].encode('utf-8'))
+         pmidA = (c_uint * n)()
+-        status = LIBPCP.pmUseContext(self.ctx)
+-        if status < 0:
+-            raise pmErr(status)
+         LIBPCP.pmLookupName.argtypes = [c_int, (c_char_p * n), POINTER(c_uint)]
+         status = LIBPCP.pmLookupName(n, names, pmidA)
+         if status < 0:
+@@ -1185,31 +1200,31 @@ class pmContext(object):
+         """PMAPI - Return list of all metric names having this identical PMID
+         tuple names = pmNameAll(metric_id)
+         """
+-        nameA_p = POINTER(c_char_p)()
+         status = LIBPCP.pmUseContext(self.ctx)
+         if status < 0:
+             raise pmErr(status)
++        nameA_p = POINTER(c_char_p)()
+         status = LIBPCP.pmNameAll(pmid, byref(nameA_p))
+         if status < 0:
+             raise pmErr(status)
+-        nameL = map(lambda x: str(nameA_p[x]), range(status))
+-        LIBC.free( nameA_p )
++        nameL = list(map(lambda x: str(nameA_p[x].decode()), range(status)))
++        LIBC.free(nameA_p)
+         return nameL
+ 
+     def pmNameID(self, pmid):
+         """PMAPI - Return a metric name from a PMID
+         name = pmNameID(self.metric_id)
+         """
+-        k = c_char_p()
++        name = c_char_p()
+         status = LIBPCP.pmUseContext(self.ctx)
+         if status < 0:
+             raise pmErr(status)
+-        status = LIBPCP.pmNameID(pmid, byref(k))
++        status = LIBPCP.pmNameID(pmid, byref(name))
+         if status < 0:
+             raise pmErr(status)
+-        name = k.value
+-        LIBC.free( k )
+-        return name
++        result = name.value
++        LIBC.free(name)
++        return str(result.decode())
+ 
+     def pmTraversePMNS(self, name, callback):
+         """PMAPI - Scan namespace, depth first, run CALLBACK at each node
+@@ -1219,6 +1234,8 @@ class pmContext(object):
+         if status < 0:
+             raise pmErr(status)
+         cb = traverseCB_type(callback)
++        if type(name) != type(b''):
++            name = name.encode('utf-8')
+         status = LIBPCP.pmTraversePMNS(name, cb)
+         if status < 0:
+             raise pmErr(status)
+@@ -1238,6 +1255,10 @@ class pmContext(object):
+         """PMAPI - Register a derived metric name and definition
+         pm.pmRegisterDerived("MetricName", "MetricName Expression")
+         """
++        if type(name) != type(b''):
++            name = name.encode('utf-8')
++        if type(expr) != type(b''):
++            expr = expr.encode('utf-8')
+         status = LIBPCP.pmRegisterDerived(name, expr)
+         if status != 0:
+             raise pmErr(status)
+@@ -1245,11 +1266,13 @@ class pmContext(object):
+         if status < 0:
+             raise pmErr(status)
+         
+-    def pmLoadDerivedConfig(self, f):
++    def pmLoadDerivedConfig(self, fname):
+         """PMAPI - Register derived metric names and definitions from a file
+         pm.pmLoadDerivedConfig("FileName")
+         """
+-        status = LIBPCP.pmLoadDerivedConfig(f)
++        if type(fname) != type(b''):
++            fname = fname.encode('utf-8')
++        status = LIBPCP.pmLoadDerivedConfig(fname)
+         if status < 0:
+             raise pmErr(status)
+         status = LIBPCP.pmReconnectContext(self.ctx)
+@@ -1262,7 +1285,8 @@ class pmContext(object):
+         definition cannot be parsed
+         pm.pmRegisterDerived()
+         """
+-        return str(LIBPCP.pmDerivedErrStr())
++        result = LIBPCP.pmDerivedErrStr()
++        return str(result.decode())
+ 
+     ##
+     # PMAPI Metrics Description Services
+@@ -1329,9 +1353,9 @@ class pmContext(object):
+         status = LIBPCP.pmLookupInDomText(get_indom(pmdesc), kind, byref(buf))
+         if status < 0:
+             raise pmErr(status)
+-        text = str(buf.value)
++        result = buf.value
+         LIBC.free(buf)
+-        return text
++        return str(result.decode())
+ 
+     def pmLookupText(self, pmid, kind = c_api.PM_TEXT_ONELINE):
+         """PMAPI - Lookup the description of a metric from its pmID
+@@ -1366,8 +1390,8 @@ class pmContext(object):
+         if status < 0:
+             raise pmErr(status)
+         if status > 0:
+-            nameL = map(lambda x: str(nameA_p[x]), range(status))
+-            instL = map(lambda x: int(instA_p[x]), range(status))
++            nameL = list(map(lambda x: str(nameA_p[x].decode()), range(status)))
++            instL = list(map(lambda x: int(instA_p[x]), range(status)))
+             LIBC.free(instA_p)
+             LIBC.free(nameA_p)
+         else:
+@@ -1383,6 +1407,8 @@ class pmContext(object):
+         status = LIBPCP.pmUseContext(self.ctx)
+         if status < 0:
+             raise pmErr(status)
++        if type(name) != type(b''):
++            name = name.encode('utf-8')
+         status = LIBPCP.pmLookupInDom(get_indom(pmdesc), name)
+         if status < 0:
+             raise pmErr(status)
+@@ -1402,9 +1428,9 @@ class pmContext(object):
+         status = LIBPCP.pmNameInDom(get_indom(pmdesc), instval, byref(name_p))
+         if status < 0:
+             raise pmErr(status)
+-        outName = str(name_p.value)
++        result = name_p.value
+         LIBC.free(name_p)
+-        return outName
++        return str(result.decode())
+ 
+     ##
+     # PMAPI Context Services
+@@ -1537,7 +1563,8 @@ class pmContext(object):
+         """
+         buflen = c_api.PM_LOG_MAXHOSTLEN
+         buffer = ctypes.create_string_buffer(buflen)
+-        return str(LIBPCP.pmGetContextHostName_r(self.ctx, buffer, buflen))
++        result = LIBPCP.pmGetContextHostName_r(self.ctx, buffer, buflen)
++        return str(result.decode())
+ 
+     ##
+     # PMAPI Timezone Services
+@@ -1555,6 +1582,8 @@ class pmContext(object):
+     @staticmethod
+     def pmNewZone(tz):
+         """PMAPI - Create new zone handle and set reporting timezone """
++        if type(tz) != type(b''):
++            tz = tz.encode('utf-8')
+         status = LIBPCP.pmNewZone(tz)
+         if status < 0:
+             raise pmErr(status)
+@@ -1575,9 +1604,9 @@ class pmContext(object):
+         status = LIBPCP.pmWhichZone(byref(tz_p))
+         if status < 0:
+             raise pmErr(status)
+-        tz = str(tz_p.value)
++        tz = tz_p.value
+         LIBC.free(tz_p)
+-        return tz
++        return str(tz.decode())
+ 
+     def pmLocaltime(self, seconds):
+         """PMAPI - convert the date and time for a reporting timezone """
+@@ -1597,7 +1626,7 @@ class pmContext(object):
+         result = ctypes.create_string_buffer(32)
+         timetp = c_long(long(seconds))
+         LIBPCP.pmCtime(byref(timetp), result)
+-        return str(result.value)
++        return str(result.value.decode())
+ 
+     ##
+     # PMAPI Metrics Services
+@@ -1680,8 +1709,8 @@ class pmContext(object):
+         if status < 0:
+             raise pmErr(status)
+         if status > 0:
+-            nameL = map(lambda x: str(nameA_p[x]), range(status))
+-            instL = map(lambda x: int(instA_p[x]), range(status))
++            nameL = list(map(lambda x: str(nameA_p[x].decode()), range(status)))
++            instL = list(map(lambda x: int(instA_p[x]), range(status)))
+             LIBC.free(instA_p)
+             LIBC.free(nameA_p)
+         else:
+@@ -1697,6 +1726,8 @@ class pmContext(object):
+         status = LIBPCP.pmUseContext(self.ctx)
+         if status < 0:
+             raise pmErr(status)
++        if type(name) != type(b''):
++            name = name.encode('utf-8')
+         status = LIBPCP.pmLookupInDomArchive(get_indom(pmdesc), name)
+         if status < 0:
+             raise pmErr(status)
+@@ -1715,9 +1746,9 @@ class pmContext(object):
+         status = LIBPCP.pmNameInDomArchive(indom, inst, byref(name_p))
+         if status < 0:
+             raise pmErr(status)
+-        outName = str(name_p.value)
++        result = name_p.value
+         LIBC.free(name_p)
+-        return outName
++        return str(result.decode())
+ 
+     def pmFetchArchive(self):
+         """PMAPI - Fetch measurements from the target source
+@@ -1740,13 +1771,17 @@ class pmContext(object):
+     @staticmethod
+     def pmGetConfig(variable):
+         """PMAPI - Return value from environment or pcp config file """
+-        return str(LIBPCP.pmGetConfig(variable))
++        if type(variable) != type(b''):
++            variable = variable.encode('utf-8')
++        result = LIBPCP.pmGetConfig(variable)
++        return str(result.decode())
+ 
+     @staticmethod
+     def pmErrStr(code):
+         """PMAPI - Return value from environment or pcp config file """
+         errstr = ctypes.create_string_buffer(c_api.PM_MAXERRMSGLEN)
+-        return str(LIBPCP.pmErrStr_r(code, errstr, c_api.PM_MAXERRMSGLEN))
++        result = LIBPCP.pmErrStr_r(code, errstr, c_api.PM_MAXERRMSGLEN)
++        return str(result.decode())
+ 
+     @staticmethod
+     def pmExtractValue(valfmt, vlist, intype, outtype):
+@@ -1799,19 +1834,22 @@ class pmContext(object):
+     def pmUnitsStr(units):
+         """PMAPI - Convert units struct to a readable string """
+         unitstr = ctypes.create_string_buffer(64)
+-        return str(LIBPCP.pmUnitsStr_r(units, unitstr, 64))
++        result = LIBPCP.pmUnitsStr_r(units, unitstr, 64)
++        return str(result.decode())
+ 
+     @staticmethod
+     def pmNumberStr(value):
+         """PMAPI - Convert double value to fixed-width string """
+         numstr = ctypes.create_string_buffer(8)
+-        return str(LIBPCP.pmNumberStr_r(value, numstr, 8))
++        result = LIBPCP.pmNumberStr_r(value, numstr, 8)
++        return str(result.decode())
+ 
+     @staticmethod
+     def pmIDStr(pmid):
+         """PMAPI - Convert a pmID to a readable string """
+         pmidstr = ctypes.create_string_buffer(32)
+-        return str(LIBPCP.pmIDStr_r(pmid, pmidstr, 32))
++        result = LIBPCP.pmIDStr_r(pmid, pmidstr, 32)
++        return str(result.decode())
+ 
+     @staticmethod
+     def pmInDomStr(pmdescp):
+@@ -1819,7 +1857,8 @@ class pmContext(object):
+         "indom" = pmGetInDom(pmDesc pmdesc)
+         """
+         indomstr = ctypes.create_string_buffer(32)
+-        return str(LIBPCP.pmInDomStr_r(get_indom(pmdescp), indomstr, 32))
++        result = LIBPCP.pmInDomStr_r(get_indom(pmdescp), indomstr, 32)
++        return str(result.decode())
+ 
+     @staticmethod
+     def pmTypeStr(typed):
+@@ -1827,7 +1866,8 @@ class pmContext(object):
+         "type" = pmTypeStr(c_api.PM_TYPE_FLOAT)
+         """
+         typestr = ctypes.create_string_buffer(32)
+-        return str(LIBPCP.pmTypeStr_r(typed, typestr, 32))
++        result = LIBPCP.pmTypeStr_r(typed, typestr, 32)
++        return str(result.decode())
+ 
+     @staticmethod
+     def pmAtomStr(atom, typed):
+@@ -1835,7 +1875,8 @@ class pmContext(object):
+         "value" = pmAtomStr(atom, c_api.PM_TYPE_U32)
+         """
+         atomstr = ctypes.create_string_buffer(96)
+-        return str(LIBPCP.pmAtomStr(byref(atom), typed, atomstr, 96))
++        result = LIBPCP.pmAtomStr_r(byref(atom), typed, atomstr, 96)
++        return str(result.decode())
+ 
+     @staticmethod
+     def pmPrintValue(fileObj, result, ptype, vset_idx, vlist_idx, min_width):
+@@ -1885,13 +1926,16 @@ class pmContext(object):
+ 
+     @staticmethod
+     def pmParseUnitsStr(string):
+-        assert isinstance(string, basestring)
++        if type(string) != type('') and type(string) != type(b''):
++            raise pmErr(c_api.PM_ERR_CONV, str(string))
++        if type(string) != type(b''):
++            string = string.encode('utf-8')
+         result = pmUnits()
+         errmsg = c_char_p()
+         multiplier = c_double()
+         status = LIBPCP.pmParseUnitsStr(string, byref(result), byref(multiplier), byref(errmsg))
+         if status < 0:
+-            text = str(errmsg.value)
++            text = str(errmsg.value.decode())
+             LIBC.free(errmsg)
+             raise pmErr(status, text)
+         return (result, multiplier.value)
+diff -Naurp pcp-3.10.2.orig/src/python/pcp/pmcc.py pcp-3.10.2/src/python/pcp/pmcc.py
+--- pcp-3.10.2.orig/src/python/pcp/pmcc.py	2015-01-21 02:18:01.000000000 +1100
++++ pcp-3.10.2/src/python/pcp/pmcc.py	2015-02-23 21:24:36.670658327 +1100
+@@ -1,8 +1,6 @@
+ """ Convenience Classes building on the base PMAPI extension module """
+ #
+-# pmcc.py
+-#
+-# Copyright (C) 2013-2014 Red Hat
++# Copyright (C) 2013-2015 Red Hat
+ # Copyright (C) 2009-2012 Michael T. Werner
+ #
+ # This file is part of the "pcp" module, the python interfaces for the
+@@ -33,11 +31,15 @@ class MetricCore(object):
+     PMAPI metrics are unique by name, and MetricCores should be also
+     rarely, some PMAPI metrics with different names might have identical PMIDs
+     PMAPI metrics are unique by (name) and by (name,pmid) - _usually_ by (pmid)
+-    too.
++    too.  Note that names here (and only here) are stored as byte strings for
++    direct PMAPI access.  All dictionaries/caching strategies built using the
++    core structure use native strings (i.e., not byte strings in python3).
+     """
+ 
+     def __init__(self, ctx, name, pmid):
+         self.ctx = ctx
++        if type(name) != type(b''):
++            name = name.encode('utf-8')
+         self.name = name
+         self.pmid = pmid
+         self.desc = None
+@@ -73,7 +75,7 @@ class Metric(object):
+     def _R_ctx(self):
+         return self._core.ctx
+     def _R_name(self):
+-        return self._core.name
++        return self._core.name.decode()
+     def _R_pmid(self):
+         return self._core.pmid
+     def _R_desc(self):
+@@ -105,7 +107,7 @@ class Metric(object):
+             try:
+                 name = instD[instval.inst]
+             except KeyError:
+-                name = b''
++                name = ''
+             outAtom = self.ctx.pmExtractValue(
+                     vset.valfmt, instval, self.desc.type, self._convType)
+             if self._convUnits:
+@@ -151,7 +153,7 @@ class Metric(object):
+             try:
+                 name = instD[instval.inst]
+             except KeyError:
+-                name = b''
++                name = ''
+             outAtom = self.ctx.pmExtractValue(vset.valfmt,
+                     instval, self.desc.type, PM_TYPE_DOUBLE)
+             poutAtom = self.ctx.pmExtractValue(pvset.valfmt,
+@@ -281,7 +283,7 @@ class MetricCache(pmContext):
+                     instmap = {}
+             self._mcIndomD.update({indom: instmap})
+ 
+-        self._mcByNameD.update({core.name: core})
++        self._mcByNameD.update({core.name.decode(): core})
+         self._mcByPmidD.update({core.pmid: core})
+ 
+     def mcGetCoresByName(self, nameL):
+@@ -291,8 +293,8 @@ class MetricCache(pmContext):
+         errL = None
+         # lookup names in cache
+         for index, name in enumerate(nameL):
+-            if type(name) != type(b''):
+-                name = name.encode('utf-8')
++            if type(name) == type(b''):
++                name = name.decode()
+             # lookup metric core in cache
+             core = self._mcByNameD.get(name)
+             if not core:
+@@ -306,8 +308,6 @@ class MetricCache(pmContext):
+         if missD:
+             idL, errL = self.mcFetchPmids(missD.keys())
+             for name, pmid in idL:
+-                if type(name) != type(b''):
+-                    name = name.encode('utf-8')
+                 if pmid == PM_ID_NULL:
+                     # fetch failed for the given metric name
+                     if not errL:
+@@ -354,7 +354,7 @@ class MetricCache(pmContext):
+             print >> stderr, fail
+             raise SystemExit(1)
+ 
+-        return zip(nameA, pmidArray), errL
++        return zip(nameL, pmidArray), errL
+ 
+ 
+ class MetricGroup(dict):
+@@ -412,6 +412,12 @@ class MetricGroup(dict):
+         self._altD = {}
+         self.mgAdd(inL)
+ 
++    def __setitem__(self, attr, value = []):
++        if attr in self:
++            raise KeyError("metric group with that key already exists")
++        else:
++            dict.__setitem__(self, attr, MetricGroup(self, inL = value))
++
+     ##
+     # methods
+ 
+diff -Naurp pcp-3.10.2.orig/src/python/pcp/pmda.py pcp-3.10.2/src/python/pcp/pmda.py
+--- pcp-3.10.2.orig/src/python/pcp/pmda.py	2015-01-24 07:23:07.000000000 +1100
++++ pcp-3.10.2/src/python/pcp/pmda.py	2015-02-23 21:24:36.670658327 +1100
+@@ -1,7 +1,7 @@
+ # pylint: disable=C0103
+ """Wrapper module for libpcp_pmda - Performace Co-Pilot Domain Agent API
+ #
+-# Copyright (C) 2013-2014 Red Hat.
++# Copyright (C) 2013-2015 Red Hat.
+ #
+ # This file is part of the "pcp" module, the python interfaces for the
+ # Performance Co-Pilot toolkit.
+@@ -86,7 +86,7 @@ class pmdaInstid(Structure):
+     def __init__(self, instid, name):
+         Structure.__init__(self)
+         self.i_inst = instid
+-        self.i_name = name
++        self.i_name = name.encode('utf-8')
+ 
+     def __str__(self):
+         return "pmdaInstid@%#lx index=%d name=%s" % (addressof(self), self.i_inst, self.i_name)
+@@ -117,7 +117,8 @@ class pmdaIndom(Structure):
+     def set_dict_instances(self, indom, insts):
+         LIBPCP_PMDA.pmdaCacheOp(indom, cpmda.PMDA_CACHE_INACTIVE)
+         for key in insts.keys():
+-            LIBPCP_PMDA.pmdaCacheStore(indom, cpmda.PMDA_CACHE_ADD, key, byref(insts[key]))
++            key8 = key.encode('utf-8')
++            LIBPCP_PMDA.pmdaCacheStore(indom, cpmda.PMDA_CACHE_ADD, key8, byref(insts[key]))
+         LIBPCP_PMDA.pmdaCacheOp(indom, cpmda.PMDA_CACHE_SAVE)
+ 
+     def set_instances(self, indom, insts):
+@@ -271,11 +272,11 @@ class MetricDispatch(object):
+             name = (c_char_p)()
+             sts = LIBPCP_PMDA.pmdaCacheLookup(indom, instance, byref(name), None)
+             if (sts == cpmda.PMDA_CACHE_ACTIVE):
+-                return name.value
++                return str(name.value.decode())
+         elif (entry.it_numinst > 0 and entry.it_indom == indom):
+             for inst in entry.it_set:
+                 if (inst.i_inst == instance):
+-                    return inst.i_name
++                    return str(inst.i_name.decode())
+         return None
+ 
+ 
+diff -Naurp pcp-3.10.2.orig/src/python/pcp/pmi.py pcp-3.10.2/src/python/pcp/pmi.py
+--- pcp-3.10.2.orig/src/python/pcp/pmi.py	2015-01-21 02:18:01.000000000 +1100
++++ pcp-3.10.2/src/python/pcp/pmi.py	2015-02-23 21:24:36.671658326 +1100
+@@ -1,7 +1,7 @@
+ # pylint: disable=C0103
+ """Wrapper module for libpcp_import - Performace Co-Pilot Log Import API
+ #
+-# Copyright (C) 2012-2013 Red Hat.
++# Copyright (C) 2012-2015 Red Hat.
+ #
+ # This file is part of the "pcp" module, the python interfaces for the
+ # Performance Co-Pilot toolkit.
+@@ -168,6 +168,8 @@ class pmiLogImport(object):
+     # overloads
+ 
+     def __init__(self, path, inherit = 0):
++        if type(path) != type(b''):
++            path = path.encode('utf-8')
+         self._path = path        # the archive path (file name)
+         self._ctx = LIBPCP_IMPORT.pmiStart(c_char_p(path), inherit)
+         if self._ctx < 0:
+@@ -187,6 +189,8 @@ class pmiLogImport(object):
+         status = LIBPCP_IMPORT.pmiUseContext(self._ctx)
+         if status < 0:
+             raise pmiErr(status)
++        if type(hostname) != type(b''):
++            hostname = hostname.encode('utf-8')
+         status = LIBPCP_IMPORT.pmiSetHostname(c_char_p(hostname))
+         if status < 0:
+             raise pmiErr(status)
+@@ -198,6 +202,8 @@ class pmiLogImport(object):
+         status = LIBPCP_IMPORT.pmiUseContext(self._ctx)
+         if status < 0:
+             raise pmiErr(status)
++        if type(timezone) != type(b''):
++            timezone = timezone.encode('utf-8')
+         status = LIBPCP_IMPORT.pmiSetTimezone(c_char_p(timezone))
+         if status < 0:
+             raise pmiErr(status)
+@@ -227,6 +233,8 @@ class pmiLogImport(object):
+         status = LIBPCP_IMPORT.pmiUseContext(self._ctx)
+         if status < 0:
+             raise pmiErr(status)
++        if type(name) != type(b''):
++            name = name.encode('utf-8')
+         status = LIBPCP_IMPORT.pmiAddMetric(c_char_p(name),
+                                         pmid, typed, indom, sem, units)
+         if status < 0:
+@@ -238,6 +246,8 @@ class pmiLogImport(object):
+         status = LIBPCP_IMPORT.pmiUseContext(self._ctx)
+         if status < 0:
+             raise pmiErr(status)
++        if type(instance) != type(b''):
++            instance = instance.encode('utf-8')
+         status = LIBPCP_IMPORT.pmiAddInstance(indom, c_char_p(instance), instid)
+         if status < 0:
+             raise pmiErr(status)
+@@ -248,6 +258,12 @@ class pmiLogImport(object):
+         status = LIBPCP_IMPORT.pmiUseContext(self._ctx)
+         if status < 0:
+             raise pmiErr(status)
++        if type(name) != type(b''):
++            name = name.encode('utf-8')
++        if type(inst) != type(b''):
++            inst = inst.encode('utf-8')
++        if type(value) != type(b''):
++            value = value.encode('utf-8')
+         status = LIBPCP_IMPORT.pmiPutValue(c_char_p(name),
+                                         c_char_p(inst), c_char_p(value))
+         if status < 0:
+@@ -259,6 +275,10 @@ class pmiLogImport(object):
+         status = LIBPCP_IMPORT.pmiUseContext(self._ctx)
+         if status < 0:
+             raise pmiErr(status)
++        if type(name) != type(b''):
++            name = name.encode('utf-8')
++        if type(inst) != type(b''):
++            inst = inst.encode('utf-8')
+         status = LIBPCP_IMPORT.pmiGetHandle(c_char_p(name), c_char_p(inst))
+         if status < 0:
+             raise pmiErr(status)
+@@ -269,6 +289,8 @@ class pmiLogImport(object):
+         status = LIBPCP_IMPORT.pmiUseContext(self._ctx)
+         if status < 0:
+             raise pmiErr(status)
++        if type(value) != type(b''):
++            value = value.encode('utf-8')
+         status = LIBPCP_IMPORT.pmiPutValueHandle(handle, c_char_p(value))
+         if status < 0:
+             raise pmiErr(status)
+diff -Naurp pcp-3.10.2.orig/src/python/pcp/pmsubsys.py pcp-3.10.2/src/python/pcp/pmsubsys.py
+--- pcp-3.10.2.orig/src/python/pcp/pmsubsys.py	2015-01-21 02:18:01.000000000 +1100
++++ pcp-3.10.2/src/python/pcp/pmsubsys.py	2015-02-23 21:24:36.671658326 +1100
+@@ -1,7 +1,7 @@
+ #
+ # Performance Co-Pilot subsystem classes
+ #
+-# Copyright (C) 2013 Red Hat Inc.
++# Copyright (C) 2013-2015 Red Hat.
+ #
+ # This program is free software; you can redistribute it and/or modify it
+ # under the terms of the GNU General Public License as published by the
+@@ -31,7 +31,7 @@ http://www.performancecopilot.org
+ 
+ import copy
+ import cpmapi as c_api
+-from pcp.pmapi import pmErr
++from pcp.pmapi import pmErr, timeval
+ from ctypes import c_char_p
+ 
+ # python version information and compatibility
+@@ -48,6 +48,7 @@ else:
+ class Subsystem(object):
+     def __init__(self):
+         self.metrics = []
++        self._timestamp = timeval(0, 0)
+         self.diff_metrics = []
+         self.metric_pmids = []
+         self.metric_descs = []
+@@ -55,6 +56,11 @@ class Subsystem(object):
+         self.metrics_dict = {}
+         self.old_metric_values = []
+ 
++    def _R_timestamp(self):
++        return self._timestamp
++
++    timestamp = property(_R_timestamp, None, None, None)
++
+     def setup_metrics(self, pcp):
+         # remove any unsupported metrics
+         name_pattern = self.metrics[0].split(".")[0] + ".*"
+@@ -162,6 +168,7 @@ class Subsystem(object):
+         list_type = type([])
+ 
+         metric_result = pcp.pmFetch(self.metric_pmids)
++        self._timestamp = metric_result.contents.timestamp
+ 
+         if max(self.old_metric_values) == 0:
+             first = True
diff --git a/pcp.spec b/pcp.spec
index d3e2b18..fb33d64 100644
--- a/pcp.spec
+++ b/pcp.spec
@@ -1,15 +1,18 @@
 Summary: System-level performance monitoring and performance management
 Name: pcp
-Version: 3.10.3
-%define buildversion 1
+Version: 3.10.2
+%define buildversion 2
 
-Release: 0.620.g89545ba%{?dist}
+Release: %{buildversion}%{?dist}
 License: GPLv2+ and LGPLv2.1+ and CC-BY
 URL: http://www.pcp.io
 Group: Applications/System
-Source0: %{name}-%{version}-0.620.g89545ba.tar.gz
+Source0: ftp://ftp.pcp.io/projects/pcp/download/%{name}-%{version}.src.tar.gz
 Source1: ftp://ftp.pcp.io/projects/pcp/download/pcp-webjs.src.tar.gz
 
+# python3 conversion patch
+Patch1: bz1194324.patch
+
 # There are no papi/libpfm devel packages for s390 nor for some rhels, disable
 %ifarch s390 s390x
 %define disable_papi 1
@@ -29,6 +32,7 @@ Source1: ftp://ftp.pcp.io/projects/pcp/download/pcp-webjs.src.tar.gz
 
 %define disable_microhttpd 0
 %define disable_cairo 0
+
 # Python development environment before el6 is pre-2.6 (too old)
 %if 0%{?rhel} == 0 || 0%{?rhel} > 5
 %define disable_python2 0
@@ -38,9 +42,18 @@ Source1: ftp://ftp.pcp.io/projects/pcp/download/pcp-webjs.src.tar.gz
 # No python3 development environment before el7
 %if 0%{?rhel} == 0 || 0%{?rhel} > 6
 %define disable_python3 0
+# Do we wish to mandate python3 use in pcp?  (f22+ and el8+)
+%if 0%{?fedora} >= 22 || 0%{?rhel} > 7
+%define default_python3 1
+%else
+%define default_python3 0
+%define
+%endif
 %else
 %define disable_python3 1
+%define default_python3 0
 %endif
+
 # Qt development and runtime environment missing components before el6
 %if 0%{?rhel} == 0 || 0%{?rhel} > 5
 %define disable_qt 0
@@ -55,6 +68,14 @@ BuildRequires: rpm-devel
 BuildRequires: avahi-devel
 %if !%{disable_python2}
 BuildRequires: python-devel
+# systemtap dtrace utility requires python2, so only use it if we can
+%if 0%{?rhel} == 0 || 0%{?rhel} > 5
+BuildRequires: systemtap-sdt-devel
+%else
+%ifnarch ppc ppc64
+BuildRequires: systemtap-sdt-devel
+%endif
+%endif
 %endif
 %if !%{disable_python3}
 BuildRequires: python3-devel
@@ -74,13 +95,6 @@ BuildRequires: libmicrohttpd-devel
 %if !%{disable_cairo}
 BuildRequires: cairo-devel
 %endif
-%if 0%{?rhel} == 0 || 0%{?rhel} > 5
-BuildRequires: systemtap-sdt-devel
-%else
-%ifnarch ppc ppc64
-BuildRequires: systemtap-sdt-devel
-%endif
-%endif
 BuildRequires: perl(ExtUtils::MakeMaker)
 BuildRequires: initscripts man
 %if 0%{?fedora} >= 18 || 0%{?rhel} >= 7
@@ -92,7 +106,7 @@ BuildRequires: qt4-devel >= 4.4
 %endif
 
 Requires: bash gawk sed grep fileutils findutils initscripts perl which
-%if !%{disable_python2}
+%if !%{disable_python2} && !%{default_python3}
 %if 0%{?rhel} <= 5
 Requires: python-ctypes
 %endif
@@ -100,7 +114,10 @@ Requires: python
 %endif
 
 Requires: pcp-libs = %{version}-%{release}
-%if !%{disable_python2}
+%if %{default_python3}
+Requires: python3-pcp = %{version}-%{release}
+%endif
+%if !%{disable_python2} && !%{default_python3}
 Requires: python-pcp = %{version}-%{release}
 %endif
 Requires: perl-PCP-PMDA = %{version}-%{release}
@@ -390,21 +407,6 @@ Performance Co-Pilot (PCP) front-end tools for importing MTRG data
 into standard PCP archive logs for replay with any PCP monitoring tool.
 
 #
-# pcp-import-ganglia2pcp
-#
-%package import-ganglia2pcp
-License: LGPLv2+
-Group: Applications/System
-Summary: Performance Co-Pilot tools for importing ganglia data into PCP archive logs
-URL: http://www.pcp.io
-Requires: pcp-libs = %{version}-%{release}
-Requires: perl-PCP-LogImport = %{version}-%{release}
-
-%description import-ganglia2pcp
-Performance Co-Pilot (PCP) front-end tools for importing ganglia data
-into standard PCP archive logs for replay with any PCP monitoring tool.
-
-#
 # pcp-import-collectl2pcp
 #
 %package import-collectl2pcp
@@ -550,6 +552,7 @@ PCP utilities and daemons, and the PCP graphical tools.
 %prep
 %setup -q
 %setup -q -T -D -a 1
+%patch1 -p1
 
 %clean
 rm -Rf $RPM_BUILD_ROOT
@@ -612,6 +615,13 @@ for f in $RPM_BUILD_ROOT/%{_initddir}/{pcp,pmcd,pmlogger,pmie,pmwebd,pmmgr,pmpro
 	sed -i -e '/^# chkconfig/s/:.*$/: - 95 05/' -e '/^# Default-Start:/s/:.*$/:/' $f
 done
 
+%if %{default_python3}
+# defaulting to python3 requires /usr/bin/python3 hashbang lines, make it so
+for f in `find $RPM_BUILD_ROOT -type f -print`; do
+	sed -i -e "1 s|^#!/usr/bin/python\b|#!/usr/bin/python3|" $f
+done
+%endif
+
 # list of PMDAs in the base pkg
 ls -1 $RPM_BUILD_ROOT/%{_pmdasdir} |\
   grep -E -v 'simple|sample|trivial|txmon' |\
@@ -1018,11 +1028,6 @@ chmod 644 "$PCP_PMNS_DIR/.NeedRebuild"
 %{_bindir}/mrtg2pcp
 %{_mandir}/man1/mrtg2pcp.1.gz
 
-%files import-ganglia2pcp
-%defattr(-,root,root)
-%{_bindir}/ganglia2pcp
-%{_mandir}/man1/ganglia2pcp.1.gz
-
 %files import-collectl2pcp
 %defattr(-,root,root)
 %{_bindir}/collectl2pcp
@@ -1091,13 +1096,8 @@ chmod 644 "$PCP_PMNS_DIR/.NeedRebuild"
 %defattr(-,root,root,-)
 
 %changelog
-* Tue Feb 17 2015 Lukas Berk <lberk at redhat.com> - 3.10.3-0.620.g89545ba
-- Automated weekly rawhide release
-- Applied spec changes from upstream git
-
-* Mon Feb 09 2015 Lukas Berk <lberk at redhat.com> - 3.10.3-0.508.g8090873
-- Automated weekly rawhide release
-- Applied spec changes from upstream git
+* Mon Feb 23 2015 Nathan Scott <nathans at redhat.com> - 3.10.2-2
+- Initial changes to support python3 as default (BZ 1194324)
 
 * Fri Jan 23 2015 Dave Brolley <brolley at redhat.com> - 3.10.2-1
 - Update to latest PCP sources.
@@ -1106,26 +1106,6 @@ chmod 644 "$PCP_PMNS_DIR/.NeedRebuild"
 - Correct units for cgroup memory metrics (BZ 1180351)
 - Add the pcp2graphite(1) export script (BZ 1163986)
 
-* Mon Jan 19 2015 Lukas Berk <lberk at redhat.com> - 3.10.2-0.309.g3c90ff9
-- Automated weekly rawhide release
-
-* Mon Jan 12 2015 Lukas Berk <lberk at redhat.com> - 3.10.2-0.305.g64a0d4b
-- Automated weekly rawhide release
-
-* Mon Jan 05 2015 Lukas Berk <lberk at redhat.com> - 3.10.2-0.292.g764a0fb
-- Automated weekly rawhide release
-
-* Mon Dec 22 2014 Lukas Berk <lberk at redhat.com> - 3.10.2-0.222.g77dcbbf
-- Automated weekly rawhide release
-- Applied spec changes from upstream git
-
-* Mon Dec 15 2014 Lukas Berk <lberk at redhat.com> - 3.10.2-0.124.g1e0c939
-- Automated weekly rawhide release
-
-* Mon Dec 08 2014 Lukas Berk <lberk at redhat.com> - 3.10.2-0.21.g6bad98e
-- Automated weekly rawhide release
-- Applied spec changes from upstream git
-
 * Mon Dec 01 2014 Nathan Scott <nathans at redhat.com> - 3.10.1-1
 - New conditionally-built pcp-pmda-perfevent sub-package.
 - Update to latest PCP sources.
diff --git a/sources b/sources
index 2880cc2..58e9801 100644
--- a/sources
+++ b/sources
@@ -1,2 +1,2 @@
-d378da0021184d88e2b8ba669c5126ee  pcp-3.10.3-0.620.g89545ba.tar.gz
+e76964d6945187513e8c34dd492811bd  pcp-3.10.2.src.tar.gz
 34e17878db46a01bc39811c52e04d6eb  pcp-webjs.src.tar.gz
-- 
cgit v0.10.2


	http://pkgs.fedoraproject.org/cgit/pcp.git/commit/?h=el5&id=7674f7200aa7f856168ac5cb6500d110387f7358


More information about the scm-commits mailing list