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 <w@1wt.eu>
This commit is contained in:
Valentine Krasnobaeva 2025-07-10 10:59:57 +02:00 committed by Willy Tarreau
parent 1888991e12
commit 0c63883be1
2 changed files with 56 additions and 0 deletions

View File

@ -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

View 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();