Пример #1
0
int init_process_info_sysdep(void) {
  char *ptr;
  char  buf[1024];
  long  page_size;
  int   page_shift;  

  if (! read_proc_file(buf, sizeof(buf), "meminfo", -1, NULL)) 
    return FALSE;
  if (! (ptr = strstr(buf, MEMTOTAL))) {
    DEBUG("system statistic error -- cannot get real memory amount\n");
    return FALSE;
  }
  if (sscanf(ptr+strlen(MEMTOTAL), "%ld", &systeminfo.mem_kbyte_max) != 1) {
    DEBUG("system statistic error -- cannot get real memory amount\n");
    return FALSE;
  }

  if ((systeminfo.cpus = sysconf(_SC_NPROCESSORS_CONF)) < 0) {
    DEBUG("system statistic error -- cannot get cpu count: %s\n", STRERROR);
    return FALSE;
  } else if (systeminfo.cpus == 0) {
    DEBUG("system reports cpu count 0, setting dummy cpu count 1\n");
    systeminfo.cpus = 1;
  }

  if ((page_size = sysconf(_SC_PAGESIZE)) <= 0) {
    DEBUG("system statistic error -- cannot get page size: %s\n", STRERROR);
    return FALSE;
  }

  for (page_shift = 0; page_size != 1; page_size >>= 1, page_shift++);
  page_shift_to_kb = page_shift - 10;

  return TRUE;
}
Пример #2
0
/**
 * @file
 * @brief 
 * Cached Ram
 *
 * @details
 * This function looks up the amount of ram used for cache in bytes.
 *
 * @param totalram
 * Output, passed by reference.  On successful return, the value
 * is set to the amount of ram used for disk cache (in bytes) available on the system.
 *
 * @return
 * The return value indicates the status of the function.
 */
int meminfo_cachedram(memsize_t *cachedram)
{
  int ret = MEMINFO_OK;
  *cachedram = 0L;
  
  
#if OS_LINUX
  int test = read_proc_file("/proc/meminfo", cachedram, "Cached:", 7);
  chkret(test, FAILURE);
  
  *cachedram *= 1024L;
#elif OS_FREEBSD
  int page;
  memsize_t v = 0;
  
  page = sysconf(_SC_PAGESIZE);
  if (page == -1)
    return FAILURE;
  
  int test = sysctl_val("vm.stats.vm.v_cache_count", &v);
  chkret(test, FAILURE);
  
  *cachedram = (memsize_t) v*page;
#else
  ret = PLATFORM_ERROR;
#endif
  
  return ret;
}
Пример #3
0
/**
 * Get system start time
 * @return seconds since unix epoch
 */
static time_t get_starttime() {
  char   buf[1024];
  double up = 0;

  if (! read_proc_file(buf, 1024, "uptime", -1, NULL)) {
    LogError("system statistic error -- cannot get system uptime\n");
    return 0;
  }

  if (sscanf(buf, "%lf", &up) != 1) {
    LogError("system statistic error -- invalid uptime\n");
    return 0;
  }

  return time(NULL) - (time_t)up;
}
Пример #4
0
/**
 * This routine returns real memory in use.
 * @return: true if successful, false if failed
 */
