On Wed, Jul 04, 2012 at 08:14:26AM -0500, Jonathan Nieder wrote: > Alessandro Ghedini wrote: > > > ulatencyd embeds a not so up-to-date version of libprocps because it uses > > some > > of its internal symbols, and > > Thanks. Which internal symbols? Maybe they could be exposed, or > maybe some other part of the API provides the same functionality.
Actually, after a little inspection, it's not really about internal symbols but
more about actual changes to the sources. It seems to me that most changes
concern support for cgroups, but I may very well be wrong.
See attached diff against upstream procps version 3.2.8, which is the version
that, AFAICT, ulatencyd embeds.
Cheers
--
perl -E '$_=q;$/= @{[@_]};and s;\S+;<inidehG ordnasselA>;eg;say~~reverse'
diff -bruN procps-3.2.8.orig/proc/alloc.c /home/ale/devel/debian/pkg-collab/packages/ulatencyd/src/proc/alloc.c
--- procps-3.2.8.orig/proc/alloc.c 2012-07-04 16:36:07.572291071 +0200
+++ /home/ale/devel/debian/pkg-collab/packages/ulatencyd/src/proc/alloc.c 2012-07-04 16:37:32.104710221 +0200
@@ -6,6 +6,7 @@
// See file COPYING for information on distribution conditions.
#include <stdlib.h>
+#include <string.h>
#include <stdio.h>
#include "alloc.h"
@@ -26,6 +27,7 @@
if (size == 0)
++size;
p = malloc(size);
+ memset(p, 0, size);
if (!p) {
fprintf(stderr, "xmalloc: malloc(%d) failed", size);
perror(NULL);
diff -bruN procps-3.2.8.orig/proc/readproc.c /home/ale/devel/debian/pkg-collab/packages/ulatencyd/src/proc/readproc.c
--- procps-3.2.8.orig/proc/readproc.c 2012-07-04 16:36:07.572291071 +0200
+++ /home/ale/devel/debian/pkg-collab/packages/ulatencyd/src/proc/readproc.c 2012-07-04 16:37:32.104710221 +0200
@@ -20,6 +20,7 @@
#include <errno.h>
#include <stdarg.h>
#include <string.h>
+#include <limits.h>
#include <unistd.h>
#include <signal.h>
#include <fcntl.h>
@@ -85,63 +86,68 @@
long Threads = 0;
long Tgid = 0;
long Pid = 0;
+ int hash = 0;
+ int isupgid = 0;
static const unsigned char asso[] =
{
- 61, 61, 61, 61, 61, 61, 61, 61, 61, 61,
- 61, 61, 61, 61, 61, 61, 61, 61, 61, 61,
- 61, 61, 61, 61, 61, 61, 61, 61, 61, 61,
- 61, 61, 61, 61, 61, 61, 61, 61, 61, 61,
- 61, 61, 61, 61, 61, 61, 61, 61, 61, 61,
- 61, 61, 61, 61, 61, 61, 61, 61, 15, 61,
- 61, 61, 61, 61, 61, 61, 30, 3, 5, 5,
- 61, 5, 61, 8, 61, 61, 3, 61, 10, 61,
- 6, 61, 13, 0, 30, 25, 0, 61, 61, 61,
- 61, 61, 61, 61, 61, 61, 61, 3, 61, 13,
- 0, 0, 61, 30, 61, 25, 61, 61, 61, 0,
- 61, 61, 61, 61, 5, 61, 0, 61, 61, 61,
- 0, 61, 61, 61, 61, 61, 61, 61
+ 66, 66, 66, 66, 66, 66, 66, 66, 66, 66,
+ 66, 66, 66, 66, 66, 66, 66, 66, 66, 66,
+ 66, 66, 66, 66, 66, 66, 66, 66, 66, 66,
+ 66, 66, 66, 66, 66, 66, 66, 66, 66, 66,
+ 66, 66, 66, 66, 66, 66, 66, 66, 66, 66,
+ 66, 66, 66, 66, 66, 66, 66, 66, 0, 66,
+ 66, 66, 66, 66, 66, 66, 3, 30, 20, 30,
+ 66, 25, 66, 20, 66, 66, 30, 66, 25, 66,
+ 0, 66, 8, 10, 3, 18, 5, 66, 66, 66,
+ 66, 66, 66, 66, 66, 66, 66, 3, 66, 10,
+ 0, 0, 66, 25, 66, 5, 66, 66, 66, 25,
+ 66, 5, 66, 66, 0, 66, 0, 0, 66, 66,
+ 25, 66, 66, 66, 66, 66, 66, 66
};
static const status_table_struct table[] = {
- F(VmStk)
+ F(Pid)
NUL NUL
- F(State)
+ F(Threads)
+ NUL
+ F(PPid)
+ NUL NUL
+ F(Tgid)
NUL
- F(VmExe)
F(ShdPnd)
+ NUL NUL
+ F(State)
NUL
- F(VmData)
+ F(VmStk)
+ NUL NUL
+ F(Uid)
NUL
- F(Name)
+ F(VmSize)
NUL NUL
F(VmRSS)
- NUL NUL
- F(VmLck)
- NUL NUL NUL
+ NUL
F(Gid)
- F(Pid)
- NUL NUL NUL
- F(VmSize)
NUL NUL
- F(VmLib)
- NUL NUL
- F(PPid)
- NUL
- F(SigCgt)
+ F(VmData)
NUL
- F(Threads)
+ F(Groups)
+ NUL NUL NUL NUL
F(SigPnd)
+ NUL NUL
+ F(SigBlk)
NUL
+ F(VmLib)
+ NUL NUL NUL NUL
+ F(VmLck)
+ NUL NUL NUL NUL
+ F(Name)
+ NUL NUL NUL NUL
F(SigIgn)
- NUL
- F(Uid)
- NUL NUL NUL NUL NUL NUL NUL NUL NUL
- NUL NUL NUL NUL NUL
- F(Tgid)
NUL NUL NUL NUL
- F(SigBlk)
- NUL NUL NUL
+ F(VmExe)
+ NUL NUL NUL NUL
+ F(SigCgt)
};
#undef F
@@ -157,6 +163,9 @@
P->vm_exe = 0;
P->vm_lib = 0;
P->nlwp = 0;
+ P->nsupgid = 0;
+ P->supgid = NULL;
+ P->supgrp = NULL;
P->signal[0] = '\0'; // so we can detect it as missing for very old kernels
goto base;
@@ -173,7 +182,9 @@
// examine a field name (hash and compare)
base:
if(unlikely(!*S)) break;
- entry = table[63 & (asso[S[3]] + asso[S[2]] + asso[S[0]])];
+ hash = asso[S[3]] + asso[S[2]] + asso[S[0]];
+ if (hash > 65) continue;
+ entry = table[hash];
colon = strchr(S, ':');
if(unlikely(!colon)) break;
if(unlikely(colon[1]!='\t')) break;
@@ -271,6 +282,21 @@
P->sgid = strtol(S,&S,10);
P->fgid = strtol(S,&S,10);
continue;
+ case_Groups:
+ isupgid = 0;
+ if (*S != '\n'){ // Is there any supplementary group ?
+ P->supgid = (int *) xmalloc(0x0004 * sizeof(int));
+ int vctsize = 0x0004;
+ while (S[1] != '\n' && isupgid<INT_MAX){ // There is one blank before '\n'
+ if (isupgid == vctsize){
+ vctsize *= 2;
+ P->supgid = (int *)xrealloc(P->supgid,vctsize * sizeof(int));
+ }
+ P->supgid[isupgid++] = strtol(S,&S,10);
+ P->nsupgid++;
+ }
+ }
+ continue;
case_VmData:
P->vm_data = strtol(S,&S,10);
continue;
@@ -407,7 +433,7 @@
/* fprintf(stderr, "statm2proc converted %d fields.\n",num); */
}
-static int file2str(const char *directory, const char *what, char *ret, int cap) {
+int file2str(const char *directory, const char *what, char *ret, int cap) {
static char filename[80];
int fd, num_read;
@@ -421,7 +447,7 @@
return num_read;
}
-static char** file2strvec(const char* directory, const char* what) {
+char** file2strvec_ext(const char* directory, const char* what, char terminator) {
char buf[2048]; /* read buf bytes at a time */
char *p, *rbuf = 0, *endbuf, **q, **ret;
int fd, tot = 0, n, c, end_of_file = 0;
@@ -442,7 +468,7 @@
free(rbuf);
return NULL; /* read error */
}
- if (end_of_file && buf[n-1]) /* last read char not null */
+ if (end_of_file && buf[n-1] != terminator) /* last read char not null */
buf[n++] = '\0'; /* so append null-terminator */
rbuf = xrealloc(rbuf, tot + n); /* allocate more memory */
memcpy(rbuf + tot, buf, n); /* copy buffer into it */
@@ -457,9 +483,12 @@
}
endbuf = rbuf + tot; /* count space for pointers */
align = (sizeof(char*)-1) - ((tot + sizeof(char*)-1) & (sizeof(char*)-1));
- for (c = 0, p = rbuf; p < endbuf; p++)
+ for (c = 0, p = rbuf; p < endbuf; p++) {
+ if (*p == terminator)
+ *p = 0;
if (!*p)
c += sizeof(char*);
+ }
c += sizeof(char*); /* one extra for NULL term */
rbuf = xrealloc(rbuf, tot + c + align); /* make room for ptrs AT END */
@@ -475,6 +504,10 @@
return ret;
}
+char** file2strvec(const char* directory, const char* what) {
+ return file2strvec_ext(directory, what, '\0');
+}
+
// warning: interface may change
int read_cmdline(char *restrict const dst, unsigned sz, unsigned pid){
char name[32];
@@ -589,6 +622,13 @@
}
}
+ if (flags & PROC_FILLSUPGRP && p->nsupgid > 0){
+ allocsupgrp(p);
+ int i;
+ for (i=0; i < p->nsupgid; i++)
+ memcpy(p->supgrp[i], group_from_gid(p->supgid[i]), P_G_SZ);
+ }
+
if ((flags & PROC_FILLCOM) || (flags & PROC_FILLARG)) /* read+parse /proc/#/cmdline */
p->cmdline = file2strvec(path, "cmdline");
else
@@ -599,6 +639,17 @@
else
p->environ = NULL;
+ if(linux_version_code>=LINUX_VERSION(2,6,24) && (flags & PROC_FILLCGROUP)) {
+ p->cgroup = file2strvec_ext(path, "cgroup", '\n'); /* read /proc/#/cgroup */
+ if(p->cgroup && *p->cgroup) {
+ int i = strlen(*p->cgroup);
+ if( (*p->cgroup)[i-1]=='\n' )
+ (*p->cgroup)[i-1] = ' '; //little hack to remove trailing \n
+ }
+ }
+ else
+ p->cgroup = NULL;
+
return p;
next_proc:
return NULL;
@@ -672,6 +723,13 @@
}
}
+ if (flags & PROC_TASKSUPGRP && t->nsupgid > 0){
+ allocsupgrp(t);
+ int i;
+ for (i=0; i < t->nsupgid; i++)
+ memcpy(t->supgrp[i], group_from_gid(t->supgid[i]), P_G_SZ);
+ }
+
#if 0
if ((flags & PROC_FILLCOM) || (flags & PROC_FILLARG)) /* read+parse /proc/#/cmdline */
t->cmdline = file2strvec(path, "cmdline");
@@ -686,7 +744,7 @@
t->cmdline = p->cmdline; // better not free these until done with all threads!
t->environ = p->environ;
#endif
-
+ t->cgroup = p->cgroup;
t->ppid = p->ppid; // ought to put the per-task ppid somewhere
return t;
@@ -777,6 +835,7 @@
saved_p = p;
if(!p) p = xcalloc(p, sizeof *p); /* passed buf or alloced mem */
+ else memset(p, 0, sizeof *p);
for(;;){
// fills in the path, plus p->tid and p->tgid
@@ -805,6 +864,7 @@
saved_t = t;
if(!t) t = xcalloc(t, sizeof *t); /* passed buf or alloced mem */
+ else memset(t, 0, sizeof *t);
// 1. got to fake a thread for old kernels
// 2. for single-threaded processes, this is faster (but must patch up stuff that differs!)
@@ -886,6 +946,29 @@
}
}
+// allocate memory for supgrp
+void allocsupgrp(proc_t *p) {
+ if (!p || p->nsupgid == 0) return;
+ p->supgrp = (char**)xmalloc(p->nsupgid * sizeof(char*));
+ int i;
+ for (i=0; i<p->nsupgid; i++)
+ p->supgrp[i] = (char*)xmalloc(P_G_SZ * sizeof(char));
+}
+
+// free memory allocated for supgrp
+void freesupgrp(proc_t *p) {
+ int i;
+ if(!p->supgid)
+ return;
+ for (i=0; i<p->nsupgid; i++)
+ if (p->supgrp && p->supgrp[i])
+ free(p->supgrp[i]);
+ free(p->supgid);
+ free(p->supgrp);
+ p->supgid = NULL;
+ p->supgrp = NULL;
+}
+
// deallocate the space allocated by readproc if the passed rbuf was NULL
void freeproc(proc_t* p) {
if (!p) /* in case p is NULL */
@@ -896,9 +979,38 @@
free((void*)*p->cmdline);
if (p->environ)
free((void*)*p->environ);
+ if (p->cgroup)
+ free((void*)*p->cgroup);
+ if (p->supgid)
+ free(p->supgid);
+
+ //printf("frp: %p\n", p);
free(p);
}
+// deallocate the space allocated by readproc if the passed rbuf was NULL
+void freeproc_light(proc_t* p) {
+ if (!p) /* in case p is NULL */
+ return;
+ /* ptrs are after strings to avoid copying memory when building them. */
+ /* so free is called on the address of the address of strvec[0]. */
+ if (p->cmdline)
+ free((void*)*p->cmdline);
+ if (p->environ)
+ free((void*)*p->environ);
+ if (p->cgroup)
+ free((void*)*p->cgroup);
+
+ if (p->supgid)
+ free(p->supgid);
+ p->cmdline = NULL;
+ p->environ = NULL;
+ p->cgroup = NULL;
+ p->supgid = NULL;
+
+ //printf("frp: %p\n", p);
+}
+
//////////////////////////////////////////////////////////////////////////////////
void look_up_our_self(proc_t *p) {
@@ -942,6 +1054,8 @@
else
PT = openproc(flags);
va_end(ap);
+ if (!PT)
+ return 0;
do { /* read table: */
tab = xrealloc(tab, (n+1)*sizeof(proc_t*));/* realloc as we go, using */
tab[n] = readproc_direct(PT, NULL); /* final null to terminate */
@@ -1034,7 +1148,7 @@
* and filled out proc_t structure.
*/
proc_t * get_proc_stats(pid_t pid, proc_t *p) {
- static char path[PATH_MAX], sbuf[1024];
+ static char path[32], sbuf[1024];
struct stat statbuf;
sprintf(path, "/proc/%d", pid);
diff -bruN procps-3.2.8.orig/proc/readproc.h /home/ale/devel/debian/pkg-collab/packages/ulatencyd/src/proc/readproc.h
--- procps-3.2.8.orig/proc/readproc.h 2012-07-04 16:36:07.568290991 +0200
+++ /home/ale/devel/debian/pkg-collab/packages/ulatencyd/src/proc/readproc.h 2012-07-04 16:37:32.108710229 +0200
@@ -38,107 +38,111 @@
typedef struct proc_t {
// 1st 16 bytes
int
- tid, // (special) task id, the POSIX thread ID (see also: tgid)
- ppid; // stat,status pid of parent process
+ tid, //!< (special) task id, the POSIX thread ID (see also: tgid)
+ ppid; //!< stat,status pid of parent process
unsigned
- pcpu; // stat (special) %CPU usage (is not filled in by readproc!!!)
+ pcpu; //!< stat (special) %CPU usage (is not filled in by readproc!!!)
char
- state, // stat,status single-char code for process state (S=sleeping)
- pad_1, // n/a padding
- pad_2, // n/a padding
- pad_3; // n/a padding
-// 2nd 16 bytes
+ state, //!< stat,status single-char code for process state (S=sleeping)
+ pad_1, //!< n/a padding
+ pad_2, //!< n/a padding
+ pad_3; //!< n/a padding
+//!< 2nd 16 bytes
unsigned long long
- utime, // stat user-mode CPU time accumulated by process
- stime, // stat kernel-mode CPU time accumulated by process
-// and so on...
- cutime, // stat cumulative utime of process and reaped children
- cstime, // stat cumulative stime of process and reaped children
- start_time; // stat start time of process -- seconds since 1-1-70
+ utime, //!< stat user-mode CPU time accumulated by process
+ stime, //!< stat kernel-mode CPU time accumulated by process
+//!< and so on...
+ cutime, //!< stat cumulative utime of process and reaped children
+ cstime, //!< stat cumulative stime of process and reaped children
+ start_time; //!< stat start time of process -- seconds since 1-1-70
#ifdef SIGNAL_STRING
char
- // Linux 2.1.7x and up have 64 signals. Allow 64, plus '\0' and padding.
- signal[18], // status mask of pending signals, per-task for readtask() but per-proc for readproc()
- blocked[18], // status mask of blocked signals
- sigignore[18], // status mask of ignored signals
- sigcatch[18], // status mask of caught signals
- _sigpnd[18]; // status mask of PER TASK pending signals
+ //!< Linux 2.1.7x and up have 64 signals. Allow 64, plus '\0' and padding.
+ signal[18], //!< status mask of pending signals, per-task for readtask() but per-proc for readproc()
+ blocked[18], //!< status mask of blocked signals
+ sigignore[18], //!< status mask of ignored signals
+ sigcatch[18], //!< status mask of caught signals
+ _sigpnd[18]; //!< status mask of PER TASK pending signals
#else
long long
- // Linux 2.1.7x and up have 64 signals.
- signal, // status mask of pending signals, per-task for readtask() but per-proc for readproc()
- blocked, // status mask of blocked signals
- sigignore, // status mask of ignored signals
- sigcatch, // status mask of caught signals
- _sigpnd; // status mask of PER TASK pending signals
+ //!< Linux 2.1.7x and up have 64 signals.
+ signal, //!< status mask of pending signals, per-task for readtask() but per-proc for readproc()
+ blocked, //!< status mask of blocked signals
+ sigignore, //!< status mask of ignored signals
+ sigcatch, //!< status mask of caught signals
+ _sigpnd; //!< status mask of PER TASK pending signals
#endif
unsigned KLONG
- start_code, // stat address of beginning of code segment
- end_code, // stat address of end of code segment
- start_stack, // stat address of the bottom of stack for the process
- kstk_esp, // stat kernel stack pointer
- kstk_eip, // stat kernel instruction pointer
- wchan; // stat (special) address of kernel wait channel proc is sleeping in
+ start_code, //!< stat address of beginning of code segment
+ end_code, //!< stat address of end of code segment
+ start_stack, //!< stat address of the bottom of stack for the process
+ kstk_esp, //!< stat kernel stack pointer
+ kstk_eip, //!< stat kernel instruction pointer
+ wchan; //!< stat (special) address of kernel wait channel proc is sleeping in
long
- priority, // stat kernel scheduling priority
- nice, // stat standard unix nice level of process
- rss, // stat resident set size from /proc/#/stat (pages)
- alarm, // stat ?
- // the next 7 members come from /proc/#/statm
- size, // statm total # of pages of memory
- resident, // statm number of resident set (non-swapped) pages (4k)
- share, // statm number of pages of shared (mmap'd) memory
- trs, // statm text resident set size
- lrs, // statm shared-lib resident set size
- drs, // statm data resident set size
- dt; // statm dirty pages
+ priority, //!< stat kernel scheduling priority
+ nice, //!< stat standard unix nice level of process
+ rss, //!< stat resident set size from /proc/#/stat (pages)
+ alarm, //!< stat ?
+ //!< the next 7 members come from /proc/#/statm
+ size, //!< statm total # of pages of memory
+ resident, //!< statm number of resident set (non-swapped) pages (4k)
+ share, //!< statm number of pages of shared (mmap'd) memory
+ trs, //!< statm text resident set size
+ lrs, //!< statm shared-lib resident set size
+ drs, //!< statm data resident set size
+ dt; //!< statm dirty pages
unsigned long
- vm_size, // status same as vsize in kb
- vm_lock, // status locked pages in kb
- vm_rss, // status same as rss in kb
- vm_data, // status data size
- vm_stack, // status stack size
- vm_exe, // status executable size
- vm_lib, // status library size (all pages, not just used ones)
- rtprio, // stat real-time priority
- sched, // stat scheduling class
- vsize, // stat number of pages of virtual memory ...
- rss_rlim, // stat resident set size limit?
- flags, // stat kernel flags for the process
- min_flt, // stat number of minor page faults since process start
- maj_flt, // stat number of major page faults since process start
- cmin_flt, // stat cumulative min_flt of process and child processes
- cmaj_flt; // stat cumulative maj_flt of process and child processes
+ vm_size, //!< status same as vsize in kb
+ vm_lock, //!< status locked pages in kb
+ vm_rss, //!< status same as rss in kb
+ vm_data, //!< status data size
+ vm_stack, //!< status stack size
+ vm_exe, //!< status executable size
+ vm_lib, //!< status library size (all pages, not just used ones)
+ rtprio, //!< stat real-time priority
+ sched, //!< stat scheduling class
+ vsize, //!< stat number of pages of virtual memory ...
+ rss_rlim, //!< stat resident set size limit?
+ flags, //!< stat kernel flags for the process
+ min_flt, //!< stat number of minor page faults since process start
+ maj_flt, //!< stat number of major page faults since process start
+ cmin_flt, //!< stat cumulative min_flt of process and child processes
+ cmaj_flt; //!< stat cumulative maj_flt of process and child processes
char
- **environ, // (special) environment string vector (/proc/#/environ)
- **cmdline; // (special) command line string vector (/proc/#/cmdline)
+ **environ, //!< (special) environment string vector (/proc/#/environ)
+ **cmdline; //!< (special) command line string vector (/proc/#/cmdline)
char
- // Be compatible: Digital allows 16 and NT allows 14 ???
- euser[P_G_SZ], // stat(),status effective user name
- ruser[P_G_SZ], // status real user name
- suser[P_G_SZ], // status saved user name
- fuser[P_G_SZ], // status filesystem user name
- rgroup[P_G_SZ], // status real group name
- egroup[P_G_SZ], // status effective group name
- sgroup[P_G_SZ], // status saved group name
- fgroup[P_G_SZ], // status filesystem group name
- cmd[16]; // stat,status basename of executable file in call to exec(2)
+ //!< Be compatible: Digital allows 16 and NT allows 14 ???
+ euser[P_G_SZ], //!< stat(),status effective user name
+ ruser[P_G_SZ], //!< status real user name
+ suser[P_G_SZ], //!< status saved user name
+ fuser[P_G_SZ], //!< status filesystem user name
+ rgroup[P_G_SZ], //!< status real group name
+ egroup[P_G_SZ], //!< status effective group name
+ sgroup[P_G_SZ], //!< status saved group name
+ fgroup[P_G_SZ], //!< status filesystem group name
+ **supgrp, //!< status supplementary groups
+ cmd[32]; //!< stat,status basename of executable file in call to exec(2)
struct proc_t
- *ring, // n/a thread group ring
- *next; // n/a various library uses
+ *ring, //!< n/a thread group ring
+ *next; //!< n/a various library uses
int
- pgrp, // stat process group id
- session, // stat session id
- nlwp, // stat,status number of threads, or 0 if no clue
- tgid, // (special) task group ID, the POSIX PID (see also: tid)
- tty, // stat full device number of controlling terminal
- euid, egid, // stat(),status effective
- ruid, rgid, // status real
- suid, sgid, // status saved
- fuid, fgid, // status fs (used for file access only)
- tpgid, // stat terminal process group id
- exit_signal, // stat might not be SIGCHLD
- processor; // stat current (or most recent?) CPU
+ pgrp, //!< stat process group id
+ session, //!< stat session id
+ nlwp, //!< stat,status number of threads, or 0 if no clue
+ tgid, //!< (special) task group ID, the POSIX PID (see also: tid)
+ tty, //!< stat full device number of controlling terminal
+ euid, egid, //!< stat(),status effective
+ ruid, rgid, //!< status real
+ suid, sgid, //!< status saved
+ fuid, fgid, //!< status fs (used for file access only)
+ tpgid, //!< stat terminal process group id
+ nsupgid, //!< status number of supplementary groups
+ *supgid, //!< status supplementary gid's
+ exit_signal, //!< stat might not be SIGCHLD
+ processor; //!< stat current (or most recent?) CPU
+ char **cgroup; //!< cgroup current cgroup, looks like a classic filepath
} proc_t;
// PROCTAB: data structure holding the persistent information readproc needs
@@ -197,6 +201,12 @@
// clean-up open files, etc from the openproc()
extern void closeproc(PROCTAB* PT);
+// allocate memory for supgrp
+extern void allocsupgrp(proc_t *p);
+
+// free memory allocated for supgrp
+extern void freesupgrp(proc_t *p);
+
// retrieve the next process matching the criteria set by the openproc()
extern proc_t* readproc(PROCTAB *restrict const PT, proc_t *restrict p);
extern proc_t* readtask(PROCTAB *restrict const PT, const proc_t *restrict const p, proc_t *restrict t);
@@ -209,6 +219,7 @@
// deallocate space allocated by readproc
extern void freeproc(proc_t* p);
+extern void freeproc_light(proc_t* p);
//fill out a proc_t for a single task
extern proc_t * get_proc_stats(pid_t pid, proc_t *p);
@@ -236,8 +247,11 @@
#define PROC_FILLSTAT 0x0040 // read stat -- currently unconditional
#define PROC_FILLWCHAN 0x0080 // look up WCHAN name
#define PROC_FILLARG 0x0100 // alloc and fill in `cmdline'
+#define PROC_FILLCGROUP 0x0200 // alloc and fill in `cgroup`
+#define PROC_FILLSUPGRP 0x0400 // resolve supplementary group id number -> group name
+#define PROC_TASKSUPGRP 0x0800 // resolve supplementary group id number -> group name
-#define PROC_LOOSE_TASKS 0x0200 // threat threads as if they were processes
+#define PROC_LOOSE_TASKS 0x2000 // threat threads as if they were processes
// Obsolete, consider only processes with one of the passed:
#define PROC_PID 0x1000 // process id numbers ( 0 terminated)
@@ -249,5 +263,9 @@
#define PROC_SPARE_3 0x04000000
#define PROC_SPARE_4 0x08000000
+
+char** file2strvec(const char* directory, const char* what);
+char** file2strvec_ext(const char* directory, const char* what, char terminator);
+
EXTERN_C_END
#endif
diff -bruN procps-3.2.8.orig/proc/sysinfo.c /home/ale/devel/debian/pkg-collab/packages/ulatencyd/src/proc/sysinfo.c
--- procps-3.2.8.orig/proc/sysinfo.c 2012-07-04 16:36:07.572291071 +0200
+++ /home/ale/devel/debian/pkg-collab/packages/ulatencyd/src/proc/sysinfo.c 2012-07-04 16:37:32.108710229 +0200
@@ -124,24 +124,25 @@
unsigned long long Hertz;
static void old_Hertz_hack(void){
- unsigned long long user_j, nice_j, sys_j, other_j; /* jiffies (clock ticks) */
+ unsigned long long user_j, nice_j, sys_j, other_j, wait_j, hirq_j, sirq_j, stol_j; /* jiffies (clock ticks) */
double up_1, up_2, seconds;
unsigned long long jiffies;
unsigned h;
char *restrict savelocale;
+ wait_j = hirq_j = sirq_j = stol_j = 0;
savelocale = setlocale(LC_NUMERIC, NULL);
setlocale(LC_NUMERIC, "C");
do{
FILE_TO_BUF(UPTIME_FILE,uptime_fd); sscanf(buf, "%lf", &up_1);
/* uptime(&up_1, NULL); */
FILE_TO_BUF(STAT_FILE,stat_fd);
- sscanf(buf, "cpu %Lu %Lu %Lu %Lu", &user_j, &nice_j, &sys_j, &other_j);
+ sscanf(buf, "cpu %Lu %Lu %Lu %Lu %Lu %Lu %Lu %Lu", &user_j, &nice_j, &sys_j, &other_j, &wait_j, &hirq_j, &sirq_j, &stol_j);
FILE_TO_BUF(UPTIME_FILE,uptime_fd); sscanf(buf, "%lf", &up_2);
/* uptime(&up_2, NULL); */
} while((long long)( (up_2-up_1)*1000.0/up_1 )); /* want under 0.1% error */
setlocale(LC_NUMERIC, savelocale);
- jiffies = user_j + nice_j + sys_j + other_j;
+ jiffies = user_j + nice_j + sys_j + other_j + wait_j + hirq_j + sirq_j + stol_j ;
seconds = (up_1 + up_2) / 2;
h = (unsigned)( (double)jiffies/seconds/smp_num_cpus );
/* actual values used by 2.4 kernels: 32 64 100 128 1000 1024 1200 */
@@ -187,6 +188,7 @@
//extern char** environ;
/* for ELF executables, notes are pushed before environment and args */
+/*
static unsigned long find_elf_note(unsigned long findme){
unsigned long *ep = (unsigned long *)environ;
while(*ep++);
@@ -194,11 +196,13 @@
if(ep[0]==findme) return ep[1];
ep+=2;
}
+
return NOTE_NOT_FOUND;
}
-
+*/
int have_privs;
+/*
static int check_for_privs(void){
unsigned long rc = find_elf_note(AT_SECURE);
if(rc==NOTE_NOT_FOUND){
@@ -208,10 +212,12 @@
}
return !!rc;
}
+*/
static void init_libproc(void) __attribute__((constructor));
static void init_libproc(void){
- have_privs = check_for_privs();
+ //have_privs = check_for_privs();
+ init_Linux_version(); /* Must be called before we check code */
// ought to count CPUs in /proc/stat instead of relying
// on glibc, which foolishly tries to parse /proc/cpuinfo
//
@@ -221,13 +227,24 @@
// _SC_NPROCESSORS_ONLN returns 1, which should work OK
smp_num_cpus = sysconf(_SC_NPROCESSORS_ONLN);
if(smp_num_cpus<1) smp_num_cpus=1; /* SPARC glibc is buggy */
-
+/*
+#ifdef __linux__
if(linux_version_code > LINUX_VERSION(2, 4, 0)){
Hertz = find_elf_note(AT_CLKTCK);
if(Hertz!=NOTE_NOT_FOUND) return;
fputs("2.4+ kernel w/o ELF notes? -- report this\n", stderr);
}
- old_Hertz_hack();
+#endif
+*/
+#if defined(__FreeBSD_kernel__) || defined(__FreeBSD__)
+ /* On FreeBSD the Hertz hack is unrelaible, there is no ELF note and
+ * Hertz isn't defined in asm/params.h
+ * See Debian Bug #460331
+ */
+ Hertz = 100;
+ return;
+#endif
+// old_Hertz_hack();
}
#if 0
@@ -604,7 +621,7 @@
);
head = tail+1;
if(!found) goto nextline;
- *(found->slot) = strtoul(head,&tail,10);
+ *(found->slot) = (unsigned long)strtoull(head,&tail,10);
nextline:
tail = strchr(head, '\n');
if(!tail) break;
@@ -794,6 +811,18 @@
}
/////////////////////////////////////////////////////////////////////////////
+static int is_disk(char *dev)
+{
+ char syspath[PATH_MAX];
+ char *slash;
+
+ while ((slash = strchr(dev, '/')))
+ *slash = '!';
+ snprintf(syspath, sizeof(syspath), "/sys/block/%s", dev);
+ return !(access(syspath, F_OK));
+}
+
+/////////////////////////////////////////////////////////////////////////////
unsigned int getdiskstat(struct disk_stat **disks, struct partition_stat **partitions){
FILE* fd;
@@ -801,6 +830,7 @@
int cPartition = 0;
int fields;
unsigned dummy;
+ char devname[PATH_MAX];
*disks = NULL;
*partitions = NULL;
@@ -813,8 +843,9 @@
fclose(fd);
break;
}
- fields = sscanf(buff, " %*d %*d %*s %*u %*u %*u %*u %*u %*u %*u %*u %*u %*u %u", &dummy);
- if (fields == 1){
+ fields = sscanf(buff, " %*d %*d %15s %*u %*u %*u %*u %*u %*u %*u %*u %*u %*u %u",
+ &devname[0], &dummy);
+ if (fields == 2 && is_disk(devname)){
(*disks) = realloc(*disks, (cDisk+1)*sizeof(struct disk_stat));
sscanf(buff, " %*d %*d %15s %u %u %llu %u %u %u %llu %u %u %u %u",
//&disk_major,
@@ -837,7 +868,9 @@
}else{
(*partitions) = realloc(*partitions, (cPartition+1)*sizeof(struct partition_stat));
fflush(stdout);
- sscanf(buff, " %*d %*d %15s %u %llu %u %u",
+ sscanf(buff, (fields == 2)
+ ? " %*d %*d %15s %u %*u %llu %*u %u %*u %llu %*u %*u %*u %*u"
+ : " %*d %*d %15s %u %llu %u %llu",
//&part_major,
//&part_minor,
(*partitions)[cPartition].partition_name,
diff -bruN procps-3.2.8.orig/proc/sysinfo.h /home/ale/devel/debian/pkg-collab/packages/ulatencyd/src/proc/sysinfo.h
--- procps-3.2.8.orig/proc/sysinfo.h 2012-07-04 16:36:07.568290991 +0200
+++ /home/ale/devel/debian/pkg-collab/packages/ulatencyd/src/proc/sysinfo.h 2012-07-04 16:37:32.108710229 +0200
@@ -113,7 +113,7 @@
unsigned parent_disk; // index into a struct disk_stat array
unsigned reads;
unsigned writes;
- unsigned requested_writes;
+ unsigned long long requested_writes;
}partition_stat;
extern unsigned int getpartitions_num(struct disk_stat *disks, int ndisks);
diff -bruN procps-3.2.8.orig/proc/version.c /home/ale/devel/debian/pkg-collab/packages/ulatencyd/src/proc/version.c
--- procps-3.2.8.orig/proc/version.c 2012-07-04 16:36:07.572291071 +0200
+++ /home/ale/devel/debian/pkg-collab/packages/ulatencyd/src/proc/version.c 2012-07-04 16:37:32.108710229 +0200
@@ -33,17 +33,26 @@
int linux_version_code;
-static void init_Linux_version(void) __attribute__((constructor));
-static void init_Linux_version(void) {
- static struct utsname uts;
+void init_Linux_version(void) {
int x = 0, y = 0, z = 0; /* cleared in case sscanf() < 3 */
+ FILE *fp;
+ char buf[256];
- if (uname(&uts) == -1) /* failure implies impending death */
+ if ( (fp=fopen("/proc/version","r")) == NULL) {
+ fprintf(stderr, "Cannot find /proc/version - is /proc mounted?\n");
exit(1);
- if (sscanf(uts.release, "%d.%d.%d", &x, &y, &z) < 3)
+ }
+ if (fgets(buf, 256, fp) == NULL) {
+ fprintf(stderr, "Cannot read kernel version from /proc/version\n");
+ fclose(fp);
+ exit(1);
+ }
+ fclose(fp);
+ if (sscanf(buf, "Linux version %d.%d.%d", &x, &y, &z) < 3)
fprintf(stderr, /* *very* unlikely to happen by accident */
"Non-standard uts for running kernel:\n"
"release %s=%d.%d.%d gives version code %d\n",
- uts.release, x, y, z, LINUX_VERSION(x,y,z));
+ buf,
+ x, y, z, LINUX_VERSION(x,y,z));
linux_version_code = LINUX_VERSION(x, y, z);
}
diff -bruN procps-3.2.8.orig/proc/version.h /home/ale/devel/debian/pkg-collab/packages/ulatencyd/src/proc/version.h
--- procps-3.2.8.orig/proc/version.h 2012-07-04 16:36:07.568290991 +0200
+++ /home/ale/devel/debian/pkg-collab/packages/ulatencyd/src/proc/version.h 2012-07-04 16:37:32.112710235 +0200
@@ -14,6 +14,7 @@
EXTERN_C_BEGIN
+void init_Linux_version(void); /* Get Linux version */
extern void display_version(void); /* display suite version */
extern const char procps_version[]; /* global buf for suite version */
signature.asc
Description: Digital signature

