Merge pull request #2110 from RincewindsHat/netbsd-fixes

Netbsd fixes
This commit is contained in:
Lorenz Kästle 2025-03-17 13:24:55 +01:00 committed by GitHub
commit 544a3a1328
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
5 changed files with 108 additions and 97 deletions

View file

@ -56,7 +56,6 @@ void print_usage(void);
# include <sys/device.h>
# include <sys/param.h>
# include <sys/sysctl.h>
# include <sys/videoio.h> /* for __u8 and friends */
# include <sys/scsiio.h>
# include <sys/ataio.h>
# include <dev/ata/atareg.h>
@ -79,48 +78,47 @@ void print_usage(void);
#define UNKNOWN -1
typedef struct threshold_s {
__u8 id;
__u8 threshold;
__u8 reserved[10];
uint8_t id;
uint8_t threshold;
uint8_t reserved[10];
} __attribute__((packed)) threshold_t;
typedef struct thresholds_s {
__u16 revision;
uint16_t revision;
threshold_t thresholds[NR_ATTRIBUTES];
__u8 reserved[18];
__u8 vendor[131];
__u8 checksum;
uint8_t reserved[18];
uint8_t vendor[131];
uint8_t checksum;
} __attribute__((packed)) thresholds_t;
typedef struct value_s {
__u8 id;
__u16 status;
__u8 value;
__u8 vendor[8];
uint8_t id;
uint16_t status;
uint8_t value;
uint8_t vendor[8];
} __attribute__((packed)) value_t;
typedef struct values_s {
__u16 revision;
uint16_t revision;
value_t values[NR_ATTRIBUTES];
__u8 offline_status;
__u8 vendor1;
__u16 offline_timeout;
__u8 vendor2;
__u8 offline_capability;
__u16 smart_capability;
__u8 reserved[16];
__u8 vendor[125];
__u8 checksum;
uint8_t offline_status;
uint8_t vendor1;
uint16_t offline_timeout;
uint8_t vendor2;
uint8_t offline_capability;
uint16_t smart_capability;
uint8_t reserved[16];
uint8_t vendor[125];
uint8_t checksum;
} __attribute__((packed)) values_t;
static struct {
__u8 value;
uint8_t value;
char *text;
} offline_status_text[] = {{0x00, "NeverStarted"}, {0x02, "Completed"}, {0x04, "Suspended"},
{0x05, "Aborted"}, {0x06, "Failed"}, {0, 0}};
} offline_status_text[] = {{0x00, "NeverStarted"}, {0x02, "Completed"}, {0x04, "Suspended"}, {0x05, "Aborted"}, {0x06, "Failed"}, {0, 0}};
static struct {
__u8 value;
uint8_t value;
char *text;
} smart_command[] = {{SMART_ENABLE, "SMART_ENABLE"},
{SMART_DISABLE, "SMART_DISABLE"},
@ -140,7 +138,7 @@ static int smart_read_values(int, values_t *);
static int nagios(values_t *, thresholds_t *);
static void print_value(value_t *, threshold_t *);
static void print_values(values_t *, thresholds_t *);
static int smart_cmd_simple(int, enum SmartCommand, __u8, bool);
static int smart_cmd_simple(int, enum SmartCommand, uint8_t, bool);
static int smart_read_thresholds(int, thresholds_t *);
static bool verbose = false;
@ -175,8 +173,9 @@ int main(int argc, char *argv[]) {
o = getopt_long(argc, argv, "+d:iq10nhVv", longopts, &longindex);
if (o == -1 || o == EOF || o == 1)
if (o == -1 || o == EOF || o == 1) {
break;
}
switch (o) {
case 'd':
@ -234,8 +233,9 @@ int main(int argc, char *argv[]) {
smart_read_values(fd, &values);
smart_read_thresholds(fd, &thresholds);
retval = nagios(&values, &thresholds);
if (verbose)
if (verbose) {
print_values(&values, &thresholds);
}
close(fd);
return retval;
@ -254,7 +254,7 @@ char *get_offline_text(int status) {
int smart_read_values(int fd, values_t *values) {
#ifdef __linux__
int e;
__u8 args[4 + 512];
uint8_t args[4 + 512];
args[0] = WIN_SMART;
args[1] = 0;
args[2] = SMART_READ_VALUES;
@ -282,8 +282,9 @@ int smart_read_values(int fd, values_t *values) {
req.cylinder = WDSMART_CYL;
if (ioctl(fd, ATAIOCCOMMAND, &req) == 0) {
if (req.retsts != ATACMD_OK)
if (req.retsts != ATACMD_OK) {
errno = ENODEV;
}
}
if (errno != 0) {
@ -370,22 +371,24 @@ void print_values(values_t *p, thresholds_t *t) {
p->smart_capability & 1 ? "SaveOnStandBy" : "", p->smart_capability & 2 ? "AutoSave" : "");
}
int smart_cmd_simple(int fd, enum SmartCommand command, __u8 val0, bool show_error) {
int smart_cmd_simple(int fd, enum SmartCommand command, uint8_t val0, bool show_error) {
int e = STATE_UNKNOWN;
#ifdef __linux__
__u8 args[4];
uint8_t args[4];
args[0] = WIN_SMART;
args[1] = val0;
args[2] = smart_command[command].value;
args[3] = 0;
if (ioctl(fd, HDIO_DRIVE_CMD, &args)) {
e = STATE_CRITICAL;
if (show_error)
if (show_error) {
printf(_("CRITICAL - %s: %s\n"), smart_command[command].text, strerror(errno));
}
} else {
e = STATE_OK;
if (show_error)
if (show_error) {
printf(_("OK - Command sent (%s)\n"), smart_command[command].text);
}
}
#endif /* __linux__ */
@ -401,20 +404,24 @@ int smart_cmd_simple(int fd, enum SmartCommand command, __u8 val0, bool show_err
req.sec_count = val0;
if (ioctl(fd, ATAIOCCOMMAND, &req) == 0) {
if (req.retsts != ATACMD_OK)
if (req.retsts != ATACMD_OK) {
errno = ENODEV;
if (req.cylinder != WDSMART_CYL)
}
if (req.cylinder != WDSMART_CYL) {
errno = ENODEV;
}
}
if (errno != 0) {
e = STATE_CRITICAL;
if (show_error)
if (show_error) {
printf(_("CRITICAL - %s: %s\n"), smart_command[command].text, strerror(errno));
}
} else {
e = STATE_OK;
if (show_error)
if (show_error) {
printf(_("OK - Command sent (%s)\n"), smart_command[command].text);
}
}
#endif /* __NetBSD__ */
@ -424,7 +431,7 @@ int smart_cmd_simple(int fd, enum SmartCommand command, __u8 val0, bool show_err
int smart_read_thresholds(int fd, thresholds_t *thresholds) {
#ifdef __linux__
int e;
__u8 args[4 + 512];
uint8_t args[4 + 512];
args[0] = WIN_SMART;
args[1] = 0;
args[2] = SMART_READ_THRESHOLDS;
@ -452,8 +459,9 @@ int smart_read_thresholds(int fd, thresholds_t *thresholds) {
req.cylinder = WDSMART_CYL;
if (ioctl(fd, ATAIOCCOMMAND, &req) == 0) {
if (req.retsts != ATACMD_OK)
if (req.retsts != ATACMD_OK) {
errno = ENODEV;
}
}
if (errno != 0) {

View file

@ -116,10 +116,10 @@ int main(int argc, char **argv) {
# ifdef PING_HAS_TIMEOUT
xasprintf(&cmd, rawcmd, timeout_interval, config.max_packets, config.addresses[i]);
# else
xasprintf(&cmd, rawcmd, config.max_packets, addresses[i]);
xasprintf(&cmd, rawcmd, config.max_packets, config.addresses[i]);
# endif
#else
xasprintf(&cmd, rawcmd, addresses[i], config.max_packets);
xasprintf(&cmd, rawcmd, config.addresses[i], config.max_packets);
#endif
if (verbose >= 2) {

View file

@ -90,6 +90,14 @@ int main(int argc, char **argv) {
exit(STATE_UNKNOWN);
}
if (verbose) {
printf("Swap retrieval result:\n"
"\tFree: %llu\n"
"\tUsed: %llu\n"
"\tTotal: %llu\n",
data.metrics.free, data.metrics.used, data.metrics.total);
}
double percent_used;
mp_check overall = mp_check_init();
if (config.output_format_is_set) {

View file

@ -1,7 +1,8 @@
#pragma once
#include "../common.h"
#include "output.h"
#include "../../lib/output.h"
#include "../../lib/states.h"
#ifndef SWAP_CONVERSION
# define SWAP_CONVERSION 1
@ -26,7 +27,7 @@ typedef struct {
typedef struct {
bool allswaps;
int no_swap_state;
mp_state_enum no_swap_state;
bool warn_is_set;
check_swap_threshold warn;
bool crit_is_set;

View file

@ -68,7 +68,7 @@ swap_result getSwapFromProcMeminfo(char proc_meminfo[]) {
FILE *meminfo_file_ptr;
meminfo_file_ptr = fopen(proc_meminfo, "r");
swap_result result = {0};
swap_result result = {};
result.errorcode = STATE_UNKNOWN;
if (meminfo_file_ptr == NULL) {
@ -78,83 +78,71 @@ swap_result getSwapFromProcMeminfo(char proc_meminfo[]) {
return result;
}
uint64_t swap_total = 0;
uint64_t swap_used = 0;
uint64_t swap_free = 0;
unsigned long swap_total = 0;
unsigned long swap_used = 0;
unsigned long swap_free = 0;
bool found_total = false;
bool found_used = false;
bool found_free = false;
char input_buffer[MAX_INPUT_BUFFER];
char str[32];
while (fgets(input_buffer, MAX_INPUT_BUFFER - 1, meminfo_file_ptr)) {
uint64_t tmp_KB = 0;
/*
* The following sscanf call looks for a line looking like: "Swap: 123
* 123 123" On which kind of system this format exists, I can not say,
* but I wanted to document this for people who are not adapt with
* sscanf anymore, like me
* Also the units used here are unclear and probably wrong
* 123 123" which exists on NetBSD (at least),
* The unit should be Bytes
*/
if (sscanf(input_buffer, "%*[S]%*[w]%*[a]%*[p]%*[:] %lu %lu %lu", &swap_total, &swap_used, &swap_free) == 3) {
result.metrics.total += swap_total;
result.metrics.used += swap_used;
result.metrics.free += swap_free;
found_total = true;
found_free = true;
found_used = true;
// Set error
result.errorcode = STATE_OK;
// Break out of fgets here, since both scanf expressions might match (NetBSD for example)
break;
}
/*
* The following sscanf call looks for lines looking like:
* "SwapTotal: 123" and "SwapFree: 123" This format exists at least
* on Debian Linux with a 5.* kernel
*/
} else {
int sscanf_result = sscanf(input_buffer,
"%*[S]%*[w]%*[a]%*[p]%[TotalFreCchd]%*[:] %lu "
"%*[k]%*[B]",
str, &tmp_KB);
/*
* The following sscanf call looks for lines looking like:
* "SwapTotal: 123" and "SwapFree: 123" This format exists at least
* on Debian Linux with a 5.* kernel
*/
unsigned long tmp_KB = 0;
int sscanf_result = sscanf(input_buffer,
"%*[S]%*[w]%*[a]%*[p]%[TotalFreCchd]%*[:] %lu "
"%*[k]%*[B]",
str, &tmp_KB);
if (sscanf_result == 2) {
if (sscanf_result == 2) {
if (verbose >= 3) {
printf("Got %s with %lu\n", str, tmp_KB);
}
/* I think this part is always in Kb, so convert to bytes */
if (strcmp("Total", str) == 0) {
swap_total = tmp_KB * 1000;
found_total = true;
} else if (strcmp("Free", str) == 0) {
swap_free = swap_free + tmp_KB * 1000;
found_free = true;
found_used = true; // No explicit used metric available
} else if (strcmp("Cached", str) == 0) {
swap_free = swap_free + tmp_KB * 1000;
found_free = true;
found_used = true; // No explicit used metric available
}
result.errorcode = STATE_OK;
if (verbose >= 3) {
printf("Got %s with %lu\n", str, tmp_KB);
}
/* I think this part is always in Kb, so convert to bytes */
if (strcmp("Total", str) == 0) {
swap_total = tmp_KB * 1000;
found_total = true;
} else if (strcmp("Free", str) == 0) {
swap_free += tmp_KB * 1000;
found_free = true;
} else if (strcmp("Cached", str) == 0) {
swap_free += tmp_KB * 1000;
}
result.errorcode = STATE_OK;
}
}
fclose(meminfo_file_ptr);
result.metrics.total = swap_total;
result.metrics.used = swap_total - swap_free;
result.metrics.free = swap_free;
result.metrics.used = swap_total - swap_free;
if (!found_free || !found_total || !found_used) {
if (!found_free || !found_total) {
result.errorcode = STATE_UNKNOWN;
}
@ -297,8 +285,14 @@ struct swapent {
};
#else
// Includes for NetBSD
# include <unistd.h>
# include <sys/swap.h>
# define bsd_swapctl swapctl
#endif
#endif // CHECK_SWAP_SWAPCTL_BSD
swap_result getSwapFromSwapctl_BSD(swap_config config) {
/* get the number of active swap devices */
@ -322,8 +316,8 @@ swap_result getSwapFromSwapctl_BSD(swap_config config) {
unsigned long long used_swap_mb = 0;
for (int i = 0; i < nswaps; i++) {
dsktotal_mb = (float)ent[i].se_nblks / (float)config.conversion_factor;
dskused_mb = (float)ent[i].se_inuse / (float)config.conversion_factor;
dsktotal_mb = (double)ent[i].se_nblks / (double)config.conversion_factor;
dskused_mb = (double)ent[i].se_inuse / (double)config.conversion_factor;
dskfree_mb = (dsktotal_mb - dskused_mb);
if (config.allswaps && dsktotal_mb > 0) {