boolean_t used_system_memory_sysdep(SystemInfo_T *si) {
        char          *ptr;
        char           buf[2048];
        unsigned long  mem_free = 0UL;
        unsigned long  buffers = 0UL;
        unsigned long  cached = 0UL;
        unsigned long  slabreclaimable = 0UL;
        unsigned long  swap_total = 0UL;
        unsigned long  swap_free = 0UL;

        if (! read_proc_file(buf, sizeof(buf), "meminfo", -1, NULL)) {
                LogError("system statistic error -- cannot get real memory free amount\n");
                goto error;
        }

        /* Memory */
        if (! (ptr = strstr(buf, "MemFree:")) || sscanf(ptr + 8, "%ld", &mem_free) != 1) {
                LogError("system statistic error -- cannot get real memory free amount\n");
                goto error;
        }
        if (! (ptr = strstr(buf, "Buffers:")) || sscanf(ptr + 8, "%ld", &buffers) != 1)
                DEBUG("system statistic error -- cannot get real memory buffers amount\n");
        if (! (ptr = strstr(buf, "Cached:")) || sscanf(ptr + 7, "%ld", &cached) != 1)
                DEBUG("system statistic error -- cannot get real memory cache amount\n");
        if (! (ptr = strstr(buf, "SReclaimable:")) || sscanf(ptr + 13, "%ld", &slabreclaimable) != 1)
                DEBUG("system statistic error -- cannot get slab reclaimable memory amount\n");
        si->total_mem = systeminfo.mem_max - (uint64_t)(mem_free + buffers + cached + slabreclaimable) * 1024;

        /* Swap */
        if (! (ptr = strstr(buf, "SwapTotal:")) || sscanf(ptr + 10, "%ld", &swap_total) != 1) {
                LogError("system statistic error -- cannot get swap total amount\n");
                goto error;
        }
        if (! (ptr = strstr(buf, "SwapFree:")) || sscanf(ptr + 9, "%ld", &swap_free) != 1) {
                LogError("system statistic error -- cannot get swap free amount\n");
                goto error;
        }
        si->swap_max = (uint64_t)swap_total * 1024;
        si->total_swap = (uint64_t)(swap_total - swap_free) * 1024;

        return true;

error:
        si->total_mem = 0ULL;
        si->swap_max = 0ULL;
        return false;
}
Пример #5
0
/**
 * This routine returns 'nelem' double precision floats containing
 * the load averages in 'loadv'; at most 3 values will be returned.
 * @param loadv destination of the load averages
 * @param nelem number of averages
 * @return: 0 if successful, -1 if failed (and all load averages are 0).
 */
int getloadavg_sysdep(double *loadv, int nelem) {
#ifdef HAVE_GETLOADAVG
        return getloadavg(loadv, nelem);
#else
        char buf[STRLEN];
        double load[3];
        if (! read_proc_file(buf, sizeof(buf), "loadavg", -1, NULL))
                return -1;
        if (sscanf(buf, "%lf %lf %lf", &load[0], &load[1], &load[2]) != 3) {
                DEBUG("system statistic error -- cannot get load average\n");
                return -1;
        }
        for (int i = 0; i < nelem; i++)
                loadv[i] = load[i];
        return 0;
#endif
}
Пример #6
0
void refresh_global_stats(proc_global_stats_t *stat)
{
  static int proc_stat_fd = -1;
  char buf[1024], *p, *end;
  int ret;

  ret = read_proc_file(&proc_stat_fd, "/proc/stat", buf, sizeof(buf)-1);
  if( ret < 0 ) return;
  buf[ret] = '\0';


  // FIXME: parse CPU info (?)

  // parse pageing activity
  p = strstr(buf,"page ");
  if( p == NULL ) {warning("couldn't find page data in /proc/stat!\n"); return;}

  p += 5; // strlen("page ");
  stat->pages_in = strtol(p, &end, 0);
  if( p == end ) {warning("bad pagein data\n"); return;}
  
  p = end;
  stat->pages_out = strtol(p, &end, 0);
  if( p == end ) {warning("bad pagein data\n"); return;}

  
  // parse swap file activity
  p = strstr(buf,"swap ");
  if( p == NULL ) {warning("couldn't find swap data in /proc/stat!\n"); return;}

  p += 5; // strlen("swap ");
  stat->pages_swapin = strtol(p, &end, 0);
  if( p == end ) {warning("bad pswapin data\n"); return;}
  
  p = end;
  stat->pages_swapout = strtol(p, &end, 0);
  if( p == end ) {warning("bad pswapout data\n"); return;}


  warning("gstats:   %d %d   %d %d\n",
          stat->pages_in, stat->pages_out,
          stat->pages_swapin, stat->pages_swapout);
}
Пример #7
0
boolean_t init_process_info_sysdep(void) {
        char *ptr;
        char  buf[2048];

        if ((hz = sysconf(_SC_CLK_TCK)) <= 0.) {
                DEBUG("system statistic error -- cannot get hz: %s\n", STRERROR);
                return false;
        }

        if ((page_size = sysconf(_SC_PAGESIZE)) <= 0) {
                DEBUG("system statistic error -- cannot get page size: %s\n", STRERROR);
                return false;
        }

        if (! read_proc_file(buf, sizeof(buf), "meminfo", -1, NULL)) {
                DEBUG("system statistic error -- cannot read /proc/meminfo\n");
                return false;
        }
        if (! (ptr = strstr(buf, "MemTotal:"))) {
                DEBUG("system statistic error -- cannot get real memory amount\n");
                return false;
        }
        long mem_max;
        if (sscanf(ptr + 9, "%ld", &mem_max) != 1) {
                DEBUG("system statistic error -- cannot get real memory amount\n");
                return false;
        }
        systeminfo.mem_max = (uint64_t)mem_max * 1024;

        if ((systeminfo.cpus = sysconf(_SC_NPROCESSORS_CONF)) < 0) {
                DEBUG("system statistic error -- cannot get cpu count: %s\n", STRERROR);
                return false;
        } else if (systeminfo.cpus == 0) {
                DEBUG("system reports cpu count 0, setting dummy cpu count 1\n");
                systeminfo.cpus = 1;
        }

        return true;
}
Пример #8
0
/**
 * This routine returns system/user CPU time in use.
 * @return: true if successful, false if failed (or not available)
 */
