summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorM. Sean Finney <seanius@users.sourceforge.net>2005-09-22 09:43:12 +0000
committerM. Sean Finney <seanius@users.sourceforge.net>2005-09-22 09:43:12 +0000
commit5163656fe8b96a98def934c2fb4a8529fe3a7489 (patch)
tree16e919f6ae083783ae27b14ac80c2821e86ad3c0
parent07881972576a9a517100f7394d5538200d6986fd (diff)
downloadmonitoring-plugins-5163656fe8b96a98def934c2fb4a8529fe3a7489.tar.gz
first version of bob ingraham's pst3 to allow checking for longer
cmdline names than otherwise possible, by querying solaris kmem directly (ps forcibly truncates). added requisite configure.in voodoo and updated THANKS.in. git-svn-id: https://nagiosplug.svn.sourceforge.net/svnroot/nagiosplug/nagiosplug/trunk@1238 f882894a-f735-0410-b71e-b25c423dba1c
-rw-r--r--THANKS.in1
-rw-r--r--configure.in11
-rw-r--r--plugins-root/pst3.c252
3 files changed, 263 insertions, 1 deletions
diff --git a/THANKS.in b/THANKS.in
index c83997ec..fb73b141 100644
--- a/THANKS.in
+++ b/THANKS.in
@@ -168,3 +168,4 @@ Ronald Tin
168Chester Hosey 168Chester Hosey
169Pascal Larisch 169Pascal Larisch
170David Sullivan 170David Sullivan
171Bob Ingraham
diff --git a/configure.in b/configure.in
index ee5fb906..176a8e22 100644
--- a/configure.in
+++ b/configure.in
@@ -598,9 +598,18 @@ dnl #### Process table test
598AC_PATH_PROG(PATH_TO_PS,ps) 598AC_PATH_PROG(PATH_TO_PS,ps)
599 599
600AC_MSG_CHECKING(for ps syntax) 600AC_MSG_CHECKING(for ps syntax)
601
602dnl Now using the pst3/kmem hack for solaris systems to avoid truncation
603if [ "$ac_cv_uname_s" = "SunOS" ]; then
604 ac_cv_ps_command="$prefix/pst3"
605 ac_cv_ps_format="%s %d %d %d %d %f %s %n"
606 ac_cv_ps_varlist="[procstat,&procuid,&procppid,&procvsz,&procrss,&procpcpu,procprog,&pos]"
607 ac_cv_ps_cols=8
608 AC_MSG_RESULT([using nagios-plugins internal ps for solaris])
609
601dnl Some gnu/linux systems (debian for one) don't like -axwo and need axwo. 610dnl Some gnu/linux systems (debian for one) don't like -axwo and need axwo.
602dnl so test for this first... 611dnl so test for this first...
603if ps axwo 'stat comm vsz rss user uid pid ppid args' 2>/dev/null | \ 612elif ps axwo 'stat comm vsz rss user uid pid ppid args' 2>/dev/null | \
604 egrep -i ["^ *STAT +[UCOMAND]+ +VSZ +RSS +USER +UID +PID +PPID +COMMAND"] > /dev/null 613 egrep -i ["^ *STAT +[UCOMAND]+ +VSZ +RSS +USER +UID +PID +PPID +COMMAND"] > /dev/null
605then 614then
606 ac_cv_ps_varlist="[procstat,&procuid,&procpid,&procppid,&procvsz,&procrss,&procpcpu,procprog,&pos]" 615 ac_cv_ps_varlist="[procstat,&procuid,&procpid,&procppid,&procvsz,&procrss,&procpcpu,procprog,&pos]"
diff --git a/plugins-root/pst3.c b/plugins-root/pst3.c
new file mode 100644
index 00000000..ace3113c
--- /dev/null
+++ b/plugins-root/pst3.c
@@ -0,0 +1,252 @@
1/* pst3.c
2 *
3 * Third version to get process arg info; this time by using
4 * a combination of reading the /proc/<pid>/psinfo structures
5 * and reading the complete arg vector from kernel memory structures.
6 *
7 * Developed and tested under Solaris 5.8 (both 32 and 64 bit modes).
8 *
9 * NOTE: This program must be setuid-root (or run by root) to work!
10 *
11 * Written: 2005-04-28 R.W.Ingraham
12 */
13
14
15#define _KMEMUSER 1
16
17#include <kvm.h>
18#include <sys/param.h>
19#include <sys/user.h>
20#include <sys/time.h>
21#include <sys/proc.h>
22#include <sys/types.h>
23#include <sys/stat.h>
24#include <stdio.h>
25#include <stdlib.h>
26#include <unistd.h>
27#include <string.h>
28#include <procfs.h>
29#include <fcntl.h>
30#include <dirent.h>
31#include <errno.h>
32
33
34/*
35 * Constants
36 */
37
38#define PROC_DIR "/proc"
39#define MAX_PATH 1024
40
41
42/*
43 * Structures
44 */
45
46
47/*
48 * Globals
49 */
50
51static char * szProg;
52static kvm_t * kd;
53static struct proc * pProc;
54static struct user * pUser;
55static char ** myArgv;
56
57
58/*
59 * Prototypes
60 */
61
62static int HandleFile (struct dirent *pDent);
63static int HandlePsInfo (char *szPath, psinfo_t *pPsInfo);
64static int GetArgVectors (pid_t pid);
65static void ShowArgVectors (void);
66static void ReleaseArgVectors();
67
68
69/*----------------------------------------------------------------------------*/
70
71int main (int argc, char **argv)
72{
73 DIR *pDir;
74 struct dirent *pDent;
75 int retcode = 0;
76
77
78 /* Set our program name global */
79 if ((szProg = strrchr(argv[0], '/')) != NULL)
80 szProg++;
81 else
82 szProg = argv[0];
83
84 /* Make sure that our euid is root */
85 if (geteuid() != 0)
86 {
87 fprintf(stderr, "%s: This program can only be run by the root user!\n", szProg);
88 exit(1);
89 }
90
91 /* Get a handle to the running kernel image */
92 if ((kd = kvm_open(NULL, NULL, NULL, O_RDONLY, argv[0])) == NULL)
93 {
94 fprintf(stderr, "%s: Failed to open kernel memory: %s\n", szProg, strerror(errno));
95 exit(2);
96 }
97
98 /* Open the /proc directory */
99 if ((pDir = opendir(PROC_DIR)) != NULL)
100 {
101 /* Display column headings */
102 printf("S UID PPID VSZ RSS %%CPU COMMAND ARGS\n");
103
104 /* Zip through all of the process entries */
105 while ((pDent = readdir(pDir)) != NULL)
106 {
107 /* Handle each pid sub-directory */
108 HandleFile(pDent);
109 }
110
111 /* Close the directory */
112 closedir(pDir);
113 }
114 else /* ERROR: Failure to open PROC_DIR */
115 {
116 fprintf(stderr, "%s: Failed to open \"%s\": %s\n", szProg, PROC_DIR, strerror(errno));
117 retcode = 3;
118 }
119
120 /* Close the handle to the running kernel image */
121 kvm_close(kd);
122
123 return retcode;
124}
125
126/*----------------------------------------------------------------------------*/
127
128static int HandleFile (struct dirent *pDent)
129{
130 char szPath[MAX_PATH];
131 psinfo_t sPsInfo;
132 int fd, len;
133 int rc = 0;
134
135 /* Skip files beginning with a "." */
136 if (pDent->d_name[0] == '.')
137 return 0;
138
139 /* Cosntruct the path to the psinfo file */
140 len = sprintf(szPath, "%s/%s/psinfo", PROC_DIR, pDent->d_name);
141
142 /* Open the psinfo file for this pid and print out its arg vectors */
143 if ((fd = open(szPath, O_RDONLY)) >= 0)
144 {
145 /* Read the psinfo struct */
146 if ((len = read(fd, &sPsInfo, sizeof(sPsInfo))) != sizeof(sPsInfo))
147 {
148 rc = errno;
149 fprintf(stderr, "%s: Read error of psinfo structure (%d)\n", szPath, len);
150 return rc;
151 }
152
153 /* Close the psinfo file */
154 close(fd);
155
156 /* Pass psinfo struct to reporting function */
157 HandlePsInfo(szPath, &sPsInfo);
158 }
159 else if (errno != ENOENT)
160 {
161 rc = errno;
162 fprintf(stderr, "%s: %s\n", szPath, strerror(errno));
163 }
164
165 return 0;
166}
167
168/*----------------------------------------------------------------------------*/
169
170static int HandlePsInfo (char *szPath, psinfo_t *pPsInfo)
171{
172 int retcode;
173 char *thisProg;
174
175 /* Make sure that the process is still there */
176 if ((retcode = GetArgVectors(pPsInfo->pr_pid)) == 0)
177 {
178 /* We use the program name from the kvm argv[0] instead
179 * of pr_fname from the psinfo struct because pr_fname
180 * may be truncated.
181 *
182 * Also, strip-off leading path information.
183 */
184 if ((thisProg = strrchr(myArgv[0], '/')) != NULL)
185 thisProg++;
186 else
187 thisProg = myArgv[0];
188
189 /* Display the ps columns (except for argv) */
190 printf("%c %5d %5d %6lu %6lu %4.1f %s ",
191 pPsInfo->pr_lwp.pr_sname,
192 (int)(pPsInfo->pr_euid),
193 (int)(pPsInfo->pr_ppid),
194 (unsigned long)(pPsInfo->pr_size),
195 (unsigned long)(pPsInfo->pr_rssize),
196 ((float)(pPsInfo->pr_pctcpu) / 0x8000 * 100.0),
197 thisProg);
198
199 /* Display the arg vectors associated with this pid */
200 ShowArgVectors();
201
202 /* Release the arg vector buffer memory */
203 ReleaseArgVectors();
204 }
205
206 return retcode;
207}
208
209/*----------------------------------------------------------------------------*/
210
211static int GetArgVectors (pid_t pid)
212{
213 int retcode = 1;
214
215 /* Get the proc structure for the specified PID */
216 if ((pProc = kvm_getproc(kd, pid)) != NULL)
217 {
218 /* Save a copy of the process' u-area */
219 if ((pUser = kvm_getu(kd, pProc)) != NULL)
220 {
221 /* Reconstruct the process' argv vector array */
222 if (kvm_getcmd(kd, pProc, pUser, &myArgv, NULL) == 0)
223 {
224 retcode = 0;
225 }
226 }
227 }
228
229 return retcode;
230}
231
232/*----------------------------------------------------------------------------*/
233
234static void ShowArgVectors (void)
235{
236 int i;
237
238 for (i=0; myArgv[i]; i++)
239 {
240 printf(" %s", myArgv[i]);
241 }
242 printf("\n");
243}
244
245/*----------------------------------------------------------------------------*/
246
247static void ReleaseArgVectors()
248{
249 /* NOOP */
250}
251
252/*----------------------------------------------------------------------------*/