diff --git a/pcp-xsos-fixes.patch b/pcp-xsos-fixes.patch new file mode 100644 index 0000000..cbe1038 --- /dev/null +++ b/pcp-xsos-fixes.patch @@ -0,0 +1,269 @@ +commit d2852e19e77e25d628399d51fcf199233547f8c4 +Author: Nathan Scott +Date: Wed Nov 13 17:17:28 2024 +1100 + + libpcp, pcp-xsos: finer grained string output control in pmPrintValue + + Implement a mechanism in pmPrintValue for producing single-line value + output, giving shell scripts a chance to operate sensibly with whacky + command lines. + + Resolves Red Hat bugs RHEL-67164 and RHEL-67148. + +diff --git a/man/man3/pmprintvalue.3 b/man/man3/pmprintvalue.3 +index 067b2aee2b..656c05849d 100644 +--- a/man/man3/pmprintvalue.3 ++++ b/man/man3/pmprintvalue.3 +@@ -80,6 +80,15 @@ and + pairs for each requested metric), based upon the + metrics type as returned from + .BR pmLookupDesc (3). ++.SH ENVIRONMENT ++Output of string metric values can be further controlled using ++.BR PCP_SQUASH_NEWLINES . ++When set in the environment of the calling process, and the ++.I type ++is set to PM_TYPE_STRING or PM_TYPE_AGGREGATE, then the output ++value is guaranteed to be free of embedded newline characters. ++If the given value contained such characters, they will have been ++replaced by a space before being printed. + .SH SEE ALSO + .BR PMAPI (3), + .BR pmAtomStr (3), +diff --git a/qa/1564 b/qa/1564 +index cbb976cfe4..714955223e 100755 +--- a/qa/1564 ++++ b/qa/1564 +@@ -117,5 +117,33 @@ pcp -a $archive xsos -x -n | _filter_net + echo === Archive pcp xsos -N + pcp -a $archive xsos -x -N | _filter_netstat + ++echo === Special case: eval command issues | tee -a $seq.full ++test -f /eperm && $sudo rm -f /eperm ++(./src/args \$\(touch /eperm\) )& ++argspid=$! ++$PCP_BINADM_DIR/pmsleep 0.25 # start args ++$sudo pcp xsos -x --ps >> $seq.full ++echo $? exit status ++test -f /eperm && echo file exists && $sudo rm -f /eperm ++$PCP_BINADM_DIR/pmsignal $argspid ++wait $argspid ++ ++echo === Special case: multiline ps issues | tee -a $seq.full ++(./src/args ' ++multi ++line ++args ++')& ++argspid=$! ++$PCP_BINADM_DIR/pmsleep 0.25 # start args ++pcp xsos -x --ps >> $seq.full ++echo $? exit status ++$PCP_BINADM_DIR/pmsignal $argspid ++wait $argspid ++ ++echo === Special case: command line errors | tee -a $seq.full ++pcp xsos unknown_arg >> $seq.full 2>&1 ++echo $? exit status ++ + # success, all done + exit +diff --git a/qa/1564.out b/qa/1564.out +index 57de00c30a..11321e342a 100644 +--- a/qa/1564.out ++++ b/qa/1564.out +@@ -111,3 +111,9 @@ NET STATS + Ip.InAddrErrors: XXX + Ip6.InAddrErrors: XXX + ++=== Special case: eval command issues ++0 exit status ++=== Special case: multiline ps issues ++0 exit status ++=== Special case: command line errors ++1 exit status +diff --git a/qa/src/.gitignore b/qa/src/.gitignore +index 7e9b0fe08a..3399d24a4e 100644 +--- a/qa/src/.gitignore ++++ b/qa/src/.gitignore +@@ -13,6 +13,7 @@ archend + archfetch + archinst + arch_maxfd ++args + atomstr + badUnitsStr_r + badloglabel +diff --git a/qa/src/GNUlocaldefs b/qa/src/GNUlocaldefs +index ae647278f2..ac0920d136 100644 +--- a/qa/src/GNUlocaldefs ++++ b/qa/src/GNUlocaldefs +@@ -48,7 +48,7 @@ CFILES = disk_test.c exercise.c context_test.c chkoptfetch.c \ + archctl_segfault.c debug.c int2pmid.c int2indom.c exectest.c \ + unpickargs.c hanoi.c progname.c countmark.c check_attribute.c \ + indom2int.c pmid2int.c scanmeta.c traverse_return_codes.c \ +- timeshift.c checkstructs.c bcc_profile.c sha1int2ext.c \ ++ timeshift.c checkstructs.c bcc_profile.c args.c sha1int2ext.c \ + getdomainname.c profilecrash.c store_and_fetch.c test_service_notify.c \ + ctx_derive.c pmstrn.c pmfstring.c pmfg-derived.c mmv_help.c sizeof.c \ + stampconv.c time_stamp.c archend.c scandata.c wait_for_values.c \ +diff --git a/qa/src/args.c b/qa/src/args.c +new file mode 100644 +index 0000000000..06d9b9b6cc +--- /dev/null ++++ b/qa/src/args.c +@@ -0,0 +1,18 @@ ++/* ++ * Copyright (c) 2024 Red Hat. ++ * ++ * QA helper that waits for stdin input then exits, useful for ++ * shell escape testing as it allows arbitrary args (ignored). ++ */ ++ ++#include ++#include ++#include ++ ++int ++main(int argc, char **argv) ++{ ++ while (1) ++ sleep(1); ++ exit(EXIT_SUCCESS); ++} +diff --git a/src/libpcp/src/check-statics b/src/libpcp/src/check-statics +index 29dcb868ad..b9f21edc32 100755 +--- a/src/libpcp/src/check-statics ++++ b/src/libpcp/src/check-statics +@@ -581,6 +581,8 @@ util.o + msgbuf # guarded by util_lock mutex + msgbuflen # guarded by util_lock mutex + msgsize # guarded by util_lock mutex ++ squashed # guarded by __pmLock_extcall mutex when set ++ # in a one-trip initialization + filename # guarded by __pmLock_extcall mutex when set + # in a one-trip initialization + ?base # no unsafe side-effects, see notes in util.c +diff --git a/src/libpcp/src/util.c b/src/libpcp/src/util.c +index d4f79ca40d..84a7df6329 100644 +--- a/src/libpcp/src/util.c ++++ b/src/libpcp/src/util.c +@@ -984,6 +984,18 @@ print_event_summary(FILE *f, const pmValue *val, int highres) + fputc(']', f); + } + ++static void ++squash_string(char *s, unsigned int len) ++{ ++ unsigned int i; ++ ++ /* replace end-of-line characters */ ++ for (i = 0; i < len; i++) { ++ if (isspace(s[i])) ++ s[i] = ' '; ++ } ++} ++ + /* Print single pmValue. */ + void + pmPrintValue(FILE *f, /* output stream */ +@@ -997,6 +1009,16 @@ pmPrintValue(FILE *f, /* output stream */ + int n; + char *p; + int sts; ++ static int squashed = -1; ++ ++ if (squashed == -1) { ++ /* one-trip initialization */ ++ PM_LOCK(__pmLock_extcall); ++ squashed = 0; ++ if (getenv("PCP_SQUASH_NEWLINES") != NULL) /* THREADSAFE */ ++ squashed = 1; ++ PM_UNLOCK(__pmLock_extcall); ++ } + + if (type != PM_TYPE_UNKNOWN && + type != PM_TYPE_EVENT && +@@ -1032,7 +1054,10 @@ pmPrintValue(FILE *f, /* output stream */ + break; + + case PM_TYPE_STRING: +- n = (int)strlen(a.cp) + 2; ++ n = (int)strlen(a.cp); ++ if (squashed) ++ squash_string(a.cp, n); ++ n += 2; + while (n < minwidth) { + fputc(' ', f); + n++; +@@ -1123,6 +1148,8 @@ pmPrintValue(FILE *f, /* output stream */ + n++; + } + n = (int)val->value.pval->vlen - PM_VAL_HDR_SIZE; ++ if (squashed) ++ squash_string(val->value.pval->vbuf, n); + fprintf(f, "\"%*.*s\"", n, n, val->value.pval->vbuf); + done = 1; + } + +commit a55c5de05836ca0e71b052a4579b34f8e6577c23 +Merge: 3bcaee943a b147af9c8e +Author: Nathan Scott +Date: Wed Nov 13 16:49:57 2024 +1100 + + Merge commit 'b147af9c8e71423be9bb62699534d3fea4d86b8a' into xsos + + +commit b147af9c8e71423be9bb62699534d3fea4d86b8a +Author: Nathan Scott +Date: Wed Nov 13 16:49:57 2024 +1100 + + Squashed 'vendor/github.com/performancecopilot/xsos-pcp/' changes from deb8740f2f..de2b314859 + + de2b314859 pcp-xsos: fine-tune error handling on bad command line options + 35f2cefa3a pcp-xsos: single-line pmPrintValue/pminfo values, escape shell chars + + git-subtree-dir: vendor/github.com/performancecopilot/xsos-pcp + git-subtree-split: de2b314859d01dec9387e06da39af6920018d219 + +diff --git a/pcp-xsos b/pcp-xsos +index e8c60f1e0c..388712752d 100755 +--- a/vendor/github.com/performancecopilot/xsos-pcp/pcp-xsos ++++ b/vendor/github.com/performancecopilot/xsos-pcp/pcp-xsos +@@ -112,7 +112,6 @@ _usage() + { + [ ! -z "$@" ] && echo $@ 1>&2 + pmgetopt --progname=$progname --usage --config=$tmp/usage +- sts=0 + exit + } + +@@ -206,9 +205,11 @@ do + color=false + ;; + -\?) ++ sts=0 + _usage "" + ;; + --) # end of options, start of arguments ++ sts=1 + _usage "Unknown argument: $2" + ;; + esac +@@ -304,6 +305,7 @@ fi + # kernel_all_load_value[15]=0.06 + # kernel_cpu_util_user_error="No value(s) available!" + ++export PCP_SQUASH_NEWLINES=1 + if ! pminfo $batch --fetch ${metrics[*]} > $tmp/metrics 2>$tmp/error + then + if grep "^pminfo:" $tmp/error > /dev/null 2>&1 +@@ -320,6 +322,8 @@ gawk < $tmp/metrics > $tmp/variables ' + function filter(string) { + gsub(/"/, "\\\"", string) # escape double quotes + gsub(/\\u/, "\\\\u", string) # escape backslash-u ++ # replace any characters with special shell meaning ++ gsub("/\\(|\\$|\\*|)|\\{|\\}\\?|`|;|!/", "-", string) + gsub(/%/, "%%", string) # percent sign in printf + gsub(/^\\"|\\"$/, "\"", string) # except on ends + return string diff --git a/pcp.spec b/pcp.spec index 15a2d6f..929f315 100644 --- a/pcp.spec +++ b/pcp.spec @@ -1,12 +1,13 @@ Name: pcp Version: 6.3.2 -Release: 1%{?dist} +Release: 2%{?dist} Summary: System-level performance monitoring and performance management License: GPL-2.0-or-later AND LGPL-2.1-or-later AND CC-BY-3.0 URL: https://pcp.io Source0: https://github.com/performancecopilot/pcp/releases/pcp-%{version}.src.tar.gz +Patch0: pcp-xsos-fixes.patch # Keep xx-default-archive-version.patch for the life of RHEL9 Patch1: redhat-issues-RHEL-2317-default-archive-version.patch Patch2: redhat-issues-RHEL-58953-perl-drop-Y2038-checks.patch @@ -3602,6 +3603,9 @@ fi %files zeroconf -f pcp-zeroconf-files.rpm %changelog +* Thu Nov 14 2024 Nathan Scott - 6.3.2-2 +- Back-port upstream bug fixes for pcp-xsos(1). + * Wed Nov 06 2024 Nathan Scott - 6.3.2-1 - Add proc PMDA access control for IO metrics (RHEL-60891) - Fix pmdastatsd segfaults within pmdaRehash (RHEL-57717)