boolean_t used_system_cpu_sysdep(SystemInfo_T *si) {
        boolean_t rv;
        unsigned long long cpu_total;
        unsigned long long cpu_user;
        unsigned long long cpu_nice;
        unsigned long long cpu_syst;
        unsigned long long cpu_idle;
        unsigned long long cpu_wait;
        unsigned long long cpu_irq;
        unsigned long long cpu_softirq;
        char buf[STRLEN];

        if (! read_proc_file(buf, sizeof(buf), "stat", -1, NULL)) {
                LogError("system statistic error -- cannot read /proc/stat\n");
                goto error;
        }

        rv = sscanf(buf, "cpu %llu %llu %llu %llu %llu %llu %llu",
                    &cpu_user,
                    &cpu_nice,
                    &cpu_syst,
                    &cpu_idle,
                    &cpu_wait,
                    &cpu_irq,
                    &cpu_softirq);
        if (rv < 4) {
                LogError("system statistic error -- cannot read cpu usage\n");
                goto error;
        } else if (rv == 4) {
                /* linux 2.4.x doesn't support these values */
                cpu_wait    = 0;
                cpu_irq     = 0;
                cpu_softirq = 0;
        }

        cpu_total = cpu_user + cpu_nice + cpu_syst + cpu_idle + cpu_wait + cpu_irq + cpu_softirq;
        cpu_user  = cpu_user + cpu_nice;

        if (old_cpu_total == 0) {
                si->total_cpu_user_percent = -1.;
                si->total_cpu_syst_percent = -1.;
                si->total_cpu_wait_percent = -1.;
        } else {
                unsigned long long delta = cpu_total - old_cpu_total;

                si->total_cpu_user_percent = 100. * (double)(cpu_user - old_cpu_user) / delta;
                si->total_cpu_syst_percent = 100. * (double)(cpu_syst - old_cpu_syst) / delta;
                si->total_cpu_wait_percent = 100. * (double)(cpu_wait - old_cpu_wait) / delta;
        }

        old_cpu_user  = cpu_user;
        old_cpu_syst  = cpu_syst;
        old_cpu_wait  = cpu_wait;
        old_cpu_total = cpu_total;
        return true;

error:
        si->total_cpu_user_percent = 0.;
        si->total_cpu_syst_percent = 0.;
        si->total_cpu_wait_percent = 0.;
        return false;
}
Пример #9
0
/**
 * Read all processes of the proc files system to initialize the process tree
 * @param reference reference of ProcessTree
 * @param pflags Process engine flags
 * @return treesize > 0 if succeeded otherwise 0
 */
