summaryrefslogtreecommitdiff
path: root/src/pmdas/linux_proc/pmda.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/pmdas/linux_proc/pmda.c')
-rw-r--r--src/pmdas/linux_proc/pmda.c1896
1 files changed, 1896 insertions, 0 deletions
diff --git a/src/pmdas/linux_proc/pmda.c b/src/pmdas/linux_proc/pmda.c
new file mode 100644
index 0000000..2d40a54
--- /dev/null
+++ b/src/pmdas/linux_proc/pmda.c
@@ -0,0 +1,1896 @@
+/*
+ * proc PMDA
+ *
+ * Copyright (c) 2000,2004,2007-2008 Silicon Graphics, Inc. All Rights Reserved.
+ * Portions Copyright (c) 2002 International Business Machines Corp.
+ * Portions Copyright (c) 2007-2011 Aconex. All Rights Reserved.
+ * Portions Copyright (c) 2012-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.
+ */
+
+#include "pmapi.h"
+#include "impl.h"
+#include "pmda.h"
+#include "domain.h"
+#include "contexts.h"
+
+#include <ctype.h>
+#include <unistd.h>
+#include <sys/vfs.h>
+#include <sys/stat.h>
+#include <sys/times.h>
+#include <sys/utsname.h>
+#include <utmp.h>
+#include <pwd.h>
+#include <grp.h>
+
+#include "../linux/convert.h"
+#include "clusters.h"
+#include "indom.h"
+
+#include "getinfo.h"
+#include "proc_pid.h"
+#include "proc_runq.h"
+#include "ksym.h"
+#include "cgroups.h"
+
+/* globals */
+static int _isDSO = 1; /* for local contexts */
+static proc_pid_t proc_pid;
+static struct utsname kernel_uname;
+static proc_runq_t proc_runq;
+static int all_access; /* =1 no access checks */
+static int have_access; /* =1 recvd uid/gid */
+static size_t _pm_system_pagesize;
+static unsigned int threads; /* control.all.threads */
+static char * cgroups; /* control.all.cgroups */
+
+char *proc_statspath = ""; /* optional path prefix for all stats files */
+
+/*
+ * The proc instance domain table is direct lookup and sparse.
+ * It is initialized in proc_init(), see below.
+ */
+static pmdaIndom indomtab[NUM_INDOMS];
+
+/*
+ * all metrics supported in this PMDA - one table entry for each
+ */
+static pmdaMetric metrictab[] = {
+
+/*
+ * proc/<pid>/stat cluster
+ */
+
+/* proc.nprocs */
+ { NULL,
+ { PMDA_PMID(CLUSTER_PID_STAT,99), PM_TYPE_U32, PM_INDOM_NULL, PM_SEM_INSTANT,
+ PMDA_PMUNITS(0,0,0,0,0,0) } },
+
+/* proc.psinfo.pid */
+ { NULL,
+ { PMDA_PMID(CLUSTER_PID_STAT,0), PM_TYPE_U32, PROC_INDOM, PM_SEM_DISCRETE,
+ PMDA_PMUNITS(0,0,0,0,0,0) } },
+
+/* proc.psinfo.cmd */
+ { NULL,
+ { PMDA_PMID(CLUSTER_PID_STAT,1), PM_TYPE_STRING, PROC_INDOM, PM_SEM_INSTANT,
+ PMDA_PMUNITS(0,0,0,0,0,0) } },
+
+/* proc.psinfo.sname */
+ { NULL,
+ { PMDA_PMID(CLUSTER_PID_STAT,2), PM_TYPE_STRING, PROC_INDOM, PM_SEM_INSTANT,
+ PMDA_PMUNITS(0,0,0,0,0,0) } },
+
+/* proc.psinfo.ppid */
+ { NULL,
+ { PMDA_PMID(CLUSTER_PID_STAT,3), PM_TYPE_U32, PROC_INDOM, PM_SEM_DISCRETE,
+ PMDA_PMUNITS(0,0,0,0,0,0) } },
+
+/* proc.psinfo.pgrp */
+ { NULL,
+ { PMDA_PMID(CLUSTER_PID_STAT,4), PM_TYPE_U32, PROC_INDOM, PM_SEM_DISCRETE,
+ PMDA_PMUNITS(0,0,0,0,0,0) } },
+
+/* proc.psinfo.session */
+ { NULL,
+ { PMDA_PMID(CLUSTER_PID_STAT,5), PM_TYPE_U32, PROC_INDOM, PM_SEM_DISCRETE,
+ PMDA_PMUNITS(0,0,0,0,0,0) } },
+
+/* proc.psinfo.tty */
+ { NULL,
+ { PMDA_PMID(CLUSTER_PID_STAT,6), PM_TYPE_U32, PROC_INDOM, PM_SEM_DISCRETE,
+ PMDA_PMUNITS(0,0,0,0,0,0) } },
+
+/* proc.psinfo.tty_pgrp */
+ { NULL,
+ { PMDA_PMID(CLUSTER_PID_STAT,7), PM_TYPE_U32, PROC_INDOM, PM_SEM_DISCRETE,
+ PMDA_PMUNITS(0,0,0,0,0,0) } },
+
+/* proc.psinfo.flags */
+ { NULL,
+ { PMDA_PMID(CLUSTER_PID_STAT,8), PM_TYPE_U32, PROC_INDOM, PM_SEM_DISCRETE,
+ PMDA_PMUNITS(0,0,0,0,0,0) } },
+
+/* proc.psinfo.minflt */
+ { NULL,
+ { PMDA_PMID(CLUSTER_PID_STAT,9), PM_TYPE_U32, PROC_INDOM, PM_SEM_COUNTER,
+ PMDA_PMUNITS(0,0,1,0,0,PM_COUNT_ONE) } },
+
+/* proc.psinfo.cmin_flt */
+ { NULL,
+ { PMDA_PMID(CLUSTER_PID_STAT,10), PM_TYPE_U32, PROC_INDOM, PM_SEM_COUNTER,
+ PMDA_PMUNITS(0,0,1,0,0,PM_COUNT_ONE) } },
+
+/* proc.psinfo.maj_flt */
+ { NULL,
+ { PMDA_PMID(CLUSTER_PID_STAT,11), PM_TYPE_U32, PROC_INDOM, PM_SEM_COUNTER,
+ PMDA_PMUNITS(0,0,1,0,0,PM_COUNT_ONE) } },
+
+/* proc.psinfo.cmaj_flt */
+ { NULL,
+ { PMDA_PMID(CLUSTER_PID_STAT,12), PM_TYPE_U32, PROC_INDOM, PM_SEM_COUNTER,
+ PMDA_PMUNITS(0,0,1,0,0,PM_COUNT_ONE) } },
+
+/* proc.psinfo.utime */
+ { NULL,
+ { PMDA_PMID(CLUSTER_PID_STAT,13), KERNEL_ULONG, PROC_INDOM, PM_SEM_COUNTER,
+ PMDA_PMUNITS(0,1,0,0,PM_TIME_MSEC,0) } },
+
+/* proc.psinfo.stime */
+ { NULL,
+ { PMDA_PMID(CLUSTER_PID_STAT,14), KERNEL_ULONG, PROC_INDOM, PM_SEM_COUNTER,
+ PMDA_PMUNITS(0,1,0,0,PM_TIME_MSEC,0) } },
+
+/* proc.psinfo.cutime */
+ { NULL,
+ { PMDA_PMID(CLUSTER_PID_STAT,15), KERNEL_ULONG, PROC_INDOM, PM_SEM_COUNTER,
+ PMDA_PMUNITS(0,1,0,0,PM_TIME_MSEC,0) } },
+
+/* proc.psinfo.cstime */
+ { NULL,
+ { PMDA_PMID(CLUSTER_PID_STAT,16), KERNEL_ULONG, PROC_INDOM, PM_SEM_COUNTER,
+ PMDA_PMUNITS(0,1,0,0,PM_TIME_MSEC,0) } },
+
+/* proc.psinfo.priority */
+ { NULL,
+ { PMDA_PMID(CLUSTER_PID_STAT,17), PM_TYPE_U32, PROC_INDOM, PM_SEM_DISCRETE,
+ PMDA_PMUNITS(0,0,0,0,0,0) } },
+
+/* proc.psinfo.nice */
+ { NULL,
+ { PMDA_PMID(CLUSTER_PID_STAT,18), PM_TYPE_U32, PROC_INDOM, PM_SEM_DISCRETE,
+ PMDA_PMUNITS(0,0,0,0,0,0) } },
+
+#if 0
+/* invalid field */
+ { NULL,
+ { PMDA_PMID(CLUSTER_PID_STAT,19), PM_TYPE_U32, PROC_INDOM, PM_SEM_INSTANT,
+ PMDA_PMUNITS(0,0,0,0,0,0) } },
+#endif
+
+/* proc.psinfo.it_real_value */
+ { NULL,
+ { PMDA_PMID(CLUSTER_PID_STAT,20), PM_TYPE_U32, PROC_INDOM, PM_SEM_DISCRETE,
+ PMDA_PMUNITS(0,0,0,0,0,0) } },
+
+/* proc.psinfo.start_time */
+ { NULL,
+ { PMDA_PMID(CLUSTER_PID_STAT,21), PM_TYPE_U32, PROC_INDOM, PM_SEM_DISCRETE,
+ PMDA_PMUNITS(0,1,0,0,PM_TIME_SEC,0) } },
+
+/* proc.psinfo.vsize */
+ { NULL,
+ { PMDA_PMID(CLUSTER_PID_STAT,22), PM_TYPE_U32, PROC_INDOM, PM_SEM_INSTANT,
+ PMDA_PMUNITS(1,0,0,PM_SPACE_KBYTE,0,0) } },
+
+/* proc.psinfo.rss */
+ { NULL,
+ { PMDA_PMID(CLUSTER_PID_STAT,23), PM_TYPE_U32, PROC_INDOM, PM_SEM_INSTANT,
+ PMDA_PMUNITS(1,0,0,PM_SPACE_KBYTE,0,0) } },
+
+/* proc.psinfo.rss_rlim */
+ { NULL,
+ { PMDA_PMID(CLUSTER_PID_STAT,24), PM_TYPE_U32, PROC_INDOM, PM_SEM_INSTANT,
+ PMDA_PMUNITS(1,0,0,PM_SPACE_KBYTE,0,0) } },
+
+/* proc.psinfo.start_code */
+ { NULL,
+ { PMDA_PMID(CLUSTER_PID_STAT,25), PM_TYPE_U32, PROC_INDOM, PM_SEM_DISCRETE,
+ PMDA_PMUNITS(0,0,0,0,0,0) } },
+
+/* proc.psinfo.end_code */
+ { NULL,
+ { PMDA_PMID(CLUSTER_PID_STAT,26), PM_TYPE_U32, PROC_INDOM, PM_SEM_DISCRETE,
+ PMDA_PMUNITS(0,0,0,0,0,0) } },
+
+/* proc.psinfo.start_stack */
+ { NULL,
+ { PMDA_PMID(CLUSTER_PID_STAT,27), PM_TYPE_U32, PROC_INDOM, PM_SEM_DISCRETE,
+ PMDA_PMUNITS(0,0,0,0,0,0) } },
+
+/* proc.psinfo.esp */
+ { NULL,
+ { PMDA_PMID(CLUSTER_PID_STAT,28), PM_TYPE_U32, PROC_INDOM, PM_SEM_DISCRETE,
+ PMDA_PMUNITS(0,0,0,0,0,0) } },
+
+/* proc.psinfo.eip */
+ { NULL,
+ { PMDA_PMID(CLUSTER_PID_STAT,29), PM_TYPE_U32, PROC_INDOM, PM_SEM_DISCRETE,
+ PMDA_PMUNITS(0,0,0,0,0,0) } },
+
+/* proc.psinfo.signal */
+ { NULL,
+ { PMDA_PMID(CLUSTER_PID_STAT,30), PM_TYPE_U32, PROC_INDOM, PM_SEM_DISCRETE,
+ PMDA_PMUNITS(0,0,0,0,0,0) } },
+
+/* proc.psinfo.blocked */
+ { NULL,
+ { PMDA_PMID(CLUSTER_PID_STAT,31), PM_TYPE_U32, PROC_INDOM, PM_SEM_DISCRETE,
+ PMDA_PMUNITS(0,0,0,0,0,0) } },
+
+/* proc.psinfo.sigignore */
+ { NULL,
+ { PMDA_PMID(CLUSTER_PID_STAT,32), PM_TYPE_U32, PROC_INDOM, PM_SEM_DISCRETE,
+ PMDA_PMUNITS(0,0,0,0,0,0) } },
+
+/* proc.psinfo.sigcatch */
+ { NULL,
+ { PMDA_PMID(CLUSTER_PID_STAT,33), PM_TYPE_U32, PROC_INDOM, PM_SEM_DISCRETE,
+ PMDA_PMUNITS(0,0,0,0,0,0) } },
+
+/* proc.psinfo.wchan */
+#if defined(HAVE_64BIT_PTR)
+ { NULL,
+ { PMDA_PMID(CLUSTER_PID_STAT,34), PM_TYPE_U64, PROC_INDOM, PM_SEM_DISCRETE,
+ PMDA_PMUNITS(0,0,0,0,0,0) } },
+#elif defined(HAVE_32BIT_PTR)
+ { NULL,
+ { PMDA_PMID(CLUSTER_PID_STAT,34), PM_TYPE_U32, PROC_INDOM, PM_SEM_DISCRETE,
+ PMDA_PMUNITS(0,0,0,0,0,0) } },
+#else
+ error! unsupported pointer size
+#endif
+
+/* proc.psinfo.nswap */
+ { NULL,
+ { PMDA_PMID(CLUSTER_PID_STAT,35), PM_TYPE_U32, PROC_INDOM, PM_SEM_COUNTER,
+ PMDA_PMUNITS(0,0,1,0,0,PM_COUNT_ONE) } },
+
+/* proc.psinfo.cnswap */
+ { NULL,
+ { PMDA_PMID(CLUSTER_PID_STAT,36), PM_TYPE_U32, PROC_INDOM, PM_SEM_COUNTER,
+ PMDA_PMUNITS(0,0,1,0,0,PM_COUNT_ONE) } },
+
+/* proc.psinfo.exit_signal */
+ { NULL,
+ { PMDA_PMID(CLUSTER_PID_STAT,37), PM_TYPE_U32, PROC_INDOM, PM_SEM_DISCRETE,
+ PMDA_PMUNITS(0,0,0,0,0,0) } },
+
+/* proc.psinfo.processor -- added by Mike Mason <mmlnx@us.ibm.com> */
+ { NULL,
+ { PMDA_PMID(CLUSTER_PID_STAT,38), PM_TYPE_U32, PROC_INDOM, PM_SEM_INSTANT,
+ PMDA_PMUNITS(0,0,0,0,0,0)}},
+
+/* proc.psinfo.ttyname */
+ { NULL,
+ { PMDA_PMID(CLUSTER_PID_STAT,39), PM_TYPE_STRING, PROC_INDOM, PM_SEM_INSTANT,
+ PMDA_PMUNITS(0,0,0,0,0,0) } },
+
+/* proc.psinfo.wchan_s -- added by Mike Mason <mmlnx@us.ibm.com> */
+ { NULL,
+ { PMDA_PMID(CLUSTER_PID_STAT,40), PM_TYPE_STRING, PROC_INDOM, PM_SEM_INSTANT,
+ PMDA_PMUNITS(0,0,0,0,0,0)}},
+
+/* proc.psinfo.psargs -- modified by Mike Mason <mmlnx@us.ibm.com> */
+ { NULL,
+ { PMDA_PMID(CLUSTER_PID_STAT,41), PM_TYPE_STRING, PROC_INDOM, PM_SEM_INSTANT,
+ PMDA_PMUNITS(0,0,0,0,0,0)}},
+
+/*
+ * proc/<pid>/status cluster
+ * Cluster added by Mike Mason <mmlnx@us.ibm.com>
+ */
+
+/* proc.id.uid */
+ { NULL,
+ { PMDA_PMID(CLUSTER_PID_STATUS,0), PM_TYPE_U32, PROC_INDOM, PM_SEM_DISCRETE,
+ PMDA_PMUNITS(0,0,0,0,0,0)}},
+
+/* proc.id.euid */
+ { NULL,
+ { PMDA_PMID(CLUSTER_PID_STATUS,1), PM_TYPE_U32, PROC_INDOM, PM_SEM_DISCRETE,
+ PMDA_PMUNITS(0,0,0,0,0,0)}},
+
+/* proc.id.suid */
+ { NULL,
+ { PMDA_PMID(CLUSTER_PID_STATUS,2), PM_TYPE_U32, PROC_INDOM, PM_SEM_DISCRETE,
+ PMDA_PMUNITS(0,0,0,0,0,0)}},
+
+/* proc.id.fsuid */
+ { NULL,
+ { PMDA_PMID(CLUSTER_PID_STATUS,3), PM_TYPE_U32, PROC_INDOM, PM_SEM_DISCRETE,
+ PMDA_PMUNITS(0,0,0,0,0,0)}},
+
+/* proc.id.gid */
+ { NULL,
+ { PMDA_PMID(CLUSTER_PID_STATUS,4), PM_TYPE_U32, PROC_INDOM, PM_SEM_DISCRETE,
+ PMDA_PMUNITS(0,0,0,0,0,0)}},
+
+/* proc.id.egid */
+ { NULL,
+ { PMDA_PMID(CLUSTER_PID_STATUS,5), PM_TYPE_U32, PROC_INDOM, PM_SEM_DISCRETE,
+ PMDA_PMUNITS(0,0,0,0,0,0)}},
+
+/* proc.id.sgid */
+ { NULL,
+ { PMDA_PMID(CLUSTER_PID_STATUS,6), PM_TYPE_U32, PROC_INDOM, PM_SEM_DISCRETE,
+ PMDA_PMUNITS(0,0,0,0,0,0)}},
+
+/* proc.id.fsgid */
+ { NULL,
+ { PMDA_PMID(CLUSTER_PID_STATUS,7), PM_TYPE_U32, PROC_INDOM, PM_SEM_DISCRETE,
+ PMDA_PMUNITS(0,0,0,0,0,0)}},
+
+/* proc.id.uid_nm */
+ { NULL,
+ { PMDA_PMID(CLUSTER_PID_STATUS,8), PM_TYPE_STRING, PROC_INDOM, PM_SEM_DISCRETE,
+ PMDA_PMUNITS(0,0,0,0,0,0)}},
+
+/* proc.id.euid_nm */
+ { NULL,
+ { PMDA_PMID(CLUSTER_PID_STATUS,9), PM_TYPE_STRING, PROC_INDOM, PM_SEM_DISCRETE,
+ PMDA_PMUNITS(0,0,0,0,0,0)}},
+
+/* proc.id.suid_nm */
+ { NULL,
+ { PMDA_PMID(CLUSTER_PID_STATUS,10), PM_TYPE_STRING, PROC_INDOM, PM_SEM_DISCRETE,
+ PMDA_PMUNITS(0,0,0,0,0,0)}},
+
+/* proc.id.fsuid_nm */
+ { NULL,
+ { PMDA_PMID(CLUSTER_PID_STATUS,11), PM_TYPE_STRING, PROC_INDOM, PM_SEM_DISCRETE,
+ PMDA_PMUNITS(0,0,0,0,0,0)}},
+
+/* proc.id.gid_nm */
+ { NULL,
+ { PMDA_PMID(CLUSTER_PID_STATUS,12), PM_TYPE_STRING, PROC_INDOM, PM_SEM_DISCRETE,
+ PMDA_PMUNITS(0,0,0,0,0,0)}},
+
+/* proc.id.egid_nm */
+ { NULL,
+ { PMDA_PMID(CLUSTER_PID_STATUS,13), PM_TYPE_STRING, PROC_INDOM, PM_SEM_DISCRETE,
+ PMDA_PMUNITS(0,0,0,0,0,0)}},
+
+/* proc.id.sgid_nm */
+ { NULL,
+ { PMDA_PMID(CLUSTER_PID_STATUS,14), PM_TYPE_STRING, PROC_INDOM, PM_SEM_DISCRETE,
+ PMDA_PMUNITS(0,0,0,0,0,0)}},
+
+/* proc.id.fsgid_nm */
+ { NULL,
+ { PMDA_PMID(CLUSTER_PID_STATUS,15), PM_TYPE_STRING, PROC_INDOM, PM_SEM_DISCRETE,
+ PMDA_PMUNITS(0,0,0,0,0,0)}},
+
+/* proc.psinfo.signal_s */
+ { NULL,
+ { PMDA_PMID(CLUSTER_PID_STATUS,16), PM_TYPE_STRING, PROC_INDOM, PM_SEM_INSTANT,
+ PMDA_PMUNITS(0,0,0,0,0,0)}},
+
+/* proc.psinfo.blocked_s */
+ { NULL,
+ { PMDA_PMID(CLUSTER_PID_STATUS,17), PM_TYPE_STRING, PROC_INDOM, PM_SEM_INSTANT,
+ PMDA_PMUNITS(0,0,0,0,0,0)}},
+
+/* proc.psinfo.sigignore_s */
+ { NULL,
+ { PMDA_PMID(CLUSTER_PID_STATUS,18), PM_TYPE_STRING, PROC_INDOM, PM_SEM_INSTANT,
+ PMDA_PMUNITS(0,0,0,0,0,0)}},
+
+/* proc.psinfo.sigcatch_s */
+ { NULL,
+ { PMDA_PMID(CLUSTER_PID_STATUS,19), PM_TYPE_STRING, PROC_INDOM, PM_SEM_INSTANT,
+ PMDA_PMUNITS(0,0,0,0,0,0)}},
+
+/* proc.memory.vmsize */
+ { NULL,
+ { PMDA_PMID(CLUSTER_PID_STATUS,20), PM_TYPE_U32, PROC_INDOM, PM_SEM_INSTANT,
+ PMDA_PMUNITS(1,0,0,PM_SPACE_KBYTE,0,0)}},
+
+/* proc.memory.vmlock */
+ { NULL,
+ { PMDA_PMID(CLUSTER_PID_STATUS,21), PM_TYPE_U32, PROC_INDOM, PM_SEM_INSTANT,
+ PMDA_PMUNITS(1,0,0,PM_SPACE_KBYTE,0,0)}},
+
+/* proc.memory.vmrss */
+ { NULL,
+ { PMDA_PMID(CLUSTER_PID_STATUS,22), PM_TYPE_U32, PROC_INDOM, PM_SEM_INSTANT,
+ PMDA_PMUNITS(1,0,0,PM_SPACE_KBYTE,0,0)}},
+
+/* proc.memory.vmdata */
+ { NULL,
+ { PMDA_PMID(CLUSTER_PID_STATUS,23), PM_TYPE_U32, PROC_INDOM, PM_SEM_INSTANT,
+ PMDA_PMUNITS(1,0,0,PM_SPACE_KBYTE,0,0)}},
+
+/* proc.memory.vmstack */
+ { NULL,
+ { PMDA_PMID(CLUSTER_PID_STATUS,24), PM_TYPE_U32, PROC_INDOM, PM_SEM_INSTANT,
+ PMDA_PMUNITS(1,0,0,PM_SPACE_KBYTE,0,0)}},
+
+/* proc.memory.vmexe */
+ { NULL,
+ { PMDA_PMID(CLUSTER_PID_STATUS,25), PM_TYPE_U32, PROC_INDOM, PM_SEM_INSTANT,
+ PMDA_PMUNITS(1,0,0,PM_SPACE_KBYTE,0,0)}},
+
+/* proc.memory.vmlib */
+ { NULL,
+ { PMDA_PMID(CLUSTER_PID_STATUS,26), PM_TYPE_U32, PROC_INDOM, PM_SEM_INSTANT,
+ PMDA_PMUNITS(1,0,0,PM_SPACE_KBYTE,0,0)}},
+
+/* proc.memory.vmswap */
+ { NULL,
+ { PMDA_PMID(CLUSTER_PID_STATUS,27), PM_TYPE_U32, PROC_INDOM, PM_SEM_INSTANT,
+ PMDA_PMUNITS(1,0,0,PM_SPACE_KBYTE,0,0)}},
+
+/* proc.psinfo.threads */
+ { NULL,
+ { PMDA_PMID(CLUSTER_PID_STATUS,28), PM_TYPE_U32, PROC_INDOM, PM_SEM_INSTANT,
+ PMDA_PMUNITS(0,0,0,0,0,0)}},
+
+/* proc.psinfo.cgroups */
+ { NULL,
+ { PMDA_PMID(CLUSTER_PID_CGROUP,0), PM_TYPE_STRING, PROC_INDOM, PM_SEM_INSTANT,
+ PMDA_PMUNITS(0,0,0,0,0,0)}},
+
+/* proc.psinfo.labels */
+ { NULL,
+ { PMDA_PMID(CLUSTER_PID_LABEL,0), PM_TYPE_STRING, PROC_INDOM, PM_SEM_INSTANT,
+ PMDA_PMUNITS(0,0,0,0,0,0)}},
+
+
+/*
+ * proc/<pid>/statm cluster
+ */
+
+/* proc.memory.size */
+ { NULL,
+ { PMDA_PMID(CLUSTER_PID_STATM,0), PM_TYPE_U32, PROC_INDOM, PM_SEM_INSTANT,
+ PMDA_PMUNITS(1,0,0,PM_SPACE_KBYTE,0,0) } },
+
+/* proc.memory.rss */
+ { NULL,
+ { PMDA_PMID(CLUSTER_PID_STATM,1), PM_TYPE_U32, PROC_INDOM, PM_SEM_INSTANT,
+ PMDA_PMUNITS(1,0,0,PM_SPACE_KBYTE,0,0) } },
+
+/* proc.memory.share */
+ { NULL,
+ { PMDA_PMID(CLUSTER_PID_STATM,2), PM_TYPE_U32, PROC_INDOM, PM_SEM_INSTANT,
+ PMDA_PMUNITS(1,0,0,PM_SPACE_KBYTE,0,0) } },
+
+/* proc.memory.textrss */
+ { NULL,
+ { PMDA_PMID(CLUSTER_PID_STATM,3), PM_TYPE_U32, PROC_INDOM, PM_SEM_INSTANT,
+ PMDA_PMUNITS(1,0,0,PM_SPACE_KBYTE,0,0) } },
+
+/* proc.memory.librss */
+ { NULL,
+ { PMDA_PMID(CLUSTER_PID_STATM,4), PM_TYPE_U32, PROC_INDOM, PM_SEM_INSTANT,
+ PMDA_PMUNITS(1,0,0,PM_SPACE_KBYTE,0,0) } },
+
+/* proc.memory.datrss */
+ { NULL,
+ { PMDA_PMID(CLUSTER_PID_STATM,5), PM_TYPE_U32, PROC_INDOM, PM_SEM_INSTANT,
+ PMDA_PMUNITS(1,0,0,PM_SPACE_KBYTE,0,0) } },
+
+/* proc.memory.dirty */
+ { NULL,
+ { PMDA_PMID(CLUSTER_PID_STATM,6), PM_TYPE_U32, PROC_INDOM, PM_SEM_INSTANT,
+ PMDA_PMUNITS(1,0,0,PM_SPACE_KBYTE,0,0) } },
+
+/* proc.memory.maps -- added by Mike Mason <mmlnx@us.ibm.com> */
+ { NULL,
+ { PMDA_PMID(CLUSTER_PID_STATM,7), PM_TYPE_STRING, PROC_INDOM, PM_SEM_INSTANT,
+ PMDA_PMUNITS(0,0,0,0,0,0)}},
+
+/*
+ * proc/<pid>/schedstat cluster
+ */
+
+/* proc.schedstat.cpu_time */
+ { NULL,
+ { PMDA_PMID(CLUSTER_PID_SCHEDSTAT,0), PM_TYPE_U64, PROC_INDOM, PM_SEM_COUNTER,
+ PMDA_PMUNITS(0,1,0,0,PM_TIME_NSEC,0)}},
+/* proc.schedstat.run_delay */
+ { NULL,
+ { PMDA_PMID(CLUSTER_PID_SCHEDSTAT,1), PM_TYPE_U64, PROC_INDOM, PM_SEM_COUNTER,
+ PMDA_PMUNITS(0,1,0,0,PM_TIME_NSEC,0)}},
+/* proc.schedstat.pcount */
+ { NULL,
+ { PMDA_PMID(CLUSTER_PID_SCHEDSTAT,2), KERNEL_ULONG, PROC_INDOM, PM_SEM_COUNTER,
+ PMDA_PMUNITS(0,0,1,0,0,PM_COUNT_ONE)}},
+
+/*
+ * proc/<pid>/io cluster
+ */
+/* proc.io.rchar */
+ { NULL,
+ { PMDA_PMID(CLUSTER_PID_IO,0), PM_TYPE_U64, PROC_INDOM, PM_SEM_COUNTER,
+ PMDA_PMUNITS(1,0,0,PM_SPACE_BYTE,0,0)}},
+/* proc.io.wchar */
+ { NULL,
+ { PMDA_PMID(CLUSTER_PID_IO,1), PM_TYPE_U64, PROC_INDOM, PM_SEM_COUNTER,
+ PMDA_PMUNITS(1,0,0,PM_SPACE_BYTE,0,0)}},
+/* proc.io.syscr */
+ { NULL,
+ { PMDA_PMID(CLUSTER_PID_IO,2), PM_TYPE_U64, PROC_INDOM, PM_SEM_COUNTER,
+ PMDA_PMUNITS(0,0,1,0,0,PM_COUNT_ONE)}},
+/* proc.io.syscw */
+ { NULL,
+ { PMDA_PMID(CLUSTER_PID_IO,3), PM_TYPE_U64, PROC_INDOM, PM_SEM_COUNTER,
+ PMDA_PMUNITS(0,0,1,0,0,PM_COUNT_ONE)}},
+/* proc.io.read_bytes */
+ { NULL,
+ { PMDA_PMID(CLUSTER_PID_IO,4), PM_TYPE_U64, PROC_INDOM, PM_SEM_COUNTER,
+ PMDA_PMUNITS(1,0,0,PM_SPACE_BYTE,0,0)}},
+/* proc.io.write_bytes */
+ { NULL,
+ { PMDA_PMID(CLUSTER_PID_IO,5), PM_TYPE_U64, PROC_INDOM, PM_SEM_COUNTER,
+ PMDA_PMUNITS(1,0,0,PM_SPACE_BYTE,0,0)}},
+/* proc.io.cancelled_write_bytes */
+ { NULL,
+ { PMDA_PMID(CLUSTER_PID_IO,6), PM_TYPE_U64, PROC_INDOM, PM_SEM_COUNTER,
+ PMDA_PMUNITS(1,0,0,PM_SPACE_BYTE,0,0)}},
+
+/*
+ * proc.runq cluster
+ */
+
+/* proc.runq.runnable */
+ { &proc_runq.runnable,
+ { PMDA_PMID(CLUSTER_PROC_RUNQ, 0), PM_TYPE_32, PM_INDOM_NULL, PM_SEM_INSTANT,
+ PMDA_PMUNITS(0,0,1,0,0,PM_COUNT_ONE) } },
+
+/* proc.runq.blocked */
+ { &proc_runq.blocked,
+ { PMDA_PMID(CLUSTER_PROC_RUNQ, 1), PM_TYPE_32, PM_INDOM_NULL, PM_SEM_INSTANT,
+ PMDA_PMUNITS(0,0,1,0,0,PM_COUNT_ONE) } },
+
+/* proc.runq.sleeping */
+ { &proc_runq.sleeping,
+ { PMDA_PMID(CLUSTER_PROC_RUNQ, 2), PM_TYPE_32, PM_INDOM_NULL, PM_SEM_INSTANT,
+ PMDA_PMUNITS(0,0,1,0,0,PM_COUNT_ONE) } },
+
+/* proc.runq.stopped */
+ { &proc_runq.stopped,
+ { PMDA_PMID(CLUSTER_PROC_RUNQ, 3), PM_TYPE_32, PM_INDOM_NULL, PM_SEM_INSTANT,
+ PMDA_PMUNITS(0,0,1,0,0,PM_COUNT_ONE) } },
+
+/* proc.runq.swapped */
+ { &proc_runq.swapped,
+ { PMDA_PMID(CLUSTER_PROC_RUNQ, 4), PM_TYPE_32, PM_INDOM_NULL, PM_SEM_INSTANT,
+ PMDA_PMUNITS(0,0,1,0,0,PM_COUNT_ONE) } },
+
+/* proc.runq.defunct */
+ { &proc_runq.defunct,
+ { PMDA_PMID(CLUSTER_PROC_RUNQ, 5), PM_TYPE_32, PM_INDOM_NULL, PM_SEM_INSTANT,
+ PMDA_PMUNITS(0,0,1,0,0,PM_COUNT_ONE) } },
+
+/* proc.runq.unknown */
+ { &proc_runq.unknown,
+ { PMDA_PMID(CLUSTER_PROC_RUNQ, 6), PM_TYPE_32, PM_INDOM_NULL, PM_SEM_INSTANT,
+ PMDA_PMUNITS(0,0,1,0,0,PM_COUNT_ONE) } },
+
+/* proc.runq.kernel */
+ { &proc_runq.kernel,
+ { PMDA_PMID(CLUSTER_PROC_RUNQ, 7), PM_TYPE_32, PM_INDOM_NULL, PM_SEM_INSTANT,
+ PMDA_PMUNITS(0,0,1,0,0,PM_COUNT_ONE) } },
+
+/*
+ * control groups cluster
+ */
+ /* cgroups.subsys.hierarchy */
+ { NULL, {PMDA_PMID(CLUSTER_CGROUP_SUBSYS,0), PM_TYPE_U32,
+ CGROUP_SUBSYS_INDOM, PM_SEM_INSTANT, PMDA_PMUNITS(0,0,0,0,0,0) }, },
+
+ /* cgroups.subsys.count */
+ { NULL, {PMDA_PMID(CLUSTER_CGROUP_SUBSYS,1), PM_TYPE_U32,
+ PM_INDOM_NULL, PM_SEM_INSTANT, PMDA_PMUNITS(0,0,1,0,0,PM_COUNT_ONE) }, },
+
+ /* cgroups.mounts.subsys */
+ { NULL, {PMDA_PMID(CLUSTER_CGROUP_MOUNTS,0), PM_TYPE_STRING,
+ CGROUP_MOUNTS_INDOM, PM_SEM_INSTANT, PMDA_PMUNITS(0,0,0,0,0,0) }, },
+
+ /* cgroups.mounts.count */
+ { NULL, {PMDA_PMID(CLUSTER_CGROUP_MOUNTS,1), PM_TYPE_U32,
+ PM_INDOM_NULL, PM_SEM_INSTANT, PMDA_PMUNITS(0,0,1,0,0,PM_COUNT_ONE) }, },
+
+ /* cgroup.groups.cpuset.[<group>.]cpus */
+ { NULL, {PMDA_PMID(CLUSTER_CPUSET_GROUPS,0), PM_TYPE_STRING,
+ PM_INDOM_NULL, PM_SEM_INSTANT, PMDA_PMUNITS(0,0,0,0,0,0) }, },
+
+ /* cgroup.groups.cpuset.[<group>.]mems */
+ { NULL, {PMDA_PMID(CLUSTER_CPUSET_GROUPS,0), PM_TYPE_STRING,
+ PM_INDOM_NULL, PM_SEM_INSTANT, PMDA_PMUNITS(0,0,0,0,0,0) }, },
+
+ /* cgroup.groups.cpuacct.[<group>.]stat.user */
+ { NULL, {PMDA_PMID(CLUSTER_CPUACCT_GROUPS,0), PM_TYPE_U64,
+ PM_INDOM_NULL, PM_SEM_COUNTER, PMDA_PMUNITS(0,1,0,0,PM_TIME_MSEC,0) }, },
+
+ /* cgroup.groups.cpuacct.[<group>.]stat.system */
+ { NULL, {PMDA_PMID(CLUSTER_CPUACCT_GROUPS,0), PM_TYPE_U64,
+ PM_INDOM_NULL, PM_SEM_COUNTER, PMDA_PMUNITS(0,1,0,0,PM_TIME_MSEC,0) }, },
+
+ /* cgroup.groups.cpuacct.[<group>.]usage */
+ { NULL, {PMDA_PMID(CLUSTER_CPUACCT_GROUPS,0), PM_TYPE_U64,
+ PM_INDOM_NULL, PM_SEM_COUNTER, PMDA_PMUNITS(0,1,0,0,PM_TIME_NSEC,0) }, },
+
+ /* cgroup.groups.cpuacct.[<group>.]usage_percpu */
+ { NULL, {PMDA_PMID(CLUSTER_CPUACCT_GROUPS,0), PM_TYPE_U64,
+ CPU_INDOM, PM_SEM_COUNTER, PMDA_PMUNITS(0,1,0,0,PM_TIME_NSEC,0) }, },
+
+ /* cgroup.groups.cpusched.[<group>.]shares */
+ { NULL, {PMDA_PMID(CLUSTER_CPUSCHED_GROUPS,0), PM_TYPE_U64,
+ PM_INDOM_NULL, PM_SEM_COUNTER, PMDA_PMUNITS(0,0,0,0,0,0) }, },
+
+ /* cgroup.groups.memory.[<group>.]stat.cache */
+ { NULL, {PMDA_PMID(CLUSTER_MEMORY_GROUPS,0), PM_TYPE_U64,
+ PM_INDOM_NULL, PM_SEM_INSTANT, PMDA_PMUNITS(1,0,0,PM_SPACE_KBYTE,0,0) }, },
+
+ /* cgroup.groups.memory.[<group>.]stat.rss */
+ { NULL, {PMDA_PMID(CLUSTER_MEMORY_GROUPS,0), PM_TYPE_U64,
+ PM_INDOM_NULL, PM_SEM_INSTANT, PMDA_PMUNITS(1,0,0,PM_SPACE_KBYTE,0,0) }, },
+
+ /* cgroup.groups.memory.[<group>.]stat.rss_huge */
+ { NULL, {PMDA_PMID(CLUSTER_MEMORY_GROUPS,0), PM_TYPE_U64,
+ PM_INDOM_NULL, PM_SEM_INSTANT, PMDA_PMUNITS(1,0,0,PM_SPACE_KBYTE,0,0) }, },
+
+ /* cgroup.groups.memory.[<group>.]stat.mapped_file */
+ { NULL, {PMDA_PMID(CLUSTER_MEMORY_GROUPS,0), PM_TYPE_U64,
+ PM_INDOM_NULL, PM_SEM_INSTANT, PMDA_PMUNITS(1,0,0,PM_SPACE_KBYTE,0,0) }, },
+
+ /* cgroup.groups.memory.[<group>.]stat.writeback */
+ { NULL, {PMDA_PMID(CLUSTER_MEMORY_GROUPS,0), PM_TYPE_U64,
+ PM_INDOM_NULL, PM_SEM_INSTANT, PMDA_PMUNITS(1,0,0,PM_SPACE_KBYTE,0,0) }, },
+
+ /* cgroup.groups.memory.[<group>.]stat.swap */
+ { NULL, {PMDA_PMID(CLUSTER_MEMORY_GROUPS,0), PM_TYPE_U64,
+ PM_INDOM_NULL, PM_SEM_INSTANT, PMDA_PMUNITS(1,0,0,PM_SPACE_KBYTE,0,0) }, },
+
+ /* cgroup.groups.memory.[<group>.]stat.pgpgin */
+ { NULL, {PMDA_PMID(CLUSTER_MEMORY_GROUPS,0), PM_TYPE_U64,
+ PM_INDOM_NULL, PM_SEM_INSTANT, PMDA_PMUNITS(1,0,0,PM_SPACE_KBYTE,0,0) }, },
+
+ /* cgroup.groups.memory.[<group>.]stat.pgpgout */
+ { NULL, {PMDA_PMID(CLUSTER_MEMORY_GROUPS,0), PM_TYPE_U64,
+ PM_INDOM_NULL, PM_SEM_INSTANT, PMDA_PMUNITS(1,0,0,PM_SPACE_KBYTE,0,0) }, },
+
+ /* cgroup.groups.memory.[<group>.]stat.pgfault */
+ { NULL, {PMDA_PMID(CLUSTER_MEMORY_GROUPS,0), PM_TYPE_U64,
+ PM_INDOM_NULL, PM_SEM_COUNTER, PMDA_PMUNITS(1,0,0,PM_SPACE_KBYTE,0,0) }, },
+
+ /* cgroup.groups.memory.[<group>.]stat.pgmajfault */
+ { NULL, {PMDA_PMID(CLUSTER_MEMORY_GROUPS,0), PM_TYPE_U64,
+ PM_INDOM_NULL, PM_SEM_COUNTER, PMDA_PMUNITS(1,0,0,PM_SPACE_KBYTE,0,0) }, },
+
+ /* cgroup.groups.memory.[<group>.]stat.inactive_anon */
+ { NULL, {PMDA_PMID(CLUSTER_MEMORY_GROUPS,0), PM_TYPE_U64,
+ PM_INDOM_NULL, PM_SEM_COUNTER, PMDA_PMUNITS(1,0,0,PM_SPACE_KBYTE,0,0) }, },
+
+ /* cgroup.groups.memory.[<group>.]stat.active_anon */
+ { NULL, {PMDA_PMID(CLUSTER_MEMORY_GROUPS,0), PM_TYPE_U64,
+ PM_INDOM_NULL, PM_SEM_COUNTER, PMDA_PMUNITS(1,0,0,PM_SPACE_KBYTE,0,0) }, },
+
+ /* cgroup.groups.memory.[<group>.]stat.inactive_file */
+ { NULL, {PMDA_PMID(CLUSTER_MEMORY_GROUPS,0), PM_TYPE_U64,
+ PM_INDOM_NULL, PM_SEM_COUNTER, PMDA_PMUNITS(1,0,0,PM_SPACE_KBYTE,0,0) }, },
+
+ /* cgroup.groups.memory.[<group>.]stat.active_file */
+ { NULL, {PMDA_PMID(CLUSTER_MEMORY_GROUPS,0), PM_TYPE_U64,
+ PM_INDOM_NULL, PM_SEM_COUNTER, PMDA_PMUNITS(1,0,0,PM_SPACE_KBYTE,0,0) }, },
+
+ /* cgroup.groups.memory.[<group>.]stat.unevictable */
+ { NULL, {PMDA_PMID(CLUSTER_MEMORY_GROUPS,0), PM_TYPE_U64,
+ PM_INDOM_NULL, PM_SEM_COUNTER, PMDA_PMUNITS(1,0,0,PM_SPACE_KBYTE,0,0) }, },
+
+ /* cgroup.groups.memory.[<group>.]stat.total_cache */
+ { NULL, {PMDA_PMID(CLUSTER_MEMORY_GROUPS,0), PM_TYPE_U64,
+ PM_INDOM_NULL, PM_SEM_INSTANT, PMDA_PMUNITS(1,0,0,PM_SPACE_KBYTE,0,0) }, },
+
+ /* cgroup.groups.memory.[<group>.]stat.total_rss */
+ { NULL, {PMDA_PMID(CLUSTER_MEMORY_GROUPS,0), PM_TYPE_U64,
+ PM_INDOM_NULL, PM_SEM_INSTANT, PMDA_PMUNITS(1,0,0,PM_SPACE_KBYTE,0,0) }, },
+
+ /* cgroup.groups.memory.[<group>.]stat.total_rss_huge */
+ { NULL, {PMDA_PMID(CLUSTER_MEMORY_GROUPS,0), PM_TYPE_U64,
+ PM_INDOM_NULL, PM_SEM_INSTANT, PMDA_PMUNITS(1,0,0,PM_SPACE_KBYTE,0,0) }, },
+
+ /* cgroup.groups.memory.[<group>.]stat.total_mapped_file */
+ { NULL, {PMDA_PMID(CLUSTER_MEMORY_GROUPS,0), PM_TYPE_U64,
+ PM_INDOM_NULL, PM_SEM_INSTANT, PMDA_PMUNITS(1,0,0,PM_SPACE_KBYTE,0,0) }, },
+
+ /* cgroup.groups.memory.[<group>.]stat.total_writeback */
+ { NULL, {PMDA_PMID(CLUSTER_MEMORY_GROUPS,0), PM_TYPE_U64,
+ PM_INDOM_NULL, PM_SEM_INSTANT, PMDA_PMUNITS(1,0,0,PM_SPACE_KBYTE,0,0) }, },
+
+ /* cgroup.groups.memory.[<group>.]stat.total_swap */
+ { NULL, {PMDA_PMID(CLUSTER_MEMORY_GROUPS,0), PM_TYPE_U64,
+ PM_INDOM_NULL, PM_SEM_INSTANT, PMDA_PMUNITS(1,0,0,PM_SPACE_KBYTE,0,0) }, },
+
+ /* cgroup.groups.memory.[<group>.]stat.total_pgpgin */
+ { NULL, {PMDA_PMID(CLUSTER_MEMORY_GROUPS,0), PM_TYPE_U64,
+ PM_INDOM_NULL, PM_SEM_INSTANT, PMDA_PMUNITS(1,0,0,PM_SPACE_KBYTE,0,0) }, },
+
+ /* cgroup.groups.memory.[<group>.]stat.total_pgpgout */
+ { NULL, {PMDA_PMID(CLUSTER_MEMORY_GROUPS,0), PM_TYPE_U64,
+ PM_INDOM_NULL, PM_SEM_INSTANT, PMDA_PMUNITS(1,0,0,PM_SPACE_KBYTE,0,0) }, },
+
+ /* cgroup.groups.memory.[<group>.]stat.total_pgfault */
+ { NULL, {PMDA_PMID(CLUSTER_MEMORY_GROUPS,0), PM_TYPE_U64,
+ PM_INDOM_NULL, PM_SEM_COUNTER, PMDA_PMUNITS(1,0,0,PM_SPACE_KBYTE,0,0) }, },
+
+ /* cgroup.groups.memory.[<group>.]stat.total_pgmajfault */
+ { NULL, {PMDA_PMID(CLUSTER_MEMORY_GROUPS,0), PM_TYPE_U64,
+ PM_INDOM_NULL, PM_SEM_COUNTER, PMDA_PMUNITS(1,0,0,PM_SPACE_KBYTE,0,0) }, },
+
+ /* cgroup.groups.memory.[<group>.]stat.total_inactive_anon */
+ { NULL, {PMDA_PMID(CLUSTER_MEMORY_GROUPS,0), PM_TYPE_U64,
+ PM_INDOM_NULL, PM_SEM_COUNTER, PMDA_PMUNITS(1,0,0,PM_SPACE_KBYTE,0,0) }, },
+
+ /* cgroup.groups.memory.[<group>.]stat.total_active_anon */
+ { NULL, {PMDA_PMID(CLUSTER_MEMORY_GROUPS,0), PM_TYPE_U64,
+ PM_INDOM_NULL, PM_SEM_COUNTER, PMDA_PMUNITS(1,0,0,PM_SPACE_KBYTE,0,0) }, },
+
+ /* cgroup.groups.memory.[<group>.]stat.total_inactive_file */
+ { NULL, {PMDA_PMID(CLUSTER_MEMORY_GROUPS,0), PM_TYPE_U64,
+ PM_INDOM_NULL, PM_SEM_COUNTER, PMDA_PMUNITS(1,0,0,PM_SPACE_KBYTE,0,0) }, },
+
+ /* cgroup.groups.memory.[<group>.]stat.total_active_file */
+ { NULL, {PMDA_PMID(CLUSTER_MEMORY_GROUPS,0), PM_TYPE_U64,
+ PM_INDOM_NULL, PM_SEM_COUNTER, PMDA_PMUNITS(1,0,0,PM_SPACE_KBYTE,0,0) }, },
+
+ /* cgroup.groups.memory.[<group>.]stat.total_unevictable */
+ { NULL, {PMDA_PMID(CLUSTER_MEMORY_GROUPS,0), PM_TYPE_U64,
+ PM_INDOM_NULL, PM_SEM_COUNTER, PMDA_PMUNITS(1,0,0,PM_SPACE_KBYTE,0,0) }, },
+
+ /* cgroup.groups.memory.[<group>.]stat.recent_rotated_anon */
+ { NULL, {PMDA_PMID(CLUSTER_MEMORY_GROUPS,0), PM_TYPE_U64,
+ PM_INDOM_NULL, PM_SEM_COUNTER, PMDA_PMUNITS(1,0,0,PM_SPACE_KBYTE,0,0) }, },
+
+ /* cgroup.groups.memory.[<group>.]stat.recent_rotated_file */
+ { NULL, {PMDA_PMID(CLUSTER_MEMORY_GROUPS,0), PM_TYPE_U64,
+ PM_INDOM_NULL, PM_SEM_COUNTER, PMDA_PMUNITS(1,0,0,PM_SPACE_KBYTE,0,0) }, },
+
+ /* cgroup.groups.memory.[<group>.]stat.recent_scanned_anon */
+ { NULL, {PMDA_PMID(CLUSTER_MEMORY_GROUPS,0), PM_TYPE_U64,
+ PM_INDOM_NULL, PM_SEM_COUNTER, PMDA_PMUNITS(1,0,0,PM_SPACE_KBYTE,0,0) }, },
+
+ /* cgroup.groups.memory.[<group>.]stat.recent_scanned_file */
+ { NULL, {PMDA_PMID(CLUSTER_MEMORY_GROUPS,0), PM_TYPE_U64,
+ PM_INDOM_NULL, PM_SEM_COUNTER, PMDA_PMUNITS(1,0,0,PM_SPACE_KBYTE,0,0) }, },
+
+ /* cgroup.groups.netclass.[<group>.]classid */
+ { NULL, {PMDA_PMID(CLUSTER_NET_CLS_GROUPS,0), PM_TYPE_U64,
+ PM_INDOM_NULL, PM_SEM_COUNTER, PMDA_PMUNITS(1,0,0,PM_SPACE_KBYTE,0,0) }, },
+
+ /* cgroup.groups.blkio.[<group>.]io_merged.read */
+ { NULL, {PMDA_PMID(CLUSTER_BLKIO_GROUPS,0), PM_TYPE_U64,
+ DISK_INDOM, PM_SEM_COUNTER, PMDA_PMUNITS(0,0,1,0,0,PM_COUNT_ONE) }, },
+
+ /* cgroup.groups.blkio.[<group>.]io_merged.write */
+ { NULL, {PMDA_PMID(CLUSTER_BLKIO_GROUPS,0), PM_TYPE_U64,
+ DISK_INDOM, PM_SEM_COUNTER, PMDA_PMUNITS(0,0,1,0,0,PM_COUNT_ONE) }, },
+
+ /* cgroup.groups.blkio.[<group>.]io_merged.sync */
+ { NULL, {PMDA_PMID(CLUSTER_BLKIO_GROUPS,0), PM_TYPE_U64,
+ DISK_INDOM, PM_SEM_COUNTER, PMDA_PMUNITS(0,0,1,0,0,PM_COUNT_ONE) }, },
+
+ /* cgroup.groups.blkio.[<group>.]io_merged.async */
+ { NULL, {PMDA_PMID(CLUSTER_BLKIO_GROUPS,0), PM_TYPE_U64,
+ DISK_INDOM, PM_SEM_COUNTER, PMDA_PMUNITS(0,0,1,0,0,PM_COUNT_ONE) }, },
+
+ /* cgroup.groups.blkio.[<group>.]io_merged.total */
+ { NULL, {PMDA_PMID(CLUSTER_BLKIO_GROUPS,0), PM_TYPE_U64,
+ DISK_INDOM, PM_SEM_COUNTER, PMDA_PMUNITS(0,0,1,0,0,PM_COUNT_ONE) }, },
+
+ /* cgroup.groups.blkio.[<group>.]io_queued.read */
+ { NULL, {PMDA_PMID(CLUSTER_BLKIO_GROUPS,0), PM_TYPE_U64,
+ DISK_INDOM, PM_SEM_COUNTER, PMDA_PMUNITS(0,0,1,0,0,PM_COUNT_ONE) }, },
+
+ /* cgroup.groups.blkio.[<group>.]io_queued.write */
+ { NULL, {PMDA_PMID(CLUSTER_BLKIO_GROUPS,0), PM_TYPE_U64,
+ DISK_INDOM, PM_SEM_COUNTER, PMDA_PMUNITS(0,0,1,0,0,PM_COUNT_ONE) }, },
+
+ /* cgroup.groups.blkio.[<group>.]io_queued.sync */
+ { NULL, {PMDA_PMID(CLUSTER_BLKIO_GROUPS,0), PM_TYPE_U64,
+ DISK_INDOM, PM_SEM_COUNTER, PMDA_PMUNITS(0,0,1,0,0,PM_COUNT_ONE) }, },
+
+ /* cgroup.groups.blkio.[<group>.]io_queued.async */
+ { NULL, {PMDA_PMID(CLUSTER_BLKIO_GROUPS,0), PM_TYPE_U64,
+ DISK_INDOM, PM_SEM_COUNTER, PMDA_PMUNITS(0,0,1,0,0,PM_COUNT_ONE) }, },
+
+ /* cgroup.groups.blkio.[<group>.]io_queued.total */
+ { NULL, {PMDA_PMID(CLUSTER_BLKIO_GROUPS,0), PM_TYPE_U64,
+ DISK_INDOM, PM_SEM_COUNTER, PMDA_PMUNITS(0,0,1,0,0,PM_COUNT_ONE) }, },
+
+ /* cgroup.groups.blkio.[<group>.]io_service_bytes.read */
+ { NULL, {PMDA_PMID(CLUSTER_BLKIO_GROUPS,0), PM_TYPE_U64,
+ DISK_INDOM, PM_SEM_COUNTER, PMDA_PMUNITS(1,0,0,PM_SPACE_KBYTE,0,0) }, },
+
+ /* cgroup.groups.blkio.[<group>.]io_service_bytes.write */
+ { NULL, {PMDA_PMID(CLUSTER_BLKIO_GROUPS,0), PM_TYPE_U64,
+ DISK_INDOM, PM_SEM_COUNTER, PMDA_PMUNITS(1,0,0,PM_SPACE_KBYTE,0,0) }, },
+
+ /* cgroup.groups.blkio.[<group>.]io_service_bytes.sync */
+ { NULL, {PMDA_PMID(CLUSTER_BLKIO_GROUPS,0), PM_TYPE_U64,
+ DISK_INDOM, PM_SEM_COUNTER, PMDA_PMUNITS(1,0,0,PM_SPACE_KBYTE,0,0) }, },
+
+ /* cgroup.groups.blkio.[<group>.]io_service_bytes.async */
+ { NULL, {PMDA_PMID(CLUSTER_BLKIO_GROUPS,0), PM_TYPE_U64,
+ DISK_INDOM, PM_SEM_COUNTER, PMDA_PMUNITS(1,0,0,PM_SPACE_KBYTE,0,0) }, },
+
+ /* cgroup.groups.blkio.[<group>.]io_service_bytes.total */
+ { NULL, {PMDA_PMID(CLUSTER_BLKIO_GROUPS,0), PM_TYPE_U64,
+ DISK_INDOM, PM_SEM_COUNTER, PMDA_PMUNITS(1,0,0,PM_SPACE_KBYTE,0,0) }, },
+
+ /* cgroup.groups.blkio.[<group>.]io_serviced.read */
+ { NULL, {PMDA_PMID(CLUSTER_BLKIO_GROUPS,0), PM_TYPE_U64,
+ DISK_INDOM, PM_SEM_COUNTER, PMDA_PMUNITS(0,0,1,0,0,PM_COUNT_ONE) }, },
+
+ /* cgroup.groups.blkio.[<group>.]io_serviced.write */
+ { NULL, {PMDA_PMID(CLUSTER_BLKIO_GROUPS,0), PM_TYPE_U64,
+ DISK_INDOM, PM_SEM_COUNTER, PMDA_PMUNITS(0,0,1,0,0,PM_COUNT_ONE) }, },
+
+ /* cgroup.groups.blkio.[<group>.]io_serviced.sync */
+ { NULL, {PMDA_PMID(CLUSTER_BLKIO_GROUPS,0), PM_TYPE_U64,
+ DISK_INDOM, PM_SEM_COUNTER, PMDA_PMUNITS(0,0,1,0,0,PM_COUNT_ONE) }, },
+
+ /* cgroup.groups.blkio.[<group>.]io_serviced.async */
+ { NULL, {PMDA_PMID(CLUSTER_BLKIO_GROUPS,0), PM_TYPE_U64,
+ DISK_INDOM, PM_SEM_COUNTER, PMDA_PMUNITS(0,0,1,0,0,PM_COUNT_ONE) }, },
+
+ /* cgroup.groups.blkio.[<group>.]io_serviced.total */
+ { NULL, {PMDA_PMID(CLUSTER_BLKIO_GROUPS,0), PM_TYPE_U64,
+ DISK_INDOM, PM_SEM_COUNTER, PMDA_PMUNITS(0,0,1,0,0,PM_COUNT_ONE) }, },
+
+ /* cgroup.groups.blkio.[<group>.]io_service_time.read */
+ { NULL, {PMDA_PMID(CLUSTER_BLKIO_GROUPS,0), PM_TYPE_U64,
+ DISK_INDOM, PM_SEM_COUNTER, PMDA_PMUNITS(0,1,0,0,PM_TIME_NSEC,0) }, },
+
+ /* cgroup.groups.blkio.[<group>.]io_service_time.write */
+ { NULL, {PMDA_PMID(CLUSTER_BLKIO_GROUPS,0), PM_TYPE_U64,
+ DISK_INDOM, PM_SEM_COUNTER, PMDA_PMUNITS(0,1,0,0,PM_TIME_NSEC,0) }, },
+
+ /* cgroup.groups.blkio.[<group>.]io_service_time.sync */
+ { NULL, {PMDA_PMID(CLUSTER_BLKIO_GROUPS,0), PM_TYPE_U64,
+ DISK_INDOM, PM_SEM_COUNTER, PMDA_PMUNITS(0,1,0,0,PM_TIME_NSEC,0) }, },
+
+ /* cgroup.groups.blkio.[<group>.]io_service_time.async */
+ { NULL, {PMDA_PMID(CLUSTER_BLKIO_GROUPS,0), PM_TYPE_U64,
+ DISK_INDOM, PM_SEM_COUNTER, PMDA_PMUNITS(0,1,0,0,PM_TIME_NSEC,0) }, },
+
+ /* cgroup.groups.blkio.[<group>.]io_service_time.total */
+ { NULL, {PMDA_PMID(CLUSTER_BLKIO_GROUPS,0), PM_TYPE_U64,
+ DISK_INDOM, PM_SEM_COUNTER, PMDA_PMUNITS(0,1,0,0,PM_TIME_NSEC,0) }, },
+
+ /* cgroup.groups.blkio.[<group>.]io_wait_time.read */
+ { NULL, {PMDA_PMID(CLUSTER_BLKIO_GROUPS,0), PM_TYPE_U64,
+ DISK_INDOM, PM_SEM_COUNTER, PMDA_PMUNITS(0,1,0,0,PM_TIME_NSEC,0) }, },
+
+ /* cgroup.groups.blkio.[<group>.]io_wait_time.write */
+ { NULL, {PMDA_PMID(CLUSTER_BLKIO_GROUPS,0), PM_TYPE_U64,
+ DISK_INDOM, PM_SEM_COUNTER, PMDA_PMUNITS(0,1,0,0,PM_TIME_NSEC,0) }, },
+
+ /* cgroup.groups.blkio.[<group>.]io_wait_time.sync */
+ { NULL, {PMDA_PMID(CLUSTER_BLKIO_GROUPS,0), PM_TYPE_U64,
+ DISK_INDOM, PM_SEM_COUNTER, PMDA_PMUNITS(0,1,0,0,PM_TIME_NSEC,0) }, },
+
+ /* cgroup.groups.blkio.[<group>.]io_wait_time.async */
+ { NULL, {PMDA_PMID(CLUSTER_BLKIO_GROUPS,0), PM_TYPE_U64,
+ DISK_INDOM, PM_SEM_COUNTER, PMDA_PMUNITS(0,1,0,0,PM_TIME_NSEC,0) }, },
+
+ /* cgroup.groups.blkio.[<group>.]io_wait_time.total */
+ { NULL, {PMDA_PMID(CLUSTER_BLKIO_GROUPS,0), PM_TYPE_U64,
+ DISK_INDOM, PM_SEM_COUNTER, PMDA_PMUNITS(0,1,0,0,PM_TIME_NSEC,0) }, },
+
+ /* cgroup.groups.blkio.[<group>.]sectors */
+ { NULL, {PMDA_PMID(CLUSTER_BLKIO_GROUPS,0), PM_TYPE_U64,
+ DISK_INDOM, PM_SEM_COUNTER, PMDA_PMUNITS(0,0,1,0,0,PM_COUNT_ONE) }, },
+
+ /* cgroup.groups.blkio.[<group>.]time */
+ { NULL, {PMDA_PMID(CLUSTER_BLKIO_GROUPS,0), PM_TYPE_U64,
+ DISK_INDOM, PM_SEM_COUNTER, PMDA_PMUNITS(0,1,0,0,PM_TIME_MSEC,0) }, },
+
+
+/*
+ * proc/<pid>/fd cluster
+ */
+
+ /* proc.fd.count */
+ { NULL, { PMDA_PMID(CLUSTER_PID_FD,0), PM_TYPE_U32,
+ PROC_INDOM, PM_SEM_INSTANT, PMDA_PMUNITS(0,0,1,0,0,PM_COUNT_ONE) } },
+
+/*
+ * Metrics control cluster
+ */
+
+ /* proc.control.all.threads */
+ { &threads, { PMDA_PMID(CLUSTER_CONTROL, 1), PM_TYPE_U32,
+ PM_INDOM_NULL, PM_SEM_INSTANT, PMDA_PMUNITS(0,0,0,0,0,0) } },
+ /* proc.control.perclient.threads */
+ { NULL, { PMDA_PMID(CLUSTER_CONTROL, 2), PM_TYPE_U32,
+ PM_INDOM_NULL, PM_SEM_INSTANT, PMDA_PMUNITS(0,0,0,0,0,0) } },
+ /* proc.control.perclient.cgroups */
+ { NULL, { PMDA_PMID(CLUSTER_CONTROL, 3), PM_TYPE_STRING,
+ PM_INDOM_NULL, PM_SEM_INSTANT, PMDA_PMUNITS(0,0,0,0,0,0) } },
+};
+
+pmInDom
+proc_indom(int serial)
+{
+ return indomtab[serial].it_indom;
+}
+
+FILE *
+proc_statsfile(const char *path, char *buffer, int size)
+{
+ snprintf(buffer, size, "%s%s", proc_statspath, path);
+ buffer[size-1] = '\0';
+ return fopen(buffer, "r");
+}
+
+static void
+proc_refresh(pmdaExt *pmda, int *need_refresh)
+{
+ int need_refresh_mtab = 0;
+
+ if (need_refresh[CLUSTER_CPUACCT_GROUPS])
+ refresh_cgroup_cpus(INDOM(CPU_INDOM));
+
+ if (need_refresh[CLUSTER_CGROUP_SUBSYS] ||
+ need_refresh[CLUSTER_CGROUP_MOUNTS] ||
+ need_refresh[CLUSTER_CPUSET_GROUPS] ||
+ need_refresh[CLUSTER_CPUACCT_GROUPS] ||
+ need_refresh[CLUSTER_CPUSCHED_GROUPS] ||
+ need_refresh[CLUSTER_BLKIO_GROUPS] ||
+ need_refresh[CLUSTER_NET_CLS_GROUPS] ||
+ need_refresh[CLUSTER_MEMORY_GROUPS]) {
+ refresh_cgroup_subsys(INDOM(CGROUP_SUBSYS_INDOM));
+ need_refresh_mtab |= refresh_cgroups(pmda, NULL);
+ }
+
+ if (need_refresh_mtab)
+ pmdaDynamicMetricTable(pmda);
+
+ if (need_refresh[CLUSTER_PID_STAT] ||
+ need_refresh[CLUSTER_PID_STATM] ||
+ need_refresh[CLUSTER_PID_STATUS] ||
+ need_refresh[CLUSTER_PID_IO] ||
+ need_refresh[CLUSTER_PID_LABEL] ||
+ need_refresh[CLUSTER_PID_CGROUP] ||
+ need_refresh[CLUSTER_PID_SCHEDSTAT] ||
+ need_refresh[CLUSTER_PID_FD]) {
+ refresh_proc_pid(&proc_pid,
+ proc_ctx_threads(pmda->e_context, threads),
+ proc_ctx_cgroups(pmda->e_context, cgroups));
+ }
+
+ if (need_refresh[CLUSTER_PROC_RUNQ])
+ refresh_proc_runq(&proc_runq);
+}
+
+static int
+proc_instance(pmInDom indom, int inst, char *name, __pmInResult **result, pmdaExt *pmda)
+{
+ __pmInDom_int *indomp = (__pmInDom_int *)&indom;
+ int need_refresh[NUM_CLUSTERS] = { 0 };
+ char newname[16]; /* see Note below */
+ int sts;
+
+ switch (indomp->serial) {
+ case CPU_INDOM:
+ /*
+ * Used by cgroup.groups.cpuacct.[<group>.]usage_percpu
+ * and cgroup.groups.cpuacct.usage_percpu
+ */
+ need_refresh[CLUSTER_CPUACCT_GROUPS]++;
+ break;
+ case DISK_INDOM:
+ need_refresh[CLUSTER_BLKIO_GROUPS]++;
+ break;
+ case PROC_INDOM:
+ need_refresh[CLUSTER_PID_STAT]++;
+ need_refresh[CLUSTER_PID_STATM]++;
+ need_refresh[CLUSTER_PID_STATUS]++;
+ need_refresh[CLUSTER_PID_LABEL]++;
+ need_refresh[CLUSTER_PID_CGROUP]++;
+ need_refresh[CLUSTER_PID_SCHEDSTAT]++;
+ need_refresh[CLUSTER_PID_IO]++;
+ need_refresh[CLUSTER_PID_FD]++;
+ break;
+ case CGROUP_SUBSYS_INDOM:
+ need_refresh[CLUSTER_CGROUP_SUBSYS]++;
+ break;
+ case CGROUP_MOUNTS_INDOM:
+ need_refresh[CLUSTER_CGROUP_MOUNTS]++;
+ break;
+ /* no default label : pmdaInstance will pick up errors */
+ }
+
+ if (indomp->serial == PROC_INDOM && inst == PM_IN_NULL && name != NULL) {
+ /*
+ * For the proc indom, if the name is a pid (as a string), and it
+ * contains only digits (i.e. it's not a full instance name) then
+ * reformat it to be exactly six digits, with leading zeros.
+ *
+ * Note that although format %06d is used here and in proc_pid.c,
+ * the pid could be longer than this (in which case there
+ * are no leading zeroes. The size of newname[] is chosen
+ * to comfortably accommodate a 32-bit pid (Linux maximum),
+ * or max value of 4294967295 (10 digits)
+ */
+ char *p;
+ for (p = name; *p != '\0'; p++) {
+ if (!isdigit((int)*p))
+ break;
+ }
+ if (*p == '\0') {
+ snprintf(newname, sizeof(newname), "%06d", atoi(name));
+ name = newname;
+ }
+ }
+
+ sts = PM_ERR_PERMISSION;
+ have_access = proc_ctx_access(pmda->e_context) || all_access;
+ if (have_access || indomp->serial != PROC_INDOM) {
+ proc_refresh(pmda, need_refresh);
+ sts = pmdaInstance(indom, inst, name, result, pmda);
+ }
+ have_access = proc_ctx_revert(pmda->e_context);
+
+ return sts;
+}
+
+/*
+ * callback provided to pmdaFetch
+ */
+
+static int
+proc_fetchCallBack(pmdaMetric *mdesc, unsigned int inst, pmAtomValue *atom)
+{
+ __pmID_int *idp = (__pmID_int *)&(mdesc->m_desc.pmid);
+ int cluster = proc_pmid_cluster(mdesc->m_desc.pmid);
+ int sts;
+ unsigned long ul;
+ const char *cp;
+ char *f;
+ int *ip;
+ proc_pid_entry_t *entry;
+ void *fsp;
+ static long hz = -1;
+ char *tail;
+
+ if (hz == -1)
+ hz = sysconf(_SC_CLK_TCK);
+
+ if (mdesc->m_user != NULL) {
+ /*
+ * The metric value is extracted directly via the address specified
+ * in metrictab. Note: not all metrics support this - those that
+ * don't have NULL for the m_user field in their respective
+ * metrictab slot.
+ */
+
+ switch (mdesc->m_desc.type) {
+ case PM_TYPE_32:
+ atom->l = *(__int32_t *)mdesc->m_user;
+ break;
+ case PM_TYPE_U32:
+ atom->ul = *(__uint32_t *)mdesc->m_user;
+ break;
+ case PM_TYPE_64:
+ atom->ll = *(__int64_t *)mdesc->m_user;
+ break;
+ case PM_TYPE_U64:
+ atom->ull = *(__uint64_t *)mdesc->m_user;
+ break;
+ case PM_TYPE_FLOAT:
+ atom->f = *(float *)mdesc->m_user;
+ break;
+ case PM_TYPE_DOUBLE:
+ atom->d = *(double *)mdesc->m_user;
+ break;
+ case PM_TYPE_STRING:
+ cp = *(char **)mdesc->m_user;
+ atom->cp = (char *)(cp ? cp : "");
+ break;
+ default:
+ return 0;
+ }
+ }
+ else
+ switch (cluster) {
+
+ case CLUSTER_PID_STAT:
+ if (idp->item == 99) /* proc.nprocs */
+ atom->ul = proc_pid.indom->it_numinst;
+ else {
+ static char ttyname[MAXPATHLEN];
+
+ if (!have_access)
+ return PM_ERR_PERMISSION;
+ if ((entry = fetch_proc_pid_stat(inst, &proc_pid)) == NULL)
+ return PM_ERR_INST;
+
+ switch (idp->item) {
+
+
+ case PROC_PID_STAT_PID:
+ atom->ul = entry->id;
+ break;
+
+ case PROC_PID_STAT_TTYNAME:
+ if ((f = _pm_getfield(entry->stat_buf, PROC_PID_STAT_TTY)) == NULL)
+ atom->cp = "?";
+ else {
+ dev_t dev = (dev_t)atoi(f);
+ atom->cp = get_ttyname_info(inst, dev, ttyname);
+ }
+ break;
+
+ case PROC_PID_STAT_CMD:
+ if ((f = _pm_getfield(entry->stat_buf, idp->item)) == NULL)
+ return PM_ERR_INST;
+ atom->cp = f + 1;
+ atom->cp[strlen(atom->cp)-1] = '\0';
+ break;
+
+ case PROC_PID_STAT_PSARGS:
+ atom->cp = entry->name + 7;
+ break;
+
+ case PROC_PID_STAT_STATE:
+ /*
+ * string
+ */
+ if ((f = _pm_getfield(entry->stat_buf, idp->item)) == NULL)
+ return PM_ERR_INST;
+ atom->cp = f;
+ break;
+
+ case PROC_PID_STAT_VSIZE:
+ case PROC_PID_STAT_RSS_RLIM:
+ /*
+ * bytes converted to kbytes
+ */
+ if ((f = _pm_getfield(entry->stat_buf, idp->item)) == NULL)
+ return PM_ERR_INST;
+ atom->ul = (__uint32_t)strtoul(f, &tail, 0);
+ atom->ul /= 1024;
+ break;
+
+ case PROC_PID_STAT_RSS:
+ /*
+ * pages converted to kbytes
+ */
+ if ((f = _pm_getfield(entry->stat_buf, idp->item)) == NULL)
+ return PM_ERR_INST;
+ atom->ul = (__uint32_t)strtoul(f, &tail, 0);
+ atom->ul *= _pm_system_pagesize / 1024;
+ break;
+
+ case PROC_PID_STAT_UTIME:
+ case PROC_PID_STAT_STIME:
+ case PROC_PID_STAT_CUTIME:
+ case PROC_PID_STAT_CSTIME:
+ /*
+ * unsigned jiffies converted to unsigned milliseconds
+ */
+ if ((f = _pm_getfield(entry->stat_buf, idp->item)) == NULL)
+ return PM_ERR_INST;
+
+ ul = (__uint32_t)strtoul(f, &tail, 0);
+ _pm_assign_ulong(atom, 1000 * (double)ul / hz);
+ break;
+
+ case PROC_PID_STAT_PRIORITY:
+ case PROC_PID_STAT_NICE:
+ /*
+ * signed decimal int
+ */
+ if ((f = _pm_getfield(entry->stat_buf, idp->item)) == NULL)
+ return PM_ERR_INST;
+ atom->l = (__int32_t)strtol(f, &tail, 0);
+ break;
+
+ case PROC_PID_STAT_WCHAN:
+ if ((f = _pm_getfield(entry->stat_buf, idp->item)) == NULL)
+ return PM_ERR_INST;
+#if defined(HAVE_64BIT_PTR)
+ atom->ull = (__uint64_t)strtoull(f, &tail, 0);
+#else
+ atom->ul = (__uint32_t)strtoul(f, &tail, 0);
+#endif
+ break;
+
+ case PROC_PID_STAT_WCHAN_SYMBOL:
+ if (entry->wchan_buf) /* 2.6 kernel, /proc/<pid>/wchan */
+ atom->cp = entry->wchan_buf;
+ else { /* old school (2.4 kernels, at least) */
+ char *wc;
+ /*
+ * Convert address to symbol name if requested
+ * Added by Mike Mason <mmlnx@us.ibm.com>
+ */
+ f = _pm_getfield(entry->stat_buf, PROC_PID_STAT_WCHAN);
+ if (f == NULL)
+ return PM_ERR_INST;
+#if defined(HAVE_64BIT_PTR)
+ atom->ull = (__uint64_t)strtoull(f, &tail, 0);
+ if ((wc = wchan(atom->ull)))
+ atom->cp = wc;
+ else
+ atom->cp = atom->ull ? f : "";
+#else
+ atom->ul = (__uint32_t)strtoul(f, &tail, 0);
+ if ((wc = wchan((__psint_t)atom->ul)))
+ atom->cp = wc;
+ else
+ atom->cp = atom->ul ? f : "";
+#endif
+ }
+ break;
+
+ default:
+ /*
+ * unsigned decimal int
+ */
+ if (idp->item < NR_PROC_PID_STAT) {
+ if ((f = _pm_getfield(entry->stat_buf, idp->item)) == NULL)
+ return PM_ERR_INST;
+ atom->ul = (__uint32_t)strtoul(f, &tail, 0);
+ }
+ else
+ return PM_ERR_PMID;
+ break;
+ }
+ }
+ break;
+
+ case CLUSTER_PID_STATM:
+ if (!have_access)
+ return PM_ERR_PERMISSION;
+ if (idp->item == PROC_PID_STATM_MAPS) { /* proc.memory.maps */
+ if ((entry = fetch_proc_pid_maps(inst, &proc_pid)) == NULL)
+ return PM_ERR_INST;
+ atom->cp = entry->maps_buf;
+ } else {
+ if ((entry = fetch_proc_pid_statm(inst, &proc_pid)) == NULL)
+ return PM_ERR_INST;
+
+ if (idp->item <= PROC_PID_STATM_DIRTY) {
+ /* unsigned int */
+ if ((f = _pm_getfield(entry->statm_buf, idp->item)) == NULL)
+ return PM_ERR_INST;
+ atom->ul = (__uint32_t)strtoul(f, &tail, 0);
+ atom->ul *= _pm_system_pagesize / 1024;
+ }
+ else
+ return PM_ERR_PMID;
+ }
+ break;
+
+ case CLUSTER_PID_SCHEDSTAT:
+ if (!have_access)
+ return PM_ERR_PERMISSION;
+ if ((entry = fetch_proc_pid_schedstat(inst, &proc_pid)) == NULL)
+ return (oserror() == ENOENT) ? PM_ERR_APPVERSION : PM_ERR_INST;
+
+ if (idp->item < NR_PROC_PID_SCHED) {
+ if ((f = _pm_getfield(entry->schedstat_buf, idp->item)) == NULL)
+ return PM_ERR_INST;
+ if (idp->item == PROC_PID_SCHED_PCOUNT &&
+ mdesc->m_desc.type == PM_TYPE_U32)
+ atom->ul = (__uint32_t)strtoul(f, &tail, 0);
+ else
+#if defined(HAVE_64BIT_PTR)
+ atom->ull = (__uint64_t)strtoull(f, &tail, 0);
+#else
+ atom->ul = (__uint32_t)strtoul(f, &tail, 0);
+#endif
+ }
+ else
+ return PM_ERR_PMID;
+ break;
+
+ case CLUSTER_PID_IO:
+ if (!have_access)
+ return PM_ERR_PERMISSION;
+ if ((entry = fetch_proc_pid_io(inst, &proc_pid)) == NULL)
+ return (oserror() == ENOENT) ? PM_ERR_APPVERSION : PM_ERR_INST;
+
+ switch (idp->item) {
+
+ case PROC_PID_IO_RCHAR:
+ if ((f = _pm_getfield(entry->io_lines.rchar, 1)) == NULL)
+ atom->ull = 0;
+ else
+ atom->ull = (__uint64_t)strtoull(f, &tail, 0);
+ break;
+ case PROC_PID_IO_WCHAR:
+ if ((f = _pm_getfield(entry->io_lines.wchar, 1)) == NULL)
+ atom->ull = 0;
+ else
+ atom->ull = (__uint64_t)strtoull(f, &tail, 0);
+ break;
+ case PROC_PID_IO_SYSCR:
+ if ((f = _pm_getfield(entry->io_lines.syscr, 1)) == NULL)
+ atom->ull = 0;
+ else
+ atom->ull = (__uint64_t)strtoull(f, &tail, 0);
+ break;
+ case PROC_PID_IO_SYSCW:
+ if ((f = _pm_getfield(entry->io_lines.syscw, 1)) == NULL)
+ atom->ull = 0;
+ else
+ atom->ull = (__uint64_t)strtoull(f, &tail, 0);
+ break;
+ case PROC_PID_IO_READ_BYTES:
+ if ((f = _pm_getfield(entry->io_lines.readb, 1)) == NULL)
+ atom->ull = 0;
+ else
+ atom->ull = (__uint64_t)strtoull(f, &tail, 0);
+ break;
+ case PROC_PID_IO_WRITE_BYTES:
+ if ((f = _pm_getfield(entry->io_lines.writeb, 1)) == NULL)
+ atom->ull = 0;
+ else
+ atom->ull = (__uint64_t)strtoull(f, &tail, 0);
+ break;
+ case PROC_PID_IO_CANCELLED_BYTES:
+ if ((f = _pm_getfield(entry->io_lines.cancel, 1)) == NULL)
+ atom->ull = 0;
+ else
+ atom->ull = (__uint64_t)strtoull(f, &tail, 0);
+ break;
+
+ default:
+ return PM_ERR_PMID;
+ }
+ break;
+
+ /*
+ * Cluster added by Mike Mason <mmlnx@us.ibm.com>
+ */
+ case CLUSTER_PID_STATUS:
+ if (!have_access)
+ return PM_ERR_PERMISSION;
+ if ((entry = fetch_proc_pid_status(inst, &proc_pid)) == NULL)
+ return PM_ERR_INST;
+
+ switch (idp->item) {
+
+ case PROC_PID_STATUS_UID:
+ case PROC_PID_STATUS_EUID:
+ case PROC_PID_STATUS_SUID:
+ case PROC_PID_STATUS_FSUID:
+ case PROC_PID_STATUS_UID_NM:
+ case PROC_PID_STATUS_EUID_NM:
+ case PROC_PID_STATUS_SUID_NM:
+ case PROC_PID_STATUS_FSUID_NM:
+ {
+ struct passwd *pwe;
+
+ if ((f = _pm_getfield(entry->status_lines.uid, (idp->item % 4) + 1)) == NULL)
+ return PM_ERR_INST;
+ atom->ul = (__uint32_t)strtoul(f, &tail, 0);
+ if (idp->item > PROC_PID_STATUS_FSUID) {
+ if ((pwe = getpwuid((uid_t)atom->ul)) != NULL)
+ atom->cp = pwe->pw_name;
+ else
+ atom->cp = "UNKNOWN";
+ }
+ }
+ break;
+
+ case PROC_PID_STATUS_GID:
+ case PROC_PID_STATUS_EGID:
+ case PROC_PID_STATUS_SGID:
+ case PROC_PID_STATUS_FSGID:
+ case PROC_PID_STATUS_GID_NM:
+ case PROC_PID_STATUS_EGID_NM:
+ case PROC_PID_STATUS_SGID_NM:
+ case PROC_PID_STATUS_FSGID_NM:
+ {
+ struct group *gre;
+
+ if ((f = _pm_getfield(entry->status_lines.gid, (idp->item % 4) + 1)) == NULL)
+ return PM_ERR_INST;
+ atom->ul = (__uint32_t)strtoul(f, &tail, 0);
+ if (idp->item > PROC_PID_STATUS_FSGID) {
+ if ((gre = getgrgid((gid_t)atom->ul)) != NULL) {
+ atom->cp = gre->gr_name;
+ } else {
+ atom->cp = "UNKNOWN";
+ }
+ }
+ }
+ break;
+
+ case PROC_PID_STATUS_SIGNAL:
+ if ((atom->cp = _pm_getfield(entry->status_lines.sigpnd, 1)) == NULL)
+ return PM_ERR_INST;
+ break;
+
+ case PROC_PID_STATUS_BLOCKED:
+ if ((atom->cp = _pm_getfield(entry->status_lines.sigblk, 1)) == NULL)
+ return PM_ERR_INST;
+ break;
+
+ case PROC_PID_STATUS_SIGCATCH:
+ if ((atom->cp = _pm_getfield(entry->status_lines.sigcgt, 1)) == NULL)
+ return PM_ERR_INST;
+ break;
+
+ case PROC_PID_STATUS_SIGIGNORE:
+ if ((atom->cp = _pm_getfield(entry->status_lines.sigign, 1)) == NULL)
+ return PM_ERR_INST;
+ break;
+
+ case PROC_PID_STATUS_VMSIZE:
+ if ((f = _pm_getfield(entry->status_lines.vmsize, 1)) == NULL)
+ atom->ul = 0;
+ else
+ atom->ul = (__uint32_t)strtoul(f, &tail, 0);
+ break;
+
+ case PROC_PID_STATUS_VMLOCK:
+ if ((f = _pm_getfield(entry->status_lines.vmlck, 1)) == NULL)
+ atom->ul = 0;
+ else
+ atom->ul = (__uint32_t)strtoul(f, &tail, 0);
+ break;
+
+ case PROC_PID_STATUS_VMRSS:
+ if ((f = _pm_getfield(entry->status_lines.vmrss, 1)) == NULL)
+ atom->ul = 0;
+ else
+ atom->ul = (__uint32_t)strtoul(f, &tail, 0);
+ break;
+
+ case PROC_PID_STATUS_VMDATA:
+ if ((f = _pm_getfield(entry->status_lines.vmdata, 1)) == NULL)
+ atom->ul = 0;
+ else
+ atom->ul = (__uint32_t)strtoul(f, &tail, 0);
+ break;
+
+ case PROC_PID_STATUS_VMSTACK:
+ if ((f = _pm_getfield(entry->status_lines.vmstk, 1)) == NULL)
+ atom->ul = 0;
+ else
+ atom->ul = (__uint32_t)strtoul(f, &tail, 0);
+ break;
+
+ case PROC_PID_STATUS_VMEXE:
+ if ((f = _pm_getfield(entry->status_lines.vmexe, 1)) == NULL)
+ atom->ul = 0;
+ else
+ atom->ul = (__uint32_t)strtoul(f, &tail, 0);
+ break;
+
+ case PROC_PID_STATUS_VMLIB:
+ if ((f = _pm_getfield(entry->status_lines.vmlib, 1)) == NULL)
+ atom->ul = 0;
+ else
+ atom->ul = (__uint32_t)strtoul(f, &tail, 0);
+ break;
+
+ case PROC_PID_STATUS_VMSWAP:
+ if ((f = _pm_getfield(entry->status_lines.vmswap, 1)) == NULL)
+ atom->ul = 0;
+ else
+ atom->ul = (__uint32_t)strtoul(f, &tail, 0);
+ break;
+
+ case PROC_PID_STATUS_THREADS:
+ if ((f = _pm_getfield(entry->status_lines.threads, 1)) == NULL)
+ atom->ul = 0;
+ else
+ atom->ul = (__uint32_t)strtoul(f, &tail, 0);
+ break;
+
+ default:
+ return PM_ERR_PMID;
+ }
+ break;
+
+ case CLUSTER_CGROUP_SUBSYS:
+ switch (idp->item) {
+ case 0: /* cgroup.subsys.hierarchy */
+ sts = pmdaCacheLookup(INDOM(CGROUP_SUBSYS_INDOM), inst, NULL, (void **)&ip);
+ if (sts < 0)
+ return sts;
+ if (sts != PMDA_CACHE_ACTIVE)
+ return PM_ERR_INST;
+ atom->ul = *ip;
+ break;
+
+ case 1: /* cgroup.subsys.count */
+ atom->ul = pmdaCacheOp(INDOM(CGROUP_SUBSYS_INDOM), PMDA_CACHE_SIZE_ACTIVE);
+ break;
+ }
+ break;
+
+ case CLUSTER_CGROUP_MOUNTS:
+ switch (idp->item) {
+ case 0: /* cgroup.mounts.subsys */
+ sts = pmdaCacheLookup(INDOM(CGROUP_MOUNTS_INDOM), inst, NULL, &fsp);
+ if (sts < 0)
+ return sts;
+ if (sts != PMDA_CACHE_ACTIVE)
+ return PM_ERR_INST;
+ atom->cp = cgroup_find_subsys(INDOM(CGROUP_SUBSYS_INDOM), fsp);
+ break;
+
+ case 1: /* cgroup.mounts.count */
+ atom->ul = pmdaCacheOp(INDOM(CGROUP_MOUNTS_INDOM), PMDA_CACHE_SIZE_ACTIVE);
+ break;
+ }
+ break;
+
+ case CLUSTER_CPUSET_GROUPS:
+ case CLUSTER_CPUACCT_GROUPS:
+ case CLUSTER_CPUSCHED_GROUPS:
+ case CLUSTER_MEMORY_GROUPS:
+ case CLUSTER_NET_CLS_GROUPS:
+ case CLUSTER_BLKIO_GROUPS:
+ return cgroup_group_fetch(mdesc->m_desc.pmid, inst, atom);
+
+ case CLUSTER_PID_FD:
+ if (!have_access)
+ return PM_ERR_PERMISSION;
+ if (idp->item > PROC_PID_FD_COUNT)
+ return PM_ERR_PMID;
+ if ((entry = fetch_proc_pid_fd(inst, &proc_pid)) == NULL)
+ return PM_ERR_INST;
+ atom->ul = entry->fd_count;
+ break;
+
+ case CLUSTER_PID_CGROUP:
+ if (!have_access)
+ return PM_ERR_PERMISSION;
+ if (idp->item > PROC_PID_CGROUP)
+ return PM_ERR_PMID;
+ if ((entry = fetch_proc_pid_cgroup(inst, &proc_pid)) == NULL) {
+ if (oserror() == ENOENT) return PM_ERR_APPVERSION;
+ if (oserror() != ENODATA) return PM_ERR_INST;
+ atom->cp = "";
+ } else {
+ atom->cp = proc_strings_lookup(entry->cgroup_id);
+ }
+ break;
+
+ case CLUSTER_PID_LABEL:
+ if (!have_access)
+ return PM_ERR_PERMISSION;
+ if (idp->item > PROC_PID_LABEL)
+ return PM_ERR_PMID;
+ if ((entry = fetch_proc_pid_label(inst, &proc_pid)) == NULL) {
+ if (oserror() == ENOENT) return PM_ERR_APPVERSION;
+ if (oserror() != ENODATA) return PM_ERR_INST;
+ atom->cp = "";
+ } else {
+ atom->cp = proc_strings_lookup(entry->label_id);
+ }
+ break;
+
+ case CLUSTER_CONTROL:
+ switch (idp->item) {
+ /* case 1: not reached -- proc.control.all.threads is direct */
+ case 2: /* proc.control.perclient.threads */
+ atom->ul = proc_ctx_threads(pmdaGetContext(), threads);
+ break;
+ case 3: /* proc.control.perclient.cgroups */
+ cp = proc_ctx_cgroups(pmdaGetContext(), cgroups);
+ atom->cp = (char *)(cp ? cp : "");
+ break;
+ default:
+ return PM_ERR_PMID;
+ }
+ break;
+
+ default: /* unknown cluster */
+ return PM_ERR_PMID;
+ }
+
+ return PMDA_FETCH_STATIC;
+}
+
+static int
+proc_fetch(int numpmid, pmID pmidlist[], pmResult **resp, pmdaExt *pmda)
+{
+ int i, sts, cluster;
+ int need_refresh[NUM_CLUSTERS] = { 0 };
+
+ for (i = 0; i < numpmid; i++) {
+ cluster = proc_pmid_cluster(pmidlist[i]);
+ if (cluster >= MIN_CLUSTER && cluster < NUM_CLUSTERS)
+ need_refresh[cluster]++;
+ }
+
+ have_access = proc_ctx_access(pmda->e_context) || all_access;
+ proc_refresh(pmda, need_refresh);
+ sts = pmdaFetch(numpmid, pmidlist, resp, pmda);
+ have_access = proc_ctx_revert(pmda->e_context);
+ return sts;
+}
+
+static int
+proc_store(pmResult *result, pmdaExt *pmda)
+{
+ int i, sts = 0;
+
+ have_access = proc_ctx_access(pmda->e_context) || all_access;
+
+ for (i = 0; i < result->numpmid; i++) {
+ pmValueSet *vsp = result->vset[i];
+ __pmID_int *idp = (__pmID_int *)&(vsp->pmid);
+ pmAtomValue av;
+
+ if (idp->cluster != CLUSTER_CONTROL)
+ sts = PM_ERR_PERMISSION;
+ else if (vsp->numval != 1)
+ sts = PM_ERR_INST;
+ else switch (idp->item) {
+ case 1: /* proc.control.all.threads */
+ if (!have_access)
+ sts = PM_ERR_PERMISSION;
+ else if ((sts = pmExtractValue(vsp->valfmt, &vsp->vlist[0],
+ PM_TYPE_U32, &av, PM_TYPE_U32)) >= 0) {
+ if (av.ul > 1) /* only zero or one allowed */
+ sts = PM_ERR_CONV;
+ else
+ threads = av.ul;
+ }
+ break;
+ case 2: /* proc.control.perclient.threads */
+ if ((sts = pmExtractValue(vsp->valfmt, &vsp->vlist[0],
+ PM_TYPE_U32, &av, PM_TYPE_U32)) >= 0) {
+ sts = proc_ctx_set_threads(pmda->e_context, av.ul);
+ }
+ break;
+ case 3: /* proc.control.perclient.cgroups */
+ if ((sts = pmExtractValue(vsp->valfmt, &vsp->vlist[0],
+ PM_TYPE_STRING, &av, PM_TYPE_STRING)) >= 0) {
+ if ((sts = proc_ctx_set_cgroups(pmda->e_context, av.cp)) < 0)
+ free(av.cp);
+ }
+ break;
+ default:
+ sts = PM_ERR_PERMISSION;
+ }
+ if (sts < 0)
+ break;
+ }
+
+ have_access = proc_ctx_revert(pmda->e_context);
+ return sts;
+}
+
+static int
+proc_text(int ident, int type, char **buf, pmdaExt *pmda)
+{
+ if ((type & PM_TEXT_PMID) == PM_TEXT_PMID) {
+ int sts = pmdaDynamicLookupText(ident, type, buf, pmda);
+ if (sts != -ENOENT)
+ return sts;
+ }
+ return pmdaText(ident, type, buf, pmda);
+}
+
+static int
+proc_pmid(const char *name, pmID *pmid, pmdaExt *pmda)
+{
+ pmdaNameSpace *tree = pmdaDynamicLookupName(pmda, name);
+ if (tree == NULL)
+ return PM_ERR_NAME;
+ if (pmDebug & DBG_TRACE_APPL2) {
+ fprintf(stderr, "proc_pmid: name=%s tree:\n", name);
+ __pmDumpNameNode(stderr, tree->root, 1);
+ }
+ return pmdaTreePMID(tree, name, pmid);
+}
+
+static int
+proc_name(pmID pmid, char ***nameset, pmdaExt *pmda)
+{
+ pmdaNameSpace *tree = pmdaDynamicLookupPMID(pmda, pmid);
+ if (tree == NULL)
+ return PM_ERR_PMID;
+ if (pmDebug & DBG_TRACE_APPL2) {
+ fprintf(stderr, "proc_name: pmid=%s tree:\n", pmIDStr(pmid));
+ __pmDumpNameNode(stderr, tree->root, 1);
+ }
+ return pmdaTreeName(tree, pmid, nameset);
+}
+
+static int
+proc_children(const char *name, int flag, char ***kids, int **sts, pmdaExt *pmda)
+{
+ pmdaNameSpace *tree = pmdaDynamicLookupName(pmda, name);
+ if (tree == NULL)
+ return PM_ERR_NAME;
+ if (pmDebug & DBG_TRACE_APPL2) {
+ fprintf(stderr, "proc_children: name=%s flag=%d tree:\n", name, flag);
+ __pmDumpNameNode(stderr, tree->root, 1);
+ }
+ return pmdaTreeChildren(tree, name, flag, kids, sts);
+}
+
+/*
+ * Helper routines for accessing a generic static string dictionary
+ */
+
+char *
+proc_strings_lookup(int index)
+{
+ char *value;
+ pmInDom dict = INDOM(STRINGS_INDOM);
+
+ if (pmdaCacheLookup(dict, index, &value, NULL) == PMDA_CACHE_ACTIVE)
+ return value;
+ return "";
+}
+
+int
+proc_strings_insert(const char *buf)
+{
+ pmInDom dict = INDOM(STRINGS_INDOM);
+ return pmdaCacheStore(dict, PMDA_CACHE_ADD, buf, NULL);
+}
+
+/*
+ * Initialise the agent (both daemon and DSO).
+ */
+
+void
+__PMDA_INIT_CALL
+proc_init(pmdaInterface *dp)
+{
+ int nindoms = sizeof(indomtab)/sizeof(indomtab[0]);
+ int nmetrics = sizeof(metrictab)/sizeof(metrictab[0]);
+ char *envpath;
+
+ _pm_system_pagesize = getpagesize();
+ if ((envpath = getenv("PROC_STATSPATH")) != NULL)
+ proc_statspath = envpath;
+
+ if (_isDSO) {
+ char helppath[MAXPATHLEN];
+ int sep = __pmPathSeparator();
+ snprintf(helppath, sizeof(helppath), "%s%c" "proc" "%c" "help",
+ pmGetConfig("PCP_PMDAS_DIR"), sep, sep);
+ pmdaDSO(dp, PMDA_INTERFACE_6, "proc DSO", helppath);
+ }
+
+ if (dp->status != 0)
+ return;
+ dp->comm.flags |= PDU_FLAG_AUTH;
+
+ dp->version.six.instance = proc_instance;
+ dp->version.six.store = proc_store;
+ dp->version.six.fetch = proc_fetch;
+ dp->version.six.text = proc_text;
+ dp->version.six.pmid = proc_pmid;
+ dp->version.six.name = proc_name;
+ dp->version.six.children = proc_children;
+ dp->version.six.attribute = proc_ctx_attrs;
+ pmdaSetEndContextCallBack(dp, proc_ctx_end);
+ pmdaSetFetchCallBack(dp, proc_fetchCallBack);
+
+ /*
+ * Initialize the instance domain table.
+ */
+ indomtab[CPU_INDOM].it_indom = CPU_INDOM;
+ indomtab[DISK_INDOM].it_indom = DISK_INDOM;
+ indomtab[DEVT_INDOM].it_indom = DEVT_INDOM;
+ indomtab[PROC_INDOM].it_indom = PROC_INDOM;
+ indomtab[STRINGS_INDOM].it_indom = STRINGS_INDOM;
+ indomtab[CGROUP_SUBSYS_INDOM].it_indom = CGROUP_SUBSYS_INDOM;
+ indomtab[CGROUP_MOUNTS_INDOM].it_indom = CGROUP_MOUNTS_INDOM;
+
+ proc_pid.indom = &indomtab[PROC_INDOM];
+
+ /*
+ * Read System.map and /proc/ksyms. Used to translate wait channel
+ * addresses to symbol names.
+ * Added by Mike Mason <mmlnx@us.ibm.com>
+ */
+ read_ksym_sources(kernel_uname.release);
+
+ cgroup_init(metrictab, nmetrics);
+ proc_ctx_init();
+
+ pmdaSetFlags(dp, PMDA_EXT_FLAG_HASHED);
+ pmdaInit(dp, indomtab, nindoms, metrictab, nmetrics);
+
+ /* string metrics use the pmdaCache API for value indexing */
+ pmdaCacheOp(INDOM(STRINGS_INDOM), PMDA_CACHE_STRINGS);
+
+ /* cgroup metrics use the pmdaCache API for indom indexing */
+ pmdaCacheOp(INDOM(CPU_INDOM), PMDA_CACHE_CULL);
+ pmdaCacheOp(INDOM(DISK_INDOM), PMDA_CACHE_CULL);
+ pmdaCacheOp(INDOM(CGROUP_SUBSYS_INDOM), PMDA_CACHE_CULL);
+ pmdaCacheOp(INDOM(CGROUP_MOUNTS_INDOM), PMDA_CACHE_CULL);
+}
+
+pmLongOptions longopts[] = {
+ PMDA_OPTIONS_HEADER("Options"),
+ PMOPT_DEBUG,
+ { "no-access-checks", 0, 'A', 0, "no access checks will be performed (insecure, beware!)" },
+ PMDAOPT_DOMAIN,
+ PMDAOPT_LOGFILE,
+ { "with-threads", 0, 'L', 0, "include threads in the all-processes instance domain" },
+ { "from-cgroup", 1, 'r', "NAME", "restrict monitoring to processes in the named cgroup" },
+ PMDAOPT_USERNAME,
+ PMOPT_HELP,
+ PMDA_OPTIONS_END
+};
+
+pmdaOptions opts = {
+ .short_options = "AD:d:l:Lr:U:?",
+ .long_options = longopts,
+};
+
+int
+main(int argc, char **argv)
+{
+ int c, sep = __pmPathSeparator();
+ pmdaInterface dispatch;
+ char helppath[MAXPATHLEN];
+ char *username = "root";
+
+ _isDSO = 0;
+ __pmSetProgname(argv[0]);
+ snprintf(helppath, sizeof(helppath), "%s%c" "proc" "%c" "help",
+ pmGetConfig("PCP_PMDAS_DIR"), sep, sep);
+ pmdaDaemon(&dispatch, PMDA_INTERFACE_6, pmProgname, PROC, "proc.log", helppath);
+
+ while ((c = pmdaGetOptions(argc, argv, &opts, &dispatch)) != EOF) {
+ switch (c) {
+ case 'A':
+ all_access = 1;
+ break;
+ case 'L':
+ threads = 1;
+ break;
+ case 'r':
+ cgroups = opts.optarg;
+ break;
+ }
+ }
+
+ if (opts.errors) {
+ pmdaUsageMessage(&opts);
+ exit(1);
+ }
+ if (opts.username)
+ username = opts.username;
+
+ pmdaOpenLog(&dispatch);
+ __pmSetProcessIdentity(username);
+
+ proc_init(&dispatch);
+ pmdaConnect(&dispatch);
+ pmdaMain(&dispatch);
+ exit(0);
+}