summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--freebsd/FreeBSDProcess.c40
-rw-r--r--freebsd/FreeBSDProcessList.c92
2 files changed, 111 insertions, 21 deletions
diff --git a/freebsd/FreeBSDProcess.c b/freebsd/FreeBSDProcess.c
index 43fd88d5..ee542b4d 100644
--- a/freebsd/FreeBSDProcess.c
+++ b/freebsd/FreeBSDProcess.c
@@ -12,6 +12,7 @@ in the source distribution for its full text.
#include "CRT.h"
#include <stdlib.h>
+#include <string.h>
#include <unistd.h>
#include <sys/syscall.h>
@@ -19,15 +20,22 @@ in the source distribution for its full text.
typedef enum FreeBSDProcessFields {
// Add platform-specific fields here, with ids >= 100
- LAST_PROCESSFIELD = 100,
+ JID = 100,
+ JAIL = 101,
+ LAST_PROCESSFIELD = 102,
} FreeBSDProcessField;
+
typedef struct FreeBSDProcess_ {
Process super;
+ int kernel;
+ int jid;
+ char* jname;
} FreeBSDProcess;
+
#ifndef Process_isKernelThread
-#define Process_isKernelThread(_process) (_process->pgrp == 0)
+#define Process_isKernelThread(_process) (_process->kernel == 1)
#endif
#ifndef Process_isUserlandThread
@@ -72,10 +80,13 @@ ProcessFieldData Process_fields[] = {
[TIME] = { .name = "TIME", .title = " TIME+ ", .description = "Total time the process has spent in user and system time", .flags = 0, },
[NLWP] = { .name = "NLWP", .title = "NLWP ", .description = "Number of threads in the process", .flags = 0, },
[TGID] = { .name = "TGID", .title = " TGID ", .description = "Thread group ID (i.e. process ID)", .flags = 0, },
+ [JID] = { .name = "JID", .title = " JID ", .description = "Jail prison ID", .flags = 0, },
+ [JAIL] = { .name = "JAIL", .title = "JAIL ", .description = "Jail prison name", .flags = 0, },
[LAST_PROCESSFIELD] = { .name = "*** report bug! ***", .title = NULL, .description = NULL, .flags = 0, },
};
ProcessPidColumn Process_pidColumns[] = {
+ { .id = JID, .label = "JID" },
{ .id = PID, .label = "PID" },
{ .id = PPID, .label = "PPID" },
{ .id = TPGID, .label = "TPGID" },
@@ -95,16 +106,26 @@ FreeBSDProcess* FreeBSDProcess_new(Settings* settings) {
void Process_delete(Object* cast) {
FreeBSDProcess* this = (FreeBSDProcess*) cast;
Process_done((Process*)cast);
+ free(this->jname);
free(this);
}
void FreeBSDProcess_writeField(Process* this, RichString* str, ProcessField field) {
- //FreeBSDProcess* fp = (FreeBSDProcess*) this;
+ FreeBSDProcess* fp = (FreeBSDProcess*) this;
char buffer[256]; buffer[255] = '\0';
int attr = CRT_colors[DEFAULT_COLOR];
- //int n = sizeof(buffer) - 1;
+ int n = sizeof(buffer) - 1;
switch (field) {
// add FreeBSD-specific fields here
+ case JID: snprintf(buffer, n, Process_pidFormat, fp->jid); break;
+ case JAIL:{
+ snprintf(buffer, n, "%-11s ", fp->jname); break;
+ if (buffer[11] != '\0') {
+ buffer[11] = ' ';
+ buffer[12] = '\0';
+ }
+ break;
+ }
default:
Process_writeField(this, str, field);
return;
@@ -124,11 +145,20 @@ long FreeBSDProcess_compare(const void* v1, const void* v2) {
}
switch (settings->sortKey) {
// add FreeBSD-specific fields here
+ case JID:
+ return (p1->jid - p2->jid);
+ case JAIL:
+ return strcmp(p1->jname ? p1->jname : "", p2->jname ? p2->jname : "");
default:
return Process_compare(v1, v2);
}
}
bool Process_isThread(Process* this) {
- return (Process_isKernelThread(this));
+ FreeBSDProcess* fp = (FreeBSDProcess*) this;
+
+ if (fp->kernel == 1 )
+ return 1;
+ else
+ return (Process_isUserlandThread(this));
}
diff --git a/freebsd/FreeBSDProcessList.c b/freebsd/FreeBSDProcessList.c
index cc51a7cd..54ae7607 100644
--- a/freebsd/FreeBSDProcessList.c
+++ b/freebsd/FreeBSDProcessList.c
@@ -20,6 +20,12 @@ in the source distribution for its full text.
/*{
#include <kvm.h>
+#include <sys/param.h>
+#include <sys/jail.h>
+#include <sys/uio.h>
+
+#define JAIL_ERRMSGLEN 1024
+char jail_errmsg[JAIL_ERRMSGLEN];
typedef struct CPUData_ {
unsigned long long int totalTime;
@@ -58,13 +64,13 @@ ProcessList* ProcessList_new(UsersTable* usersTable, Hashtable* pidWhiteList, ui
fpl->cpus[i].totalTime = 1;
fpl->cpus[i].totalPeriod = 1;
}
-
+
size_t len;
len = 4; sysctlnametomib("vm.stats.vm.v_wire_count", MIB_vm_stats_vm_v_wire_count, &len);
len = 4; sysctlnametomib("vm.stats.vm.v_cache_count", MIB_vm_stats_vm_v_cache_count, &len);
len = 2; sysctlnametomib("hw.physmem", MIB_hw_physmem, &len);
- pageSizeKb = PAGE_SIZE_KB;
-
+ pageSizeKb = PAGE_SIZE_KB;
+
fpl->kd = kvm_open(NULL, "/dev/null", NULL, 0, NULL);
assert(fpl->kd);
@@ -74,14 +80,14 @@ ProcessList* ProcessList_new(UsersTable* usersTable, Hashtable* pidWhiteList, ui
void ProcessList_delete(ProcessList* this) {
const FreeBSDProcessList* fpl = (FreeBSDProcessList*) this;
if (fpl->kd) kvm_close(fpl->kd);
-
+
ProcessList_done(this);
free(this);
}
static inline void FreeBSDProcessList_scanMemoryInfo(ProcessList* pl) {
const FreeBSDProcessList* fpl = (FreeBSDProcessList*) pl;
-
+
size_t len = sizeof(pl->totalMem);
sysctl(MIB_hw_physmem, 2, &(pl->totalMem), &len, NULL, 0);
pl->totalMem /= 1024;
@@ -90,7 +96,7 @@ static inline void FreeBSDProcessList_scanMemoryInfo(ProcessList* pl) {
pl->freeMem = pl->totalMem - pl->usedMem;
sysctl(MIB_vm_stats_vm_v_cache_count, 4, &(pl->cachedMem), &len, NULL, 0);
pl->cachedMem *= pageSizeKb;
-
+
struct kvm_swap swap[16];
int nswap = kvm_getswapinfo(fpl->kd, swap, sizeof(swap)/sizeof(swap[0]), 0);
pl->totalSwap = 0;
@@ -101,7 +107,7 @@ static inline void FreeBSDProcessList_scanMemoryInfo(ProcessList* pl) {
}
pl->totalSwap *= pageSizeKb;
pl->usedSwap *= pageSizeKb;
-
+
pl->sharedMem = 0; // currently unused
pl->buffersMem = 0; // not exposed to userspace
}
@@ -131,27 +137,75 @@ char* FreeBSDProcessList_readProcessName(kvm_t* kd, struct kinfo_proc* kproc, in
return comm;
}
+char* FreeBSDProcessList_readJailName(struct kinfo_proc* kproc) {
+ int jid;
+ struct iovec jiov[6];
+ char* jname;
+ char jnamebuf[MAXHOSTNAMELEN];
+
+ if (kproc->ki_jid != 0 ){
+ memset(jnamebuf, 0, sizeof(jnamebuf));
+ *(const void **)&jiov[0].iov_base = "jid";
+ jiov[0].iov_len = sizeof("jid");
+ jiov[1].iov_base = &kproc->ki_jid;
+ jiov[1].iov_len = sizeof(kproc->ki_jid);
+ *(const void **)&jiov[2].iov_base = "name";
+ jiov[2].iov_len = sizeof("name");
+ jiov[3].iov_base = jnamebuf;
+ jiov[3].iov_len = sizeof(jnamebuf);
+ *(const void **)&jiov[4].iov_base = "errmsg";
+ jiov[4].iov_len = sizeof("errmsg");
+ jiov[5].iov_base = jail_errmsg;
+ jiov[5].iov_len = JAIL_ERRMSGLEN;
+ jail_errmsg[0] = 0;
+ jid = jail_get(jiov, 6, 0);
+ if (jid < 0) {
+ if (!jail_errmsg[0])
+ snprintf(jail_errmsg, JAIL_ERRMSGLEN, "jail_get: %s", strerror(errno));
+ return NULL;
+ } else if (jid == kproc->ki_jid) {
+ jname = strdup(jnamebuf);
+ if (jname == NULL)
+ strerror_r(errno, jail_errmsg, JAIL_ERRMSGLEN);
+ return jname;
+ } else {
+ return NULL;
+ }
+ } else {
+ jnamebuf[0]='-';
+ jnamebuf[1]='\0';
+ jname = strdup(jnamebuf);
+ }
+ return jname;
+}
+
void ProcessList_goThroughEntries(ProcessList* this) {
FreeBSDProcessList* fpl = (FreeBSDProcessList*) this;
Settings* settings = this->settings;
bool hideKernelThreads = settings->hideKernelThreads;
bool hideUserlandThreads = settings->hideUserlandThreads;
-
+
FreeBSDProcessList_scanMemoryInfo(this);
-
+
int count = 0;
struct kinfo_proc* kprocs = kvm_getprocs(fpl->kd, KERN_PROC_ALL, 0, &count);
-
+
for (int i = 0; i < count; i++) {
struct kinfo_proc* kproc = &kprocs[i];
-
+
bool preExisting = false;
Process* proc = ProcessList_getProcess(this, kproc->ki_pid, &preExisting, (Process_New) FreeBSDProcess_new);
FreeBSDProcess* fp = (FreeBSDProcess*) proc;
- proc->show = ! ((hideKernelThreads && Process_isKernelThread(proc)) || (hideUserlandThreads && Process_isUserlandThread(proc)));
-
+ proc->show = ! ((hideKernelThreads && Process_isKernelThread(fp)) || (hideUserlandThreads && Process_isUserlandThread(proc)));
+
if (!preExisting) {
+ fp->jid = kproc->ki_jid;
+ proc->pid = kproc->ki_pid;
+ if ( ! ((kproc->ki_pid == 0) || (kproc->ki_pid == 1) ) && kproc->ki_flag & P_SYSTEM)
+ fp->kernel = 1;
+ else
+ fp->kernel = 0;
proc->ppid = kproc->ki_ppid;
proc->tpgid = kproc->ki_tpgid;
proc->tgid = kproc->ki_pid;
@@ -163,6 +217,7 @@ void ProcessList_goThroughEntries(ProcessList* this) {
proc->user = UsersTable_getRef(this->usersTable, proc->st_uid);
ProcessList_add((ProcessList*)this, proc);
proc->comm = FreeBSDProcessList_readProcessName(fpl->kd, kproc, &proc->basenameOffset);
+ fp->jname = FreeBSDProcessList_readJailName(kproc);
} else {
if (settings->updateProcessNames) {
free(proc->comm);
@@ -174,8 +229,12 @@ void ProcessList_goThroughEntries(ProcessList* this) {
proc->m_resident = kproc->ki_rssize; // * pageSizeKb;
proc->nlwp = kproc->ki_numthreads;
proc->time = (kproc->ki_runtime + 5000) / 10000;
+
proc->priority = kproc->ki_pri.pri_level - PZERO;
- if (kproc->ki_pri.pri_class == PRI_TIMESHARE) {
+
+ if (strcmp("intr", kproc->ki_comm) == 0 && kproc->ki_flag & P_SYSTEM) {
+ proc->nice = 0; //@etosan: freebsd intr kernel process (not thread) has weird nice value
+ } else if (kproc->ki_pri.pri_class == PRI_TIMESHARE) {
proc->nice = kproc->ki_nice - NZERO;
} else if (PRI_IS_REALTIME(kproc->ki_pri.pri_class)) {
proc->nice = PRIO_MIN - 1 - (PRI_MAX_REALTIME - kproc->ki_pri.pri_level);
@@ -183,6 +242,7 @@ void ProcessList_goThroughEntries(ProcessList* this) {
proc->nice = PRIO_MAX + 1 + kproc->ki_pri.pri_level - PRI_MIN_IDLE;
}
+
switch (kproc->ki_stat) {
case SIDL: proc->state = 'I'; break;
case SRUN: proc->state = 'R'; break;
@@ -194,10 +254,10 @@ void ProcessList_goThroughEntries(ProcessList* this) {
default: proc->state = '?';
}
- if (Process_isKernelThread(proc)) {
+ if (Process_isKernelThread(fp)) {
this->kernelThreads++;
}
-
+
this->totalTasks++;
if (proc->state == 'R')
this->runningTasks++;