int initprocesstree_sysdep(ProcessTree_T **reference, ProcessEngine_Flags pflags) {
        int                 rv, bytes = 0;
        int                 treesize = 0;
        int                 stat_pid = 0;
        int                 stat_ppid = 0;
        int                 stat_uid = 0;
        int                 stat_euid = 0;
        int                 stat_gid = 0;
        char               *tmp = NULL;
        char                procname[STRLEN];
        char                buf[4096];
        char                stat_item_state;
        long                stat_item_cutime = 0;
        long                stat_item_cstime = 0;
        long                stat_item_rss = 0;
        int                 stat_item_threads = 0;
        glob_t              globbuf;
        unsigned long       stat_item_utime = 0;
        unsigned long       stat_item_stime = 0;
        unsigned long long  stat_item_starttime = 0ULL;

        ASSERT(reference);

        /* Find all processes in the /proc directory */
        if ((rv = glob("/proc/[0-9]*", 0, NULL, &globbuf))) {
                LogError("system statistic error -- glob failed: %d (%s)\n", rv, STRERROR);
                return 0;
        }

        treesize = globbuf.gl_pathc;

        ProcessTree_T *pt = CALLOC(sizeof(ProcessTree_T), treesize);

        /* Insert data from /proc directory */
        time_t starttime = get_starttime();
        for (int i = 0; i < treesize; i++) {
                stat_pid = atoi(globbuf.gl_pathv[i] + 6); // skip "/proc/"

                /********** /proc/PID/stat **********/
                if (! read_proc_file(buf, sizeof(buf), "stat", stat_pid, NULL)) {
                        DEBUG("system statistic error -- cannot read /proc/%d/stat\n", stat_pid);
                        continue;
                }
                if (! (tmp = strrchr(buf, ')'))) {
                        DEBUG("system statistic error -- file /proc/%d/stat parse error\n", stat_pid);
                        continue;
                }
                *tmp = 0;
                if (sscanf(buf, "%*d (%255s", procname) != 1) {
                        DEBUG("system statistic error -- file /proc/%d/stat process name parse error\n", stat_pid);
                        continue;
                }
                tmp += 2;
                if (sscanf(tmp,
                           "%c %d %*d %*d %*d %*d %*u %*u %*u %*u %*u %lu %lu %ld %ld %*d %*d %d %*u %llu %*u %ld %*u %*u %*u %*u %*u %*u %*u %*u %*u %*u %*u %*u %*u %*d %*d\n",
                           &stat_item_state,
                           &stat_ppid,
                           &stat_item_utime,
                           &stat_item_stime,
                           &stat_item_cutime,
                           &stat_item_cstime,
                           &stat_item_threads,
                           &stat_item_starttime,
                           &stat_item_rss) != 9) {
                        DEBUG("system statistic error -- file /proc/%d/stat parse error\n", stat_pid);
                        continue;
                }

                /********** /proc/PID/status **********/
                if (! read_proc_file(buf, sizeof(buf), "status", stat_pid, NULL)) {
                        DEBUG("system statistic error -- cannot read /proc/%d/status\n", stat_pid);
                        continue;
                }
                if (! (tmp = strstr(buf, "Uid:"))) {
                        DEBUG("system statistic error -- cannot find process uid\n");
                        continue;
                }
                if (sscanf(tmp + 4, "\t%d\t%d", &stat_uid, &stat_euid) != 2) {
                        DEBUG("system statistic error -- cannot read process uid\n");
                        continue;
                }
                if (! (tmp = strstr(buf, "Gid:"))) {
                        DEBUG("system statistic error -- cannot find process gid\n");
                        continue;
                }
                if (sscanf(tmp + 4, "\t%d", &stat_gid) != 1) {
                        DEBUG("system statistic error -- cannot read process gid\n");
                        continue;
                }

                /********** /proc/PID/cmdline **********/
                if (pflags & ProcessEngine_CollectCommandLine) {
                        if (! read_proc_file(buf, sizeof(buf), "cmdline", stat_pid, &bytes)) {
                                DEBUG("system statistic error -- cannot read /proc/%d/cmdline\n", stat_pid);
                                continue;
                        }
                        for (int j = 0; j < (bytes - 1); j++) // The cmdline file contains argv elements/strings terminated separated by '\0' => join the string
                                if (buf[j] == 0)
                                        buf[j] = ' ';
                        pt[i].cmdline = Str_dup(*buf ? buf : procname);
                }

                /* Set the data in ptree only if all process related reads succeeded (prevent partial data in the case that continue was called during data gathering) */
                pt[i].pid = stat_pid;
                pt[i].ppid = stat_ppid;
                pt[i].cred.uid = stat_uid;
                pt[i].cred.euid = stat_euid;
                pt[i].cred.gid = stat_gid;
                pt[i].threads = stat_item_threads;
                pt[i].uptime = starttime > 0 ? (systeminfo.time / 10. - (starttime + (time_t)(stat_item_starttime / hz))) : 0;
                pt[i].cpu.time = (double)(stat_item_utime + stat_item_stime) / hz * 10.; // jiffies -> seconds = 1/hz
                pt[i].memory.usage = (uint64_t)stat_item_rss * (uint64_t)page_size;
                pt[i].zombie = stat_item_state == 'Z' ? true : false;
        }

        *reference = pt;
        globfree(&globbuf);

        return treesize;
}
Пример #10
0
/**
 * Read stats from /proc/self/stat.
 *
 * FIXME: the FD caching may not work correctly for cloned children -
 * check on this later.
 **/
