Esempio n. 1
0
/**
 * 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;
  size_t                     size = sizeof(maxslp);
  char                       buf[_POSIX2_LINE_MAX];
  int                        mib_proc2[6] = {CTL_KERN, KERN_PROC2, KERN_PROC_ALL, 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 = CALLOC(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 = CALLOC(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 (int i = 0; i < treesize; i++) {
    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;
    pt[i].time = get_float_time();
    char **args;
    if ((args = kvm_getargv2(kvm_handle, &pinfo[i], 0))) {
      StringBuffer_T cmdline = StringBuffer_create(64);
      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)
      pt[i].cmdline = Str_dup(pinfo[i].p_comm);
  }
  FREE(pinfo);
  kvm_close(kvm_handle);

  *reference = pt;

  return treesize;
}
/**
 * Read all processes to initialize the information 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) {
        size_t size = sizeof(maxslp);
        static int mib_maxslp[] = {CTL_VM, VM_MAXSLP};
        if (sysctl(mib_maxslp, 2, &maxslp, &size, NULL, 0) < 0) {
                LogError("system statistic error -- vm.maxslp failed\n");
                return 0;
        }

        int mib_proc2[6] = {CTL_KERN, KERN_PROC2, KERN_PROC_ALL, 0, sizeof(struct kinfo_proc2), 0};
        if (sysctl(mib_proc2, 6, NULL, &size, NULL, 0) == -1) {
                LogError("system statistic error -- kern.proc2 #1 failed\n");
                return 0;
        }

        size *= 2; // Add reserve for new processes which were created between calls of sysctl
        struct kinfo_proc2 *pinfo = CALLOC(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\n");
                return 0;
        }

        int treesize = (int)(size / sizeof(struct kinfo_proc2));

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

        char buf[_POSIX2_LINE_MAX];
        kvm_t *kvm_handle = kvm_openfiles(NULL, NULL, NULL, KVM_NO_FILES, buf);
        if (! kvm_handle) {
                FREE(pinfo);
                FREE(pt);
                LogError("system statistic error -- kvm_openfiles failed: %s\n", buf);
                return 0;
        }

        StringBuffer_T cmdline = NULL;
        if (pflags & ProcessEngine_CollectCommandLine)
                cmdline = StringBuffer_create(64);
        for (int i = 0; i < treesize; i++) {
                pt[i].pid          = pinfo[i].p_pid;
                pt[i].ppid         = pinfo[i].p_ppid;
                pt[i].cred.uid     = pinfo[i].p_ruid;
                pt[i].cred.euid    = pinfo[i].p_uid;
                pt[i].cred.gid     = pinfo[i].p_rgid;
                pt[i].threads      = pinfo[i].p_nlwps;
                pt[i].uptime       = systeminfo.time / 10. - pinfo[i].p_ustart_sec;
                pt[i].cpu.time     = pinfo[i].p_rtime_sec * 10 + (double)pinfo[i].p_rtime_usec / 100000.;
                pt[i].memory.usage = (uint64_t)pinfo[i].p_vm_rssize * (uint64_t)pagesize;
                pt[i].zombie       = pinfo[i].p_stat == SZOMB ? true : false;
                if (pflags & ProcessEngine_CollectCommandLine) {
                        char **args = kvm_getargv2(kvm_handle, &pinfo[i], 0);
                        if (args) {
                                StringBuffer_clear(cmdline);
                                for (int j = 0; args[j]; j++)
                                        StringBuffer_append(cmdline, args[j + 1] ? "%s " : "%s", args[j]);
                                if (StringBuffer_length(cmdline))
                                        pt[i].cmdline = Str_dup(StringBuffer_toString(StringBuffer_trim(cmdline)));
                        }
                        if (! pt[i].cmdline || ! *pt[i].cmdline) {
                                FREE(pt[i].cmdline);
                                pt[i].cmdline = Str_dup(pinfo[i].p_comm);
                        }
                }
        }
        if (pflags & ProcessEngine_CollectCommandLine)
                StringBuffer_free(&cmdline);
        FREE(pinfo);
        kvm_close(kvm_handle);

        *reference = pt;

        return treesize;
}