]> git.ipfire.org Git - thirdparty/util-linux.git/commitdiff
lsclocks: add NS_OFFSET column
authorThomas Weißschuh <thomas@t-8ch.de>
Fri, 30 Jun 2023 20:23:55 +0000 (22:23 +0200)
committerThomas Weißschuh <thomas@t-8ch.de>
Mon, 10 Jul 2023 11:41:39 +0000 (13:41 +0200)
Signed-off-by: Thomas Weißschuh <thomas@t-8ch.de>
include/pathnames.h
misc-utils/lsclocks.1.adoc
misc-utils/lsclocks.c

index 56f64c3870e9ebac06a2d64d960534fa0db347a2..074b4d8ed4ef70c4b2276b3c9a628edae4a61a70 100644 (file)
 #define _PATH_PROC_SETGROUPS   "/proc/self/setgroups"
 
 #define _PATH_PROC_FDDIR       "/proc/self/fd"
+#define _PATH_PROC_TIMENS_OFF   "/proc/self/timens_offsets"
 
 #define _PATH_PROC_ATTR_CURRENT        "/proc/self/attr/current"
 #define _PATH_PROC_ATTR_EXEC   "/proc/self/attr/exec"
index e5d1142d9d70c586379e7a29c624efb508ceacad..4024c93e4b9178f11de8e81f276778ff3ad5352b 100644 (file)
@@ -72,6 +72,9 @@ Human readable version of *RESOL_RAW*.
 REL_TIME <``string``>::
 *TIME* time formatted as time range.
 
+NS_OFFSET <``number``>::
+Offset of the current namespace to the parent namespace as read from */proc/self/timens_offsets*.
+
 
 == AUTHORS
 
index a41c51b2fe8210621bebfce9553ba4f144231ac3..dd6fedda71d0a040496992458573f4cdfdd0d765 100644 (file)
@@ -32,6 +32,8 @@
 #include "timeutils.h"
 #include "closestream.h"
 #include "xalloc.h"
+#include "pathnames.h"
+#include "all-io.h"
 
 #define CLOCKFD 3
 #define FD_TO_CLOCKID(fd) ((~(clockid_t) (fd) << 3) | CLOCKFD)
@@ -76,15 +78,18 @@ struct clockinfo {
        clockid_t id;
        const char * const id_name;
        const char * const name;
+       const char * const ns_offset_name;
 };
 
 static const struct clockinfo clocks[] = {
        { CLOCK_REALTIME,         "CLOCK_REALTIME",         "realtime"         },
-       { CLOCK_MONOTONIC,        "CLOCK_MONOTONIC",        "monotonic"        },
+       { CLOCK_MONOTONIC,        "CLOCK_MONOTONIC",        "monotonic",
+         .ns_offset_name = "monotonic"                                        },
        { CLOCK_MONOTONIC_RAW,    "CLOCK_MONOTONIC_RAW",    "monotonic-raw"    },
        { CLOCK_REALTIME_COARSE,  "CLOCK_REALTIME_COARSE",  "realtime-coarse"  },
        { CLOCK_MONOTONIC_COARSE, "CLOCK_MONOTONIC_COARSE", "monotonic-coarse" },
-       { CLOCK_BOOTTIME,         "CLOCK_BOOTTIME",         "boottime"         },
+       { CLOCK_BOOTTIME,         "CLOCK_BOOTTIME",         "boottime",
+         .ns_offset_name = "boottime"                                         },
        { CLOCK_REALTIME_ALARM,   "CLOCK_REALTIME_ALARM",   "realtime-alarm"   },
        { CLOCK_BOOTTIME_ALARM,   "CLOCK_BOOTTIME_ALARM",   "boottime-alarm"   },
        { CLOCK_TAI,              "CLOCK_TAI",              "tai"              },
@@ -100,6 +105,7 @@ enum {
        COL_RESOL,
        COL_RESOL_RAW,
        COL_REL_TIME,
+       COL_NS_OFFSET,
 };
 
 /* column names */
@@ -121,6 +127,7 @@ static const struct colinfo infos[] = {
        [COL_RESOL]      = { "RESOL",      1, SCOLS_FL_RIGHT, SCOLS_JSON_STRING, N_("human readable resolution") },
        [COL_RESOL_RAW]  = { "RESOL_RAW",  1, SCOLS_FL_RIGHT, SCOLS_JSON_NUMBER, N_("resolution") },
        [COL_REL_TIME]   = { "REL_TIME",   1, SCOLS_FL_RIGHT, SCOLS_JSON_STRING, N_("human readable relative time") },
+       [COL_NS_OFFSET]  = { "NS_OFFSET",  1, SCOLS_FL_RIGHT, SCOLS_JSON_NUMBER, N_("namespace offset") },
 };
 
 static int column_name_to_id(const char *name, size_t namesz)
@@ -210,6 +217,38 @@ static clockid_t parse_clock(const char *name)
        errx(EXIT_FAILURE, _("Unknown clock: %s"), name);
 }
 
+static int64_t get_namespace_offset(const char *name)
+{
+       char *tokstr, *buf, *saveptr, *line, *space;
+       uint64_t ret;
+       int fd;
+
+       fd = open(_PATH_PROC_TIMENS_OFF, O_RDONLY);
+       if (fd == -1)
+               err(EXIT_FAILURE, _("Could not open %s"), _PATH_PROC_TIMENS_OFF);
+
+       read_all_alloc(fd, &buf);
+
+       for (tokstr = buf; ; tokstr = NULL) {
+               line = strtok_r(tokstr, "\n", &saveptr);
+               if (!line)
+                       continue;
+               line = (char *) startswith(line, name);
+               if (!line || line[0] != ' ')
+                       continue;
+
+               line = (char *) skip_blank(line);
+               space = strchr(line, ' ');
+               if (space)
+                       *space = '\0';
+               ret = strtos64_or_err(line, _("Invalid offset"));
+               break;
+       }
+
+       free(buf);
+       return ret;
+}
+
 int main(int argc, char **argv)
 {
        size_t i, j;
@@ -386,6 +425,11 @@ int main(int argc, char **argv)
                                                errx(EXIT_FAILURE, _("failed to format relative time"));
                                        scols_line_set_data(ln, j, buf);
                                        break;
+                               case COL_NS_OFFSET:
+                                       if (clockinfo->ns_offset_name)
+                                               scols_line_asprintf(ln, j, "%"PRId64,
+                                                                   get_namespace_offset(clockinfo->ns_offset_name));
+                                       break;
                        }
                }
        }