void refresh_process_stats(proc_self_stat_t *stat)
{
  static int fd = -1;
  char buf[256];
  int ret;
  //int len;

  ret = read_proc_file(&fd, "/proc/self/stat", buf, sizeof(buf));
  if( ret < 0 ) return;
  if( ret == sizeof(buf) ) {
    warning("too much data in /proc/self/stat - can't get valid stats\n"); 
    if( fd >= 0) close(fd);
    fd = -2;
    return;
  }
  
  // parse.  We could do this faster ourselves, by not keeping all of
  // this data.  The speed shouldn't really matter, though, since this
  // routine should only be called a few times / second.
  ret = sscanf(buf, "%d (%[^)]) %c %d %d %d %d %d %lu %lu \
%lu %lu %lu %lu %lu %ld %ld %ld %ld %ld %ld %llu %lu %ld %lu %lu %lu %lu %lu \
%lu %lu %lu %lu %lu %lu %lu %lu %d %d %lu %lu",

               &stat->pid, 
               &stat->comm[0],
               &stat->state,
               &stat->ppid,
               &stat->pgrp,
               &stat->session,
               &stat->tty_nr,
               &stat->tty_pgrp,

               &stat->flags,
               &stat->min_flt,
               &stat->cmin_flt,
               &stat->maj_flt,
               &stat->cmaj_flt,
               &stat->tms_utime,
               &stat->tms_stime,
               &stat->tms_cutime,
               &stat->tms_cstime,

               &stat->priority,
               &stat->nice,
               &stat->removed, 
               &stat->it_real_value,
               &stat->start_time, // just unsigned long in 2.4
  
               &stat->vsize,
               &stat->rss,
               &stat->rss_rlim_cur,
               &stat->start_code,
               &stat->end_code,
               &stat->start_stack,
               &stat->esp,
               &stat->eip,

               &stat->pending_sig, // obsolete - use /proc/self/status
               &stat->blocked_sig, // obsolete - use /proc/self/status
               &stat->sigign,      // obsolete - use /proc/self/status
               &stat->sigcatch,    // obsolete - use /proc/self/status
               &stat->wchan,

               &stat->nswap,
               &stat->cnswap,
               &stat->exit_signal,
               &stat->cpu_num,
               &stat->rt_priority, // new in 2.5
               &stat->policy      // new in 2.5
               );

  warning("stats: %d (%s)... %ld %ld   %ld  ret=%d\n", 
          stat->pid, 
          stat->comm,
          stat->vsize,
          stat->rss,
          stat->maj_flt,
          ret);
  
  if( ret != 39 && ret != 41 ) {
    warning("error parsing /proc/self/stat - got %d items\n", ret);
    //bzero(stat, sizeof(proc_self_stat_t));
    if( fd >= 0) close(fd);
    fd = -1;
    return;
  }
}
Пример #11
0
int read_proc_dir(const char *dir_name, const char *pid, int position)
{
    DIR *dp;
    struct dirent *entry;

    if ((dir_name == NULL) || (strlen(dir_name) > PATH_MAX)) {
        merror("%s: Invalid directory given", ARGV0);
        return (-1);
    }

    /* Open the directory */
    dp = opendir(dir_name);
    if (!dp) {
        return (0);
    }

    while ((entry = readdir(dp)) != NULL) {
        char f_name[PATH_MAX + 2];

        /* Ignore . and ..  */
        if (strcmp(entry->d_name, ".")  == 0 ||
                strcmp(entry->d_name, "..") == 0) {
            continue;
        }

        if (position == PROC) {
            char *tmp_str;

            tmp_str = entry->d_name;
            while (*tmp_str != '\0') {
                if (!isdigit((int)*tmp_str)) {
                    break;
                }
                tmp_str++;
            }

            if (*tmp_str != '\0') {
                continue;
            }

            snprintf(f_name, PATH_MAX + 1, "%s/%s", dir_name, entry->d_name);
            read_proc_file(f_name, pid, position + 1);
        } else if (position == PID) {
            if (strcmp(entry->d_name, "task") == 0) {
                snprintf(f_name, PATH_MAX + 1, "%s/%s", dir_name, entry->d_name);
                read_proc_file(f_name, pid, position + 1);
            }
        } else if (position == TASK) {
            /* Check under proc/pid/task/lwp */
            if (strcmp(entry->d_name, pid) == 0) {
                proc_pid_found = 1;
                break;
            }
        } else {
            break;
        }
    }

    closedir(dp);

    return (0);
}
Пример #12
0
/**
 * Read all processes of the proc files system to initialize
 * the process tree (sysdep version... but should work for
 * all procfs based unices) 
 * @param reference  reference of ProcessTree
 * @return treesize>0 if succeeded otherwise =0.
 */
