This replaces the old 600-openvz-veid-on-kernels-gt-2.6.18.patch Source: https://patch-diff.githubusercontent.com/raw/hishamhm/htop/pull/464.patch From: Alexander Pisarev Date: Wed, 6 Apr 2016 14:47:28 +0300 Subject: [PATCH] Add support of UUID CTID used in the new version of OpenVZ In the new version of OpenVZ (Virtuozzo 7), containers could be identified by UUIDs and integer numbers like before (so called legacy CTID). Existing support of OpenVZ can't work with UUIDs. This patch fix it. CTIDs and VPIDs are now read from /proc/[id]/status instead of /proc/[id]/stat because of the following reasons: * the /proc/[id]/status has named fields and OpenVZ kernel writes either CTID or UUID to envID field (depending on which type is used); * OpenVZ kernel appends own data to /proc/[id]/stat file, a change in parameters reported by vanilla kernel would also shift the position of OpenVZ data so it would not be read correctly. As UUIDs are much longer than old numerical CTIDs, the UUID strings will get truncated in output (although sorting is still done using complete UUIDs). --- linux/LinuxProcess.c | 9 ++++++--- linux/LinuxProcess.h | 2 +- linux/LinuxProcessList.c | 38 +++++++++++++++++++++++--------------- 3 files changed, 30 insertions(+), 19 deletions(-) --- a/linux/LinuxProcess.c +++ b/linux/LinuxProcess.c @@ -119,7 +119,7 @@ double io_rate_write_bps; #endif #ifdef HAVE_OPENVZ - unsigned int ctid; + char* ctid; unsigned int vpid; #endif #ifdef HAVE_VSERVER @@ -271,6 +271,9 @@ void Process_delete(Object* cast) { LinuxProcess* this = (LinuxProcess*) cast; Process_done((Process*)cast); +#ifdef HAVE_OPENVZ + free(this->ctid); +#endif #ifdef HAVE_CGROUP free(this->cgroup); #endif @@ -361,7 +364,7 @@ } #endif #ifdef HAVE_OPENVZ - case CTID: xSnprintf(buffer, n, "%7u ", lp->ctid); break; + case CTID: xSnprintf(buffer, n, "%8.8s ", lp->ctid); break; case VPID: xSnprintf(buffer, n, Process_pidFormat, lp->vpid); break; #endif #ifdef HAVE_VSERVER @@ -441,7 +444,7 @@ #endif #ifdef HAVE_OPENVZ case CTID: - return (p2->ctid - p1->ctid); + return strcmp(p1->ctid ?: "", p2->ctid ?: ""); case VPID: return (p2->vpid - p1->vpid); #endif --- a/linux/LinuxProcess.h +++ b/linux/LinuxProcess.h @@ -111,7 +111,7 @@ double io_rate_write_bps; #endif #ifdef HAVE_OPENVZ - unsigned int ctid; + char* ctid; unsigned int vpid; #endif #ifdef HAVE_VSERVER --- a/linux/LinuxProcessList.c +++ b/linux/LinuxProcessList.c @@ -480,27 +480,35 @@ #ifdef HAVE_OPENVZ static void LinuxProcessList_readOpenVZData(LinuxProcess* process, const char* dirname, const char* name) { - if ( (access("/proc/vz", R_OK) != 0)) { - process->vpid = process->super.pid; - process->ctid = 0; + process->vpid = process->super.pid; + free(process->ctid); + process->ctid = xStrdup("0"); + if ( (access("/proc/vz", R_OK) != 0)) return; - } char filename[MAX_NAME+1]; - xSnprintf(filename, MAX_NAME, "%s/%s/stat", dirname, name); + xSnprintf(filename, MAX_NAME, "%s/%s/status", dirname, name); FILE* file = fopen(filename, "r"); if (!file) return; - (void) fscanf(file, - "%*32u %*32s %*1c %*32u %*32u %*32u %*32u %*32u %*32u %*32u " - "%*32u %*32u %*32u %*32u %*32u %*32u %*32u %*32u " - "%*32u %*32u %*32u %*32u %*32u %*32u %*32u %*32u " - "%*32u %*32u %*32u %*32u %*32u %*32u %*32u %*32u " - "%*32u %*32u %*32u %*32u %*32u %*32u %*32u %*32u " - "%*32u %*32u %*32u %*32u %*32u %*32u %*32u " - "%*32u %*32u %32u %32u", - &process->vpid, &process->ctid); + char buffer[PROC_LINE_LENGTH + 1]; + while (fgets(buffer, PROC_LINE_LENGTH, file)) { + if (String_startsWith(buffer, "envID:")) { + char ctid[PROC_LINE_LENGTH + 1]; + int ok = sscanf(buffer, "envID:\t%36s", ctid); + if (ok == 1) { + free(process->ctid); + process->ctid = xStrdup(ctid); + } + } + else if (String_startsWith(buffer, "VPid:")) { + unsigned int vpid; + int ok = sscanf(buffer, "VPid:\t%32u", &vpid); + if (ok == 1) { + process->vpid = vpid; + } + } + } fclose(file); - return; } #endif