]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
MINOR: debug: add distro name and version in postmortem
authorValentine Krasnobaeva <vkrasnobaeva@haproxy.com>
Thu, 10 Jul 2025 08:59:57 +0000 (10:59 +0200)
committerWilly Tarreau <w@1wt.eu>
Fri, 11 Jul 2025 09:48:19 +0000 (11:48 +0200)
Since 2012, systemd compliant distributions contain
/etc/os-release file. This file has some standardized format, see details at
https://www.freedesktop.org/software/systemd/man/latest/os-release.html.

Let's read it in feed_post_mortem_linux() to gather more info about the
distribution.

(cherry picked from commit f1594c41368baf8f60737b229e4359fa7e1289a9)
Signed-off-by: Willy Tarreau <w@1wt.eu>
include/haproxy/defaults.h
src/debug.c

index 4e012775a9208877df2a4b8832939e445700175b..f3e357ecfae89a2e817ca0466a0a10f9e8fa46cc 100644 (file)
 // via standard input.
 #define MAX_CFG_SIZE   10485760
 
+// may be handy for some system config files, where we just need to find
+// some specific values (read with fgets)
+#define MAX_LINES_TO_READ 32
+
 // max # args on a configuration line
 #define MAX_LINE_ARGS   64
 
index aede2c730348099600cd3969f71ca1242da7db15..bbd63bf9cd035eff00db98b8411a363676401bf8 100644 (file)
@@ -103,6 +103,7 @@ struct post_mortem {
        char post_mortem_magic[32];     // "POST-MORTEM STARTS HERE+7654321\0"
        struct {
                struct utsname utsname; // OS name+ver+arch+hostname
+               char distro[64];        // Distro name and version from os-release file if exists
                char hw_vendor[64];     // hardware/hypervisor vendor when known
                char hw_family[64];     // hardware/hypervisor product family when known
                char hw_model[64];      // hardware/hypervisor product/model when known
@@ -688,6 +689,8 @@ static int debug_parse_cli_show_dev(char **args, char *payload, struct appctx *a
                chunk_appendf(&trash, "  OS architecture: %s\n", post_mortem.platform.utsname.machine);
        if (*post_mortem.platform.utsname.nodename)
                chunk_appendf(&trash, "  node name: %s\n", HA_ANON_CLI(post_mortem.platform.utsname.nodename));
+       if (*post_mortem.platform.distro)
+               chunk_appendf(&trash, "  distro pretty name: %s\n", HA_ANON_CLI(post_mortem.platform.distro));
 
        chunk_appendf(&trash, "Process info\n");
        chunk_appendf(&trash, "  pid: %d\n", post_mortem.process.pid);
@@ -2770,6 +2773,12 @@ static void feed_post_mortem_linux()
 
 static int feed_post_mortem()
 {
+       FILE *file;
+       struct stat statbuf;
+       char line[64];
+       char file_path[32];
+       int line_cnt = 0;
+
        /* write an easily identifiable magic at the beginning of the struct */
        strncpy(post_mortem.post_mortem_magic,
                "POST-MORTEM STARTS HERE+7654321\0",
@@ -2777,6 +2786,49 @@ static int feed_post_mortem()
        /* kernel type, version and arch */
        uname(&post_mortem.platform.utsname);
 
+       /* try to find os-release file, this may give the current minor version of
+        * distro if it was recently updated.
+        */
+       snprintf(file_path, sizeof(file_path), "%s", "/etc/os-release");
+       if (stat(file_path, &statbuf) != 0) {
+               /* fallback to "/usr/lib/os-release" */
+               snprintf(file_path, sizeof(file_path), "%s", "/usr/lib/os-release");
+               if (stat(file_path, &statbuf) != 0 ) {
+                       goto process_info;
+               }
+       }
+
+       /* try open and find the line with distro PRETTY_NAME (name + full version) */
+       if ((file = fopen(file_path, "r")) == NULL) {
+               goto process_info;
+       }
+
+       while ((fgets(line, sizeof(post_mortem.platform.distro), file)) && (line_cnt < MAX_LINES_TO_READ)) {
+               line_cnt++;
+               if (strncmp(line, "PRETTY_NAME=", 12) == 0) {
+                       /* cut \n and trim possible quotes */
+                       char *start = line + 12;
+                       char *newline = strchr(start, '\n');
+
+                       if (newline) {
+                               *newline = '\0';
+                       } else {
+                               newline = start + strlen(start);
+                       }
+
+                       /* trim possible quotes */
+                       if (*start == '"')
+                               start++;
+                       if (newline > start && *(newline - 1) == '"')
+                               *(--newline) = '\0';
+
+                       strlcpy2(post_mortem.platform.distro, start, sizeof(post_mortem.platform.distro));
+                       break;
+               }
+       }
+       fclose(file);
+
+process_info:
        /* some boot-time info related to the process */
        post_mortem.process.pid = getpid();
        post_mortem.process.boot_uid = geteuid();