From: Willy Tarreau Date: Wed, 22 Nov 2023 10:32:51 +0000 (+0100) Subject: MINOR: debug: add OS/hardware info to the post_mortem struct X-Git-Tag: v2.9-dev11~26 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=4e3f9921dead4840db68bbc0b5dbde9b11ae8233;p=thirdparty%2Fhaproxy.git MINOR: debug: add OS/hardware info to the post_mortem struct Let's extract some info about the system (board model, vendor etc), this will indicate some hypervisors, some cloud instances or some uncommon embedded boards etc. Typically, vmware, qemu and raspberry-pi are visible here and can help during the troubleshooting session. --- diff --git a/src/debug.c b/src/debug.c index 7a98ffce65..166c85235c 100644 --- a/src/debug.c +++ b/src/debug.c @@ -78,6 +78,11 @@ struct post_mortem { /* platform-specific information */ struct { struct utsname utsname; // OS name+ver+arch+hostname + 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 + char brd_vendor[64]; // mainboard vendor when known + char brd_model[64]; // mainboard model when known } platform; } post_mortem ALIGNED(256) = { }; @@ -445,6 +450,16 @@ static int debug_parse_cli_show_dev(char **args, char *payload, struct appctx *a chunk_reset(&trash); chunk_appendf(&trash, "Platform info\n"); + if (*post_mortem.platform.hw_vendor) + chunk_appendf(&trash, " machine vendor: %s\n", post_mortem.platform.hw_vendor); + if (*post_mortem.platform.hw_family) + chunk_appendf(&trash, " machine family: %s\n", post_mortem.platform.hw_family); + if (*post_mortem.platform.hw_model) + chunk_appendf(&trash, " machine model: %s\n", post_mortem.platform.hw_model); + if (*post_mortem.platform.brd_vendor) + chunk_appendf(&trash, " board vendor: %s\n", post_mortem.platform.brd_vendor); + if (*post_mortem.platform.brd_model) + chunk_appendf(&trash, " board model: %s\n", post_mortem.platform.brd_model); if (*post_mortem.platform.utsname.sysname) chunk_appendf(&trash, " OS name: %s\n", post_mortem.platform.utsname.sysname); if (*post_mortem.platform.utsname.release) @@ -1877,10 +1892,52 @@ REGISTER_PER_THREAD_INIT(init_debug_per_thread); #endif /* USE_THREAD_DUMP */ +static void feed_post_mortem_linux() +{ +#if defined(__linux__) + /* DMI reports either HW or hypervisor, this allows to detect most VMs. + * On ARM the device-tree is often more precise for the model. Since many + * boards present "to be filled by OEM" or so in many fields, we dedup + * them as much as possible. + */ + if (read_line_to_trash("/sys/class/dmi/id/sys_vendor") > 0) + strlcpy2(post_mortem.platform.hw_vendor, trash.area, sizeof(post_mortem.platform.hw_vendor)); + + if (read_line_to_trash("/sys/class/dmi/id/product_family") > 0 && + strcmp(trash.area, post_mortem.platform.hw_vendor) != 0) + strlcpy2(post_mortem.platform.hw_family, trash.area, sizeof(post_mortem.platform.hw_family)); + + if ((read_line_to_trash("/sys/class/dmi/id/product_name") > 0 && + strcmp(trash.area, post_mortem.platform.hw_vendor) != 0 && + strcmp(trash.area, post_mortem.platform.hw_family) != 0)) + strlcpy2(post_mortem.platform.hw_model, trash.area, sizeof(post_mortem.platform.hw_model)); + + if ((read_line_to_trash("/sys/class/dmi/id/board_vendor") > 0 && + strcmp(trash.area, post_mortem.platform.hw_vendor) != 0)) + strlcpy2(post_mortem.platform.brd_vendor, trash.area, sizeof(post_mortem.platform.brd_vendor)); + + if ((read_line_to_trash("/sys/firmware/devicetree/base/model") > 0 && + strcmp(trash.area, post_mortem.platform.brd_vendor) != 0 && + strcmp(trash.area, post_mortem.platform.hw_vendor) != 0 && + strcmp(trash.area, post_mortem.platform.hw_family) != 0 && + strcmp(trash.area, post_mortem.platform.hw_model) != 0) || + (read_line_to_trash("/sys/class/dmi/id/board_name") > 0 && + strcmp(trash.area, post_mortem.platform.brd_vendor) != 0 && + strcmp(trash.area, post_mortem.platform.hw_vendor) != 0 && + strcmp(trash.area, post_mortem.platform.hw_family) != 0 && + strcmp(trash.area, post_mortem.platform.hw_model) != 0)) + strlcpy2(post_mortem.platform.brd_model, trash.area, sizeof(post_mortem.platform.brd_model)); +#endif // __linux__ +} + static int feed_post_mortem() { /* kernel type, version and arch */ uname(&post_mortem.platform.utsname); + + if (strcmp(post_mortem.platform.utsname.sysname, "Linux") == 0) + feed_post_mortem_linux(); + return ERR_NONE; }