MatthiasPetermann / netbsd_exporter

The netbsd_exporter retrieves system metrics such as disk I/O, network I/O, RAM and filesystem usage, as well as CPU load from the running system and exposes them in the format of Prometheus metrics. It is designed to be integrated into inetd, providing a lightweight, NetBSD-focused alternative to the node_exporter.
BSD 2-Clause "Simplified" License
0 stars 0 forks source link

Shows negative numbers for file system size values on 32bit arch #1

Closed als-git closed 1 month ago

als-git commented 1 month ago

How to reproduce:

Simply build and run on a 32bit machine. I tested my usual candidates for this: port-i386, port-sparc, port-vax. I assume this code was written and tested on 64bit machines only.

Example output (snipped irrelevant parts):

netbsd_fs_size_bytes{device="wd0a",mountpoint="/"} -1958563840 netbsd_fs_used_bytes{device="wd0a",mountpoint="/"} -1555032064 netbsd_fs_free_bytes{device="wd0a",mountpoint="/"} -1808840704

df says:

/dev/wd0a 26G 2.6G 22G 10% /

How to fix:

This is essentially the old C language trap that identically named integer types are of different size depending on platform word size. In this case, long is 8 bytes (64bit) on a 64bit machine (which is large enough here) and 4 bytes (32bit) on a 32bit machine (which will cheerfully overflow here).

There are reasons int64_t, uint64_t, int32_t and friends are defined these days. Of course with that, gcc rightfully complains about the formatting args, because uint64_t is long long int on 32bit and long int on 64bit machines. So I ended up using long long which is 64bit on both.

With that, it works correctly on both 32bit and 64bit machines. Tested platforms: port-i386, port-amd64, port-vax, port-sparc, port-sparc64.

And for those who no longer have 32bit machines, qemu works very well (that's how I run my port-sparc machine on an arm64 host).

Patch follows

--- netbsd_exporter.h.orig      2024-05-09 18:58:29.961248161 +0200
+++ netbsd_exporter.h   2024-05-09 19:49:00.021634195 +0200
@@ -31,7 +31,7 @@
 int option_http_header = 1;
 int option_syslog = 1;

-void print_filesystem_metric(const char*, const char*, const char*, long );
+void print_filesystem_metric(const char*, const char*, const char*, long long unsigned int);

 void print_disk_io_metric(const char*, long long unsigned int, long long unsigned int );

--- netbsd_exporter.c.orig      2024-05-07 11:40:44.013487932 +0200
+++ netbsd_exporter.c   2024-05-09 19:49:15.832451252 +0200
@@ -53,8 +53,8 @@
 #include "netbsd_exporter.h"
 #include "version.h"

-void print_filesystem_metric(const char* metric, const char* device, const char* mountpoint, long value) {
-    printf("netbsd_fs_%s_bytes{device=\"%s\",mountpoint=\"%s\"} %ld\n", metric, device, mountpoint, value);
+void print_filesystem_metric(const char* metric, const char* device, const char* mountpoint, long long unsigned int value) {
+    printf("netbsd_fs_%s_bytes{device=\"%s\",mountpoint=\"%s\"} %llu\n", metric, device, mountpoint, value);
 }

 void print_disk_io_metric(const char* device, long long unsigned int rbytes, long long unsigned int wbytes) {
MatthiasPetermann commented 1 month ago

Hello Alex, thank you very much for your bug report and the helpful explanations. I have adopted the changes with minimal adjustments. Kind regards, Matthias