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