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) {