mirror of https://github.com/xzeldon/htop.git
Support for cgroups (thanks to Guillaume Zitta and Daniel Lezcano)
This commit is contained in:
parent
b2fee47a14
commit
84ed4c01f6
|
@ -4,6 +4,8 @@ What's new in version 0.8.4
|
||||||
* Add support for "steal"/guest CPU time measurement
|
* Add support for "steal"/guest CPU time measurement
|
||||||
in virtualization environments
|
in virtualization environments
|
||||||
* Expand and collapse subtrees using '+' and '-' when in tree-view
|
* Expand and collapse subtrees using '+' and '-' when in tree-view
|
||||||
|
* Support for cgroups
|
||||||
|
(thanks to Guillaume Zitta and Daniel Lezcano)
|
||||||
* Show custom thread names
|
* Show custom thread names
|
||||||
(thanks to Anders Torger)
|
(thanks to Anders Torger)
|
||||||
* Add support for STARTTIME field
|
* Add support for STARTTIME field
|
||||||
|
|
26
Process.c
26
Process.c
|
@ -63,6 +63,9 @@ typedef enum ProcessField_ {
|
||||||
#ifdef HAVE_TASKSTATS
|
#ifdef HAVE_TASKSTATS
|
||||||
RCHAR, WCHAR, SYSCR, SYSCW, RBYTES, WBYTES, CNCLWB, IO_READ_RATE, IO_WRITE_RATE, IO_RATE,
|
RCHAR, WCHAR, SYSCR, SYSCW, RBYTES, WBYTES, CNCLWB, IO_READ_RATE, IO_WRITE_RATE, IO_RATE,
|
||||||
#endif
|
#endif
|
||||||
|
#ifdef HAVE_CGROUP
|
||||||
|
CGROUP,
|
||||||
|
#endif
|
||||||
LAST_PROCESSFIELD
|
LAST_PROCESSFIELD
|
||||||
} ProcessField;
|
} ProcessField;
|
||||||
|
|
||||||
|
@ -153,6 +156,9 @@ typedef struct Process_ {
|
||||||
double io_rate_write_bps;
|
double io_rate_write_bps;
|
||||||
unsigned long long io_rate_write_time;
|
unsigned long long io_rate_write_time;
|
||||||
#endif
|
#endif
|
||||||
|
#ifdef HAVE_CGROUP
|
||||||
|
char* cgroup;
|
||||||
|
#endif
|
||||||
} Process;
|
} Process;
|
||||||
|
|
||||||
}*/
|
}*/
|
||||||
|
@ -182,6 +188,9 @@ const char *Process_fieldNames[] = {
|
||||||
"RCHAR", "WCHAR", "SYSCR", "SYSCW", "RBYTES", "WBYTES", "CNCLWB",
|
"RCHAR", "WCHAR", "SYSCR", "SYSCW", "RBYTES", "WBYTES", "CNCLWB",
|
||||||
"IO_READ_RATE", "IO_WRITE_RATE", "IO_RATE",
|
"IO_READ_RATE", "IO_WRITE_RATE", "IO_RATE",
|
||||||
#endif
|
#endif
|
||||||
|
#ifdef HAVE_CGROUP
|
||||||
|
"CGROUP",
|
||||||
|
#endif
|
||||||
"*** report bug! ***"
|
"*** report bug! ***"
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -204,6 +213,10 @@ const char *Process_fieldTitles[] = {
|
||||||
" RD_CHAR ", " WR_CHAR ", " RD_SYSC ", " WR_SYSC ", " IO_RBYTES ", " IO_WBYTES ", " IO_CANCEL ",
|
" RD_CHAR ", " WR_CHAR ", " RD_SYSC ", " WR_SYSC ", " IO_RBYTES ", " IO_WBYTES ", " IO_CANCEL ",
|
||||||
" IORR ", " IOWR ", " IO ",
|
" IORR ", " IOWR ", " IO ",
|
||||||
#endif
|
#endif
|
||||||
|
#ifdef HAVE_CGROUP
|
||||||
|
" CGROUP ",
|
||||||
|
#endif
|
||||||
|
"*** report bug! ***"
|
||||||
};
|
};
|
||||||
|
|
||||||
static int Process_getuid = -1;
|
static int Process_getuid = -1;
|
||||||
|
@ -426,6 +439,9 @@ static void Process_writeField(Process* this, RichString* str, ProcessField fiel
|
||||||
case IO_WRITE_RATE: Process_outputRate(this, str, attr, buffer, n, this->io_rate_write_bps); return;
|
case IO_WRITE_RATE: Process_outputRate(this, str, attr, buffer, n, this->io_rate_write_bps); return;
|
||||||
case IO_RATE: Process_outputRate(this, str, attr, buffer, n, this->io_rate_read_bps + this->io_rate_write_bps); return;
|
case IO_RATE: Process_outputRate(this, str, attr, buffer, n, this->io_rate_read_bps + this->io_rate_write_bps); return;
|
||||||
#endif
|
#endif
|
||||||
|
#ifdef HAVE_CGROUP
|
||||||
|
case CGROUP: snprintf(buffer, n, "%-10s ", this->cgroup); break;
|
||||||
|
#endif
|
||||||
|
|
||||||
default:
|
default:
|
||||||
snprintf(buffer, n, "- ");
|
snprintf(buffer, n, "- ");
|
||||||
|
@ -450,6 +466,9 @@ void Process_delete(Object* cast) {
|
||||||
Process* this = (Process*) cast;
|
Process* this = (Process*) cast;
|
||||||
assert (this != NULL);
|
assert (this != NULL);
|
||||||
if (this->comm) free(this->comm);
|
if (this->comm) free(this->comm);
|
||||||
|
#ifdef HAVE_CGROUP
|
||||||
|
if (this->cgroup) free(this->cgroup);
|
||||||
|
#endif
|
||||||
free(this);
|
free(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -467,6 +486,9 @@ Process* Process_new(struct ProcessList_ *pl) {
|
||||||
this->stime = 0;
|
this->stime = 0;
|
||||||
this->comm = NULL;
|
this->comm = NULL;
|
||||||
this->indent = 0;
|
this->indent = 0;
|
||||||
|
#ifdef HAVE_CGROUP
|
||||||
|
this->cgroup = NULL;
|
||||||
|
#endif
|
||||||
if (Process_getuid == -1) Process_getuid = getuid();
|
if (Process_getuid == -1) Process_getuid = getuid();
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
@ -590,6 +612,10 @@ int Process_compare(const void* v1, const void* v2) {
|
||||||
case IO_WRITE_RATE: diff = p2->io_rate_write_bps - p1->io_rate_write_bps; goto test_diff;
|
case IO_WRITE_RATE: diff = p2->io_rate_write_bps - p1->io_rate_write_bps; goto test_diff;
|
||||||
case IO_RATE: diff = (p2->io_rate_read_bps + p2->io_rate_write_bps) - (p1->io_rate_read_bps + p1->io_rate_write_bps); goto test_diff;
|
case IO_RATE: diff = (p2->io_rate_read_bps + p2->io_rate_write_bps) - (p1->io_rate_read_bps + p1->io_rate_write_bps); goto test_diff;
|
||||||
#endif
|
#endif
|
||||||
|
#ifdef HAVE_CGROUP
|
||||||
|
case CGROUP:
|
||||||
|
return strcmp(p1->cgroup ? p1->cgroup : "", p2->cgroup ? p2->cgroup : "");
|
||||||
|
#endif
|
||||||
|
|
||||||
default:
|
default:
|
||||||
return (p1->pid - p2->pid);
|
return (p1->pid - p2->pid);
|
||||||
|
|
|
@ -642,6 +642,26 @@ static bool ProcessList_processEntries(ProcessList* this, const char* dirname, P
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef HAVE_CGROUP
|
||||||
|
snprintf(statusfilename, MAX_NAME, "%s/%s/cgroup", dirname, name);
|
||||||
|
status = ProcessList_fopen(this, statusfilename, "r");
|
||||||
|
if (status) {
|
||||||
|
char buffer[256];
|
||||||
|
char *ok = fgets(buffer, 255, status);
|
||||||
|
if (ok) {
|
||||||
|
char* trimmed = String_trim(buffer);
|
||||||
|
char** fields = String_split(trimmed, ':');
|
||||||
|
free(trimmed);
|
||||||
|
|
||||||
|
char* value = String_cat(fields[2], " ");
|
||||||
|
String_freeArray(fields);
|
||||||
|
process->cgroup = strndup(value + 1, 10);
|
||||||
|
free(value);
|
||||||
|
}
|
||||||
|
fclose(status);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef HAVE_VSERVER
|
#ifdef HAVE_VSERVER
|
||||||
snprintf(statusfilename, MAX_NAME, "%s/%s/status", dirname, name);
|
snprintf(statusfilename, MAX_NAME, "%s/%s/status", dirname, name);
|
||||||
status = ProcessList_fopen(this, statusfilename, "r");
|
status = ProcessList_fopen(this, statusfilename, "r");
|
||||||
|
|
|
@ -69,6 +69,11 @@ if test "x$enable_openvz" = xyes; then
|
||||||
AC_DEFINE(HAVE_OPENVZ, 1, [Define if openvz support enabled.])
|
AC_DEFINE(HAVE_OPENVZ, 1, [Define if openvz support enabled.])
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
AC_ARG_ENABLE(cgroup, [AC_HELP_STRING([--enable-cgroup], [enable cgroups support])], ,enable_cgroup="no")
|
||||||
|
if test "x$enable_cgroup" = xyes; then
|
||||||
|
AC_DEFINE(HAVE_CGROUP, 1, [Define if cgroup support enabled.])
|
||||||
|
fi
|
||||||
|
|
||||||
AC_ARG_ENABLE(vserver, [AC_HELP_STRING([--enable-vserver], [enable VServer support])], ,enable_vserver="no")
|
AC_ARG_ENABLE(vserver, [AC_HELP_STRING([--enable-vserver], [enable VServer support])], ,enable_vserver="no")
|
||||||
if test "x$enable_vserver" = xyes; then
|
if test "x$enable_vserver" = xyes; then
|
||||||
AC_DEFINE(HAVE_VSERVER, 1, [Define if vserver support enabled.])
|
AC_DEFINE(HAVE_VSERVER, 1, [Define if vserver support enabled.])
|
||||||
|
|
|
@ -14,4 +14,4 @@
|
||||||
|
|
||||||
SUBDIRS = src
|
SUBDIRS = src
|
||||||
DIST_SUBDIRS = $(SUBDIRS)
|
DIST_SUBDIRS = $(SUBDIRS)
|
||||||
EXTRA_DIST = README VERSION LICENSE AUTHORS autogen.sh
|
EXTRA_DIST = README VERSION LICENSE AUTHORS
|
||||||
|
|
Loading…
Reference in New Issue