int initprocesstree_sysdep(ProcessTree_T ** reference) {
  int                 i = 0, j;
  int                 rv, bytes = 0;
  int                 treesize = 0;
  int                 stat_ppid = 0;
  char               *tmp = NULL;
  char                procname[STRLEN];
  char                buf[1024];
  char                stat_item_state;
  long                stat_item_cutime = 0;
  long                stat_item_cstime = 0;
  long                stat_item_rss = 0;
  glob_t              globbuf;
  unsigned long       stat_item_utime = 0;
  unsigned long       stat_item_stime = 0;
  unsigned long long  stat_item_starttime = 0ULL;
  ProcessTree_T      *pt = NULL;

  ASSERT(reference);

  /* Find all processes in the /proc directory */
  if ((rv = glob("/proc/[0-9]*", GLOB_ONLYDIR, NULL, &globbuf))) {
    LogError("system statistic error -- glob failed: %d (%s)\n", rv, STRERROR);
    return FALSE;
  } 

  treesize = globbuf.gl_pathc;

  pt = CALLOC(sizeof(ProcessTree_T), treesize);

  /* Insert data from /proc directory */
  for (i = 0; i < treesize; i++) {

    pt[i].pid = atoi(globbuf.gl_pathv[i] + strlen("/proc/"));
    
    if (!read_proc_file(buf, sizeof(buf), "stat", pt[i].pid, NULL)) {
      DEBUG("system statistic error -- cannot read /proc/%d/stat\n", pt[i].pid);
      continue;
    }

    pt[i].time = get_float_time();

    if (!(tmp = strrchr(buf, ')'))) {
      DEBUG("system statistic error -- file /proc/%d/stat parse error\n", pt[i].pid);
      continue;
    }
    *tmp = 0;
    if (sscanf(buf, "%*d (%256s", procname) != 1) {
      DEBUG("system statistic error -- file /proc/%d/stat process name parse error\n", pt[i].pid);
      continue;
    }

    tmp += 2;

    /* This implementation is done by using fs/procfs/array.c as a basis
     * it is also worth looking into the source of the procps utils */
    if (sscanf(tmp,
         "%c %d %*d %*d %*d %*d %*u %*u"
         "%*u %*u %*u %lu %lu %ld %ld %*d %*d %*d "
         "%*u %llu %*u %ld %*u %*u %*u %*u %*u "
         "%*u %*u %*u %*u %*u %*u %*u %*u %*d %*d\n",
         &stat_item_state,
         &stat_ppid,
         &stat_item_utime,
         &stat_item_stime,
         &stat_item_cutime,
         &stat_item_cstime,
         &stat_item_starttime,
         &stat_item_rss) != 8) {
      DEBUG("system statistic error -- file /proc/%d/stat parse error\n", pt[i].pid);
      continue;
    }
    
    pt[i].ppid      = stat_ppid;
    pt[i].starttime = get_starttime() + (time_t)(stat_item_starttime / HZ);
  
    /* jiffies -> seconds = 1 / HZ
     * HZ is defined in "asm/param.h"  and it is usually 1/100s but on
     * alpha system it is 1/1024s */
    pt[i].cputime     = ((float)(stat_item_utime + stat_item_stime) * 10.0) / HZ;
    pt[i].cpu_percent = 0;

    /* State is Zombie -> then we are a Zombie ... clear or? (-: */
    if (stat_item_state == 'Z')
      pt[i].status_flag |= PROCESS_ZOMBIE;

    if (page_shift_to_kb < 0)
      pt[i].mem_kbyte = (stat_item_rss >> abs(page_shift_to_kb));
    else
      pt[i].mem_kbyte = (stat_item_rss << abs(page_shift_to_kb));

    if (! read_proc_file(buf, sizeof(buf), "cmdline", pt[i].pid, &bytes)) {
      DEBUG("system statistic error -- cannot read /proc/%d/cmdline\n", pt[i].pid);
      continue;
    }
    /* The cmdline file contains argv elements/strings terminated separated by '\0' => join the string: */
    for (j = 0; j < (bytes - 1); j++)
      if (buf[j] == 0)
        buf[j] = ' ';
    pt[i].cmdline = *buf ? Str_dup(buf) : Str_dup(procname);
  }
Пример #13
0
/**
 * Read all processes of the proc files system to initialize
 * the process tree (sysdep version... but should work for
 * all procfs based unices)
 * @param reference  reference of ProcessTree
 * @return treesize>0 if succeeded otherwise =0.
 */
int initprocesstree_sysdep(ProcessTree_T ** reference) {
  int            i;
  int            rv;
  int            pid;
  int            treesize;
  char           buf[4096];
  glob_t         globbuf;
  pstatus_t      pstatus;
  psinfo_t      *psinfo = (psinfo_t *)&buf;
  ProcessTree_T *pt;

  ASSERT(reference);

  /* Find all processes in the /proc directory */
  if ((rv = glob("/proc/[0-9]*", NULL, NULL, &globbuf)) != 0) {
    LogError("system statistic error -- glob failed: %d (%s)\n", rv, STRERROR);
    return 0;
  }

  treesize = globbuf.gl_pathc;

  /* Allocate the tree */
  pt = xcalloc(sizeof(ProcessTree_T), treesize);

  /* Insert data from /proc directory */
  for (i = 0; i < treesize; i++) {
    pid = atoi(globbuf.gl_pathv[i] + strlen("/proc/"));
    pt[i].pid = pid;

    /* get the actual time */
    pt[i].time = get_float_time();

    if (! read_proc_file(buf, sizeof(buf), "psinfo", pt[i].pid, NULL)) {
      pt[i].cputime     = 0;
      pt[i].cpu_percent = 0;
      pt[i].mem_kbyte   = 0;
      continue;
    } 

    pt[i].ppid      = psinfo->pr_ppid;
    pt[i].starttime = psinfo->pr_start.tv_sec;
        
    /* If we don't have any light-weight processes (LWP) then we are definitely a zombie */
    if (psinfo->pr_nlwp == 0) {
      pt[i].status_flag = PROCESS_ZOMBIE;
      pt[i].cputime     = 0;
      pt[i].cpu_percent = 0;
      pt[i].mem_kbyte   = 0;
      continue;
    } 
    
    pt[i].mem_kbyte = psinfo->pr_rssize;

    pt[i].cmdline  = xstrdup(psinfo->pr_psargs);
    if (! pt[i].cmdline || ! *pt[i].cmdline)
      pt[i].cmdline = xstrdup(psinfo->pr_fname);

    if (! read_proc_file(buf, sizeof(buf), "status", pt[i].pid, NULL)) {
      pt[i].cputime     = 0;
      pt[i].cpu_percent = 0;
    } else {
      memcpy(&pstatus, buf, sizeof(pstatus_t));
      pt[i].cputime     = (timestruc_to_tseconds(pstatus.pr_utime) + timestruc_to_tseconds(pstatus.pr_stime));
      pt[i].cpu_percent = 0;
    }
  }
  
  *reference = pt;

  /* Free globbing buffer */
  globfree(&globbuf);

  return treesize;
}