From: Valentine Krasnobaeva Date: Thu, 10 Jul 2025 08:59:57 +0000 (+0200) Subject: MINOR: debug: add distro name and version in postmortem X-Git-Tag: v3.3-dev3~1 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=0c63883be10e4cd0b898a2a4f60494e4d098559b;p=thirdparty%2Fhaproxy.git MINOR: debug: add distro name and version in postmortem 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 --- diff --git a/include/haproxy/defaults.h b/include/haproxy/defaults.h index 4e012775a..f3e357ecf 100644 --- a/include/haproxy/defaults.h +++ b/include/haproxy/defaults.h @@ -115,6 +115,10 @@ // 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 diff --git a/src/debug.c b/src/debug.c index aede2c730..bbd63bf9c 100644 --- a/src/debug.c +++ b/src/debug.c @@ -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();