/** * Read all processes to initialize the information tree. * @param reference reference of ProcessTree * @return treesize>0 if succeeded otherwise =0. */ int initprocesstree_sysdep(ProcessTree_T **reference) { int treesize; static kvm_t *kvm_handle; ProcessTree_T *pt; struct kinfo_proc *pinfo; if (! (kvm_handle = kvm_open(NULL, _PATH_DEVNULL, NULL, O_RDONLY, prog))) { LogError("system statistic error -- cannot initialize kvm interface\n"); return 0; } pinfo = kvm_getprocs(kvm_handle, KERN_PROC_PROC, 0, &treesize); if (! pinfo || (treesize < 1)) { LogError("system statistic error -- cannot get process tree\n"); kvm_close(kvm_handle); return 0; } pt = CALLOC(sizeof(ProcessTree_T), treesize); for (int i = 0; i < treesize; i++) { StringBuffer_T cmdline = StringBuffer_create(64); pt[i].pid = pinfo[i].ki_pid; pt[i].ppid = pinfo[i].ki_ppid; pt[i].uid = pinfo[i].ki_ruid; pt[i].euid = pinfo[i].ki_uid; pt[i].gid = pinfo[i].ki_rgid; pt[i].starttime = pinfo[i].ki_start.tv_sec; pt[i].cputime = (long)(pinfo[i].ki_runtime / 100000); pt[i].mem_kbyte = (unsigned long)(pinfo[i].ki_rssize * pagesize_kbyte); int flags = pinfo[i].ki_stat; char * procname = pinfo[i].ki_comm; if (flags == SZOMB) pt[i].zombie = true; pt[i].cpu_percent = 0; pt[i].time = get_float_time(); char **args; if ((args = kvm_getargv(kvm_handle, &pinfo[i], 0))) { for (int j = 0; args[j]; j++) StringBuffer_append(cmdline, args[j + 1] ? "%s " : "%s", args[j]); pt[i].cmdline = Str_dup(StringBuffer_toString(StringBuffer_trim(cmdline))); } StringBuffer_free(&cmdline); if (! pt[i].cmdline || ! *pt[i].cmdline) { FREE(pt[i].cmdline); pt[i].cmdline = Str_dup(procname); } } *reference = pt; kvm_close(kvm_handle); return treesize; }
/** * Read all processes to initialize the process tree * @param reference reference of ProcessTree * @return treesize>0 if succeeded otherwise 0. */ int initprocesstree_sysdep(ProcessTree_T ** reference) { int i; int treesize; ProcessTree_T *pt; ASSERT(reference); pstat_getdynamic(&pst_dyn, sizeof(struct pst_dynamic), 1, 0); nproc = pst_dyn.psd_activeprocs; if (nproc) RESIZE(psall, nproc * sizeof(struct pst_status)); else return 0; if ((treesize = pstat_getproc(psall, sizeof(struct pst_status), nproc , 0)) == -1) { LogError("system statistic error 1 -- pstat_getproc failed: %s\n", strerror(errno)); return 0; } pt = CALLOC(sizeof(ProcessTree_T), treesize); for (i = 0; i < treesize; i++) { pt[i].pid = psall[i].pst_pid; pt[i].ppid = psall[i].pst_ppid; pt[i].starttime = psall[i].pst_start; pt[i].time = get_float_time(); pt[i].cputime = psall[i].pst_utime + psall[i].pst_stime * 10; pt[i].cpu_percent = (int)(1000. * psall[i].pst_pctcpu / (float)systeminfo.cpus); pt[i].mem_kbyte = (unsigned long)(psall[i].pst_rssize * (page_size / 1024.0)); pt[i].cmdline = (psall[i].pst_cmd && *psall[i].pst_cmd) ? Str_dup(psall[i].pst_cmd) : Str_dup(psall[i].pst_ucomm); if ( psall[i].pst_stat == PS_ZOMBIE ) pt[i].status_flag |= PROCESS_ZOMBIE; } *reference = pt; return treesize; }
/** * Read all processes to initialize the information tree. * @param reference reference of ProcessTree * @return treesize>0 if succeeded otherwise =0. */ int initprocesstree_sysdep(ProcessTree_T **reference) { int i; int treesize; static kvm_t *kvm_handle; ProcessTree_T *pt; struct kinfo_proc *pinfo; if (!(kvm_handle = kvm_open(NULL, _PATH_DEVNULL, NULL, O_RDONLY, prog))) { LogError("system statistic error -- cannot initialize kvm interface\n"); return FALSE; } pinfo = kvm_getprocs(kvm_handle, KERN_PROC_ALL, 0, &treesize); if (!pinfo || (treesize < 1)) { LogError("system statistic error -- cannot get process tree\n"); kvm_close(kvm_handle); return FALSE; } pt = xcalloc(sizeof(ProcessTree_T), treesize); for (i = 0; i < treesize; i++) { int j, flags; char *procname = NULL; char **args; Buffer_T cmdline; memset(&cmdline, 0, sizeof(Buffer_T)); #if (__FreeBSD_version > 500000) pt[i].pid = pinfo[i].ki_pid; pt[i].ppid = pinfo[i].ki_ppid; pt[i].starttime = pinfo[i].ki_start.tv_sec; pt[i].cputime = (long)(pinfo[i].ki_runtime / 100000); pt[i].mem_kbyte = (unsigned long)(pinfo[i].ki_rssize * pagesize_kbyte); flags = pinfo[i].ki_stat; args = kvm_getargv(kvm_handle, &pinfo[i], 0); procname = pinfo[i].ki_comm; #else pt[i].pid = pinfo[i].kp_proc.p_pid; pt[i].ppid = pinfo[i].kp_eproc.e_ppid; pt[i].starttime = pinfo[i].kp_eproc.e_stats.p_start.tv_sec; pt[i].cputime = (long)(pinfo[i].kp_proc.p_runtime / 100000); pt[i].mem_kbyte = (unsigned long)(pinfo[i].kp_eproc.e_vm.vm_rssize * pagesize_kbyte); flags = pinfo[i].kp_proc.p_stat; args = kvm_getargv(kvm_handle, &pinfo[i], 0); procname = pinfo[i].kp_proc.p_comm; #endif if (flags == SZOMB) pt[i].status_flag |= PROCESS_ZOMBIE; pt[i].cpu_percent = 0; pt[i].time = get_float_time(); if (args) { for (j = 0; args[j]; j++) Util_stringbuffer(&cmdline, args[j + 1] ? "%s " : "%s", args[j]); pt[i].cmdline = cmdline.buf; } if (! pt[i].cmdline || ! *pt[i].cmdline) pt[i].cmdline = xstrdup(procname); } *reference = pt; kvm_close(kvm_handle); return treesize; }
/** * Read all processes to initialize the information tree. * @param reference reference of ProcessTree * @return treesize > 0 if succeeded otherwise = 0. */ int initprocesstree_sysdep(ProcessTree_T **reference) { int i; int treesize; char buf[_POSIX2_LINE_MAX]; size_t size = sizeof(maxslp); int mib_proc2[6] = {CTL_KERN, KERN_PROC2, KERN_PROC_KTHREAD, 0, sizeof(struct kinfo_proc2), 0}; static int mib_maxslp[] = {CTL_VM, VM_MAXSLP}; ProcessTree_T *pt; kvm_t *kvm_handle; static struct kinfo_proc2 *pinfo; if (sysctl(mib_maxslp, 2, &maxslp, &size, NULL, 0) < 0) { LogError("system statistic error -- vm.maxslp failed"); return FALSE; } if (sysctl(mib_proc2, 6, NULL, &size, NULL, 0) == -1) { LogError("system statistic error -- kern.proc2 #1 failed"); return FALSE; } size *= 2; // Add reserve for new processes which were created between calls of sysctl pinfo = xcalloc(1, size); mib_proc2[5] = (int)(size / sizeof(struct kinfo_proc2)); if (sysctl(mib_proc2, 6, pinfo, &size, NULL, 0) == -1) { FREE(pinfo); LogError("system statistic error -- kern.proc2 #2 failed"); return FALSE; } treesize = (int)(size / sizeof(struct kinfo_proc2)); pt = xcalloc(sizeof(ProcessTree_T), treesize); if (! (kvm_handle = kvm_openfiles(NULL, NULL, NULL, KVM_NO_FILES, buf))) { LogError("system statistic error -- kvm_openfiles failed: %s", buf); return FALSE; } for (i = 0; i < treesize; i++) { int j; char **args; Buffer_T cmdline; pt[i].pid = pinfo[i].p_pid; pt[i].ppid = pinfo[i].p_ppid; pt[i].starttime = pinfo[i].p_ustart_sec; pt[i].cputime = (long)((pinfo[i].p_rtime_sec * 10) + (pinfo[i].p_rtime_usec / 100000)); pt[i].cpu_percent = 0; pt[i].mem_kbyte = (unsigned long)(pinfo[i].p_vm_rssize * pagesize_kbyte); if (pinfo[i].p_stat == SZOMB) pt[i].status_flag |= PROCESS_ZOMBIE; //FIXME: save system service flag too (kernel threads) pt[i].time = get_float_time(); memset(&cmdline, 0, sizeof(Buffer_T)); if ((args = kvm_getargv2(kvm_handle, &pinfo[i], 0))) { for (j = 0; args[j]; j++) Util_stringbuffer(&cmdline, args[j + 1] ? "%s " : "%s", args[j]); pt[i].cmdline = cmdline.buf; } if (! pt[i].cmdline || ! *pt[i].cmdline) pt[i].cmdline = xstrdup(pinfo[i].p_comm); } FREE(pinfo); kvm_close(kvm_handle); *reference = pt; return treesize; }
/** * 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); }
/** * 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; }