summaryrefslogtreecommitdiff
path: root/src/pmdas/process
diff options
context:
space:
mode:
Diffstat (limited to 'src/pmdas/process')
-rw-r--r--src/pmdas/process/GNUmakefile65
-rwxr-xr-xsrc/pmdas/process/Install28
-rw-r--r--src/pmdas/process/README74
-rwxr-xr-xsrc/pmdas/process/Remove41
-rw-r--r--src/pmdas/process/help38
-rw-r--r--src/pmdas/process/pmns26
-rw-r--r--src/pmdas/process/process.c413
-rw-r--r--src/pmdas/process/process.conf11
-rw-r--r--src/pmdas/process/root16
9 files changed, 712 insertions, 0 deletions
diff --git a/src/pmdas/process/GNUmakefile b/src/pmdas/process/GNUmakefile
new file mode 100644
index 0000000..b04c78f
--- /dev/null
+++ b/src/pmdas/process/GNUmakefile
@@ -0,0 +1,65 @@
+#
+# Copyright (c) 2001 Alan Bailey (bailey@mcs.anl.gov or abailey@ncsa.uiuc.edu)
+# for the portions of the code supporting the initial agent functionality.
+# All rights reserved.
+# Copyright (c) 2001,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
+
+
+IAM = process
+DOMAIN = PROCESS
+TARGETS = $(IAM)
+CFILES = process.c
+SCRIPTS = Install Remove
+DFILES = README
+LSRCFILES= $(SCRIPTS) pmns help root $(DFILES) process.conf
+
+PMDADIR = $(PCP_PMDAS_DIR)/$(IAM)
+PMCHART = $(PCP_VAR_DIR)/config/pmchart
+
+LDIRT = domain.h *.o $(IAM).log pmda$(IAM) pmda_$(IAM).so $(TARGETS) \
+ help.dir help.pag
+LLDLIBS = $(PCP_PMDALIB)
+
+default: build-me
+
+include $(BUILDRULES)
+
+# This PMDA is only valid on platforms with a procfs
+# It is also superceded by the cgroup functionality on Linux
+# thus has not been built for some time, for reference only.
+#build-me: $(TARGETS)
+#install install_pcp : default
+# $(INSTALL) -m 755 -d $(PMDADIR)
+# $(INSTALL) -m 755 $(IAM) $(PMDADIR)/pmda$(IAM)
+# $(INSTALL) -m 755 $(SCRIPTS) $(PMDADIR)
+# $(INSTALL) -m 644 $(DFILES) pmns help root domain.h $(PMDADIR)
+# $(INSTALL) -m 644 process.conf $(PMDADIR)/process.conf
+#else
+build-me:
+install:
+#endif
+
+$(IAM): $(OBJECTS)
+
+default_pcp : default
+
+install_pcp : install
+
+process.o: domain.h
+
+domain.h: ../../pmns/stdpmid
+ $(DOMAIN_MAKERULE)
diff --git a/src/pmdas/process/Install b/src/pmdas/process/Install
new file mode 100755
index 0000000..7bc54b9
--- /dev/null
+++ b/src/pmdas/process/Install
@@ -0,0 +1,28 @@
+#! /bin/sh
+#
+# Copyright (c) 2001 Alan Bailey. All Rights Reserved.
+# Copyright (c) 2001,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.
+#
+# Install the process PMDA and/or PMNS
+#
+
+. $PCP_DIR/etc/pcp.env
+. $PCP_SHARE_DIR/lib/pmdaproc.sh
+
+iam=process
+pmda_interface=2
+forced_restart=true
+
+pmdaSetup
+pmdaInstall
+exit 0
diff --git a/src/pmdas/process/README b/src/pmdas/process/README
new file mode 100644
index 0000000..78579e8
--- /dev/null
+++ b/src/pmdas/process/README
@@ -0,0 +1,74 @@
+#
+# Copyright (c) 2001 Alan Bailey (bailey@mcs.anl.gov or abailey@ncsa.uiuc.edu)
+# for the portions of the code supporting the initial agent functionality.
+# All rights reserved.
+#
+# Copyright (c) 2001,2004 Silicon Graphics, Inc. All Rights Reserved.
+#
+
+Process PMDA
+============
+
+This PMDA monitors root processes to see if they are still running.
+The processes that are monitored are stored in a config file,
+and the PMDA returns the number of root processes with that name
+running. In this way, you can check to see if the number of processes
+is in a range, is 1, is 0, or some other combination.
+
+This source code was contributed by Alan Bailey (abailey@ncsa.uiuc.edu)
+to the PCP open source project.
+
+Metrics
+=======
+
+The file ./help contains descriptions for all of the metrics exported
+by this PMDA.
+
+Once the PMDA has been installed, the following command will list all
+the available metrics and their explanatory "help" text:
+
+ $ pminfo -fT process
+
+Installation
+============
+
+ + # cd $PCP_PMDAS_DIR/process
+
+ + Check that there is no clash in the Performance Metrics Domain
+ defined in ./domain.h and the other PMDAs currently in use
+ ($PCP_PMCDCONF_PATH). If there is, edit ./domain.h
+ to choose another domain number.
+
+ + Then simply use
+
+ # ./Install
+
+ and choose both the "collector" and "monitor" installation
+ configuration options -- everything else is automated.
+
+ + Alternatively, to install just the Performance Metrics Name Space
+ for the process metrics on the local system, but not the process
+ PMDA (presumably because the local system is running PCP 1.x and
+ you wish to connect to a remote system where PCP 2.0 and the process
+ PMDA is running), make sure the Performance Metrics Domain defined
+ in ./domain.h matches the domain chosen for the process PMDA on the
+ remote system (check the second field in the corresponding line of the
+ $PCP_PMCDCONF_PATH file on the remote system), then
+
+ # ./Install -N
+
+De-installation
+===============
+
+ + Simply use
+
+ # cd $PCP_PMDAS_DIR/process
+ # ./Remove
+
+Troubleshooting
+===============
+
+ + After installing or restarting the agent, the PMCD log file
+ ($PCP_LOG_DIR/pmcd/pmcd.log) and the PMDA log file
+ ($PCP_LOG_DIR/pmcd/process.log) should be checked for any warnings or
+ errors.
diff --git a/src/pmdas/process/Remove b/src/pmdas/process/Remove
new file mode 100755
index 0000000..b90a863
--- /dev/null
+++ b/src/pmdas/process/Remove
@@ -0,0 +1,41 @@
+#! /bin/sh
+#
+# Copyright (c) 2001 Alan Bailey (bailey@mcs.anl.gov or abailey@ncsa.uiuc.edu)
+# for the portions of the code supporting the initial agent functionality.
+# All rights reserved.
+# Copyright (c) 2001,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.
+#
+# You should have received a copy of the GNU General Public License along
+# with this program; if not, write to the Free Software Foundation, Inc.,
+# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+#
+# Remove the process PMDA
+#
+
+# source the PCP configuration environment variables
+. $PCP_DIR/etc/pcp.env
+
+# Get the common procedures and variable assignments
+#
+. $PCP_SHARE_DIR/lib/pmdaproc.sh
+
+# The name of the PMDA
+#
+iam=process
+
+# Do it
+#
+pmdaSetup
+pmdaRemove
+
+exit 0
diff --git a/src/pmdas/process/help b/src/pmdas/process/help
new file mode 100644
index 0000000..acf2a37
--- /dev/null
+++ b/src/pmdas/process/help
@@ -0,0 +1,38 @@
+#
+# Copyright (c) 2001 Alan Bailey (bailey@mcs.anl.gov or abailey@ncsa.uiuc.edu)
+# for the portions of the code supporting the initial agent functionality.
+# All rights reserved.
+# Copyright (c) 2001,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.
+#
+# You should have received a copy of the GNU General Public License along
+# with this program; if not, write to the Free Software Foundation, Inc.,
+# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+#
+# process PMDA help file in the ASCII format
+#
+# lines beginning with a # are ignored
+# lines beginning @ introduce a new entry of the form
+# @ metric_name oneline-text
+# help test goes
+# here over multiple lines
+# ...
+#
+# the metric_name is decoded against the default PMNS -- as a special case,
+# a name of the form NNN.MM (for numeric NNN and MM) is interpreted as an
+# instance domain identification, and the text describes the instance domain
+#
+# blank lines before the @ line are ignored
+#
+
+@ process.running Tool for tracking running root processes
+This tracks the number of running root processes for processes you define
diff --git a/src/pmdas/process/pmns b/src/pmdas/process/pmns
new file mode 100644
index 0000000..8df2327
--- /dev/null
+++ b/src/pmdas/process/pmns
@@ -0,0 +1,26 @@
+/*
+ * Copyright (c) 2001 Alan Bailey (bailey@mcs.anl.gov or abailey@ncsa.uiuc.edu)
+ * for the portions of the code supporting the initial agent functionality.
+ * All rights reserved.
+ * Copyright (c) 2001,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.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Metrics for process PMDA
+ */
+
+process {
+ running PROCESS:0:0
+}
diff --git a/src/pmdas/process/process.c b/src/pmdas/process/process.c
new file mode 100644
index 0000000..00f9d80
--- /dev/null
+++ b/src/pmdas/process/process.c
@@ -0,0 +1,413 @@
+/*
+ * The process PMDA
+ *
+ * This code monitors root processes to see if they are still
+ * running. The processes that are monitored are stored in a config file,
+ * and the PMDA returns the number of root processes with that name
+ * running. In this way, you can check to see if the number of processes
+ * is in a range, is 1, is 0, or some other combination.
+ *
+ * Copyright (c) 2001 Alan Bailey (bailey@mcs.anl.gov or abailey@ncsa.uiuc.edu)
+ * for the portions of the code supporting the initial agent functionality.
+ * All rights reserved.
+ *
+ * Copyright (c) 2001,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.
+ */
+
+#include "pmapi.h"
+#include "impl.h"
+#include "pmda.h"
+#include "domain.h"
+#include <ctype.h>
+#include <dirent.h>
+#include <sys/stat.h>
+
+/*
+ * Process PMDA
+ *
+ * Metrics
+ * process.running
+ * The number of root processes running for each name
+ * The process names are stored in
+ * PCP_VAR_DIR/pmdas/process/process.conf
+ */
+
+static pmdaInstid *processes;
+
+static pmdaIndom indomtab[] = {
+#define PROC_INDOM 0
+ { PROC_INDOM, 0, NULL }
+};
+
+static pmdaMetric metrictab[] = {
+/* process.running */
+ { NULL,
+ { PMDA_PMID(0,0), PM_TYPE_DOUBLE, PROC_INDOM, PM_SEM_INSTANT,
+ PMDA_PMUNITS(0,0,0,0,0,0) }, },
+};
+
+/* Variables needed for this file */
+static int *num_procs;
+static struct stat file_change;
+static int npidlist;
+static int maxpidlist;
+static int *pidlist;
+static int isDSO = 1;
+static char mypath[MAXPATHLEN];
+
+/* Routines in this file */
+static void process_clear_config_info(void);
+static void process_grab_config_info(void);
+static void process_config_file_check(void);
+static int process_refresh_pidlist(void);
+
+static void
+process_config_file_check(void)
+{
+ struct stat statbuf;
+ static int last_error;
+ int sep = __pmPathSeparator();
+
+ snprintf(mypath, sizeof(mypath), "%s%c" "process" "%c" "process.conf",
+ pmGetConfig("PCP_PMDAS_DIR"), sep, sep);
+ if (stat(mypath, &statbuf) == -1) {
+ if (oserror() != last_error) {
+ last_error = oserror();
+ __pmNotifyErr(LOG_WARNING, "stat failed on %s: %s\n",
+ mypath, pmErrStr(-oserror()));
+ }
+ } else {
+ last_error = 0;
+#if defined(HAVE_ST_MTIME_WITH_E)
+ if (memcmp(&statbuf.st_mtime, &file_change.st_mtime, sizeof(statbuf.st_mtime)) != 0)
+#elif defined(HAVE_ST_MTIME_WITH_SPEC)
+ if (memcmp(&statbuf.st_mtimespec, &file_change.st_mtimespec, sizeof(statbuf.st_mtimespec)) != 0)
+#else
+ if (memcmp(&statbuf.st_mtim, &file_change.st_mtim, sizeof(statbuf.st_mtim)) != 0)
+#endif
+ {
+ process_clear_config_info();
+ process_grab_config_info();
+ file_change = statbuf;
+ }
+ }
+}
+
+/*
+ * This function is called when the config file needs to be read in
+ * again, so we can define new instances and such. This frees the
+ * previous memory, if any (on startup, there won't be any), and sets
+ * the two variables to NULL for fun.
+ */
+static void
+process_clear_config_info(void)
+{
+ int i;
+
+ /* Free the memory holding the process name */
+ for (i = 0; i < indomtab[PROC_INDOM].it_numinst; i++)
+ free(processes[i].i_name);
+
+ /* Free the processes structure */
+ if (processes)
+ free(processes);
+
+ /* Free the process counter structure */
+ if (num_procs)
+ free(num_procs);
+ num_procs = NULL;
+
+ indomtab[PROC_INDOM].it_set = processes = NULL;
+ indomtab[PROC_INDOM].it_numinst = 0;
+}
+
+/*
+ * This routine opens the config file and stores the information in the
+ * processes structure. The processes structure must be reallocated as
+ * necessary, and also the num_procs structure needs to be reallocated
+ * as we define new processes. When all of that is done, we fill in the
+ * values in the indomtab structure, those being the number of instances
+ * and the pointer to the processes structure.
+ *
+ * A lot of this code was taken from the simple.c code, but in this
+ * case, I changed a lot of it to fit my purposes...
+ */
+static void
+process_grab_config_info(void)
+{
+ FILE *fp;
+ char process_name[1024];
+ char *q;
+ size_t size;
+ int process_number = 0;
+ int sep = __pmPathSeparator();
+
+ snprintf(mypath, sizeof(mypath), "%s%c" "process" "%c" "process.conf",
+ pmGetConfig("PCP_PMDAS_DIR"), sep, sep);
+ if ((fp = fopen(mypath, "r")) == NULL) {
+ __pmNotifyErr(LOG_ERR, "fopen on %s failed: %s\n",
+ mypath, pmErrStr(-oserror()));
+ if (processes != NULL) {
+ free(processes);
+ processes = NULL;
+ process_number = 0;
+ }
+ goto done;
+ }
+
+ while (fgets(process_name, sizeof(process_name), fp) != NULL) {
+ if (process_name[0] == '#')
+ continue;
+ /* Remove the newline */
+ if ((q = strchr(process_name, '\n')) != NULL) {
+ *q = '\0';
+ } else {
+ /* This means the line was too long */
+ __pmNotifyErr(LOG_WARNING, "line %d in config file too long\n",
+ process_number + 1);
+ }
+ size = (process_number + 1) * sizeof(pmdaInstid);
+ if ((processes = realloc(processes, size)) == NULL)
+ __pmNoMem("process", size, PM_FATAL_ERR);
+ processes[process_number].i_name = malloc(strlen(process_name) + 1);
+ strcpy(processes[process_number].i_name, process_name);
+ processes[process_number].i_inst = process_number;
+ process_number++;
+ }
+ fclose(fp);
+
+done:
+ if (processes == NULL)
+ __pmNotifyErr(LOG_WARNING, "\"process\" instance domain is empty");
+
+ indomtab[PROC_INDOM].it_set = processes;
+ indomtab[PROC_INDOM].it_numinst = process_number;
+
+ num_procs = realloc(num_procs, (process_number)*sizeof(int));
+}
+
+/*
+ * This code refreshes the count of all the processes that we want to
+ * monitor. It does this by calling process_refresh_pidlist, which just
+ * grabs a list of all the running processes (as PIDs). We then loop
+ * through each of these processes, and check to see if it is a root
+ * process. If so, we then open up the /proc/<PID>/status file,
+ * and see what the process name is. If it is one of our special
+ * processes that we want to track, then we up the count for that
+ * process in num_procs. Then we're done.
+ */
+static void
+process_refresh_pid_checks(void)
+{
+ int proc;
+ char proc_path[30];
+ char cmd_line[200];
+ FILE *fd;
+ int proc_name;
+ int item;
+ struct stat statbuf;
+
+ process_refresh_pidlist();
+
+ /* Clear the variables */
+ for (item = 0; item < indomtab[PROC_INDOM].it_numinst; item++)
+ num_procs[item] = 0;
+
+ for (proc = 0; proc < npidlist; proc++) {
+ sprintf(proc_path, "/proc/%d/status", pidlist[proc]);
+ if (stat(proc_path, &statbuf) == -1) {
+ /* We can't stat it, let's assume the process isn't running anymore */
+ continue;
+ } else {
+ /* This checks to make sure the process is a root process */
+ if (statbuf.st_uid != 0) {
+ continue;
+ }
+ }
+
+ if ((fd = fopen(proc_path, "r")) != NULL) {
+ /*
+ * matching process by name is platform specific ... this code
+ * works for Linux when /proc/<pid>/status is ascii and the
+ * first line is of the form:
+ * Name: <cmdname>
+ */
+ if (fgets(cmd_line, sizeof(cmd_line), fd) == NULL) {
+ /*
+ * not expected, but not a disaster ... we'll just not try
+ * to match this one
+ */
+ fclose(fd);
+ continue;
+ }
+ fclose(fd);
+
+ for (proc_name = 0; proc_name < indomtab[PROC_INDOM].it_numinst; proc_name++) {
+ if (strstr(cmd_line, (processes[proc_name]).i_name)) {
+ (num_procs[proc_name])++;
+ }
+ }
+ }
+ }
+}
+
+/*
+ * Read in the list of all processes running.
+ */
+int
+process_refresh_pidlist()
+{
+ DIR *dirp = opendir("/proc");
+ struct dirent *dp;
+
+ if (dirp == NULL)
+ return -oserror();
+
+ npidlist = 0;
+ while ((dp = readdir(dirp)) != (struct dirent *)NULL) {
+ if (isdigit((int)dp->d_name[0])) {
+ if (npidlist >= maxpidlist) {
+ maxpidlist += 16;
+ pidlist = (int *)realloc(pidlist, maxpidlist * sizeof(int));
+ }
+ pidlist[npidlist++] = atoi(dp->d_name);
+ }
+ }
+ closedir(dirp);
+
+#ifdef PCP_DEBUG
+ if (pmDebug & DBG_TRACE_APPL2) {
+ fprintf(stderr, "process_refresh_pidlist: found %d PIDs:", npidlist);
+ if (npidlist > 0) {
+ fprintf(stderr, " %d", pidlist[0]);
+ if (npidlist > 1) {
+ fprintf(stderr, " %d", pidlist[1]);
+ if (npidlist == 3)
+ fprintf(stderr, " %d", pidlist[2]);
+ else if (npidlist == 4)
+ fprintf(stderr, " %d %d", pidlist[2], pidlist[3]);
+ else if (npidlist > 4)
+ fprintf(stderr, " ... %d %d", pidlist[npidlist-2],
+ pidlist[npidlist-1]);
+ }
+ }
+ fprintf(stderr, "\n");
+ }
+#endif
+
+ return npidlist;
+}
+
+static int
+process_fetch(int numpmid, pmID pmidlist[], pmResult **resp, pmdaExt *pmda)
+{
+ /*
+ * This is the wrapper over the pmdaFetch routine, to handle the problem
+ * of varying instance domains. All this does is check to see if the
+ * config file has been updated, and update the instance domain if so,
+ * and refresh the pid count for the processes.
+ */
+ process_config_file_check();
+ process_refresh_pid_checks();
+ return pmdaFetch(numpmid, pmidlist, resp, pmda);
+}
+
+
+/*
+ * callback provided to pmdaFetch
+ */
+static int
+process_fetchCallBack(pmdaMetric *mdesc, unsigned int inst, pmAtomValue *atom)
+{
+ __pmID_int *idp = (__pmID_int *)&(mdesc->m_desc.pmid);
+
+ if (idp->cluster != 0)
+ return PM_ERR_PMID;
+ if (idp->item != 0)
+ return PM_ERR_PMID;
+
+ /* We have the values stored, simply grab it and return it. */
+ atom->d = num_procs[inst];
+ return 0;
+}
+
+/*
+ * Initialise the agent (both daemon and DSO).
+ */
+void
+process_init(pmdaInterface *dp)
+{
+ if (isDSO) {
+ int sep = __pmPathSeparator();
+ snprintf(mypath, sizeof(mypath), "%s%c" "process" "%c" "help",
+ pmGetConfig("PCP_PMDAS_DIR"), sep, sep);
+ pmdaDSO(dp, PMDA_INTERFACE_2, "process DSO", mypath);
+ }
+
+ if (dp->status != 0)
+ return;
+
+ dp->version.two.fetch = process_fetch;
+
+ /* Let's grab the info right away just to make sure it's there. */
+ process_grab_config_info();
+
+ pmdaSetFetchCallBack(dp, process_fetchCallBack);
+
+ pmdaInit(dp, indomtab, sizeof(indomtab)/sizeof(indomtab[0]),
+ metrictab, sizeof(metrictab)/sizeof(metrictab[0]));
+}
+
+pmLongOptions longopts[] = {
+ PMDA_OPTIONS_HEADER("Options"),
+ PMOPT_DEBUG,
+ PMDAOPT_DOMAIN,
+ PMDAOPT_LOGFILE,
+ PMOPT_HELP,
+ PMDA_OPTIONS_END
+};
+
+pmdaOptions opts = {
+ .short_options = "D:d:l:?",
+ .long_options = longopts,
+};
+
+/*
+ * Set up the agent if running as a daemon.
+ */
+int
+main(int argc, char **argv)
+{
+ int sep = __pmPathSeparator();
+ pmdaInterface desc;
+
+ isDSO = 0;
+ __pmSetProgname(argv[0]);
+
+ snprintf(mypath, sizeof(mypath), "%s%c" "process" "%c" "help",
+ pmGetConfig("PCP_PMDAS_DIR"), sep, sep);
+ pmdaDaemon(&desc, PMDA_INTERFACE_2, pmProgname, PROCESS,
+ "process.log", mypath);
+
+ pmdaGetOptions(argc, argv, &opts, &desc);
+ if (opts.errors) {
+ pmdaUsageMessage(&opts);
+ exit(1);
+ }
+
+ pmdaOpenLog(&desc);
+ process_init(&desc);
+ pmdaConnect(&desc);
+ pmdaMain(&desc);
+ exit(0);
+}
diff --git a/src/pmdas/process/process.conf b/src/pmdas/process/process.conf
new file mode 100644
index 0000000..a02879d
--- /dev/null
+++ b/src/pmdas/process/process.conf
@@ -0,0 +1,11 @@
+# Copyright (c) 2001 Alan Bailey (bailey@mcs.anl.gov or abailey@ncsa.uiuc.edu)
+# for the portions of the code supporting the initial agent functionality.
+# All rights reserved.
+# Copyright (c) 2001,2004 Silicon Graphics, Inc. All Rights Reserved.
+#
+sshd
+crond
+inetd
+nfsd
+afsd
+test
diff --git a/src/pmdas/process/root b/src/pmdas/process/root
new file mode 100644
index 0000000..f2fba58
--- /dev/null
+++ b/src/pmdas/process/root
@@ -0,0 +1,16 @@
+/*
+ * Copyright (c) 2001 Alan Bailey (bailey@mcs.anl.gov or abailey@ncsa.uiuc.edu)
+ * for the portions of the code supporting the initial agent functionality.
+ * All rights reserved.
+ * Copyright (c) 2001,2004 Silicon Graphics, Inc. All Rights Reserved.
+ */
+
+/*
+ * fake "root" for validating the local PMNS subtree
+ */
+#include <stdpmid>
+
+root { process }
+
+#include "pmns"
+