X-Git-Url: https://git.octo.it/?a=blobdiff_plain;f=src%2Fprocesses.c;h=30798d42a6b76274608a6270c7481dddd3a17350;hb=66f9d645f883eee0aa408428eefdebdcc6dcfa7e;hp=261accbcbc7582218c6f5744cb818beba533ffe8;hpb=37905c5a2370c8e6edae5011978773eeaa589d09;p=collectd.git diff --git a/src/processes.c b/src/processes.c index 261accbc..30798d42 100644 --- a/src/processes.c +++ b/src/processes.c @@ -4,6 +4,9 @@ * Copyright (C) 2006-2008 Florian octo Forster * Copyright (C) 2008 Oleg King * Copyright (C) 2009 Sebastian Harl + * Copyright (C) 2009 Andrés J. Díaz + * Copyright (C) 2009 Manuel Sanmartin + * Copyright (C) 2010 Clément Stenac * * 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 @@ -24,6 +27,9 @@ * Florian octo Forster * Oleg King * Sebastian Harl + * Andrés J. Díaz + * Manuel Sanmartin + * Clément Stenac **/ #include "collectd.h" @@ -94,6 +100,15 @@ # include /* #endif HAVE_LIBKVM_GETPROCS && HAVE_STRUCT_KINFO_PROC_FREEBSD */ +#elif HAVE_PROCINFO_H +# include +# include + +#define MAXPROCENTRY 32 +#define MAXTHRDENTRY 16 +#define MAXARGLN 1024 +/* #endif HAVE_PROCINFO_H */ + #else # error "No applicable input method." #endif @@ -106,8 +121,6 @@ # define ARG_MAX 4096 #endif -#define BUFSIZE 256 - static const char *config_keys[] = { "Process", @@ -124,6 +137,8 @@ typedef struct procstat_entry_s unsigned long num_lwp; unsigned long vmem_size; unsigned long vmem_rss; + unsigned long vmem_data; + unsigned long vmem_code; unsigned long stack_size; unsigned long vmem_minflt; @@ -136,6 +151,12 @@ typedef struct procstat_entry_s unsigned long cpu_user_counter; unsigned long cpu_system_counter; + /* io data */ + derive_t io_rchar; + derive_t io_wchar; + derive_t io_syscr; + derive_t io_syscw; + struct procstat_entry_s *next; } procstat_entry_t; @@ -151,6 +172,8 @@ typedef struct procstat unsigned long num_lwp; unsigned long vmem_size; unsigned long vmem_rss; + unsigned long vmem_data; + unsigned long vmem_code; unsigned long stack_size; unsigned long vmem_minflt_counter; @@ -159,6 +182,12 @@ typedef struct procstat unsigned long cpu_user_counter; unsigned long cpu_system_counter; + /* io data */ + derive_t io_rchar; + derive_t io_wchar; + derive_t io_syscr; + derive_t io_syscw; + struct procstat *next; struct procstat_entry_s *instances; } procstat_t; @@ -179,7 +208,19 @@ static long pagesize_g; #elif HAVE_LIBKVM_GETPROCS && HAVE_STRUCT_KINFO_PROC_FREEBSD /* no global variables */ -#endif /* HAVE_LIBKVM_GETPROCS && HAVE_STRUCT_KINFO_PROC_FREEBSD */ +/* #endif HAVE_LIBKVM_GETPROCS && HAVE_STRUCT_KINFO_PROC_FREEBSD */ + +#elif HAVE_PROCINFO_H +static struct procentry64 procentry[MAXPROCENTRY]; +static struct thrdentry64 thrdentry[MAXTHRDENTRY]; +static int pagesize; + +#ifndef _AIXVERSION_610 +int getprocs64 (void *procsinfo, int sizproc, void *fdsinfo, int sizfd, pid_t *index, int count); +int getthrds64( pid_t, void *, int, tid64_t *, int ); +#endif +int getargs (struct procentry64 *processBuffer, int bufferLen, char *argsBuffer, int argsLen); +#endif /* HAVE_PROCINFO_H */ /* put name of process from config to list_head_g tree list_head_g is a list of 'procstat_t' structs with @@ -225,13 +266,13 @@ static void ps_list_register (const char *name, const char *regexp) ERROR ("processes plugin: ps_list_register: " "Regular expression \"%s\" found in config " "file, but support for regular expressions " - "has been dispabled at compile time.", + "has been disabled at compile time.", regexp); sfree (new); return; } #endif - + for (ptr = list_head_g; ptr != NULL; ptr = ptr->next) { if (strcmp (ptr->name, name) == 0) @@ -307,13 +348,13 @@ static void ps_list_add (const char *name, const char *cmdline, procstat_entry_t if ((pse == NULL) || (pse->id != entry->id)) { procstat_entry_t *new; - + new = (procstat_entry_t *) malloc (sizeof (procstat_entry_t)); if (new == NULL) return; memset (new, 0, sizeof (procstat_entry_t)); new->id = entry->id; - + if (pse == NULL) ps->instances = new; else @@ -327,14 +368,27 @@ static void ps_list_add (const char *name, const char *cmdline, procstat_entry_t pse->num_lwp = entry->num_lwp; pse->vmem_size = entry->vmem_size; pse->vmem_rss = entry->vmem_rss; + pse->vmem_data = entry->vmem_data; + pse->vmem_code = entry->vmem_code; pse->stack_size = entry->stack_size; + pse->io_rchar = entry->io_rchar; + pse->io_wchar = entry->io_wchar; + pse->io_syscr = entry->io_syscr; + pse->io_syscw = entry->io_syscw; ps->num_proc += pse->num_proc; ps->num_lwp += pse->num_lwp; ps->vmem_size += pse->vmem_size; ps->vmem_rss += pse->vmem_rss; + ps->vmem_data += pse->vmem_data; + ps->vmem_code += pse->vmem_code; ps->stack_size += pse->stack_size; + ps->io_rchar += ((pse->io_rchar == -1)?0:pse->io_rchar); + ps->io_wchar += ((pse->io_wchar == -1)?0:pse->io_wchar); + ps->io_syscr += ((pse->io_syscr == -1)?0:pse->io_syscr); + ps->io_syscw += ((pse->io_syscw == -1)?0:pse->io_syscw); + if ((entry->vmem_minflt_counter == 0) && (entry->vmem_majflt_counter == 0)) { @@ -356,7 +410,7 @@ static void ps_list_add (const char *name, const char *cmdline, procstat_entry_t pse->vmem_minflt = entry->vmem_minflt_counter - pse->vmem_minflt_counter; } pse->vmem_minflt_counter = entry->vmem_minflt_counter; - + if (entry->vmem_majflt_counter < pse->vmem_majflt_counter) { pse->vmem_majflt = entry->vmem_majflt_counter @@ -393,7 +447,7 @@ static void ps_list_add (const char *name, const char *cmdline, procstat_entry_t pse->cpu_user = entry->cpu_user_counter - pse->cpu_user_counter; } pse->cpu_user_counter = entry->cpu_user_counter; - + if (entry->cpu_system_counter < pse->cpu_system_counter) { pse->cpu_system = entry->cpu_system_counter @@ -424,7 +478,13 @@ static void ps_list_reset (void) ps->num_lwp = 0; ps->vmem_size = 0; ps->vmem_rss = 0; + ps->vmem_data = 0; + ps->vmem_code = 0; ps->stack_size = 0; + ps->io_rchar = -1; + ps->io_wchar = -1; + ps->io_syscr = -1; + ps->io_syscw = -1; pse_prev = NULL; pse = ps->instances; @@ -538,7 +598,11 @@ static int ps_init (void) #elif HAVE_LIBKVM_GETPROCS && HAVE_STRUCT_KINFO_PROC_FREEBSD /* no initialization */ -#endif /* HAVE_LIBKVM_GETPROCS && HAVE_STRUCT_KINFO_PROC_FREEBSD */ +/* #endif HAVE_LIBKVM_GETPROCS && HAVE_STRUCT_KINFO_PROC_FREEBSD */ + +#elif HAVE_PROCINFO_H + pagesize = getpagesize(); +#endif /* HAVE_PROCINFO_H */ return (0); } /* int ps_init */ @@ -584,6 +648,16 @@ static void ps_submit_proc_list (procstat_t *ps) vl.values_len = 1; plugin_dispatch_values (&vl); + sstrncpy (vl.type, "ps_data", sizeof (vl.type)); + vl.values[0].gauge = ps->vmem_data; + vl.values_len = 1; + plugin_dispatch_values (&vl); + + sstrncpy (vl.type, "ps_code", sizeof (vl.type)); + vl.values[0].gauge = ps->vmem_code; + vl.values_len = 1; + plugin_dispatch_values (&vl); + sstrncpy (vl.type, "ps_stacksize", sizeof (vl.type)); vl.values[0].gauge = ps->stack_size; vl.values_len = 1; @@ -607,76 +681,185 @@ static void ps_submit_proc_list (procstat_t *ps) vl.values_len = 2; plugin_dispatch_values (&vl); - DEBUG ("name = %s; num_proc = %lu; num_lwp = %lu; vmem_rss = %lu; " + if ( (ps->io_rchar != -1) && (ps->io_wchar != -1) ) + { + sstrncpy (vl.type, "ps_disk_octets", sizeof (vl.type)); + vl.values[0].derive = ps->io_rchar; + vl.values[1].derive = ps->io_wchar; + vl.values_len = 2; + plugin_dispatch_values (&vl); + } + + if ( (ps->io_syscr != -1) && (ps->io_syscw != -1) ) + { + sstrncpy (vl.type, "ps_disk_ops", sizeof (vl.type)); + vl.values[0].derive = ps->io_syscr; + vl.values[1].derive = ps->io_syscw; + vl.values_len = 2; + plugin_dispatch_values (&vl); + } + + DEBUG ("name = %s; num_proc = %lu; num_lwp = %lu; " + "vmem_size = %lu; vmem_rss = %lu; vmem_data = %lu; " + "vmem_code = %lu; " "vmem_minflt_counter = %lu; vmem_majflt_counter = %lu; " - "cpu_user_counter = %lu; cpu_system_counter = %lu;", - ps->name, ps->num_proc, ps->num_lwp, ps->vmem_rss, + "cpu_user_counter = %lu; cpu_system_counter = %lu; " + "io_rchar = %"PRIi64"; io_wchar = %"PRIi64"; " + "io_syscr = %"PRIi64"; io_syscw = %"PRIi64";", + ps->name, ps->num_proc, ps->num_lwp, + ps->vmem_size, ps->vmem_rss, + ps->vmem_data, ps->vmem_code, ps->vmem_minflt_counter, ps->vmem_majflt_counter, - ps->cpu_user_counter, ps->cpu_system_counter); + ps->cpu_user_counter, ps->cpu_system_counter, + ps->io_rchar, ps->io_wchar, ps->io_syscr, ps->io_syscw); } /* void ps_submit_proc_list */ /* ------- additional functions for KERNEL_LINUX/HAVE_THREAD_INFO ------- */ #if KERNEL_LINUX -static int *ps_read_tasks (int pid) +static int ps_read_tasks (int pid) { - int *list = NULL; - int list_size = 1; /* size of allocated space, in elements */ - int list_len = 0; /* number of currently used elements */ - char dirname[64]; DIR *dh; struct dirent *ent; + int count = 0; ssnprintf (dirname, sizeof (dirname), "/proc/%i/task", pid); if ((dh = opendir (dirname)) == NULL) { DEBUG ("Failed to open directory `%s'", dirname); - return (NULL); + return (-1); } while ((ent = readdir (dh)) != NULL) { - if (!isdigit (ent->d_name[0])) + if (!isdigit ((int) ent->d_name[0])) continue; + else + count++; + } + closedir (dh); - if ((list_len + 1) >= list_size) - { - int *new_ptr; - int new_size = 2 * list_size; - /* Comes in sizes: 2, 4, 8, 16, ... */ + return ((count >= 1) ? count : 1); +} /* int *ps_read_tasks */ - new_ptr = (int *) realloc (list, (size_t) (sizeof (int) * new_size)); - if (new_ptr == NULL) - { - if (list != NULL) - free (list); - ERROR ("processes plugin: " - "Failed to allocate more memory."); - return (NULL); - } +/* Read advanced virtual memory data from /proc/pid/status */ +static procstat_t *ps_read_vmem (int pid, procstat_t *ps) +{ + FILE *fh; + char buffer[1024]; + char filename[64]; + unsigned long long lib = 0; + unsigned long long exe = 0; + unsigned long long data = 0; + char *fields[8]; + int numfields; + + ssnprintf (filename, sizeof (filename), "/proc/%i/status", pid); + if ((fh = fopen (filename, "r")) == NULL) + return (NULL); - list = new_ptr; - list_size = new_size; + while (fgets (buffer, sizeof(buffer), fh) != NULL) + { + long long tmp; + char *endptr; - memset (list + list_len, 0, sizeof (int) * (list_size - list_len)); + if (strncmp (buffer, "Vm", 2) != 0) + continue; + + numfields = strsplit (buffer, fields, + STATIC_ARRAY_SIZE (fields)); + + if (numfields < 2) + continue; + + errno = 0; + endptr = NULL; + tmp = strtoll (fields[1], &endptr, /* base = */ 10); + if ((errno == 0) && (endptr != fields[1])) + { + if (strncmp (buffer, "VmData", 6) == 0) + { + data = tmp; + } + else if (strncmp (buffer, "VmLib", 5) == 0) + { + lib = tmp; + } + else if (strncmp(buffer, "VmExe", 5) == 0) + { + exe = tmp; + } } + } /* while (fgets) */ - list[list_len] = atoi (ent->d_name); - if (list[list_len] != 0) - list_len++; + if (fclose (fh)) + { + char errbuf[1024]; + WARNING ("processes: fclose: %s", + sstrerror (errno, errbuf, sizeof (errbuf))); } - closedir (dh); + ps->vmem_data = data * 1024; + ps->vmem_code = (exe + lib) * 1024; + + return (ps); +} /* procstat_t *ps_read_vmem */ - if (list_len == 0) +static procstat_t *ps_read_io (int pid, procstat_t *ps) +{ + FILE *fh; + char buffer[1024]; + char filename[64]; + + char *fields[8]; + int numfields; + + ssnprintf (filename, sizeof (filename), "/proc/%i/io", pid); + if ((fh = fopen (filename, "r")) == NULL) return (NULL); - assert (list_len < list_size); - assert (list[list_len] == 0); + while (fgets (buffer, sizeof (buffer), fh) != NULL) + { + derive_t *val = NULL; + long long tmp; + char *endptr; + + if (strncasecmp (buffer, "rchar:", 6) == 0) + val = &(ps->io_rchar); + else if (strncasecmp (buffer, "wchar:", 6) == 0) + val = &(ps->io_wchar); + else if (strncasecmp (buffer, "syscr:", 6) == 0) + val = &(ps->io_syscr); + else if (strncasecmp (buffer, "syscw:", 6) == 0) + val = &(ps->io_syscw); + else + continue; - return (list); -} /* int *ps_read_tasks */ + numfields = strsplit (buffer, fields, + STATIC_ARRAY_SIZE (fields)); + + if (numfields < 2) + continue; + + errno = 0; + endptr = NULL; + tmp = strtoll (fields[1], &endptr, /* base = */ 10); + if ((errno != 0) || (endptr == fields[1])) + *val = -1; + else + *val = (derive_t) tmp; + } /* while (fgets) */ + + if (fclose (fh)) + { + char errbuf[1024]; + WARNING ("processes: fclose: %s", + sstrerror (errno, errbuf, sizeof (errbuf))); + } + + return (ps); +} /* procstat_t *ps_read_io */ int ps_read_process (int pid, procstat_t *ps, char *state) { @@ -686,7 +869,6 @@ int ps_read_process (int pid, procstat_t *ps, char *state) char *fields[64]; char fields_len; - int *tasks; int i; int ppid; @@ -707,7 +889,7 @@ int ps_read_process (int pid, procstat_t *ps, char *state) return (-1); buffer[i] = 0; - fields_len = strsplit (buffer, fields, 64); + fields_len = strsplit (buffer, fields, STATIC_ARRAY_SIZE (fields)); if (fields_len < 24) { DEBUG ("processes plugin: ps_read_process (pid = %i):" @@ -736,21 +918,14 @@ int ps_read_process (int pid, procstat_t *ps, char *state) ps->num_lwp = 0; ps->num_proc = 0; } - else if ((tasks = ps_read_tasks (pid)) == NULL) - { - /* Kernel 2.4 or so */ - ps->num_lwp = 1; - ps->num_proc = 1; - } else { - ps->num_lwp = 0; + if ( (ps->num_lwp = ps_read_tasks (pid)) == -1 ) + { + /* returns -1 => kernel 2.4 */ + ps->num_lwp = 1; + } ps->num_proc = 1; - for (i = 0; tasks[i] != 0; i++) - ps->num_lwp++; - - free (tasks); - tasks = NULL; } /* Leave the rest at zero if this is only a zombi */ @@ -782,12 +957,31 @@ int ps_read_process (int pid, procstat_t *ps, char *state) cpu_system_counter = cpu_system_counter * 1000000 / CONFIG_HZ; vmem_rss = vmem_rss * pagesize_g; + if ( (ps_read_vmem(pid, ps)) == NULL) + { + /* No VMem data */ + ps->vmem_data = -1; + ps->vmem_code = -1; + DEBUG("ps_read_process: did not get vmem data for pid %i",pid); + } + ps->cpu_user_counter = (unsigned long) cpu_user_counter; ps->cpu_system_counter = (unsigned long) cpu_system_counter; ps->vmem_size = (unsigned long) vmem_size; ps->vmem_rss = (unsigned long) vmem_rss; ps->stack_size = (unsigned long) stack_size; + if ( (ps_read_io (pid, ps)) == NULL) + { + /* no io data */ + ps->io_rchar = -1; + ps->io_wchar = -1; + ps->io_syscr = -1; + ps->io_syscw = -1; + + DEBUG("ps_read_process: not get io data for pid %i",pid); + } + /* success */ return (0); } /* int ps_read_process (...) */ @@ -805,13 +999,18 @@ static char *ps_get_cmdline (pid_t pid, char *name, char *buf, size_t buf_len) if ((pid < 1) || (NULL == buf) || (buf_len < 2)) return NULL; - ssnprintf (file, sizeof (file), "/proc/%u/cmdline", pid); + ssnprintf (file, sizeof (file), "/proc/%u/cmdline", + (unsigned int) pid); + errno = 0; fd = open (file, O_RDONLY); if (fd < 0) { char errbuf[4096]; - WARNING ("processes plugin: Failed to open `%s': %s.", file, - sstrerror (errno, errbuf, sizeof (errbuf))); + /* ENOENT means the process exited while we were handling it. + * Don't complain about this, it only fills the logs. */ + if (errno != ENOENT) + WARNING ("processes plugin: Failed to open `%s': %s.", file, + sstrerror (errno, errbuf, sizeof (errbuf))); return NULL; } @@ -826,7 +1025,7 @@ static char *ps_get_cmdline (pid_t pid, char *name, char *buf, size_t buf_len) status = read (fd, (void *)buf_ptr, len); if (status < 0) { - char errbuf[4096]; + char errbuf[1024]; if ((EAGAIN == errno) || (EINTR == errno)) continue; @@ -881,6 +1080,70 @@ static char *ps_get_cmdline (pid_t pid, char *name, char *buf, size_t buf_len) } return buf; } /* char *ps_get_cmdline (...) */ + +static unsigned long read_fork_rate () +{ + FILE *proc_stat; + char buf[1024]; + unsigned long result = 0; + int numfields; + char *fields[3]; + + proc_stat = fopen("/proc/stat", "r"); + if (proc_stat == NULL) { + char errbuf[1024]; + ERROR ("processes plugin: fopen (/proc/stat) failed: %s", + sstrerror (errno, errbuf, sizeof (errbuf))); + return ULONG_MAX; + } + + while (fgets (buf, sizeof(buf), proc_stat) != NULL) + { + char *endptr; + + numfields = strsplit(buf, fields, STATIC_ARRAY_SIZE (fields)); + if (numfields != 2) + continue; + + if (strcmp ("processes", fields[0]) != 0) + continue; + + errno = 0; + endptr = NULL; + result = strtoul(fields[1], &endptr, /* base = */ 10); + if ((endptr == fields[1]) || (errno != 0)) { + ERROR ("processes plugin: Cannot parse fork rate: %s", + fields[1]); + result = ULONG_MAX; + break; + } + + break; + } + + fclose(proc_stat); + + return result; +} + +static void ps_submit_fork_rate (unsigned long value) +{ + value_t values[1]; + value_list_t vl = VALUE_LIST_INIT; + + values[0].derive = (derive_t) value; + + vl.values = values; + vl.values_len = 1; + sstrncpy (vl.host, hostname_g, sizeof (vl.host)); + sstrncpy (vl.plugin, "processes", sizeof (vl.plugin)); + sstrncpy (vl.plugin_instance, "", sizeof (vl.plugin_instance)); + sstrncpy (vl.type, "fork_rate", sizeof (vl.type)); + sstrncpy (vl.type_instance, "", sizeof (vl.type_instance)); + + plugin_dispatch_values (&vl); +} + #endif /* KERNEL_LINUX */ #if HAVE_THREAD_INFO @@ -1046,7 +1309,11 @@ static int ps_read (void) } pse.num_proc++; + pse.vmem_size = task_basic_info.virtual_size; pse.vmem_rss = task_basic_info.resident_size; + /* Does not seem to be easily exposed */ + pse.vmem_data = 0; + pse.vmem_code = 0; pse.vmem_minflt_counter = task_events_info.cow_faults; pse.vmem_majflt_counter = task_events_info.faults; @@ -1203,6 +1470,8 @@ static int ps_read (void) procstat_entry_t pse; char state; + unsigned long fork_rate; + procstat_t *ps_ptr; running = sleeping = zombies = stopped = paging = blocked = 0; @@ -1238,6 +1507,8 @@ static int ps_read (void) pse.num_lwp = ps.num_lwp; pse.vmem_size = ps.vmem_size; pse.vmem_rss = ps.vmem_rss; + pse.vmem_data = ps.vmem_data; + pse.vmem_code = ps.vmem_code; pse.stack_size = ps.stack_size; pse.vmem_minflt = 0; @@ -1250,6 +1521,11 @@ static int ps_read (void) pse.cpu_system = 0; pse.cpu_system_counter = ps.cpu_system_counter; + pse.io_rchar = ps.io_rchar; + pse.io_wchar = ps.io_wchar; + pse.io_syscr = ps.io_syscr; + pse.io_syscw = ps.io_syscw; + switch (state) { case 'R': running++; break; @@ -1276,6 +1552,10 @@ static int ps_read (void) for (ps_ptr = list_head_g; ps_ptr != NULL; ps_ptr = ps_ptr->next) ps_submit_proc_list (ps_ptr); + + fork_rate = read_fork_rate(); + if (fork_rate != ULONG_MAX) + ps_submit_fork_rate(fork_rate); /* #endif KERNEL_LINUX */ #elif HAVE_LIBKVM_GETPROCS && HAVE_STRUCT_KINFO_PROC_FREEBSD @@ -1359,6 +1639,8 @@ static int ps_read (void) pse.vmem_size = procs[i].ki_size; pse.vmem_rss = procs[i].ki_rssize * getpagesize(); + pse.vmem_data = procs[i].ki_dsize * getpagesize(); + pse.vmem_code = procs[i].ki_tsize * getpagesize(); pse.stack_size = procs[i].ki_ssize * getpagesize(); pse.vmem_minflt = 0; pse.vmem_minflt_counter = procs[i].ki_rusage.ru_minflt; @@ -1374,6 +1656,12 @@ static int ps_read (void) * 1000 + procs[i].ki_rusage.ru_stime.tv_usec; + /* no io data */ + pse.io_rchar = -1; + pse.io_wchar = -1; + pse.io_syscr = -1; + pse.io_syscw = -1; + switch (procs[i].ki_stat) { case SSTOP: stopped++; break; @@ -1400,7 +1688,141 @@ static int ps_read (void) for (ps_ptr = list_head_g; ps_ptr != NULL; ps_ptr = ps_ptr->next) ps_submit_proc_list (ps_ptr); -#endif /* HAVE_LIBKVM_GETPROCS && HAVE_STRUCT_KINFO_PROC_FREEBSD */ +/* #endif HAVE_LIBKVM_GETPROCS && HAVE_STRUCT_KINFO_PROC_FREEBSD */ + +#elif HAVE_PROCINFO_H + /* AIX */ + int running = 0; + int sleeping = 0; + int zombies = 0; + int stopped = 0; + int paging = 0; + int blocked = 0; + + pid_t pindex = 0; + int nprocs; + + procstat_t *ps; + procstat_entry_t pse; + + ps_list_reset (); + while ((nprocs = getprocs64 (procentry, sizeof(struct procentry64), + /* fdsinfo = */ NULL, sizeof(struct fdsinfo64), + &pindex, MAXPROCENTRY)) > 0) + { + int i; + + for (i = 0; i < nprocs; i++) + { + tid64_t thindex; + int nthreads; + char arglist[MAXARGLN+1]; + char *cargs; + char *cmdline; + + if (procentry[i].pi_state == SNONE) continue; + /* if (procentry[i].pi_state == SZOMB) FIXME */ + + cmdline = procentry[i].pi_comm; + cargs = procentry[i].pi_comm; + if ( procentry[i].pi_flags & SKPROC ) + { + if (procentry[i].pi_pid == 0) + cmdline = "swapper"; + cargs = cmdline; + } + else + { + if (getargs(&procentry[i], sizeof(struct procentry64), arglist, MAXARGLN) >= 0) + { + int n; + + n = -1; + while (++n < MAXARGLN) + { + if (arglist[n] == '\0') + { + if (arglist[n+1] == '\0') + break; + arglist[n] = ' '; + } + } + cargs = arglist; + } + } + + pse.id = procentry[i].pi_pid; + pse.age = 0; + pse.num_lwp = procentry[i].pi_thcount; + pse.num_proc = 1; + + thindex=0; + while ((nthreads = getthrds64(procentry[i].pi_pid, + thrdentry, sizeof(struct thrdentry64), + &thindex, MAXTHRDENTRY)) > 0) + { + int j; + + for (j=0; j< nthreads; j++) + { + switch (thrdentry[j].ti_state) + { + /* case TSNONE: break; */ + case TSIDL: blocked++; break; /* FIXME is really blocked */ + case TSRUN: running++; break; + case TSSLEEP: sleeping++; break; + case TSSWAP: paging++; break; + case TSSTOP: stopped++; break; + case TSZOMB: zombies++; break; + } + } + if (nthreads < MAXTHRDENTRY) + break; + } + + pse.cpu_user = 0; + /* tv_usec is nanosec ??? */ + pse.cpu_user_counter = procentry[i].pi_ru.ru_utime.tv_sec * 1000000 + + procentry[i].pi_ru.ru_utime.tv_usec / 1000; + + pse.cpu_system = 0; + /* tv_usec is nanosec ??? */ + pse.cpu_system_counter = procentry[i].pi_ru.ru_stime.tv_sec * 1000000 + + procentry[i].pi_ru.ru_stime.tv_usec / 1000; + + pse.vmem_minflt = 0; + pse.vmem_minflt_counter = procentry[i].pi_minflt; + pse.vmem_majflt = 0; + pse.vmem_majflt_counter = procentry[i].pi_majflt; + + pse.vmem_size = procentry[i].pi_tsize + procentry[i].pi_dvm * pagesize; + pse.vmem_rss = (procentry[i].pi_drss + procentry[i].pi_trss) * pagesize; + /* Not supported */ + pse.vmem_data = 0; + pse.vmem_code = 0; + pse.stack_size = 0; + + pse.io_rchar = -1; + pse.io_wchar = -1; + pse.io_syscr = -1; + pse.io_syscw = -1; + + ps_list_add (cmdline, cargs, &pse); + } /* for (i = 0 .. nprocs) */ + + if (nprocs < MAXPROCENTRY) + break; + } /* while (getprocs64() > 0) */ + ps_submit_state ("running", running); + ps_submit_state ("sleeping", sleeping); + ps_submit_state ("zombies", zombies); + ps_submit_state ("stopped", stopped); + ps_submit_state ("paging", paging); + ps_submit_state ("blocked", blocked); + + for (ps = list_head_g; ps != NULL; ps = ps->next) + ps_submit_proc_list (ps); +#endif /* HAVE_PROCINFO_H */ return (0); } /* int ps_read */