Skip to content

A column for LXC and LXD containers #216

Description

@jb-boin

There was already an issue on the original project about that : hishamhm/htop#328

I did a simple patch to add the feature but it's not clean enough for a PR request at the moment.

I updated the patch to run on htop 3.0.2, tested on Debian Buster with LXC containers (/lxc/$NAME) and Ubuntu 20.04 with LXD containers with LXC 3 (/lxc.payload/$NAME) and also with LXC 4 (/lxc.payload.$NAME) :

--- htop-3.0.2.orig/linux/LinuxProcess.c	2020-09-15 08:00:00.000000000 +0200
+++ htop-3.0.2/linux/LinuxProcess.c	2020-10-05 18:12:51.157239834 +0200
@@ -96,6 +96,7 @@
 #endif
 #ifdef HAVE_CGROUP
    [CGROUP] = { .name = "CGROUP", .title = "    CGROUP ", .description = "Which cgroup the process is in", .flags = PROCESS_FLAG_LINUX_CGROUP, },
+   [LXC] = { .name = "LXC", .title = "       LXC ", .description = "Which LXC constainer the process is in", .flags = PROCESS_FLAG_LINUX_CGROUP, },
 #endif
    [OOM] = { .name = "OOM", .title = " OOM ", .description = "OOM (Out-of-Memory) killer score", .flags = PROCESS_FLAG_LINUX_OOM, },
    [IO_PRIORITY] = { .name = "IO_PRIORITY", .title = "IO ", .description = "I/O priority", .flags = PROCESS_FLAG_LINUX_IOPRIO, },
@@ -145,6 +146,7 @@
    Process_done((Process*)cast);
 #ifdef HAVE_CGROUP
    free(this->cgroup);
+   free(this->lxc);
 #endif
    free(this->ttyDevice);
    free(this);
@@ -251,6 +253,7 @@
    #endif
    #ifdef HAVE_CGROUP
    case CGROUP: xSnprintf(buffer, n, "%-10s ", lp->cgroup); break;
+   case LXC:    xSnprintf(buffer, n, "%-10s ", lp->lxc); break;
    #endif
    case OOM: xSnprintf(buffer, n, "%4u ", lp->oom); break;
    case IO_PRIORITY: {
@@ -346,6 +349,8 @@
    #ifdef HAVE_CGROUP
    case CGROUP:
       return strcmp(p1->cgroup ? p1->cgroup : "", p2->cgroup ? p2->cgroup : "");
+   case LXC:
+      return strcmp(p1->lxc ? p1->lxc : "", p2->lxc ? p2->lxc : "");
    #endif
    case OOM:
       return ((int)p2->oom - (int)p1->oom);
--- htop-3.0.2.orig/linux/LinuxProcess.h	2020-09-15 08:00:00.000000000 +0200
+++ htop-3.0.2/linux/LinuxProcess.h	2020-10-05 18:08:53.635160688 +0200
@@ -69,6 +69,7 @@
    #endif
    #ifdef HAVE_CGROUP
    CGROUP = 113,
+   LXC = 122,
    #endif
    OOM = 114,
    IO_PRIORITY = 115,
@@ -80,7 +81,7 @@
    M_PSS = 119,
    M_SWAP = 120,
    M_PSSWP = 121,
-   LAST_PROCESSFIELD = 122,
+   LAST_PROCESSFIELD = 123,
 } LinuxProcessField;
 
 #include "IOPriority.h"
@@ -126,6 +127,7 @@
    #endif
    #ifdef HAVE_CGROUP
    char* cgroup;
+   char* lxc;
    #endif
    unsigned int oom;
    char* ttyDevice;
--- htop-3.0.2.orig/linux/LinuxProcessList.c	2020-09-15 08:00:00.000000000 +0200
+++ htop-3.0.2/linux/LinuxProcessList.c	2020-10-05 19:06:33.511649423 +0200
@@ -520,6 +520,33 @@
       if (!ok) break;
       char* group = strchr(buffer, ':');
       if (!group) break;
+
+      if (!process->lxc) {
+         // Each line have 3 columns separated by a ':', the 3rd column contains the pathname
+         char* groupPathname = strchr(group + 1, ':') + 1;
+         if (groupPathname) {
+            if ( String_startsWith(groupPathname, "/lxc.payload/") || String_startsWith(groupPathname, "/lxc.payload.") ) {
+               // The process is inside a LXC container using CGroup V2 (/lxc.payload.) or a modern CGroup V1 terminology (/lxc.payload/), for a better readability, only the container name is kept
+               char *slashpostion = strchr((groupPathname + 13), '/');
+               if (slashpostion) {
+                  // There is a '/' in the CGroup string (after the initial "/lxc.payload"), a '\0' will truncate the string at this position
+                  groupPathname[(slashpostion - groupPathname)] = '\0';
+               }
+               free(process->lxc);
+               process->lxc = xStrdup(String_trim(groupPathname + 13));
+            } else if (String_startsWith(groupPathname, "/lxc/")) {
+               // The process is inside a LXC container using a legacy CGroup V1 (/lxc/), for a better readability, only the container name is kept
+               char *slashpostion = strchr((groupPathname + 5), '/');
+               if (slashpostion) {
+                  // There is a '/' in the CGroup string (after the initial "/lxc/"), a '\0' will truncate the string at this position
+                  groupPathname[(slashpostion - groupPathname)] = '\0';
+               }
+               free(process->lxc);
+               process->lxc = xStrdup(String_trim(groupPathname + 5));
+            }
+         }
+      }
+
       if (at != output) {
          *at = ';';
          at++;
@@ -529,6 +556,12 @@
       left -= wrote;
    }
    fclose(file);
+   if (!process->lxc) {
+      // The process is not in a LXC container
+      free(process->lxc);
+      // To show an empty value instead of (null)
+      process->lxc = xStrdup("");
+   }
    free(process->cgroup);
    process->cgroup = xStrdup(output);
 }

The test packages working in both Debian Buster and Ubuntu 20.04 are available at http://jbboin.phpnet.org/htop/

Metadata

Metadata

Assignees

No one assigned

    Labels

    Containers 📦Light-weight virtualization suitesLinux 🐧Linux related issues

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions