diff --git a/.gitignore b/.gitignore index fcbb48d..5dd2b00 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,2 @@ /pcp-5.3.5.src.tar.gz +/pcp-5.3.7.src.tar.gz diff --git a/pcp.spec b/pcp.spec index d0d6cc6..83c905f 100644 --- a/pcp.spec +++ b/pcp.spec @@ -1,22 +1,21 @@ Name: pcp -Version: 5.3.5 -Release: 8%{?dist} +Version: 5.3.7 +Release: 7%{?dist} Summary: System-level performance monitoring and performance management License: GPLv2+ and LGPLv2+ and CC-BY URL: https://pcp.io %global artifactory https://performancecopilot.jfrog.io/artifactory Source0: %{artifactory}/pcp-source-release/pcp-%{version}.src.tar.gz +Patch0: redhat-bugzilla-2003956-pmdabcc-update-kernel-version-check-due-to-backporting.patch +Patch1: redhat-bugzilla-1981886-pmdasockets-backporting.patch +Patch2: redhat-bugzilla-2059461-pmie-systemd-fixup.patch +Patch3: redhat-bugzilla-2081262-pmdaproc-cgroups-fix.patch +Patch4: redhat-bugzilla-2059463-pmdapostfix-harden.patch -Patch0: redhat-bugzilla-2017632.patch -Patch1: redhat-bugzilla-2029301.patch -Patch2: redhat-bugzilla-2030121.patch -Patch3: redhat-bugzilla-2027753.patch -Patch4: redhat-bugzilla-2030140.patch -Patch5: redhat-bugzilla-2003956.patch -Patch6: redhat-bugzilla-2003956-pmdabcc-update-kernel-version-check-due-to-backporting.patch -Patch7: redhat-bugzilla-1973833.patch -Patch8: redhat-bugzilla-1991763.patch +# The additional linker flags break out-of-tree PMDAs. +# https://bugzilla.redhat.com/show_bug.cgi?id=2043092 +%undefine _package_note_flags %if 0%{?fedora} >= 26 || 0%{?rhel} > 7 %global __python2 python2 @@ -296,9 +295,18 @@ BuildRequires: qt5-qtsvg-devel Requires: bash xz gawk sed grep findutils which %{_hostname_executable} Requires: pcp-libs = %{version}-%{release} %if !%{disable_selinux} + +# rpm boolean dependencies are supported since RHEL 8 +%if 0%{?fedora} >= 35 || 0%{?rhel} >= 8 +# This ensures that the pcp-selinux package and all it's dependencies are not pulled +# into containers and other systems that do not use SELinux +Requires: (pcp-selinux = %{version}-%{release} if selinux-policy-targeted) +%else Requires: pcp-selinux = %{version}-%{release} %endif +%endif + %global _confdir %{_sysconfdir}/pcp %global _logsdir %{_localstatedir}/log/pcp %global _pmnsdir %{_localstatedir}/lib/pcp/pmns @@ -2287,10 +2295,6 @@ updated policy package. %patch2 -p1 %patch3 -p1 %patch4 -p1 -%patch5 -p1 -%patch6 -p1 -%patch7 -p1 -%patch8 -p1 %build # the buildsubdir macro gets defined in %setup and is apparently only available in the next step (i.e. the %build step) @@ -3348,6 +3352,23 @@ PCP_LOG_DIR=%{_logsdir} %files zeroconf -f pcp-zeroconf-files.rpm %changelog +* Mon May 09 2022 Nathan Scott - 5.3.7-7 +- Additional selinux policy rules for pmdasockets (BZ 1981886) + +* Thu May 05 2022 Nathan Scott - 5.3.7-5 +- Harden pmdapostfix(1) against missing Postfix (BZ 2059463) +- Fix cgroups failure on non-x86_64 platforms (BZ 2081262) + +* Tue May 03 2022 Nathan Scott - 5.3.7-3 +- Fix remaining issues in the pcp-ss(1) utility (BZ 1981886) +- Remove benign warning message from pmie systemd unit file. + +* Tue Apr 05 2022 Nathan Scott - 5.3.7-1 +- Fix several issues in the pcp-ss(1) utility (BZ 1981886) +- Document pmproxy archive discovery further (BZ 2026726) +- Improve SQL Server PMDA secure settings (BZ 2057615) +- Rebase to latest stable version of PCP (BZ 2059461) + * Wed Feb 02 2022 Nathan Scott - 5.3.5-8 - Fix pcp-zeroconf logger interval override regression (BZ 1991763) - Remove warnings from spec setup of PCP systemd units (BZ 2048024) diff --git a/redhat-bugzilla-1973833.patch b/redhat-bugzilla-1973833.patch deleted file mode 100644 index ef1b249..0000000 --- a/redhat-bugzilla-1973833.patch +++ /dev/null @@ -1,193 +0,0 @@ -commit 6b907e90c74fce82d6b712493d8b362bdd1a1ec1 -Author: Nathan Scott -Date: Tue Dec 14 08:54:14 2021 +1100 - - pmlogconf: switch to the bulk pmLookupDescs(3) interface - - No functional change, all existing regression tests pass. - - Related to Red Hat BZ #1973833. - -diff --git a/src/pmlogconf/pmlogconf.c b/src/pmlogconf/pmlogconf.c -index fa1156859d..ef4fc08bbd 100644 ---- a/src/pmlogconf/pmlogconf.c -+++ b/src/pmlogconf/pmlogconf.c -@@ -473,13 +473,19 @@ fetch_groups(void) - { - static pmResult *result; - const char **names; -+ pmDesc *descs; - pmID *pmids; -- int i, n, sts; -+ int i, n, sts, count; - -- /* prepare arrays of names and identifiers for PMAPI metric lookup */ -+ /* prepare arrays of names, descriptors and IDs for PMAPI metric lookup */ - if ((names = calloc(ngroups, sizeof(char *))) == NULL) - return -ENOMEM; -+ if ((descs = calloc(ngroups, sizeof(pmDesc))) == NULL) { -+ free(names); -+ return -ENOMEM; -+ } - if ((pmids = calloc(ngroups, sizeof(pmID))) == NULL) { -+ free(descs); - free(names); - return -ENOMEM; - } -@@ -490,15 +496,16 @@ fetch_groups(void) - continue; - names[n++] = (const char *)groups[i].metric; - } -+ count = n; - -- if ((sts = pmLookupName(n, names, pmids)) < 0) { -- if (n == 1) -+ if ((sts = pmLookupName(count, names, pmids)) < 0) { -+ if (count == 1) - groups[0].pmid = PM_ID_NULL; - else - fprintf(stderr, "%s: cannot lookup metric names: %s\n", - pmGetProgname(), pmErrStr(sts)); - } -- else if ((sts = pmFetch(n, pmids, &result)) < 0) { -+ else if ((sts = pmFetch(count, pmids, &result)) < 0) { - fprintf(stderr, "%s: cannot fetch metric values: %s\n", - pmGetProgname(), pmErrStr(sts)); - } -@@ -510,6 +517,13 @@ fetch_groups(void) - else - groups[i].pmid = pmids[n++]; - } -+ /* descriptor lookup, descs_hash handles failure here */ -+ (void) pmLookupDescs(count, pmids, descs); -+ -+ /* create a hash over the descs for quick PMID lookup */ -+ if ((sts = descs_hash(count, descs)) < 0) -+ fprintf(stderr, "%s: cannot hash metric descs: %s\n", -+ pmGetProgname(), pmErrStr(sts)); - /* create a hash over the result for quick PMID lookup */ - if ((sts = values_hash(result)) < 0) - fprintf(stderr, "%s: cannot hash metric values: %s\n", -@@ -806,14 +820,16 @@ evaluate_string_regexp(group_t *group, regex_cmp_t compare) - int i, found; - pmValueSet *vsp; - pmValue *vp; -+ pmDesc *dp; - pmAtomValue atom; - regex_t regex; - int sts, type; - -- if ((vsp = metric_values(group->pmid)) == NULL) -+ if ((vsp = metric_values(group->pmid)) == NULL || -+ (dp = metric_desc(group->pmid)) == NULL) - return 0; - -- type = metric_type(group->pmid); -+ type = dp->type; - if (type < 0 || type > PM_TYPE_STRING) { - fprintf(stderr, "%s: %s uses regular expression on non-scalar metric\n", - pmGetProgname(), group->tag); -@@ -849,11 +865,14 @@ evaluate_string_regexp(group_t *group, regex_cmp_t compare) - static int - evaluate_values(group_t *group, numeric_cmp_t ncmp, string_cmp_t scmp) - { -- int type = metric_type(group->pmid); -+ pmDesc *dp; -+ -+ if ((dp = metric_desc(group->pmid)) == NULL) -+ return 0; - -- if (type == PM_TYPE_STRING) -+ if (dp->type == PM_TYPE_STRING) - return evaluate_string_values(group, scmp); -- return evaluate_number_values(group, type, ncmp); -+ return evaluate_number_values(group, dp->type, ncmp); - } - - int -diff --git a/src/pmlogconf/util.c b/src/pmlogconf/util.c -index d44c2e529a..293eb2eca3 100644 ---- a/src/pmlogconf/util.c -+++ b/src/pmlogconf/util.c -@@ -1,5 +1,5 @@ - /* -- * Copyright (c) 2020 Red Hat. All Rights Reserved. -+ * Copyright (c) 2020-2021 Red Hat. All Rights Reserved. - * - * 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 -@@ -14,7 +14,7 @@ - #include "util.h" - - static __pmHashCtl valuesctl; /* pointers to values in pmResult */ --static __pmHashCtl typesctl; /* metric types from pmLookupDesc */ -+static __pmHashCtl descsctl; /* metric descs from pmLookupDesc */ - - int - values_hash(pmResult *result) -@@ -47,27 +47,33 @@ metric_values(pmID pmid) - } - - int --metric_type(pmID pmid) -+descs_hash(int numpmid, pmDesc *descs) - { -- __pmHashNode *node; -- pmDesc desc; -- int sts, *data; -+ unsigned int i; -+ pmDesc *dp; -+ int sts; - -- if (pmid == PM_IN_NULL) -- return PM_TYPE_UNKNOWN; -- if ((node = __pmHashSearch(pmid, &typesctl)) == NULL) { -- if ((sts = pmLookupDesc(pmid, &desc)) < 0) -- return sts; -- if ((data = malloc(sizeof(int))) == NULL) -- return sts; -- *data = desc.type; -- if ((sts = __pmHashAdd(pmid, data, &typesctl)) < 0) { -- free(data); -+ if ((sts = __pmHashPreAlloc(numpmid, &descsctl)) < 0) -+ return sts; -+ -+ for (i = 0; i < numpmid; i++) { -+ dp = &descs[i]; -+ if ((sts = __pmHashAdd(dp->pmid, dp, &descsctl)) < 0) - return sts; -- } -- return *data; - } -- return *(int *)node->data; -+ return numpmid; -+} -+ -+pmDesc * -+metric_desc(pmID pmid) -+{ -+ __pmHashNode *node; -+ -+ if (pmid == PM_IN_NULL) -+ return NULL; -+ if ((node = __pmHashSearch(pmid, &descsctl)) == NULL) -+ return NULL; -+ return (pmDesc *)node->data; - } - - int -diff --git a/src/pmlogconf/util.h b/src/pmlogconf/util.h -index 17d856a0d7..a11350d899 100644 ---- a/src/pmlogconf/util.h -+++ b/src/pmlogconf/util.h -@@ -34,7 +34,9 @@ extern void fmt(const char *, char *, size_t, int, int, fmt_t, void *); - - extern int values_hash(pmResult *); - extern pmValueSet *metric_values(pmID); --extern int metric_type(pmID); -+ -+extern int descs_hash(int, pmDesc *); -+extern pmDesc *metric_desc(pmID); - - typedef int (*numeric_cmp_t)(double, double); - extern int number_equal(double, double); diff --git a/redhat-bugzilla-1981886-pmdasockets-backporting.patch b/redhat-bugzilla-1981886-pmdasockets-backporting.patch new file mode 100644 index 0000000..bdcc5d4 --- /dev/null +++ b/redhat-bugzilla-1981886-pmdasockets-backporting.patch @@ -0,0 +1,459 @@ +diff --git a/qa/1927 b/qa/1927 +new file mode 100755 +index 000000000..46afa9509 +--- /dev/null ++++ b/qa/1927 +@@ -0,0 +1,88 @@ ++#!/bin/sh ++# PCP QA Test No. 1927 ++# Exercise the sockets PMDA Install/Remove and string metric bug. ++# ++# Copyright (c) 2022 Red Hat. All Rights Reserved. ++# ++ ++seq=`basename $0` ++echo "QA output created by $seq" ++ ++# get standard environment, filters and checks ++. ./common.product ++. ./common.filter ++. ./common.check ++ ++[ -f $PCP_PMDAS_DIR/sockets/pmdasockets ] || _notrun "sockets pmda not installed" ++ ++_cleanup() ++{ ++ cd $here ++ $sudo rm -rf $tmp $tmp.* ++} ++ ++status=0 # success is the default! ++$sudo rm -rf $tmp $tmp.* $seq.full ++ ++_filter_sockets() ++{ ++ grep -v 'No value(s) available' ++} ++ ++pmdasockets_remove() ++{ ++ echo ++ echo "=== remove sockets agent ===" ++ $sudo ./Remove >$tmp.out 2>&1 ++ _filter_pmda_remove <$tmp.out ++} ++ ++pmdasockets_install() ++{ ++ # start from known starting points ++ cd $PCP_PMDAS_DIR/sockets ++ $sudo ./Remove >/dev/null 2>&1 ++ ++ echo ++ echo "=== sockets agent installation ===" ++ $sudo ./Install $tmp.out 2>&1 ++ cat $tmp.out >>$here/$seq.full ++ # Check sockets metrics have appeared ... X metrics and Y values ++ _filter_pmda_install <$tmp.out \ ++ | sed \ ++ -e 's/[0-9][0-9]* warnings, //' \ ++ | $PCP_AWK_PROG ' ++/Check network.persocket metrics have appeared/ { ++ if ($7 >= 50 && $7 <= 99) $7 = "X" ++ if ($10 >= 0) $10 = "Y" ++ } ++ { print }' ++} ++ ++_prepare_pmda sockets ++# note: _restore_auto_restart pmcd done in _cleanup_pmda() ++trap "_cleanup_pmda sockets; exit \$status" 0 1 2 3 15 ++ ++_stop_auto_restart pmcd ++ ++# real QA test starts here ++pmdasockets_install ++ ++# pmcd should have been started by the Install process - check ++if pminfo -v network.persocket > $tmp.info 2> $tmp.err ++then ++ : ++else ++ echo "... failed! ... here is the Install log ..." ++ cat $tmp.out ++fi ++cat $tmp.info $tmp.err | _filter_sockets ++ ++echo "Check the values for v6only metric are 0 or 1 ..." ++pminfo -f network.persocket.v6only | egrep -v 'value [01]$' | sed -e '/^$/d' ++ ++pmdasockets_remove ++status=0 ++ ++# success, all done ++exit +diff --git a/qa/1927.out b/qa/1927.out +new file mode 100644 +index 000000000..2ae4385fd +--- /dev/null ++++ b/qa/1927.out +@@ -0,0 +1,17 @@ ++QA output created by 1927 ++ ++=== sockets agent installation === ++Updating the Performance Metrics Name Space (PMNS) ... ++Terminate PMDA if already installed ... ++[...install files, make output...] ++Updating the PMCD control file, and notifying PMCD ... ++Check network.persocket metrics have appeared ... X metrics and Y values ++Check the values for v6only metric are 0 or 1 ... ++network.persocket.v6only ++ ++=== remove sockets agent === ++Culling the Performance Metrics Name Space ... ++network.persocket ... done ++Updating the PMCD control file, and notifying PMCD ... ++[...removing files...] ++Check network.persocket metrics have gone away ... OK +diff --git a/qa/group b/qa/group +index acfc5d208..846c0c4bd 100644 +--- a/qa/group ++++ b/qa/group +@@ -1967,6 +1967,7 @@ x11 + 1901 pmlogger local + 1902 help local + 1914 atop local ++1927 pmda.sockets local + 1937 pmlogrewrite pmda.xfs local + 1955 libpcp pmda pmda.pmcd local + 1956 pmda.linux pmcd local +diff --git a/src/pmdas/linux_sockets/pmda.c b/src/pmdas/linux_sockets/pmda.c +index d10eacf29..5a3018d8a 100644 +--- a/src/pmdas/linux_sockets/pmda.c ++++ b/src/pmdas/linux_sockets/pmda.c +@@ -1,7 +1,7 @@ + /* + * Sockets PMDA + * +- * Copyright (c) 2021 Red Hat. ++ * Copyright (c) 2021-2022 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 +@@ -14,6 +14,7 @@ + * for more details. + */ + ++#include + #include "pmapi.h" + #include "pmda.h" + +@@ -147,6 +148,31 @@ sockets_fetchCallBack(pmdaMetric *metric, unsigned int inst, pmAtomValue *atom) + return PMDA_FETCH_STATIC; + } + ++/* ++ * Restrict the allowed filter strings to only limited special ++ * characters (open and close brackets - everthing else can be ++ * done with alphanumerics) to limit any attack surface here. ++ * The ss filtering language is more complex than we ever want ++ * to be attempting to parse ourself, so we leave that side of ++ * things to the ss command itself. ++ */ ++int ++sockets_check_filter(const char *string) ++{ ++ const char *p; ++ ++ for (p = string; *p; p++) { ++ if (isspace(*p)) ++ continue; ++ if (isalnum(*p)) ++ continue; ++ if (*p == '(' || *p == ')') ++ continue; ++ return 0; /* disallow */ ++ } ++ return 1; ++} ++ + static int + sockets_store(pmResult *result, pmdaExt *pmda) + { +@@ -165,9 +191,14 @@ sockets_store(pmResult *result, pmdaExt *pmda) + case 0: /* network.persocket.filter */ + if ((sts = pmExtractValue(vsp->valfmt, &vsp->vlist[0], + PM_TYPE_STRING, &av, PM_TYPE_STRING)) >= 0) { ++ if (sockets_check_filter(av.cp)) { ++ sts = PM_ERR_BADSTORE; ++ free(av.cp); ++ break; ++ } + if (ss_filter) + free(ss_filter); +- ss_filter = av.cp; /* TODO filter syntax check */ ++ ss_filter = av.cp; + } + break; + default: +diff --git a/src/pmdas/linux_sockets/ss_parse.c b/src/pmdas/linux_sockets/ss_parse.c +index 94c5e16e9..9f3afc691 100644 +--- a/src/pmdas/linux_sockets/ss_parse.c ++++ b/src/pmdas/linux_sockets/ss_parse.c +@@ -1,5 +1,5 @@ + /* +- * Copyright (c) 2021 Red Hat. ++ * Copyright (c) 2021-2022 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 +@@ -21,65 +21,70 @@ static ss_stats_t ss_p; + /* boolean value with no separate value, default 0 */ + #define PM_TYPE_BOOL (PM_TYPE_UNKNOWN-1) + ++/* helper macros to extract field address and size */ ++#define SSFIELD(str,type,f) {(str), (sizeof(str)-1), type, (&(f)), (sizeof(f))} ++#define SSNULLFIELD(str) {(str), (sizeof(str)-1), PM_TYPE_UNKNOWN, NULL} ++ + static struct { + char *field; + int len; + int type; + void *addr; ++ int size; + int found; + } parse_table[] = { +- { "timer:", 6, PM_TYPE_STRING, &ss_p.timer_str }, +- { "uid:", 4, PM_TYPE_U32, &ss_p.uid }, +- { "ino:", 4, PM_TYPE_64, &ss_p.inode }, +- { "sk:", 3, PM_TYPE_U64, &ss_p.sk }, +- { "cgroup:", 7, PM_TYPE_STRING, &ss_p.cgroup }, +- { "v6only:", 7, PM_TYPE_32, &ss_p.v6only }, +- { "--- ", 4, PM_TYPE_UNKNOWN, NULL }, +- { "<-> ", 4, PM_TYPE_UNKNOWN, NULL }, +- { "--> ", 4, PM_TYPE_UNKNOWN, NULL }, +- { "skmem:", 6, PM_TYPE_STRING, &ss_p.skmem_str, }, +- { "ts ", 3, PM_TYPE_BOOL, &ss_p.ts }, +- { "sack ", 5, PM_TYPE_BOOL, &ss_p.sack }, +- { "cubic ", 6, PM_TYPE_BOOL, &ss_p.cubic }, +- { "wscale:", 7, PM_TYPE_STRING, &ss_p.wscale_str }, +- { "rto:", 4, PM_TYPE_DOUBLE, &ss_p.rto }, +- { "rtt:", 4, PM_TYPE_STRING, &ss_p.round_trip_str }, +- { "ato:", 4, PM_TYPE_DOUBLE, &ss_p.ato }, +- { "backoff:", 8, PM_TYPE_32, &ss_p.backoff }, +- { "mss:", 4, PM_TYPE_U32, &ss_p.mss }, +- { "pmtu:", 5, PM_TYPE_U32, &ss_p.pmtu }, +- { "rcvmss:", 7, PM_TYPE_U32, &ss_p.rcvmss }, +- { "advmss:", 7, PM_TYPE_U32, &ss_p.advmss }, +- { "cwnd:", 5, PM_TYPE_U32, &ss_p.cwnd }, +- { "lost:", 5, PM_TYPE_32, &ss_p.lost }, +- { "ssthresh:", 9, PM_TYPE_U32, &ss_p.ssthresh }, +- { "bytes_sent:", 11, PM_TYPE_U64, &ss_p.bytes_sent }, +- { "bytes_retrans:", 14, PM_TYPE_U64, &ss_p.bytes_retrans }, +- { "bytes_acked:", 12, PM_TYPE_U64, &ss_p.bytes_acked }, +- { "bytes_received:", 15, PM_TYPE_U64, &ss_p.bytes_received }, +- { "segs_out:", 9, PM_TYPE_U32, &ss_p.segs_out }, +- { "segs_in:", 8, PM_TYPE_U32, &ss_p.segs_in }, +- { "data_segs_out:", 14, PM_TYPE_U32, &ss_p.data_segs_out }, +- { "data_segs_in:", 13, PM_TYPE_U32, &ss_p.data_segs_in }, +- { "send ", 5, PM_TYPE_DOUBLE, &ss_p.send }, /* no ':' */ +- { "lastsnd:", 8, PM_TYPE_U32, &ss_p.lastsnd }, +- { "lastrcv:", 8, PM_TYPE_U32, &ss_p.lastrcv }, +- { "lastack:", 8, PM_TYPE_U32, &ss_p.lastack }, +- { "pacing_rate ", 12, PM_TYPE_DOUBLE, &ss_p.pacing_rate }, /* no ':' */ +- { "delivery_rate ", 14, PM_TYPE_DOUBLE, &ss_p.delivery_rate }, /* no ':' */ +- { "delivered:", 10, PM_TYPE_U32, &ss_p.delivered }, +- { "app_limited ", 12, PM_TYPE_BOOL, &ss_p.app_limited }, +- { "reord_seen:", 11, PM_TYPE_32, &ss_p.reord_seen }, +- { "busy:", 5, PM_TYPE_U64, &ss_p.busy }, +- { "unacked:", 8, PM_TYPE_32, &ss_p.unacked }, +- { "rwnd_limited:", 13, PM_TYPE_U64, &ss_p.rwnd_limited }, +- { "retrans:", 8, PM_TYPE_STRING, &ss_p.retrans_str }, +- { "dsack_dups:", 11, PM_TYPE_U32, &ss_p.dsack_dups }, +- { "rcv_rtt:", 8, PM_TYPE_DOUBLE, &ss_p.rcv_rtt }, +- { "rcv_space:", 10, PM_TYPE_32, &ss_p.rcv_space }, +- { "rcv_ssthresh:", 13, PM_TYPE_32, &ss_p.rcv_ssthresh }, +- { "minrtt:", 7, PM_TYPE_DOUBLE, &ss_p.minrtt }, +- { "notsent:", 8, PM_TYPE_U32, &ss_p.notsent }, ++ SSFIELD("timer:", PM_TYPE_STRING, ss_p.timer_str), ++ SSFIELD("uid:", PM_TYPE_U32, ss_p.uid), ++ SSFIELD("ino:", PM_TYPE_64, ss_p.inode), ++ SSFIELD("sk:", PM_TYPE_U64, ss_p.sk), ++ SSFIELD("cgroup:", PM_TYPE_STRING, ss_p.cgroup), ++ SSFIELD("v6only:", PM_TYPE_32, ss_p.v6only), ++ SSNULLFIELD("--- "), ++ SSNULLFIELD("<-> "), ++ SSNULLFIELD("--> "), ++ SSFIELD("skmem:", PM_TYPE_STRING, ss_p.skmem_str), ++ SSFIELD("ts ", PM_TYPE_BOOL, ss_p.ts), ++ SSFIELD("sack ", PM_TYPE_BOOL, ss_p.sack), ++ SSFIELD("cubic ", PM_TYPE_BOOL, ss_p.cubic), ++ SSFIELD("wscale:", PM_TYPE_STRING, ss_p.wscale_str), ++ SSFIELD("rto:", PM_TYPE_DOUBLE, ss_p.rto), ++ SSFIELD("rtt:", PM_TYPE_STRING, ss_p.round_trip_str), ++ SSFIELD("ato:", PM_TYPE_DOUBLE, ss_p.ato), ++ SSFIELD("backoff:", PM_TYPE_32, ss_p.backoff), ++ SSFIELD("mss:", PM_TYPE_U32, ss_p.mss), ++ SSFIELD("pmtu:", PM_TYPE_U32, ss_p.pmtu), ++ SSFIELD("rcvmss:", PM_TYPE_U32, ss_p.rcvmss), ++ SSFIELD("advmss:", PM_TYPE_U32, ss_p.advmss), ++ SSFIELD("cwnd:", PM_TYPE_U32, ss_p.cwnd), ++ SSFIELD("lost:", PM_TYPE_32, ss_p.lost), ++ SSFIELD("ssthresh:", PM_TYPE_U32, ss_p.ssthresh), ++ SSFIELD("bytes_sent:", PM_TYPE_U64, ss_p.bytes_sent), ++ SSFIELD("bytes_retrans:", PM_TYPE_U64, ss_p.bytes_retrans), ++ SSFIELD("bytes_acked:", PM_TYPE_U64, ss_p.bytes_acked), ++ SSFIELD("bytes_received:", PM_TYPE_U64, ss_p.bytes_received), ++ SSFIELD("segs_out:", PM_TYPE_U32, ss_p.segs_out), ++ SSFIELD("segs_in:", PM_TYPE_U32, ss_p.segs_in), ++ SSFIELD("data_segs_out:", PM_TYPE_U32, ss_p.data_segs_out), ++ SSFIELD("data_segs_in:", PM_TYPE_U32, ss_p.data_segs_in), ++ SSFIELD("send ", PM_TYPE_DOUBLE, ss_p.send), /* no ':' */ ++ SSFIELD("lastsnd:", PM_TYPE_U32, ss_p.lastsnd), ++ SSFIELD("lastrcv:", PM_TYPE_U32, ss_p.lastrcv), ++ SSFIELD("lastack:", PM_TYPE_U32, ss_p.lastack), ++ SSFIELD("pacing_rate ", PM_TYPE_DOUBLE, ss_p.pacing_rate), /* no ':' */ ++ SSFIELD("delivery_rate ", PM_TYPE_DOUBLE, ss_p.delivery_rate), /* no ':' */ ++ SSFIELD("delivered:", PM_TYPE_U32, ss_p.delivered), ++ SSFIELD("app_limited ", PM_TYPE_BOOL, ss_p.app_limited), ++ SSFIELD("reord_seen:", PM_TYPE_32, ss_p.reord_seen), ++ SSFIELD("busy:", PM_TYPE_U64, ss_p.busy), ++ SSFIELD("unacked:", PM_TYPE_32, ss_p.unacked), ++ SSFIELD("rwnd_limited:", PM_TYPE_U64, ss_p.rwnd_limited), ++ SSFIELD("retrans:", PM_TYPE_STRING, ss_p.retrans_str), ++ SSFIELD("dsack_dups:", PM_TYPE_U32, ss_p.dsack_dups), ++ SSFIELD("rcv_rtt:", PM_TYPE_DOUBLE, ss_p.rcv_rtt), ++ SSFIELD("rcv_space:", PM_TYPE_32, ss_p.rcv_space), ++ SSFIELD("rcv_ssthresh:", PM_TYPE_32, ss_p.rcv_ssthresh), ++ SSFIELD("minrtt:", PM_TYPE_DOUBLE, ss_p.minrtt), ++ SSFIELD("notsent:", PM_TYPE_U32, ss_p.notsent), + + { NULL } + }; +@@ -225,8 +230,11 @@ ss_parse(char *line, int has_state_field, ss_stats_t *ss) + if (*p == '(') + p++; + r = (char *)parse_table[i].addr; +- for (s=p; *s && *s != ' ' && *s != '\n' && *s != ')'; s++) +- *r++ = *s; /* TODO check r len */ ++ for (s=p; *s && *s != ' ' && *s != '\n' && *s != ')'; s++) { ++ *r++ = *s; ++ if (r - (char *)parse_table[i].addr >= parse_table[i].size - 1) ++ break; ++ } + *r = '\0'; + break; + case PM_TYPE_32: +diff --git a/src/pmdas/linux_sockets/ss_stats.h b/src/pmdas/linux_sockets/ss_stats.h +index 183db5afa..009a00cd9 100644 +--- a/src/pmdas/linux_sockets/ss_stats.h ++++ b/src/pmdas/linux_sockets/ss_stats.h +@@ -1,11 +1,11 @@ + /* +- * Copyright (c) 2021 Red Hat. +- * ++ * Copyright (c) 2021-2022 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 +@@ -26,7 +26,7 @@ typedef struct ss_stats { + __int32_t timer_retrans; + __uint32_t uid; + __uint64_t sk; +- char cgroup[64]; ++ char cgroup[128]; + __int32_t v6only; + char skmem_str[64]; + __int32_t skmem_rmem_alloc; +commit 77ba20d5e76ada83283a262dd2083b2fc284b5f8 +Author: Nathan Scott +Date: Thu May 5 09:33:46 2022 +1000 + + selinux: policy updates needed for the pmdasockets metrics + + Thanks to Jan Kurík and Miloš Malík we have the additional + selinux policy requirements - without these we see QE test + failures for this agent with pcp-ss(1) on RHEL. + + Related to Red Hat BZ #1981886. + +diff --git a/qa/917.out.in b/qa/917.out.in +index 3bd1dc15e..6a4356a12 100644 +--- a/qa/917.out.in ++++ b/qa/917.out.in +@@ -154,9 +154,9 @@ Checking policies. + # -- end logging_watch_journal_dirs(pcp_domain) expansion + allow [pcp_pmcd_t] [cluster_tmpfs_t] : [file] { write }; + allow [pcp_pmcd_t] [drbd_exec_t] : [file] { execute execute_no_trans }; +- allow [pcp_pmcd_t] self : [netlink_generic_socket] { bind create getattr setopt write read }; +- allow [pcp_pmcd_t] [sbd_exec_t] : [file] { execute execute_no_trans }; +- allow [pcp_pmcd_t] self : [netlink_tcpdiag_socket] { bind create getattr nlmsg_read setopt }; ++! allow [pcp_pmcd_t] self : [netlink_generic_socket] { bind create getattr setopt write read }; ++! allow [pcp_pmcd_t] [sbd_exec_t] : [file] { execute execute_no_trans }; ++! allow [pcp_pmcd_t] self : [netlink_tcpdiag_socket] { append bind connect create getattr getopt ioctl lock read setattr setopt shutdown write }; + allow [syslogd_t] [pcp_log_t] : [fifo_file] { open read write }; + allow [pcp_pmcd_t] [etc_t] : [dir] { open read search getattr lock ioctl }; + allow [pcp_pmcd_t] [shadow_t] : [file] { getattr ioctl lock open read }; +diff --git a/src/selinux/GNUlocaldefs b/src/selinux/GNUlocaldefs +index 1a1b1428c..1462c5ccb 100644 +--- a/src/selinux/GNUlocaldefs ++++ b/src/selinux/GNUlocaldefs +@@ -138,8 +138,8 @@ PCP_NETLINK_GENERIC_SOCKET_RULE="allow pcp_pmcd_t self:netlink_generic_socket { + endif + + ifeq "$(PCP_SELINUX_NETLINK_TCPDIAG_SOCKET_CLASS)" "true" +-PCP_NETLINK_TCPDIAG_SOCKET_CLASS="class netlink_tcpdiag_socket { bind create getattr nlmsg_read setopt };" +-PCP_NETLINK_TCPDIAG_SOCKET_RULE="allow pcp_pmcd_t self:netlink_tcpdiag_socket { bind create getattr nlmsg_read setopt };" ++PCP_NETLINK_TCPDIAG_SOCKET_CLASS="class netlink_tcpdiag_socket { append bind connect create getattr getopt ioctl lock read setattr setopt shutdown write };" ++PCP_NETLINK_TCPDIAG_SOCKET_RULE="allow pcp_pmcd_t self:netlink_tcpdiag_socket { append bind connect create getattr getopt ioctl lock read setattr setopt shutdown write };" + endif + + ifeq "$(PCP_SELINUX_LOCKDOWN_CLASS)" "true" +commit a6222992fe5f97f94bdddd928ce9557be1918bfd +Author: Jan Kurik +Date: Fri May 6 08:04:46 2022 +1000 + + selinux: fine-tune netlink_tcpdiag_socket policy for all platforms + + Previous policy set did not apply correctly on ppc64le and aarch64 + architectures. After some tweaking the following set of permissions + was found to work on all the supported architectures and fixes the + behavior of the sockets PMDA. + + Related to Red Hat BZ #1981886. + +diff --git a/qa/917.out.in b/qa/917.out.in +index 6a4356a12..723193aa2 100644 +--- a/qa/917.out.in ++++ b/qa/917.out.in +@@ -156,7 +156,7 @@ Checking policies. + allow [pcp_pmcd_t] [drbd_exec_t] : [file] { execute execute_no_trans }; + ! allow [pcp_pmcd_t] self : [netlink_generic_socket] { bind create getattr setopt write read }; + ! allow [pcp_pmcd_t] [sbd_exec_t] : [file] { execute execute_no_trans }; +-! allow [pcp_pmcd_t] self : [netlink_tcpdiag_socket] { append bind connect create getattr getopt ioctl lock read setattr setopt shutdown write }; ++! allow [pcp_pmcd_t] self : [netlink_tcpdiag_socket] { append bind connect create getattr getopt ioctl lock nlmsg_read nlmsg_write read setattr setopt shutdown write }; + allow [syslogd_t] [pcp_log_t] : [fifo_file] { open read write }; + allow [pcp_pmcd_t] [etc_t] : [dir] { open read search getattr lock ioctl }; + allow [pcp_pmcd_t] [shadow_t] : [file] { getattr ioctl lock open read }; +diff --git a/src/selinux/GNUlocaldefs b/src/selinux/GNUlocaldefs +index 1462c5ccb..9733aead9 100644 +--- a/src/selinux/GNUlocaldefs ++++ b/src/selinux/GNUlocaldefs +@@ -138,8 +138,8 @@ PCP_NETLINK_GENERIC_SOCKET_RULE="allow pcp_pmcd_t self:netlink_generic_socket { + endif + + ifeq "$(PCP_SELINUX_NETLINK_TCPDIAG_SOCKET_CLASS)" "true" +-PCP_NETLINK_TCPDIAG_SOCKET_CLASS="class netlink_tcpdiag_socket { append bind connect create getattr getopt ioctl lock read setattr setopt shutdown write };" +-PCP_NETLINK_TCPDIAG_SOCKET_RULE="allow pcp_pmcd_t self:netlink_tcpdiag_socket { append bind connect create getattr getopt ioctl lock read setattr setopt shutdown write };" ++PCP_NETLINK_TCPDIAG_SOCKET_CLASS="class netlink_tcpdiag_socket { append bind connect create getattr getopt ioctl lock nlmsg_read nlmsg_write read setattr setopt shutdown write };" ++PCP_NETLINK_TCPDIAG_SOCKET_RULE="allow pcp_pmcd_t self:netlink_tcpdiag_socket { append bind connect create getattr getopt ioctl lock nlmsg_read nlmsg_write read setattr setopt shutdown write };" + endif + + ifeq "$(PCP_SELINUX_LOCKDOWN_CLASS)" "true" diff --git a/redhat-bugzilla-1991763.patch b/redhat-bugzilla-1991763.patch deleted file mode 100644 index 4d9dc7b..0000000 --- a/redhat-bugzilla-1991763.patch +++ /dev/null @@ -1,83 +0,0 @@ -commit 69c7d9bf5ac24bda51f8c876dc258bfe054b7cf8 -Author: Sunil Mohan Adapa -Date: Tue Feb 1 09:55:23 2022 -0800 - - pmlogger: zeroconf: Prioritize user configuration over zeroconf - - In 2c17ba0cc16f58de511dff1e3122096d60c50bb0, zeroconf provided - defaults (/usr/share/pcp/zeroconf/pmlogger, which was actually - /etc/sysconf/pmlogger_zeroconf at the time of the change) were prioritized over - user configuration (/etc/sysconf/pmlogger). This lead to regression in clients - which edited the user configuration and expected the changes to be given - priority over zeroconf configuration. This was identified at least in - ansible-pcp[1]. - - Undo the changes in this commit so that the final priority is as follows: - - User configuration (/etc/sysconfig/pmlogger) - (priority over) - Zeroconf defaults (/usr/share/pcp/zeroconf/pmlogger) - (priority over) - Code defaults (pmlogger.c) - - Links: - - 1) https://github.com/performancecopilot/pcp/pull/1462#issuecomment-1022714960 - - Tests: - - - Install pcp. Ensure pmlogger is running. Notice that there is no - PMLOGGER_INTERVAL set in the pmlogger daemon's environment. - - - Install pcp-zeroconf. Restart pmlogger. Notice that PMLOGGER_INTERVAL - environment is set in the pmlogger daemon's environment. The value is 10. - - - Edit /etc/sysconfig/pmlogger and set the value of PMLOGGER_INTERVAL to 15. - Restart pmlogger and notice that PMLOGGER_INTERVAL is set to 15 in pmlogger - daemon's environment. - - Signed-off-by: Sunil Mohan Adapa - Tested-by: Sunil Mohan Adapa - -diff --git a/src/pmlogger/pmlogger.defaults b/src/pmlogger/pmlogger.defaults -index 1765760b5..1e96cd6ff 100644 ---- a/src/pmlogger/pmlogger.defaults -+++ b/src/pmlogger/pmlogger.defaults -@@ -1,7 +1,7 @@ - # Environment variables for the primary pmlogger daemon. See also - # the pmlogger control file and pmlogconf(1) for additional details. --# Settings defined in this file will be overridden by any settings --# in the pmlogger zeroconf file (if present). -+# Settings defined in this file will override any settings in the -+# pmlogger zeroconf file (if present). - - # Behaviour regarding listening on external-facing interfaces; - # unset PMLOGGER_LOCAL to allow connections from remote hosts. -diff --git a/src/pmlogger/pmlogger.zeroconf b/src/pmlogger/pmlogger.zeroconf -index 9defc6e3d..fe86dedcc 100644 ---- a/src/pmlogger/pmlogger.zeroconf -+++ b/src/pmlogger/pmlogger.zeroconf -@@ -1,6 +1,6 @@ - # --# PMLOGGER environment variables defined in this file take precedence over --# the same variables defined in the standard pmlogger config file. -+# PMLOGGER environment variables defined in the standard pmlogger config file -+# take precedence over the same variables defined in this file. - # - # The PMLOGGER_INTERVAL setting affects the default primary pmlogger recording - # frequency. This only affects the *default* interval setting when specified -diff --git a/src/pmlogger/pmlogger_check.sh b/src/pmlogger/pmlogger_check.sh -index 6cc2a8ed7..64750cb5f 100755 ---- a/src/pmlogger/pmlogger_check.sh -+++ b/src/pmlogger/pmlogger_check.sh -@@ -983,8 +983,8 @@ END { print m }'` - then - if [ "X$primary" = Xy ] - then -- # pcp-zeroconf environment variables (if present) take precedence -- envs=`grep -h ^PMLOGGER "$PMLOGGERENVS" "$PMLOGGERZEROCONFENVS" 2>/dev/null` -+ # User configuration takes precedence over pcp-zeroconf -+ envs=`grep -h ^PMLOGGER "$PMLOGGERZEROCONFENVS" "$PMLOGGERENVS" 2>/dev/null` - args="-P $args" - iam=" primary" - # clean up port-map, just in case diff --git a/redhat-bugzilla-2003956.patch b/redhat-bugzilla-2003956.patch deleted file mode 100644 index a027740..0000000 --- a/redhat-bugzilla-2003956.patch +++ /dev/null @@ -1,1433 +0,0 @@ -commit 14ffcd934e1c5099b471f4e73da32d1b32bac7e6 -Author: Andreas Gerstmayr -Date: Mon Dec 13 20:10:40 2021 +0100 - - pmdabcc: sync bcc PMDA modules with upstream bcc tools - -diff --git a/src/pmdas/bcc/modules/execsnoop.bpf b/src/pmdas/bcc/modules/execsnoop.bpf -index f69200773..aa755b3a1 100644 ---- a/src/pmdas/bcc/modules/execsnoop.bpf -+++ b/src/pmdas/bcc/modules/execsnoop.bpf -@@ -4,40 +4,57 @@ - #include - #include - #include -+ - #define ARGSIZE 128 -+ - enum event_type { - EVENT_ARG, - EVENT_RET, - }; -+ - struct data_t { - u32 pid; // PID as in the userspace term (i.e. task->tgid in kernel) - u32 ppid; // Parent PID as in the userspace term (i.e task->real_parent->tgid in kernel) -+ u32 uid; - char comm[TASK_COMM_LEN]; - enum event_type type; - char argv[ARGSIZE]; - int retval; - }; -+ - BPF_PERF_OUTPUT(events); -+ - static int __submit_arg(struct pt_regs *ctx, void *ptr, struct data_t *data) - { -- bpf_probe_read(data->argv, sizeof(data->argv), ptr); -+ bpf_probe_read_user(data->argv, sizeof(data->argv), ptr); - events.perf_submit(ctx, data, sizeof(struct data_t)); - return 1; - } -+ - static int submit_arg(struct pt_regs *ctx, void *ptr, struct data_t *data) - { - const char *argp = NULL; -- bpf_probe_read(&argp, sizeof(argp), ptr); -+ bpf_probe_read_user(&argp, sizeof(argp), ptr); - if (argp) { - return __submit_arg(ctx, (void *)(argp), data); - } - return 0; - } -+ - int syscall__execve(struct pt_regs *ctx, - const char __user *filename, - const char __user *const __user *__argv, - const char __user *const __user *__envp) - { -+ -+ u32 uid = bpf_get_current_uid_gid() & 0xffffffff; -+ -+ UID_FILTER -+ -+ if (container_should_be_filtered()) { -+ return 0; -+ } -+ - // create data here and pass to submit_arg to save stack space (#555) - struct data_t data = {}; - struct task_struct *task; -@@ -52,25 +69,37 @@ int syscall__execve(struct pt_regs *ctx, - - bpf_get_current_comm(&data.comm, sizeof(data.comm)); - data.type = EVENT_ARG; -+ - __submit_arg(ctx, (void *)filename, &data); -+ - // skip first arg, as we submitted filename - #pragma unroll - for (int i = 1; i < MAXARG; i++) { - if (submit_arg(ctx, (void *)&__argv[i], &data) == 0) - goto out; - } -+ - // handle truncated argument list - char ellipsis[] = "..."; - __submit_arg(ctx, (void *)ellipsis, &data); - out: - return 0; - } -+ - int do_ret_sys_execve(struct pt_regs *ctx) - { -+ if (container_should_be_filtered()) { -+ return 0; -+ } -+ - struct data_t data = {}; - struct task_struct *task; - -+ u32 uid = bpf_get_current_uid_gid() & 0xffffffff; -+ UID_FILTER -+ - data.pid = bpf_get_current_pid_tgid() >> 32; -+ data.uid = uid; - - task = (struct task_struct *)bpf_get_current_task(); - // Some kernels, like Ubuntu 4.13.0-generic, return 0 -@@ -82,5 +111,6 @@ int do_ret_sys_execve(struct pt_regs *ctx) - data.type = EVENT_RET; - data.retval = PT_REGS_RC(ctx); - events.perf_submit(ctx, &data, sizeof(data)); -+ - return 0; - } -diff --git a/src/pmdas/bcc/modules/execsnoop.python b/src/pmdas/bcc/modules/execsnoop.python -index 54382fa9b..1127cc471 100644 ---- a/src/pmdas/bcc/modules/execsnoop.python -+++ b/src/pmdas/bcc/modules/execsnoop.python -@@ -44,20 +44,6 @@ MODULE = 'execsnoop' - BASENS = 'proc.exec.' - units_none = pmUnits(0, 0, 0, 0, 0, 0) - --TASK_COMM_LEN = 16 # linux/sched.h --ARGSIZE = 128 # should match #define in execsnoop.bpf -- --class Data(ct.Structure): -- """ execsnoop data struct """ -- _fields_ = [ -- ("pid", ct.c_uint), -- ("ppid", ct.c_uint), -- ("comm", ct.c_char * TASK_COMM_LEN), -- ("type", ct.c_int), -- ("argv", ct.c_char * ARGSIZE), -- ("retval", ct.c_int), -- ] -- - class EventType(object): - """ Event type """ - EVENT_ARG = 0 -@@ -137,7 +123,7 @@ class PCPBCCModule(PCPBCCBase): - - def handle_event(self, _cpu, data, _size): - """ Event handler """ -- event = ct.cast(data, ct.POINTER(Data)).contents -+ event = self.bpf["events"].event(data) - skip = False - - if event.type == EventType.EVENT_ARG: -@@ -145,9 +131,9 @@ class PCPBCCModule(PCPBCCBase): - elif event.type == EventType.EVENT_RET: - if event.retval != 0 and not self.include_failed: - skip = True -- if self.command and not re.search(self.command, event.comm): -+ if self.command and not re.search(bytes(self.command), event.comm): - skip = True -- if self.args and not re.search(self.args, b" ".join(self.argv_cache[event.pid])): -+ if self.args and not re.search(bytes(self.args), b" ".join(self.argv_cache[event.pid])): - skip = True - - if not skip: -@@ -177,10 +163,14 @@ class PCPBCCModule(PCPBCCBase): - - self.bpf_text = self.bpf_text.replace("MAXARG", str(self.max_args)) - -+ bpf_text = self.bpf_text -+ bpf_text = bpf_text.replace('UID_FILTER', '') -+ bpf_text = bpf_text.replace('container_should_be_filtered()', '0') -+ - if self.debug: -- self.log("BPF to be compiled:\n" + self.bpf_text.strip()) -+ self.log("BPF to be compiled:\n" + bpf_text.strip()) - -- self.bpf = BPF(text=self.bpf_text) -+ self.bpf = BPF(text=bpf_text) - execve_fnname = self.get_syscall_fnname("execve") - self.bpf.attach_kprobe(event=execve_fnname, fn_name="syscall__execve") - self.bpf.attach_kretprobe(event=execve_fnname, fn_name="do_ret_sys_execve") -diff --git a/src/pmdas/bcc/modules/pcpbcc.python b/src/pmdas/bcc/modules/pcpbcc.python -index 0555dc33f..62783b7fc 100644 ---- a/src/pmdas/bcc/modules/pcpbcc.python -+++ b/src/pmdas/bcc/modules/pcpbcc.python -@@ -14,6 +14,7 @@ - """ PCP BCC PMDA module base class """ - - import re -+import platform - import ctypes as ct - from os import kill, listdir, path - from collections import OrderedDict -@@ -348,6 +349,16 @@ class PCPBCCBase(object): - """ Returns BCC version as an int tuple (for comparisons) """ - return tuple(map(int, PCPBCCBase.bcc_version().split('.'))) - -+ @staticmethod -+ def kernel_version(): -+ """Returns the kernel version""" -+ version_str = platform.release() -+ m = re.match(r'^(\d+)\.(\d+)\.(\d+)', version_str) -+ if m: -+ return tuple(map(int, m.groups())) -+ else: -+ return (0, 0, 0) -+ - def perf_buffer_poller(self): - """ BPF poller """ - try: -diff --git a/src/pmdas/bcc/modules/runqlat.python b/src/pmdas/bcc/modules/runqlat.python -index 27007c7e5..1c6c6b4b0 100644 ---- a/src/pmdas/bcc/modules/runqlat.python -+++ b/src/pmdas/bcc/modules/runqlat.python -@@ -30,7 +30,11 @@ from modules.pcpbcc import PCPBCCBase - # - # BPF program - # --bpf_src = "modules/runqlat.bpf" -+is_support_raw_tp = BPF.support_raw_tracepoint() -+if is_support_raw_tp: -+ bpf_src = "modules/runqlat_tp.bpf" -+else: -+ bpf_src = "modules/runqlat_kp.bpf" - - # - # PCP BCC PMDA constants -@@ -59,6 +63,7 @@ class PCPBCCModule(PCPBCCBase): - self.proc_filter = self.config.get(MODULE, opt) - self.update_pids(self.get_proc_info(self.proc_filter)) - -+ self.log("Using BPF source file %s." % bpf_src) - self.log("Initialized.") - - def metrics(self): -@@ -89,7 +94,23 @@ class PCPBCCModule(PCPBCCBase): - with open(path.dirname(__file__) + '/../' + bpf_src) as src: - self.bpf_text = src.read() - -+ # BPF.kernel_struct_has_field requires BCC v0.23.0 -+ # use kernel version check as alternative -+ # pylint: disable=no-member -+ if ( -+ hasattr(BPF, "kernel_struct_has_field") -+ and BPF.kernel_struct_has_field(b"task_struct", b"__state") == 1 -+ ) or self.kernel_version() >= (5, 14, 0): -+ self.bpf_text = self.bpf_text.replace('STATE_FIELD', '__state') -+ else: -+ self.bpf_text = self.bpf_text.replace('STATE_FIELD', 'state') -+ - self.bpf_text = self.bpf_text.replace("FILTER", "PID_CHECK") -+ self.bpf_text = self.bpf_text.replace('FACTOR', 'delta /= 1000;') -+ -+ self.bpf_text = self.bpf_text.replace('STORAGE', 'BPF_HISTOGRAM(dist);') -+ self.bpf_text = self.bpf_text.replace('STORE', -+ 'dist.increment(bpf_log2l(delta));') - - if not self.pids and self.proc_filter and self.proc_refresh: - self.log("No process to attach found, activation postponed.") -@@ -102,9 +123,11 @@ class PCPBCCModule(PCPBCCBase): - - self.reset_cache() - self.bpf = BPF(text=bpf_text) -- self.bpf.attach_kprobe(event="ttwu_do_wakeup", fn_name="trace_ttwu_do_wakeup") -- self.bpf.attach_kprobe(event="wake_up_new_task", fn_name="trace_wake_up_new_task") -- self.bpf.attach_kprobe(event_re=r"^finish_task_switch$|^finish_task_switch\.isra\.\d$", fn_name="trace_run") -+ if not is_support_raw_tp: -+ self.bpf.attach_kprobe(event="ttwu_do_wakeup", fn_name="trace_ttwu_do_wakeup") -+ self.bpf.attach_kprobe(event="wake_up_new_task", fn_name="trace_wake_up_new_task") -+ self.bpf.attach_kprobe(event_re=r"^finish_task_switch$|^finish_task_switch\.isra\.\d$", -+ fn_name="trace_run") - self.log("Compiled.") - except Exception as error: # pylint: disable=broad-except - self.bpf = None -diff --git a/src/pmdas/bcc/modules/runqlat.bpf b/src/pmdas/bcc/modules/runqlat_kp.bpf -similarity index 54% -rename from src/pmdas/bcc/modules/runqlat.bpf -rename to src/pmdas/bcc/modules/runqlat_kp.bpf -index a3664a035..dd643d600 100644 ---- a/src/pmdas/bcc/modules/runqlat.bpf -+++ b/src/pmdas/bcc/modules/runqlat_kp.bpf -@@ -5,6 +5,7 @@ - #include - #include - #include -+#include - - typedef struct pid_key { - u64 id; // work around -@@ -17,7 +18,7 @@ typedef struct pidns_key { - } pidns_key_t; - - BPF_HASH(start, u32); --BPF_HISTOGRAM(dist); -+STORAGE - - struct rq; - -@@ -31,6 +32,45 @@ static int trace_enqueue(u32 tgid, u32 pid) - return 0; - } - -+static __always_inline unsigned int pid_namespace(struct task_struct *task) -+{ -+ -+/* pids[] was removed from task_struct since commit 2c4704756cab7cfa031ada4dab361562f0e357c0 -+ * Using the macro INIT_PID_LINK as a conditional judgment. -+ */ -+#ifdef INIT_PID_LINK -+ struct pid_link pids; -+ unsigned int level; -+ struct upid upid; -+ struct ns_common ns; -+ -+ /* get the pid namespace by following task_active_pid_ns(), -+ * pid->numbers[pid->level].ns -+ */ -+ bpf_probe_read_kernel(&pids, sizeof(pids), &task->pids[PIDTYPE_PID]); -+ bpf_probe_read_kernel(&level, sizeof(level), &pids.pid->level); -+ bpf_probe_read_kernel(&upid, sizeof(upid), &pids.pid->numbers[level]); -+ bpf_probe_read_kernel(&ns, sizeof(ns), &upid.ns->ns); -+ -+ return ns.inum; -+#else -+ struct pid *pid; -+ unsigned int level; -+ struct upid upid; -+ struct ns_common ns; -+ -+ /* get the pid namespace by following task_active_pid_ns(), -+ * pid->numbers[pid->level].ns -+ */ -+ bpf_probe_read_kernel(&pid, sizeof(pid), &task->thread_pid); -+ bpf_probe_read_kernel(&level, sizeof(level), &pid->level); -+ bpf_probe_read_kernel(&upid, sizeof(upid), &pid->numbers[level]); -+ bpf_probe_read_kernel(&ns, sizeof(ns), &upid.ns->ns); -+ -+ return ns.inum; -+#endif -+} -+ - int trace_wake_up_new_task(struct pt_regs *ctx, struct task_struct *p) - { - return trace_enqueue(p->tgid, p->pid); -@@ -48,7 +88,7 @@ int trace_run(struct pt_regs *ctx, struct task_struct *prev) - u32 pid, tgid; - - // ivcsw: treat like an enqueue event and store timestamp -- if (prev->state == TASK_RUNNING) { -+ if (prev->STATE_FIELD == TASK_RUNNING) { - tgid = prev->tgid; - pid = prev->pid; - if (!(FILTER || pid == 0)) { -@@ -69,10 +109,10 @@ int trace_run(struct pt_regs *ctx, struct task_struct *prev) - return 0; // missed enqueue - } - delta = bpf_ktime_get_ns() - *tsp; -- delta /= 1000; -+ FACTOR - - // store as histogram -- dist.increment(bpf_log2l(delta)); -+ STORE - - start.delete(&pid); - return 0; -diff --git a/src/pmdas/bcc/modules/runqlat_tp.bpf b/src/pmdas/bcc/modules/runqlat_tp.bpf -new file mode 100644 -index 000000000..f0e9ce69b ---- /dev/null -+++ b/src/pmdas/bcc/modules/runqlat_tp.bpf -@@ -0,0 +1,124 @@ -+// Copyright 2016 Netflix, Inc. -+// Licensed under the Apache License, Version 2.0 (the "License") -+ -+#include -+#include -+#include -+#include -+#include -+ -+typedef struct pid_key { -+ u64 id; // work around -+ u64 slot; -+} pid_key_t; -+ -+typedef struct pidns_key { -+ u64 id; // work around -+ u64 slot; -+} pidns_key_t; -+ -+BPF_HASH(start, u32); -+STORAGE -+ -+struct rq; -+ -+// record enqueue timestamp -+static int trace_enqueue(u32 tgid, u32 pid) -+{ -+ if (FILTER || pid == 0) -+ return 0; -+ u64 ts = bpf_ktime_get_ns(); -+ start.update(&pid, &ts); -+ return 0; -+} -+ -+static __always_inline unsigned int pid_namespace(struct task_struct *task) -+{ -+ -+/* pids[] was removed from task_struct since commit 2c4704756cab7cfa031ada4dab361562f0e357c0 -+ * Using the macro INIT_PID_LINK as a conditional judgment. -+ */ -+#ifdef INIT_PID_LINK -+ struct pid_link pids; -+ unsigned int level; -+ struct upid upid; -+ struct ns_common ns; -+ -+ /* get the pid namespace by following task_active_pid_ns(), -+ * pid->numbers[pid->level].ns -+ */ -+ bpf_probe_read_kernel(&pids, sizeof(pids), &task->pids[PIDTYPE_PID]); -+ bpf_probe_read_kernel(&level, sizeof(level), &pids.pid->level); -+ bpf_probe_read_kernel(&upid, sizeof(upid), &pids.pid->numbers[level]); -+ bpf_probe_read_kernel(&ns, sizeof(ns), &upid.ns->ns); -+ -+ return ns.inum; -+#else -+ struct pid *pid; -+ unsigned int level; -+ struct upid upid; -+ struct ns_common ns; -+ -+ /* get the pid namespace by following task_active_pid_ns(), -+ * pid->numbers[pid->level].ns -+ */ -+ bpf_probe_read_kernel(&pid, sizeof(pid), &task->thread_pid); -+ bpf_probe_read_kernel(&level, sizeof(level), &pid->level); -+ bpf_probe_read_kernel(&upid, sizeof(upid), &pid->numbers[level]); -+ bpf_probe_read_kernel(&ns, sizeof(ns), &upid.ns->ns); -+ -+ return ns.inum; -+#endif -+} -+ -+RAW_TRACEPOINT_PROBE(sched_wakeup) -+{ -+ // TP_PROTO(struct task_struct *p) -+ struct task_struct *p = (struct task_struct *)ctx->args[0]; -+ return trace_enqueue(p->tgid, p->pid); -+} -+ -+RAW_TRACEPOINT_PROBE(sched_wakeup_new) -+{ -+ // TP_PROTO(struct task_struct *p) -+ struct task_struct *p = (struct task_struct *)ctx->args[0]; -+ return trace_enqueue(p->tgid, p->pid); -+} -+ -+RAW_TRACEPOINT_PROBE(sched_switch) -+{ -+ // TP_PROTO(bool preempt, struct task_struct *prev, struct task_struct *next) -+ struct task_struct *prev = (struct task_struct *)ctx->args[1]; -+ struct task_struct *next = (struct task_struct *)ctx->args[2]; -+ u32 pid, tgid; -+ -+ // ivcsw: treat like an enqueue event and store timestamp -+ if (prev->STATE_FIELD == TASK_RUNNING) { -+ tgid = prev->tgid; -+ pid = prev->pid; -+ if (!(FILTER || pid == 0)) { -+ u64 ts = bpf_ktime_get_ns(); -+ start.update(&pid, &ts); -+ } -+ } -+ -+ tgid = next->tgid; -+ pid = next->pid; -+ if (FILTER || pid == 0) -+ return 0; -+ u64 *tsp, delta; -+ -+ // fetch timestamp and calculate delta -+ tsp = start.lookup(&pid); -+ if (tsp == 0) { -+ return 0; // missed enqueue -+ } -+ delta = bpf_ktime_get_ns() - *tsp; -+ FACTOR -+ -+ // store as histogram -+ STORE -+ -+ start.delete(&pid); -+ return 0; -+} -diff --git a/src/pmdas/bcc/modules/tcplife.python b/src/pmdas/bcc/modules/tcplife.python -index 0c6f17c36..02c693a6a 100644 ---- a/src/pmdas/bcc/modules/tcplife.python -+++ b/src/pmdas/bcc/modules/tcplife.python -@@ -37,16 +37,11 @@ from modules.pcpbcc import PCPBCCBase - # - # BPF program - # --bpf_src = "modules/tcplife.bpf" --# Compat with kernel < 4.16, bcc < 0.6 --TRACEFS = "/sys/kernel/debug/tracing" --bpf_src_old_tp = "modules/tcplife_old_tp.bpf" --bpf_src_old_kb = "modules/tcplife_old_kb.bpf" --if not path.exists(TRACEFS + "/events/sock/inet_sock_set_state"): -- if path.exists(TRACEFS + "/events/tcp/tcp_set_state"): -- bpf_src = bpf_src_old_tp -- else: -- bpf_src = bpf_src_old_kb -+if BPF.tracepoint_exists("sock", "inet_sock_set_state"): -+ bpf_src = "modules/tcplife_tp.bpf" -+else: -+ bpf_src = "modules/tcplife_kp.bpf" -+ - - # - # PCP BCC PMDA constants -@@ -57,35 +52,6 @@ units_bytes = pmUnits(1, 0, 0, PM_SPACE_BYTE, 0, 0) - units_usecs = pmUnits(0, 1, 0, 0, PM_TIME_USEC, 0) - units_none = pmUnits(0, 0, 0, 0, 0, 0) - --TASK_COMM_LEN = 16 # linux/sched.h -- --class Data_ipv4(ct.Structure): -- """ IPv4 data struct """ -- _fields_ = [ -- ("ts_us", ct.c_ulonglong), -- ("pid", ct.c_ulonglong), -- ("saddr", ct.c_ulonglong), -- ("daddr", ct.c_ulonglong), -- ("ports", ct.c_ulonglong), -- ("rx_b", ct.c_ulonglong), -- ("tx_b", ct.c_ulonglong), -- ("span_us", ct.c_ulonglong), -- ("task", ct.c_char * TASK_COMM_LEN) -- ] -- --class Data_ipv6(ct.Structure): -- """ IPv6 data struct """ -- _fields_ = [ -- ("ts_us", ct.c_ulonglong), -- ("pid", ct.c_ulonglong), -- ("saddr", (ct.c_ulonglong * 2)), -- ("daddr", (ct.c_ulonglong * 2)), -- ("ports", ct.c_ulonglong), -- ("rx_b", ct.c_ulonglong), -- ("tx_b", ct.c_ulonglong), -- ("span_us", ct.c_ulonglong), -- ("task", ct.c_char * TASK_COMM_LEN) -- ] - - # - # PCP BCC Module -@@ -129,24 +95,22 @@ class PCPBCCModule(PCPBCCBase): - self.lock = Lock() - self.thread = None - -- # Compat with kernel < 4.16 - self.log("Using BPF source file %s." % bpf_src) - - # Exit hard if impossible to continue -- if self.bcc_version() == "0.6.1" and bpf_src == bpf_src_old_kb: -- raise RuntimeError("BCC 0.6.1 bug makes it incompatible with this module " -- "on kernel < 4.15.") -+ if self.bcc_version_tuple() < (0, 6, 1): -+ raise RuntimeError("BCC 0.6.1+ is required for this module.") - - self.log("Initialized.") - - def handle_ip_event(self, data, version): - """ IP event handler """ - if version == 4: -- event = ct.cast(data, ct.POINTER(Data_ipv4)).contents -+ event = self.bpf["ipv4_events"].event(data) - laddr = inet_ntop(AF_INET, pack("I", event.saddr)) - daddr = inet_ntop(AF_INET, pack("I", event.daddr)) - else: -- event = ct.cast(data, ct.POINTER(Data_ipv6)).contents -+ event = self.bpf["ipv6_events"].event(data) - laddr = inet_ntop(AF_INET6, event.saddr) - daddr = inet_ntop(AF_INET6, event.daddr) - -@@ -205,31 +169,25 @@ class PCPBCCModule(PCPBCCBase): - if not self.bpf_text: - with open(path.dirname(__file__) + '/../' + bpf_src) as src: - self.bpf_text = src.read() -- # Compat with bcc < 0.6 -- self.log("Testing BCC compatilibility, possible errors below are safe to ignore.") -- try: -- test_txt = self.bpf_text.replace("// NEW: ", "").replace("FILTER_PID", "") -- test_bpf = BPF(text=test_txt) -- test_bpf.cleanup() -- self.bpf_text = self.bpf_text.replace("// NEW: ", "") -- except Exception: # pylint: disable=broad-except -- self.bpf_text = self.bpf_text.replace("// OLD: ", "") -- self.log("Tested BCC compatilibility, possible errors above are safe to ignore.") - - if self.dports: - filterp = " && ".join(["dport != %d" % port for port in self.dports]) - filter_txt = "if (%s) { birth.delete(&sk); return 0; }" % filterp -- self.bpf_text = self.bpf_text.replace("//FILTER_DPORT", filter_txt) -+ self.bpf_text = self.bpf_text.replace("FILTER_DPORT", filter_txt) - if self.lports: - filterp = " && ".join(["lport != %d" % port for port in self.lports]) - filter_txt = "if (%s) { birth.delete(&sk); return 0; }" % filterp -- self.bpf_text = self.bpf_text.replace("//FILTER_LPORT", filter_txt) -+ self.bpf_text = self.bpf_text.replace("FILTER_LPORT", filter_txt) - - if not self.pids and self.proc_filter and self.proc_refresh: - self.log("No process to attach found, activation postponed.") - return - - bpf_text = self.apply_pid_filter(self.bpf_text, self.pids, False) -+ bpf_text = bpf_text.replace('FILTER_PID', '') -+ bpf_text = bpf_text.replace('FILTER_DPORT', '') -+ bpf_text = bpf_text.replace('FILTER_LPORT', '') -+ bpf_text = bpf_text.replace('FILTER_FAMILY', '') - - if self.debug: - self.log("BPF to be compiled:\n" + bpf_text.strip()) -diff --git a/src/pmdas/bcc/modules/tcplife_old_kb.bpf b/src/pmdas/bcc/modules/tcplife_kp.bpf -similarity index 81% -rename from src/pmdas/bcc/modules/tcplife_old_kb.bpf -rename to src/pmdas/bcc/modules/tcplife_kp.bpf -index eed01941a..5486c6a37 100644 ---- a/src/pmdas/bcc/modules/tcplife_old_kb.bpf -+++ b/src/pmdas/bcc/modules/tcplife_kp.bpf -@@ -2,7 +2,6 @@ - // Licensed under the Apache License, Version 2.0 (the "License") - - #include --#define KBUILD_MODNAME "pcpbcctcplife" - #include - #include - #include -@@ -11,11 +10,10 @@ BPF_HASH(birth, struct sock *, u64); - - // separate data structs for ipv4 and ipv6 - struct ipv4_data_t { -- // XXX: switch some to u32's when supported - u64 ts_us; -- u64 pid; -- u64 saddr; -- u64 daddr; -+ u32 pid; -+ u32 saddr; -+ u32 daddr; - u64 ports; - u64 rx_b; - u64 tx_b; -@@ -26,7 +24,7 @@ BPF_PERF_OUTPUT(ipv4_events); - - struct ipv6_data_t { - u64 ts_us; -- u64 pid; -+ u32 pid; - unsigned __int128 saddr; - unsigned __int128 daddr; - u64 ports; -@@ -49,12 +47,12 @@ int kprobe__tcp_set_state(struct pt_regs *ctx, struct sock *sk, int state) - - // lport is either used in a filter here, or later - u16 lport = sk->__sk_common.skc_num; -- //FILTER_LPORT -+ FILTER_LPORT - - // dport is either used in a filter here, or later - u16 dport = sk->__sk_common.skc_dport; - dport = ntohs(dport); -- //FILTER_DPORT -+ FILTER_DPORT - - /* - * This tool includes PID and comm context. It's best effort, and may -@@ -74,6 +72,9 @@ int kprobe__tcp_set_state(struct pt_regs *ctx, struct sock *sk, int state) - * sets ESTABLISHED without a tcp_set_state() call. Until we know - * that for sure, match all early states to increase chances a - * timestamp is set. -+ * Note that this needs to be set before the PID filter later on, -+ * since the PID isn't reliable for these early stages, so we must -+ * save all timestamps and do the PID filter later when we can. - */ - u64 ts = bpf_ktime_get_ns(); - birth.update(&sk, &ts); -@@ -101,7 +102,7 @@ int kprobe__tcp_set_state(struct pt_regs *ctx, struct sock *sk, int state) - delta_us = (bpf_ktime_get_ns() - *tsp) / 1000; - birth.delete(&sk); - -- // fetch possible cached data -+ // fetch possible cached data, and filter - struct id_t *mep; - mep = whoami.lookup(&sk); - if (mep != 0) -@@ -116,9 +117,13 @@ int kprobe__tcp_set_state(struct pt_regs *ctx, struct sock *sk, int state) - - u16 family = sk->__sk_common.skc_family; - -+ FILTER_FAMILY -+ - if (family == AF_INET) { -- struct ipv4_data_t data4 = {.span_us = delta_us, -- .rx_b = rx_b, .tx_b = tx_b}; -+ struct ipv4_data_t data4 = {}; -+ data4.span_us = delta_us; -+ data4.rx_b = rx_b; -+ data4.tx_b = tx_b; - data4.ts_us = bpf_ktime_get_ns() / 1000; - data4.saddr = sk->__sk_common.skc_rcv_saddr; - data4.daddr = sk->__sk_common.skc_daddr; -@@ -128,17 +133,19 @@ int kprobe__tcp_set_state(struct pt_regs *ctx, struct sock *sk, int state) - if (mep == 0) { - bpf_get_current_comm(&data4.task, sizeof(data4.task)); - } else { -- bpf_probe_read(&data4.task, sizeof(data4.task), (void *)mep->task); -+ bpf_probe_read_kernel(&data4.task, sizeof(data4.task), (void *)mep->task); - } - ipv4_events.perf_submit(ctx, &data4, sizeof(data4)); - - } else /* 6 */ { -- struct ipv6_data_t data6 = {.span_us = delta_us, -- .rx_b = rx_b, .tx_b = tx_b}; -+ struct ipv6_data_t data6 = {}; -+ data6.span_us = delta_us; -+ data6.rx_b = rx_b; -+ data6.tx_b = tx_b; - data6.ts_us = bpf_ktime_get_ns() / 1000; -- bpf_probe_read(&data6.saddr, sizeof(data6.saddr), -+ bpf_probe_read_kernel(&data6.saddr, sizeof(data6.saddr), - sk->__sk_common.skc_v6_rcv_saddr.in6_u.u6_addr32); -- bpf_probe_read(&data6.daddr, sizeof(data6.daddr), -+ bpf_probe_read_kernel(&data6.daddr, sizeof(data6.daddr), - sk->__sk_common.skc_v6_daddr.in6_u.u6_addr32); - // a workaround until data6 compiles with separate lport/dport - data6.ports = dport + ((0ULL + lport) << 32); -@@ -146,7 +153,7 @@ int kprobe__tcp_set_state(struct pt_regs *ctx, struct sock *sk, int state) - if (mep == 0) { - bpf_get_current_comm(&data6.task, sizeof(data6.task)); - } else { -- bpf_probe_read(&data6.task, sizeof(data6.task), (void *)mep->task); -+ bpf_probe_read_kernel(&data6.task, sizeof(data6.task), (void *)mep->task); - } - ipv6_events.perf_submit(ctx, &data6, sizeof(data6)); - } -diff --git a/src/pmdas/bcc/modules/tcplife_old_tp.bpf b/src/pmdas/bcc/modules/tcplife_old_tp.bpf -deleted file mode 100644 -index a7c9c625c..000000000 ---- a/src/pmdas/bcc/modules/tcplife_old_tp.bpf -+++ /dev/null -@@ -1,166 +0,0 @@ --// Copyright 2016 Netflix, Inc. --// Licensed under the Apache License, Version 2.0 (the "License") -- --#include --#define KBUILD_MODNAME "pcpbcctcplife" --#include --#include --#include -- --BPF_HASH(birth, struct sock *, u64); -- --// separate data structs for ipv4 and ipv6 --struct ipv4_data_t { -- // XXX: switch some to u32's when supported -- u64 ts_us; -- u64 pid; -- u64 saddr; -- u64 daddr; -- u64 ports; -- u64 rx_b; -- u64 tx_b; -- u64 span_us; -- char task[TASK_COMM_LEN]; --}; --BPF_PERF_OUTPUT(ipv4_events); -- --struct ipv6_data_t { -- u64 ts_us; -- u64 pid; -- unsigned __int128 saddr; -- unsigned __int128 daddr; -- u64 ports; -- u64 rx_b; -- u64 tx_b; -- u64 span_us; -- char task[TASK_COMM_LEN]; --}; --BPF_PERF_OUTPUT(ipv6_events); -- --struct id_t { -- u32 pid; -- char task[TASK_COMM_LEN]; --}; --BPF_HASH(whoami, struct sock *, struct id_t); -- --TRACEPOINT_PROBE(tcp, tcp_set_state) --{ -- u32 pid = bpf_get_current_pid_tgid() >> 32; -- // sk is mostly used as a UUID, once for skc_family, and two tcp stats: -- struct sock *sk = (struct sock *)args->skaddr; -- -- // lport is either used in a filter here, or later -- u16 lport = args->sport; -- //FILTER_LPORT -- -- // dport is either used in a filter here, or later -- u16 dport = args->dport; -- //FILTER_DPORT -- -- /* -- * This tool includes PID and comm context. It's best effort, and may -- * be wrong in some situations. It currently works like this: -- * - record timestamp on any state < TCP_FIN_WAIT1 -- * - cache task context on: -- * TCP_SYN_SENT: tracing from client -- * TCP_LAST_ACK: client-closed from server -- * - do output on TCP_CLOSE: -- * fetch task context if cached, or use current task -- */ -- -- // capture birth time -- if (args->newstate < TCP_FIN_WAIT1) { -- /* -- * Matching just ESTABLISHED may be sufficient, provided no code-path -- * sets ESTABLISHED without a tcp_set_state() call. Until we know -- * that for sure, match all early states to increase chances a -- * timestamp is set. -- * Note that this needs to be set before the PID filter later on, -- * since the PID isn't reliable for these early stages, so we must -- * save all timestamps and do the PID filter later when we can. -- */ -- u64 ts = bpf_ktime_get_ns(); -- birth.update(&sk, &ts); -- } -- -- // record PID & comm on SYN_SENT -- if (args->newstate == TCP_SYN_SENT || args->newstate == TCP_LAST_ACK) { -- // now we can PID filter, both here and a little later on for CLOSE -- FILTER_PID -- struct id_t me = {.pid = pid}; -- bpf_get_current_comm(&me.task, sizeof(me.task)); -- whoami.update(&sk, &me); -- } -- -- if (args->newstate != TCP_CLOSE) -- return 0; -- -- // calculate lifespan -- u64 *tsp, delta_us; -- tsp = birth.lookup(&sk); -- if (tsp == 0) { -- whoami.delete(&sk); // may not exist -- return 0; // missed create -- } -- delta_us = (bpf_ktime_get_ns() - *tsp) / 1000; -- birth.delete(&sk); -- -- // fetch possible cached data, and filter -- struct id_t *mep; -- mep = whoami.lookup(&sk); -- if (mep != 0) -- pid = mep->pid; -- FILTER_PID -- -- // get throughput stats. see tcp_get_info(). -- u64 rx_b = 0, tx_b = 0, sport = 0; -- struct tcp_sock *tp = (struct tcp_sock *)sk; -- // OLD: bpf_probe_read(&rx_b, sizeof(rx_b), &tp->bytes_received); -- // OLD: bpf_probe_read(&tx_b, sizeof(tx_b), &tp->bytes_acked); -- // NEW: rx_b = tp->bytes_received; -- // NEW: tx_b = tp->bytes_acked; -- -- u16 family = 0; -- // OLD: bpf_probe_read(&family, sizeof(family), &sk->__sk_common.skc_family); -- // NEW: family = sk->__sk_common.skc_family; -- -- if (family == AF_INET) { -- -- struct ipv4_data_t data4 = {.span_us = delta_us, -- .rx_b = rx_b, .tx_b = tx_b}; -- data4.ts_us = bpf_ktime_get_ns() / 1000; -- bpf_probe_read(&data4.saddr, sizeof(u32), args->saddr); -- bpf_probe_read(&data4.daddr, sizeof(u32), args->daddr); -- // a workaround until data4 compiles with separate lport/dport -- data4.ports = dport + ((0ULL + lport) << 32); -- data4.pid = pid; -- -- if (mep == 0) { -- bpf_get_current_comm(&data4.task, sizeof(data4.task)); -- } else { -- bpf_probe_read(&data4.task, sizeof(data4.task), (void *)mep->task); -- } -- ipv4_events.perf_submit(args, &data4, sizeof(data4)); -- -- } else /* 6 */ { -- struct ipv6_data_t data6 = {.span_us = delta_us, -- .rx_b = rx_b, .tx_b = tx_b}; -- data6.ts_us = bpf_ktime_get_ns() / 1000; -- bpf_probe_read(&data6.saddr, sizeof(data6.saddr), args->saddr_v6); -- bpf_probe_read(&data6.daddr, sizeof(data6.daddr), args->saddr_v6); -- // a workaround until data6 compiles with separate lport/dport -- data6.ports = dport + ((0ULL + lport) << 32); -- data6.pid = pid; -- if (mep == 0) { -- bpf_get_current_comm(&data6.task, sizeof(data6.task)); -- } else { -- bpf_probe_read(&data6.task, sizeof(data6.task), (void *)mep->task); -- } -- ipv6_events.perf_submit(args, &data6, sizeof(data6)); -- } -- -- if (mep != 0) -- whoami.delete(&sk); -- -- return 0; --} -diff --git a/src/pmdas/bcc/modules/tcplife.bpf b/src/pmdas/bcc/modules/tcplife_tp.bpf -similarity index 80% -rename from src/pmdas/bcc/modules/tcplife.bpf -rename to src/pmdas/bcc/modules/tcplife_tp.bpf -index 19ca8d740..2b16b98e7 100644 ---- a/src/pmdas/bcc/modules/tcplife.bpf -+++ b/src/pmdas/bcc/modules/tcplife_tp.bpf -@@ -2,7 +2,6 @@ - // Licensed under the Apache License, Version 2.0 (the "License") - - #include --#define KBUILD_MODNAME "pcpbcctcplife" - #include - #include - #include -@@ -11,11 +10,10 @@ BPF_HASH(birth, struct sock *, u64); - - // separate data structs for ipv4 and ipv6 - struct ipv4_data_t { -- // XXX: switch some to u32's when supported - u64 ts_us; -- u64 pid; -- u64 saddr; -- u64 daddr; -+ u32 pid; -+ u32 saddr; -+ u32 daddr; - u64 ports; - u64 rx_b; - u64 tx_b; -@@ -26,7 +24,7 @@ BPF_PERF_OUTPUT(ipv4_events); - - struct ipv6_data_t { - u64 ts_us; -- u64 pid; -+ u32 pid; - unsigned __int128 saddr; - unsigned __int128 daddr; - u64 ports; -@@ -54,11 +52,11 @@ TRACEPOINT_PROBE(sock, inet_sock_set_state) - - // lport is either used in a filter here, or later - u16 lport = args->sport; -- //FILTER_LPORT -+ FILTER_LPORT - - // dport is either used in a filter here, or later - u16 dport = args->dport; -- //FILTER_DPORT -+ FILTER_DPORT - - /* - * This tool includes PID and comm context. It's best effort, and may -@@ -115,20 +113,23 @@ TRACEPOINT_PROBE(sock, inet_sock_set_state) - pid = mep->pid; - FILTER_PID - -+ u16 family = args->family; -+ FILTER_FAMILY -+ - // get throughput stats. see tcp_get_info(). - u64 rx_b = 0, tx_b = 0, sport = 0; - struct tcp_sock *tp = (struct tcp_sock *)sk; -- // OLD: bpf_probe_read(&rx_b, sizeof(rx_b), &tp->bytes_received); -- // OLD: bpf_probe_read(&tx_b, sizeof(tx_b), &tp->bytes_acked); -- // NEW: rx_b = tp->bytes_received; -- // NEW: tx_b = tp->bytes_acked; -+ rx_b = tp->bytes_received; -+ tx_b = tp->bytes_acked; - - if (args->family == AF_INET) { -- struct ipv4_data_t data4 = {.span_us = delta_us, -- .rx_b = rx_b, .tx_b = tx_b}; -+ struct ipv4_data_t data4 = {}; -+ data4.span_us = delta_us; -+ data4.rx_b = rx_b; -+ data4.tx_b = tx_b; - data4.ts_us = bpf_ktime_get_ns() / 1000; -- bpf_probe_read(&data4.saddr, sizeof(u32), args->saddr); -- bpf_probe_read(&data4.daddr, sizeof(u32), args->daddr); -+ __builtin_memcpy(&data4.saddr, args->saddr, sizeof(data4.saddr)); -+ __builtin_memcpy(&data4.daddr, args->daddr, sizeof(data4.daddr)); - // a workaround until data4 compiles with separate lport/dport - data4.ports = dport + ((0ULL + lport) << 32); - data4.pid = pid; -@@ -136,23 +137,25 @@ TRACEPOINT_PROBE(sock, inet_sock_set_state) - if (mep == 0) { - bpf_get_current_comm(&data4.task, sizeof(data4.task)); - } else { -- bpf_probe_read(&data4.task, sizeof(data4.task), (void *)mep->task); -+ bpf_probe_read_kernel(&data4.task, sizeof(data4.task), (void *)mep->task); - } - ipv4_events.perf_submit(args, &data4, sizeof(data4)); - - } else /* 6 */ { -- struct ipv6_data_t data6 = {.span_us = delta_us, -- .rx_b = rx_b, .tx_b = tx_b}; -+ struct ipv6_data_t data6 = {}; -+ data6.span_us = delta_us; -+ data6.rx_b = rx_b; -+ data6.tx_b = tx_b; - data6.ts_us = bpf_ktime_get_ns() / 1000; -- bpf_probe_read(&data6.saddr, sizeof(data6.saddr), args->saddr_v6); -- bpf_probe_read(&data6.daddr, sizeof(data6.daddr), args->saddr_v6); -+ __builtin_memcpy(&data6.saddr, args->saddr_v6, sizeof(data6.saddr)); -+ __builtin_memcpy(&data6.daddr, args->daddr_v6, sizeof(data6.daddr)); - // a workaround until data6 compiles with separate lport/dport - data6.ports = dport + ((0ULL + lport) << 32); - data6.pid = pid; - if (mep == 0) { - bpf_get_current_comm(&data6.task, sizeof(data6.task)); - } else { -- bpf_probe_read(&data6.task, sizeof(data6.task), (void *)mep->task); -+ bpf_probe_read_kernel(&data6.task, sizeof(data6.task), (void *)mep->task); - } - ipv6_events.perf_submit(args, &data6, sizeof(data6)); - } -diff --git a/src/pmdas/bcc/modules/tcpperpid.python b/src/pmdas/bcc/modules/tcpperpid.python -index 3cb2cfcfd..0096929a6 100644 ---- a/src/pmdas/bcc/modules/tcpperpid.python -+++ b/src/pmdas/bcc/modules/tcpperpid.python -@@ -32,16 +32,10 @@ from modules.pcpbcc import PCPBCCBase - # - # BPF program - # --bpf_src = "modules/tcplife.bpf" --# Compat with kernel < 4.16, bcc < 0.6 --TRACEFS = "/sys/kernel/debug/tracing" --bpf_src_old_tp = "modules/tcplife_old_tp.bpf" --bpf_src_old_kb = "modules/tcplife_old_kb.bpf" --if not path.exists(TRACEFS + "/events/sock/inet_sock_set_state"): -- if path.exists(TRACEFS + "/events/tcp/tcp_set_state"): -- bpf_src = bpf_src_old_tp -- else: -- bpf_src = bpf_src_old_kb -+if BPF.tracepoint_exists("sock", "inet_sock_set_state"): -+ bpf_src = "modules/tcplife_tp.bpf" -+else: -+ bpf_src = "modules/tcplife_kp.bpf" - - # Alternative, "high resolution" BPF - bpf_highres = "modules/tcptop.bpf" -@@ -53,36 +47,6 @@ MODULE = 'tcpperpid' - BASENS = 'proc.io.net.total.' - units_bytes = pmUnits(1, 0, 0, PM_SPACE_BYTE, 0, 0) - --TASK_COMM_LEN = 16 # linux/sched.h -- --class Data_ipv4(ct.Structure): -- """ IPv4 data struct """ -- _fields_ = [ -- ("ts_us", ct.c_ulonglong), -- ("pid", ct.c_ulonglong), -- ("saddr", ct.c_ulonglong), -- ("daddr", ct.c_ulonglong), -- ("ports", ct.c_ulonglong), -- ("rx_b", ct.c_ulonglong), -- ("tx_b", ct.c_ulonglong), -- ("span_us", ct.c_ulonglong), -- ("task", ct.c_char * TASK_COMM_LEN) -- ] -- --class Data_ipv6(ct.Structure): -- """ IPv6 data struct """ -- _fields_ = [ -- ("ts_us", ct.c_ulonglong), -- ("pid", ct.c_ulonglong), -- ("saddr", (ct.c_ulonglong * 2)), -- ("daddr", (ct.c_ulonglong * 2)), -- ("ports", ct.c_ulonglong), -- ("rx_b", ct.c_ulonglong), -- ("tx_b", ct.c_ulonglong), -- ("span_us", ct.c_ulonglong), -- ("task", ct.c_char * TASK_COMM_LEN) -- ] -- - # - # PCP BCC Module - # -@@ -133,15 +97,14 @@ class PCPBCCModule(PCPBCCBase): - self.log("Using BPF source file %s." % src) - - # Exit hard if impossible to continue -- if self.bcc_version() == "0.6.1" and src == bpf_src_old_kb and not self.highres: -- raise RuntimeError("BCC 0.6.1 bug makes it incompatible with this module " -- "on kernel < 4.15 in non-highres mode.") -+ if self.bcc_version_tuple() < (0, 6, 1) and not self.highres: -+ raise RuntimeError("BCC 0.6.1+ is required for this module in non-highres mode.") - - self.log("Initialized.") - - def handle_ipv4_event(self, _cpu, data, _size): - """ IPv4 event handler """ -- event = ct.cast(data, ct.POINTER(Data_ipv4)).contents -+ event = self.bpf["ipv4_events"].event(data) - pid = str(event.pid).zfill(6) - self.lock.acquire() - if pid not in self.ipv4_stats: -@@ -153,7 +116,7 @@ class PCPBCCModule(PCPBCCBase): - - def handle_ipv6_event(self, _cpu, data, _size): - """ IPv6 event handler """ -- event = ct.cast(data, ct.POINTER(Data_ipv6)).contents -+ event = self.bpf["ipv6_events"].event(data) - pid = str(event.pid).zfill(6) - self.lock.acquire() - if pid not in self.ipv6_stats: -@@ -199,31 +162,25 @@ class PCPBCCModule(PCPBCCBase): - self.bpf_text = src.read() - if self.highres: - self.bpf_text = self.bpf_text.replace("FILTER", "FILTER_PID") -- # Compat with bcc < 0.6 -- self.log("Testing BCC compatilibility, possible errors below are safe to ignore.") -- try: -- test_txt = self.bpf_text.replace("// NEW: ", "").replace("FILTER_PID", "") -- test_bpf = BPF(text=test_txt) -- test_bpf.cleanup() -- self.bpf_text = self.bpf_text.replace("// NEW: ", "") -- except Exception: # pylint: disable=broad-except -- self.bpf_text = self.bpf_text.replace("// OLD: ", "") -- self.log("Tested BCC compatilibility, possible errors above are safe to ignore.") - - if self.dports: - filterp = " && ".join(["dport != %d" % port for port in self.dports]) - filter_txt = "if (%s) { birth.delete(&sk); return 0; }" % filterp -- self.bpf_text = self.bpf_text.replace("//FILTER_DPORT", filter_txt) -+ self.bpf_text = self.bpf_text.replace("FILTER_DPORT", filter_txt) - if self.lports: - filterp = " && ".join(["lport != %d" % port for port in self.lports]) - filter_txt = "if (%s) { birth.delete(&sk); return 0; }" % filterp -- self.bpf_text = self.bpf_text.replace("//FILTER_LPORT", filter_txt) -+ self.bpf_text = self.bpf_text.replace("FILTER_LPORT", filter_txt) - - if not self.pids and self.proc_filter and self.proc_refresh: - self.log("No process to attach found, activation postponed.") - return - - bpf_text = self.apply_pid_filter(self.bpf_text, self.pids, False) -+ bpf_text = bpf_text.replace('FILTER_PID', '') -+ bpf_text = bpf_text.replace('FILTER_DPORT', '') -+ bpf_text = bpf_text.replace('FILTER_LPORT', '') -+ bpf_text = bpf_text.replace('FILTER_FAMILY', '') - - if self.debug: - self.log("BPF to be compiled:\n" + bpf_text.strip()) -diff --git a/src/pmdas/bcc/modules/tcptop.bpf b/src/pmdas/bcc/modules/tcptop.bpf -index 349ee1529..c1fed7aef 100644 ---- a/src/pmdas/bcc/modules/tcptop.bpf -+++ b/src/pmdas/bcc/modules/tcptop.bpf -@@ -4,6 +4,7 @@ - #include - #include - #include -+ - struct ipv4_key_t { - u32 pid; - u32 saddr; -@@ -13,25 +14,32 @@ struct ipv4_key_t { - }; - BPF_HASH(ipv4_send_bytes, struct ipv4_key_t); - BPF_HASH(ipv4_recv_bytes, struct ipv4_key_t); -+ - struct ipv6_key_t { -+ unsigned __int128 saddr; -+ unsigned __int128 daddr; - u32 pid; -- // workaround until unsigned __int128 support: -- u64 saddr0; -- u64 saddr1; -- u64 daddr0; -- u64 daddr1; - u16 lport; - u16 dport; -+ u64 __pad__; - }; - BPF_HASH(ipv6_send_bytes, struct ipv6_key_t); - BPF_HASH(ipv6_recv_bytes, struct ipv6_key_t); -+ - int kprobe__tcp_sendmsg(struct pt_regs *ctx, struct sock *sk, - struct msghdr *msg, size_t size) - { -- u32 pid = bpf_get_current_pid_tgid(); -- FILTER -+ if (container_should_be_filtered()) { -+ return 0; -+ } -+ -+ u32 pid = bpf_get_current_pid_tgid() >> 32; -+ FILTER_PID -+ - u16 dport = 0, family = sk->__sk_common.skc_family; -- u64 *val, zero = 0; -+ -+ FILTER_FAMILY -+ - if (family == AF_INET) { - struct ipv4_key_t ipv4_key = {.pid = pid}; - ipv4_key.saddr = sk->__sk_common.skc_rcv_saddr; -@@ -39,31 +47,24 @@ int kprobe__tcp_sendmsg(struct pt_regs *ctx, struct sock *sk, - ipv4_key.lport = sk->__sk_common.skc_num; - dport = sk->__sk_common.skc_dport; - ipv4_key.dport = ntohs(dport); -- val = ipv4_send_bytes.lookup_or_init(&ipv4_key, &zero); -- if (val) { -- (*val) += size; -- } -+ ipv4_send_bytes.increment(ipv4_key, size); -+ - } else if (family == AF_INET6) { - struct ipv6_key_t ipv6_key = {.pid = pid}; -- bpf_probe_read(&ipv6_key.saddr0, sizeof(ipv6_key.saddr0), -- &sk->__sk_common.skc_v6_rcv_saddr.in6_u.u6_addr32[0]); -- bpf_probe_read(&ipv6_key.saddr1, sizeof(ipv6_key.saddr1), -- &sk->__sk_common.skc_v6_rcv_saddr.in6_u.u6_addr32[2]); -- bpf_probe_read(&ipv6_key.daddr0, sizeof(ipv6_key.daddr0), -- &sk->__sk_common.skc_v6_daddr.in6_u.u6_addr32[0]); -- bpf_probe_read(&ipv6_key.daddr1, sizeof(ipv6_key.daddr1), -- &sk->__sk_common.skc_v6_daddr.in6_u.u6_addr32[2]); -+ bpf_probe_read_kernel(&ipv6_key.saddr, sizeof(ipv6_key.saddr), -+ &sk->__sk_common.skc_v6_rcv_saddr.in6_u.u6_addr32); -+ bpf_probe_read_kernel(&ipv6_key.daddr, sizeof(ipv6_key.daddr), -+ &sk->__sk_common.skc_v6_daddr.in6_u.u6_addr32); - ipv6_key.lport = sk->__sk_common.skc_num; - dport = sk->__sk_common.skc_dport; - ipv6_key.dport = ntohs(dport); -- val = ipv6_send_bytes.lookup_or_init(&ipv6_key, &zero); -- if (val) { -- (*val) += size; -- } -+ ipv6_send_bytes.increment(ipv6_key, size); - } - // else drop -+ - return 0; - } -+ - /* - * tcp_recvmsg() would be obvious to trace, but is less suitable because: - * - we'd need to trace both entry and return, to have both sock and size -@@ -72,12 +73,21 @@ int kprobe__tcp_sendmsg(struct pt_regs *ctx, struct sock *sk, - */ - int kprobe__tcp_cleanup_rbuf(struct pt_regs *ctx, struct sock *sk, int copied) - { -- u32 pid = bpf_get_current_pid_tgid(); -- FILTER -+ if (container_should_be_filtered()) { -+ return 0; -+ } -+ -+ u32 pid = bpf_get_current_pid_tgid() >> 32; -+ FILTER_PID -+ - u16 dport = 0, family = sk->__sk_common.skc_family; - u64 *val, zero = 0; -+ - if (copied <= 0) - return 0; -+ -+ FILTER_FAMILY -+ - if (family == AF_INET) { - struct ipv4_key_t ipv4_key = {.pid = pid}; - ipv4_key.saddr = sk->__sk_common.skc_rcv_saddr; -@@ -85,28 +95,20 @@ int kprobe__tcp_cleanup_rbuf(struct pt_regs *ctx, struct sock *sk, int copied) - ipv4_key.lport = sk->__sk_common.skc_num; - dport = sk->__sk_common.skc_dport; - ipv4_key.dport = ntohs(dport); -- val = ipv4_recv_bytes.lookup_or_init(&ipv4_key, &zero); -- if (val) { -- (*val) += copied; -- } -+ ipv4_recv_bytes.increment(ipv4_key, copied); -+ - } else if (family == AF_INET6) { - struct ipv6_key_t ipv6_key = {.pid = pid}; -- bpf_probe_read(&ipv6_key.saddr0, sizeof(ipv6_key.saddr0), -- &sk->__sk_common.skc_v6_rcv_saddr.in6_u.u6_addr32[0]); -- bpf_probe_read(&ipv6_key.saddr1, sizeof(ipv6_key.saddr1), -- &sk->__sk_common.skc_v6_rcv_saddr.in6_u.u6_addr32[2]); -- bpf_probe_read(&ipv6_key.daddr0, sizeof(ipv6_key.daddr0), -- &sk->__sk_common.skc_v6_daddr.in6_u.u6_addr32[0]); -- bpf_probe_read(&ipv6_key.daddr1, sizeof(ipv6_key.daddr1), -- &sk->__sk_common.skc_v6_daddr.in6_u.u6_addr32[2]); -+ bpf_probe_read_kernel(&ipv6_key.saddr, sizeof(ipv6_key.saddr), -+ &sk->__sk_common.skc_v6_rcv_saddr.in6_u.u6_addr32); -+ bpf_probe_read_kernel(&ipv6_key.daddr, sizeof(ipv6_key.daddr), -+ &sk->__sk_common.skc_v6_daddr.in6_u.u6_addr32); - ipv6_key.lport = sk->__sk_common.skc_num; - dport = sk->__sk_common.skc_dport; - ipv6_key.dport = ntohs(dport); -- val = ipv6_recv_bytes.lookup_or_init(&ipv6_key, &zero); -- if (val) { -- (*val) += copied; -- } -+ ipv6_recv_bytes.increment(ipv6_key, copied); - } - // else drop -+ - return 0; - } -diff --git a/src/pmdas/bcc/modules/tcptop.python b/src/pmdas/bcc/modules/tcptop.python -index 45063dff3..db1c1da15 100644 ---- a/src/pmdas/bcc/modules/tcptop.python -+++ b/src/pmdas/bcc/modules/tcptop.python -@@ -120,13 +120,14 @@ class PCPBCCModule(PCPBCCBase): - with open(path.dirname(__file__) + '/../' + bpf_src) as src: - self.bpf_text = src.read() - -- self.bpf_text = self.bpf_text.replace("FILTER", "FILTER_PID") -- - if not self.pids and self.proc_filter and self.proc_refresh: - self.log("No process to attach found, activation postponed.") - return - - bpf_text = self.apply_pid_filter(self.bpf_text, self.pids, False) -+ bpf_text = bpf_text.replace('FILTER_PID', '') -+ bpf_text = bpf_text.replace('FILTER_FAMILY', '') -+ bpf_text = bpf_text.replace('container_should_be_filtered()', '0') - - if self.debug: - self.log("BPF to be compiled:\n" + bpf_text.strip()) -@@ -155,21 +156,31 @@ class PCPBCCModule(PCPBCCBase): - - @staticmethod - def ipv4_table_to_dict(table): -- """ Build hashable dict from IPv4 BPF table """ -- return {TCPSessionKey(pid=k.pid, -- laddr=inet_ntop(AF_INET, pack("I", k.saddr)), -- lport=k.lport, -- daddr=inet_ntop(AF_INET, pack("I", k.daddr)), -- dport=k.dport):v.value for k, v in table.items()} -+ """Build hashable dict from IPv4 BPF table""" -+ return { -+ TCPSessionKey( -+ pid=k.pid, -+ laddr=inet_ntop(AF_INET, pack("I", k.saddr)), -+ lport=k.lport, -+ daddr=inet_ntop(AF_INET, pack("I", k.daddr)), -+ dport=k.dport, -+ ): v.value -+ for k, v in table.items() -+ } - - @staticmethod - def ipv6_table_to_dict(table): -- """ Build hashable dict from IPv6 BPF table """ -- return {TCPSessionKey(pid=k.pid, -- laddr=inet_ntop(AF_INET6, pack("QQ", k.saddr0, k.saddr1)), -- lport=k.lport, -- daddr=inet_ntop(AF_INET6, pack("QQ", k.daddr0, k.daddr1)), -- dport=k.dport):v.value for k, v in table.items()} -+ """Build hashable dict from IPv6 BPF table""" -+ return { -+ TCPSessionKey( -+ pid=k.pid, -+ laddr=inet_ntop(AF_INET6, k.saddr), -+ lport=k.lport, -+ daddr=inet_ntop(AF_INET6, k.daddr), -+ dport=k.dport, -+ ): v.value -+ for k, v in table.items() -+ } - - def refresh_stats(self): - """ Refresh statistics from BPF table """ -commit d45ce8e85035cc95ba897cd19967fad6d5d741be (cherry-picked) -Author: Andreas Gerstmayr -Date: Wed Dec 15 08:03:40 2021 +0100 - - qa: update qa/1118 to add new log output of runqlat bcc module - -diff --git a/qa/1118 b/qa/1118 -index 4123495b5..bcaec0a0d 100755 ---- a/qa/1118 -+++ b/qa/1118 -@@ -21,12 +21,19 @@ _label_filter() - grep '"0-1"' | grep '"statistic":"histogram"' | grep '"lower_bound":0' | grep 'upper_bound":1' > /dev/null && echo 'OK' - } - -+_install_filter() -+{ -+ sed \ -+ -e "s/Using BPF source file .\+/Using BPF source file X/g" \ -+ #end -+} -+ - _prepare_pmda bcc - trap "_pmdabcc_cleanup; exit \$status" 0 1 2 3 15 - _stop_auto_restart pmcd - - # real QA test starts here --cat < -Date: Tue Nov 23 16:11:24 2021 +1100 - - pmlogconf: fix reprobing with interactive changes - - In testing an earlier persistance fix it was discovered - that reprobe was inadvertently overwriting user requests - for changes interactively. - - Related to Red Hat BZ #2017632 - -diff --git a/qa/368.out b/qa/368.out -index 829162f859..179a1142cf 100644 ---- a/qa/368.out -+++ b/qa/368.out -@@ -80,44 +80,10 @@ Differences ... - Keep changes? [y] - Group: qa group one - Log this group? [y] ... --Differences ... --*** TMP.orig ... ----- TMP.conf.new ... --*************** --*** 22,35 **** -- sample.long.million -- } -- #---- --! #+ 02:x:: --! #---- --! #+ 03:y:default: --! ## qa group three -- log advisory on default { --! sample.longlong.ten -- } -- #---- -- #+ 04:n:default: -- ## qa group four -- #---- ----- 22,36 ---- -- sample.long.million -- } -- #---- --! #+ 02:y:default: --! ## qa group two -- log advisory on default { --! sample.ulong.ten -- } -- #---- --+ #+ 03:n:default: --+ ## qa group three --+ #---- -- #+ 04:n:default: -- ## qa group four -- #---- --Keep changes? [y] -+No changes -+ - Group: qa group one --Log this group? [y] ...... -+Log this group? [y] ..... - Differences ... - *** TMP.orig ... - --- TMP.conf.new ... -@@ -132,18 +98,8 @@ Differences ... - #---- - --- 18,23 ---- - *************** --*** 26,31 **** ----- 25,31 ---- -- ## qa group two -- log advisory on default { -- sample.ulong.ten --+ sample.ulong.million -- } -- #---- -- #+ 03:n:default: --*************** --*** 37,42 **** ----- 37,53 ---- -+*** 36,41 **** -+--- 35,51 ---- - #+ 05:n:default: - ## qa group five - #---- -@@ -185,15 +141,13 @@ log advisory on default { - sample.long.million - } - #---- --#+ 02:y:default: --## qa group two --log advisory on default { -- sample.ulong.ten -- sample.ulong.million --} -+#+ 02:x:: - #---- --#+ 03:n:default: -+#+ 03:y:default: - ## qa group three -+log advisory on default { -+ sample.longlong.ten -+} - #---- - #+ 04:n:default: - ## qa group four -diff --git a/src/pmlogconf/pmlogconf.c b/src/pmlogconf/pmlogconf.c -index c03c61e797..fa1156859d 100644 ---- a/src/pmlogconf/pmlogconf.c -+++ b/src/pmlogconf/pmlogconf.c -@@ -913,13 +913,13 @@ evaluate_state(group_t *group) - if ((group->pmlogger || group->pmrep) && !group->pmlogconf) { - state = group->saved_state; - } else if (evaluate_group(group)) { /* probe */ -- if (reprobe == 0 && group->saved_state != 0) -+ if (group->saved_state != 0) - state = group->saved_state; - else - state = group->true_state; - group->success = 1; - } else { -- if (reprobe == 0 && group->saved_state != 0) -+ if (group->saved_state != 0) - state = group->saved_state; - else - state = group->false_state; diff --git a/redhat-bugzilla-2027753.patch b/redhat-bugzilla-2027753.patch deleted file mode 100644 index 918a6d5..0000000 --- a/redhat-bugzilla-2027753.patch +++ /dev/null @@ -1,841 +0,0 @@ -diff -Naurp pcp-5.3.5.orig/qa/032 pcp-5.3.5/qa/032 ---- pcp-5.3.5.orig/qa/032 2021-11-01 13:02:26.000000000 +1100 -+++ pcp-5.3.5/qa/032 2022-01-21 10:55:30.286602172 +1100 -@@ -34,13 +34,6 @@ trap "_cleanup" 0 1 2 3 15 - - _stop_auto_restart pmcd - --if [ -d $PCP_LOG_DIR/pmlogger ] --then -- LOGGING_DIR=$PCP_LOG_DIR/pmlogger --else -- LOGGING_DIR=$PCP_LOG_DIR --fi -- - _service pcp stop | _filter_pcp_stop - _wait_pmcd_end - _writable_primary_logger -@@ -48,7 +41,7 @@ _writable_primary_logger - _service pmcd start 2>&1 | _filter_pcp_start - _wait_for_pmcd - _service pmlogger start 2>&1 | _filter_pcp_start --_wait_for_pmlogger -P $LOGGING_DIR/$LOCALHOST/pmlogger.log -+_wait_for_pmlogger - - # real QA test starts here - _echo "expect this to be off" -diff -Naurp pcp-5.3.5.orig/qa/041 pcp-5.3.5/qa/041 ---- pcp-5.3.5.orig/qa/041 2021-09-01 08:58:41.000000000 +1000 -+++ pcp-5.3.5/qa/041 2022-01-21 10:55:30.286602172 +1100 -@@ -40,12 +40,11 @@ _expect() - echo "" | tee -a $seq.full - } - -+status=1 - _needclean=true - TAG=000666000magic --status=1 --[ -z "$PCP_PMLOGGERCONTROL_PATH" ] && \ -- PCP_PMLOGGERCONTROL_PATH="$PCP_SYSCONF_DIR/pmlogger/control" -- -+LOGGING_DIR="$PCP_ARCHIVE_DIR" -+rm -f $seq.full - trap "_cleanup" 0 1 2 3 15 - - _stop_auto_restart pmcd -@@ -68,15 +67,6 @@ _cleanup() - exit $status - } - --if [ -d $PCP_LOG_DIR/pmlogger ] --then -- LOGGING_DIR=$PCP_LOG_DIR/pmlogger --else -- LOGGING_DIR=$PCP_LOG_DIR --fi -- --rm -f $seq.full -- - # real QA test starts here - - # disable all pmloggers ... -diff -Naurp pcp-5.3.5.orig/qa/066 pcp-5.3.5/qa/066 ---- pcp-5.3.5.orig/qa/066 2021-02-17 15:27:41.000000000 +1100 -+++ pcp-5.3.5/qa/066 2022-01-21 10:55:30.286602172 +1100 -@@ -42,6 +42,7 @@ signal=$PCP_BINADM_DIR/pmsignal - log=$PCP_PMCDLOG_PATH - _needclean=true - LOCALHOST=`hostname` -+LOGGING_DIR="$PCP_ARCHIVE_DIR" - - _filter_log() - { -@@ -80,13 +81,6 @@ interrupt() - exit - } - --if [ -d $PCP_LOG_DIR/pmlogger ] --then -- LOGGING_DIR=$PCP_LOG_DIR/pmlogger --else -- LOGGING_DIR=$PCP_LOG_DIR --fi -- - cleanup() - { - if [ $_needclean ] -diff -Naurp pcp-5.3.5.orig/qa/067 pcp-5.3.5/qa/067 ---- pcp-5.3.5.orig/qa/067 2021-02-17 15:27:41.000000000 +1100 -+++ pcp-5.3.5/qa/067 2022-01-21 10:55:30.287602155 +1100 -@@ -31,6 +31,7 @@ trap "rm -f $tmp.*; exit" 0 1 2 3 15 - signal=$PCP_BINADM_DIR/pmsignal - log=$PCP_PMCDLOG_PATH - LOCALHOST=`hostname` -+LOGGING_DIR="$PCP_ARCHIVE_DIR" - - _filter_log() - { -@@ -69,13 +70,6 @@ interrupt() - exit - } - --if [ -d $PCP_LOG_DIR/pmlogger ] --then -- LOGGING_DIR=$PCP_LOG_DIR/pmlogger --else -- LOGGING_DIR=$PCP_LOG_DIR --fi -- - cleanup() - { - _restore_config $PCP_PMCDCONF_PATH -diff -Naurp pcp-5.3.5.orig/qa/068 pcp-5.3.5/qa/068 ---- pcp-5.3.5.orig/qa/068 2019-01-13 14:14:12.000000000 +1100 -+++ pcp-5.3.5/qa/068 2022-01-21 10:55:30.287602155 +1100 -@@ -19,22 +19,11 @@ echo "QA output created by $seq" - - _needclean=true - LOCALHOST=`hostname` -- -+LOGGING_DIR="$PCP_ARCHIVE_DIR" - trap "_cleanup" 0 1 2 3 15 - --# don't need to regenerate config.default with pmlogconf --# --export PMLOGGER_CHECK_SKIP_LOGCONF=yes -- - _stop_auto_restart pmcd - --if [ -d $PCP_LOG_DIR/pmlogger ] --then -- LOGGING_DIR=$PCP_LOG_DIR/pmlogger --else -- LOGGING_DIR=$PCP_LOG_DIR --fi -- - _cleanup() - { - echo >>$seq.full -diff -Naurp pcp-5.3.5.orig/qa/069 pcp-5.3.5/qa/069 ---- pcp-5.3.5.orig/qa/069 2021-11-08 09:45:56.000000000 +1100 -+++ pcp-5.3.5/qa/069 2022-01-21 10:55:30.287602155 +1100 -@@ -45,6 +45,7 @@ nconfig=$tmp.pmcd.conf.new - log=$PCP_PMCDLOG_PATH - LOCALHOST=`hostname` - LOCALHOST_FULL=`pmhostname` -+LOGGING_DIR="$PCP_ARCHIVE_DIR" - _needclean=true - - rm -f $seq.full -@@ -104,13 +105,6 @@ skip > 0 { skip--; next } - - } - --if [ -d $PCP_LOG_DIR/pmlogger ] --then -- LOGGING_DIR=$PCP_LOG_DIR/pmlogger --else -- LOGGING_DIR=$PCP_LOG_DIR --fi -- - cleanup() - { - if $_needclean -diff -Naurp pcp-5.3.5.orig/qa/1055 pcp-5.3.5/qa/1055 ---- pcp-5.3.5.orig/qa/1055 2021-02-17 15:27:41.000000000 +1100 -+++ pcp-5.3.5/qa/1055 2022-01-21 10:55:30.287602155 +1100 -@@ -17,6 +17,7 @@ signal=$PCP_BINADM_DIR/pmsignal - status=1 - done_clean=false - LOCALHOST=`hostname` -+LOGGING_DIR="$PCP_ARCHIVE_DIR" - - _cleanup() - { -@@ -66,13 +67,7 @@ $sudo cp $tmp.tmp $PCP_PMCDCONF_PATH - _writable_primary_logger - _service pcp restart 2>&1 | _filter_pcp_start - _wait_for_pmcd --if [ -d $PCP_LOG_DIR/pmlogger ] --then -- LOGGING_DIR=$PCP_LOG_DIR/pmlogger --else -- LOGGING_DIR=$PCP_LOG_DIR --fi --_wait_for_pmlogger -P $LOGGING_DIR/$LOCALHOST/pmlogger.log -+_wait_for_pmlogger - - # Reset pmlogger - echo "log sample.dynamic.meta.metric" -diff -Naurp pcp-5.3.5.orig/qa/172 pcp-5.3.5/qa/172 ---- pcp-5.3.5.orig/qa/172 2021-02-17 15:27:41.000000000 +1100 -+++ pcp-5.3.5/qa/172 2022-01-21 10:55:30.287602155 +1100 -@@ -39,6 +39,7 @@ else - esac - fi - -+LOGGING_DIR="$PCP_ARCHIVE_DIR" - LOCALHOST=`hostname` - _needclean=true - status=0 -@@ -48,13 +49,6 @@ _interrupt() - status=1 - } - --if [ -d $PCP_LOG_DIR/pmlogger ] --then -- LOGGING_DIR=$PCP_LOG_DIR/pmlogger --else -- LOGGING_DIR=$PCP_LOG_DIR --fi -- - _cleanup() - { - if $_needclean -diff -Naurp pcp-5.3.5.orig/qa/192 pcp-5.3.5/qa/192 ---- pcp-5.3.5.orig/qa/192 2019-01-13 14:14:12.000000000 +1100 -+++ pcp-5.3.5/qa/192 2022-01-21 10:55:30.287602155 +1100 -@@ -13,6 +13,7 @@ echo "QA output created by $seq" - . ./common.filter - . ./common.check - -+LOGGING_DIR="$PCP_ARCHIVE_DIR" - LOCALHOST=`hostname` - _needclean=true - status=0 -@@ -22,13 +23,6 @@ _interrupt() - status=1 - } - --if [ -d $PCP_LOG_DIR/pmlogger ] --then -- LOGGING_DIR=$PCP_LOG_DIR/pmlogger --else -- LOGGING_DIR=$PCP_LOG_DIR --fi -- - _cleanup() - { - if $_needclean -diff -Naurp pcp-5.3.5.orig/qa/220 pcp-5.3.5/qa/220 ---- pcp-5.3.5.orig/qa/220 2021-07-13 09:34:38.000000000 +1000 -+++ pcp-5.3.5/qa/220 2022-01-21 10:55:30.287602155 +1100 -@@ -18,13 +18,7 @@ which netstat >/dev/null 2>&1 || _notrun - status=0 - clean=false - LOCALHOST=`hostname` -- --if [ -d $PCP_LOG_DIR/pmlogger ] --then -- LOGGING_DIR=$PCP_LOG_DIR/pmlogger --else -- LOGGING_DIR=$PCP_LOG_DIR --fi -+LOGGING_DIR="$PCP_ARCHIVE_DIR" - - _cleanup() - { -diff -Naurp pcp-5.3.5.orig/qa/258 pcp-5.3.5/qa/258 ---- pcp-5.3.5.orig/qa/258 2019-01-30 14:22:38.000000000 +1100 -+++ pcp-5.3.5/qa/258 2022-01-21 10:55:30.287602155 +1100 -@@ -19,6 +19,7 @@ echo "QA output created by $seq" - signal=$PCP_BINADM_DIR/pmsignal - status=1 - LOCALHOST=`hostname` -+LOGGING_DIR="$PCP_ARCHIVE_DIR" - _needclean=true - - _interrupt() -@@ -26,13 +27,6 @@ _interrupt() - status=1 - } - --if [ -d $PCP_LOG_DIR/pmlogger ] --then -- LOGGING_DIR=$PCP_LOG_DIR/pmlogger --else -- LOGGING_DIR=$PCP_LOG_DIR --fi -- - _cleanup() - { - cd $here -diff -Naurp pcp-5.3.5.orig/qa/279 pcp-5.3.5/qa/279 ---- pcp-5.3.5.orig/qa/279 2021-02-17 15:27:41.000000000 +1100 -+++ pcp-5.3.5/qa/279 2022-01-21 10:55:30.287602155 +1100 -@@ -17,6 +17,7 @@ echo "QA output created by $seq" - status=1 # failure is the default! - killer=`pwd`/src/killparent - LOCALHOST=`hostname` -+LOGGING_DIR="$PCP_ARCHIVE_DIR" - _needclean=true - - rm -f $seq.full -@@ -76,13 +77,6 @@ _filter_pmcd() - # end - } - --if [ -d $PCP_LOG_DIR/pmlogger ] --then -- LOGGING_DIR=$PCP_LOG_DIR/pmlogger --else -- LOGGING_DIR=$PCP_LOG_DIR --fi -- - _save_config $PCP_PMCDCONF_PATH - _disable_loggers - pmafm $LOGGING_DIR/$LOCALHOST/Latest remove >$tmp.cmd 2>&1 \ -diff -Naurp pcp-5.3.5.orig/qa/280 pcp-5.3.5/qa/280 ---- pcp-5.3.5.orig/qa/280 2021-08-16 14:12:25.000000000 +1000 -+++ pcp-5.3.5/qa/280 2022-01-21 10:55:30.287602155 +1100 -@@ -13,16 +13,6 @@ echo "QA output created by $seq" - . ./common.filter - . ./common.check - --if [ -d "$PCP_ARCHIVE_DIR" ] --then -- LOGGING_DIR=$PCP_ARCHIVE_DIR --elif [ -d $PCP_LOG_DIR/pmlogger ] --then -- LOGGING_DIR=$PCP_LOG_DIR/pmlogger --else -- LOGGING_DIR=$PCP_LOG_DIR --fi -- - _filter() - { - [ -z "$PCP_PMLOGGERCONTROL_PATH" ] && \ -@@ -52,6 +42,7 @@ _filter() - status=1 # failure is the default! - signal=$PCP_BINADM_DIR/pmsignal - LOCALHOST=`hostname` -+LOGGING_DIR="$PCP_ARCHIVE_DIR" - trap "_cleanup; $sudo rm -f $tmp.* $LOGGING_DIR/$LOCALHOST/lock; exit \$status" 0 1 2 3 15 - - _stop_auto_restart pmcd -diff -Naurp pcp-5.3.5.orig/qa/282 pcp-5.3.5/qa/282 ---- pcp-5.3.5.orig/qa/282 2021-02-17 15:27:41.000000000 +1100 -+++ pcp-5.3.5/qa/282 2022-01-21 10:55:30.287602155 +1100 -@@ -32,7 +32,7 @@ _needclean=true - sleepy=false - - LOCALHOST=`hostname` --LOGGING_DIR=$PCP_LOG_DIR/pmlogger -+LOGGING_DIR="$PCP_ARCHIVE_DIR" - CHECK=`which pmlogger_check` - [ -z "$CHECK" -o ! -x "$CHECK" ] && \ - _notrun "Cannot find an executable pmlogger_check: \"$CHECK\"" -diff -Naurp pcp-5.3.5.orig/qa/336 pcp-5.3.5/qa/336 ---- pcp-5.3.5.orig/qa/336 2018-10-23 07:37:45.000000000 +1100 -+++ pcp-5.3.5/qa/336 2022-01-21 10:55:30.288602138 +1100 -@@ -19,6 +19,7 @@ echo "QA output created by $seq" - signal=$PCP_BINADM_DIR/pmsignal - status=1 # failure is the default! - LOCALHOST=`hostname` -+LOGGING_DIR="$PCP_ARCHIVE_DIR" - _needclean=true - - if [ -n "$PCP_TRACE_HOST" ] -@@ -31,13 +32,6 @@ _interrupt() - status=1 - } - --if [ -d $PCP_LOG_DIR/pmlogger ] --then -- LOGGING_DIR=$PCP_LOG_DIR/pmlogger --else -- LOGGING_DIR=$PCP_LOG_DIR --fi -- - _cleanup() - { - cd $here -diff -Naurp pcp-5.3.5.orig/qa/854 pcp-5.3.5/qa/854 ---- pcp-5.3.5.orig/qa/854 2021-02-17 15:27:41.000000000 +1100 -+++ pcp-5.3.5/qa/854 2022-01-21 10:55:30.288602138 +1100 -@@ -17,6 +17,7 @@ signal=$PCP_BINADM_DIR/pmsignal - status=1 - done_clean=false - LOCALHOST=`hostname` -+LOGGING_DIR="$PCP_ARCHIVE_DIR" - - _cleanup() - { -@@ -59,20 +60,14 @@ cat <$tmp.tmp - # Installed by PCP QA test $seq on `date` - pmcd 2 dso pmcd_init $PMDA_PMCD_PATH - sample 29 pipe binary $PCP_PMDAS_DIR/sample/pmdasample -d 29 --simple 253 pipe binary /var/lib/pcp/pmdas/simple/pmdasimple -d 253 -+simple 253 pipe binary $PCP_PMDAS_DIR/simple/pmdasimple -d 253 - End-of-File - $sudo cp $tmp.tmp $PCP_PMCDCONF_PATH - - _writable_primary_logger - _service pcp restart 2>&1 | _filter_pcp_start - _wait_for_pmcd --if [ -d $PCP_LOG_DIR/pmlogger ] --then -- LOGGING_DIR=$PCP_LOG_DIR/pmlogger --else -- LOGGING_DIR=$PCP_LOG_DIR --fi --_wait_for_pmlogger -P $LOGGING_DIR/$LOCALHOST/pmlogger.log -+_wait_for_pmlogger - - # Reset pmlogger - echo "log sample.dynamic.meta.metric" -diff -Naurp pcp-5.3.5.orig/qa/856 pcp-5.3.5/qa/856 ---- pcp-5.3.5.orig/qa/856 2019-01-13 14:14:12.000000000 +1100 -+++ pcp-5.3.5/qa/856 2022-01-21 10:55:30.288602138 +1100 -@@ -17,6 +17,7 @@ signal=$PCP_BINADM_DIR/pmsignal - status=1 - done_clean=false - LOCALHOST=`hostname` -+LOGGING_DIR="$PCP_ARCHIVE_DIR" - - _cleanup() - { -@@ -69,13 +70,7 @@ $sudo cp $tmp.tmp $PCP_PMCDCONF_PATH - _writable_primary_logger - _service pcp restart 2>&1 | _filter_pcp_start - _wait_for_pmcd --if [ -d $PCP_LOG_DIR/pmlogger ] --then -- LOGGING_DIR=$PCP_LOG_DIR/pmlogger --else -- LOGGING_DIR=$PCP_LOG_DIR --fi --_wait_for_pmlogger -P $LOGGING_DIR/$LOCALHOST/pmlogger.log -+_wait_for_pmlogger - - # Reset pmlogger - echo "log sample.dynamic.meta.metric" -diff -Naurp pcp-5.3.5.orig/qa/882 pcp-5.3.5/qa/882 ---- pcp-5.3.5.orig/qa/882 2019-01-13 14:14:12.000000000 +1100 -+++ pcp-5.3.5/qa/882 2022-01-21 10:55:30.288602138 +1100 -@@ -17,6 +17,7 @@ signal=$PCP_BINADM_DIR/pmsignal - status=1 - done_clean=false - LOCALHOST=`hostname` -+LOGGING_DIR="$PCP_ARCHIVE_DIR" - - _cleanup() - { -@@ -69,13 +70,7 @@ $sudo cp $tmp.tmp $PCP_PMCDCONF_PATH - _writable_primary_logger - _service pcp restart 2>&1 | _filter_pcp_start - _wait_for_pmcd --if [ -d $PCP_LOG_DIR/pmlogger ] --then -- LOGGING_DIR=$PCP_LOG_DIR/pmlogger --else -- LOGGING_DIR=$PCP_LOG_DIR --fi --_wait_for_pmlogger -P $LOGGING_DIR/$LOCALHOST/pmlogger.log -+_wait_for_pmlogger - - # Reset pmlogger - echo "log sample.dynamic.meta.metric" -diff -Naurp pcp-5.3.5.orig/qa/932 pcp-5.3.5/qa/932 ---- pcp-5.3.5.orig/qa/932 2021-02-17 15:27:41.000000000 +1100 -+++ pcp-5.3.5/qa/932 2022-01-21 10:55:30.288602138 +1100 -@@ -17,6 +17,7 @@ signal=$PCP_BINADM_DIR/pmsignal - status=1 - done_clean=false - LOCALHOST=`hostname` -+LOGGING_DIR="$PCP_ARCHIVE_DIR" - - _cleanup() - { -@@ -67,13 +68,7 @@ $sudo cp $tmp.tmp $PCP_PMCDCONF_PATH - _writable_primary_logger - _service pcp restart 2>&1 | _filter_pcp_start - _wait_for_pmcd --if [ -d $PCP_LOG_DIR/pmlogger ] --then -- LOGGING_DIR=$PCP_LOG_DIR/pmlogger --else -- LOGGING_DIR=$PCP_LOG_DIR --fi --_wait_for_pmlogger -P $LOGGING_DIR/$LOCALHOST/pmlogger.log -+_wait_for_pmlogger - - # Reset pmlogger - echo "log sample.dynamic.meta.metric" -diff -Naurp pcp-5.3.5.orig/qa/common.check pcp-5.3.5/qa/common.check ---- pcp-5.3.5.orig/qa/common.check 2021-11-05 09:54:05.000000000 +1100 -+++ pcp-5.3.5/qa/common.check 2022-01-21 10:55:30.288602138 +1100 -@@ -262,7 +262,7 @@ _service() - # good reason for this) - # ditto for pmlogger_daily and pmlogger_daily-poll - # -- for svc in pmlogger_check pmlogger_daily pmlogger_daily-poll -+ for svc in pmlogger_check pmlogger_daily pmlogger_farm_check pmlogger_daily-poll - do - if systemctl show --property=ActiveState $svc.timer 2>&1 \ - | grep '=active$' >/dev/null -@@ -1940,9 +1940,11 @@ _remove_job_scheduler() - $rc_sudo rm -f $rc_cron_backup $rc_systemd_state - - if systemctl cat pmie_daily.timer >/dev/null 2>&1; then -- for i in pmie.service pmie_daily.timer pmie_check.timer pmlogger_daily.timer \ -+ for i in pmie.service pmie_daily.timer \ -+ pmie_check.timer pmie_farm_check.timer \ - pmlogger_daily_report.timer pmlogger_daily_report-poll.timer \ -- pmlogger_daily-poll.timer pmlogger_check.timer ; do -+ pmlogger_daily-poll.timer pmlogger_daily.timer \ -+ pmlogger_check.timer pmlogger_farm_check.timer ; do - $rc_sudo systemctl is-active "$i" > /dev/null || continue - $rc_sudo systemctl stop $i >/dev/null - echo "$i" >> $rc_systemd_state -diff -Naurp pcp-5.3.5.orig/src/pmie/GNUmakefile pcp-5.3.5/src/pmie/GNUmakefile ---- pcp-5.3.5.orig/src/pmie/GNUmakefile 2021-11-09 10:50:58.000000000 +1100 -+++ pcp-5.3.5/src/pmie/GNUmakefile 2022-01-21 10:55:54.918186303 +1100 -@@ -1,5 +1,5 @@ - # --# Copyright (c) 2013-2015,2020-2021 Red Hat. -+# Copyright (c) 2013-2015,2020-2022 Red Hat. - # Copyright (c) 2000,2004 Silicon Graphics, Inc. All Rights Reserved. - # - # This program is free software; you can redistribute it and/or modify it -@@ -84,7 +84,6 @@ pmie.service : pmie.service.in - - pmie_farm.service : pmie_farm.service.in - $(SED) <$< >$@ \ -- -e 's;@CRONTAB_PATH@;'$(CRONTAB_PATH)';' \ - -e 's;@PCP_SYSCONFIG_DIR@;'$(PCP_SYSCONFIG_DIR)';' \ - -e 's;@PCP_BINADM_DIR@;'$(PCP_BINADM_DIR)';' \ - -e 's;@PCP_VAR_DIR@;'$(PCP_VAR_DIR)';' \ -@@ -95,7 +94,10 @@ pmie_farm.service : pmie_farm.service.in - - pmie_farm_check.service : pmie_farm_check.service.in - $(SED) <$< >$@ \ -+ -e 's;@CRONTAB_PATH@;'$(CRONTAB_PATH)';' \ - -e 's;@PCP_BIN_DIR@;'$(PCP_BIN_DIR)';' \ -+ -e 's;@PCP_VAR_DIR@;'$(PCP_VAR_DIR)';' \ -+ -e 's;@SD_SERVICE_TYPE@;'$(SD_SERVICE_TYPE)';' \ - # END - - pmie_check.service : pmie_check.service.in -diff -Naurp pcp-5.3.5.orig/src/pmie/pmie_check.service.in pcp-5.3.5/src/pmie/pmie_check.service.in ---- pcp-5.3.5.orig/src/pmie/pmie_check.service.in 2021-11-04 08:26:15.000000000 +1100 -+++ pcp-5.3.5/src/pmie/pmie_check.service.in 2022-01-21 10:55:30.288602138 +1100 -@@ -2,7 +2,6 @@ - Description=Check PMIE instances are running - Documentation=man:pmie_check(1) - ConditionPathExists=!@CRONTAB_PATH@ --PartOf=pmie.service - - [Service] - Type=@SD_SERVICE_TYPE@ -@@ -15,6 +14,3 @@ ExecStart=@PCP_BINADM_DIR@/pmie_check $P - WorkingDirectory=@PCP_VAR_DIR@ - Group=@PCP_GROUP@ - User=@PCP_USER@ -- --[Install] --RequiredBy=pmie.service -diff -Naurp pcp-5.3.5.orig/src/pmie/pmie_check.timer pcp-5.3.5/src/pmie/pmie_check.timer ---- pcp-5.3.5.orig/src/pmie/pmie_check.timer 2021-02-17 15:27:41.000000000 +1100 -+++ pcp-5.3.5/src/pmie/pmie_check.timer 2022-01-21 10:55:30.288602138 +1100 -@@ -1,6 +1,5 @@ - [Unit] - Description=Half-hourly check of PMIE instances --PartOf=pmie.service - - [Timer] - # if enabled, runs 1m after boot and every half hour -diff -Naurp pcp-5.3.5.orig/src/pmie/pmie_daily.service.in pcp-5.3.5/src/pmie/pmie_daily.service.in ---- pcp-5.3.5.orig/src/pmie/pmie_daily.service.in 2021-10-07 14:28:56.000000000 +1100 -+++ pcp-5.3.5/src/pmie/pmie_daily.service.in 2022-01-21 10:55:30.288602138 +1100 -@@ -6,6 +6,7 @@ ConditionPathExists=!@CRONTAB_PATH@ - [Service] - Type=@SD_SERVICE_TYPE@ - Restart=no -+TimeoutStartSec=1h - Environment="PMIE_DAILY_PARAMS=-X xz -x 3" - EnvironmentFile=-@PCP_SYSCONFIG_DIR@/pmie_timers - ExecStart=@PCP_BINADM_DIR@/pmie_daily $PMIE_DAILY_PARAMS -diff -Naurp pcp-5.3.5.orig/src/pmie/pmie_daily.timer pcp-5.3.5/src/pmie/pmie_daily.timer ---- pcp-5.3.5.orig/src/pmie/pmie_daily.timer 2019-02-20 18:03:00.000000000 +1100 -+++ pcp-5.3.5/src/pmie/pmie_daily.timer 2022-01-21 10:55:30.288602138 +1100 -@@ -2,6 +2,7 @@ - Description=Daily processing of PMIE logs - - [Timer] -+Persistent=true - OnCalendar=*-*-* 00:08:00 - - [Install] -diff -Naurp pcp-5.3.5.orig/src/pmie/pmie_farm_check.service.in pcp-5.3.5/src/pmie/pmie_farm_check.service.in ---- pcp-5.3.5.orig/src/pmie/pmie_farm_check.service.in 2021-11-09 10:50:58.000000000 +1100 -+++ pcp-5.3.5/src/pmie/pmie_farm_check.service.in 2022-01-21 10:55:54.918186303 +1100 -@@ -1,19 +1,15 @@ - [Unit] --Description=Check and migrate non-primary pmie instances to pmie_farm --Documentation=man:pmie_check(1) --# TODO non-systemd ConditionPathExists=!/etc/cron.d/pcp-pmie -+Description=Check and migrate non-primary pmie farm instances -+Documentation=man:pmiectl(1) -+ConditionPathExists=!@CRONTAB_PATH@ - - [Service] --Type=exec -+Type=@SD_SERVICE_TYPE@ - Restart=no - TimeoutStartSec=4h - TimeoutStopSec=120 - ExecStart=@PCP_BIN_DIR@/pmiectl -m check --WorkingDirectory=/var/lib/pcp -- -+WorkingDirectory=@PCP_VAR_DIR@ - # root so pmiectl can migrate pmie processes to the pmie_farm service - Group=root - User=root -- --[Install] --RequiredBy=pmie_farm.service -diff -Naurp pcp-5.3.5.orig/src/pmie/pmie_farm_check.timer pcp-5.3.5/src/pmie/pmie_farm_check.timer ---- pcp-5.3.5.orig/src/pmie/pmie_farm_check.timer 2021-11-04 08:26:15.000000000 +1100 -+++ pcp-5.3.5/src/pmie/pmie_farm_check.timer 2022-01-21 10:49:07.985980678 +1100 -@@ -1,10 +1,11 @@ - [Unit] --Description=5 minute check of pmie farm instances -+Description=Half-hourly check of pmie farm instances - - [Timer] --# if enabled, runs 1m after boot and every 5 mins -+# if enabled, runs 1m after boot and every half hour - OnBootSec=1min --OnCalendar=*:00/5 -+OnCalendar=*-*-* *:28:10 -+OnCalendar=*-*-* *:58:10 - - [Install] - WantedBy=timers.target -diff -Naurp pcp-5.3.5.orig/src/pmie/pmie_farm.service.in pcp-5.3.5/src/pmie/pmie_farm.service.in ---- pcp-5.3.5.orig/src/pmie/pmie_farm.service.in 2021-11-04 08:26:15.000000000 +1100 -+++ pcp-5.3.5/src/pmie/pmie_farm.service.in 2022-01-21 10:49:07.986980661 +1100 -@@ -1,9 +1,9 @@ - [Unit] - Description=pmie farm service --Documentation=man:pmie(1) --After=network-online.target pmcd.service --Before=pmie_check.timer pmie_daily.timer --BindsTo=pmie_farm_check.timer pmie_check.timer pmie_daily.timer -+Documentation=man:pmie_check(1) -+Before=pmie_farm_check.timer -+BindsTo=pmie_farm_check.timer -+PartOf=pmie.service - - [Service] - Type=@SD_SERVICE_TYPE@ -@@ -15,13 +15,9 @@ TimeoutStopSec=120 - Environment="PMIE_CHECK_PARAMS=--skip-primary" - EnvironmentFile=-@PCP_SYSCONFIG_DIR@/pmie_timers - ExecStart=@PCP_BINADM_DIR@/pmie_farm $PMIE_CHECK_PARAMS -- - WorkingDirectory=@PCP_VAR_DIR@ - Group=@PCP_GROUP@ - User=@PCP_USER@ - - [Install] --WantedBy=multi-user.target -- --# This dependency will be removed in PCPv6. --WantedBy=pmie.service -+RequiredBy=pmie.service -diff -Naurp pcp-5.3.5.orig/src/pmie/pmie_farm.sh pcp-5.3.5/src/pmie/pmie_farm.sh ---- pcp-5.3.5.orig/src/pmie/pmie_farm.sh 2021-11-05 17:02:47.000000000 +1100 -+++ pcp-5.3.5/src/pmie/pmie_farm.sh 2022-01-21 10:49:07.986980661 +1100 -@@ -12,8 +12,8 @@ - # or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - # for more details. - # --# Administrative script to start the pmlogger_farm service. --# All arguments to pmlogger_check are passed from pmlogger_farm.service. -+# Administrative script to start the pmie_farm service. -+# All arguments to pmie_check are passed from pmie_farm.service. - # - . $PCP_DIR/etc/pcp.env - -diff -Naurp pcp-5.3.5.orig/src/pmie/pmie.service.in pcp-5.3.5/src/pmie/pmie.service.in ---- pcp-5.3.5.orig/src/pmie/pmie.service.in 2021-02-22 11:32:05.000000000 +1100 -+++ pcp-5.3.5/src/pmie/pmie.service.in 2022-01-21 10:49:07.986980661 +1100 -@@ -2,8 +2,8 @@ - Description=Performance Metrics Inference Engine - Documentation=man:pmie(1) - After=network-online.target pmcd.service --Before=pmie_check.timer pmie_daily.timer --BindsTo=pmie_check.timer pmie_daily.timer -+Before=pmie_farm.service pmie_check.timer pmie_daily.timer -+BindsTo=pmie_farm.service pmie_check.timer pmie_daily.timer - Wants=pmcd.service - - [Service] -diff -Naurp pcp-5.3.5.orig/src/pmlogger/GNUmakefile pcp-5.3.5/src/pmlogger/GNUmakefile ---- pcp-5.3.5.orig/src/pmlogger/GNUmakefile 2021-11-09 09:08:40.000000000 +1100 -+++ pcp-5.3.5/src/pmlogger/GNUmakefile 2022-01-21 10:55:54.918186303 +1100 -@@ -1,5 +1,5 @@ - # --# Copyright (c) 2013-2021 Red Hat. -+# Copyright (c) 2013-2022 Red Hat. - # Copyright (c) 2000,2004 Silicon Graphics, Inc. All Rights Reserved. - # - # This program is free software; you can redistribute it and/or modify it -@@ -99,7 +99,6 @@ pmlogger.service : pmlogger.service.in - - pmlogger_farm.service : pmlogger_farm.service.in - $(SED) <$< >$@ \ -- -e 's;@CRONTAB_PATH@;'$(CRONTAB_PATH)';' \ - -e 's;@PCP_SYSCONFIG_DIR@;'$(PCP_SYSCONFIG_DIR)';' \ - -e 's;@PCP_BINADM_DIR@;'$(PCP_BINADM_DIR)';' \ - -e 's;@PCP_VAR_DIR@;'$(PCP_VAR_DIR)';' \ -@@ -110,7 +109,10 @@ pmlogger_farm.service : pmlogger_farm.se - - pmlogger_farm_check.service : pmlogger_farm_check.service.in - $(SED) <$< >$@ \ -+ -e 's;@CRONTAB_PATH@;'$(CRONTAB_PATH)';' \ - -e 's;@PCP_BIN_DIR@;'$(PCP_BIN_DIR)';' \ -+ -e 's;@PCP_VAR_DIR@;'$(PCP_VAR_DIR)';' \ -+ -e 's;@SD_SERVICE_TYPE@;'$(SD_SERVICE_TYPE)';' \ - # END - - pmlogger_daily.service : pmlogger_daily.service.in -diff -Naurp pcp-5.3.5.orig/src/pmlogger/pmlogger_check.service.in pcp-5.3.5/src/pmlogger/pmlogger_check.service.in ---- pcp-5.3.5.orig/src/pmlogger/pmlogger_check.service.in 2021-11-04 08:26:15.000000000 +1100 -+++ pcp-5.3.5/src/pmlogger/pmlogger_check.service.in 2022-01-21 10:55:30.289602121 +1100 -@@ -15,6 +15,3 @@ ExecStart=@PCP_BINADM_DIR@/pmlogger_chec - WorkingDirectory=@PCP_VAR_DIR@ - Group=@PCP_GROUP@ - User=@PCP_USER@ -- --[Install] --RequiredBy=pmlogger.service -diff -Naurp pcp-5.3.5.orig/src/pmlogger/pmlogger_daily_report.service.in pcp-5.3.5/src/pmlogger/pmlogger_daily_report.service.in ---- pcp-5.3.5.orig/src/pmlogger/pmlogger_daily_report.service.in 2021-10-07 14:28:56.000000000 +1100 -+++ pcp-5.3.5/src/pmlogger/pmlogger_daily_report.service.in 2022-01-21 10:55:30.289602121 +1100 -@@ -13,6 +13,3 @@ ExecStart=@PCP_BINADM_DIR@/pmlogger_dail - WorkingDirectory=@PCP_VAR_DIR@ - Group=@PCP_GROUP@ - User=@PCP_USER@ -- --[Install] --WantedBy=pmlogger.service -diff -Naurp pcp-5.3.5.orig/src/pmlogger/pmlogger_farm_check.service.in pcp-5.3.5/src/pmlogger/pmlogger_farm_check.service.in ---- pcp-5.3.5.orig/src/pmlogger/pmlogger_farm_check.service.in 2021-11-09 09:08:40.000000000 +1100 -+++ pcp-5.3.5/src/pmlogger/pmlogger_farm_check.service.in 2022-01-21 10:55:54.918186303 +1100 -@@ -1,19 +1,15 @@ - [Unit] --Description=Check and migrate non-primary pmlogger instances to pmlogger_farm --Documentation=man:pmlogger_check(1) --# TODO non-systemd ConditionPathExists=!/etc/cron.d/pcp-pmlogger -+Description=Check and migrate non-primary pmlogger farm instances -+Documentation=man:pmlogctl(1) -+ConditionPathExists=!@CRONTAB_PATH@ - - [Service] --Type=exec -+Type=@SD_SERVICE_TYPE@ - Restart=no - TimeoutStartSec=4h - TimeoutStopSec=120 - ExecStart=@PCP_BIN_DIR@/pmlogctl -m check --WorkingDirectory=/var/lib/pcp -- --# root so pmlogctl can migrate pmloggers to the pmlogger_farm service -+WorkingDirectory=@PCP_VAR_DIR@ -+# root so pmlogctl can migrate pmlogger processes to the pmlogger_farm service - Group=root - User=root -- --[Install] --RequiredBy=pmlogger_farm.service -diff -Naurp pcp-5.3.5.orig/src/pmlogger/pmlogger_farm_check.timer pcp-5.3.5/src/pmlogger/pmlogger_farm_check.timer ---- pcp-5.3.5.orig/src/pmlogger/pmlogger_farm_check.timer 2021-11-04 08:26:15.000000000 +1100 -+++ pcp-5.3.5/src/pmlogger/pmlogger_farm_check.timer 2022-01-21 10:49:07.986980661 +1100 -@@ -1,10 +1,11 @@ - [Unit] --Description=5 minute check of pmlogger farm instances -+Description=Half-hourly check of pmlogger farm instances - - [Timer] --# if enabled, runs 1m after boot and every 5 mins -+# if enabled, runs 1m after boot and every half hour - OnBootSec=1min --OnCalendar=*:00/5 -+OnCalendar=*-*-* *:25:10 -+OnCalendar=*-*-* *:55:10 - - [Install] - WantedBy=timers.target -diff -Naurp pcp-5.3.5.orig/src/pmlogger/pmlogger_farm.service.in pcp-5.3.5/src/pmlogger/pmlogger_farm.service.in ---- pcp-5.3.5.orig/src/pmlogger/pmlogger_farm.service.in 2021-11-04 08:26:15.000000000 +1100 -+++ pcp-5.3.5/src/pmlogger/pmlogger_farm.service.in 2022-01-21 10:55:30.289602121 +1100 -@@ -1,9 +1,9 @@ - [Unit] - Description=pmlogger farm service --Documentation=man:pmlogger(1) --After=network-online.target pmcd.service --Before=pmlogger_check.timer pmlogger_daily.timer --BindsTo=pmlogger_farm_check.timer pmlogger_check.timer pmlogger_daily.timer -+Documentation=man:pmlogger_check(1) -+Before=pmlogger_farm_check.timer -+BindsTo=pmlogger_farm_check.timer -+PartOf=pmlogger.service - - [Service] - Type=@SD_SERVICE_TYPE@ -@@ -12,16 +12,12 @@ Restart=always - TimeoutStartSec=4h - TimeoutStopSec=120 - # the pmlogger_farm service manages all pmloggers except the primary --Environment="PMLOGGER_CHECK_PARAMS=--skip-primary" -+Environment="PMLOGGER_CHECK_PARAMS=--skip-primary --quick" - EnvironmentFile=-@PCP_SYSCONFIG_DIR@/pmlogger_timers - ExecStart=@PCP_BINADM_DIR@/pmlogger_farm $PMLOGGER_CHECK_PARAMS -- - WorkingDirectory=@PCP_VAR_DIR@ - Group=@PCP_GROUP@ - User=@PCP_USER@ - - [Install] --WantedBy=multi-user.target -- --# This dependency will be removed in PCPv6. --WantedBy=pmlogger.service -+RequiredBy=pmlogger.service -diff -Naurp pcp-5.3.5.orig/src/pmlogger/pmlogger.service.in pcp-5.3.5/src/pmlogger/pmlogger.service.in ---- pcp-5.3.5.orig/src/pmlogger/pmlogger.service.in 2021-11-04 08:26:15.000000000 +1100 -+++ pcp-5.3.5/src/pmlogger/pmlogger.service.in 2022-01-21 10:49:07.986980661 +1100 -@@ -2,8 +2,8 @@ - Description=Performance Metrics Archive Logger - Documentation=man:pmlogger(1) - After=network-online.target pmcd.service --Before=pmlogger_check.timer pmlogger_daily.timer --BindsTo=pmlogger_check.timer pmlogger_daily.timer -+Before=pmlogger_farm.service pmlogger_check.timer pmlogger_daily.timer -+BindsTo=pmlogger_farm.service pmlogger_check.timer pmlogger_daily.timer - Wants=pmcd.service - - [Service] diff --git a/redhat-bugzilla-2029301.patch b/redhat-bugzilla-2029301.patch deleted file mode 100644 index 47b515d..0000000 --- a/redhat-bugzilla-2029301.patch +++ /dev/null @@ -1,38 +0,0 @@ -commit 9d9adc9d6c8eb24a6884da81c18b927ea706a68e -Author: Nathan Scott -Date: Tue Dec 7 11:18:11 2021 +1100 - - pmdanvidia: fix mishandling of zero-byte size passed to realloc - - Picked up during QA of recent nvidia changes - some hardware lacks - support for per-process metrics, or the hardware (GPU) has not yet - been accessed by a process using its resources, which had the side - effect that a zero-byte size argument was passed into realloc. In - turn, this passes back something that can be freed and an issue in - the logic meant this would happen on subsequent calls also. - - Resolves the QA failure and Red Hat BZ #2029301 - -diff --git a/src/pmdas/nvidia/nvidia.c b/src/pmdas/nvidia/nvidia.c -index f1c12f2275..dc5bb93a0d 100644 ---- a/src/pmdas/nvidia/nvidia.c -+++ b/src/pmdas/nvidia/nvidia.c -@@ -617,11 +617,16 @@ refresh(pcp_nvinfo_t *nvinfo, int need_processes) - /* update indoms, cull old entries that remain inactive */ - if (need_processes) { - pmdaIndom *proc_indomp = &indomtab[PROC_INDOM]; -- pmdaInstid *it_set = proc_indomp->it_set; -+ pmdaInstid *it_set = NULL; - size_t bytes = nproc * sizeof(pmdaInstid); - -- if ((it_set = (pmdaInstid *)realloc(it_set, bytes)) == NULL) -+ if (bytes > 0) { -+ it_set = (pmdaInstid *)realloc(proc_indomp->it_set, bytes); -+ if (it_set == NULL) -+ free(proc_indomp->it_set); -+ } else if (proc_indomp->it_set != NULL) { - free(proc_indomp->it_set); -+ } - - if ((proc_indomp->it_set = it_set) != NULL) { - for (i = j = 0; i < processes.hsize && j < nproc; i++) { diff --git a/redhat-bugzilla-2030121.patch b/redhat-bugzilla-2030121.patch deleted file mode 100644 index 9a24ef0..0000000 --- a/redhat-bugzilla-2030121.patch +++ /dev/null @@ -1,50 +0,0 @@ -commit df7b7bf64eb354114e6c519e3e03ffc446afa8ba -Author: Nathan Scott -Date: Fri Nov 26 09:17:23 2021 +1100 - - libpcp_pmda: add indom cache fast-paths for inst lookup beyond max - - We encountered a situation where indom cache loading consumed vast - CPU resources for an indom of size ~150k instances. Profiling was - used to identify the insert loop that ensures the inst linked list - within the cache hash tables is sorted - this loop is O(N*2) as we - potentially walk this list from the start on every insert during a - cache load. Because cache loading happens from a sorted file, the - worst-case scenario happened every time - each new instance insert - occurs beyond the current maximum. Fortunately we maintain a last - entry pointer, so the new fast path uses that first and falls back - to the original behaviour for an out-of-order insertion. - - A second opportunity for the same optimization was identified when - auditing the rest of cache.c - in the find_inst() routine for inst - identifier lookups beyond the current maximum observed instance. - - Resolves Red Hat BZ #2024648 - -diff --git a/src/libpcp_pmda/src/cache.c b/src/libpcp_pmda/src/cache.c -index 0e66506d74..196ffc1da9 100644 ---- a/src/libpcp_pmda/src/cache.c -+++ b/src/libpcp_pmda/src/cache.c -@@ -328,6 +328,9 @@ find_inst(hdr_t *h, int inst) - { - entry_t *e; - -+ if ((e = h->last) != NULL && e->inst < inst) -+ return NULL; -+ - for (e = h->first; e != NULL; e = e->next) { - if (e->inst == inst && e->state != PMDA_CACHE_EMPTY) - break; -@@ -621,7 +624,11 @@ insert_cache(hdr_t *h, const char *name, int inst, int *sts) - *sts = PM_ERR_INST; - return e; - } -- for (e = h->first; e != NULL; e = e->next) { -+ /* if this entry is beyond the (sorted) list end, avoid linear scan */ -+ if ((e = h->last) == NULL || e->inst > inst) -+ e = h->first; -+ /* linear search over linked list, starting at either first or last */ -+ for (; e != NULL; e = e->next) { - if (e->inst < inst) - last_e = e; - else if (e->inst > inst) diff --git a/redhat-bugzilla-2030140.patch b/redhat-bugzilla-2030140.patch deleted file mode 100644 index 3a9687f..0000000 --- a/redhat-bugzilla-2030140.patch +++ /dev/null @@ -1,742 +0,0 @@ -diff -Naurp pcp-5.3.5.orig/qa/1458 pcp-5.3.5/qa/1458 ---- pcp-5.3.5.orig/qa/1458 1970-01-01 10:00:00.000000000 +1000 -+++ pcp-5.3.5/qa/1458 2021-12-09 11:25:01.973327231 +1100 -@@ -0,0 +1,219 @@ -+#!/bin/sh -+# PCP QA Test No. 1458 -+# Exercise access pmproxy with secure.enabled = false -+# -+# The main purpose of this is to test that the component works correctly -+# when secure.enabled = false; we can expect the https URLs to fail. -+# -+# See https://github.com/performancecopilot/pcp/issues/1490 -+ -+# Copyright (c) 2019,2021 Red Hat -+# Modified by Netflix, Inc. -+# -+ -+seq=`basename $0` -+echo "QA output created by $seq" -+ -+# get standard environment, filters and checks -+. ./common.product -+. ./common.filter -+. ./common.check -+ -+_check_series # pmseries availability means libuv is in use -+_check_valgrind -+openssl help 2>/dev/null || _notrun "No openssl binary found" -+ -+if [ -f /etc/lsb-release ] -+then -+ . /etc/lsb-release -+ if [ "$DISTRIB_ID" = Ubuntu ] -+ then -+ # This test fails for Ubuntu 19.10 with a myriad of errors involving -+ # the use of uninitialized values. The code paths very but typically -+ # involve libuv -> libssl -> libcrypto -+ # -+ case "$DISTRIB_RELEASE" -+ in -+ 19.10) -+ _notrun "problems with libuv, libssl, libcrypto and valgrind on Ubuntu $DISTRIB_RELEASE" -+ ;; -+ esac -+ fi -+fi -+ -+_cleanup() -+{ -+ cd $here -+ if $need_restore -+ then -+ need_restore=false -+ _restore_config $PCP_SYSCONF_DIR/labels -+ _sighup_pmcd -+ fi -+ $sudo rm -rf $tmp $tmp.* -+} -+ -+status=1 # failure is the default! -+need_restore=false -+username=`id -u -n` -+$sudo rm -rf $tmp $tmp.* $seq.full -+trap "_cleanup; exit \$status" 0 1 2 3 15 -+ -+_check_empty() -+{ -+ tee -a $seq.full > $tmp.unfiltered -+ if [ -s $tmp.unfiltered ] -+ then -+ echo "Botch: got output from curl" -+ else -+ echo "Good!, empty output from curl" -+ fi -+} -+ -+_filter_json() -+{ -+ tee -a $seq.full > $tmp.unfiltered -+ if [ -s $tmp.unfiltered ] -+ then -+ pmjson < $tmp.unfiltered > $tmp.filtered -+ status=$? -+ if [ $status -eq 0 ]; then -+ cat $tmp.filtered | \ -+ sed \ -+ -e '/"machineid": .*/d' \ -+ -e 's,"series": .*,"series": "SERIES",g' \ -+ -e 's,"context": .*,"context": "CONTEXT",g' \ -+ -e 's,"hostname": .*,"hostname": "HOSTNAME",g' \ -+ -e 's,"domainname": .*,"domainname": "DOMAINNAME",g' \ -+ #end -+ else -+ echo "Invalid JSON: $status" -+ cat $tmp.unfiltered -+ rm -f $tmp.context -+ fi -+ else -+ echo "Botch: no output from curl" -+ fi -+} -+ -+_filter_port() -+{ -+ sed \ -+ -e '/ ipv6 /d' \ -+ -e "s/ $port / PORT /g" \ -+ #end -+} -+ -+# real QA test starts here -+_save_config $PCP_SYSCONF_DIR/labels -+need_restore=true -+ -+$sudo rm -rf $PCP_SYSCONF_DIR/labels/* -+_sighup_pmcd -+ -+openssl req \ -+ -new -newkey rsa:4096 -days 365 -nodes -x509 \ -+ -subj "/C=US/ST=Denial/L=Springfield/O=Dis/CN=www.pcpqa.com" \ -+ -keyout $tmp.key -out $tmp.cert >$seq.full 2>&1 -+# creates a self-signed (insecure) certificate, so for testing only -+ -+echo "[pmproxy]" >> $tmp.conf -+echo "pcp.enabled = true" >> $tmp.conf -+echo "http.enabled = true" >> $tmp.conf -+echo "redis.enabled = false" >> $tmp.conf -+echo "secure.enabled = false" >> $tmp.conf -+ -+port=`_find_free_port` -+mkdir -p $tmp.pmproxy/pmproxy -+export PCP_RUN_DIR=$tmp.pmproxy -+export PCP_TMP_DIR=$tmp.pmproxy -+ -+$_valgrind_clean_assert pmproxy -f -l- --timeseries \ -+ -c $tmp.conf -p $port -U $username \ -+ >$tmp.valout 2>$tmp.valerr & -+pid=$! -+ -+echo "valgrind pid: $pid" >>$seq.full -+echo "pmproxy port: $port" >>$seq.full -+ -+# valgrind takes awhile to fire up -+i=0 -+while [ $i -lt 40 ] -+do -+ $PCP_BINADM_DIR/telnet-probe -c localhost $port && break -+ sleep 1 -+ i=`expr $i + 1` -+done -+if $PCP_BINADM_DIR/telnet-probe -c localhost $port -+then -+ echo "Startup took $i secs" >>$seq.full -+else -+ echo "Arrgh: valgrind failed start pmproxy and get port $port ready after 30 secs" -+ exit -+fi -+ -+date >>$seq.full -+echo "=== checking serial http operation ===" | tee -a $seq.full -+for i in 1 2 3 4; do -+ curl -Gs "http://localhost:$port/pmapi/metric?name=sample.long.ten" 2>$tmp.err$i >$tmp.out$i -+done -+for i in 1 2 3 4; do -+echo === out$i === | tee -a $seq.full -+_filter_json < $tmp.out$i -+done -+ -+date >>$seq.full -+echo "=== checking parallel http operation ===" | tee -a $seq.full -+for i in 1 2 3 4; do -+ curl -Gs "http://localhost:$port/pmapi/metric?name=sample.long.ten" 2>$tmp.err$i >$tmp.out$i & 2>/dev/null eval pid$i=$! -+done -+wait $pid1 $pid2 $pid3 $pid4 -+for i in 1 2 3 4; do -+echo === out$i === | tee -a $seq.full -+_filter_json < $tmp.out$i -+done -+ -+date >>$seq.full -+echo "=== checking serial https/TLS operation ===" | tee -a $seq.full -+for i in 1 2 3 4; do -+ curl -k -Gs "https://localhost:$port/pmapi/metric?name=sample.long.ten" 2>$tmp.err$i >$tmp.out$i -+done -+for i in 1 2 3 4; do -+echo === out$i === | tee -a $seq.full -+_check_empty < $tmp.out$i -+done -+ -+date >>$seq.full -+echo "=== checking parallel https/TLS operation ===" | tee -a $seq.full -+for i in 1 2 3 4; do -+ curl -k -Gs "https://localhost:$port/pmapi/metric?name=sample.long.ten" 2>$tmp.err$i >$tmp.out$i & 2>/dev/null eval pid$i=$! -+done -+wait $pid1 $pid2 $pid3 $pid4 -+for i in 1 2 3 4; do -+echo === out$i === | tee -a $seq.full -+_check_empty < $tmp.out$i -+done -+ -+echo "=== check pmproxy is running ===" -+pminfo -v -h localhost@localhost:$port hinv.ncpu -+if [ $? -eq 0 ]; then -+ echo "pmproxy check passed" -+else -+ echo "pmproxy check failed" -+fi -+ -+# valgrind takes awhile to shutdown too -+pmsignal $pid >/dev/null 2>&1 -+pmsleep 3.5 -+echo "=== valgrind stdout ===" | tee -a $seq.full -+cat $tmp.valout | _filter_valgrind -+ -+echo "=== valgrind stderr ===" | tee -a $seq.full -+cat $tmp.valerr | _filter_pmproxy_log | _filter_port -+ -+# final kill if it's spinning -+$sudo kill -9 $pid >/dev/null 2>&1 -+ -+# success, all done -+status=0 -+exit -diff -Naurp pcp-5.3.5.orig/qa/1458.out pcp-5.3.5/qa/1458.out ---- pcp-5.3.5.orig/qa/1458.out 1970-01-01 10:00:00.000000000 +1000 -+++ pcp-5.3.5/qa/1458.out 2021-12-09 11:25:01.973327231 +1100 -@@ -0,0 +1,221 @@ -+QA output created by 1458 -+=== checking serial http operation === -+=== out1 === -+{ -+ "context": "CONTEXT" -+ "metrics": [ -+ { -+ "name": "sample.long.ten", -+ "series": "SERIES" -+ "pmid": "29.0.11", -+ "type": "32", -+ "sem": "instant", -+ "units": "none", -+ "labels": { -+ "agent": "sample", -+ "cluster": "zero", -+ "domainname": "DOMAINNAME" -+ "hostname": "HOSTNAME" -+ "role": "testing" -+ }, -+ "text-oneline": "10 as a 32-bit integer", -+ "text-help": "10 as a 32-bit integer" -+ } -+ ] -+} -+=== out2 === -+{ -+ "context": "CONTEXT" -+ "metrics": [ -+ { -+ "name": "sample.long.ten", -+ "series": "SERIES" -+ "pmid": "29.0.11", -+ "type": "32", -+ "sem": "instant", -+ "units": "none", -+ "labels": { -+ "agent": "sample", -+ "cluster": "zero", -+ "domainname": "DOMAINNAME" -+ "hostname": "HOSTNAME" -+ "role": "testing" -+ }, -+ "text-oneline": "10 as a 32-bit integer", -+ "text-help": "10 as a 32-bit integer" -+ } -+ ] -+} -+=== out3 === -+{ -+ "context": "CONTEXT" -+ "metrics": [ -+ { -+ "name": "sample.long.ten", -+ "series": "SERIES" -+ "pmid": "29.0.11", -+ "type": "32", -+ "sem": "instant", -+ "units": "none", -+ "labels": { -+ "agent": "sample", -+ "cluster": "zero", -+ "domainname": "DOMAINNAME" -+ "hostname": "HOSTNAME" -+ "role": "testing" -+ }, -+ "text-oneline": "10 as a 32-bit integer", -+ "text-help": "10 as a 32-bit integer" -+ } -+ ] -+} -+=== out4 === -+{ -+ "context": "CONTEXT" -+ "metrics": [ -+ { -+ "name": "sample.long.ten", -+ "series": "SERIES" -+ "pmid": "29.0.11", -+ "type": "32", -+ "sem": "instant", -+ "units": "none", -+ "labels": { -+ "agent": "sample", -+ "cluster": "zero", -+ "domainname": "DOMAINNAME" -+ "hostname": "HOSTNAME" -+ "role": "testing" -+ }, -+ "text-oneline": "10 as a 32-bit integer", -+ "text-help": "10 as a 32-bit integer" -+ } -+ ] -+} -+=== checking parallel http operation === -+=== out1 === -+{ -+ "context": "CONTEXT" -+ "metrics": [ -+ { -+ "name": "sample.long.ten", -+ "series": "SERIES" -+ "pmid": "29.0.11", -+ "type": "32", -+ "sem": "instant", -+ "units": "none", -+ "labels": { -+ "agent": "sample", -+ "cluster": "zero", -+ "domainname": "DOMAINNAME" -+ "hostname": "HOSTNAME" -+ "role": "testing" -+ }, -+ "text-oneline": "10 as a 32-bit integer", -+ "text-help": "10 as a 32-bit integer" -+ } -+ ] -+} -+=== out2 === -+{ -+ "context": "CONTEXT" -+ "metrics": [ -+ { -+ "name": "sample.long.ten", -+ "series": "SERIES" -+ "pmid": "29.0.11", -+ "type": "32", -+ "sem": "instant", -+ "units": "none", -+ "labels": { -+ "agent": "sample", -+ "cluster": "zero", -+ "domainname": "DOMAINNAME" -+ "hostname": "HOSTNAME" -+ "role": "testing" -+ }, -+ "text-oneline": "10 as a 32-bit integer", -+ "text-help": "10 as a 32-bit integer" -+ } -+ ] -+} -+=== out3 === -+{ -+ "context": "CONTEXT" -+ "metrics": [ -+ { -+ "name": "sample.long.ten", -+ "series": "SERIES" -+ "pmid": "29.0.11", -+ "type": "32", -+ "sem": "instant", -+ "units": "none", -+ "labels": { -+ "agent": "sample", -+ "cluster": "zero", -+ "domainname": "DOMAINNAME" -+ "hostname": "HOSTNAME" -+ "role": "testing" -+ }, -+ "text-oneline": "10 as a 32-bit integer", -+ "text-help": "10 as a 32-bit integer" -+ } -+ ] -+} -+=== out4 === -+{ -+ "context": "CONTEXT" -+ "metrics": [ -+ { -+ "name": "sample.long.ten", -+ "series": "SERIES" -+ "pmid": "29.0.11", -+ "type": "32", -+ "sem": "instant", -+ "units": "none", -+ "labels": { -+ "agent": "sample", -+ "cluster": "zero", -+ "domainname": "DOMAINNAME" -+ "hostname": "HOSTNAME" -+ "role": "testing" -+ }, -+ "text-oneline": "10 as a 32-bit integer", -+ "text-help": "10 as a 32-bit integer" -+ } -+ ] -+} -+=== checking serial https/TLS operation === -+=== out1 === -+Good!, empty output from curl -+=== out2 === -+Good!, empty output from curl -+=== out3 === -+Good!, empty output from curl -+=== out4 === -+Good!, empty output from curl -+=== checking parallel https/TLS operation === -+=== out1 === -+Good!, empty output from curl -+=== out2 === -+Good!, empty output from curl -+=== out3 === -+Good!, empty output from curl -+=== out4 === -+Good!, empty output from curl -+=== check pmproxy is running === -+pmproxy check passed -+=== valgrind stdout === -+=== valgrind stderr === -+Log for pmproxy on HOST started DATE -+ -+pmproxy: PID = PID -+pmproxy request port(s): -+ sts fd port family address -+ === ==== ===== ====== ======= -+ok FD unix UNIX_DOMAIN_SOCKET -+ok FD PORT inet INADDR_ANY -+[DATE] pmproxy(PID) Info: pmproxy caught SIGTERM -+[DATE] pmproxy(PID) Info: pmproxy Shutdown -+ -+Log finished DATE -diff -Naurp pcp-5.3.5.orig/src/pmproxy/src/pcp.c pcp-5.3.5/src/pmproxy/src/pcp.c ---- pcp-5.3.5.orig/src/pmproxy/src/pcp.c 2021-09-24 09:33:06.000000000 +1000 -+++ pcp-5.3.5/src/pmproxy/src/pcp.c 2021-12-09 11:22:09.829321418 +1100 -@@ -1,6 +1,6 @@ - /* -- * Copyright (c) 2018-2019 Red Hat. -- * -+ * Copyright (c) 2018-2019,2021 Red Hat. -+ * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU Lesser General Public License as published - * by the Free Software Foundation; either version 2.1 of the License, or -@@ -19,22 +19,13 @@ - #define PDU_MAXLENGTH (MAXHOSTNAMELEN + HEADER_LENGTH + sizeof("65536")-1) - - static void --client_free(struct client *client) --{ -- if (client->u.pcp.hostname) -- sdsfree(client->u.pcp.hostname); -- if (client->buffer) -- sdsfree(client->buffer); --} -- --static void - on_server_close(uv_handle_t *handle) - { - struct client *client = (struct client *)handle; - - if (pmDebugOptions.pdu) - fprintf(stderr, "client %p pmcd connection closed\n", client); -- client_free(client); -+ client_put(client); - } - - static void -@@ -92,12 +83,11 @@ on_server_read(uv_stream_t *stream, ssiz - void - on_pcp_client_close(struct client *client) - { -- if (client->u.pcp.connected) { -+ if (client->u.pcp.connected) - uv_close((uv_handle_t *)&client->u.pcp.socket, on_server_close); -- memset(&client->u.pcp, 0, sizeof(client->u.pcp)); -- } else { -- client_free(client); -- } -+ if (client->u.pcp.hostname) -+ sdsfree(client->u.pcp.hostname); -+ memset(&client->u.pcp, 0, sizeof(client->u.pcp)); - } - - static void -@@ -118,6 +108,8 @@ on_pcp_client_connect(uv_connect_t *conn - - /* socket connection to pmcd successfully established */ - client->u.pcp.state = PCP_PROXY_SETUP; -+ client->u.pcp.connected = 1; -+ client_get(client); - - /* if we have already received PDUs, send them on now */ - if ((buffer = client->buffer) != NULL) { -diff -Naurp pcp-5.3.5.orig/src/pmproxy/src/secure.c pcp-5.3.5/src/pmproxy/src/secure.c ---- pcp-5.3.5.orig/src/pmproxy/src/secure.c 2021-11-01 13:02:26.000000000 +1100 -+++ pcp-5.3.5/src/pmproxy/src/secure.c 2021-12-09 11:22:09.831321384 +1100 -@@ -1,5 +1,5 @@ - /* -- * Copyright (c) 2019 Red Hat. -+ * Copyright (c) 2019,2021 Red Hat. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU Lesser General Public License as published -@@ -16,7 +16,7 @@ - #include - #include - --/* called with proxy->mutex locked */ -+/* called with proxy->write_mutex locked */ - static void - remove_connection_from_queue(struct client *client) - { -@@ -44,9 +44,9 @@ on_secure_client_close(struct client *cl - if (pmDebugOptions.auth || pmDebugOptions.http) - fprintf(stderr, "%s: client %p\n", "on_secure_client_close", client); - -- uv_mutex_lock(&client->proxy->mutex); -+ uv_mutex_lock(&client->proxy->write_mutex); - remove_connection_from_queue(client); -- uv_mutex_unlock(&client->proxy->mutex); -+ uv_mutex_unlock(&client->proxy->write_mutex); - /* client->read and client->write freed by SSL_free */ - SSL_free(client->secure.ssl); - } -@@ -63,7 +63,7 @@ maybe_flush_ssl(struct proxy *proxy, str - client->secure.pending.writes_count > 0) - return; - -- uv_mutex_lock(&proxy->mutex); -+ uv_mutex_lock(&proxy->write_mutex); - if (proxy->pending_writes == NULL) { - proxy->pending_writes = client; - client->secure.pending.prev = client->secure.pending.next = NULL; -@@ -75,7 +75,7 @@ maybe_flush_ssl(struct proxy *proxy, str - client->secure.pending.prev = c; - } - client->secure.pending.queued = 1; -- uv_mutex_unlock(&proxy->mutex); -+ uv_mutex_unlock(&proxy->write_mutex); - } - - static void -@@ -161,7 +161,7 @@ flush_secure_module(struct proxy *proxy) - size_t i, used; - int sts; - -- uv_mutex_lock(&proxy->mutex); -+ uv_mutex_lock(&proxy->write_mutex); - head = &proxy->pending_writes; - while ((client = *head) != NULL) { - flush_ssl_buffer(client); -@@ -212,7 +212,7 @@ flush_secure_module(struct proxy *proxy) - sizeof(uv_buf_t) * client->secure.pending.writes_count); - } - } -- uv_mutex_unlock(&proxy->mutex); -+ uv_mutex_unlock(&proxy->write_mutex); - } - - void -@@ -221,7 +221,8 @@ secure_client_write(struct client *clien - struct proxy *proxy = client->proxy; - uv_buf_t *dup; - size_t count, bytes; -- int i, sts, defer = 0, maybe = 0; -+ unsigned int i; -+ int sts, defer = 0, maybe = 0; - - for (i = 0; i < request->nbuffers; i++) { - if (defer == 0) { -diff -Naurp pcp-5.3.5.orig/src/pmproxy/src/server.c pcp-5.3.5/src/pmproxy/src/server.c ---- pcp-5.3.5.orig/src/pmproxy/src/server.c 2021-11-01 13:02:26.000000000 +1100 -+++ pcp-5.3.5/src/pmproxy/src/server.c 2021-12-09 11:22:09.831321384 +1100 -@@ -1,5 +1,5 @@ - /* -- * Copyright (c) 2018-2019 Red Hat. -+ * Copyright (c) 2018-2019,2021 Red Hat. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU Lesser General Public License as published -@@ -125,7 +125,7 @@ server_init(int portcount, const char *l - pmGetProgname()); - return NULL; - } -- uv_mutex_init(&proxy->mutex); -+ uv_mutex_init(&proxy->write_mutex); - - count = portcount + (*localpath ? 1 : 0); - if (count) { -@@ -229,7 +229,6 @@ void - client_put(struct client *client) - { - unsigned int refcount; -- struct proxy *proxy = client->proxy; - - uv_mutex_lock(&client->mutex); - assert(client->refcount); -@@ -237,22 +236,16 @@ client_put(struct client *client) - uv_mutex_unlock(&client->mutex); - - if (refcount == 0) { -- /* remove client from the doubly-linked list */ -- uv_mutex_lock(&proxy->mutex); -- if (client->next != NULL) -- client->next->prev = client->prev; -- *client->prev = client->next; -- uv_mutex_unlock(&proxy->mutex); -- - if (client->protocol & STREAM_PCP) - on_pcp_client_close(client); - if (client->protocol & STREAM_HTTP) - on_http_client_close(client); - if (client->protocol & STREAM_REDIS) - on_redis_client_close(client); -- if (client->protocol & STREAM_SECURE) -+ if ((client->protocol & STREAM_SECURE) && client->stream.secure) - on_secure_client_close(client); -- -+ if (client->buffer) -+ sdsfree(client->buffer); - memset(client, 0, sizeof(*client)); - free(client); - } -@@ -284,7 +277,7 @@ on_client_write(uv_write_t *writer, int - "on_client_write", status, client); - - if (status == 0) { -- if (client->protocol & STREAM_SECURE) -+ if ((client->protocol & STREAM_SECURE) && client->stream.secure) - on_secure_client_write(client); - if (client->protocol & STREAM_PCP) - on_pcp_client_write(client); -@@ -434,10 +427,16 @@ on_client_read(uv_stream_t *stream, ssiz - if (nread > 0) { - if (client->protocol == STREAM_UNKNOWN) - client->protocol |= client_protocol(*buf->base); -- if (client->protocol & STREAM_SECURE) -+ -+#ifdef HAVE_OPENSSL -+ if ((client->protocol & STREAM_SECURE) && (proxy->ssl != NULL)) - on_secure_client_read(proxy, client, nread, buf); - else - on_protocol_read(stream, nread, buf); -+#else -+ on_protocol_read(stream, nread, buf); -+#endif -+ - } else if (nread < 0) { - if (pmDebugOptions.af) - fprintf(stderr, "%s: read error %ld " -@@ -494,14 +493,6 @@ on_client_connection(uv_stream_t *stream - handle->data = (void *)proxy; - client->proxy = proxy; - -- /* insert client into doubly-linked list at the head */ -- uv_mutex_lock(&proxy->mutex); -- if ((client->next = proxy->first) != NULL) -- proxy->first->prev = &client->next; -- proxy->first = client; -- client->prev = &proxy->first; -- uv_mutex_unlock(&proxy->mutex); -- - status = uv_read_start((uv_stream_t *)&client->stream.u.tcp, - on_buffer_alloc, on_client_read); - if (status != 0) { -@@ -719,7 +710,7 @@ shutdown_ports(void *arg) - struct proxy *proxy = (struct proxy *)arg; - struct server *server; - struct stream *stream; -- int i; -+ unsigned int i; - - for (i = 0; i < proxy->nservers; i++) { - server = &proxy->servers[i]; -@@ -756,7 +747,8 @@ dump_request_ports(FILE *output, void *a - struct proxy *proxy = (struct proxy *)arg; - struct stream *stream; - uv_os_fd_t uv_fd; -- int i, fd; -+ unsigned int i; -+ int fd; - - fprintf(output, "%s request port(s):\n" - " sts fd port family address\n" -diff -Naurp pcp-5.3.5.orig/src/pmproxy/src/server.h pcp-5.3.5/src/pmproxy/src/server.h ---- pcp-5.3.5.orig/src/pmproxy/src/server.h 2021-09-24 09:33:06.000000000 +1000 -+++ pcp-5.3.5/src/pmproxy/src/server.h 2021-12-09 11:22:09.830321401 +1100 -@@ -1,5 +1,5 @@ - /* -- * Copyright (c) 2018-2019 Red Hat. -+ * Copyright (c) 2018-2019,2021 Red Hat. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU Lesser General Public License as published -@@ -97,11 +97,11 @@ typedef struct http_client { - - typedef struct pcp_client { - pcp_proxy_state_t state; -- sds hostname; - unsigned int port : 16; - unsigned int certreq : 1; - unsigned int connected : 1; - unsigned int pad : 14; -+ sds hostname; - uv_connect_t pmcd; - uv_tcp_t socket; - } pcp_client_t; -@@ -136,8 +136,6 @@ typedef struct client { - pcp_client_t pcp; - } u; - struct proxy *proxy; -- struct client *next; -- struct client **prev; - sds buffer; - } client_t; - -@@ -161,7 +159,7 @@ typedef struct proxy { - struct dict *config; /* configuration dictionary */ - uv_loop_t *events; /* global, async event loop */ - uv_callback_t write_callbacks; -- uv_mutex_t mutex; /* protects client lists and pending writes */ -+ uv_mutex_t write_mutex; /* protects pending writes */ - } proxy_t; - - extern void proxylog(pmLogLevel, sds, void *); diff --git a/redhat-bugzilla-2059461-pmie-systemd-fixup.patch b/redhat-bugzilla-2059461-pmie-systemd-fixup.patch new file mode 100644 index 0000000..b3190a7 --- /dev/null +++ b/redhat-bugzilla-2059461-pmie-systemd-fixup.patch @@ -0,0 +1,11 @@ +diff -Naurp pcp-5.3.7.orig/src/pmie/GNUmakefile pcp-5.3.7/src/pmie/GNUmakefile +--- pcp-5.3.7.orig/src/pmie/GNUmakefile 2022-02-02 11:53:05.000000000 +1100 ++++ pcp-5.3.7/src/pmie/GNUmakefile 2022-05-03 11:45:12.108743480 +1000 +@@ -80,6 +80,7 @@ pmie.service : pmie.service.in + $(SED) <$< >$@ \ + -e 's;@PCP_RC_DIR@;'$(PCP_RC_DIR)';' \ + -e 's;@PCP_RUN_DIR@;'$(PCP_RUN_DIR)';' \ ++ -e 's;@PCP_SYSCONFIG_DIR@;'$(PCP_SYSCONFIG_DIR)';' \ + # END + + pmie_farm.service : pmie_farm.service.in diff --git a/redhat-bugzilla-2059463-pmdapostfix-harden.patch b/redhat-bugzilla-2059463-pmdapostfix-harden.patch new file mode 100644 index 0000000..73236d6 --- /dev/null +++ b/redhat-bugzilla-2059463-pmdapostfix-harden.patch @@ -0,0 +1,146 @@ +commit f54eddf494e474531e5af609bcc376037a918977 +Author: Nathan Scott +Date: Tue Apr 26 14:32:59 2022 +1000 + + pmdapostfix: harden against a not-yet-running postfix + + Ensure the postfix PMDA can start and service requests even + if postfix is not yet started. + +diff --git a/src/perl/PMDA/local.c b/src/perl/PMDA/local.c +index e223bde7a..33130bc5d 100644 +--- a/src/perl/PMDA/local.c ++++ b/src/perl/PMDA/local.c +@@ -1,5 +1,5 @@ + /* +- * Copyright (c) 2012-2017 Red Hat. ++ * Copyright (c) 2012-2017,2022 Red Hat. + * Copyright (c) 2008-2011 Aconex. All Rights Reserved. + * + * This program is free software; you can redistribute it and/or modify it +@@ -139,18 +139,15 @@ int + local_tail(char *file, scalar_t *callback, int cookie) + { + int fd = open(file, O_RDONLY | O_NDELAY); +- struct stat stats; ++ struct stat stats = {0}; + int me; + +- if (fd < 0) { +- pmNotifyErr(LOG_ERR, "open failed (%s): %s", file, osstrerror()); +- exit(1); +- } +- if (fstat(fd, &stats) < 0) { +- pmNotifyErr(LOG_ERR, "fstat failed (%s): %s", file, osstrerror()); +- exit(1); +- } +- lseek(fd, 0L, SEEK_END); ++ if (fd < 0) ++ pmNotifyErr(LOG_INFO, "open failed (%s): %s", file, osstrerror()); ++ else if (fstat(fd, &stats) < 0) ++ pmNotifyErr(LOG_INFO, "fstat failed (%s): %s", file, osstrerror()); ++ else ++ lseek(fd, 0L, SEEK_END); + me = local_file(FILE_TAIL, fd, callback, cookie); + files[me].me.tail.path = strdup(file); + files[me].me.tail.dev = stats.st_dev; +@@ -416,10 +413,11 @@ local_pmdaMain(pmdaInterface *self) + } + + for (i = 0; i < nfiles; i++) { +- fd = files[i].fd; + /* check for log rotation or host reconnection needed */ + if ((count % 10) == 0) /* but only once every 10 */ + local_connection(&files[i]); ++ if ((fd = files[i].fd) < 0) ++ continue; + if (files[i].type != FILE_TAIL && !(__pmFD_ISSET(fd, &readyfds))) + continue; + offset = 0; +@@ -431,21 +429,16 @@ multiread: + (oserror() == EAGAIN) || + (oserror() == EWOULDBLOCK))) + continue; +- if (files[i].type == FILE_SOCK) { +- close(files[i].fd); +- files[i].fd = -1; +- continue; +- } +- pmNotifyErr(LOG_ERR, "Data read error on %s: %s\n", +- local_filetype(files[i].type), osstrerror()); +- exit(1); ++ close(files[i].fd); ++ files[i].fd = -1; ++ continue; + } + if (bytes == 0) { + if (files[i].type == FILE_TAIL) + continue; +- pmNotifyErr(LOG_ERR, "No data to read - %s may be closed\n", +- local_filetype(files[i].type)); +- exit(1); ++ close(files[i].fd); ++ files[i].fd = -1; ++ continue; + } + /* + * good read ... data up to buffer + offset + bytes is all OK +diff --git a/src/pmdas/postfix/pmdapostfix.pl b/src/pmdas/postfix/pmdapostfix.pl +index ac46816bc..d6d3f4d3a 100644 +--- a/src/pmdas/postfix/pmdapostfix.pl ++++ b/src/pmdas/postfix/pmdapostfix.pl +@@ -1,5 +1,5 @@ + # +-# Copyright (c) 2012-2015 Red Hat. ++# Copyright (c) 2012-2015,2022 Red Hat. + # Copyright (c) 2009-2010 Josef 'Jeff' Sipek + # + # This program is free software; you can redistribute it and/or modify it +@@ -56,8 +56,6 @@ my @postfix_received_dom = ( + 1 => 'smtp', + ); + +-my $setup = defined($ENV{'PCP_PERL_PMNS'}) || defined($ENV{'PCP_PERL_DOMAIN'}); +- + sub postfix_do_refresh + { + QUEUE: +@@ -212,7 +210,7 @@ $logstats{"received"}{1} = 0; + + # Note: + # Environment variables. +-# $PMDA_POSTFIX_QSHAPE: alternative executable qshape scrpipt (for QA) ++# $PMDA_POSTFIX_QSHAPE: alternative executable qshape script (for QA) + # ... over-rides default and command line argument. + # ... over-rides default arguments -b 10 -t $refresh + # $PMDA_POSTFIX_REFRESH: alternative refresh rate (for QA) +@@ -228,7 +226,7 @@ if (defined($ENV{'PMDA_POSTFIX_QSHAPE'})) { + $qshape = $ENV{'PMDA_POSTFIX_QSHAPE'}; + $qshape_args = ''; + } +-if (!$setup) { $pmda->log("qshape cmd: $qshape $qshape_args "); } ++unless (pmda_install()) { $pmda->log("qshape cmd: $qshape $qshape_args "); } + + if (defined($ENV{'PMDA_POSTFIX_REFRESH'})) { $refresh = $ENV{'PMDA_POSTFIX_REFRESH'}; } + +@@ -238,12 +236,15 @@ foreach my $file ( @logfiles ) { + } + } + if (defined($ENV{'PMDA_POSTFIX_LOG'})) { $logfile = $ENV{'PMDA_POSTFIX_LOG'}; } +-unless(defined($logfile)) +-{ +- $pmda->log("Fatal: No Postfix log file found in: @logfiles"); +- die 'No Postfix log file found'; ++unless (pmda_install()) { ++ if (defined($logfile)) { ++ $pmda->log("logfile: $logfile"); ++ } else { ++ $pmda->log("Warning: assuming logfile: $logfiles[0] as no Postfix log found yet from: @logfiles"); ++ } + } +-if (!$setup) { $pmda->log("logfile: $logfile"); } ++# set a good default if none found, before continuing ++unless (defined($logfile)) { $logfile = $logfiles[0]; } + + $pmda->add_indom($postfix_queues_indom, \@postfix_queues_dom, '', ''); + $pmda->add_indom($postfix_sent_indom, \@postfix_sent_dom, '', ''); diff --git a/redhat-bugzilla-2081262-pmdaproc-cgroups-fix.patch b/redhat-bugzilla-2081262-pmdaproc-cgroups-fix.patch new file mode 100644 index 0000000..77256ef --- /dev/null +++ b/redhat-bugzilla-2081262-pmdaproc-cgroups-fix.patch @@ -0,0 +1,44 @@ +commit d874d2e486c8a64fa9945ed7aa0048cccbd46f77 +Author: Nathan Scott +Date: Wed May 4 17:11:19 2022 +1000 + + pmdaproc: fix cgroup cpu metrics refresh structures + + Jan Kurik encountered this issue when running the regression + testsuite (especially qa/359) on non-x86_64 architectures. + + Something must've changed in the toolchain recently on these + platforms since we've not seen this before, but this bug has + been in our code for some time. It works everywhere else by + good fortune, when there just happen to be NULLs after these + cgroups CPU parsing data structures. + + Resolves Red Hat BZ #2081262. + +diff --git a/src/pmdas/linux_proc/cgroups.c b/src/pmdas/linux_proc/cgroups.c +index 413a72343..26d59863a 100644 +--- a/src/pmdas/linux_proc/cgroups.c ++++ b/src/pmdas/linux_proc/cgroups.c +@@ -1,5 +1,5 @@ + /* +- * Copyright (c) 2012-2019 Red Hat. ++ * Copyright (c) 2012-2019,2022 Red Hat. + * Copyright (c) 2010 Aconex. All Rights Reserved. + * + * This program is free software; you can redistribute it and/or modify it +@@ -863,6 +863,7 @@ read_cpu_time(const char *file, cgroup_cputime_t *ccp) + { "usage_usec", &cputime.usage }, + { "user_usec", &cputime.user }, + { "system_usec", &cputime.system }, ++ { NULL, NULL } + }; + char buffer[4096], name[64]; + unsigned long long value; +@@ -903,6 +904,7 @@ read_cpu_stats(const char *file, cgroup_cpustat_t *ccp) + { "nr_periods", &cpustat.nr_periods }, + { "nr_throttled", &cpustat.nr_throttled }, + { "throttled_time", &cpustat.throttled_time }, ++ { NULL, NULL } + }; + char buffer[4096], name[64]; + unsigned long long value; diff --git a/sources b/sources index 71deb6c..3c69425 100644 --- a/sources +++ b/sources @@ -1 +1 @@ -SHA512 (pcp-5.3.5.src.tar.gz) = d5481e2667d881ebc6a70e842958350e400f0a34cf746a29a97e77150af78d50d6eec5108a4e6fb013025bbd1089828c7cc02cc18220925f0198ed02924dc693 +SHA512 (pcp-5.3.7.src.tar.gz) = 04f494a7f161dea414fca14433ffa883272a9b68fb32c2954632f6e9a94d9a292714264db6860e1c670743023b90831eb787e757a29e3affeb196aa6a8918086