diff options
author | Igor Pashev <pashev.igor@gmail.com> | 2014-10-26 12:33:50 +0400 |
---|---|---|
committer | Igor Pashev <pashev.igor@gmail.com> | 2014-10-26 12:33:50 +0400 |
commit | 47e6e7c84f008a53061e661f31ae96629bc694ef (patch) | |
tree | 648a07f3b5b9d67ce19b0fd72e8caa1175c98f1a /src/include | |
download | pcp-debian.tar.gz |
Debian 3.9.10debian/3.9.10debian
Diffstat (limited to 'src/include')
-rw-r--r-- | src/include/GNUmakefile | 51 | ||||
-rw-r--r-- | src/include/builddefs.in | 706 | ||||
-rw-r--r-- | src/include/buildrules | 192 | ||||
-rw-r--r-- | src/include/pcp.conf.in | 206 | ||||
-rw-r--r-- | src/include/pcp.env | 95 | ||||
-rw-r--r-- | src/include/pcp.mingw | 75 | ||||
-rw-r--r-- | src/include/pcp/GNUmakefile | 42 | ||||
-rw-r--r-- | src/include/pcp/config.h.in | 685 | ||||
-rw-r--r-- | src/include/pcp/config32.h | 23 | ||||
-rw-r--r-- | src/include/pcp/config64.h | 23 | ||||
-rw-r--r-- | src/include/pcp/configsz.h.in | 24 | ||||
-rw-r--r-- | src/include/pcp/fault.h | 64 | ||||
-rw-r--r-- | src/include/pcp/impl.h | 1488 | ||||
-rw-r--r-- | src/include/pcp/import.h | 67 | ||||
-rwxr-xr-x | src/include/pcp/mk_pmdbg | 58 | ||||
-rw-r--r-- | src/include/pcp/mmv_dev.h | 84 | ||||
-rw-r--r-- | src/include/pcp/mmv_stats.h | 108 | ||||
-rw-r--r-- | src/include/pcp/platform_defs.h.in | 13 | ||||
-rw-r--r-- | src/include/pcp/pmafm.h | 47 | ||||
-rw-r--r-- | src/include/pcp/pmapi.h | 884 | ||||
-rw-r--r-- | src/include/pcp/pmda.h | 725 | ||||
-rw-r--r-- | src/include/pcp/pmtime.h | 107 | ||||
-rw-r--r-- | src/include/pcp/trace.h | 110 | ||||
-rw-r--r-- | src/include/pcp/trace_dev.h | 95 |
24 files changed, 5972 insertions, 0 deletions
diff --git a/src/include/GNUmakefile b/src/include/GNUmakefile new file mode 100644 index 0000000..a6c1ce8 --- /dev/null +++ b/src/include/GNUmakefile @@ -0,0 +1,51 @@ +# +# Copyright (c) 2000,2004 Silicon Graphics, Inc. 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 +# Free Software Foundation; either version 2 of the License, or (at your +# option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +# for more details. +# + +TOPDIR = ../.. +include $(TOPDIR)/src/include/builddefs +-include ./GNUlocaldefs + +CONFFILES = builddefs pcp.conf +LSRCFILES = builddefs.in buildrules pcp.conf.in pcp.env pcp.mingw + +LDIRT = builddefs.install + +SUBDIRS = pcp + +default :: default_pcp + +default_pcp : $(SUBDIRS) pcp.conf builddefs.install + $(SUBDIRS_MAKERULE) + +include $(BUILDRULES) + +install :: default_pcp install_pcp + +install_pcp : $(SUBDIRS) default_pcp + $(INSTALL) -m 644 pcp.conf $(PCP_ETC_DIR)/pcp.conf +ifeq "$(TARGET_OS)" "mingw" + $(INSTALL) -m 644 pcp.mingw $(PCP_ETC_DIR)/pcp.env +else + $(INSTALL) -m 644 pcp.env $(PCP_ETC_DIR)/pcp.env +endif + $(INSTALL) -m 644 buildrules $(PCP_INC_DIR)/buildrules + $(INSTALL) -m 644 builddefs.install $(PCP_INC_DIR)/builddefs + $(SUBDIRS_MAKERULE) + +builddefs.install : builddefs + sed -e 's;^include .*pcp.conf;include $$(PCP_DIR)/etc/pcp.conf;' \ + -e 's;^BUILDRULES.*=.*buildrules;BUILDRULES = $$\(PCP_INC_DIR\)/buildrules;' \ + -e 's;^INSTALL_SH.*=.*install-sh;INSTALL_SH = $$\(PCP_BINADM_DIR\)/install-sh;' \ + -e 's;^GENPMDA.*=.*genpmda;GENPMDA = $$\(PCP_BIN_DIR\)/genpmda;' \ + < builddefs > builddefs.install diff --git a/src/include/builddefs.in b/src/include/builddefs.in new file mode 100644 index 0000000..337b265 --- /dev/null +++ b/src/include/builddefs.in @@ -0,0 +1,706 @@ +# +# Copyright (c) 2012-2014 Red Hat. +# Copyright (c) 2008 Aconex. All Rights Reserved. +# Copyright (c) 2000,2003,2004 Silicon Graphics, Inc. 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 +# Free Software Foundation; either version 2 of the License, or (at your +# option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +# for more details. +# + +# Common gmake macros for building +# +# @configure_input@ +# +ifndef _BUILDDEFS_INCLUDED_ +_BUILDDEFS_INCLUDED_ = 1 + +ifndef _PCP_CONF_INCLUDED_ +_PCP_CONF_INCLUDED_ = 1 +include $(TOPDIR)/src/include/pcp.conf +endif + +# General package information +PACKAGE_VERSION ?= @PACKAGE_VERSION@ +PACKAGE_MAJOR ?= @PACKAGE_MAJOR@ +PACKAGE_MINOR ?= @PACKAGE_MINOR@ +PACKAGE_REVISION ?= @PACKAGE_REVISION@ +PACKAGE_BUILD ?= @PACKAGE_BUILD@ +PACKAGE_NAME ?= pcp +PACKAGE_CONFIGURE ?= @PACKAGE_CONFIGURE@ +PACKAGE_DISTRIBUTION ?= @PACKAGE_DISTRIBUTION@ +SGI_CHROOT_BUILD ?= 0 +SGI_ISSP_BUILD ?= 0 + +BUILDRULES = $(TOPDIR)/src/include/buildrules + +# LCFLAGS, LLDFLAGS, LLDLIBS, LDIRT may be specified in local makefiles. + +# turn on all warnings by default +ifeq "@cc_is_gcc@" "yes" +WARN_OFF = -Wall +else +WARN_OFF = +endif + +LIBPCP_ABIDIR ?= src +PCPLIB_LDFLAGS = -L$(TOPDIR)/src/libpcp/$(LIBPCP_ABIDIR) \ + -L$(TOPDIR)/src/libpcp_pmda/$(LIBPCP_ABIDIR) +# backward compatibility +PCP_LIBS = $(PCPLIB_LDFLAGS) + +# platform-specific CFLAGS, LDLIBS, and shared library extension +# +# Note: +# Need PCFLAGS setting here to match the CFLAGS settings in +# ../../configure.ac (likewise for PLDFLAGS and LDFLAGS). +# +TARGET_OS = @target_os@ +PCFLAGS = @PCFLAGS@ +PLDFLAGS = @PLDFLAGS@ +ifneq (, $(filter linux kfreebsd gnu, $(TARGET_OS))) +DSOSUFFIX = so +endif +ifeq "$(TARGET_OS)" "darwin" +DSOSUFFIX = dylib +CASE_INSENSITIVE_FS=1 +endif +ifeq "$(TARGET_OS)" "mingw" +DSOSUFFIX = dll +EXECSUFFIX = .exe +SHELLSUFFIX = .sh +PLDLIBS = -lwsock32 +endif +ifeq "$(TARGET_OS)" "solaris" +PLDFLAGS += -fPIC +PLDLIBS = -lnsl -lsocket -lresolv -ldl -lposix4 +DSOSUFFIX = so +endif +ifeq "$(TARGET_OS)" "aix" +DSOSUFFIX = so +# -qcpluscmt +# allow C++-style // as comment preamble +# -brtl +# use run-time linker +# -bnoipath +# do not use path to DSOs from the build, use default search path +# rules +# (and does not accept -Wall as a valid option) +PLDFLAGS += -brtl -bnoipath +WARN_OFF = +endif +ifeq "$(TARGET_OS)" "freebsd" +DSOSUFFIX = so +endif +ifeq "$(TARGET_OS)" "netbsd" +DSOSUFFIX = so +endif + +CFLAGS_ABI = @cflags_abi@ +CFLAGS_OPT = -O2 -g +CFLAGS += $(PCFLAGS) $(LCFLAGS) $(WARN_OFF) $(CFLAGS_OPT) \ + -DPCP_DEBUG -DPCP_VERSION=\"$(PCP_VERSION)\" \ + -I$(TOPDIR)/src/include -I$(TOPDIR)/src/include/pcp + +PIECFLAGS = @PIECFLAGS@ +PIELDFLAGS = @PIELDFLAGS@ +INVISIBILITY = @INVISIBILITY@ # hide shared library symbols + +NSSCFLAGS = @NSSCFLAGS@ +NSPRCFLAGS = @NSPRCFLAGS@ +SASLCFLAGS = @SASLCFLAGS@ +AVAHICFLAGS = @avahi_CFLAGS@ + +LDFLAGS += $(PLDFLAGS) $(WARN_OFF) $(PCP_LIBS) $(LLDFLAGS) + +SRCFILES = GNUmakefile $(HFILES) $(CFILES) $(CXXFILES) $(MFILES) \ + $(LSRCFILES) $(LFILES) $(YFILES) $(PYFILES) + +LDLIBS = $(LLDLIBS) $(PLDLIBS) +MAKEOPTS = --no-print-directory + +ifdef PROJECT +QTDIRDIRT = build debug release .obj .ui .moc .qrc *.xcodeproj *.app +QTDIRT = *.a *.o ui_* moc_* qrc_* Info.plist Makefile* object_script.* +endif +DEPDIRT = dep dep.bak +MANDIRT = *.[1-9].gz *.[1-9].bz2 *.[1-9].lzma *.[1-9].xz *.[1-9].tmp +LIBDIRT = $(LIBTARGET) $(STATICLIBTARGET) +CDIRT = $(OBJECTS) $(CMDTARGET) $(CXXMDTARGET) +DIRT = $(LDIRT) $(DEPDIRT) $(MANDIRT) $(QTDIRT) $(CDIRT) $(LIBDIRT) +DIRDIRT = $(LDIRDIRT) $(QTDIRDIRT) + +OBJECTS = $(ASFILES:.s=.o) \ + $(CFILES:.c=.o) \ + $(CXXFILES:.cxx=.o) \ + $(FFILES:.f=.o) \ + $(LFILES:.l=.o) \ + $(YFILES:%.y=%.tab.o) + +#NB: don't override $(MAKE); gnumake sets it well, propagating -j etc. +#MAKE = @make@ +CC = @cc@ +CXX = @cxx@ +LD = @ld@ +AWK = @awk@ +SED = @sed@ +CPP = @cpp@ +LEX = @lex@ +YACC = @yacc@ +ECHO = @echo@ +LN_S = @LN_S@ +GREP = @grep@ +GIT = @GIT@ +PYTHON = @PYTHON@ +DTRACE = @DTRACE@ +QMAKE = @qmake@ + +INSTALL_SH = $(TOPDIR)/install-sh +INSTALL = $(INSTALL_SH) -o $(PCP_USER_INSTALL) -g $(PCP_GROUP_INSTALL) + +CCF = $(CC) $(CFLAGS) +CXXF = $(CXX) $(CFLAGS) $(CXXFLAGS) +# NB: don't use $(MAKEF), since that suppresses gnumake's subdir parallelization +#MAKEF = $(MAKE) $(MAKEOPTS) +LDF = $(LD) $(LDFLAGS) +MAKEDEPEND = @makedepend@ + +ifeq "$(TARGET_OS)" "freebsd" +# gmake on FreeBSD has a strange default rule that passes insufficient +# flags to cc/ld for the link step. This change prevents errors like +# undefined reference to `__stack_chk_fail_local' +# +LDFLAGS += $(CFLAGS) +endif + +ZIP = @gzip@ +BZIP2 = @bzip2@ +LZMA = @lzma@ +XZ = @xz@ +TAR = @tar@ +RPMPROG = @rpmprog@ +PACKAGE_MAKER = @package_maker@ +HDIUTIL = @hdiutil@ +MKINSTALLP = @mkinstallp@ +DLLTOOL = @dlltool@ +RPMBUILD= @rpmbuild@ +RPM = @rpm@ +POD2MAN = @pod2man@ +DPKG = @dpkg@ +MAKEPKG = @makepkg@ +GENPMDA = $(TOPDIR)/src/genpmda/genpmda +PKGMK = @pkgmk@ +MD5SUM = @md5sum@ +XMLTO = @xmlto@ +DBLATEX = @dblatex@ +PUBLICAN = @publican@ +BOOK_TOOLCHAIN = @book_toolchain@ + +HAVE_GZIPPED_MANPAGES = @have_gzipped_manpages@ +HAVE_BZIP2ED_MANPAGES = @have_bzip2ed_manpages@ +HAVE_LZMAED_MANPAGES = @have_lzmaed_manpages@ +HAVE_XZED_MANPAGES = @have_xzed_manpages@ +PCP_MAN_DIR = @pcp_man_dir@ +PCP_BOOKS_DIR = @pcp_books_dir@ +PCP_ICONS_DIR = @pcp_icons_dir@ +PCP_DESKTOP_DIR = @pcp_desktop_dir@ + +NEED_OLD_TBL_HEADER = @need_old_tbl_header@ +RDYNAMIC_FLAG = @rdynamic_flag@ +QT_RELEASE = @qt_release@ + +ENABLE_SHARED = @enable_shared@ +ENABLE_SECURE = @enable_secure@ +ENABLE_PROBES = @enable_probes@ +ENABLE_AVAHI = @enable_avahi@ +ENABLE_QT = @enable_qt@ +ENABLE_SYSTEMD = @enable_systemd@ +ENABLE_PAPI = @enable_papi@ + +# additional libraries needed for particular functions +LIB_FOR_BASENAME = @lib_for_basename@ +LIB_FOR_DLOPEN = @lib_for_dlopen@ +LIB_FOR_REGEX = @lib_for_regex@ +LIB_FOR_MATH = @lib_for_math@ +LIB_FOR_READLINE = @lib_for_readline@ +LIB_FOR_CURSES = @lib_for_curses@ +LIB_FOR_PTHREADS = @lib_for_pthreads@ +LIB_FOR_RT = @lib_for_rt@ +LIB_FOR_NSS = @lib_for_nss@ +LIB_FOR_NSPR = @lib_for_nspr@ +LIB_FOR_SASL = @lib_for_sasl@ +LIB_FOR_SSL = @lib_for_ssl@ +LIB_FOR_AVAHI = @lib_for_avahi@ +LIB_FOR_ATOMIC = @lib_for_atomic@ + +HAVE_LIBMICROHTTPD = @HAVE_LIBMICROHTTPD@ +HAVE_RPMLIB = @HAVE_RPMLIB@ + +SHELL = /bin/sh +IMAGES_DIR = $(TOPDIR)/all-images +DIST_DIR = $(TOPDIR)/dist + +# env vars to be set before you can run a PCP binary in the build +# environment ... needed for tools like newhelp +# +# default, then special case for different platforms +# +RUN_IN_BUILD_ENV = PCP_CONF=$(TOPDIR)/src/include/pcp.conf LD_LIBRARY_PATH=$(TOPDIR)/src/libpcp/src:$(TOPDIR)/src/libpcp_pmda/src:$$LD_LIBRARY_PATH HOME=`pwd` PCP_ALT_CPP=$(TOPDIR)/src/pmcpp/pmcpp +ifeq "$(TARGET_OS)" "darwin" +RUN_IN_BUILD_ENV = PCP_CONF=$(TOPDIR)/src/include/pcp.conf DYLD_LIBRARY_PATH=$(TOPDIR)/src/libpcp/src:$(TOPDIR)/src/libpcp_pmda/src:$$DYLD_LIBRARY_PATH HOME=`pwd` PCP_ALT_CPP=$(TOPDIR)/src/pmcpp/pmcpp +endif +ifeq "$(TARGET_OS)" "aix" +RUN_IN_BUILD_ENV = PCP_CONF=$(TOPDIR)/src/include/pcp.conf LIBPATH=$(TOPDIR)/src/libpcp/src:$(TOPDIR)/src/libpcp_pmda/src:$$LIBPATH HOME=`pwd` PCP_ALT_CPP=$(TOPDIR)/src/pmcpp/pmcpp +endif +ifeq "$(TARGET_OS)" "mingw" +RUN_IN_BUILD_ENV = PCP_CONF=$(TOPDIR)/src/include/pcp.conf PATH=$(TOPDIR)/src/libpcp/src:$(TOPDIR)/src/libpcp_pmda/src:$$PATH USERPROFILE=`pwd` PCP_ALT_CPP=`pwd`/$(TOPDIR)/src/pmcpp/pmcpp +endif + +SUBDIRS_MAKERULE = \ + +for d in `echo $^ `; do \ + if test -d "$$d" -a -f "$$d/GNUmakefile"; then \ + $(ECHO) === $$d ===; \ + $(MAKE) $(MAKEOPTS) -C $$d $@ || exit $$?; \ + fi; \ + done + +# prepare symbols file for the GNU toolchain (linker) for DSO PMDAs +VERSION_SCRIPT_MAKERULE = \ + @rm -f $@; \ + echo "{" >$@; \ + echo " global: $(PMDAINIT);" >>$@; \ + echo " local: *;" >>$@; \ + echo "};" >>$@; \ + +# prepare domain.h used during the PMDA build process for each PMDA +DOMAIN_MAKERULE = \ + @rm -f $@; \ + echo "/*" >$@; \ + echo " * built from $<" >>$@; \ + echo " */" >>$@; \ + $(AWK) <$< '\ + $$1=="\#define" && $$2 == "$(DOMAIN)" {\ + print "\#define $(DOMAIN) " $$3 >>"$@"; found++ \ + }\ + END {\ + if (found == 0) { \ + print "Botch: no define for domain $(DOMAIN) in $<"; \ + system("rm '$@'"); \ + exit(1) \ + }\ + if (found > 1) { \ + print "Botch: multiple defines for domain $(DOMAIN) in $<";\ + print "... see $@ for details"; \ + system("rm '$@'"); \ + exit(1) \ + }\ + exit(0) \ + }' || ( rm -f $@ && false ) + +DOMAIN_PERLRULE = \ + @export perldomain=`sed -n \ + -e '/PCP::PMDA->new/s/[^0-9]*$$//' \ + -e '/PCP::PMDA->new/s/^[^0-9]*//p' pmda$(IAM).pl`; \ + $(AWK) <$< '\ + BEGIN {\ + domain = toupper("$(IAM)") \ + }\ + $$1=="\#define" && $$2 == domain { \ + pmd=$$3; found++ \ + }\ + END {\ + if (found == 0) {\ + print "Botch: no define for domain " domain " in $<"; \ + exit(1) \ + }\ + if (found > 1) {\ + print "Botch: multiple defines of domain " domain " in $<";\ + exit(1) \ + }\ + if (pmd != "'"$$perldomain"'") {\ + print "Botch: domain number in ../../pmns/stdpmid (" pmd ") does not match domain number in Perl source ("'"$$perldomain"'")"; \ + exit(1) \ + }\ + exit(0) \ + }' + +DOMAIN_PYTHONRULE = \ + @export pythondomain=`sed -n \ + -e '/PMDA(/s/[^0-9]*$$//' \ + -e '/PMDA(/s/^[^0-9]*//p' $(PYSCRIPT)`; \ + $(AWK) <$< '\ + BEGIN {\ + domain = toupper("$(IAM)") \ + }\ + $$1=="\#define" && $$2 == domain { \ + pmd=$$3; found++ \ + }\ + END {\ + if (found == 0) {\ + print "Botch: no define for domain " domain " in $<"; \ + exit(1) \ + }\ + if (found > 1) {\ + print "Botch: multiple defines of domain " domain " in $<";\ + exit(1) \ + }\ + if (pmd != "'"$$pythondomain"'") {\ + print "Botch: domain number in ../../pmns/stdpmid (" pmd ") does not match domain number in Python source ("'"$$pythondomain"'")"; \ + exit(1) \ + }\ + exit(0) \ + }' + +POD_OPTIONS = --section=$(MAN_SECTION) --release=$(PCP_VERSION) \ + --center="Performance Co-Pilot" --date="Performance Co-Pilot" +POD_MAKERULE = $(POD2MAN) $(POD_OPTIONS) $^ $@ + +ifeq "$(TARGET_OS)" "mingw" +INSTALL_MAN = +else +INSTALL_MAN = \ + test -z "$$MAN_PAGES" && MAN_PAGES="$(MAN_PAGES)"; \ + for d in `echo $$MAN_PAGES`; do \ + first=true; \ + base=`echo $$d | sed -e 's/\.[0-9]//g'`; \ + $(AWK) <$$d ' \ +BEGIN { state=0; print "'"$$base"'" } \ +$$1==".ds" { ds["\\\\\\*\\("$$2] = $$3 } \ +$$1==".SH" && $$2=="NAME" { state=1; next } \ +$$1==".SH" && state==1 { exit } \ +/^\./ { next } \ +state==1 { for (i=1;i<=NF;i++) { \ + if ($$i=="\\-" || $$i=="-") exit; \ + gsub ("\\\\f3", "", $$i); gsub ("\\\\f1.*", "", $$i); \ + for ( d in ds ) sub (d, ds[d], $$i); \ + print $$i \ + } \ + }' \ + | LC_COLLATE=POSIX $(PCP_SORT_PROG) -u \ + | while read m; do \ + [ -z "$$m" -o "$$m" = "\\" ] && continue; \ + t=$(MAN_DEST)/$$m.$(MAN_SECTION); \ + if $$first; then \ + _tfx= ;\ + if $(NEED_OLD_TBL_HEADER) ; then \ + $(SED) -e "1s/^'\\\\\"! tbl.*/'\\\\\" t/" $$d > $$d.tmp; _tfx=.tmp; \ + fi; \ + if $(HAVE_GZIPPED_MANPAGES) ; then \ + $(ZIP) -c $$d$$_tfx > $$d.gz; _tfx=.gz; _sfx=.gz; \ + fi; \ + if $(HAVE_BZIP2ED_MANPAGES) ; then \ + $(BZIP2) -c $$d$$_tfx > $$d.bz2; _tfx=.bz2; _sfx=.bz2; \ + fi; \ + if $(HAVE_LZMAED_MANPAGES) ; then \ + $(LZMA) -c $$d$$_tfx > $$d.lzma; _tfx=.lzma; _sfx=.lzma; \ + fi; \ + if $(HAVE_XZED_MANPAGES) ; then \ + $(XZ) -c $$d$$_tfx > $$d.xz; _tfx=.xz; _sfx=.xz; \ + fi; \ + u=$$m.$(MAN_SECTION)$$_sfx; \ + echo $(INSTALL) -m 644 $${d}$$_tfx $${t}$$_sfx; \ + $(INSTALL) -m 644 $${d}$$_tfx $${t}$$_sfx; \ + else \ + if test ! -z $(CASE_INSENSITIVE_FS) -a $(CASE_INSENSITIVE_FS); then \ + if test "`echo $$u | tr 'a-z' 'A-Z'`" != "`basename $${t}$$_sfx | tr 'a-z' 'A-Z'`"; then \ + echo $(INSTALL) -S $$u $${t}$$_sfx; \ + $(INSTALL) -S $$u $${t}$$_sfx; \ + fi \ + else \ + echo $(INSTALL) -S $$u $${t}$$_sfx; \ + $(INSTALL) -S $$u $${t}$$_sfx; \ + fi \ + fi; \ + first=false; \ + done; \ + done +endif + +PERL_INSTALL_BASE = @perl_install_base@ +PERL_INSTALLDIRS = @perl_installdirs@ + +# MakeMaker INSTALL_BASE needs to be unset for proper vendor_perl paths to be used for --prefix=/usr; +ifeq "$(PERL_INSTALL_BASE)" "/usr" +ifneq "$(TARGET_OS)" "darwin" +MAKEMAKER_EXTRA_OPTIONS= +else +MAKEMAKER_EXTRA_OPTIONS=INSTALL_BASE=$(PERL_INSTALL_BASE) INSTALLBASE=$(PERL_INSTALL_BASE) +endif +else +MAKEMAKER_EXTRA_OPTIONS=INSTALL_BASE=$(PERL_INSTALL_BASE) INSTALLBASE=$(PERL_INSTALL_BASE) +endif + +PERL_MAKE_MAKEFILE = \ + export PCP_TOPDIR=`cd $(TOPDIR) && pwd`; \ + NSS_CFLAGS="$(NSS_CFLAGS)" NSPR_CFLAGS="$(NSPR_CFLAGS)" \ + TARGET_OS="$(TARGET_OS)" CC="$(CC) $(CFLAGS_ABI)" perl Makefile.PL $(MAKEMAKER_EXTRA_OPTIONS) $(MAKEMAKER_OPTIONS) + +# Collect files from a Perl "make -f Makefile install" below +# src/perl to build the PCP Perl packaging list, and also clean up +# the installed files to remove unwanted files and make the DSO +# executable +# +# Usage is $(call PERL_GET_FILELIST,listfile,base) +# where listfile is something like $(TOPDIR)/perl-pcp-pmda.list and +# base is the DSO basename like PMDA. +# +# We need different versions for the different installation and +# packaging regimes. +# +ifeq "$(PACKAGE_DISTRIBUTION)" "debian" +# For Debian packaging, this is not needed +PERL_GET_FILELIST = +else +ifeq "$(PACKAGE_DISTRIBUTION)" "gentoo" +# Gentoo cannot rely on the .packlist files from the install, so create +# a temporary pack.list file +PERL_GET_FILELIST = \ + $(PERLMAKE) -f Makefile install DESTDIR=$$DIST_ROOT \ + | tee pack.list; \ + sed -n -e '/\.bs$$/d' -e 's/\.[0-9]pm$$/&.gz/' -e "s@^Installing $$DIST_ROOT@@p" <pack.list >$(1) || exit 1; \ + if [ -s $(1) ]; then rm -f pack.list; \ + else echo "Arrgh ... no files to include in package via $(1), see pack.list"; exit 1; \ + fi; \ + find $$DIST_ROOT/$(PERL_INSTALL_BASE) -name perllocal.pod -exec rm -f '{}' ';' ; \ + find $$DIST_ROOT/$(PERL_INSTALL_BASE) -name \*.bs -exec rm -f '{}' ';' ; \ + find $$DIST_ROOT/$(PERL_INSTALL_BASE) -name $(2).so -exec chmod 755 '{}' ';' +else +ifeq "$(PACKAGE_DISTRIBUTION)" "freebsd" +# FreeBSD Perl packaging is a broken mystery at this point in time +# 1. there is no .packlist files being created +# 2. $(PERLMAKE) -f Makefile install DESTDIR=$$DIST_ROOT does not work +# so disable the packaging pro tem +PERL_GET_FILELIST = +else +# Everyone else ... includes the RPM-based packaging platforms +ifeq "$(PACKAGE_DISTRIBUTION)" "mandriva" + man_suffix=lzma +else + man_suffix=gz +endif +PERL_GET_FILELIST = \ + $(PERLMAKE) -f Makefile install DESTDIR=$$DIST_ROOT; \ + find $$DIST_ROOT/$(PERL_INSTALL_BASE) -name .packlist -exec mv '{}' $(1) ';' ; \ + if [ -s $(1) ] ; then \ + _sfx=.gz; \ + $(HAVE_BZIP2ED_MANPAGES) && _sfx=.bz2; \ + $(HAVE_LZMAED_MANPAGES) && _sfx=.lzma; \ + $(HAVE_XZED_MANPAGES) && _sfx=.xz; \ + sed -n -e '/\.bs$$/d' -e 's/\.[0-9]pm$$/&'"$$_sfx/" -e "s@^$$DIST_ROOT@@p" $(1) >$(1).tmp; \ + mv $(1).tmp $1; \ + else echo "Arrgh ... no files to include in package via $(1)"; exit 1; \ + fi; \ + find $$DIST_ROOT/$(PERL_INSTALL_BASE) -name perllocal.pod -exec rm -f '{}' ';' ; \ + find $$DIST_ROOT/$(PERL_INSTALL_BASE) -name \*.bs -exec rm -f '{}' ';' ; \ + find $$DIST_ROOT/$(PERL_INSTALL_BASE) -name $(2).so -exec chmod 755 '{}' ';' +endif +endif +endif + +# Create perl manifest files explicitly for some distributions +ifeq "$(shell [ '$(PACKAGE_DISTRIBUTION)' = cocoa \ + -o '$(PACKAGE_DISTRIBUTION)' = macosx \ + -o '$(PACKAGE_DISTRIBUTION)' = gentoo \ + -o '$(PACKAGE_DISTRIBUTION)' = solaris \ + -o '$(PACKAGE_DISTRIBUTION)' = freebsd \ + ] && echo 1)" "1" +# Gather installed Perl files before packaging +PERL_INSTALL = \ + if [ -n "$(DIST_MANIFEST)" ]; then \ + if [ "`echo $(TOPDIR)/perl-pcp-*.list`" != "$(TOPDIR)/perl-pcp-*.list" ]; then \ + cat $(TOPDIR)/perl-pcp-*.list | while read f; do \ + bn=`basename $$f .gz`; \ + dn=`dirname $$f`; \ + $(INSTALL) -d $$dn || exit 1; \ + src=`find */blib -name $$bn`; \ + if [ -x $$src ] ; then mode=0755; else mode=0644; fi; \ + $(INSTALL) -m $$mode $$src $$dn/$$bn || exit 1; \ + done; \ + fi; \ + fi +else +PERL_INSTALL = +endif + +SYSTEMD_CFLAGS=@SYSTEMD_CFLAGS@ +SYSTEMD_LIBS=@SYSTEMD_LIBS@ +PMDA_SYSTEMD=@PMDA_SYSTEMD@ + +IB_LIBS=@IB_LIBS@ +PMDA_INFINIBAND=@PMDA_INFINIBAND@ + + +# +# Python platform-specific installation quirks +PYTHON_PREFIX=@python_prefix@ +SETUP_PY_BUILD_OPTIONS = --include-dirs=$(TOPDIR)/src/include +SETUP_PY_BUILD_OPTIONS += --library-dirs=$(TOPDIR)/src/libpcp/src:$(TOPDIR)/src/libpcp_pmda/src:$(TOPDIR)/src/libpcp_gui/src:$(TOPDIR)/src/libpcp_import/src:$(TOPDIR)/src/libpcp_mmv/src +SETUP_PY_INSTALL_OPTIONS = --skip-build +SETUP_PY_INSTALL_OPTIONS += --root=$${DIST_ROOT-/} +SETUP_PY_INSTALL_OPTIONS += --record=$(TOPDIR)/python-pcp.list +ifeq "$(PYTHON_PREFIX)" "/usr" +ifeq "$(PACKAGE_DISTRIBUTION)" "debian" +SETUP_PY_INSTALL_OPTIONS += --install-layout=deb +endif +else +SETUP_PY_INSTALL_OPTIONS += --prefix=$(PYTHON_PREFIX) +endif +# RPM byte-compiles and installs results in our DIST_ROOT, cater for this: +ifeq "$(shell [ '$(TARGET_OS)' = linux -a '$(PACKAGE_DISTRIBUTION)' != gentoo \ + ] && echo 1)" "1" +# Linux and not Gentoo (which needs tarball packaging) +PYTHON_INSTALL = \ + $(AWK) '{print} /.pyc$$/ {sub(/.pyc$$/,".pyo"); print}' \ + < $(TOPDIR)/python-pcp.list > $(TOPDIR)/python-pcp.list.rpm; \ + cat $(TOPDIR)/python-pcp.list.rpm | while read f; do \ + touch $${DIST_ROOT-/}$$f; \ + done +else +ifeq "$(shell [ '$(PACKAGE_DISTRIBUTION)' = cocoa \ + -o '$(PACKAGE_DISTRIBUTION)' = macosx \ + -o '$(PACKAGE_DISTRIBUTION)' = gentoo \ + -o '$(PACKAGE_DISTRIBUTION)' = solaris \ + -o '$(PACKAGE_DISTRIBUTION)' = freebsd \ + ] && echo 1)" "1" +# Gather installed Python files before packaging +# Lines in python-pcp.list are like this +# /usr/lib/python2.7/site-packages/pcp.py +# /usr/lib/python2.7/site-packages/pcp.pyc +# /usr/lib/python2.7/site-packages/pmapi.so +# /usr/lib/python2.7/site-packages/pcp-0.2-py2.7.egg-info +# +# Matching build artifacts are below src/python/build +# +PYTHON_INSTALL = \ + if [ -n "$(DIST_MANIFEST)" ]; then \ + cat $(TOPDIR)/python-pcp.list \ + | while read f; do \ + bn=`basename $$f`; \ + dn=`dirname $$f`; \ + $(INSTALL) -d $$dn || exit 1; \ + src=`find $(TOPDIR)/src/python/build -name $$bn`; \ + $(INSTALL) $$src $$f || exit 1; \ + done; \ + fi +else +PYTHON_INSTALL = +endif +endif + +# Qt magic for build/installs across all the supported platforms +ifeq ($(PCP_PLATFORM),darwin) +QTMAKE = $(QMAKE) -spec macx-g++ CONFIG+=$(QT_RELEASE) && make -f Makefile +MACBUILD = build/$(QT_RELEASE)/$(COMMAND).app/Contents +BINARY = $(MACBUILD)/MacOS/$(COMMAND) +LNMAKE = test ! -f $(BINARY) -o -L $(COMMAND) || $(LN_S) $(BINARY) $(COMMAND) +WINDOW = mac +endif +ifeq ($(PCP_PLATFORM),mingw) +QTMAKE = $(QMAKE) CONFIG+=$(QT_RELEASE) && $(MAKE) -f Makefile +BINARY = $(QT_RELEASE)/$(COMMAND) +LNMAKE = +WINDOW = win +endif +ifeq "$(findstring $(PCP_PLATFORM),darwin mingw)" "" +QTMAKE = $(QMAKE) CONFIG+=$(QT_RELEASE) && $(MAKE) $(MAKEOPTS) -f Makefile +BINARY = build/$(QT_RELEASE)/$(COMMAND) +LNMAKE = test ! -f $(BINARY) -o -L $(COMMAND) || $(LN_S) $(BINARY) $(COMMAND) +WINDOW = x11 +endif + +ifeq ($(PCP_PLATFORM),darwin) +INSTALL_DIRECTORY_HIERARCHY=\ + d=$(1); while [ "$$d" != "$(2)" -a "$$d" != "/" -a "$$d" != "." ] ; do \ + echo $$d; d=`dirname $$d`; done | sort | while read id; do \ + $(INSTALL) -m 755 -d $$id || exit 1; done + +INSTALL_QT_RESOURCES=\ + printf "[Paths]\nPlugins=/Library/PCP/Plugins\n\n" > qt.conf; \ + $(INSTALL) -m 644 qt.conf $(1)/qt.conf; \ + rm qt.conf; \ + find frameworks -type d -name qt_menu.nib | while read nib; do \ + $(INSTALL) -m 755 -d $(1)/qt_menu.nib || exit 1; \ + find $$nib -type f | while read nibs; do \ + f=`basename $$nibs`; \ + $(INSTALL) -m 644 $$nibs $(1)/qt_menu.nib/$$f || exit 1; \ + done; \ + done + +MAC_APPSUPPORT_DIR=/Library/PCP +MAC_FRAMEWORKS_DIR=$(MAC_APPSUPPORT_DIR)/Frameworks + +# WARNING! +# This rule modified the binary it was given, once modified the +# binary cannot be used with this rule again. +# If the binary is installed then it's important to call this +# rule before calling install rule for the binary. +INSTALL_QT_FRAMEWORKS=\ + otool -L $(1) | awk '{if (NR != 1) {print $$1}}' |\ + egrep 'Qt.*\.framework' | while read qt; do \ + tdir=`dirname $$qt`; \ + install_name_tool -change $$qt $(MAC_FRAMEWORKS_DIR)/$$qt $(1);\ + $(call INSTALL_DIRECTORY_HIERARCHY,$(MAC_FRAMEWORKS_DIR)/$$tdir,/Library/PCP); \ + mkdir -p frameworks/$$tdir || exit 1; \ + fwqt="frameworks/$$qt"; \ + cp /Library/Frameworks/$$qt frameworks/$$qt || exit 1; \ + otool -L $$fwqt | awk '{if (NR != 1) {print $$1}}' |\ + egrep 'Qt.*\.framework' | while read dep; do \ + install_name_tool -change $$dep $(MAC_FRAMEWORKS_DIR)/$$dep $$fwqt;\ + done; \ + $(INSTALL) frameworks/$$qt $(MAC_FRAMEWORKS_DIR)/$$qt; \ + if [ -d /Library/Frameworks/$$tdir/Resources ] ; then \ + $(INSTALL) -d $(MAC_FRAMEWORKS_DIR)/$$tdir/Resources; \ + (cd /Library/Frameworks/$$tdir; find Resources -type f) | \ + while read rf; do \ + rfpath="$$tdir/$$rf"; rfd=`dirname $$rfpath`; \ + fwpath="frameworks/$$rfpath"; brfd=`basename $$rfd`; \ + mkdir -p frameworks/$$rfd || exit 1; \ + cp /Library/Frameworks/$$rfpath $$fwpath || exit 1; \ + [ $$brfd != qt_menu.nib ] || continue; \ + $(INSTALL) -d $(MAC_FRAMEWORKS_DIR)/$$rfd || exit 1; \ + $(INSTALL) $$fwpath $(MAC_FRAMEWORKS_DIR)/$$rfpath;\ + done \ + fi; done +endif + + +# For targets that should always be rebuilt, +# define a target that is never up-to-date. +# Targets needing this should depend on $(_FORCE) +_FORCE = __force_build + +PCP_USER = @pcp_user@ +PCP_GROUP = @pcp_group@ +PCP_USER_INSTALL = @pcp_user_install@ +PCP_GROUP_INSTALL = @pcp_group_install@ + +PCPLIB = -lpcp +ifneq "$(PCPLIB)" "$(LIB_FOR_BASENAME)" +PCPLIB += $(LIB_FOR_BASENAME) +endif +ifeq "$(ENABLE_SHARED)" "no" +PCPLIB += $(LIB_FOR_MATH) $(LIB_FOR_PTHREADS) $(LIB_FOR_DLOPEN) $(LIB_FOR_RT) +endif +PCP_GUILIB = -lpcp_gui $(PCPLIB) +PCP_PMDALIB = -lpcp_pmda $(PCPLIB) +PCP_TRACELIB = -lpcp_trace $(PCPLIB) + +ifdef PCP_ALTLIBS +ifeq ($(PCP_LIB_DIR),$(PCP_LIB32_DIR)) +PCP_ALTLIBS = +else +ifneq "$(findstring $(MAKECMDGOALS),clean clobber)" "" +PCP_ALTLIBS = +endif +endif +endif + +BUILD_PMMGR=@BUILD_PMMGR@ + +endif # _BUILDDEFS_INCLUDED_ diff --git a/src/include/buildrules b/src/include/buildrules new file mode 100644 index 0000000..6471029 --- /dev/null +++ b/src/include/buildrules @@ -0,0 +1,192 @@ +# +# Copyright (c) 2013-2014 Red Hat. +# Copyright (c) 2007 Aconex. All Rights Reserved. +# Copyright (c) 2000,2003,2004 Silicon Graphics, Inc. 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 +# Free Software Foundation; either version 2 of the License, or (at your +# option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +# for more details. +# +# Common build rules for gmake +# +ifndef _BUILDRULES_INCLUDED_ +_BUILDRULES_INCLUDED_ = 1 + +ifndef _BUILDDEFS_INCLUDED_ +include $(TOPDIR)/src/include/builddefs +endif + +# +# Standard targets +# +ifdef CMDTARGET +$(CMDTARGET) : $(SUBDIRS) $(OBJECTS) + $(CCF) -o $(CMDTARGET) $(LDFLAGS) $(OBJECTS) $(LDLIBS) +endif +ifdef CXXMDTARGET +$(CXXMDTARGET) : $(SUBDIRS) $(OBJECTS) + $(CXXF) -o $(CXXMDTARGET) $(LDFLAGS) $(OBJECTS) $(LDLIBS) +endif + +# GNU make has a built-in recipe for .cc / .C / .cpp, but not for .cxx -> .o +.cxx.o: + $(CXXF) $(CXXFLAGS) -c $< -o $@ +.SUFFIXES: .cxx + +ifdef LIBTARGET +ifneq (, $(filter linux freebsd kfreebsd netbsd mingw gnu, $(TARGET_OS))) +_SHAREDOPTS = -shared -Wl,-soname,$(LIBTARGET) +endif +ifeq ($(TARGET_OS), solaris) +_SHAREDOPTS = -shared -fpic +endif +ifeq ($(TARGET_OS), darwin) +# libtool doesnt understand -dynamiclib so we need both +_SHAREDOPTS = -fPIC -dynamic -dynamiclib -flat_namespace -undefined suppress -headerpad_max_install_names -arch i386 +ifeq ($(PACKAGE_DISTRIBUTION), cocoa) +_SHAREDOPTS += -arch x86_64 +endif +endif +ifeq ($(TARGET_OS), aix) +_SHAREDOPTS = -qmkshrobj +endif + +ifdef VERSION_SCRIPT +ifneq ($(INVISIBILITY),) +ifeq ($(TARGET_OS), darwin) +# Mac OS X ld(1) takes a different format for the symbols file +# _SHAREDOPTS += -Wl,-exported_symbols_list $(VERSION_SCRIPT) +else +_SHAREDOPTS += -Wl,--version-script=$(VERSION_SCRIPT) +endif +endif +endif + +$(LIBTARGET) : $(SUBDIRS) $(OBJECTS) + $(CC) $(LDFLAGS) $(_SHAREDOPTS) -o $(LIBTARGET) $(OBJECTS) $(LDLIBS) $(LIB_FOR_DLOPEN) $(LIB_FOR_BASENAME) +endif + +ifdef STATICLIBTARGET +$(STATICLIBTARGET) : $(SUBDIRS) $(OBJECTS) +ifeq ($(TARGET_OS), darwin) + libtool -static -o $(STATICLIBTARGET) $? +else + $(AR) cr $(STATICLIBTARGET) $? +endif +endif + +ifdef WINDOWLINKS +windowlinks: + @for l in $(WINDOWLINKS) ; do \ + if [ ! -L $$l -a ! -f $$l ] ; then \ + $(LN_S) $(WINDOW)_$$l $$l ; \ + fi \ + done +endif + +# Suffix rule to support transition for YFILES to OBJECTS +%.tab.h : %.y + $(YACC) -d -b `basename $< .y` $< + +%.tab.c : %.y + $(YACC) -d -b `basename $< .y` $< + +# Dealing with quirks of the various packaging mechanisms +%.py: %.python + $(LN_S) $< $@ + +%.pl: %.perl + $(LN_S) $< $@ + +# Suffix rule to support transition for XML to PDF (books) +%.pdf: %.xml +ifeq ($(BOOK_TOOLCHAIN),publican) + $(PUBLICAN) build --langs=en-US --formats=pdf +endif +ifeq ($(BOOK_TOOLCHAIN),xmlto) + $(XMLTO) --with-fop pdf $^ +endif +ifeq ($(BOOK_TOOLCHAIN),dblatex) + $(DBLATEX) --type pdf $^ +endif + +ifeq ($(TARGET_OS), mingw) +# +# .exe rule for Windows +# +.SUFFIXES: .exe +.o.exe: + $(CCF) -o $* $(LDFLAGS) $(OBJECTS) $(LDLIBS) +endif + +clean clobber :: $(SUBDIRS) $(PRO_SUBDIRS) $(SNIA_SUBDIRS) + rm -rf $(DIRT) + @rm -fr $(DIRDIRT) + $(SUBDIRS_MAKERULE) + +realclean distclean: clean + rm -f $(TOPDIR)/src/include/builddefs \ + $(TOPDIR)/src/include/pcp.conf \ + $(TOPDIR)/src/include/pcp/config.h \ + $(TOPDIR)/src/include/pcp/configsz.h \ + $(TOPDIR)/src/include/pcp/platform_defs.h \ + $(TOPDIR)/src/include/pcp/pmdbg.h + rm -f $(TOPDIR)/build/GNUlocaldefs + rm -f $(TOPDIR)/pcp.lsm + +# +# Never blow away subdirs +# +ifdef SUBDIRS +.PRECIOUS: $(SUBDIRS) +endif + +endif + +$(_FORCE): + +# The depend target does not depend on any other targets (even though it +# actually depends on CFILES and HFILES). This is because there are several +# places where we generate header files (e.g. domain.h is generated for each +# subdir below src/pmdas, and domain.h in turn depends on src/pmns/stdpmid, +# which itself a generated file ...). As a result, you can't run make +# depend after make clobber, because the generated files will be missing. +# +# So running makedepend is for development use when you change a header +# somewhere and you need to be sure everything that depends on that header +# will be remade properly. + +.PHONY : depend $(_FORCE) + +depend : $(SUBDIRS) + $(SUBDIRS_MAKERULE) + touch dep + $(MAKEDEPEND) -fdep -- $(CFLAGS) -- $(CFILES) + +# +# include dep, but only if it exists +-include dep + +# Support for building multiple versions of the same library +ifneq ($(PCP_ALTLIBS),) +$(PCP_ALTLIBS): + rm -rf $@ + mkdir $@ + cp GNUlocaldefs.$@ $@/GNUlocaldefs + $(MAKE) -C src SLDEST=../$@ SLSRC=../src libsrc_symlinks +endif + +libsrc_symlinks: + test -n "$(SLDEST)" -a -d $(SLDEST) + for f in $(SRCFILES); do \ + if [ -e $(SLDEST)/$$f -a ! -L $(SLDEST)/$$f ] ; then \ + echo "$$f exists in $(SLDEST) and not a symlink"; exit 1; \ + fi; \ + rm -f $(SLDEST)/$$f; $(LN_S) $(SLSRC)/$$f $(SLDEST)/$$f || exit 1; \ + done diff --git a/src/include/pcp.conf.in b/src/include/pcp.conf.in new file mode 100644 index 0000000..3d4feb4 --- /dev/null +++ b/src/include/pcp.conf.in @@ -0,0 +1,206 @@ +# +# Copyright (c) 2013 Red Hat. +# Copyright (c) 2000-2001,2003 Silicon Graphics, Inc. All Rights Reserved. +# +# This program is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License as published by the +# Free Software Foundation; either version 2 of the License, or (at your +# option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +# for more details. +# +# This file defines the directories and paths used by PCP +# and is installed as the file /etc/pcp.conf for use at run-time. +# +# Note: the syntax of this file must allow processing to generate +# correct variable assignments for both sh and make, +# hence there should be no spaces immediately before or after +# the equals in each assignment, no quoting on the right of the +# equals although the value may contain embedded spaces. +# +# Shell scripts should never source this file directly, rather they +# should use this file indirectly by sourcing /etc/pcp.env, i.e. +# . $PCP_DIR/etc/pcp.env +# this will handle the quoting and white space issues and set all +# "variables" beginning with PCP_ in this file into the environment. +# The defaults may be over-ridden by setting $PCP_CONF in the environment +# as the full path to an alternate version of this file. +# +# The "standard paths" reflect the directory structure that is used by +# default on the platform on which this file is installed. +# + +# directory for _this_ file ... useful in the build +# Standard path: /etc +PCP_ETC_DIR=@pcp_etc_dir@ + +# directory for PCP configuration files +# Standard path: /etc/pcp +PCP_SYSCONF_DIR=@pcp_sysconf_dir@ + +# directory for rc/startup scripts +# Standard path: /etc/init.d +PCP_RC_DIR=@pcp_rc_dir@ + +# directory for sysconfig controls +# Standard path: /etc/sysconf (Redhat-specific) +# <empty> if no sysconfig support +PCP_SYSCONFIG_DIR=@pcp_sysconfig_dir@ + +# directory for public binaries +# Standard path: /usr/bin +PCP_BIN_DIR=@pcp_bin_dir@ + +# directory for private PCP binaries (not run directly by users) +# Standard path is platform dependent, but generally one of +# /usr/libexec/pcp/bin or /usr/lib/pcp/bin or /usr/share/pcp/bin +PCP_BINADM_DIR=@pcp_binadm_dir@ + +# directory for runtime shared libraries, libpcp.so, etc. +# Standard path: /usr/lib +PCP_LIB_DIR=@pcp_lib_dir@ +PCP_LIB32_DIR=@pcp_lib32_dir@ + +# directory for shared PCP files (shareable for diskless) +# Standard path: /usr/share/pcp +# Subdirectories: bin lib +PCP_SHARE_DIR=@pcp_share_dir@ + +# directory for headers +# Standard path: /usr/include/pcp +PCP_INC_DIR=@pcp_inc_dir@ + +# parent directory of man pages +# Standard path: /usr/man +# Subdirectories: man1 man3 man5 +PCP_MAN_DIR=@pcp_man_dir@ + +# directory for non-shared (i.e. system local) PCP files +# Standard path: /var/lib/pcp +# Subdirectories: config pmns (note see $PCP_PMDAS_DIR) for pmdas +PCP_VAR_DIR=@pcp_var_dir@ + +# path to pmcd config file +# Standard path: $PCP_SYSCONF_DIR/pmcd/pmcd.conf +PCP_PMCDCONF_PATH=@pcp_pmcdconf_path@ + +# path to pmcd options file +# Standard path: $PCP_SYSCONF_DIR/pmcd/pmcd.options +PCP_PMCDOPTIONS_PATH=@pcp_pmcdoptions_path@ + +# path to site-local pmcd startup script +# Standard path: $PCP_SYSCONF_DIR/pmcd/rc.local +PCP_PMCDRCLOCAL_PATH=@pcp_pmcdrclocal_path@ + +# path to pmproxy options file +# Standard path: $PCP_SYSCONF_DIR/pmproxy/pmproxy.options +PCP_PMPROXYOPTIONS_PATH=@pcp_pmproxyoptions_path@ + +# path to pmwebd options file +# Standard path: $PCP_SYSCONF_DIR/pmwebd/pmwebd.options +PCP_PMWEBDOPTIONS_PATH=@pcp_pmwebdoptions_path@ + +# path to pmmgr options file +# Standard path: $PCP_SYSCONF_DIR/pmmgr/pmmgr.options +PCP_PMMGROPTIONS_PATH=@pcp_pmmgroptions_path@ + +# path to pmie control file +# Standard path: $PCP_SYSCONF_DIR/pmie/control +PCP_PMIECONTROL_PATH=@pcp_pmiecontrol_path@ + +# path to pmsnap control file +# Standard path: $PCP_SYSCONF_DIR/pmsnap/control +PCP_PMSNAPCONTROL_PATH=@pcp_pmsnapcontrol_path@ + +# path to pmlogger control file +# Standard path: $PCP_SYSCONF_DIR/pmlogger/control +PCP_PMLOGGERCONTROL_PATH=@pcp_pmloggercontrol_path@ + +# directory for PCP PMDAs +# Standard path: /var/lib/pcp/pmdas +# Subdirectories: one per PMDA +PCP_PMDAS_DIR=@pcp_pmdas_dir@ + +# directory for PCP pid files +# Standard path: /var/run/pcp +PCP_RUN_DIR=@pcp_run_dir@ + +# directory for PCP logs +# Standard path: /var/log/pcp +# Subdirectories: pmcd pmlogger pmie +PCP_LOG_DIR=@pcp_log_dir@ + +# directory for PCP temp status files +# Standard path: /var/lib/pcp/tmp +# Subdirectories: pmie pmlogger +PCP_TMP_DIR=@pcp_tmp_dir@ + +# directory for PCP temp work files +# Standard path: /var/tmp +PCP_TMPFILE_DIR=@pcp_tmpfile_dir@ + +# directory for PCP documentation +# Standard path: /usr/share/doc/pcp +PCP_DOC_DIR=@pcp_doc_dir@ +PCP_HTML_DIR=@pcp_html_dir@ + +# directory for PCP demos and examples +# Standard path: /usr/share/pcp/demos +PCP_DEMOS_DIR=@pcp_demos_dir@ + +# awk +PCP_AWK_PROG="@awk@" + +# unix-like sort +PCP_SORT_PROG=@sort@ + +# tools needed to rebuild things on the target platform +PCP_MAKE_PROG=@make@ +PCP_CC_PROG="@cc@ @cflags_abi@" + +# echo +# for lines without newline, use +# $PCP_ECHO_PROG $PCP_ECHO_N "string""$PCP_ECHO_C" +PCP_ECHO_PROG=@echo@ +PCP_ECHO_N=@echo_n@ +PCP_ECHO_C=@echo_c@ + +# write to the system log +PCP_SYSLOG_PROG=@pcp_syslog_prog@ + +# running process list +PCP_PS_PROG=@pcp_ps_prog@ +PCP_PS_HAVE_BSD=@pcp_ps_have_bsd@ +PCP_PS_ALL_FLAGS=@pcp_ps_all_flags@ + +# locate executables +PCP_WHICH_PROG=@which@ + +# host operating system +PCP_PLATFORM=@target_os@ +PCP_PLATFORM_PATHS=@pcp_platform_paths@ + +# PCP version +PCP_VERSION=@PACKAGE_VERSION@ + +# confirmation dialog +PCP_XCONFIRM_PROG=@ac_xconfirm_prog@ + +# mpi +PCP_MPI_DIRS=@pcp_mpi_dirs@ + +# default account for running daemons (preferably unprivileged) +# Standard user: "pcp" and group: "pcp" +PCP_USER=@pcp_user@ +PCP_GROUP=@pcp_group@ + +# directory for SASL configuration files +# Standard path: /etc/sasl2 +PCP_SASLCONF_DIR=@pcp_saslconf_dir@ + +# directory for systemd unit files +# Standard path: /usr/lib/systemd/systemd +PCP_SYSTEMDUNIT_DIR=@pcp_systemdunit_dir@ diff --git a/src/include/pcp.env b/src/include/pcp.env new file mode 100644 index 0000000..d0ccab2 --- /dev/null +++ b/src/include/pcp.env @@ -0,0 +1,95 @@ +# +# Copyright (c) 2000,2003 Silicon Graphics, Inc. All Rights Reserved. +# Copyright (c) 2010 Aconex. 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 +# Free Software Foundation; either version 2 of the License, or (at your +# option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +# for more details. +# +# This file is sourced by PCP scripts to set the environment +# variables defined in the file named $PCP_CONF (or /etc/pcp.conf +# if $PCP_CONF is not defined). Any variable already defined in +# the environment is not changed. +# +# Note: any variables NOT starting with PCP_ will be ignored. +# This is a security issue so don't change it. +# Note also, this (variant of this) file is not used on Windows. +# +if [ -z "$PCP_ENV_DONE" ] +then + if [ -n "$PCP_CONF" ] + then + __CONF="$PCP_CONF" + elif [ -n "$PCP_DIR" ] + then + __CONF="$PCP_DIR/etc/pcp.conf" + else + __CONF=/etc/pcp.conf + fi + if [ ! -f "$__CONF" ] + then + echo "pcp.env: Fatal Error: \"$__CONF\" not found" >&2 + exit 1 + fi + eval `sed -e 's/"//g' $__CONF \ + | awk -F= ' +/^PCP_/ && NF == 2 { + exports=exports" "$1 + printf "%s=${%s:-\"%s\"}\n", $1, $1, $2 +} END { + print "export", exports +}'` + export PCP_ENV_DONE=y +fi + +# Always need to set $PATH ... sudo -E leaves $PCP_ENV_DONE set, but +# clears/resets $PATH. Note that order is important: any paths with +# PCP-specific binaries should end up ahead of more generic paths in +# the final $PATH to avoid conflicts on names of non-pcp binaries. +# +for dir in ${PCP_BIN_DIR} ${PCP_BINADM_DIR} \ + ${PCP_SHARE_DIR}/bin ${PCP_PLATFORM_PATHS} +do + if [ -d $dir ] + then + if echo ":$PATH:" | grep ":$dir:" >/dev/null 2>&1 + then + : + else + PATH="$dir:$PATH" + fi + fi +done +export PATH + +_get_pids_by_name() +{ + if [ $# -ne 1 ] + then + echo "Usage: _get_pids_by_name process-name" >&2 + exit 1 + fi + + # Algorithm ... all ps(1) variants have a time of the form MM:SS + # or HH:MM:SS or HH:MM.SS before the psargs field, so we're using + # this as the search anchor. + # + # Matches with $1 (process-name) occur if the first psarg is $1 + # or ends in /$1 ... the matching uses sed's regular expressions, + # so passing a regex into $1 will work. + + $PCP_PS_PROG $PCP_PS_ALL_FLAGS \ + | sed -n \ + -e 's/$/ /' \ + -e 's/[ ][ ]*/ /g' \ + -e 's/^ //' \ + -e 's/^[^ ]* //' \ + -e "/[0-9][:\.][0-9][0-9] *[^ ]*\/$1 /s/ .*//p" \ + -e "/[0-9][:\.][0-9][0-9] *$1 /s/ .*//p" +} diff --git a/src/include/pcp.mingw b/src/include/pcp.mingw new file mode 100644 index 0000000..871e16b --- /dev/null +++ b/src/include/pcp.mingw @@ -0,0 +1,75 @@ +# +# Copyright (c) 2000,2003 Silicon Graphics, Inc. All Rights Reserved. +# Copyright (c) 2010 Aconex. 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 +# Free Software Foundation; either version 2 of the License, or (at your +# option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +# for more details. +# +# This file is sourced by PCP scripts to set the environment +# variables defined in the file named $PCP_CONF (or /etc/pcp.conf +# if $PCP_CONF is not defined). Any variable already defined in +# the environment is not changed. +# +# Note: any variables NOT starting with PCP_ will be ignored. +# This is a security issue so don't change it. +# Note also, this variant of pcp.env is *only* used on Windows. +# +if [ -z "$PCP_ENV_DONE" ] +then + __CONF=${PCP_CONF-/etc/pcp.conf} + if [ ! -f "$__CONF" ] + then + echo "pcp.env: Fatal Error: \"$__CONF\" not found" >&2 + exit 1 + fi + export PCP_DIR=/c/MinGW/sys/1.0 + export PCP_CONF=$PCP_DIR/etc/pcp.conf + eval export `PATH=/lib:$PATH $PCP_DIR/libexec/pcp/bin/pmconfig.exe -s` + export PATH="/sbin:/bin:/lib:/etc:${PCP_BIN_DIR}:${PCP_BINADM_DIR}:${PCP_SHARE_DIR}/bin:${PCP_SHARE_DIR}/lib:${PCP_PLATFORM_PATHS}" + export PCP_ENV_DONE=y +fi + +mkaf() { + mkaf.sh $@ +} +pmafm() { + pmafm.sh $@ +} +pmsignal() { + pmsignal.sh $@ +} + +_get_pids_by_name() +{ + if [ $# -ne 1 ] + then + echo "Usage: _get_pids_by_name process-name" >&2 + exit 1 + fi + + # Algorithm ... all ps(1) variants have a time of the form MM:SS + # or HH:MM:SS or HH:MM.SS before the psargs field, so we're using + # this as the search anchor. + # + # Matches with $1 (process-name) occur if the first psarg is $1 + # or ends in /$1 ... the matching uses sed's regular expressions, + # so passing a regex into $1 will work. + + $PCP_PS_PROG $PCP_PS_ALL_FLAGS \ + | sed -n \ + -e 's/$/ /' \ + -e 's/[ ][ ]*/ /g' \ + -e 's/^ //' \ + -e 's/^[^ ]* //' \ + -e "/[0-9][:\.][0-9][0-9] *[^ ]*\\$1\.exe /s/ .*//p" \ + -e "/[0-9][:\.][0-9][0-9] *[^ ]*\/$1 /s/ .*//p" \ + -e "/[0-9][:\.][0-9][0-9] *$1\.exe /s/ .*//p" \ + -e "/[0-9][:\.][0-9][0-9] *$1 /s/ .*//p" +} diff --git a/src/include/pcp/GNUmakefile b/src/include/pcp/GNUmakefile new file mode 100644 index 0000000..4aaf310 --- /dev/null +++ b/src/include/pcp/GNUmakefile @@ -0,0 +1,42 @@ +# +# Copyright (c) 2013-2014 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 +# under the terms of the GNU General Public License as published by the +# Free Software Foundation; either version 2 of the License, or (at your +# option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +# for more details. +# + +TOPDIR = ../../.. +include $(TOPDIR)/src/include/builddefs +-include ./GNUlocaldefs + +HFILES = pmapi.h impl.h pmda.h pmtime.h pmafm.h import.h \ + trace.h trace_dev.h mmv_stats.h mmv_dev.h \ + config32.h config64.h +INFILES = config.h.in configsz.h.in platform_defs.h.in +CONFFILES = config.h configsz.h platform_defs.h +GENERATED_HFILES = pmdbg.h $(CONFFILES) + +LSRCFILES = mk_pmdbg fault.h $(INFILES) +LDIRT = $(GENERATED_HFILES) + +default :: default_pcp + +default_pcp : $(HEADERS) $(GENERATED_HFILES) + +include $(BUILDRULES) + +install :: default_pcp install_pcp + +install_pcp : default_pcp + $(INSTALL) -m 644 $(HFILES) $(GENERATED_HFILES) $(PCP_INC_DIR) + +pmdbg.h : pmapi.h impl.h + ./mk_pmdbg diff --git a/src/include/pcp/config.h.in b/src/include/pcp/config.h.in new file mode 100644 index 0000000..ae1ccdd --- /dev/null +++ b/src/include/pcp/config.h.in @@ -0,0 +1,685 @@ +/* + * Copyright (c) 2012-2014 Red Hat. + * Copyright (c) 2003 Moser, Inc. All Rights Reserved. + * Copyright (c) 2000-2004,2008 Silicon Graphics, Inc. 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 + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + */ + +#ifndef _PCP_CONFIG_H +#define _PCP_CONFIG_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include <time.h> + +/* + * The type of timestamps in struct stat: either HAVE_STAT_TIMESPEC, + * HAVE_STAT_TIMESPEC_T, HAVE_STAT_TIMESTRUC or HAVE_STAT_TIME_T + */ +#undef HAVE_STAT_TIMESPEC_T +#undef HAVE_STAT_TIMESTRUC +#undef HAVE_STAT_TIMESPEC +#undef HAVE_STAT_TIME_T + +/* HAVE_ST_MTIME if stat.st_mtime has a ``spec'' on the end */ +#undef HAVE_ST_MTIME_WITH_SPEC + +/* HAVE_ST_MTIME if stat.st_mtime has an ``e'' on the end */ +#undef HAVE_ST_MTIME_WITH_E + +/* if your compiler supports LL sufix on 64 bit int constants */ +#undef HAVE_CONST_LONGLONG + +/* + * HAVE_UNDERBAR_ENVIRON if extern char **_environ is defined + * (else extern char **environ will be used) + */ +#undef HAVE_UNDERBAR_ENVIRON + +/* + * If the pointer-to-function arguments to scandir() + * are (*scanfn)(const struct dirent *dep) + * Otherwise ``const'' will be omitted. + */ +#undef HAVE_CONST_DIRENT + +/* + * If the dirent structure contains a directory offset field. + */ +#undef HAVE_DIRENT_D_OFF + +/* Defined if printf %p -> 0x prefix for value */ +#undef HAVE_PRINTF_P_PFX +#ifdef HAVE_PRINTF_P_PFX +#define PRINTF_P_PFX "" +#else +#define PRINTF_P_PFX "0x" +#endif + +/* Defined if bit fields are allocated left-to-right within a word */ +#undef HAVE_BITFIELDS_LTOR + +/* if compiler can cast __uint64_t to double */ +#undef HAVE_CAST_U64_DOUBLE + +/* + * long and pointer must be either 32 bit or 64 bit + * + * This is complicated by RPMs "multilib" feature, which requires there + * to be no differences between header files on 32 and 64 bit platforms. + */ +#undef HAVE_BITS_WORDSIZE_H +#ifdef HAVE_BITS_WORDSIZE_H +# include <bits/wordsize.h> +# if __WORDSIZE == 32 +# include "config32.h" +# elif __WORDSIZE == 64 +# include "config64.h" +# else +# error "Unknown word size" +# endif +#else +# include "configsz.h" +#endif + +/* Define if header file is available */ +#undef HAVE_FCNTL_H +#undef HAVE_LIMITS_H +#undef HAVE_MALLOC_H +#undef HAVE_STRINGS_H +#undef HAVE_SYSLOG_H +#undef HAVE_UNISTD_H +#undef HAVE_STDDEF_H +#undef HAVE_SCHED_H +#undef HAVE_DLFCN_H +#undef HAVE_DL_H +#undef HAVE_SYS_TIME_H +#undef HAVE_SYS_TIMEB_H +#undef HAVE_SYS_TIMES_H +#undef HAVE_SYS_SYSINFO_H +#undef HAVE_SYS_SYSTEMINFO_H +#undef HAVE_SYS_RESOURCE_H +#undef HAVE_SYS_PRCTL_H +#undef HAVE_ENDIAN_H +#undef HAVE_STANDARDS_H +#undef HAVE_SYS_BYTEORDER_H +#undef HAVE_PTHREAD_H +#undef HAVE_LIBGEN_H +#undef HAVE_SYS_PARAM_H +#undef HAVE_SYS_MMAN_H +#undef HAVE_SYS_UN_H +#undef HAVE_STDINT_H +#undef HAVE_VALUES_H +#undef HAVE_IEEEFP_H +#undef HAVE_MATH_H +#undef HAVE_PWD_H +#undef HAVE_GRP_H +#undef HAVE_REGEX_H +#undef HAVE_TERMIO_H +#undef HAVE_TERMIOS_H +#undef HAVE_SYS_TERMIOS_H +#undef HAVE_SYS_IOCTL_H +#undef HAVE_SYS_WAIT_H +#undef HAVE_WINDOWS_H +#undef HAVE_WINSOCK2_H +#undef HAVE_WS2TCPIP_H +#undef HAVE_EXECINFO_H +#undef HAVE_IPTYPES_H +#undef HAVE_NETDB_H +#undef HAVE_SYS_SOCKET_H +#undef HAVE_NETINET_IN_H +#undef HAVE_NETINET_TCP_H +#undef HAVE_ARPA_INET_H + +#undef HAVE_SYS_ENDIAN_H +#undef HAVE_SYS_MACHINE_H +#undef HAVE_MACHINE_ENDIAN_H + +#undef HAVE_AI_ADDRCONFIG + +#if defined(HAVE_MALLOC_H) +#include <malloc.h> +#endif +#if defined(HAVE_STDDEF_H) +#include <stddef.h> +#endif +#if defined(HAVE_SYSLOG_H) +#include <syslog.h> +#endif +#if defined(HAVE_WINSOCK2_H) +#include <winsock2.h> +#endif +#if defined(HAVE_WINDOWS_H) +#include <windows.h> +#endif +#if defined(HAVE_WS2TCPIP_H) +#include <ws2tcpip.h> +#endif + +/* HAVE_NETWORK_BYTEORDER for big endian systems (not Intel) */ +#if defined(HAVE_ENDIAN_H) +#include <endian.h> +#elif defined(HAVE_SYS_ENDIAN_H) +#include <sys/endian.h> +#elif defined(HAVE_MACHINE_ENDIAN_H) +#include <machine/endian.h> +#endif +#if defined(HAVE_ENDIAN_H) || defined(HAVE_SYS_ENDIAN_H) || defined(HAVE_MACHINE_ENDIAN_H) +#if defined(BYTE_ORDER) && BYTE_ORDER == BIG_ENDIAN +#define HAVE_NETWORK_BYTEORDER +#endif +#endif + +#if defined(HAVE_SYS_BYTEORDER_H) +#include <sys/byteorder.h> +#if defined(_BIG_ENDIAN) +#define HAVE_NETWORK_BYTEORDER +#endif +#endif + +#if defined(HAVE_SYS_MACHINE_H) +#include <sys/machine.h> +#if defined(BYTE_ORDER) && BYTE_ORDER == BIG_ENDIAN +#define HAVE_NETWORK_BYTEORDER +#endif +#endif + +/* define which libraries are available */ +#undef HAVE_SECURE_SOCKETS +#undef HAVE_STATIC_PROBES +#undef HAVE_SERVICE_DISCOVERY +#undef HAVE_AVAHI +#undef HAVE_LIBREGEX +#undef HAVE_READLINE + +/* define which libc functions are available */ +#undef HAVE_WAIT3 + +#undef HAVE_MKTIME +#undef HAVE_CLOCK_GETTIME +#undef HAVE_NANOSLEEP +#undef HAVE_USLEEP +#undef HAVE_UNSETENV + +#undef HAVE_SELECT +#undef HAVE_SOCKET +#undef HAVE_GETHOSTNAME +#undef HAVE_GETPEERUCRED +#undef HAVE_GETPEEREID + +#undef HAVE_UNAME +#undef HAVE_SYSLOG +#undef HAVE___CLONE +#undef HAVE_PIPE2 +#undef HAVE_FCNTL + +#undef HAVE_PRCTL +#undef HAVE_SETLINEBUF +#undef HAVE_WAITPID +#undef HAVE_ATEXIT +#undef HAVE_KILL + +#undef HAVE_CHOWN +#undef HAVE_GETCWD +#undef HAVE_SCANDIR +#undef HAVE_MKSTEMP + +#undef HAVE_GETUID +#undef HAVE_GETGID +#undef HAVE_GETGRENT +#undef HAVE_GETGRENT_R +#undef HAVE_GETGRNAM +#undef HAVE_GETGRNAM_R +#undef HAVE_GETGRGID +#undef HAVE_GETGRGID_R +#undef HAVE_GETPWENT +#undef HAVE_GETPWENT_R +#undef HAVE_GETPWNAM +#undef HAVE_GETPWNAM_R +#undef HAVE_GETPWUID +#undef HAVE_GETPWUID_R + +#undef HAVE_BRK +#undef HAVE_SBRK +#undef HAVE_POSIX_MEMALIGN +#undef HAVE_MEMALIGN +#undef HAVE_VALLOC + +#undef HAVE_SIGNAL +#undef HAVE_SIGHOLD +#undef HAVE_SIGRELSE +#undef HAVE_TCGETATTR +#undef GWINSZ_IN_SYS_IOCTL + +#undef HAVE_REGEX +#undef HAVE_REGCMP +#undef HAVE_REGEXEC +#undef HAVE_REGCOMP + +#undef HAVE_STRTOD +#undef HAVE_STRTOL +#undef HAVE_STRTOLL +#undef HAVE_STRTOULL +#undef HAVE_STRNDUP +#undef HAVE_STRCHRNUL + +#undef HAVE_DLOPEN +#undef HAVE_FPCLASSIFY +#undef HAVE_ISNAN +#undef HAVE_ISNANF +#undef HAVE_FLOG10 +#undef HAVE_POW +#undef HAVE_DIRNAME +#undef HAVE_BASENAME +#undef HAVE_SYSINFO +#undef HAVE_TRACE_BACK_STACK +#undef HAVE_BACKTRACE +#undef HAVE_READDIR64 + +/* if termio signals are supported */ +#ifdef HAVE_TERMIOS_H +#ifdef HAVE_TCGETATTR +#define HAVE_TERMIO_SIGNALS +#endif +#endif + +/* if the /proc pseudo filesystem exists */ +#undef HAVE_PROCFS + +/* Infiniband API version information */ +#undef HAVE_PORT_PERFORMANCE_QUERY_VIA +#undef HAVE_PMA_QUERY_VIA + +#ifndef ULONGLONG_MAX +#define ULONGLONG_MAX (__uint64_t)18446744073709551615ULL +#endif + +#ifndef LONGLONG_MAX +#define LONGLONG_MAX (__int64_t)9223372036854775807LL +#endif + +/* some types only known by some compilers */ +#undef uint_t +#undef __int32_t +#undef __uint32_t +#undef __int64_t +#undef __uint64_t + +/* Check if __psint_t is set to something meaningful */ +#undef HAVE___PSINT_T +#ifndef HAVE___PSINT_T +#ifdef HAVE_32BIT_PTR +typedef int __psint_t; +#elif defined HAVE_64BIT_PTR +#ifdef HAVE_64BIT_LONG +typedef long __psint_t; +#else +/* This is a very strange architecture, which has 64 bit pointers but + * not 64 bit longs. So, I'd just punt here and assume long long is Ok */ +typedef long long __psint_t; +#endif +#else +#error Unknown pointer size - not 32 and not 64 +#endif +#endif + +/* Check if ptrdiff_t type is available */ +#undef HAVE_PTRDIFF_T +#ifndef HAVE_PTRDIFF_T +#define ptrdiff_t long +#endif + +/* + * User and group accounts - POSIX uid_t/gid_t combo or Win32 SID + */ +#undef HAVE_UID_T +#undef HAVE_GID_T +#undef HAVE_SID +#if defined(HAVE_UID_T) && defined(HAVE_GID_T) +typedef uid_t __pmUserID; +typedef gid_t __pmGroupID; +#elif defined(HAVE_SID) +typedef SID __pmUserID; +typedef SID __pmGroupID; +#else +bozo! unclear how to represent users and groups for this platform +#endif + +/* + * socklen_t is not always defined, so use __pmSockLen abstraction + */ +#undef HAVE_SOCKLEN_T +#ifdef HAVE_SOCKLEN_T +#include <sys/types.h> +#include <sys/socket.h> +typedef socklen_t __pmSockLen; +#else +typedef int __pmSockLen; +#endif + +/* + * MAXNAMELEN hides in may places and may have alias names ... + */ +#ifndef MAXNAMELEN +#include <stdio.h> +#ifdef HAVE_SYS_PARAM_H +#include <sys/param.h> +#endif +#if !defined(MAXNAMELEN) && defined(FILENAME_MAX) +/* posix version of the bsd MAXNAMELEN macro */ +#define MAXNAMELEN FILENAME_MAX +#endif +#endif +#ifndef MAXNAMELEN +bozo! need to find where MAXNAMELEN is defined for this platform +#endif + +/* + * MAXPATHLEN hides in many places and may have alias names ... + */ +#ifndef MAXPATHLEN +#ifdef HAVE_SYS_PARAM_H +#include <sys/param.h> +#endif +#ifdef HAVE_LIMITS_H +#include <limits.h> +#endif +#if !defined(MAXPATHLEN) && defined(PATH_MAX) +/* posix version of the bsd MAXPATHLEN macro */ +#define MAXPATHLEN PATH_MAX +#endif +#endif +#ifndef MAXPATHLEN +/* bozo! need to find where MAXPATHLEN is defined for this platform */ +#define PATH_MAX 4096 +#define MAXPATHLEN PATH_MAX +#endif + +/* + * MAXHOSTNAMELEN hides in many places and may also have aliases ... + */ +#ifndef MAXHOSTNAMELEN +#ifdef HAVE_SYS_PARAM_H +#include <sys/param.h> +#endif +#endif +#ifndef MAXHOSTNAMELEN +#ifdef HAVE_LIMITS_H +#include <limits.h> +#endif +#endif +#ifndef MAXHOSTNAMELEN +#ifdef HAVE_NETDB_H +#include <netdb.h> +#endif +#endif +#ifndef MAXHOSTNAMELEN +#ifdef HAVE_IPTYPES_H +#include <iptypes.h> +#define MAXHOSTNAMELEN MAX_HOSTNAME_LEN +#endif +#endif +#ifndef MAXHOSTNAMELEN +/* bozo! need to find where MAXHOSTNAMELEN is defined for this platform*/ +#define MAXHOSTNAMELEN 4096 +#endif + +#ifndef HAVE_FLOG10 +#if !defined(flog10) +#define flog10(x) (float)log10((double)x) +#endif +#endif + +#if !defined(WORD_BIT) +#define WORD_BIT 32 +#endif + +#undef RETSIGTYPE +#ifndef RETSIGTYPE +#define RETSIGTYPE void +#endif + +#undef HAVE_SIGPF +#ifndef HAVE_SIGPF +/* The return type of signal() */ +typedef void (*SIG_PF) (int); +#endif + +#undef HAVE_SA_SIGINFO +#undef HAVE_SIGPIPE +#undef HAVE_SIGHUP + +#undef HAVE_WAIT_INCLUDES_SIGNAL +#ifndef HAVE_WAIT_INCLUDES_SIGNAL +#include <signal.h> +#endif + +#undef HAVE_PR_TERMCHILD +#undef HAVE_PR_SET_PDEATHSIG + +#ifdef HAVE_LIBGEN_H +#include <libgen.h> +#endif + +/* thread support options */ +#undef HAVE_PTHREAD_MUTEX_T +#undef HAVE_PTHREAD_BARRIER_T +#undef HAVE___THREAD + +#undef HAVE_FNDELAY +#if !defined(HAVE_FNDELAY) +/* Only Solaris is known to need this so far */ +#ifndef FNDELAY +#define FNDELAY O_NDELAY +#endif +#endif + +#undef HAVE_ALTZONE +#undef HAVE_STRFTIME_z +#undef HAVE_STRERROR_R_PTR + +#undef HAVE_STRUCT_TIMESPEC +#undef HAVE_STRUCT_SOCKADDR_UN +#undef HAVE_STRUCT_UCRED + +#ifndef HAVE_VALLOC +#define valloc(x) malloc(x) +#endif + +/* Determine if we are on a Linux box */ +#undef IS_LINUX + +/* Determine if we are on a Solaris box */ +#undef IS_SOLARIS + +/* Determine if we are on an AIX box */ +#undef IS_AIX + +/* Determine if we are on a FreeBSD box */ +#undef IS_FREEBSD + +/* Determine if we are on a GNU box */ +#undef IS_GNU + +/* Determine if we are on a NetBSD box */ +#undef IS_NETBSD + +/* Determine if we are on a Mac OS X box */ +#undef IS_DARWIN +#ifdef IS_DARWIN +#define DLOPEN_NO_WARN +#define st_atim st_atimespec /* workaround */ +#define st_mtim st_mtimespec /* workaround */ +#define st_ctim st_ctimespec /* workaround */ +#endif + +/* Determine if we are on Windows with MinGW compiler */ +#undef IS_MINGW +#ifdef IS_MINGW + +#ifdef PCP_VERSION /* used to reduce namespace pollution */ +#define EHOSTDOWN WSAEHOSTDOWN +#define ENODATA WSANO_DATA +extern const char *wsastrerror(int); + +#define HAVE_PIPE1 +#define HAVE_MKDIR2 +#define HAVE_RENAME2 +#define HAVE_DLOPEN +#define HAVE_FNDELAY + +#define MAP_FAILED NULL +#define O_NDELAY 0 +#define SIGHUP (NSIG+1) +#define SIGUSR1 (NSIG+2) +#define SIGBUS (NSIG+3) +#define S_IRGRP 0 +#define S_IWGRP 0 +#define S_IROTH 0 +#define S_IWOTH 0 +#define S_IRWXG 0 +#define S_IRWXO 0 +#define S_ISVTX 0 + +#define fcntl(f, cmd, ...) 0 +#define mkdir2(path, mode) mkdir(path) +#define rename2(a, b) (unlink(b), rename(a,b)) +#define realpath(path, pp) strcpy(pp, path) +#define pipe1(fds) _pipe(fds, 4096, O_BINARY) + +extern void setlinebuf(FILE *); +extern char *index(const char *, int); +extern char *rindex(const char *, int); +extern char *strcasestr(const char *, const char *); +extern long int lrand48(void); +extern void srand48(long int); + +#ifdef HAVE_STRUCT_TIMESPEC +/* + * This is a bit odd ... but for MinGW, struct timespec is not in + * <time.h> but _is_ in <pthread.h> ... the structure (sec, nanosec) + * is what we want, so include <pthread.h> + */ +#include <pthread.h> +#endif + +extern int nanosleep(const struct timespec *, struct timespec *); +extern unsigned int sleep(unsigned int); + +enum { RTLD_NOW, RTLD_LAZY }; +extern void *dlopen(const char *, int); +extern char *dlerror(void); +extern void *dlsym(void *, const char *); +extern int dlclose(void *); + +extern void openlog(const char *, int, int); +extern void syslog(int, const char *, ...); +extern void closelog(void); +#endif +enum { LOG_EMERG, LOG_ALERT, LOG_CRIT, LOG_ERR, + LOG_WARNING, LOG_NOTICE, LOG_INFO, LOG_DEBUG, + LOG_PID, LOG_CONS, LOG_DAEMON }; + +#ifdef LIBPCP_INTERNAL +#define INTERN __declspec(dllexport) +#define EXTERN +#else +#define INTERN +#define EXTERN __declspec(dllimport) +#endif + +#define setoserror(n) (errno = (n)) /* not SetLastError() */ +#define oserror() errno /* not GetLastError() */ +#define neterror() WSAGetLastError() +#define hosterror() WSAGetLastError() +#define osstrerror() strerror(GetLastError()) +#define osstrerror_r(buf, len) pmErrStr_r(-GetLastError(), buf, len) +#define netstrerror() strerror(WSAGetLastError()) +#define netstrerror_r(buf, len) pmErrStr_r(-WSAGetLastError(), buf, len) +#define hoststrerror() strerror(WSAGetLastError()) + +#else /*!MINGW*/ +#define INTERN +#define EXTERN extern + +#define setoserror(n) (errno = (n)) +#define oserror() errno +#define neterror() errno +#define hosterror() h_errno +#define osstrerror() strerror(errno) +#define osstrerror_r(buf, len) pmErrStr_r(-errno, buf, len) +#define netstrerror() strerror(errno) +#define netstrerror_r(buf, len) pmErrStr_r(-errno, buf, len) +#define hoststrerror() hstrerror(h_errno) +#endif + +#ifndef O_CLOEXEC +#define O_CLOEXEC 0 +#endif + +#ifndef FD_CLOEXEC +#define FD_CLOEXEC 0 +#endif + +/* + * run-time environment that is in libc for most platforms, but for some + * we need to provide our own implementation + */ +#ifndef HAVE_DIRNAME +extern char *dirname(char *); +#endif +#ifndef HAVE_BASENAME +extern char *basename(char *); +#endif +#ifndef HAVE_STRNDUP +extern char *strndup(const char *, size_t); +#endif +#ifndef HAVE_STRCHRNUL +extern char *strchrnul(const char *, int); +#endif +#ifndef HAVE_STRCHRNUL +extern char *strchrnul(const char *, int c); +#endif + +#ifdef HAVE_CONST_DIRENT +#define const_dirent const struct dirent +#else +#define const_dirent struct dirent +#endif + +#ifndef HAVE_SCANDIR +struct dirent; +extern int scandir(const char *, struct dirent ***, + int(*filter)(const_dirent *), + int(*compare)(const_dirent **, const_dirent **)); +extern int alphasort(const_dirent **, const_dirent **); +#endif + +#ifndef HAVE_MKDIR2 +#define mkdir2(path,mode) mkdir(path,mode) +#endif + +#ifndef HAVE_RENAME2 +#define rename2(path,target) rename(path,target) +#endif + +#ifndef HAVE_PIPE1 +#define pipe1(fds) pipe(fds) +#endif + +#ifdef __cplusplus +} +#endif + +#endif /* _PCP_CONFIG_H */ diff --git a/src/include/pcp/config32.h b/src/include/pcp/config32.h new file mode 100644 index 0000000..64eba4c --- /dev/null +++ b/src/include/pcp/config32.h @@ -0,0 +1,23 @@ +/* + * Copyright (c) 2014 Red Hat. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + */ + +#ifndef _PCP_CONFIG32_H +#define _PCP_CONFIG32_H + +/* #undef HAVE_64BIT_LONG */ +#define HAVE_32BIT_LONG 1 +#define HAVE_32BIT_PTR 1 +/* #undef HAVE_64BIT_PTR */ + +#endif /* _PCP_CONFIG32_H */ diff --git a/src/include/pcp/config64.h b/src/include/pcp/config64.h new file mode 100644 index 0000000..4bae2ee --- /dev/null +++ b/src/include/pcp/config64.h @@ -0,0 +1,23 @@ +/* + * Copyright (c) 2014 Red Hat. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + */ + +#ifndef _PCP_CONFIG64_H +#define _PCP_CONFIG64_H + +#define HAVE_64BIT_LONG 1 +/* #undef HAVE_32BIT_LONG */ +/* #undef HAVE_32BIT_PTR */ +#define HAVE_64BIT_PTR 1 + +#endif /* _PCP_CONFIG64_H */ diff --git a/src/include/pcp/configsz.h.in b/src/include/pcp/configsz.h.in new file mode 100644 index 0000000..4a06e40 --- /dev/null +++ b/src/include/pcp/configsz.h.in @@ -0,0 +1,24 @@ +/* + * Copyright (c) 2014 Red Hat. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + */ + +#ifndef _PCP_CONFIGSZ_H +#define _PCP_CONFIGSZ_H + +/* long and pointer must be either 32 bit or 64 bit */ +#undef HAVE_64BIT_LONG +#undef HAVE_32BIT_LONG +#undef HAVE_32BIT_PTR +#undef HAVE_64BIT_PTR + +#endif /* _PCP_CONFIGSZ_H */ diff --git a/src/include/pcp/fault.h b/src/include/pcp/fault.h new file mode 100644 index 0000000..511609f --- /dev/null +++ b/src/include/pcp/fault.h @@ -0,0 +1,64 @@ +/* + * Copyright (c) 2011 Ken McDonell. All Rights Reserved. + * + * This library 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 + * (at your option) any later version. + * + * This library 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 Lesser General Public + * License for more details. + */ + +#ifndef _FAULT_H +#define _FAULT_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* + * Routines to support fault injection infrastructure + * + * Build libpcp with -DPM_FAULT_INJECTION to enable all of this. + */ +extern void __pmFaultInject(const char *, int); +extern void __pmFaultSummary(FILE *f); + +#ifdef PM_FAULT_INJECTION +extern int __pmFault_arm; +#define PM_FAULT_POINT(ident, class) __pmFaultInject(ident, class) +#ifdef malloc +#undef malloc +#endif +#define malloc(x) __pmFault_malloc(x) +extern void *__pmFault_malloc(size_t); +#ifdef realloc +#undef realloc +#endif +#define realloc(x,y) __pmFault_realloc(x,y) +extern void *__pmFault_realloc(void *, size_t); +#ifdef strdup +#undef strdup +#endif +#define strdup(x) __pmFault_strdup(x) +extern char *__pmFault_strdup(const char *); +#define PM_FAULT_CHECK(class) if (__pmFault_arm == PM_FAULT_PMAPI) { __pmFault_arm = 0; return PM_ERR_FAULT; } +#else +#define PM_FAULT_POINT(ident, class) +#define PM_FAULT_CHECK(class) +#endif + +/* + * Classes of fault types (second arg to __pmFaultInject()) + */ +#define PM_FAULT_ALLOC 100 +#define PM_FAULT_PMAPI 101 + +#ifdef __cplusplus +} +#endif + +#endif /* _FAULT_H */ diff --git a/src/include/pcp/impl.h b/src/include/pcp/impl.h new file mode 100644 index 0000000..c139fe1 --- /dev/null +++ b/src/include/pcp/impl.h @@ -0,0 +1,1488 @@ +/* + * Copyright (c) 2012-2014 Red Hat. + * Copyright (c) 2008-2009 Aconex. All Rights Reserved. + * Copyright (c) 1995-2002 Silicon Graphics, Inc. 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 + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + */ + +#ifndef _IMPL_H +#define _IMPL_H + +#include <time.h> +#include <fcntl.h> +#include <dirent.h> +#include <signal.h> +#include <unistd.h> +#include <sys/types.h> +#include <sys/param.h> +#include <sys/time.h> +#ifdef HAVE_SYS_SOCKET_H +#include <sys/socket.h> +#endif +#ifdef HAVE_NETINET_TCP_H +#include <netinet/tcp.h> +#endif +#ifdef HAVE_NETINET_IN_H +#include <netinet/in.h> +#endif +#ifdef HAVE_ARPA_INET_H +#include <arpa/inet.h> +#endif +#ifdef HAVE_NETDB_H +#include <netdb.h> +#endif + +/* + * Thread-safe support ... #define to enable thread-safe protection of + * global data structures and mutual exclusion when required. + * + * We require pthread.h and working mutex, the rest can be faked + * by the libpcp itself. + */ +#if defined(HAVE_PTHREAD_H) && defined(HAVE_PTHREAD_MUTEX_T) +#define PM_MULTI_THREAD 1 +#include <pthread.h> +typedef pthread_mutex_t __pmMutex; +#else +typedef void * __pmMutex; +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +/* + * This defines the routines, macros and data structures that are used + * in the Performance Metrics Collection Subsystem (PMCS) below the + * PMAPI. + */ + +/* + * internal libpcp state ... PM_STATE_APPL means we are at or above the + * PMAPI in a state where PMAPI calls can safely be made ... PM_STATE_PMCS + * means we are in the PMCD, or a PMDA, or low-level PDU code, and + * PMAPI calls are a bad idea. + */ +#define PM_STATE_APPL 0 +#define PM_STATE_PMCS 1 + +extern void __pmSetInternalState(int); +extern int __pmGetInternalState(void); + +/* + * PMCD connections come here by default, over-ride with $PMCD_PORT in + * environment + */ +#define SERVER_PORT 44321 +#define SERVER_PROTOCOL "pcp" +/* + * port that clients connect to pmproxy(1) on by default, over-ride with + * $PMPROXY_PORT in environment + */ +#define PROXY_PORT 44322 +#define PROXY_PROTOCOL "proxy" + +/* + * port that clients connect to pmwebd(1) by default + */ +#define PMWEBD_PORT 44323 +#define PMWEBD_PROTOCOL "http" + +/* + * Internally, this is how to decode a PMID! + * - flag is to denote state internally in some operations + * - domain is usually the unique domain number of a PMDA, but DYNAMIC_PMID + * (number 511) is reserved for PMIDs representing the root of a + * dynamic subtree in the PMNS (and in this case the real domain number + * is encoded in the cluster field) + * - cluster and item together uniquely identify a metric within a domain + */ +#define DYNAMIC_PMID 511 +typedef struct { +#ifdef HAVE_BITFIELDS_LTOR + unsigned int flag : 1; + unsigned int domain : 9; + unsigned int cluster : 12; + unsigned int item : 10; +#else + unsigned int item : 10; + unsigned int cluster : 12; + unsigned int domain : 9; + unsigned int flag : 1; +#endif +} __pmID_int; + +static inline __pmID_int * +__pmid_int(pmID *idp) +{ + /* avoid gcc's warning about dereferencing type-punned pointers */ + return (__pmID_int *)idp; +} + +static inline unsigned int +pmid_item(pmID id) +{ + return __pmid_int(&id)->item; +} + +static inline unsigned int +pmid_cluster(pmID id) +{ + return __pmid_int(&id)->cluster; +} + +static inline unsigned int +pmid_domain(pmID id) +{ + return __pmid_int(&id)->domain; +} + +static inline pmID +pmid_build(unsigned int domain, unsigned int cluster, unsigned int item) +{ + pmID id; + __pmID_int idint; + + idint.flag = 0; + idint.domain = domain; + idint.cluster = cluster; + idint.item = item; + memcpy(&id, &idint, sizeof(id)); + return id; +} + +/* + * Internally, this is how to decode an Instance Domain Identifier + * - flag is to denote state internally in some operations + * - domain is usually the unique domain number of a PMDA, but DYNAMIC_PMID + * (number 511) is reserved (see above for PMID encoding rules) + * - serial uniquely identifies an InDom within a domain + */ +typedef struct { +#ifdef HAVE_BITFIELDS_LTOR + int flag : 1; + unsigned int domain : 9; + unsigned int serial : 22; +#else + unsigned int serial : 22; + unsigned int domain : 9; + int flag : 1; +#endif +} __pmInDom_int; + +static inline __pmInDom_int * +__pmindom_int(pmInDom *idp) +{ + /* avoid gcc's warning about dereferencing type-punned pointers */ + return (__pmInDom_int *)idp; +} + +static inline unsigned int +pmInDom_domain(pmInDom id) +{ + return __pmindom_int(&id)->domain; +} + +static inline unsigned int +pmInDom_serial(pmInDom id) +{ + return __pmindom_int(&id)->serial; +} + +static inline pmInDom +pmInDom_build(unsigned int domain, unsigned int serial) +{ + pmInDom ind; + __pmInDom_int indint; + + indint.flag = 0; + indint.domain = domain; + indint.serial = serial; + memcpy(&ind, &indint, sizeof(ind)); + return ind; +} + +/* + * internal structure of a PMNS node + */ +typedef struct __pmnsNode { + struct __pmnsNode *parent; + struct __pmnsNode *next; + struct __pmnsNode *first; + struct __pmnsNode *hash; /* used as "last" in build, then pmid hash synonym */ + char *name; + pmID pmid; +} __pmnsNode; + +/* + * internal structure of a PMNS tree + */ +typedef struct __pmnsTree { + __pmnsNode *root; /* root of tree structure */ + __pmnsNode **htab; /* hash table of nodes keyed on pmid */ + int htabsize; /* number of nodes in the table */ + char *symbol; /* store all names contiguously */ + int contiguous; /* is data stored contiguously ? */ + int mark_state; /* the total mark value for trimming */ +} __pmnsTree; + + +/* used by pmnsmerge... */ +extern __pmnsTree *__pmExportPMNS(void); + +/* for PMNS in archives */ +extern int __pmNewPMNS(__pmnsTree **); +extern void __pmFreePMNS(__pmnsTree *); +extern void __pmUsePMNS(__pmnsTree *); /* for debugging */ +extern int __pmFixPMNSHashTab(__pmnsTree *, int, int); +extern int __pmAddPMNSNode(__pmnsTree *, int, const char *); + + +/* return true if the named pmns file has changed */ +extern int __pmHasPMNSFileChanged(const char *); + +/* standard log file set up */ +extern FILE *__pmOpenLog(const char *, const char *, FILE *, int *); +extern FILE *__pmRotateLog(const char *, const char *, FILE *, int *); +/* make __pmNotifyErr also add entries to syslog */ +extern void __pmSyslog(int); +/* standard error, warning and info wrapper for syslog(3C) */ +extern void __pmNotifyErr(int, const char *, ...) __PM_PRINTFLIKE(2,3); + +/* + * These are for debugging only (but are present in the shipped libpcp) + */ +EXTERN int pmDebug; +#define DBG_TRACE_PDU 1 /* PDU send and receive */ +#define DBG_TRACE_FETCH 2 /* dump pmFetch results */ +#define DBG_TRACE_PROFILE 4 /* trace profile changes */ +#define DBG_TRACE_VALUE 8 /* metric value conversions */ +#define DBG_TRACE_CONTEXT 16 /* trace PMAPI context changes */ +#define DBG_TRACE_INDOM 32 /* instance domain operations */ +#define DBG_TRACE_PDUBUF 64 /* PDU buffer management */ +#define DBG_TRACE_LOG 128 /* generic archive log operations */ +#define DBG_TRACE_LOGMETA (1<<8) /* meta data in archives */ +#define DBG_TRACE_OPTFETCH (1<<9) /* optFetch tracing */ +#define DBG_TRACE_AF (1<<10) /* trace async timer events */ +#define DBG_TRACE_APPL0 (1<<11) /* reserved for applications */ +#define DBG_TRACE_APPL1 (1<<12) /* reserved for applications */ +#define DBG_TRACE_APPL2 (1<<13) /* reserved for applications */ +#define DBG_TRACE_PMNS (1<<14) /* PMNS operations */ +#define DBG_TRACE_LIBPMDA (1<<15) /* libpcp_pmda */ +#define DBG_TRACE_TIMECONTROL (1<<16) /* time control api */ +#define DBG_TRACE_PMC (1<<17) /* metrics class */ +#define DBG_TRACE_DERIVE (1<<18) /* derived metrics */ +#define DBG_TRACE_LOCK (1<<19) /* lock tracing */ +#define DBG_TRACE_INTERP (1<<20) /* interpolate mode for archives */ +#define DBG_TRACE_CONFIG (1<<21) /* configuration parameters */ +#define DBG_TRACE_LOOP (1<<22) /* pmLoop tracing */ +#define DBG_TRACE_FAULT (1<<23) /* fault injection tracing */ +#define DBG_TRACE_AUTH (1<<24) /* authentication tracing */ +#define DBG_TRACE_DISCOVERY (1<<25) /* service discovery tracing */ +/* not yet allocated, bits (1<<26) ... (1<<29) */ +#define DBG_TRACE_DESPERATE (1<<30) /* verbose/desperate level */ + +extern int __pmParseDebug(const char *); +extern void __pmDumpResult(FILE *, const pmResult *); +extern void __pmDumpHighResResult(FILE *, const pmHighResResult *); +extern void __pmPrintStamp(FILE *, const struct timeval *); +extern void __pmPrintHighResStamp(FILE *, const struct timespec *); +extern void __pmPrintTimespec(FILE *, const __pmTimespec *); +extern void __pmPrintTimeval(FILE *, const __pmTimeval *); +extern void __pmPrintDesc(FILE *, const pmDesc *); +extern void __pmFreeResultValues(pmResult *); +extern char *__pmPDUTypeStr_r(int, char *, int); +extern const char *__pmPDUTypeStr(int); /* NOT thread-safe */ +extern void __pmDumpNameSpace(FILE *, int); +extern void __pmDumpNameNode(FILE *, __pmnsNode *, int); +extern void __pmDumpStack(FILE *); +EXTERN int __pmLogReads; + +#ifdef PCP_DEBUG +extern void __pmDumpIDList(FILE *, int, const pmID *); +extern void __pmDumpNameList(FILE *, int, char **); +extern void __pmDumpStatusList(FILE *, int, const int *); +extern void __pmDumpNameAndStatusList(FILE *, int, char **, int *); +#endif + +/* + * Logs and archives of performance metrics (not to be confused + * with diagnostic logs for error messages, etc.) + * + * __pmLogCtl log control + * __pmLogTI temporal index record + */ + +/* + * Hashed Data Structures for the Processing of Logs and Archives + */ +typedef struct __pmHashNode { + struct __pmHashNode *next; + unsigned int key; + void *data; +} __pmHashNode; + +typedef struct __pmHashCtl { + int nodes; + int hsize; + __pmHashNode **hash; + __pmHashNode *next; + unsigned int index; +} __pmHashCtl; + +typedef enum { + PM_HASH_WALK_START = 0, + PM_HASH_WALK_NEXT, + PM_HASH_WALK_STOP, + PM_HASH_WALK_DELETE_NEXT, + PM_HASH_WALK_DELETE_STOP, +} __pmHashWalkState; + +extern void __pmHashInit(__pmHashCtl *); +typedef __pmHashWalkState(*__pmHashWalkCallback)(const __pmHashNode *, void *); +extern void __pmHashWalkCB(__pmHashWalkCallback, void *, const __pmHashCtl *); +extern __pmHashNode *__pmHashWalk(__pmHashCtl *, __pmHashWalkState); +extern __pmHashNode *__pmHashSearch(unsigned int, __pmHashCtl *); +extern int __pmHashAdd(unsigned int, void *, __pmHashCtl *); +extern int __pmHashDel(unsigned int, void *, __pmHashCtl *); +extern void __pmHashClear(__pmHashCtl *); + +/* + * External file and internal (below PMAPI) format for an archive label + * Note: int is OK here, because configure ensures int is a 32-bit integer + */ +typedef struct { + int ill_magic; /* PM_LOG_MAGIC | log format version no. */ + int ill_pid; /* PID of logger */ + __pmTimeval ill_start; /* start of this log */ + int ill_vol; /* current log volume no. */ + char ill_hostname[PM_LOG_MAXHOSTLEN];/* name of collection host */ + char ill_tz[PM_TZ_MAXLEN]; /* $TZ at collection host */ +} __pmLogLabel; + +/* + * unfortunately, in this version, PCP archives are limited to no + * more than 2 Gbytes ... + */ +typedef __uint32_t __pm_off_t; + +/* + * Temporal Index Record + * Note: int is OK here, because configure ensures int is a 32-bit integer + */ +typedef struct { + __pmTimeval ti_stamp; /* now */ + int ti_vol; /* current log volume no. */ + __pm_off_t ti_meta; /* end of meta data file */ + __pm_off_t ti_log; /* end of metrics log file */ +} __pmLogTI; + +/* + * Log/Archive Control + */ +typedef struct { + int l_refcnt; /* number of contexts using this log */ + char *l_name; /* external log base name */ + FILE *l_tifp; /* temporal index */ + FILE *l_mdfp; /* meta data */ + FILE *l_mfp; /* current metrics log */ + int l_curvol; /* current metrics log volume no. */ + int l_state; /* (when writing) log state */ + __pmHashCtl l_hashpmid; /* PMID hashed access */ + __pmHashCtl l_hashindom; /* instance domain hashed access */ + __pmHashCtl l_hashrange; /* ptr to first and last value in log for */ + /* each metric */ + int l_minvol; /* (when reading) lowest known volume no. */ + int l_maxvol; /* (when reading) highest known volume no. */ + int l_numseen; /* (when reading) size of l_seen */ + int *l_seen; /* (when reading) volumes opened OK */ + __pmLogLabel l_label; /* (when reading) log label */ + __pm_off_t l_physend; /* (when reading) offset to physical EOF */ + /* for last volume */ + __pmTimeval l_endtime; /* (when reading) timestamp at logical EOF */ + int l_numti; /* (when reading) no. temporal index entries */ + __pmLogTI *l_ti; /* (when reading) temporal index */ + __pmnsTree *l_pmns; /* namespace from meta data */ +} __pmLogCtl; + +/* l_state values */ +#define PM_LOG_STATE_NEW 0 +#define PM_LOG_STATE_INIT 1 + +/* + * Return the argument if it's a valid filename else return NULL + * (note: this function could be replaced with a call to access(), + * but is retained for historical reasons). + */ +extern const char *__pmFindPMDA(const char *); + +/* + * Internal instance profile states + */ +#define PM_PROFILE_INCLUDE 0 /* include all, exclude some */ +#define PM_PROFILE_EXCLUDE 1 /* exclude all, include some */ + +/* Profile entry (per instance domain) */ +typedef struct __pmInDomProfile { + pmInDom indom; /* instance domain */ + int state; /* include all or exclude all */ + int instances_len; /* length of instances array */ + int *instances; /* array of instances */ +} __pmInDomProfile; + +/* Instance profile for all domains */ +typedef struct __pmProfile { + int state; /* default global state */ + int profile_len; /* length of profile array */ + __pmInDomProfile *profile; /* array of instance profiles */ +} __pmProfile; + +/* + * Dump the instance profile, for a particular instance domain + * If indom == PM_INDOM_NULL, then print all instance domains + */ +extern void __pmDumpProfile(FILE *, int, const __pmProfile *); + +/* + * Result structure for instance domain queries + * Only the PMDAs and pmcd need to know about this. + */ +typedef struct __pmInResult { + pmInDom indom; /* instance domain */ + int numinst; /* may be 0 */ + int *instlist; /* instance ids, may be NULL */ + char **namelist; /* instance names, may be NULL */ +} __pmInResult; +extern void __pmDumpInResult(FILE *, const __pmInResult *); + +/* instance profile methods */ +extern int __pmProfileSetSent(void); +extern void __pmFreeProfile(__pmProfile *); +extern __pmInDomProfile *__pmFindProfile(pmInDom, const __pmProfile *); +extern int __pmInProfile(pmInDom, const __pmProfile *, int); +extern void __pmFreeInResult(__pmInResult *); + +/* + * Version and capabilities information for PDU exchanges + */ + +#define UNKNOWN_VERSION 0 +#define PDU_VERSION2 2 +#define PDU_VERSION PDU_VERSION2 + +#define PDU_OVERRIDE2 -1002 + +typedef struct { +#ifdef HAVE_BITFIELDS_LTOR + unsigned int zero : 1; /* ensure this is zero for 1.x compatibility */ + unsigned int version : 7; /* PDU_VERSION collector protocol preference */ + unsigned int licensed : 8; /* ensure this is one for 2.x compatibility */ + unsigned int features : 16; /* advertised (enabled) collector features */ +#else + unsigned int features : 16; + unsigned int licensed : 8; + unsigned int version : 7; + unsigned int zero : 1; +#endif +} __pmPDUInfo; + +/* + * Host specification allowing one or more pmproxy host, and port numbers + * within the one string, i.e. pmcd host specifications of the form: + * host:port,port@proxy:port,port + */ +typedef struct { + char *name; /* hostname (always valid) */ + int *ports; /* array of host port numbers */ + int nports; /* number of ports in host port array */ +} pmHostSpec; + +extern int __pmParseHostSpec(const char *, pmHostSpec **, int *, char **); +extern int __pmUnparseHostSpec(pmHostSpec *, int, char *, size_t); +extern void __pmFreeHostSpec(pmHostSpec *, int); + +typedef enum { + PCP_ATTR_NONE = 0, + PCP_ATTR_PROTOCOL = 1, /* either pcp:/pcps: protocol (libssl) */ + PCP_ATTR_SECURE = 2, /* relaxed/enforced pcps mode (libssl) */ + PCP_ATTR_COMPRESS = 3, /* compression flag, no value (libnss) */ + PCP_ATTR_USERAUTH = 4, /* user auth flag, no value (libsasl) */ + PCP_ATTR_USERNAME = 5, /* user login identity (libsasl) */ + PCP_ATTR_AUTHNAME = 6, /* authentication name (libsasl) */ + PCP_ATTR_PASSWORD = 7, /* passphrase-based secret (libsasl) */ + PCP_ATTR_METHOD = 8, /* use authentication method (libsasl) */ + PCP_ATTR_REALM = 9, /* realm to authenticate in (libsasl) */ + PCP_ATTR_UNIXSOCK = 10, /* AF_UNIX socket + SO_PEERCRED (unix) */ + PCP_ATTR_USERID = 11, /* uid - user identifier (posix) */ + PCP_ATTR_GROUPID = 12, /* gid - group identifier (posix) */ + PCP_ATTR_LOCAL = 13, /* AF_UNIX socket with localhost fallback */ + PCP_ATTR_PROCESSID = 14, /* pid - process identifier (posix) */ +} __pmAttrKey; + +extern __pmAttrKey __pmLookupAttrKey(const char *, size_t); +extern int __pmAttrKeyStr_r(__pmAttrKey, char *, size_t); +extern int __pmAttrStr_r(__pmAttrKey, const char *, char *, size_t); + +extern int __pmParseHostAttrsSpec( + const char *, pmHostSpec **, int *, __pmHashCtl *, char **); +extern int __pmUnparseHostAttrsSpec( + pmHostSpec *, int, __pmHashCtl *, char *, size_t); +extern void __pmFreeHostAttrsSpec(pmHostSpec *, int, __pmHashCtl *); +extern void __pmFreeAttrsSpec(__pmHashCtl *); + +/* + * Control for connection to a PMCD + */ +typedef struct { + __pmMutex pc_lock; /* mutex pmcd ipc */ + int pc_refcnt; /* number of contexts using this socket */ + int pc_fd; /* socket for comm with pmcd */ + /* ... -1 means no connection */ + pmHostSpec *pc_hosts; /* pmcd and proxy host specifications */ + int pc_nhosts; /* number of pmHostSpec entries */ + int pc_timeout; /* set if connect times out */ + int pc_tout_sec; /* timeout for __pmGetPDU */ + time_t pc_again; /* time to try again */ +} __pmPMCDCtl; + +extern int __pmConnectPMCD(pmHostSpec *, int, int, __pmHashCtl *); +extern int __pmConnectLocal(__pmHashCtl *); +extern int __pmAuxConnectPMCD(const char *); +extern int __pmAuxConnectPMCDPort(const char *, int); +extern int __pmAuxConnectPMCDUnixSocket(const char *); + +extern int __pmAddHostPorts(pmHostSpec *, int *, int); +extern void __pmDropHostPort(pmHostSpec *); +extern void __pmConnectGetPorts(pmHostSpec *); + +/* + * SSL/TLS/IPv6 support via NSS/NSPR. + */ +extern int __pmSecureServerSetup(const char *, const char *); +extern void __pmSecureServerShutdown(void); +extern int __pmSecureServerHandshake(int, int, __pmHashCtl *); +extern int __pmSecureClientHandshake(int, int, const char *, __pmHashCtl *); + +typedef fd_set __pmFdSet; +typedef struct __pmSockAddr __pmSockAddr; +typedef struct __pmHostEnt __pmHostEnt; + +extern int __pmCreateSocket(void); +extern int __pmCreateIPv6Socket(void); +extern int __pmCreateUnixSocket(void); +extern void __pmCloseSocket(int); + +extern int __pmSetSockOpt(int, int, int, const void *, __pmSockLen); +extern int __pmGetSockOpt(int, int, int, void *, __pmSockLen *); +extern int __pmConnect(int, void *, __pmSockLen); +extern int __pmBind(int, void *, __pmSockLen); +extern int __pmListen(int, int); +extern int __pmAccept(int, void *, __pmSockLen *); +extern ssize_t __pmWrite(int, const void *, size_t); +extern ssize_t __pmRead(int, void *, size_t); +extern ssize_t __pmSend(int, const void *, size_t, int); +extern ssize_t __pmRecv(int, void *, size_t, int); +extern int __pmConnectTo(int, const __pmSockAddr *, int); +extern int __pmConnectCheckError(int); +extern int __pmConnectRestoreFlags(int, int); +extern int __pmSocketClosed(void); +extern int __pmGetFileStatusFlags(int); +extern int __pmSetFileStatusFlags(int, int); +extern int __pmGetFileDescriptorFlags(int); +extern int __pmSetFileDescriptorFlags(int, int); + +extern int __pmFD(int); +extern void __pmFD_CLR(int, __pmFdSet *); +extern int __pmFD_ISSET(int, __pmFdSet *); +extern void __pmFD_SET(int, __pmFdSet *); +extern void __pmFD_ZERO(__pmFdSet *); +extern void __pmFD_COPY(__pmFdSet *, const __pmFdSet *); +extern int __pmSelectRead(int, __pmFdSet *, struct timeval *); +extern int __pmSelectWrite(int, __pmFdSet *, struct timeval *); + +extern __pmSockAddr *__pmSockAddrAlloc(void); +extern void __pmSockAddrFree(__pmSockAddr *); +extern size_t __pmSockAddrSize(void); +extern void __pmSockAddrInit(__pmSockAddr *, int, int, int); +extern int __pmSockAddrCompare(const __pmSockAddr *, const __pmSockAddr *); +extern __pmSockAddr *__pmSockAddrDup(const __pmSockAddr *); +extern __pmSockAddr *__pmSockAddrMask(__pmSockAddr *, const __pmSockAddr *); +extern void __pmSockAddrSetFamily(__pmSockAddr *, int); +extern int __pmSockAddrGetFamily(const __pmSockAddr *); +extern void __pmSockAddrSetPort(__pmSockAddr *, int); +extern int __pmSockAddrGetPort(const __pmSockAddr *); +extern void __pmSockAddrSetScope(__pmSockAddr *, int); +extern void __pmSockAddrSetPath(__pmSockAddr *, const char *); +extern int __pmSockAddrIsLoopBack(const __pmSockAddr *); +extern int __pmSockAddrIsInet(const __pmSockAddr *); +extern int __pmSockAddrIsIPv6(const __pmSockAddr *); +extern int __pmSockAddrIsUnix(const __pmSockAddr *); +extern char * __pmSockAddrToString(const __pmSockAddr *); +extern __pmSockAddr *__pmStringToSockAddr(const char *); +extern __pmSockAddr *__pmLoopBackAddress(int); +extern __pmSockAddr *__pmSockAddrFirstSubnetAddr(const __pmSockAddr *, int); +extern __pmSockAddr *__pmSockAddrNextSubnetAddr(__pmSockAddr *, int); + +extern __pmHostEnt * __pmHostEntAlloc(void); +extern void __pmHostEntFree(__pmHostEnt *); +extern __pmSockAddr *__pmHostEntGetSockAddr(const __pmHostEnt *, void **); +extern char * __pmHostEntGetName(__pmHostEnt *); + +extern __pmHostEnt * __pmGetAddrInfo(const char *); +extern char * __pmGetNameInfo(__pmSockAddr *); + +/* + * Query server features - used for expressing protocol capabilities + */ +typedef enum { + PM_SERVER_FEATURE_SECURE = 0, + PM_SERVER_FEATURE_COMPRESS, + PM_SERVER_FEATURE_IPV6, + PM_SERVER_FEATURE_AUTH, + PM_SERVER_FEATURE_CREDS_REQD, + PM_SERVER_FEATURE_UNIX_DOMAIN, + PM_SERVER_FEATURE_DISCOVERY, + PM_SERVER_FEATURES +} __pmServerFeature; + +extern int __pmServerHasFeature(__pmServerFeature); +extern int __pmServerSetFeature(__pmServerFeature); +extern int __pmServerClearFeature(__pmServerFeature); +extern int __pmServerCreatePIDFile(const char *, int); +extern int __pmServerAddPorts(const char *); +extern int __pmServerAddInterface(const char *); +extern void __pmServerSetLocalSocket(const char *); +extern int __pmServerSetLocalCreds(int, __pmHashCtl *); +extern void __pmServerSetServiceSpec(const char *); +typedef void (*__pmServerCallback)(__pmFdSet *, int, int); +extern void __pmServerAddNewClients(__pmFdSet *, __pmServerCallback); +extern int __pmServerAddToClientFdSet(__pmFdSet *, int); +extern int __pmServerOpenRequestPorts(__pmFdSet *, int); +extern void __pmServerCloseRequestPorts(void); +extern void __pmServerDumpRequestPorts(FILE *); +extern char *__pmServerRequestPortString(int, char *, size_t); + +/* Service broadcasting, for servers. */ +typedef struct __pmServerPresence __pmServerPresence; +extern __pmServerPresence *__pmServerAdvertisePresence(const char *, int); +extern void __pmServerUnadvertisePresence(__pmServerPresence *); + +/* + * Per-context controls for archives and logs + */ +typedef struct { + __pmLogCtl *ac_log; /* global logging and archive control */ + long ac_offset; /* fseek ptr for archives */ + int ac_vol; /* volume for ac_offset */ + int ac_serial; /* serial access pattern for archives */ + __pmHashCtl ac_pmid_hc; /* per PMID controls for INTERP */ + double ac_end; /* time at end of archive */ + void *ac_want; /* used in interp.c */ + void *ac_unbound; /* used in interp.c */ + void *ac_cache; /* used in interp.c */ + int ac_cache_idx; /* used in interp.c */ +} __pmArchCtl; + +/* + * PMAPI context. We keep an array of these, + * one for each context created by the application. + */ +typedef struct { + __pmMutex c_lock; /* mutex for multi-thread access */ + int c_type; /* HOST, ARCHIVE, LOCAL or FREE */ + int c_mode; /* current mode PM_MODE_* */ + __pmPMCDCtl *c_pmcd; /* pmcd control for HOST contexts */ + __pmArchCtl *c_archctl; /* log control for ARCHIVE contexts */ + __pmTimeval c_origin; /* pmFetch time origin / current time */ + int c_delta; /* for updating origin */ + int c_sent; /* profile has been sent to pmcd */ + __pmProfile *c_instprof; /* instance profile */ + void *c_dm; /* derived metrics, if any */ + int c_flags; /* ctx flags (set via type/env/attrs) */ + __pmHashCtl c_attrs; /* various optional context attributes */ +} __pmContext; + +#define __PM_MODE_MASK 0xffff + +#define PM_CONTEXT_FREE -1 /* special type */ + +/* + * Convert opaque context handle to __pmContext pointer + */ +extern __pmContext *__pmHandleToPtr(int); + +/* + * Dump the current context (source details + instance profile), + * for a particular instance domain. + * If indom == PM_INDOM_NULL, then print all all instance domains + */ +extern void __pmDumpContext(FILE *, int, pmInDom); + +/* + * pmFetch helper routines, providing hooks for derivations. + */ +extern int __pmPrepareFetch(__pmContext *, int, const pmID *, pmID **); +extern int __pmFinishResult(__pmContext *, int, pmResult **); + +/* + * Protocol data unit support + * Note: int is OK here, because configure ensures int is a 32-bit integer + */ +typedef struct { + int len; /* length of pdu_header + PDU */ + int type; /* PDU type */ + int from; /* pid of PDU originator */ +} __pmPDUHdr; + +typedef __uint32_t __pmPDU; +/* + * round a size up to the next multiple of a __pmPDU size + * + * PM_PDU_SIZE is in units of __pmPDU size + * PM_PDU_SIZE_BYTES is in units of bytes + */ +#define PM_PDU_SIZE(x) (((x)+sizeof(__pmPDU)-1)/sizeof(__pmPDU)) +#define PM_PDU_SIZE_BYTES(x) (sizeof(__pmPDU)*PM_PDU_SIZE(x)) + +/* Types of credential PDUs (c_type) */ +#define CVERSION 0x1 + +typedef struct { +#ifdef HAVE_BITFIELDS_LTOR + unsigned int c_type: 8; /* Credentials PDU type */ + unsigned int c_vala: 8; + unsigned int c_valb: 8; + unsigned int c_valc: 8; +#else + unsigned int c_valc: 8; + unsigned int c_valb: 8; + unsigned int c_vala: 8; + unsigned int c_type: 8; +#endif +} __pmCred; + +/* Flags for CVERSION credential PDUs, and __pmPDUInfo features */ +#define PDU_FLAG_SECURE (1U<<0) +#define PDU_FLAG_COMPRESS (1U<<1) +#define PDU_FLAG_AUTH (1U<<2) +#define PDU_FLAG_CREDS_REQD (1U<<3) +#define PDU_FLAG_SECURE_ACK (1U<<4) +#define PDU_FLAG_NO_NSS_INIT (1U<<5) + +/* Credential CVERSION PDU elements look like this */ +typedef struct { +#ifdef HAVE_BITFIELDS_LTOR + unsigned int c_type: 8; /* Credentials PDU type */ + unsigned int c_version: 8; /* PCP protocol version */ + unsigned int c_flags: 16; /* All feature requests */ +#else + unsigned int c_flags: 16; + unsigned int c_version: 8; + unsigned int c_type: 8; +#endif +} __pmVersionCred; + +extern int __pmXmitPDU(int, __pmPDU *); +extern int __pmGetPDU(int, int, int, __pmPDU **); +extern int __pmGetPDUCeiling(void); +extern int __pmSetPDUCeiling(int); + +EXTERN unsigned int *__pmPDUCntIn; +EXTERN unsigned int *__pmPDUCntOut; +extern void __pmSetPDUCntBuf(unsigned *, unsigned *); + +/* timeout options for PDU handling */ +#define TIMEOUT_NEVER 0 +#define TIMEOUT_DEFAULT -1 +/*#define TIMEOUT_ASYNC -2*/ +#define TIMEOUT_CONNECT -3 + +/* mode options for __pmGetPDU */ +#define ANY_SIZE 0 /* replacement for old PDU_BINARY */ +#define LIMIT_SIZE 2 /* replacement for old PDU_CLIENT */ + +extern __pmPDU *__pmFindPDUBuf(int); +extern void __pmPinPDUBuf(void *); +extern int __pmUnpinPDUBuf(void *); +extern void __pmCountPDUBuf(int, int *, int *); + +#define PDU_START 0x7000 +#define PDU_ERROR 0x7000 +#define PDU_RESULT 0x7001 +#define PDU_PROFILE 0x7002 +#define PDU_FETCH 0x7003 +#define PDU_DESC_REQ 0x7004 +#define PDU_DESC 0x7005 +#define PDU_INSTANCE_REQ 0x7006 +#define PDU_INSTANCE 0x7007 +#define PDU_TEXT_REQ 0x7008 +#define PDU_TEXT 0x7009 +#define PDU_CONTROL_REQ 0x700a +#define PDU_CREDS 0x700c +#define PDU_PMNS_IDS 0x700d +#define PDU_PMNS_NAMES 0x700e +#define PDU_PMNS_CHILD 0x700f +#define PDU_PMNS_TRAVERSE 0x7010 +#define PDU_AUTH 0x7011 +#define PDU_FINISH 0x7011 +#define PDU_MAX (PDU_FINISH - PDU_START) + +/* + * Unit of space allocation for PDU buffer. + */ +#define PDU_CHUNK 1024 + +/* + * PDU encoding formats + * These have been retired ... + * #define PDU_BINARY 0 + * #define PDU_ASCII 1 + * And this has been replaced by LIMIT_SIZE for __pmGetPDU + * #define PDU_CLIENT 2 + */ + +/* + * Anonymous PDU sender, when context does not matter, e.g. PDUs from + * a PMDA sent to PMCD + */ +#define FROM_ANON 0 + +extern int __pmSendError(int, int, int); +extern int __pmDecodeError(__pmPDU *, int *); +extern int __pmSendXtendError(int, int, int, int); +extern int __pmDecodeXtendError(__pmPDU *, int *, int *); +extern int __pmSendResult(int, int, const pmResult *); +extern int __pmEncodeResult(int, const pmResult *, __pmPDU **); +extern int __pmDecodeResult(__pmPDU *, pmResult **); +extern int __pmSendProfile(int, int, int, __pmProfile *); +extern int __pmDecodeProfile(__pmPDU *, int *, __pmProfile **); +extern int __pmSendFetch(int, int, int, __pmTimeval *, int, pmID *); +extern int __pmDecodeFetch(__pmPDU *, int *, __pmTimeval *, int *, pmID **); +extern int __pmSendDescReq(int, int, pmID); +extern int __pmDecodeDescReq(__pmPDU *, pmID *); +extern int __pmSendDesc(int, int, pmDesc *); +extern int __pmDecodeDesc(__pmPDU *, pmDesc *); +extern int __pmSendInstanceReq(int, int, const __pmTimeval *, pmInDom, int, const char *); +extern int __pmDecodeInstanceReq(__pmPDU *, __pmTimeval *, pmInDom *, int *, char **); +extern int __pmSendInstance(int, int, __pmInResult *); +extern int __pmDecodeInstance(__pmPDU *, __pmInResult **); +extern int __pmSendTextReq(int, int, int, int); +extern int __pmDecodeTextReq(__pmPDU *, int *, int *); +extern int __pmSendText(int, int, int, const char *); +extern int __pmDecodeText(__pmPDU *, int *, char **); +extern int __pmSendCreds(int, int, int, const __pmCred *); +extern int __pmDecodeCreds(__pmPDU *, int *, int *, __pmCred **); +extern int __pmSendIDList(int, int, int, const pmID *, int); +extern int __pmDecodeIDList(__pmPDU *, int, pmID *, int *); +extern int __pmSendNameList(int, int, int, char **, const int *); +extern int __pmDecodeNameList(__pmPDU *, int *, char ***, int **); +extern int __pmSendChildReq(int, int, const char *, int); +extern int __pmDecodeChildReq(__pmPDU *, char **, int *); +extern int __pmSendTraversePMNSReq(int, int, const char *); +extern int __pmDecodeTraversePMNSReq(__pmPDU *, char **); +extern int __pmSendAuth(int, int, int, const char *, int); +extern int __pmDecodeAuth(__pmPDU *, int *, char **, int *); + +#if defined(HAVE_64BIT_LONG) + +/* + * A pmValue contains the union of a 32-bit int and a pointer. In the world + * of 64-bit pointers, a pmValue is therefore larger than in the 32-bit world. + * The structures below are used in all PDUs containing pmResults to ensure + * 32-bit and 64-bit programs exchanging PDUs can communicate. + * Note that a pmValue can only hold a 32-bit value in situ regardless of + * whether the pointer size is 32 or 64 bits. + */ + +typedef struct { + int inst; /* instance identifier */ + union { + unsigned int pval; /* offset into PDU buffer for value */ + int lval; /* 32-bit value in situ */ + } value; +} __pmValue_PDU; + +typedef struct { + pmID pmid; /* metric identifier */ + int numval; /* number of values */ + int valfmt; /* value style */ + __pmValue_PDU vlist[1]; /* set of instances/values */ +} __pmValueSet_PDU; + +#elif defined(HAVE_32BIT_LONG) + +/* In the 32-bit world, structures may be used in PDUs as defined */ + +typedef pmValue __pmValue_PDU; +typedef pmValueSet __pmValueSet_PDU; + +#else +bozo - unknown size of long !!! +#endif + +/* + * For the help text PDUs, the type (PM_TEXT_ONELINE or PM_TEXT_HELP) + * is 'or'd with the following to encode the request for a PMID or + * a pmInDom ... + * Note the values must therefore be (a) bit fields and (b) different + * to the public macros PM_TEXT_* in pmapi.h + */ +#define PM_TEXT_PMID 4 +#define PM_TEXT_INDOM 8 + +/* + * no mem today, my love has gone away .... + */ +extern void __pmNoMem(const char *, size_t, int); +#define PM_FATAL_ERR 1 +#define PM_RECOV_ERR 0 + +/* + * Startup handling: + * set program name, as used in __pmNotifyErr() ... default is "pcp" + * set default user for __pmSetProcessIdentity() ... default is "pcp" + */ +EXTERN char *pmProgname; +extern int __pmSetProgname(const char *); +extern int __pmGetUsername(char **); + +/* + * Cleanup handling: + * shutdown various components in libpcp, releasing all resources + * (local context PMDAs, any global NSS socket state, etc). + */ +extern int __pmShutdown(void); + +/* + * Map platform error values to PMAPI error codes. + */ +extern int __pmMapErrno(int); + +/* + * __pmLogInDom is used to hold the instance identifiers for an instance + * domain internally ... if multiple sets are observed over time, these + * are linked together in reverse chronological order + * -- externally we write these as + * timestamp + * indom <- note, added wrt indom_t + * numinst + * inst[0], .... inst[numinst-1] + * nameindex[0] .... nameindex[numinst-1] + * string (name) table, all null-byte terminated + * + * NOTE: 3 types of allocation + * (1) + * buf is NULL, + * namelist and instlist have been allocated + * separately and so must each be freed. + * (2) + * buf is NOT NULL, allinbuf == 1, + * all allocations were in the buffer and so only + * the buffer should be freed, + * (3) + * buf is NOT NULL, allinbuf == 0, + * as well as buffer allocation, + * the namelist has been allocated separately and so + * both the buf and namelist should be freed. + */ +typedef struct _indom_t { + struct _indom_t *next; + __pmTimeval stamp; + int numinst; + int *instlist; + char **namelist; + int *buf; + int allinbuf; +} __pmLogInDom; + +/* + * record header in the metadata log file ... len (by itself) also is + * used as a trailer + */ +typedef struct { + int len; /* record length, includes header and trailer */ + int type; /* see TYPE_* #defines below */ +} __pmLogHdr; + +#define TYPE_DESC 1 /* header, pmDesc, trailer */ +#define TYPE_INDOM 2 /* header, __pmLogInDom, trailer */ + +extern void __pmLogPutIndex(const __pmLogCtl *, const __pmTimeval *); + +extern const char *__pmLogName_r(const char *, int, char *, int); +extern const char *__pmLogName(const char *, int); /* NOT thread-safe */ +extern FILE *__pmLogNewFile(const char *, int); +extern int __pmLogCreate(const char *, const char *, int, __pmLogCtl *); +#define PMLOGREAD_NEXT 0 +#define PMLOGREAD_TO_EOF 1 +extern int __pmLogRead(__pmLogCtl *, int, FILE *, pmResult **, int); +extern int __pmLogWriteLabel(FILE *, const __pmLogLabel *); +extern int __pmLogOpen(const char *, __pmContext *); +extern int __pmLogLoadLabel(__pmLogCtl *, const char *); +extern int __pmLogLoadIndex(__pmLogCtl *); +extern int __pmLogLoadMeta(__pmLogCtl *); +extern void __pmLogClose(__pmLogCtl *); +extern void __pmLogCacheClear(FILE *); + +extern int __pmLogPutDesc(__pmLogCtl *, const pmDesc *, int, char **); +extern int __pmLogLookupDesc(__pmLogCtl *, pmID, pmDesc *); +extern int __pmLogPutInDom(__pmLogCtl *, pmInDom, const __pmTimeval *, int, int *, char **); +extern int __pmLogGetInDom(__pmLogCtl *, pmInDom, __pmTimeval *, int **, char ***); +extern int __pmLogLookupInDom(__pmLogCtl *, pmInDom, __pmTimeval *, const char *); +extern int __pmLogNameInDom(__pmLogCtl *, pmInDom, __pmTimeval *, int, char **); + +extern int __pmLogPutResult(__pmLogCtl *, __pmPDU *); +extern int __pmLogPutResult2(__pmLogCtl *, __pmPDU *); +extern int __pmLogFetch(__pmContext *, int, pmID *, pmResult **); +extern int __pmLogFetchInterp(__pmContext *, int, pmID *, pmResult **); +extern void __pmLogSetTime(__pmContext *); +extern void __pmLogResetInterp(__pmContext *); +extern void __pmFreeInterpData(__pmContext *); + +extern int __pmLogChangeVol(__pmLogCtl *, int); +extern int __pmLogChkLabel(__pmLogCtl *, FILE *, __pmLogLabel *, int); +extern int __pmGetArchiveEnd(__pmLogCtl *, struct timeval *); + +/* struct for maintaining information about pmlogger ports */ +typedef struct { + int pid; /* process id of logger */ + int port; /* internet port for logger control */ + char *pmcd_host; /* host pmlogger is collecting from */ + char *archive; /* archive base pathname */ + char *name; /* file name (minus dirname) */ +} __pmLogPort; + +/* Returns control port info for a pmlogger given its pid. + * If pid == PM_LOG_ALL_PIDS, get all pmloggers' control ports. + * If pid == PM_LOG_PRIMARY_PID, get primar logger's control port. + * Note: do NOT free any part of result returned via the parameter. + * + * __pmLogFindPort(const char *hostname, int pid, __pmLogPort **result); + */ +extern int __pmLogFindPort(const char *, int, __pmLogPort **); + +#define PM_LOG_PRIMARY_PID 0 /* symbolic pid for primary logger */ +#define PM_LOG_PRIMARY_PORT 0 /* symbolic port for primary pmlogger */ +#define PM_LOG_ALL_PIDS -1 /* symbolic pid for all pmloggers */ +#define PM_LOG_NO_PID -2 /* not a valid pid for pmlogger */ +#define PM_LOG_NO_PORT -2 /* not a valid port for pmlogger */ + +extern const char *__pmLogLocalSocketDefault(int, char *buf, size_t bufSize); +extern const char *__pmLogLocalSocketUser(int, char *buf, size_t bufSize); + +/* time utils */ +extern time_t __pmMktime(struct tm *); + +/* reverse ctime and time interval parsing */ +extern int __pmParseCtime(const char *, struct tm *, char **); +extern int __pmConvertTime(struct tm *, struct timeval *, struct timeval *); +extern int __pmParseTime(const char *, struct timeval *, struct timeval *, + struct timeval *, char **); + +/* manipulate internal timestamps */ +extern double __pmTimevalSub(const __pmTimeval *, const __pmTimeval *); + +/* 32-bit file checksum */ +extern __int32_t __pmCheckSum(FILE *); + +/* check for localhost */ +extern int __pmIsLocalhost(const char *); + +/* + * struct timeval manipulations + */ +extern double __pmtimevalAdd(const struct timeval *, const struct timeval *); +extern double __pmtimevalSub(const struct timeval *, const struct timeval *); +extern double __pmtimevalToReal(const struct timeval *); +extern void __pmtimevalFromReal(double, struct timeval *); +extern void __pmtimevalSleep(struct timeval); +extern void __pmtimevalPause(struct timeval); +extern void __pmtimevalNow(struct timeval *); + +typedef struct { + char *label; /* label to name tz */ + char *tz; /* env $TZ */ + int handle; /* handle from pmNewZone() */ +} pmTimeZone; + +/* + * event tracing for monitoring time between events + */ +extern void __pmEventTrace(const char *); /* NOT thread-safe */ +extern void __pmEventTrace_r(const char *, int *, double *, double *); + +/* + * More IPC protocol stuff + */ + +typedef int (*__pmConnectHostType)(int, int); + +extern int __pmSetSocketIPC(int); +extern int __pmSetVersionIPC(int, int); +extern int __pmSetDataIPC(int, void *); +extern int __pmDataIPCSize(void); +extern int __pmLastVersionIPC(void); +extern int __pmVersionIPC(int); +extern int __pmSocketIPC(int); +extern int __pmDataIPC(int, void *); +extern void __pmOverrideLastFd(int); +extern void __pmPrintIPC(void); +extern void __pmResetIPC(int); + +/* safely insert an atom value into a pmValue */ +extern int __pmStuffValue(const pmAtomValue *, pmValue *, int); + +/* + * Optimized fetch bundling ("optfetch") services + */ +typedef struct __optreq { + struct __optreq *r_next; /* next request */ + struct __fetchctl *r_fetch; /* back ptr */ + pmDesc *r_desc; /* pmDesc for request pmID */ + int r_numinst; /* request instances */ + int *r_instlist; /* request instances */ + void *r_aux; /* generic pointer to aux data */ +} optreq_t; + +typedef struct __pmidctl { + struct __pmidctl *p_next; /* next pmid control */ + optreq_t *p_rqp; /* first request for this metric */ + pmID p_pmid; /* my pmID */ + int p_numinst; /* union over requests */ + int *p_instlist; /* union over requests */ + void *p_aux; /* generic pointer to aux data */ +} pmidctl_t; + +typedef struct __indomctl { + struct __indomctl *i_next; /* next indom control */ + pmidctl_t *i_pmp; /* first metric, in this group */ + pmInDom i_indom; /* my pmInDom */ + int i_numinst; /* arg for pmAddProfile */ + int *i_instlist; /* arg for pmAddProfile */ + void *i_aux; /* generic pointer to aux data */ +} indomctl_t; + +typedef struct __fetchctl { + struct __fetchctl *f_next; /* next fetch control */ + indomctl_t *f_idp; /* first indom, in this group */ + int f_state; /* state changes during updates */ + int f_cost; /* used internally for optimization */ + int f_newcost; /* used internally for optimization */ + int f_numpmid; /* arg for pmFetch() */ + pmID *f_pmidlist; /* arg for pmFetch() */ + void *f_aux; /* generic pointer to aux data */ +} fetchctl_t; + +/* states relevant to user */ +#define OPT_STATE_NEW 1 /* newly created group */ +#define OPT_STATE_PMID 2 /* list of pmids changed */ +#define OPT_STATE_PROFILE 4 /* instance profile changed */ + +/* states used during optimization */ +#define OPT_STATE_UMASK 7 /* preserve user state bits */ +#define OPT_STATE_XREQ 8 /* things that may have changed */ +#define OPT_STATE_XPMID 16 +#define OPT_STATE_XINDOM 32 +#define OPT_STATE_XFETCH 64 +#define OPT_STATE_XPROFILE 128 + +/* + * Objective function parameters + */ +typedef struct { + int c_pmid; /* cost per PMD for PMIDs in a fetch */ + int c_indom; /* cost per PMD for indoms in a fetch */ + int c_fetch; /* cost of a new fetch group */ + int c_indomsize; /* expected numer of instances for an indom */ + int c_xtrainst; /* cost of retrieving an unwanted metric inst */ + int c_scope; /* cost opt., 0 for incremental, 1 for global */ +} optcost_t; + +#define OPT_COST_INFINITY 0x7fffffff + +extern void __pmOptFetchAdd(fetchctl_t **, optreq_t *); +extern int __pmOptFetchDel(fetchctl_t **, optreq_t *); +extern void __pmOptFetchRedo(fetchctl_t **); +extern void __pmOptFetchDump(FILE *, const fetchctl_t *); +extern void __pmOptFetchGetParams(optcost_t *); +extern void __pmOptFetchPutParams(optcost_t *); + +/* work out local timezone */ +extern char *__pmTimezone(void); /* NOT thread-safe */ +extern char *__pmTimezone_r(char *, int); + +/* + */ + +/* + * Generic access control routines + */ +extern int __pmAccAddOp(unsigned int); + +extern int __pmAccAddHost(const char *, unsigned int, unsigned int, int); +extern int __pmAccAddUser(const char *, unsigned int, unsigned int, int); +extern int __pmAccAddGroup(const char *, unsigned int, unsigned int, int); + +extern int __pmAccAddClient(__pmSockAddr *, unsigned int *); +extern int __pmAccAddAccount(const char *, const char *, unsigned int *); +extern void __pmAccDelClient(__pmSockAddr *); +extern void __pmAccDelAccount(const char *, const char *); + +extern void __pmAccDumpHosts(FILE *); +extern void __pmAccDumpUsers(FILE *); +extern void __pmAccDumpGroups(FILE *); +extern void __pmAccDumpLists(FILE *); + +extern int __pmAccSaveHosts(void); +extern int __pmAccSaveUsers(void); +extern int __pmAccSaveGroups(void); +extern int __pmAccSaveLists(void); + +extern int __pmAccRestoreHosts(void); +extern int __pmAccRestoreUsers(void); +extern int __pmAccRestoreGroups(void); +extern int __pmAccRestoreLists(void); + +extern void __pmAccFreeSavedHosts(void); +extern void __pmAccFreeSavedUsers(void); +extern void __pmAccFreeSavedGroups(void); +extern void __pmAccFreeSavedLists(void); + +/* + * platform independent process routines + */ +extern int __pmProcessExists(pid_t); +extern int __pmProcessTerminate(pid_t, int); +extern pid_t __pmProcessCreate(char **, int *, int *); +extern int __pmProcessDataSize(unsigned long *); +extern int __pmProcessRunTimes(double *, double *); +extern int __pmSetProcessIdentity(const char *); + +/* + * platform independent memory mapped file handling + */ +extern void *__pmMemoryMap(int, size_t, int); +extern void __pmMemoryUnmap(void *, size_t); + +/* + * platform independent signal handling + */ +typedef void (*__pmSignalHandler)(int); +extern int __pmSetSignalHandler(int, __pmSignalHandler); + +/* + * platform independent environment and filesystem path access + */ +typedef void (*__pmConfigCallback)(char *, char *, char *); +EXTERN const __pmConfigCallback __pmNativeConfig; +extern void __pmConfig(__pmConfigCallback); +extern char *__pmNativePath(char *); +extern int __pmAbsolutePath(char *); +extern int __pmPathSeparator(void); +extern int __pmMakePath(const char *, mode_t); + +/* + * discover configurable features of the shared libraries + */ +typedef void (*__pmAPIConfigCallback)(const char *, const char *); +extern void __pmAPIConfig(__pmAPIConfigCallback); +extern const char *__pmGetAPIConfig(const char *); + +/* + * internals of argument parsing for special circumstances + */ +extern void __pmStartOptions(pmOptions *); +extern void __pmAddOptArchive(pmOptions *, char *); +extern void __pmAddOptArchiveList(pmOptions *, char *); +extern void __pmAddOptArchiveFolio(pmOptions *, char *); +extern void __pmAddOptHost(pmOptions *, char *); +extern void __pmAddOptHostList(pmOptions *, char *); +extern void __pmEndOptions(pmOptions *); + +/* + * AF - general purpose asynchronous event management routines + */ +extern int __pmAFregister(const struct timeval *, void *, void (*)(int, void *)); +extern int __pmAFunregister(int); +extern void __pmAFblock(void); +extern void __pmAFunblock(void); +extern int __pmAFisempty(void); + +/* + * private PDU protocol between pmlc and pmlogger + */ +#define LOG_PDU_VERSION2 2 /* private pdus & PCP 2.0 error codes */ +#define LOG_PDU_VERSION LOG_PDU_VERSION2 + +#define LOG_REQUEST_NEWVOLUME 1 +#define LOG_REQUEST_STATUS 2 +#define LOG_REQUEST_SYNC 3 + +typedef struct { + __pmTimeval ls_start; /* start time for log */ + __pmTimeval ls_last; /* last time log written */ + __pmTimeval ls_timenow; /* current time */ + int ls_state; /* state of log (from __pmLogCtl) */ + int ls_vol; /* current volume number of log */ + __int64_t ls_size; /* size of current volume */ + char ls_hostname[PM_LOG_MAXHOSTLEN]; + /* name of pmcd host */ + char ls_fqdn[PM_LOG_MAXHOSTLEN]; + /* fully qualified domain name of pmcd host */ + char ls_tz[PM_TZ_MAXLEN]; + /* $TZ at collection host */ + char ls_tzlogger[PM_TZ_MAXLEN]; + /* $TZ at pmlogger */ +} __pmLoggerStatus; + +#define PDU_LOG_CONTROL 0x8000 +#define PDU_LOG_STATUS 0x8001 +#define PDU_LOG_REQUEST 0x8002 + +extern int __pmConnectLogger(const char *, int *, int *); +extern int __pmSendLogControl(int, const pmResult *, int, int, int); +extern int __pmDecodeLogControl(const __pmPDU *, pmResult **, int *, int *, int *); +extern int __pmSendLogRequest(int, int); +extern int __pmDecodeLogRequest(const __pmPDU *, int *); +extern int __pmSendLogStatus(int, __pmLoggerStatus *); +extern int __pmDecodeLogStatus(__pmPDU *, __pmLoggerStatus **); + +/* logger timeout helper function */ +extern int __pmLoggerTimeout(void); + +/* + * other interfaces shared by pmlc and pmlogger + */ + +extern int __pmControlLog(int, const pmResult *, int, int, int, pmResult **); + +#define PM_LOG_OFF 0 /* state */ +#define PM_LOG_MAYBE 1 +#define PM_LOG_ON 2 + +#define PM_LOG_MANDATORY 11 /* control */ +#define PM_LOG_ADVISORY 12 +#define PM_LOG_ENQUIRE 13 + +/* macros for logging control values from __pmControlLog() */ +#define PMLC_SET_ON(val, flag) \ + (val) = ((val) & ~0x1) | ((flag) & 0x1) +#define PMLC_GET_ON(val) \ + ((val) & 0x1) +#define PMLC_SET_MAND(val, flag) \ + (val) = ((val) & ~0x2) | (((flag) & 0x1) << 1) +#define PMLC_GET_MAND(val) \ + (((val) & 0x2) >> 1) +#define PMLC_SET_AVAIL(val, flag) \ + (val) = ((val) & ~0x4) | (((flag) & 0x1) << 2) +#define PMLC_GET_AVAIL(val) \ + (((val) & 0x4) >> 2) +#define PMLC_SET_INLOG(val, flag) \ + (val) = ((val) & ~0x8) | (((flag) & 0x1) << 3) +#define PMLC_GET_INLOG(val) \ + (((val) & 0x8) >> 3) + +#define PMLC_SET_STATE(val, state) \ + (val) = ((val) & ~0xf) | ((state) & 0xf) +#define PMLC_GET_STATE(val) \ + ((val) & 0xf) + +/* 28 bits of delta, 32 bits of state */ +#define PMLC_MAX_DELTA 0x0fffffff + +#define PMLC_SET_DELTA(val, delta) \ + (val) = ((val) & 0xf) | ((delta) << 4) +#define PMLC_GET_DELTA(val) \ + ((((val) & ~0xf) >> 4) & PMLC_MAX_DELTA) + +/* + * helper functions to register client identity with pmcd for export + * via pmcd.client.whoami + */ +extern char *__pmGetClientId(int, char **); +extern int __pmSetClientIdArgv(int, char **); +extern int __pmSetClientId(const char *); + +/* + * Adding/deleting/clearing the list of DSO PMDAs supported for + * PM_CONTEXT_LOCAL contexts + */ +#define PM_LOCAL_ADD 1 +#define PM_LOCAL_DEL 2 +#define PM_LOCAL_CLEAR 3 +extern int __pmLocalPMDA(int, int, const char *, const char *); +extern char *__pmSpecLocalPMDA(const char *); + +/* + * Helper methods for packed arrays of event records + */ +extern int __pmCheckEventRecords(pmValueSet *, int); +extern int __pmCheckHighResEventRecords(pmValueSet *, int); +extern void __pmDumpEventRecords(FILE *, pmValueSet *, int); +extern void __pmDumpHighResEventRecords(FILE *, pmValueSet *, int); + +/* Get nanosecond precision timestamp from system clocks */ +extern int __pmGetTimespec(struct timespec *); + +/* Anonymous metric registration (uses derived metrics support) */ +extern int __pmRegisterAnon(const char *, int); + +/* + * Multi-thread support + * Use PM_MULTI_THREAD_DEBUG for lock debugging with -Dlock[,appl?...] + */ +extern void __pmInitLocks(void); +extern int __pmLock(void *, const char *, int); +extern int __pmUnlock(void *, const char *, int); + +/* + * Each of these scopes defines one or more PMAPI routines that will + * not allow calls from more than one thread. + */ +#define PM_SCOPE_DSO_PMDA 0 +#define PM_SCOPE_ACL 1 +#define PM_SCOPE_AF 2 +#define PM_SCOPE_LOGPORT 3 +#define PM_SCOPE_MAX 3 +extern int __pmMultiThreaded(int); + +#define PM_INIT_LOCKS() __pmInitLocks() +#define PM_MULTIPLE_THREADS(x) __pmMultiThreaded(x) +#define PM_LOCK(lock) __pmLock(&(lock), __FILE__, __LINE__) +#define PM_UNLOCK(lock) __pmUnlock(&(lock), __FILE__, __LINE__) + +#ifdef HAVE_PTHREAD_MUTEX_T +extern pthread_mutex_t __pmLock_libpcp; /* big libpcp lock */ +#else +extern void *__pmLock_libpcp; /* symbol exposure */ +#endif + +/* + * Service discovery with options. + * The 4th argument is a pointer to a mask of flags for boolean options + * and status. It is set and tested using the following bits. + */ +#define PM_SERVICE_DISCOVERY_INTERRUPTED 0x1 +#define PM_SERVICE_DISCOVERY_RESOLVE 0x2 + +extern int __pmDiscoverServicesWithOptions(const char *, + const char *, + const char *, + const volatile unsigned *, + char ***); + + +#ifdef __cplusplus +} +#endif + +#endif /* _IMPL_H */ diff --git a/src/include/pcp/import.h b/src/include/pcp/import.h new file mode 100644 index 0000000..82b5be3 --- /dev/null +++ b/src/include/pcp/import.h @@ -0,0 +1,67 @@ +/* + * Copyright (c) 2012-2013 Red Hat. + * Copyright (c) 2010 Ken McDonell. 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 + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + */ +#ifndef _IMPORT_H +#define _IMPORT_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* core libpcp_import API routines */ +extern int pmiStart(const char *, int); +extern int pmiUseContext(int); +extern int pmiEnd(void); +extern int pmiSetHostname(const char *); +extern int pmiSetTimezone(const char *); +extern int pmiAddMetric(const char *, pmID, int, pmInDom, int, pmUnits); +extern int pmiAddInstance(pmInDom, const char *, int); +extern int pmiPutValue(const char *, const char *, const char *); +extern int pmiGetHandle(const char *, const char *); +extern int pmiPutValueHandle(int, const char *); +extern int pmiWrite(int, int); +extern int pmiPutResult(const pmResult *); + +/* helper routines */ +extern pmID pmiID(int, int, int); +extern pmInDom pmiInDom(int, int); +extern pmUnits pmiUnits(int, int, int, int, int, int); + +/* diagnostic routines */ +#define PMI_MAXERRMSGLEN 128 /* safe size to accomodate any error message */ +extern char *pmiErrStr_r(int, char *, int); +extern const char *pmiErrStr(int); /* cannot ever be made thread-safe */ +extern void pmiDump(void); + +/* libpcp_import error codes */ +#define PMI_ERR_BASE 20000 +#define PMI_ERR_DUPMETRICNAME (-PMI_ERR_BASE-1) /* Metric name already defined */ +#define PMI_ERR_DUPMETRICID (-PMI_ERR_BASE-2) /* Metric pmID already defined */ +#define PMI_ERR_DUPINSTNAME (-PMI_ERR_BASE-3) /* External instance name already defined */ +#define PMI_ERR_DUPINSTID (-PMI_ERR_BASE-4) /* Internal instance identifer already defined */ +#define PMI_ERR_INSTNOTNULL (-PMI_ERR_BASE-5) /* Non-null instance expected for a singular metric */ +#define PMI_ERR_INSTNULL (-PMI_ERR_BASE-6) /* Null instance not allowed for a non-singular metric */ +#define PMI_ERR_BADHANDLE (-PMI_ERR_BASE-7) /* Illegal handle */ +#define PMI_ERR_DUPVALUE (-PMI_ERR_BASE-8) /* Value already assigned for singular metric */ +#define PMI_ERR_BADTYPE (-PMI_ERR_BASE-9) /* Illegal metric type */ +#define PMI_ERR_BADSEM (-PMI_ERR_BASE-10) /* Illegal metric semantics */ +#define PMI_ERR_NODATA (-PMI_ERR_BASE-11) /* No data to output */ +#define PMI_ERR_BADMETRICNAME (-PMI_ERR_BASE-12) /* Illegal metric name */ +#define PMI_ERR_BADTIMESTAMP (-PMI_ERR_BASE-13) /* Illegal result timestamp */ + +#ifdef __cplusplus +} +#endif + +#endif /* _IMPORT_H */ diff --git a/src/include/pcp/mk_pmdbg b/src/include/pcp/mk_pmdbg new file mode 100755 index 0000000..a234f3b --- /dev/null +++ b/src/include/pcp/mk_pmdbg @@ -0,0 +1,58 @@ +#!/bin/sh +# +# Copyright (c) 1997 Silicon Graphics, Inc. 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 +# Free Software Foundation; either version 2 of the License, or (at your +# option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +# for more details. +# +# Create pmdbg.h from impl.h + +if [ -f ../pcp.conf ] +then + # needed for $PCP_SORT_PROG + . ../pcp.conf +else + echo "mk_pmdbg: cannot find pcp.conf" + exit 1 +fi + +if [ ! -f impl.h ] +then + echo "mk_pmdbg: cannot find impl.h" + exit 1 +fi + +rm -f pmdbg.h +cat <<End-of-File >pmdbg.h +/* + * Built from impl.h by mk_pmdbg. Any modifications will be lost. + */ + +typedef const struct { + const char *name; + const int bit; +} debug_map_t; + +static const debug_map_t debug_map[] = { +End-of-File + +sed -n <impl.h \ + -e '/#define[ ]*DBG_TRACE_/{ +s/#define[ ]*\(DBG_TRACE_\)\([A-Z0-9_]*\).*/ { "\2", \1\2 },/p +}' \ +| $PCP_SORT_PROG >>pmdbg.h + +cat <<End-of-File >>pmdbg.h +}; + +static const int num_debug = sizeof(debug_map) / sizeof(debug_map[0]); +End-of-File + +exit 0 diff --git a/src/include/pcp/mmv_dev.h b/src/include/pcp/mmv_dev.h new file mode 100644 index 0000000..92e3b8e --- /dev/null +++ b/src/include/pcp/mmv_dev.h @@ -0,0 +1,84 @@ +/* + * Copyright (C) 2001,2009 Silicon Graphics, Inc. All Rights Reserved. + * Copyright (C) 2009 Aconex. All Rights Reserved. + * + * This library 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 + * (at your option) any later version. + * + * This library 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 Lesser General Public + * License for more details. + */ +#ifndef _MMV_DEV_H +#define _MMV_DEV_H + +#define MMV_VERSION 1 + +typedef enum { + MMV_TOC_INDOMS = 1, /* mmv_disk_indom_t */ + MMV_TOC_INSTANCES = 2, /* mmv_disk_instance_t */ + MMV_TOC_METRICS = 3, /* mmv_disk_metric_t */ + MMV_TOC_VALUES = 4, /* mmv_disk_value_t */ + MMV_TOC_STRINGS = 5, /* mmv_disk_string_t */ +} mmv_toc_type_t; + +/* The way the Table Of Contents is written into the file */ +typedef struct { + mmv_toc_type_t type; /* What is it? */ + __int32_t count; /* Number of entries */ + __uint64_t offset; /* Offset of section from file start */ +} mmv_disk_toc_t; + +typedef struct { + __uint32_t serial; /* Unique identifier */ + __uint32_t count; /* Number of instances */ + __uint64_t offset; /* Offset of first instance */ + __uint64_t shorttext; /* Offset of short help text string */ + __uint64_t helptext; /* Offset of long help text string */ +} mmv_disk_indom_t; + +typedef struct { + __uint64_t indom; /* Offset into files indom section */ + __uint32_t padding; /* zero filled, alignment bits */ + __int32_t internal; /* Internal instance ID */ + char external[MMV_NAMEMAX]; /* External instance ID */ +} mmv_disk_instance_t; + +typedef struct { + char payload[MMV_STRINGMAX]; /* NULL terminated string */ +} mmv_disk_string_t; + +typedef struct { + char name[MMV_NAMEMAX]; + __uint32_t item; /* Unique identifier */ + mmv_metric_type_t type; + mmv_metric_sem_t semantics; + pmUnits dimension; + __int32_t indom; /* Instance domain number */ + __uint32_t padding; /* zero filled, alignment bits */ + __uint64_t shorttext; /* Offset of short help text string */ + __uint64_t helptext; /* Offset of long help text string */ +} mmv_disk_metric_t; + +typedef struct { + pmAtomValue value; /* Union of all possible value types */ + __int64_t extra; /* INTEGRAL(starttime)/STRING(offset) */ + __uint64_t metric; /* Offset into the metric section */ + __uint64_t instance; /* Offset into the instance section */ +} mmv_disk_value_t; + +typedef struct { + char magic[4]; /* MMV\0 */ + __int32_t version; /* version */ + __uint64_t g1; /* Generation numbers */ + __uint64_t g2; + __int32_t tocs; /* Number of toc entries */ + mmv_stats_flags_t flags; + __int32_t process; /* client process identifier (flags) */ + __int32_t cluster; /* preferred PMDA cluster identifier */ +} mmv_disk_header_t; + +#endif /* _MMV_DEV_H */ diff --git a/src/include/pcp/mmv_stats.h b/src/include/pcp/mmv_stats.h new file mode 100644 index 0000000..12f53d7 --- /dev/null +++ b/src/include/pcp/mmv_stats.h @@ -0,0 +1,108 @@ +/* + * Copyright (C) 2013 Red Hat. + * Copyright (C) 2009 Aconex. All Rights Reserved. + * Copyright (C) 2001,2009 Silicon Graphics, Inc. All Rights Reserved. + * + * This library 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 + * (at your option) any later version. + * + * This library 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 Lesser General Public + * License for more details. + */ +#ifndef _MMV_STATS_H +#define _MMV_STATS_H + +#ifdef __cplusplus +extern "C" { +#endif + +#define MMV_NAMEMAX 64 +#define MMV_STRINGMAX 256 + +typedef enum mmv_metric_type { + MMV_TYPE_NOSUPPORT = PM_TYPE_NOSUPPORT, + MMV_TYPE_I32 = PM_TYPE_32, /* 32-bit signed integer */ + MMV_TYPE_U32 = PM_TYPE_U32, /* 32-bit unsigned integer */ + MMV_TYPE_I64 = PM_TYPE_64, /* 64-bit signed integer */ + MMV_TYPE_U64 = PM_TYPE_U64, /* 64-bit unsigned integer */ + MMV_TYPE_FLOAT = PM_TYPE_FLOAT, /* 32-bit floating point */ + MMV_TYPE_DOUBLE = PM_TYPE_DOUBLE,/* 64-bit floating point */ + MMV_TYPE_STRING = PM_TYPE_STRING,/* NULL-terminate string */ + MMV_TYPE_ELAPSED = 9, /* 64-bit elapsed time */ +} mmv_metric_type_t; + +typedef enum mmv_metric_sem { + MMV_SEM_COUNTER = PM_SEM_COUNTER, + MMV_SEM_INSTANT = PM_SEM_INSTANT, + MMV_SEM_DISCRETE = PM_SEM_DISCRETE, +} mmv_metric_sem_t; + +typedef struct mmv_instances { + __int32_t internal; /* Internal instance ID */ + char external[MMV_NAMEMAX]; /* External instance ID */ +} mmv_instances_t; + +typedef struct mmv_indom { + __uint32_t serial; /* Unique identifier */ + __uint32_t count; /* Number of instances */ + mmv_instances_t * instances; /* Internal/external IDs */ + char * shorttext; /* Short help text string */ + char * helptext; /* Long help text string */ +} mmv_indom_t; + +typedef struct mmv_metric { + char name[MMV_NAMEMAX]; + __uint32_t item; /* Unique identifier */ + mmv_metric_type_t type; + mmv_metric_sem_t semantics; + pmUnits dimension; + __uint32_t indom; /* Indom serial */ + char * shorttext; /* Short help text string */ + char * helptext; /* Long help text string */ +} mmv_metric_t; + +#ifdef HAVE_BITFIELDS_LTOR +#define MMV_UNITS(a,b,c,d,e,f) {a,b,c,d,e,f,0} +#else +#define MMV_UNITS(a,b,c,d,e,f) {0,f,e,d,c,b,a} +#endif + +typedef enum mmv_stats_flags { + MMV_FLAG_NOPREFIX = 0x1, /* Don't prefix metric names by filename */ + MMV_FLAG_PROCESS = 0x2, /* Indicates process check on PID needed */ +} mmv_stats_flags_t; + +extern void * mmv_stats_init(const char *, int, mmv_stats_flags_t, + const mmv_metric_t *, int, + const mmv_indom_t *, int); +extern void mmv_stats_stop(const char *, void *); + +extern pmAtomValue * mmv_lookup_value_desc(void *, const char *, const char *); +extern void mmv_inc_value(void *, pmAtomValue *, double); +extern void mmv_set_value(void *, pmAtomValue *, double); +extern void mmv_set_string(void *, pmAtomValue *, const char *, int); + +extern void mmv_stats_add(void *, const char *, const char *, double); +extern void mmv_stats_inc(void *, const char *, const char *); +extern void mmv_stats_set(void *, const char *, const char *, double); +extern void mmv_stats_add_fallback(void *, const char *, const char *, + const char *, double); +extern void mmv_stats_inc_fallback(void *, const char *, const char *, + const char *); +extern pmAtomValue * mmv_stats_interval_start(void *, pmAtomValue *, + const char *, const char *); +extern void mmv_stats_interval_end(void *, pmAtomValue *); +extern void mmv_stats_set_string(void *, const char *, + const char *, const char *); +extern void mmv_stats_set_strlen(void *, const char *, + const char *, const char *, size_t); + +#ifdef __cplusplus +} +#endif + +#endif /* _MMV_STATS_H */ diff --git a/src/include/pcp/platform_defs.h.in b/src/include/pcp/platform_defs.h.in new file mode 100644 index 0000000..091657e --- /dev/null +++ b/src/include/pcp/platform_defs.h.in @@ -0,0 +1,13 @@ +/* + * @configure_input@ + */ +#ifndef _PCP_PLATFORM_DEFS_H +#define _PCP_PLATFORM_DEFS_H + +#include "config.h" + +/* printf candy ... */ +#define FMT_PID @fmt_pid@ +#define FMT_PTHREAD @fmt_pthread@ + +#endif /* _PCP_PLATFORM_DEFS_H */ diff --git a/src/include/pcp/pmafm.h b/src/include/pcp/pmafm.h new file mode 100644 index 0000000..d1330e5 --- /dev/null +++ b/src/include/pcp/pmafm.h @@ -0,0 +1,47 @@ +/* + * Copyright (c) 1997 Silicon Graphics, Inc. All Rights Reserved. + * + * This library 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 + * (at your option) any later version. + * + * This library 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 Lesser General Public + * License for more details. + */ + +#ifndef _PMAFM_H +#define _PMAFM_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* + * Recording session support + */ +#define PM_REC_ON 40 +#define PM_REC_OFF 41 +#define PM_REC_DETACH 43 +#define PM_REC_STATUS 44 +#define PM_REC_SETARG 45 + +typedef struct { + FILE *f_config; /* caller writes pmlogger configuration here */ + int fd_ipc; /* IPC channel to pmlogger */ + char *logfile; /* full pathname for pmlogger error logfile */ + pid_t pid; /* process id for pmlogger */ + int status; /* exit status, -1 if unknown */ +} pmRecordHost; + +extern FILE *pmRecordSetup(const char *, const char *, int); +extern int pmRecordAddHost(const char *, int, pmRecordHost **); +extern int pmRecordControl(pmRecordHost *, int, const char *); + +#ifdef __cplusplus +} +#endif + +#endif /* _PMAFM_H */ diff --git a/src/include/pcp/pmapi.h b/src/include/pcp/pmapi.h new file mode 100644 index 0000000..be4b45e --- /dev/null +++ b/src/include/pcp/pmapi.h @@ -0,0 +1,884 @@ +/* + * Copyright (c) 2012-2014 Red Hat. + * Copyright (c) 1997,2004 Silicon Graphics, Inc. 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 + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + */ + +#ifndef _PMAPI_H +#define _PMAPI_H + +#include <stdlib.h> +#include <stdio.h> +#include <errno.h> +#include <unistd.h> +#include <string.h> +#include <sys/types.h> +#include <sys/param.h> +#include <sys/time.h> + +/* + * Platform and environment customization + */ +#include "platform_defs.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define PMAPI_VERSION_2 2 +#define PMAPI_VERSION PMAPI_VERSION_2 + +/* + * -------- Naming Services -------- + */ +typedef unsigned int pmID; /* Metric Identifier */ +#define PM_ID_NULL 0xffffffff + +typedef unsigned int pmInDom; /* Instance-Domain */ +#define PM_INDOM_NULL 0xffffffff +#define PM_IN_NULL 0xffffffff + +#define PM_NS_DEFAULT NULL /* default name */ + +/* + * Encoding for the units (dimensions Time and Space) and scale + * for Performance Metric Values + * + * For example, a pmUnits struct of + * { 1, -1, 0, PM_SPACE_MBYTE, PM_TIME_SEC, 0 } + * represents Mbytes/sec, while + * { 0, 1, -1, 0, PM_TIME_HOUR, 6 } + * represents hours/million-events + */ +typedef struct { +#ifdef HAVE_BITFIELDS_LTOR + signed int dimSpace : 4; /* space dimension */ + signed int dimTime : 4; /* time dimension */ + signed int dimCount : 4; /* event dimension */ + unsigned int scaleSpace : 4; /* one of PM_SPACE_* below */ + unsigned int scaleTime : 4; /* one of PM_TIME_* below */ + signed int scaleCount : 4; /* one of PM_COUNT_* below */ + unsigned int pad : 8; +#else + unsigned int pad : 8; + signed int scaleCount : 4; /* one of PM_COUNT_* below */ + unsigned int scaleTime : 4; /* one of PM_TIME_* below */ + unsigned int scaleSpace : 4; /* one of PM_SPACE_* below */ + signed int dimCount : 4; /* event dimension */ + signed int dimTime : 4; /* time dimension */ + signed int dimSpace : 4; /* space dimension */ +#endif +} pmUnits; /* dimensional units and scale of value */ + +/* pmUnits.scaleSpace */ +#define PM_SPACE_BYTE 0 /* bytes */ +#define PM_SPACE_KBYTE 1 /* Kilobytes (1024) */ +#define PM_SPACE_MBYTE 2 /* Megabytes (1024^2) */ +#define PM_SPACE_GBYTE 3 /* Gigabytes (1024^3) */ +#define PM_SPACE_TBYTE 4 /* Terabytes (1024^4) */ +#define PM_SPACE_PBYTE 5 /* Petabytes (1024^5) */ +#define PM_SPACE_EBYTE 6 /* Exabytes (1024^6) */ +/* pmUnits.scaleTime */ +#define PM_TIME_NSEC 0 /* nanoseconds */ +#define PM_TIME_USEC 1 /* microseconds */ +#define PM_TIME_MSEC 2 /* milliseconds */ +#define PM_TIME_SEC 3 /* seconds */ +#define PM_TIME_MIN 4 /* minutes */ +#define PM_TIME_HOUR 5 /* hours */ +/* + * pmUnits.scaleCount (e.g. count events, syscalls, interrupts, etc.) + * -- these are simply powers of 10, and not enumerated here, + * e.g. 6 for 10^6, or -3 for 10^-3 + */ +#define PM_COUNT_ONE 0 /* 1 */ + +/* Performance Metric Descriptor */ +typedef struct { + pmID pmid; /* unique identifier */ + int type; /* base data type (see below) */ + pmInDom indom; /* instance domain */ + int sem; /* semantics of value (see below) */ + pmUnits units; /* dimension and units */ +} pmDesc; + +/* pmDesc.type -- data type of metric values */ +#define PM_TYPE_NOSUPPORT -1 /* not implemented in this version */ +#define PM_TYPE_32 0 /* 32-bit signed integer */ +#define PM_TYPE_U32 1 /* 32-bit unsigned integer */ +#define PM_TYPE_64 2 /* 64-bit signed integer */ +#define PM_TYPE_U64 3 /* 64-bit unsigned integer */ +#define PM_TYPE_FLOAT 4 /* 32-bit floating point */ +#define PM_TYPE_DOUBLE 5 /* 64-bit floating point */ +#define PM_TYPE_STRING 6 /* array of char */ +#define PM_TYPE_AGGREGATE 7 /* arbitrary binary data (aggregate) */ +#define PM_TYPE_AGGREGATE_STATIC 8 /* static pointer to aggregate */ +#define PM_TYPE_EVENT 9 /* packed pmEventArray */ +#define PM_TYPE_HIGHRES_EVENT 10 /* packed pmHighResEventArray */ +#define PM_TYPE_UNKNOWN 255 /* used in pmValueBlock, not pmDesc */ + +/* pmDesc.sem -- semantics/interpretation of metric values */ +#define PM_SEM_COUNTER 1 /* cumulative counter (monotonic increasing) */ + /* was PM_SEM_RATE, no longer used now */ +#define PM_SEM_INSTANT 3 /* instantaneous value, continuous domain */ +#define PM_SEM_DISCRETE 4 /* instantaneous value, discrete domain */ + +#define PM_ERR_BASE2 12345 +#define PM_ERR_BASE PM_ERR_BASE2 + +/* PMAPI Error Conditions */ + +#define PM_ERR_GENERIC (-PM_ERR_BASE-0) /* Generic error, already reported above */ +#define PM_ERR_PMNS (-PM_ERR_BASE-1) /* Problems parsing PMNS definitions */ +#define PM_ERR_NOPMNS (-PM_ERR_BASE-2) /* PMNS not accessible */ +#define PM_ERR_DUPPMNS (-PM_ERR_BASE-3) /* Attempt to reload the PMNS */ +#define PM_ERR_TEXT (-PM_ERR_BASE-4) /* Oneline or help text is not available */ +#define PM_ERR_APPVERSION (-PM_ERR_BASE-5) /* Metric not supported by this version of monitored application */ +#define PM_ERR_VALUE (-PM_ERR_BASE-6) /* Missing metric value(s) */ +/* retired PM_ERR_LICENSE (-PM_ERR_BASE-7) Current PCP license does not permit this operation */ +#define PM_ERR_TIMEOUT (-PM_ERR_BASE-8) /* Timeout waiting for a response from PMCD */ +#define PM_ERR_NODATA (-PM_ERR_BASE-9) /* Empty archive log file */ +#define PM_ERR_RESET (-PM_ERR_BASE-10) /* pmcd reset or configuration changed */ +/* retired PM_ERR_FILE (-PM_ERR_BASE-11) Cannot locate a file */ +#define PM_ERR_NAME (-PM_ERR_BASE-12) /* Unknown metric name */ +#define PM_ERR_PMID (-PM_ERR_BASE-13) /* Unknown or illegal metric identifier */ +#define PM_ERR_INDOM (-PM_ERR_BASE-14) /* Unknown or illegal instance domain identifier */ +#define PM_ERR_INST (-PM_ERR_BASE-15) /* Unknown or illegal instance identifier */ +#define PM_ERR_UNIT (-PM_ERR_BASE-16) /* Illegal pmUnits specification */ +#define PM_ERR_CONV (-PM_ERR_BASE-17) /* Impossible value or scale conversion */ +#define PM_ERR_TRUNC (-PM_ERR_BASE-18) /* Truncation in value conversion */ +#define PM_ERR_SIGN (-PM_ERR_BASE-19) /* Negative value in conversion to unsigned */ +#define PM_ERR_PROFILE (-PM_ERR_BASE-20) /* Explicit instance identifier(s) required */ +#define PM_ERR_IPC (-PM_ERR_BASE-21) /* IPC protocol failure */ +/* retired PM_ERR_NOASCII (-PM_ERR_BASE-22) ASCII format not supported for this PDU */ +#define PM_ERR_EOF (-PM_ERR_BASE-23) /* IPC channel closed */ +#define PM_ERR_NOTHOST (-PM_ERR_BASE-24) /* Operation requires context with host source of metrics */ +#define PM_ERR_EOL (-PM_ERR_BASE-25) /* End of PCP archive log */ +#define PM_ERR_MODE (-PM_ERR_BASE-26) /* Illegal mode specification */ +#define PM_ERR_LABEL (-PM_ERR_BASE-27) /* Illegal label record at start of a PCP archive log file */ +#define PM_ERR_LOGREC (-PM_ERR_BASE-28) /* Corrupted record in a PCP archive log */ +#define PM_ERR_NOTARCHIVE (-PM_ERR_BASE-29) /* Operation requires context with archive source of metrics */ +#define PM_ERR_LOGFILE (-PM_ERR_BASE-30) /* Missing archive file */ +#define PM_ERR_NOCONTEXT (-PM_ERR_BASE-31) /* Attempt to use an illegal context */ +#define PM_ERR_PROFILESPEC (-PM_ERR_BASE-32) /* NULL pmInDom with non-NULL instlist */ +#define PM_ERR_PMID_LOG (-PM_ERR_BASE-33) /* Metric not defined in the PCP archive log */ +#define PM_ERR_INDOM_LOG (-PM_ERR_BASE-34) /* Instance domain identifier not defined in the PCP archive log */ +#define PM_ERR_INST_LOG (-PM_ERR_BASE-35) /* Instance identifier not defined in the PCP archive log */ +#define PM_ERR_NOPROFILE (-PM_ERR_BASE-36) /* Missing profile - protocol botch */ +#define PM_ERR_NOAGENT (-PM_ERR_BASE-41) /* No pmcd agent for domain of request */ +#define PM_ERR_PERMISSION (-PM_ERR_BASE-42) /* No permission to perform requested operation */ +#define PM_ERR_CONNLIMIT (-PM_ERR_BASE-43) /* PMCD connection limit for this host exceeded */ +#define PM_ERR_AGAIN (-PM_ERR_BASE-44) /* try again. Info not currently available */ +#define PM_ERR_ISCONN (-PM_ERR_BASE-45) /* already connected */ +#define PM_ERR_NOTCONN (-PM_ERR_BASE-46) /* not connected */ +#define PM_ERR_NEEDPORT (-PM_ERR_BASE-47) /* port name required */ +/* retired PM_ERR_WANTACK (-PM_ERR_BASE-48) can not send due to pending acks */ +#define PM_ERR_NONLEAF (-PM_ERR_BASE-49) /* PMNS node is not a leaf node */ +/* retired PM_ERR_OBJSTYLE (-PM_ERR_BASE-50) user/kernel object style mismatch */ +/* retired PM_ERR_PMCDLICENSE (-PM_ERR_BASE-51) PMCD is not licensed to accept connections */ +#define PM_ERR_TYPE (-PM_ERR_BASE-52) /* Unknown or illegal metric type */ +#define PM_ERR_THREAD (-PM_ERR_BASE-53) /* Operation not supported for multi-threaded applications */ + +/* retired PM_ERR_CTXBUSY (-PM_ERR_BASE-97) Context is busy */ +#define PM_ERR_TOOSMALL (-PM_ERR_BASE-98) /* Insufficient elements in list */ +#define PM_ERR_TOOBIG (-PM_ERR_BASE-99) /* Result size exceeded */ +#define PM_ERR_FAULT (-PM_ERR_BASE-100) /* QA fault injected */ + +#define PM_ERR_PMDAREADY (-PM_ERR_BASE-1048) /* now ready to respond */ +#define PM_ERR_PMDANOTREADY (-PM_ERR_BASE-1049) /* not yet ready to respond */ +#define PM_ERR_NYI (-PM_ERR_BASE-8999) /* Functionality not yet implemented [end-of-range mark] */ + +/* + * Report PMAPI errors messages + */ +extern char *pmErrStr(int); /* NOT thread-safe */ +extern char *pmErrStr_r(int, char *, int); +/* safe size for a pmErrStr_r buffer to accommodate all error messages */ +#define PM_MAXERRMSGLEN 128 + +/* + * Load a Performance Metrics Name Space + */ +extern int pmLoadNameSpace(const char *); +extern int pmLoadASCIINameSpace(const char *, int); +extern void pmUnloadNameSpace(void); + +/* + * Where is PMNS located - added for distributed PMNS. + */ +extern int pmGetPMNSLocation(void); +#define PMNS_LOCAL 1 +#define PMNS_REMOTE 2 +#define PMNS_ARCHIVE 3 + +/* + * Trim a name space with respect to the current context + * (usually from an archive, or after processing an archive) + */ +extern int pmTrimNameSpace(void); + +/* + * Expand a list of names to a list of metrics ids + */ +extern int pmLookupName(int, char **, pmID *); + +/* + * Find the names of descendent nodes in the PMNS + * and in the latter case get the status of each child. + */ +extern int pmGetChildren(const char *, char ***); +extern int pmGetChildrenStatus(const char *, char ***, int **); +#define PMNS_LEAF_STATUS 0 /* leaf node in PMNS tree */ +#define PMNS_NONLEAF_STATUS 1 /* non-terminal node in PMNS tree */ + +/* + * Reverse Lookup: find name(s) given a metric id + */ +extern int pmNameID(pmID, char **); /* one */ +extern int pmNameAll(pmID, char ***); /* all */ + +/* + * Handy recursive descent of the PMNS + */ +extern int pmTraversePMNS(const char *, void(*)(const char *)); +extern int pmTraversePMNS_r(const char *, void(*)(const char *, void *), void *); + +/* + * Given a metric, find it's descriptor (caller supplies buffer for desc), + * from the current context. + */ +extern int pmLookupDesc(pmID, pmDesc *); + +/* + * Return the internal instance identifier, from the current context, + * given an instance domain and the external instance name. + * Archive variant scans the union of the indom entries in the archive + * log. + */ +extern int pmLookupInDom(pmInDom, const char *); +extern int pmLookupInDomArchive(pmInDom, const char *); + +/* + * Return the external instance name, from the current context, + * given an instance domain and the internal instance identifier. + * Archive variant scans the union of the indom entries in the archive + * log. + */ +extern int pmNameInDom(pmInDom, int, char **); +extern int pmNameInDomArchive(pmInDom, int, char **); + +/* + * Return all of the internal instance identifiers (instlist) and external + * instance names (namelist) for the given instance domain in the current + * context. + * Archive variant returns the union of the indom entries in the archive + * log. + */ +extern int pmGetInDom(pmInDom, int **, char ***); +extern int pmGetInDomArchive(pmInDom, int **, char ***); + +/* + * Given context ID, return the host name associated with that context, + * or the empty string if no name can be found + */ +extern const char *pmGetContextHostName(int); +extern char *pmGetContextHostName_r(int, char *, int); + +/* + * Return the handle of the current context + */ +extern int pmWhichContext(void); + +/* + * Destroy a context and close its connection + */ +extern int pmDestroyContext(int); + +/* + * Establish a new context (source of performance data + instance profile) + * for the named host + */ +extern int pmNewContext(int, const char *); +#define PM_CONTEXT_UNDEF -1 /* current context is undefined */ +#define PM_CONTEXT_HOST 1 /* host via pmcd */ +#define PM_CONTEXT_ARCHIVE 2 /* PCP archive */ +#define PM_CONTEXT_LOCAL 3 /* local host, no pmcd connection */ +#define PM_CONTEXT_TYPEMASK 0xff /* mask to separate types / flags */ +/* #define PM_CTXFLAG_SHALLOW (1U<<8) -- don't actually connect to host */ +/* #define PM_CTXFLAG_EXCLUSIVE (1U<<9) -- don't share socket among ctxts */ +#define PM_CTXFLAG_SECURE (1U<<10)/* encrypted socket comms channel */ +#define PM_CTXFLAG_COMPRESS (1U<<11)/* compressed socket host channel */ +#define PM_CTXFLAG_RELAXED (1U<<12)/* encrypted if possible else not */ +#define PM_CTXFLAG_AUTH (1U<<13)/* make authenticated connection */ + +/* + * Duplicate current context -- returns handle to new one for pmUseContext() + */ +extern int pmDupContext(void); + +/* + * Restore (previously established or duplicated) context + */ +extern int pmUseContext(int); + +/* + * Reconnect an existing context (when pmcd dies, etc). All existing context + * settings are preserved and the previous context settings are restored. + */ +extern int pmReconnectContext(int); + +/* + * Add to instance profile. + * If pmInDom == PM_INDOM_NULL, then all instance domains are selected. + * If no inst parameters are given, then all instances are selected. + * e.g. to select all available instances in all domains, + * then use pmAddProfile(PM_INDOM_NULL, 0, NULL). + */ +extern int pmAddProfile(pmInDom, int, int *); + +/* + * Delete from instance profile. + * Similar (but negated) functional semantics to pmProfileAdd. + * E.g. to disable all instances in all domains then use + * pmDelProfile(PM_INDOM_NULL, 0, NULL). + */ +extern int pmDelProfile(pmInDom, int, int *); + +/* + * ---------- Collection services ---------- + * + * Result from pmFetch is encoded as a timestamp and vector of pointers + * to pmValueSet instances (one per PMID in the result). + * Each pmValueSet has a PMID, a value count, a value format, and a vector of + * instance-value pairs. Aggregate, string and non-int values are returned + * via one further level of indirection using pmValueBlocks. + * + * timeStamp + * ->pmID + * value format + * instance, value + * instance, value + * ... etc + * + * ->pmID + * value format + * instance, value + * ... etc + * + * + * Notes on pmValueBlock + * 0. may be used for arbitrary binary data + * 1. only ever allocated dynamically, and vbuf expands to accommodate + * an arbitrary value (don't believe the [1] size!) + * 2. len is the length of the len field + the real size of vbuf + * (which includes the null-byte terminator if there is one) + */ +typedef struct { +#ifdef HAVE_BITFIELDS_LTOR + unsigned int vtype : 8; /* value type */ + unsigned int vlen : 24; /* bytes for vtype/vlen + vbuf */ +#else + unsigned int vlen : 24; /* bytes for vtype/vlen + vbuf */ + unsigned int vtype : 8; /* value type */ +#endif + char vbuf[1]; /* the value */ +} pmValueBlock; + +#define PM_VAL_HDR_SIZE 4 /* bytes for the vtype/vlen header */ +#define PM_VAL_VLEN_MAX 0x00ffffff /* maximum vbuf[] size */ + +typedef struct { + int inst; /* instance identifier */ + union { + pmValueBlock *pval; /* pointer to value-block */ + int lval; /* integer value insitu (lval 'cuz it WAS a long) */ + } value; +} pmValue; + +typedef struct { + pmID pmid; /* metric identifier */ + int numval; /* number of values */ + int valfmt; /* value style */ + pmValue vlist[1]; /* set of instances/values */ +} pmValueSet; + +/* values for valfmt */ +#define PM_VAL_INSITU 0 /* value.lval is it */ +#define PM_VAL_DPTR 1 /* value.pval->vbuf is it, and dynamic alloc */ +#define PM_VAL_SPTR 2 /* value.pval->vbuf is it, and static alloc */ + + +/* Result returned by pmFetch() */ +typedef struct { + struct timeval timestamp; /* time stamped by collector */ + int numpmid; /* number of PMIDs */ + pmValueSet *vset[1]; /* set of value sets, one per PMID */ +} pmResult; + +/* High resolution event timer result from pmUnpackHighResEventRecords() */ +typedef struct { + struct timespec timestamp; /* time stamped by collector */ + int numpmid; /* number of PMIDs */ + pmValueSet *vset[1]; /* set of value sets, one per PMID */ +} pmHighResResult; + +/* Generic Union for Value-Type conversions */ +typedef union { + __int32_t l; /* 32-bit signed */ + __uint32_t ul; /* 32-bit unsigned */ + __int64_t ll; /* 64-bit signed */ + __uint64_t ull; /* 64-bit unsigned */ + float f; /* 32-bit floating point */ + double d; /* 64-bit floating point */ + char *cp; /* char ptr */ + pmValueBlock *vbp; /* pmValueBlock ptr */ +} pmAtomValue; + +/* + * Fetch metrics. Value/instances returned depends on current instance profile. + * By default, all available instances for each requested metric id are + * returned. The metrics argument is terminated with PM_NULL_ID + * + * The value sets returned are in the same order as the metrics argument, + * and the number of value sets returned is guaranteed to be the same as + * the number of metrics in the agument. + */ +extern int pmFetch(int, pmID *, pmResult **); + +/* + * PMCD state changes returned as pmFetch function result for PM_CONTEXT_HOST + * contexts, i.e. when communicating with PMCD + */ +#define PMCD_NO_CHANGE 0 +#define PMCD_ADD_AGENT 1 +#define PMCD_RESTART_AGENT 2 +#define PMCD_DROP_AGENT 4 + +/* + * Variant that is used to return a pmResult from an archive + */ +extern int pmFetchArchive(pmResult **); + +/* + * struct timeval is sometimes 2 x 64-bit ... we use a 2 x 32-bit format for + * PDUs, internally within libpcp and for (external) archive logs + */ +typedef struct { + __int32_t tv_sec; /* seconds since Jan. 1, 1970 */ + __int32_t tv_usec; /* and microseconds */ +} __pmTimeval; + +typedef struct { + __int64_t tv_sec; /* seconds since Jan. 1, 1970 */ + __int64_t tv_nsec; /* and nanoseconds */ +} __pmTimespec; + +/* + * Label Record at the start of every log file - as exported above + * the PMAPI ... + * NOTE MAXHOSTNAMELEN is a bad choice here for ll_hostname[], as + * it may vary on different hosts ... we use PM_LOG_MAXHOSTLEN instead, and + * size this to be the same as MAXHOSTNAMELEN in IRIX 5.3 + * NOTE that the struct timeval means we have another struct (__pmLogLabel) + * for internal use that has a __pmTimeval in place of the struct timeval. + */ +#define PM_TZ_MAXLEN 40 +#define PM_LOG_MAXHOSTLEN 64 +#define PM_LOG_MAGIC 0x50052600 +#define PM_LOG_VERS02 0x2 +#define PM_LOG_VOL_TI -2 /* temporal index */ +#define PM_LOG_VOL_META -1 /* meta data */ +typedef struct { + int ll_magic; /* PM_LOG_MAGIC | log format version no. */ + pid_t ll_pid; /* PID of logger */ + struct timeval ll_start; /* start of this log */ + char ll_hostname[PM_LOG_MAXHOSTLEN]; /* name of collection host */ + char ll_tz[PM_TZ_MAXLEN]; /* $TZ at collection host */ +} pmLogLabel; + +/* + * Get the label record from the current archive context, and discover + * when the archive ends + */ +extern int pmGetArchiveLabel(pmLogLabel *); +extern int pmGetArchiveEnd(struct timeval *); + +/* Free result buffer */ +extern void pmFreeResult(pmResult *); +extern void pmFreeHighResResult(pmHighResResult *); + +/* Value extract from pmValue and type conversion */ +extern int pmExtractValue(int, const pmValue *, int, pmAtomValue *, int); + +/* Print single pmValue */ +extern void pmPrintValue(FILE *, int, int, const pmValue *, int); + +/* Scale conversion, based on value format, value type and scale */ +extern int pmConvScale(int, const pmAtomValue *, const pmUnits *, pmAtomValue *, + const pmUnits *); + +/* Sort instances for each metric within a pmResult */ +extern void pmSortInstances(pmResult *); + +/* Adjust collection time and/or mode for pmFetch */ +extern int pmSetMode(int, const struct timeval *, int); +#define PM_MODE_LIVE 0 +#define PM_MODE_INTERP 1 +#define PM_MODE_FORW 2 +#define PM_MODE_BACK 3 + +/* Modify the value of one or more metrics */ +extern int pmStore(const pmResult *); + +/* Get help and descriptive text */ +extern int pmLookupText(pmID, int, char **); +extern int pmLookupInDomText(pmInDom, int, char **); +#define PM_TEXT_ONELINE 1 +#define PM_TEXT_HELP 2 + +/* + * Some handy formatting routines for messages, and other output + */ +extern const char *pmIDStr(pmID); /* NOT thread-safe */ +extern char *pmIDStr_r(pmID, char *, int); +extern const char *pmInDomStr(pmInDom); /* NOT thread-safe */ +extern char *pmInDomStr_r(pmInDom, char *, int); +extern const char *pmTypeStr(int); /* NOT thread-safe */ +extern char *pmTypeStr_r(int, char *, int); +extern const char *pmUnitsStr(const pmUnits *); /* NOT thread-safe */ +extern char *pmUnitsStr_r(const pmUnits *, char *, int); +extern const char *pmAtomStr(const pmAtomValue *, int); /* NOT thread-safe */ +extern char *pmAtomStr_r(const pmAtomValue *, int, char *, int); +extern const char *pmNumberStr(double); /* NOT thread-safe */ +extern char *pmNumberStr_r(double, char *, int); +extern const char *pmEventFlagsStr(int); /* NOT thread-safe */ +extern char *pmEventFlagsStr_r(int, char *, int); + +/* Extended time base definitions and macros */ +#define PM_XTB_FLAG 0x1000000 + +#define PM_XTB_SET(type) (PM_XTB_FLAG | ((type) << 16)) +#define PM_XTB_GET(x) (((x) & PM_XTB_FLAG) ? (((x) & 0xff0000) >> 16) : -1) + +/* Parse -t, -S, -T, -A and -O options */ +extern int pmParseInterval(const char *, struct timeval *, char **); +extern int pmParseTimeWindow( + const char *, const char *, const char *, const char *, + const struct timeval *, const struct timeval *, + struct timeval *, struct timeval *, struct timeval *, char **); + +/* Reporting timezone */ +extern int pmUseZone(const int); +extern int pmNewZone(const char *); +extern int pmNewContextZone(void); +extern int pmWhichZone(char **); +extern char *pmCtime(const time_t *, char *); +extern struct tm *pmLocaltime(const time_t *, struct tm *); + +/* Parse host:metric[instances] or archive/metric[instances] */ +typedef struct { + int isarch; /* source type: 0 -> live host, 1 -> archive, 2 -> local context */ + char *source; /* name of source host or archive */ + char *metric; /* name of metric */ + int ninst; /* number of instances, 0 -> all */ + char *inst[1]; /* array of instance names */ +} pmMetricSpec; + +/* Parsing of host:metric[instances] or archive/metric[instances] */ +extern int pmParseMetricSpec(const char *, int, char *, pmMetricSpec **, + char **); +extern void pmFreeMetricSpec(pmMetricSpec *p); + +/* + * Configurable error reporting + */ +#ifdef __GNUC__ +# define __PM_PRINTFLIKE(idx,cnt) __attribute__ ((format (printf, idx,cnt))) +#else +# define __PM_PRINTFLIKE(idx,cnt) +#endif + +extern int pmprintf(const char *, ...) __PM_PRINTFLIKE(1,2); +extern int pmflush(void); + +/* + * Wrapper for config/environment variables. Warning: this will exit() with + * a FATAL error if /etc/pcp.conf does not exist and $PCP_CONF is not set. + * Return values point to strings in the environment. + */ +extern char *pmGetConfig(const char *); + +/* + * Common command line argument parsing interfaces + */ + +#define PMAPI_OPTIONS "A:a:D:gh:n:O:p:S:s:T:t:VZ:z?" +#define PMAPI_OPTIONS_HEADER(s) { "", 0, '-', 0, (s) } +#define PMAPI_OPTIONS_TEXT(s) { "", 0, '|', 0, (s) } +#define PMAPI_OPTIONS_END { NULL, 0, 0, 0, NULL } + +#define PMOPT_ALIGN { "align", 1, 'A', "TIME", \ + "align sample times on natural boundaries" } +#define PMOPT_ARCHIVE { "archive", 1, 'a', "FILE", \ + "metrics source is a PCP log archive" } +#define PMOPT_DEBUG { "debug", 1, 'D', "DBG", \ + NULL } +#define PMOPT_GUIMODE { "guimode", 0, 'g', 0, \ + "start in GUI mode with new time control" } +#define PMOPT_HOST { "host", 1, 'h', "HOST", \ + "metrics source is PMCD on host" } +#define PMOPT_HOSTSFILE { "hostsfile", 1, 'H', "FILE", \ + "read metric source hosts from a file" } +#define PMOPT_SPECLOCAL { "spec-local", 1, 'K', "SPEC", \ + "optional additional PMDA spec for local connection" } +#define PMOPT_LOCALPMDA { "local-PMDA", 0, 'L', 0, \ + "metrics source is local connection to a PMDA" } +#define PMOPT_NAMESPACE { "namespace", 1, 'n', "FILE", \ + "use an alternative PMNS" } +#define PMOPT_DUPNAMES { "dupnames", 1, 'N', "FILE", \ + "use an alternative PMNS (duplicate names allowed)" } +#define PMOPT_ORIGIN { "origin", 1, 'O', "TIME", \ + "initial sample time within the time window" } +#define PMOPT_GUIPORT { "guiport", 1, 'p', "N", \ + "port for connection to existing time control" } +#define PMOPT_START { "start", 1, 'S', "TIME", \ + "start of the time window" } +#define PMOPT_SAMPLES { "samples", 1, 's', "N", \ + "terminate after this many samples" } +#define PMOPT_FINISH { "finish", 1, 'T', "TIME", \ + "end of the time window" } +#define PMOPT_INTERVAL { "interval", 1, 't', "DELTA", \ + "sampling interval" } +#define PMOPT_VERSION { "version", 0, 'V', 0, \ + "display version number and exit" } +#define PMOPT_TIMEZONE { "timezone", 1, 'Z', "TZ", \ + "set reporting timezone" } +#define PMOPT_HOSTZONE { "hostzone", 0, 'z', 0, \ + "set reporting timezone to local time of metrics source" } +#define PMOPT_HELP { "help", 0, '?', 0, \ + "show this usage message and exit" } + +#define PMAPI_GENERAL_OPTIONS \ + PMAPI_OPTIONS_HEADER("General options"), \ + PMOPT_ALIGN, \ + PMOPT_ARCHIVE, \ + PMOPT_DEBUG, \ + PMOPT_GUIMODE, \ + PMOPT_HOST, \ + PMOPT_NAMESPACE, \ + PMOPT_ORIGIN, \ + PMOPT_GUIPORT, \ + PMOPT_START, \ + PMOPT_SAMPLES, \ + PMOPT_FINISH, \ + PMOPT_INTERVAL, \ + PMOPT_TIMEZONE, \ + PMOPT_HOSTZONE, \ + PMOPT_VERSION, \ + PMOPT_HELP + +/* long-only standard options */ +#define PMLONGOPT_ARCHIVE_LIST "archive-list" +#define PMOPT_ARCHIVE_LIST { PMLONGOPT_ARCHIVE_LIST, 1, 0, "FILES", \ + "comma-separated list of metric source archives" } +#define PMLONGOPT_ARCHIVE_FOLIO "archive-folio" +#define PMOPT_ARCHIVE_FOLIO { PMLONGOPT_ARCHIVE_FOLIO, 1, 0, "FILE", \ + "read metric source archives from a folio" } +#define PMLONGOPT_HOST_LIST "host-list" +#define PMOPT_HOST_LIST { PMLONGOPT_HOST_LIST, 1, 0, "HOSTS", \ + "comma-separated list of metric source hosts" } + +/* pmOptions flags */ +#define PM_OPTFLAG_INIT (1<<0) /* initialisation done */ +#define PM_OPTFLAG_DONE (1<<1) /* parsing is complete */ +#define PM_OPTFLAG_MULTI (1<<2) /* allow multi-context */ +#define PM_OPTFLAG_USAGE_ERR (1<<3) /* argument parse fail */ +#define PM_OPTFLAG_RUNTIME_ERR (1<<4) /* any runtime failure */ +#define PM_OPTFLAG_EXIT (1<<5) /* tool should exit(0) */ +#define PM_OPTFLAG_POSIX (1<<6) /* POSIXLY_CORRECT set */ +#define PM_OPTFLAG_MIXED (1<<7) /* allow hosts+archives */ +#define PM_OPTFLAG_ENV_ONLY (1<<8) /* use env options only */ +#define PM_OPTFLAG_LONG_ONLY (1<<9) /* use long options only */ +#define PM_OPTFLAG_BOUNDARIES (1<<10) /* calculate time window */ +#define PM_OPTFLAG_STDOUT_TZ (1<<11) /* write timezone change */ +#define PM_OPTFLAG_NOFLUSH (1<<12) /* caller issues pmflush */ +#define PM_OPTFLAG_QUIET (1<<13) /* silence getopt errors */ + +struct __pmOptions; +typedef int (*pmOptionOverride)(int, struct __pmOptions *); + +typedef struct { + const char * long_opt; + int has_arg; + int short_opt; + const char * argname; + const char * message; +} pmLongOptions; + +typedef struct __pmOptions { + int version; + int flags; + + /* in: define set of all options */ + const char * short_options; + pmLongOptions * long_options; + const char * short_usage; + + /* in: method for general override */ + pmOptionOverride override; + + /* out: usual getopt information */ + int index; + int optind; + int opterr; + int optopt; + char *optarg; + + /* internals; do not ever access */ + int __initialized; + char * __nextchar; + int __ordering; + int __posixly_correct; + int __first_nonopt; + int __last_nonopt; + + /* out: error count */ + int errors; + + /* out: PMAPI options and values */ + int context; /* PM_CONTEXT_{HOST,ARCHIVE,LOCAL} */ + int nhosts; + int narchives; + char ** hosts; + char ** archives; + struct timeval start; + struct timeval finish; + struct timeval origin; + struct timeval interval; + char * align_optarg; + char * start_optarg; + char * finish_optarg; + char * origin_optarg; + char * guiport_optarg; + char * timezone; + int samples; + int guiport; + int padding; + unsigned int guiflag : 1; + unsigned int tzflag : 1; + unsigned int nsflag : 1; + unsigned int Lflag : 1; + unsigned int zeroes : 28; +} pmOptions; + +extern int pmgetopt_r(int, char *const *, pmOptions *); +extern int pmGetOptions(int, char *const *, pmOptions *); +extern int pmGetContextOptions(int, pmOptions *); +extern void pmUsageMessage(pmOptions *); +extern void pmFreeOptions(pmOptions *); + +/* + * Derived Metrics support + */ +extern int pmLoadDerivedConfig(const char *); +extern char *pmRegisterDerived(const char *, const char *); +extern char *pmDerivedErrStr(void); + +/* + * Event Record support + */ +typedef struct { + pmID ep_pmid; + /* vtype and vlen fields the format same as for pmValueBlock */ +#ifdef HAVE_BITFIELDS_LTOR + unsigned int ep_type : 8; /* value type */ + unsigned int ep_len : 24; /* bytes for type/len + vbuf */ +#else + unsigned int ep_len : 24; /* bytes for type/len + vbuf */ + unsigned int ep_type : 8; /* value type */ +#endif + /* actual value (vbuf) goes here ... */ +} pmEventParameter; + +typedef struct { + __pmTimeval er_timestamp; /* must be 2 x 32-bit format */ + unsigned int er_flags; /* event record characteristics */ + int er_nparams; /* number of er_param[] entries */ + pmEventParameter er_param[1]; +} pmEventRecord; + +typedef struct { + __pmTimespec er_timestamp; /* must be 2 x 64-bit format */ + unsigned int er_flags; /* event record characteristics */ + int er_nparams; /* number of er_param[] entries */ + pmEventParameter er_param[1]; +} pmHighResEventRecord; + +/* Potential flags bits set in er_flags (above) */ +#define PM_EVENT_FLAG_POINT (1U<<0) /* an observation, default type */ +#define PM_EVENT_FLAG_START (1U<<1) /* marking start of a new event */ +#define PM_EVENT_FLAG_END (1U<<2) /* completion of a traced event */ +#define PM_EVENT_FLAG_ID (1U<<3) /* 1st parameter is a trace ID */ +#define PM_EVENT_FLAG_PARENT (1U<<4) /* 2nd parameter is parents ID */ +#define PM_EVENT_FLAG_MISSED (1U<<31)/* nparams shows #missed events */ + +typedef struct { + /* align initial declarations with start of pmValueBlock */ +#ifdef HAVE_BITFIELDS_LTOR + unsigned int ea_type : 8; /* value type */ + unsigned int ea_len : 24; /* bytes for type/len + vbuf */ +#else + unsigned int ea_len : 24; /* bytes for type/len + vbuf */ + unsigned int ea_type : 8; /* value type */ +#endif + /* real event records start here */ + int ea_nrecords; /* number of ea_record[] entries */ + pmEventRecord ea_record[1]; +} pmEventArray; + +typedef struct { + /* align initial declarations with start of pmValueBlock */ +#ifdef HAVE_BITFIELDS_LTOR + unsigned int ea_type : 8; /* value type */ + unsigned int ea_len : 24; /* bytes for type/len + vbuf */ +#else + unsigned int ea_len : 24; /* bytes for type/len + vbuf */ + unsigned int ea_type : 8; /* value type */ +#endif + /* real event records start here */ + int ea_nrecords; /* number of ea_record[] entries */ + pmHighResEventRecord ea_record[1]; +} pmHighResEventArray; + +/* Unpack a PM_TYPE_EVENT value into a set on pmResults */ +extern int pmUnpackEventRecords(pmValueSet *, int, pmResult ***); + +/* Free set of pmResults from pmUnpackEventRecords */ +extern void pmFreeEventResult(pmResult **); + +/* Unpack a PM_TYPE_HIGHRES_EVENT value into a set on pmHighResResults */ +extern int pmUnpackHighResEventRecords(pmValueSet *, int, pmHighResResult ***); + +/* Free set of pmHighResResults from pmUnpackEventRecords */ +extern void pmFreeHighResEventResult(pmHighResResult **); + +/* Service discovery, for clients. */ +#define PM_SERVER_SERVICE_SPEC "pmcd" +#define PM_SERVER_PROXY_SPEC "pmproxy" +#define PM_SERVER_WEBD_SPEC "pmwebd" + +extern int pmDiscoverServices(const char *, const char *, char ***); + +#ifdef __cplusplus +} +#endif + +#endif /* _PMAPI_H */ diff --git a/src/include/pcp/pmda.h b/src/include/pcp/pmda.h new file mode 100644 index 0000000..0b6eba1 --- /dev/null +++ b/src/include/pcp/pmda.h @@ -0,0 +1,725 @@ +/* + * Copyright (c) 2013-2014 Red Hat. + * Copyright (c) 1995,2005 Silicon Graphics, Inc. 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 + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + */ +#ifndef _PMDA_H +#define _PMDA_H + +#include <stdarg.h> + +#ifdef __cplusplus +extern "C" { +#endif + +/* + * libpcp_pmda interface versions + */ +#define PMDA_INTERFACE_2 2 /* new function arguments */ +#define PMDA_INTERFACE_3 3 /* 3-state return from fetch callback */ +#define PMDA_INTERFACE_4 4 /* dynamic pmns */ +#define PMDA_INTERFACE_5 5 /* client context in pmda and */ + /* 4-state return from fetch callback */ +#define PMDA_INTERFACE_6 6 /* client security attributes in pmda */ +#define PMDA_INTERFACE_LATEST 6 + +/* + * Type of I/O connection to PMCD (pmdaUnknown defaults to pmdaPipe) + */ +typedef enum {pmdaPipe, pmdaInet, pmdaUnix, pmdaUnknown, pmdaIPv6} pmdaIoType; + +/* + * Instance description: index and name + */ +typedef struct { + int i_inst; /* internal instance identifier */ + char *i_name; /* external instance identifier */ +} pmdaInstid; + +/* + * Instance domain description: unique instance id, number of instances in + * this domain, and the list of instances (not null terminated). + */ +typedef struct { + pmInDom it_indom; /* indom, filled in */ + int it_numinst; /* number of instances */ + pmdaInstid *it_set; /* instance identifiers */ +} pmdaIndom; + +/* + * Metric description: handle for extending description, and the description. + */ +typedef struct { + void *m_user; /* for users external use */ + pmDesc m_desc; /* metric description */ +} pmdaMetric; + +/* + * Type of function call back used by pmdaFetch. + */ +typedef int (*pmdaFetchCallBack)(pmdaMetric *, unsigned int, pmAtomValue *); + +/* + * return values for a pmdaFetchCallBack method + */ +#define PMDA_FETCH_NOVALUES 0 +#define PMDA_FETCH_STATIC 1 +#define PMDA_FETCH_DYNAMIC 2 /* free avp->vp after __pmStuffValue */ + +/* + * Type of function call back used by pmdaMain to clean up a pmResult structure + * after a fetch. + */ +typedef void (*pmdaResultCallBack)(pmResult *); + +/* + * Type of function call back used by pmdaMain on receipt of each PDU to check + * availability, etc. + */ +typedef int (*pmdaCheckCallBack)(void); + +/* + * Type of function call back used by pmdaMain after each PDU has been + * processed. + */ +typedef void (*pmdaDoneCallBack)(void); + +/* + * Type of function call back used by pmdaMain when a client context is + * closed by PMCD. + */ +typedef void (*pmdaEndContextCallBack)(int); + +/* + * Forward declarations of structures so that inclusion of (internal) impl.h + * header file is not mandated if this header file is included. + */ +typedef struct __pmnsTree pmdaNameSpace; +typedef struct __pmHashCtl pmdaHashTable; +typedef struct __pmProfile pmdaInProfile; +typedef struct __pmInResult pmdaInResult; + +/* + * libpcp_pmda extension structure. + * + * The fields of this structure are initialised using pmdaDaemon() or pmdaDSO() + * (if the agent is a daemon or a DSO respectively), pmdaGetOpt() and + * pmdaInit(). + * + */ +typedef struct { + + unsigned int e_flags; /* PMDA_EXT_FLAG_* bit field */ + void *e_ext; /* used internally within libpcp_pmda */ + + char *e_sockname; /* socket name to pmcd */ + char *e_name; /* name of this pmda */ + char *e_logfile; /* path to log file */ + char *e_helptext; /* path to help text */ + int e_status; /* =0 is OK */ + int e_infd; /* input file descriptor from pmcd */ + int e_outfd; /* output file descriptor to pmcd */ + int e_port; /* port to pmcd */ + int e_singular; /* =0 for singular values */ + int e_ordinal; /* >=0 for non-singular values */ + int e_direct; /* =1 if pmid map to meta table */ + int e_domain; /* metrics domain */ + int e_nmetrics; /* number of metrics */ + int e_nindoms; /* number of instance domains */ + int e_help; /* help text comes via this handle */ + pmdaInProfile *e_prof; /* last received profile */ + pmdaIoType e_io; /* connection type to pmcd */ + pmdaIndom *e_indoms; /* instance domain table */ + pmdaIndom *e_idp; /* used in instance domain expansion */ + pmdaMetric *e_metrics; /* metric description table */ + + pmdaResultCallBack e_resultCallBack; /* callback to clean up pmResult after fetch */ + pmdaFetchCallBack e_fetchCallBack; /* callback to assign metric values in fetch */ + pmdaCheckCallBack e_checkCallBack; /* callback on receipt of a PDU */ + pmdaDoneCallBack e_doneCallBack; /* callback after PDU has been processed */ + /* added for PMDA_INTERFACE_5 */ + int e_context; /* client context id from pmcd */ + pmdaEndContextCallBack e_endCallBack; /* callback after client context closed */ +} pmdaExt; + +#define PMDA_EXT_FLAG_DIRECT 0x01 /* direct mapped PMID metric table */ +#define PMDA_EXT_FLAG_HASHED 0x02 /* hashed PMID metric table lookup */ +#define PMDA_EXT_SETUPDONE 0x04 /* __pmdaSetup() has been called */ +#define PMDA_EXT_CONNECTED 0x08 /* pmdaConnect() done */ +#define PMDA_EXT_NOTREADY 0x10 /* pmcd connection marked NOTREADY */ + +/* + * Optionally restrict symbol visibility for DSO PMDAs + * + * When compiled with -fvisibility=hidden this directive can be used + * to set up the init routine so that it is the only symbol exported + * by the DSO PMDA. This gives the compiler opportunity to generate + * more optimal code as well as ensuring that just the one symbol is + * exported (which is a good idea in itself). + */ +#ifdef __GNUC__ +# define __PMDA_INIT_CALL __attribute__ ((visibility ("default"))) +#else +# define __PMDA_INIT_CALL +#endif + +/* + * Interface Definitions for PMDA DSO Interface + * The new interface structure makes use of a union to manage new revisions + * cleanly. The structure for each new version must be backward compatible + * to all of the previous versions (i.e. contain earlier fields unchanged). + * + * The domain field is set by pmcd(1) in the case of a DSO PMDA, and by + * pmdaDaemon and pmdaGetOpt in the case of a Daemon PMDA. It should not be + * modified. + */ +typedef struct { + int domain; /* performance metrics domain id */ + struct { + unsigned int pmda_interface : 8; /* PMDA DSO interface version */ + unsigned int pmapi_version : 8; /* PMAPI version */ + unsigned int flags : 16; /* optional feature flags */ + } comm; /* set/return communication and version info */ + int status; /* return initialization status here */ + + union { + +/* + * Interface Version 2 and 3 (PCP 2.0) + * PMDA_INTERFACE_2 and PMDA_INTERFACE_3 + */ + + struct { + pmdaExt *ext; + int (*profile)(pmdaInProfile *, pmdaExt *); + int (*fetch)(int, pmID *, pmResult **, pmdaExt *); + int (*desc)(pmID, pmDesc *, pmdaExt *); + int (*instance)(pmInDom, int, char *, pmdaInResult **, pmdaExt *); + int (*text)(int, int, char **, pmdaExt *); + int (*store)(pmResult *, pmdaExt *); + } any, two, three; + +/* + * Interface Version 4 (dynamic pmns support) and Version 5 (client context + * in PMDA). + * PMDA_INTERFACE_4, PMDA_INTERFACE_5 + */ + + struct { + pmdaExt *ext; + int (*profile)(pmdaInProfile *, pmdaExt *); + int (*fetch)(int, pmID *, pmResult **, pmdaExt *); + int (*desc)(pmID, pmDesc *, pmdaExt *); + int (*instance)(pmInDom, int, char *, pmdaInResult **, pmdaExt *); + int (*text)(int, int, char **, pmdaExt *); + int (*store)(pmResult *, pmdaExt *); + int (*pmid)(const char *, pmID *, pmdaExt *); + int (*name)(pmID, char ***, pmdaExt *); + int (*children)(const char *, int, char ***, int **, pmdaExt *); + } four, five; + +/* + * Interface Version 6 (client context security attributes in PMDA). + * PMDA_INTERFACE_6 + */ + struct { + pmdaExt *ext; + int (*profile)(pmdaInProfile *, pmdaExt *); + int (*fetch)(int, pmID *, pmResult **, pmdaExt *); + int (*desc)(pmID, pmDesc *, pmdaExt *); + int (*instance)(pmInDom, int, char *, pmdaInResult **, pmdaExt *); + int (*text)(int, int, char **, pmdaExt *); + int (*store)(pmResult *, pmdaExt *); + int (*pmid)(const char *, pmID *, pmdaExt *); + int (*name)(pmID, char ***, pmdaExt *); + int (*children)(const char *, int, char ***, int **, pmdaExt *); + int (*attribute)(int, int, const char *, int, pmdaExt *); + } six; + + } version; + +} pmdaInterface; + +/* + * PM_CONTEXT_LOCAL support + */ +typedef struct { + int domain; + char *name; + char *init; + void *handle; + pmdaInterface dispatch; +} __pmDSO; + +extern __pmDSO *__pmLookupDSO(int /*domain*/); + +/* Macro that can be used to create each metrics' PMID. */ +#define PMDA_PMID(x,y) (((x)<<10)|(y)) + +/* Macro for pmUnits bitmap in a pmDesc declaration */ +#ifdef HAVE_BITFIELDS_LTOR +#define PMDA_PMUNITS(a,b,c,d,e,f) {a,b,c,d,e,f,0} +#else +#define PMDA_PMUNITS(a,b,c,d,e,f) {0,f,e,d,c,b,a} +#endif + +/* Command line option processing macros and data structures */ + +#define PMDA_OPTIONS "D:d:h:i:l:pu:U:" +#define PMDA_OPTIONS_HEADER(s) { "", 0, '-', 0, (s) } +#define PMDA_OPTIONS_TEXT(s) { "", 0, '|', 0, (s) } +#define PMDA_OPTIONS_END { NULL, 0, 0, 0, NULL } + +#define PMDAOPT_DEBUG { "debug", 1, 'D', "DBG", \ + NULL } +#define PMDAOPT_DOMAIN { "domain", 1, 'd', "NUM", \ + "use domain (numeric) for metrics domain of PMDA" } +#define PMDAOPT_HELPTEXT { "helpfile", 1, 'h', "FILE", \ + "path to PMDA metrics help text file" } +#define PMDAOPT_INET { "inet", 1, 'i', "PORT", \ + "pmcd IPv4 connection service name or numeric port" } +#define PMDAOPT_IPV6 { "ipv6", 1, '6', "PORT", \ + "pmcd IPv6 connection service name or numeric port" } +#define PMDAOPT_LOGFILE { "log", 1, 'l', "FILE", \ + "write log to FILE rather than using default log name" } +#define PMDAOPT_PIPE { "pipe", 0, 'p', 0, \ + "use a pipe for communication with pmcd" } +#define PMDAOPT_UNIX { "unix", 1, 'u', "FILE", \ + "use a unix domain socket for communication with pmcd" } +#define PMDAOPT_USERNAME { "username", 1, 'U', "USER", \ + "run the PMDA using the named user account" } + +struct __pmdaOptions; +typedef int (*pmdaOptionOverride)(int, struct __pmdaOptions *); + +typedef struct __pmdaOptions { + int version; + int flags; + const char * short_options; + pmLongOptions * long_options; + const char * short_usage; + pmdaOptionOverride override; + + /* out: usual getopt information */ + int index; + int optind; + int opterr; + int optopt; + char *optarg; + + /* internals; do not ever access */ + int __initialized; + char * __nextchar; + int __ordering; + int __posixly_correct; + int __first_nonopt; + int __last_nonopt; + + /* out: error count */ + int errors; + + /* out: PMDA options (non-pmdaInterface options) */ + char * username; +} pmdaOptions; + + +/* + * PMDA Setup Routines. + * + * pmdaGetOpt + * pmdaGetOptions + * pmdaUsageMessage + * Replacements for pmgetopt_r(3) which strip out the standard PMDA flags + * before returning the next command line option. The standard PMDA + * flags are PMDA_OPTIONS which will initialise the pmdaExt structure + * with the IPC details, path to the log and help file, domain number, + * and the user account under which the PMDA should run. + * An error counter will be incremented if there was an error parsing any + * of these options. + * + * pmdaDaemon + * Setup the pmdaInterface structure for a daemon and initialise + * the pmdaExt structure with the PMDA's name, domain and path to + * the log file and help file. The libpcp internal state is also + * initialised. + * + * pmdaDSO + * Setup the pmdaInterface structure for a DSO and initialise the + * pmdaExt structure with the PMDA's name and help file. + * + * pmdaOpenLog + * Redirects stderr to the logfile. + * + * pmdaSetFlags + * Allow behaviour flags to be set to enable features, such as to request + * libpcp_pmda internally use direct or hashed PMID metric table mapping. + * Can be called multiple times - effects are cumulative - no flag can be + * cleared, although libpcp_pmda may disable a flag later on if it cannot + * enact the requested behaviour. + * + * pmdaInit + * Further initialises the pmdaExt structure with the instance domain and + * metric structures. Unique identifiers are applied to each instance + * domain and metric. Also open the help text file and checks whether the + * metrics can be directly mapped. + * + * pmdaConnect + * Connect to the PMCD process using the method set in the pmdaExt e_io + * field. + * + * pmdaMain + * Loop which receives PDUs and dispatches the callbacks. Must be called + * by a daemon PMDA. + * + * pmdaSetResultCallBack + * Allows an application specific routine to be specified for cleaning up + * a pmResult after a fetch. Most PMDAs should not use this. + * + * pmdaSetFetchCallBack + * Allows an application specific routine to be specified for completing a + * pmAtom structure with a metrics value. This must be set if pmdaFetch is + * used as the fetch callback. + * + * pmdaSetCheckCallBack + * Allows an application specific routine to be called upon receipt of any + * PDU. For all PDUs except PDU_PROFILE, a result less than zero + * indicates an error. If set to zero (which is also the default), + * the callback is ignored. + * + * pmdaSetDoneCallBack + * Allows an application specific routine to be called after each PDU is + * processed. The result is ignored. If set to zero (which is also + * the default), the callback is ignored. + * + * pmdaSetEndContextCallBack + * Allows an application specific routine to be called when a + * PMCD context is closed, so any per-context state can be cleaned + * up. If set to zero (which is also the default), the callback + * is ignored. + */ + +extern int pmdaGetOpt(int, char *const *, const char *, pmdaInterface *, int *); +extern int pmdaGetOptions(int, char *const *, pmdaOptions *, pmdaInterface *); +extern void pmdaUsageMessage(pmdaOptions *); +extern void pmdaDaemon(pmdaInterface *, int, char *, int , char *, char *); +extern void pmdaDSO(pmdaInterface *, int, char *, char *); +extern void pmdaOpenLog(pmdaInterface *); +extern void pmdaSetFlags(pmdaInterface *, int); +extern void pmdaInit(pmdaInterface *, pmdaIndom *, int, pmdaMetric *, int); +extern void pmdaConnect(pmdaInterface *); + +extern void pmdaMain(pmdaInterface *); + +extern void pmdaSetResultCallBack(pmdaInterface *, pmdaResultCallBack); +extern void pmdaSetFetchCallBack(pmdaInterface *, pmdaFetchCallBack); +extern void pmdaSetCheckCallBack(pmdaInterface *, pmdaCheckCallBack); +extern void pmdaSetDoneCallBack(pmdaInterface *, pmdaDoneCallBack); +extern void pmdaSetEndContextCallBack(pmdaInterface *, pmdaEndContextCallBack); + +/* + * Callbacks to PMCD which should be adequate for most PMDAs. + * NOTE: if pmdaFetch is used, e_callback must be specified in the pmdaExt + * structure. + * + * pmdaProfile + * Store the instance profile away for the next fetch. + * + * pmdaFetch + * Resize the pmResult and call e_callback in the pmdaExt structure + * for each metric instance required by the profile. + * + * pmdaInstance + * Return description of instances and instance domains. + * + * pmdaDesc + * Return the metric desciption. + * + * pmdaText + * Return the help text for the metric. + * + * pmdaStore + * Store a value into a metric. This is a no-op. + * + * pmdaPMID + * Return the PMID for a named metric within a dynamic subtree + * of the PMNS. + * + * pmdaName + * Given a PMID, return the names of all matching metrics within a + * dynamic subtree of the PMNS. + * + * pmdaChildren + * If traverse == 0, return the names of all the descendent children + * and their status, given a named metric in a dynamic subtree of + * the PMNS (this is the pmGetChildren or pmGetChildrenStatus variant). + * If traverse == 1, return the full names of all descendent metrics + * (this is the pmTraversePMNS variant, with the status added) + * + * pmdaAttribute + * Inform the agent about security aspects of a client connection, + * such as the authenticated userid. Passed in a client identifier, + * numeric PCP_ATTR, pointer to the associated value, and the length + * of the value. + */ + +extern int pmdaProfile(pmdaInProfile *, pmdaExt *); +extern int pmdaFetch(int, pmID *, pmResult **, pmdaExt *); +extern int pmdaInstance(pmInDom, int, char *, pmdaInResult **, pmdaExt *); +extern int pmdaDesc(pmID, pmDesc *, pmdaExt *); +extern int pmdaText(int, int, char **, pmdaExt *); +extern int pmdaStore(pmResult *, pmdaExt *); +extern int pmdaPMID(const char *, pmID *, pmdaExt *); +extern int pmdaName(pmID, char ***, pmdaExt *); +extern int pmdaChildren(const char *, int, char ***, int **, pmdaExt *); +extern int pmdaAttribute(int, int, const char *, int, pmdaExt *); + +/* + * PMDA "help" text manipulation + */ +extern int pmdaOpenHelp(char *); +extern void pmdaCloseHelp(int); +extern char *pmdaGetHelp(int, pmID, int); +extern char *pmdaGetInDomHelp(int, pmInDom, int); + +/* + * Dynamic metric table manipulation + * + * pmdaDynamicPMNS + * Register a new dynamic namespace sub-tree associated with one or more + * PMID clusters. Callbacks are passed in to deal with PMDA-specific + * components (names, help text, metric duplication, and table sizing). + * + * pmdaDynamicLookupName + * Perform PMDA name lookup operations for the name callback, for dynamic + * metrics. + * + * pmdaDynamicLookupPMID + * Perform PMDA reverse name lookup operations for the PMID callback, for + * dynamic metrics. + * + * pmdaDynamicLookupText + * Perform PMDA help text lookup operations for dynamic metrics. + * + * pmdaDynamicMetricTable + * Install a new metric table for the PMDA, after changes to the set of + * metrics which the PMDA must export (IOW, dynamic metrics are in use). + * + * pmdaRehash + * Update the metrictable within the pmdaExt structure with new (dynamic) + * metrics and recompute the hash table used for optimised lookup. Aids + * PMDAs with large numbers of metrics to get closer to directly mapped + * PMID lookup time, rather than multiple linear table scans per fetch. + * [NOTE: can be used by any interface version, not only dynamic metrics] + */ +typedef int (*pmdaUpdatePMNS)(pmdaExt *, pmdaNameSpace **); +typedef int (*pmdaUpdateText)(pmdaExt *, pmID, int, char **); +typedef void (*pmdaUpdateMetric)(pmdaMetric *, pmdaMetric *, int); +typedef void (*pmdaCountMetrics)(int *, int *); +extern void pmdaDynamicPMNS(const char *, int *, int, + pmdaUpdatePMNS, pmdaUpdateText, + pmdaUpdateMetric, pmdaCountMetrics, + pmdaMetric *, int); +extern int pmdaDynamicSetClusterMask(const char *, unsigned int); +extern pmdaNameSpace *pmdaDynamicLookupName(pmdaExt *, const char *); +extern pmdaNameSpace *pmdaDynamicLookupPMID(pmdaExt *, pmID); +extern int pmdaDynamicLookupText(pmID, int, char **, pmdaExt *); +extern void pmdaDynamicMetricTable(pmdaExt *); + +extern void pmdaRehash(pmdaExt *, pmdaMetric *, int); + +/* + * Dynamic names interface (version 4) helper routines. + * + * pmdaTreePMID + * when a pmdaNameSpace is being used, this provides + * an implementation for the four.pmid() interface. + * + * pmdaTreeName + * when a pmdaNameSpace is being used, this provides + * an implementation for the four.name() interface. + * + * pmdaTreeChildren + * when a pmdaNameSpace is being used, this provides + * an implementation for the four.children() interface. + * + * pmdaTreeRebuildHash + * iterate over a pmdaNameSpace and (re)build the hash + * for any subsequent PMID -> name (reverse) lookups + * + * pmdaTreeSize + * returns the numbers of entries in a pmdaNameSpace. + */ +extern int pmdaTreePMID(pmdaNameSpace *, const char *, pmID *); +extern int pmdaTreeName(pmdaNameSpace *, pmID, char ***); +extern int pmdaTreeChildren(pmdaNameSpace *, const char *, int, char ***, int **); +extern void pmdaTreeRebuildHash(pmdaNameSpace *, int); +extern int pmdaTreeSize(pmdaNameSpace *); + +/* + * PMDA instance domain cache support + * + * pmdaCacheStore + * add entry into the cache, or change state, assigns internal + * instance identifier + * + * pmdaCacheStoreKey + * add entry into the cache, or change state, caller provides "hint" + * for internal instance identifier + * + * pmdaCacheLookup + * fetch entry based on internal instance identifier + * + * pmdaCacheLookupName + * fetch entry based on external instance name + * + * pmdaCacheLookupKey + * fetch entry based on key as "hint", like pmdaCacheStoreKey() + * + * pmdaCacheOp + * service routines to load, unload, mark as write-thru, purge, + * count entries, etc + * + * pmdaCachePurge + * cull inactive entries + */ +extern int pmdaCacheStore(pmInDom, int, const char *, void *); +extern int pmdaCacheStoreKey(pmInDom, int, const char *, int, const void *, void *); +extern int pmdaCacheLookup(pmInDom, int, char **, void **); +extern int pmdaCacheLookupName(pmInDom, const char *, int *, void **); +extern int pmdaCacheLookupKey(pmInDom, const char *, int, const void *, char **, int *, void **); +extern int pmdaCacheOp(pmInDom, int); +extern int pmdaCachePurge(pmInDom, time_t); + +#define PMDA_CACHE_LOAD 1 +#define PMDA_CACHE_ADD 2 +#define PMDA_CACHE_HIDE 3 +#define PMDA_CACHE_CULL 4 +#define PMDA_CACHE_EMPTY 5 +#define PMDA_CACHE_SAVE 6 +#define PMDA_CACHE_STRINGS 7 +#define PMDA_CACHE_ACTIVE 8 +#define PMDA_CACHE_INACTIVE 9 +#define PMDA_CACHE_SIZE 10 +#define PMDA_CACHE_SIZE_ACTIVE 11 +#define PMDA_CACHE_SIZE_INACTIVE 12 +#define PMDA_CACHE_REUSE 13 +#define PMDA_CACHE_WALK_REWIND 14 +#define PMDA_CACHE_WALK_NEXT 15 +#define PMDA_CACHE_CHECK 16 +#define PMDA_CACHE_REORG 17 +#define PMDA_CACHE_SYNC 18 +#define PMDA_CACHE_DUMP 19 +#define PMDA_CACHE_DUMP_ALL 20 + +/* + * Internal libpcp_pmda routines. + * + * __pmdaCntInst + * Returns the number of instances for an entry in the instance domain + * table. + * + * __pmdaStartInst + * Setup for __pmdaNextInst to iterate over an instance domain. + * + * __pmdaNextInst + * Step through an instance domain, returning instances one at a + * time. + * + * __pmdaMainPDU + * Use this when you need to override pmdaMain and construct + * your own loop. + * Call this function in the _body_ of your loop. + * See pmdaMain code for an example. + * Returns negative int on failure, 0 otherwise. + * + * __pmdaInFd + * This returns the file descriptor that is used to get the + * PDU from pmcd. + * One may use the fd to do a select call in a custom main loop. + * Returns negative int on failure, file descriptor otherwise. + * + * __pmdaCacheDumpAll and __pmdaCacheDump + * print out cache contents + */ + +extern int __pmdaCntInst(pmInDom, pmdaExt *); +extern void __pmdaStartInst(pmInDom, pmdaExt *); +extern int __pmdaNextInst(int *, pmdaExt *); + +extern int __pmdaMainPDU(pmdaInterface *); +extern int __pmdaInFd(pmdaInterface *); + +extern void __pmdaCacheDumpAll(FILE *, int); +extern void __pmdaCacheDump(FILE *, pmInDom, int); + +/* + * Client Context support + */ +extern int pmdaGetContext(void); +extern void __pmdaSetContext(int); + +/* + * Event Record support + */ +extern int pmdaEventNewArray(void); +extern int pmdaEventResetArray(int); +extern int pmdaEventReleaseArray(int); +extern int pmdaEventAddRecord(int, struct timeval *, int); +extern int pmdaEventAddMissedRecord(int, struct timeval *, int); +extern int pmdaEventAddParam(int, pmID, int, pmAtomValue *); +extern pmEventArray *pmdaEventGetAddr(int); + +/* + * High Resolution Timer Event Record support + */ +extern int pmdaEventNewHighResArray(void); +extern int pmdaEventResetHighResArray(int); +extern int pmdaEventReleaseHighResArray(int); +extern int pmdaEventAddHighResRecord(int, struct timespec *, int); +extern int pmdaEventAddHighResMissedRecord(int, struct timespec *, int); +extern int pmdaEventHighResAddParam(int, pmID, int, pmAtomValue *); +extern pmHighResEventArray *pmdaEventHighResGetAddr(int); + +/* + * Event Queue support + */ +extern int pmdaEventNewQueue(const char *, size_t); +extern int pmdaEventNewActiveQueue(const char *, size_t, unsigned int); +extern int pmdaEventQueueHandle(const char *); +extern int pmdaEventQueueAppend(int, void *, size_t, struct timeval *); +extern int pmdaEventQueueClients(int, pmAtomValue *); +extern int pmdaEventQueueCounter(int, pmAtomValue *); +extern int pmdaEventQueueBytes(int, pmAtomValue *); +extern int pmdaEventQueueMemory(int, pmAtomValue *); + +typedef int (*pmdaEventDecodeCallBack)(int, + void *, size_t, struct timeval *, void *); +extern int pmdaEventQueueRecords(int, pmAtomValue *, int, + pmdaEventDecodeCallBack, void *); + +extern int pmdaEventNewClient(int); +extern int pmdaEventEndClient(int); +extern int pmdaEventClients(pmAtomValue *); + +typedef int (*pmdaEventApplyFilterCallBack)(void *, void *, size_t); +typedef void (*pmdaEventReleaseFilterCallBack)(void *); +extern int pmdaEventSetFilter(int, int, void *, + pmdaEventApplyFilterCallBack, pmdaEventReleaseFilterCallBack); +extern int pmdaEventSetAccess(int, int, int); + +extern char *__pmdaEventPrint(const char *, int, char *, int); + +#ifdef __cplusplus +} +#endif + +#endif /* _PMDA_H */ diff --git a/src/include/pcp/pmtime.h b/src/include/pcp/pmtime.h new file mode 100644 index 0000000..86db5a3 --- /dev/null +++ b/src/include/pcp/pmtime.h @@ -0,0 +1,107 @@ +/* + * Copyright (C) 2006-2007 Aconex. All Rights Reserved. + * + * This library 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 + * (at your option) any later version. + * + * This library 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 Lesser General Public + * License for more details. + */ +#ifndef PMTIME_H +#define PMTIME_H + +#include <sys/time.h> + +typedef enum { + PM_TCTL_SET = (1<<0), // client -> server + PM_TCTL_STEP = (1<<1), // server -> clients + PM_TCTL_TZ = (1<<2), // server -> clients + PM_TCTL_VCRMODE = (1<<3), // server -> clients + PM_TCTL_VCRMODE_DRAG= (1<<4), // server -> clients + PM_TCTL_GUISHOW = (1<<5), // client -> server + PM_TCTL_GUIHIDE = (1<<6), // client -> server + PM_TCTL_BOUNDS = (1<<7), // client -> server + PM_TCTL_ACK = (1<<8), // client -> server (except handshake) +} pm_tctl_command; + +typedef enum { + PM_STATE_STOP = 0, + PM_STATE_FORWARD = 1, + PM_STATE_BACKWARD = 2, +} pm_tctl_state; + +typedef enum { + PM_MODE_STEP = 0, + PM_MODE_NORMAL = 1, + PM_MODE_FAST = 2, +} pm_tctl_mode; + +typedef enum { + PM_SOURCE_NONE = -1, + PM_SOURCE_HOST = 0, + PM_SOURCE_ARCHIVE = 1, +} pm_tctl_source; + +#define PMTIME_MAGIC 0x54494D45 /* "TIME" */ + +typedef struct { + unsigned int magic; + unsigned int length; + pm_tctl_command command; + pm_tctl_source source; + pm_tctl_state state; + pm_tctl_mode mode; + struct timeval delta; + struct timeval position; + struct timeval start; /* archive only */ + struct timeval end; /* archive only */ + char data[0]; /* arbitrary length info (e.g. $TZ) */ +} pmTime; + +extern int pmTimeSendAck(int, struct timeval *); +extern int pmTimeConnect(int, pmTime *); +extern int pmTimeShowDialog(int, int); +extern int pmTimeRecv(int, pmTime **); + +/* + * Time state management API for simple clients + */ + +typedef void (*pmTimeStateResume)(void); +typedef void (*pmTimeStateRewind)(void); +typedef void (*pmTimeStateExited)(void); +typedef void (*pmTimeStateBoundary)(void); +typedef void (*pmTimeStatePosition)(struct timeval); +typedef void (*pmTimeStateInterval)(struct timeval); +typedef void (*pmTimeStateStepped)(struct timeval); +typedef void (*pmTimeStateNewZone)(char *, char *); + +typedef struct { + pmTimeStateResume resume; + pmTimeStateRewind rewind; + pmTimeStateExited exited; + pmTimeStateBoundary boundary; + pmTimeStatePosition position; + pmTimeStateInterval interval; + pmTimeStateStepped stepped; + pmTimeStateNewZone newzone; + struct timeval delta; + int fd; + int showgui; + int context; + int padding; +} pmTimeControls; + +extern pmTime *pmTimeStateSetup(pmTimeControls *, int, int, + struct timeval, struct timeval, + struct timeval, struct timeval, char *, char *); +extern void pmTimeStateAck(pmTimeControls *, pmTime *); +extern void pmTimeStateMode(int, struct timeval, struct timeval *); +extern int pmTimeStateVector(pmTimeControls *, pmTime *); +extern void pmTimeStateBounds(pmTimeControls *, pmTime *); + +#endif /* PMTIME_H */ diff --git a/src/include/pcp/trace.h b/src/include/pcp/trace.h new file mode 100644 index 0000000..af64d79 --- /dev/null +++ b/src/include/pcp/trace.h @@ -0,0 +1,110 @@ +/* + * Copyright (c) 1997 Silicon Graphics, Inc. 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 + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + */ +#ifndef _TRACE_H +#define _TRACE_H + +/* + * Transaction monitoring PMDA (trace) public interface. + * + * An example program using this interface can be found at + * $PCP_DEMOS_DIR/trace/demo.c and contains further doumentation. + * Also refer to the pmdatrace(1) and pmdatrace(3) man pages and + * the Performance Co-Pilot Programmer's Guide. + */ + +#ifdef __cplusplus +extern "C" { +#endif + +/* + * Add a new entry to the table of transactions currently being monitored, + * or update an existing entry. + */ +extern int pmtracebegin(const char *); + +/* + * Make measurements recorded for the given transaction tag available + * through the trace PMDA. + */ +extern int pmtraceend(const char *); + +/* + * Cancel a transaction which began from an earlier call to pmtracebegin, + * without exporting new data through the trace PMDA. + */ +extern int pmtraceabort(const char *); + +/* + * An alternate form of measurement can be obtained using pmtracepoint. + * This is a count-only measurement, and will result in the trace PMDA + * exporting the number of times a given code point is passed (ie. the + * the number of times a particular label has been passed to pmtracepoint. + */ +extern int pmtracepoint(const char *); + +/* + * An extension to pmtracepoint is pmtraceobs, with similar semantics to + * pmtracepoint except allowing an arbitrary numeric value (double) to be + * exported up through the PMAPI. + */ +extern int pmtraceobs(const char *, double); + +/* + * Similar to pmtraceobs is pmtracecounter, with the only difference + * being the way the trace PMDA exports the given numeric value to + * PMAPI clients (exported with counter semantics, rather than with + * instantaneous semantics which is the case with pmtraceobs). + */ +extern int pmtracecounter(const char *, double); + +/* + * Should any of these routines return a negative value, the return value + * can be passed to pmtraceerrstr for the associated error message. + * This performs a lookup into a static error message table, so the returned + * pointer must not be freed. + */ +extern char *pmtraceerrstr(int); + +#define PMTRACE_ERR_BASE 12000 +#define PMTRACE_ERR_TAGNAME (-PMTRACE_ERR_BASE-0) +#define PMTRACE_ERR_INPROGRESS (-PMTRACE_ERR_BASE-1) +#define PMTRACE_ERR_NOPROGRESS (-PMTRACE_ERR_BASE-2) +#define PMTRACE_ERR_NOSUCHTAG (-PMTRACE_ERR_BASE-3) +#define PMTRACE_ERR_TAGTYPE (-PMTRACE_ERR_BASE-4) +#define PMTRACE_ERR_TAGLENGTH (-PMTRACE_ERR_BASE-5) +#define PMTRACE_ERR_IPC (-PMTRACE_ERR_BASE-6) +#define PMTRACE_ERR_ENVFORMAT (-PMTRACE_ERR_BASE-7) +#define PMTRACE_ERR_TIMEOUT (-PMTRACE_ERR_BASE-8) +#define PMTRACE_ERR_VERSION (-PMTRACE_ERR_BASE-9) +#define PMTRACE_ERR_PERMISSION (-PMTRACE_ERR_BASE-10) +#define PMTRACE_ERR_CONNLIMIT (-PMTRACE_ERR_BASE-11) + +/* + * Diagnostic and state switching + */ +extern int pmtracestate(int code); + +#define PMTRACE_STATE_NONE 0 /* default: synchronous and no diagnostics */ +#define PMTRACE_STATE_API 1 /* debug: processing just below the API */ +#define PMTRACE_STATE_COMMS 2 /* debug: shows network-related activity */ +#define PMTRACE_STATE_PDU 4 /* debug: shows app<->PMDA IPC traffic */ +#define PMTRACE_STATE_PDUBUF 8 /* debug: internal IPC buffer management */ +#define PMTRACE_STATE_NOAGENT 16 /* debug: no PMDA communications at all */ +#define PMTRACE_STATE_ASYNC 32 /* control: use asynchronous PDU protocol */ + +#ifdef __cplusplus +} +#endif + +#endif /* _TRACE_H */ diff --git a/src/include/pcp/trace_dev.h b/src/include/pcp/trace_dev.h new file mode 100644 index 0000000..a237a97 --- /dev/null +++ b/src/include/pcp/trace_dev.h @@ -0,0 +1,95 @@ +/* + * Copyright (c) 1997-2001,2003 Silicon Graphics, Inc. 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 + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + */ + +#ifndef _TRACE_DEV_H +#define _TRACE_DEV_H + +#ifndef _PLATFORM_DEFS_H +#include "platform_defs.h" +#endif + +#ifdef _cplusplus +extern "C" { +#endif + +#define MAXTAGNAMELEN 256 + +#define TRACE_ENV_HOST "PCP_TRACE_HOST" +#define TRACE_ENV_PORT "PCP_TRACE_PORT" +#define TRACE_ENV_TIMEOUT "PCP_TRACE_TIMEOUT" +#define TRACE_ENV_NOAGENT "PCP_TRACE_NOAGENT" +#define TRACE_ENV_REQTIMEOUT "PCP_TRACE_REQTIMEOUT" +#define TRACE_ENV_RECTIMEOUT "PCP_TRACE_RECONNECT" +#define TRACE_PORT 4323 +#define TRACE_PDU_VERSION 1 + +#define TRACE_TYPE_TRANSACT 1 +#define TRACE_TYPE_POINT 2 +#define TRACE_TYPE_OBSERVE 3 +#define TRACE_TYPE_COUNTER 4 +#define TRACE_FIRST_TYPE TRACE_TYPE_TRANSACT +#define TRACE_LAST_TYPE TRACE_TYPE_COUNTER + +/* + * Protocol data unit (PDU) support snarfed from impl.h, pdu.c and pdubuf.c + */ +typedef struct { + int len; /* length of pdu_header + PDU */ + int type; /* PDU type */ + int from; /* pid of PDU originator */ +} __pmTracePDUHdr; + +typedef __uint32_t __pmTracePDU; + +extern int __pmtracexmitPDU(int, __pmTracePDU *); +extern int __pmtracegetPDU(int, int, __pmTracePDU **); + +/* for __pmtracegetPDU */ +#define TRACE_TIMEOUT_NEVER 0 +#define TRACE_TIMEOUT_DEFAULT -1 + +/* unit of space allocation for PDU buffer. */ +#define TRACE_PDU_CHUNK 1024 + +extern __pmTracePDU *__pmtracefindPDUbuf(int); +extern void __pmtracepinPDUbuf(void *); +extern int __pmtraceunpinPDUbuf(void *); +extern int __pmtracemoreinput(int); +extern void __pmtracenomoreinput(int); + + +#define TRACE_PDU_BASE 0x7050 +#define TRACE_PDU_ACK 0x7050 +#define TRACE_PDU_DATA 0x7051 +#define TRACE_PDU_MAX 2 + +extern int __pmtracesendack(int, int); +extern int __pmtracedecodeack(__pmTracePDU *, int *); +extern int __pmtracesenddata(int, char *, int, int, double); +extern int __pmtracedecodedata(__pmTracePDU *, char **, int *, int *, int *, double *); + +#define TRACE_PROTOCOL_FINAL -1 +#define TRACE_PROTOCOL_QUERY 0 +#define TRACE_PROTOCOL_ASYNC 1 +#define TRACE_PROTOCOL_SYNC 2 + +extern int __pmtraceprotocol(int); + +extern int __pmstate; + +#ifdef __cplusplus +} +#endif + +#endif /* _TRACE_DEV_H */ |