mirror of
https://github.com/monitoring-plugins/monitoring-plugins.git
synced 2026-03-24 11:23:12 -04:00
Refactor check_disk and library functions
This commit is contained in:
parent
0bca1d1aa3
commit
908aed4e6f
4 changed files with 1078 additions and 754 deletions
1083
plugins/check_disk.c
1083
plugins/check_disk.c
File diff suppressed because it is too large
Load diff
|
|
@ -1,92 +0,0 @@
|
|||
#pragma once
|
||||
|
||||
#include "../../config.h"
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
|
||||
typedef struct {
|
||||
// Output options
|
||||
bool erronly;
|
||||
bool display_mntp;
|
||||
/* show only local filesystems. */
|
||||
bool show_local_fs;
|
||||
/* show only local filesystems but call stat() on remote ones. */
|
||||
bool stat_remote_fs;
|
||||
bool display_inodes_perfdata;
|
||||
|
||||
bool exact_match;
|
||||
bool ignore_missing;
|
||||
bool path_ignored;
|
||||
bool path_selected;
|
||||
bool freespace_ignore_reserved;
|
||||
|
||||
char *warn_freespace_units;
|
||||
char *crit_freespace_units;
|
||||
char *warn_freespace_percent;
|
||||
char *crit_freespace_percent;
|
||||
char *warn_usedspace_units;
|
||||
char *crit_usedspace_units;
|
||||
char *warn_usedspace_percent;
|
||||
char *crit_usedspace_percent;
|
||||
char *warn_usedinodes_percent;
|
||||
char *crit_usedinodes_percent;
|
||||
char *warn_freeinodes_percent;
|
||||
char *crit_freeinodes_percent;
|
||||
|
||||
/* Linked list of filesystem types to omit.
|
||||
If the list is empty, don't exclude any types. */
|
||||
struct regex_list *fs_exclude_list;
|
||||
/* Linked list of filesystem types to check.
|
||||
If the list is empty, include all types. */
|
||||
struct regex_list *fs_include_list;
|
||||
struct name_list *device_path_exclude_list;
|
||||
struct parameter_list *path_select_list;
|
||||
/* Linked list of mounted filesystems. */
|
||||
struct mount_entry *mount_list;
|
||||
struct name_list *seen;
|
||||
|
||||
char *units;
|
||||
uintmax_t mult;
|
||||
char *group;
|
||||
} check_disk_config;
|
||||
|
||||
check_disk_config check_disk_config_init() {
|
||||
check_disk_config tmp = {
|
||||
.erronly = false,
|
||||
.display_mntp = false,
|
||||
.show_local_fs = false,
|
||||
.stat_remote_fs = false,
|
||||
.display_inodes_perfdata = false,
|
||||
|
||||
.exact_match = false,
|
||||
.ignore_missing = false,
|
||||
.path_ignored = false,
|
||||
.path_selected = false,
|
||||
.freespace_ignore_reserved = false,
|
||||
|
||||
.warn_freespace_units = NULL,
|
||||
.crit_freespace_units = NULL,
|
||||
.warn_freespace_percent = NULL,
|
||||
.crit_freespace_percent = NULL,
|
||||
.warn_usedspace_units = NULL,
|
||||
.crit_usedspace_units = NULL,
|
||||
.warn_usedspace_percent = NULL,
|
||||
.crit_usedspace_percent = NULL,
|
||||
.warn_usedinodes_percent = NULL,
|
||||
.crit_usedinodes_percent = NULL,
|
||||
.warn_freeinodes_percent = NULL,
|
||||
.crit_freeinodes_percent = NULL,
|
||||
|
||||
.fs_exclude_list = NULL,
|
||||
.fs_include_list = NULL,
|
||||
.device_path_exclude_list = NULL,
|
||||
.path_select_list = NULL,
|
||||
.mount_list = NULL,
|
||||
.seen = NULL,
|
||||
|
||||
.units = NULL,
|
||||
.mult = 1024 * 1024,
|
||||
.group = NULL,
|
||||
};
|
||||
return tmp;
|
||||
}
|
||||
|
|
@ -29,7 +29,12 @@
|
|||
#include "../common.h"
|
||||
#include "utils_disk.h"
|
||||
#include "../../gl/fsusage.h"
|
||||
#include "../../lib/thresholds.h"
|
||||
#include "../../lib/states.h"
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <assert.h>
|
||||
|
||||
void np_add_name(struct name_list **list, const char *name) {
|
||||
struct name_list *new_entry;
|
||||
|
|
@ -70,152 +75,39 @@ int np_add_regex(struct regex_list **list, const char *regex, int cflags) {
|
|||
return regcomp_result;
|
||||
}
|
||||
|
||||
struct parameter_list parameter_list_init(const char *name) {
|
||||
struct parameter_list result = {
|
||||
parameter_list_elem parameter_list_init(const char *name) {
|
||||
parameter_list_elem result = {
|
||||
.name = strdup(name),
|
||||
.best_match = NULL,
|
||||
|
||||
.name_next = NULL,
|
||||
.name_prev = NULL,
|
||||
|
||||
.freespace_units = NULL,
|
||||
.freespace_percent = NULL,
|
||||
.usedspace_units = NULL,
|
||||
.usedspace_percent = NULL,
|
||||
.usedinodes_percent = NULL,
|
||||
.freeinodes_percent = NULL,
|
||||
.freespace_units = mp_thresholds_init(),
|
||||
.freespace_percent = mp_thresholds_init(),
|
||||
.freeinodes_percent = mp_thresholds_init(),
|
||||
|
||||
.group = NULL,
|
||||
.dfree_pct = -1,
|
||||
.dused_pct = -1,
|
||||
.total = 0,
|
||||
.available = 0,
|
||||
.available_to_root = 0,
|
||||
.used = 0,
|
||||
.dused_units = 0,
|
||||
.dfree_units = 0,
|
||||
.dtotal_units = 0,
|
||||
|
||||
.inodes_total = 0,
|
||||
.inodes_free = 0,
|
||||
.inodes_free_to_root = 0,
|
||||
.inodes_used = 0,
|
||||
.dused_inodes_percent = 0,
|
||||
.dfree_inodes_percent = 0,
|
||||
|
||||
.used_bytes = 0,
|
||||
.free_bytes = 0,
|
||||
.total_bytes = 0,
|
||||
|
||||
.next = NULL,
|
||||
.prev = NULL,
|
||||
};
|
||||
return result;
|
||||
}
|
||||
|
||||
/* Initialises a new parameter at the end of list */
|
||||
struct parameter_list *np_add_parameter(struct parameter_list **list, const char *name) {
|
||||
struct parameter_list *current = *list;
|
||||
struct parameter_list *new_path;
|
||||
new_path = (struct parameter_list *)malloc(sizeof *new_path);
|
||||
|
||||
*new_path = parameter_list_init(name);
|
||||
|
||||
if (current == NULL) {
|
||||
*list = new_path;
|
||||
new_path->name_prev = NULL;
|
||||
} else {
|
||||
while (current->name_next) {
|
||||
current = current->name_next;
|
||||
}
|
||||
current->name_next = new_path;
|
||||
new_path->name_prev = current;
|
||||
}
|
||||
return new_path;
|
||||
}
|
||||
|
||||
/* Delete a given parameter from list and return pointer to next element*/
|
||||
struct parameter_list *np_del_parameter(struct parameter_list *item, struct parameter_list *prev) {
|
||||
if (item == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
struct parameter_list *next;
|
||||
|
||||
if (item->name_next) {
|
||||
next = item->name_next;
|
||||
} else {
|
||||
next = NULL;
|
||||
}
|
||||
|
||||
if (next) {
|
||||
next->name_prev = prev;
|
||||
}
|
||||
|
||||
if (prev) {
|
||||
prev->name_next = next;
|
||||
}
|
||||
|
||||
if (item->name) {
|
||||
free(item->name);
|
||||
}
|
||||
free(item);
|
||||
|
||||
return next;
|
||||
}
|
||||
|
||||
/* returns a pointer to the struct found in the list */
|
||||
struct parameter_list *np_find_parameter(struct parameter_list *list, const char *name) {
|
||||
for (struct parameter_list *temp_list = list; temp_list; temp_list = temp_list->name_next) {
|
||||
if (!strcmp(temp_list->name, name)) {
|
||||
return temp_list;
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void np_set_best_match(struct parameter_list *desired, struct mount_entry *mount_list, bool exact) {
|
||||
for (struct parameter_list *d = desired; d; d = d->name_next) {
|
||||
if (!d->best_match) {
|
||||
struct mount_entry *mount_entry;
|
||||
size_t name_len = strlen(d->name);
|
||||
size_t best_match_len = 0;
|
||||
struct mount_entry *best_match = NULL;
|
||||
struct fs_usage fsp;
|
||||
|
||||
/* set best match if path name exactly matches a mounted device name */
|
||||
for (mount_entry = mount_list; mount_entry; mount_entry = mount_entry->me_next) {
|
||||
if (strcmp(mount_entry->me_devname, d->name) == 0) {
|
||||
if (get_fs_usage(mount_entry->me_mountdir, mount_entry->me_devname, &fsp) >= 0) {
|
||||
best_match = mount_entry;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* set best match by directory name if no match was found by devname */
|
||||
if (!best_match) {
|
||||
for (mount_entry = mount_list; mount_entry; mount_entry = mount_entry->me_next) {
|
||||
size_t len = strlen(mount_entry->me_mountdir);
|
||||
if ((!exact && (best_match_len <= len && len <= name_len &&
|
||||
(len == 1 || strncmp(mount_entry->me_mountdir, d->name, len) == 0))) ||
|
||||
(exact && strcmp(mount_entry->me_mountdir, d->name) == 0)) {
|
||||
if (get_fs_usage(mount_entry->me_mountdir, mount_entry->me_devname, &fsp) >= 0) {
|
||||
best_match = mount_entry;
|
||||
best_match_len = len;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (best_match) {
|
||||
d->best_match = best_match;
|
||||
} else {
|
||||
d->best_match = NULL; /* Not sure why this is needed as it should be null on initialisation */
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Returns true if name is in list */
|
||||
bool np_find_name(struct name_list *list, const char *name) {
|
||||
if (list == NULL || name == NULL) {
|
||||
return false;
|
||||
}
|
||||
for (struct name_list *n = list; n; n = n->next) {
|
||||
if (!strcmp(name, n->name)) {
|
||||
for (struct name_list *iterator = list; iterator; iterator = iterator->next) {
|
||||
if (!strcmp(name, iterator->name)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
@ -228,13 +120,13 @@ bool np_find_regmatch(struct regex_list *list, const char *name) {
|
|||
return false;
|
||||
}
|
||||
|
||||
int len = strlen(name);
|
||||
size_t len = strlen(name);
|
||||
|
||||
for (; list; list = list->next) {
|
||||
/* Emulate a full match as if surrounded with ^( )$
|
||||
by checking whether the match spans the whole name */
|
||||
regmatch_t m;
|
||||
if (!regexec(&list->regex, name, 1, &m, 0) && m.rm_so == 0 && m.rm_eo == len) {
|
||||
regmatch_t dummy_match;
|
||||
if (!regexec(&list->regex, name, 1, &dummy_match, 0) && dummy_match.rm_so == 0 && dummy_match.rm_eo == len) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
@ -243,8 +135,8 @@ bool np_find_regmatch(struct regex_list *list, const char *name) {
|
|||
}
|
||||
|
||||
bool np_seen_name(struct name_list *list, const char *name) {
|
||||
for (struct name_list *s = list; s; s = s->next) {
|
||||
if (!strcmp(s->name, name)) {
|
||||
for (struct name_list *iterator = list; iterator; iterator = iterator->next) {
|
||||
if (!strcmp(iterator->name, name)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
@ -254,3 +146,356 @@ bool np_seen_name(struct name_list *list, const char *name) {
|
|||
bool np_regex_match_mount_entry(struct mount_entry *me, regex_t *re) {
|
||||
return ((regexec(re, me->me_devname, (size_t)0, NULL, 0) == 0) || (regexec(re, me->me_mountdir, (size_t)0, NULL, 0) == 0));
|
||||
}
|
||||
|
||||
check_disk_config check_disk_config_init() {
|
||||
check_disk_config tmp = {
|
||||
.erronly = false,
|
||||
.display_mntp = false,
|
||||
.show_local_fs = false,
|
||||
.stat_remote_fs = false,
|
||||
.display_inodes_perfdata = false,
|
||||
|
||||
.exact_match = false,
|
||||
.freespace_ignore_reserved = false,
|
||||
|
||||
.ignore_missing = false,
|
||||
.path_ignored = false,
|
||||
|
||||
// FS Filters
|
||||
.fs_exclude_list = NULL,
|
||||
.fs_include_list = NULL,
|
||||
.device_path_exclude_list = NULL,
|
||||
|
||||
// Actual filesystems paths to investigate
|
||||
.path_select_list = filesystem_list_init(),
|
||||
|
||||
.mount_list = NULL,
|
||||
.seen = NULL,
|
||||
|
||||
.display_unit = Humanized,
|
||||
// .unit = MebiBytes,
|
||||
|
||||
.output_format_is_set = false,
|
||||
};
|
||||
return tmp;
|
||||
}
|
||||
|
||||
char *get_unit_string(byte_unit unit) {
|
||||
switch (unit) {
|
||||
case Bytes:
|
||||
return "Bytes";
|
||||
case KibiBytes:
|
||||
return "KiB";
|
||||
case MebiBytes:
|
||||
return "MiB";
|
||||
case GibiBytes:
|
||||
return "GiB";
|
||||
case TebiBytes:
|
||||
return "TiB";
|
||||
case PebiBytes:
|
||||
return "PiB";
|
||||
case ExbiBytes:
|
||||
return "EiB";
|
||||
case KiloBytes:
|
||||
return "KB";
|
||||
case MegaBytes:
|
||||
return "MB";
|
||||
case GigaBytes:
|
||||
return "GB";
|
||||
case TeraBytes:
|
||||
return "TB";
|
||||
case PetaBytes:
|
||||
return "PB";
|
||||
case ExaBytes:
|
||||
return "EB";
|
||||
default:
|
||||
assert(false);
|
||||
}
|
||||
}
|
||||
|
||||
measurement_unit measurement_unit_init() {
|
||||
measurement_unit tmp = {
|
||||
.name = NULL,
|
||||
.filesystem_type = NULL,
|
||||
.is_group = false,
|
||||
|
||||
.freeinodes_percent_thresholds = mp_thresholds_init(),
|
||||
.freespace_percent_thresholds = mp_thresholds_init(),
|
||||
.freespace_bytes_thresholds = mp_thresholds_init(),
|
||||
|
||||
.free_bytes = 0,
|
||||
.used_bytes = 0,
|
||||
.total_bytes = 0,
|
||||
|
||||
.inodes_total = 0,
|
||||
.inodes_free = 0,
|
||||
.inodes_free_to_root = 0,
|
||||
.inodes_used = 0,
|
||||
};
|
||||
return tmp;
|
||||
}
|
||||
|
||||
// Add a given element to the list, memory for the new element is freshly allocated
|
||||
// Returns a pointer to new element
|
||||
measurement_unit_list *add_measurement_list(measurement_unit_list *list, measurement_unit elem) {
|
||||
// find last element
|
||||
measurement_unit_list *new = NULL;
|
||||
if (list == NULL) {
|
||||
new = calloc(1, sizeof(measurement_unit_list));
|
||||
if (new == NULL) {
|
||||
die(STATE_UNKNOWN, _("allocation failed"));
|
||||
}
|
||||
} else {
|
||||
measurement_unit_list *list_elem = list;
|
||||
while (list_elem->next != NULL) {
|
||||
list_elem = list_elem->next;
|
||||
}
|
||||
|
||||
new = calloc(1, sizeof(measurement_unit_list));
|
||||
if (new == NULL) {
|
||||
die(STATE_UNKNOWN, _("allocation failed"));
|
||||
}
|
||||
|
||||
list_elem->next = new;
|
||||
}
|
||||
|
||||
new->unit = elem;
|
||||
new->next = NULL;
|
||||
return new;
|
||||
}
|
||||
|
||||
measurement_unit add_filesystem_to_measurement_unit(measurement_unit unit, parameter_list_elem filesystem) {
|
||||
|
||||
unit.free_bytes += filesystem.free_bytes;
|
||||
unit.used_bytes += filesystem.used_bytes;
|
||||
unit.total_bytes += filesystem.total_bytes;
|
||||
|
||||
unit.inodes_total += filesystem.inodes_total;
|
||||
unit.inodes_free += filesystem.inodes_free;
|
||||
unit.inodes_free_to_root += filesystem.inodes_free_to_root;
|
||||
unit.inodes_used += filesystem.inodes_used;
|
||||
return unit;
|
||||
}
|
||||
|
||||
measurement_unit create_measurement_unit_from_filesystem(parameter_list_elem filesystem, bool display_mntp) {
|
||||
measurement_unit result = measurement_unit_init();
|
||||
if (!display_mntp) {
|
||||
result.name = strdup(filesystem.best_match->me_mountdir);
|
||||
} else {
|
||||
result.name = strdup(filesystem.best_match->me_devname);
|
||||
}
|
||||
|
||||
if (filesystem.group) {
|
||||
result.is_group = true;
|
||||
} else {
|
||||
result.is_group = false;
|
||||
if (filesystem.best_match) {
|
||||
result.filesystem_type = filesystem.best_match->me_type;
|
||||
}
|
||||
}
|
||||
|
||||
result.freeinodes_percent_thresholds = filesystem.freeinodes_percent;
|
||||
result.freespace_percent_thresholds = filesystem.freespace_percent;
|
||||
result.freespace_bytes_thresholds = filesystem.freespace_units;
|
||||
result.free_bytes = filesystem.free_bytes;
|
||||
result.total_bytes = filesystem.total_bytes;
|
||||
result.used_bytes = filesystem.used_bytes;
|
||||
result.inodes_total = filesystem.inodes_total;
|
||||
result.inodes_used = filesystem.inodes_used;
|
||||
result.inodes_free = filesystem.inodes_free;
|
||||
result.inodes_free_to_root = filesystem.inodes_free_to_root;
|
||||
return result;
|
||||
}
|
||||
|
||||
#define RANDOM_STRING_LENGTH 64
|
||||
|
||||
char *humanize_byte_value(uintmax_t value, bool use_si_units) {
|
||||
// Idea: A reasonable output should have at most 3 orders of magnitude
|
||||
// before the decimal separator
|
||||
// 353GiB is ok, 2444 GiB should be 2.386 TiB
|
||||
char *result = calloc(RANDOM_STRING_LENGTH, sizeof(char));
|
||||
if (result == NULL) {
|
||||
die(STATE_UNKNOWN, _("allocation failed"));
|
||||
}
|
||||
|
||||
if (use_si_units) {
|
||||
// SI units, powers of 10
|
||||
if (value < KiloBytes) {
|
||||
snprintf(result, RANDOM_STRING_LENGTH, "%ju B", value);
|
||||
} else if (value < MegaBytes) {
|
||||
snprintf(result, RANDOM_STRING_LENGTH, "%ju KB", value / KiloBytes);
|
||||
} else if (value < GigaBytes) {
|
||||
snprintf(result, RANDOM_STRING_LENGTH, "%ju MB", value / MegaBytes);
|
||||
} else if (value < TeraBytes) {
|
||||
snprintf(result, RANDOM_STRING_LENGTH, "%ju GB", value / GigaBytes);
|
||||
} else if (value < PetaBytes) {
|
||||
snprintf(result, RANDOM_STRING_LENGTH, "%ju TB", value / TeraBytes);
|
||||
} else {
|
||||
snprintf(result, RANDOM_STRING_LENGTH, "%ju PB", value / PetaBytes);
|
||||
}
|
||||
} else {
|
||||
// IEC units, powers of 2 ^ 10
|
||||
if (value < KibiBytes) {
|
||||
snprintf(result, RANDOM_STRING_LENGTH, "%ju B", value);
|
||||
} else if (value < MebiBytes) {
|
||||
snprintf(result, RANDOM_STRING_LENGTH, "%ju KiB", value / KibiBytes);
|
||||
} else if (value < GibiBytes) {
|
||||
snprintf(result, RANDOM_STRING_LENGTH, "%ju MiB", value / MebiBytes);
|
||||
} else if (value < TebiBytes) {
|
||||
snprintf(result, RANDOM_STRING_LENGTH, "%ju GiB", value / GibiBytes);
|
||||
} else if (value < PebiBytes) {
|
||||
snprintf(result, RANDOM_STRING_LENGTH, "%ju TiB", value / TebiBytes);
|
||||
} else {
|
||||
snprintf(result, RANDOM_STRING_LENGTH, "%ju PiB", value / PebiBytes);
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
filesystem_list filesystem_list_init() {
|
||||
filesystem_list tmp = {
|
||||
.length = 0,
|
||||
.first = NULL,
|
||||
};
|
||||
return tmp;
|
||||
}
|
||||
|
||||
parameter_list_elem *mp_int_fs_list_append(filesystem_list *list, const char *name) {
|
||||
parameter_list_elem *current = list->first;
|
||||
parameter_list_elem *new_path = (struct parameter_list *)malloc(sizeof *new_path);
|
||||
*new_path = parameter_list_init(name);
|
||||
|
||||
if (current == NULL) {
|
||||
list->first = new_path;
|
||||
new_path->prev = NULL;
|
||||
list->length = 1;
|
||||
} else {
|
||||
while (current->next) {
|
||||
current = current->next;
|
||||
}
|
||||
current->next = new_path;
|
||||
new_path->prev = current;
|
||||
list->length++;
|
||||
}
|
||||
return new_path;
|
||||
}
|
||||
|
||||
parameter_list_elem *mp_int_fs_list_find(filesystem_list list, const char *name) {
|
||||
if (list.length == 0) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
for (parameter_list_elem *temp_list = list.first; temp_list; temp_list = temp_list->next) {
|
||||
if (!strcmp(temp_list->name, name)) {
|
||||
return temp_list;
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
parameter_list_elem *mp_int_fs_list_del(filesystem_list *list, parameter_list_elem *item) {
|
||||
if (list->length == 0) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (item == NULL) {
|
||||
// Got NULL for item, interpret this as "delete first element"
|
||||
// as a kind of compatibility to the old function
|
||||
item = list->first;
|
||||
}
|
||||
|
||||
if (list->first == item) {
|
||||
list->length--;
|
||||
|
||||
list->first = item->next;
|
||||
if (list->first) {
|
||||
list->first->prev = NULL;
|
||||
}
|
||||
return list->first;
|
||||
}
|
||||
|
||||
// Was not the first element, continue
|
||||
parameter_list_elem *prev = list->first;
|
||||
parameter_list_elem *current = list->first->next;
|
||||
|
||||
while (current != item && current != NULL) {
|
||||
prev = current;
|
||||
current = current->next;
|
||||
}
|
||||
|
||||
if (current == NULL) {
|
||||
// didn't find that element ....
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// remove the element
|
||||
parameter_list_elem *next = current->next;
|
||||
prev->next = next;
|
||||
list->length--;
|
||||
if (next) {
|
||||
next->prev = prev;
|
||||
}
|
||||
|
||||
if (item->name) {
|
||||
free(item->name);
|
||||
}
|
||||
free(item);
|
||||
|
||||
return next;
|
||||
}
|
||||
|
||||
parameter_list_elem *mp_int_fs_list_get_next(parameter_list_elem *current) {
|
||||
if (!current) {
|
||||
return NULL;
|
||||
}
|
||||
return current->next;
|
||||
}
|
||||
|
||||
void mp_int_fs_list_set_best_match(filesystem_list list, struct mount_entry *mount_list, bool exact) {
|
||||
for (parameter_list_elem *elem = list.first; elem; elem = mp_int_fs_list_get_next(elem)) {
|
||||
if (!elem->best_match) {
|
||||
size_t name_len = strlen(elem->name);
|
||||
struct mount_entry *best_match = NULL;
|
||||
|
||||
/* set best match if path name exactly matches a mounted device name */
|
||||
for (struct mount_entry *mount_entry = mount_list; mount_entry; mount_entry = mount_entry->me_next) {
|
||||
if (strcmp(mount_entry->me_devname, elem->name) == 0) {
|
||||
struct fs_usage fsp;
|
||||
if (get_fs_usage(mount_entry->me_mountdir, mount_entry->me_devname, &fsp) >= 0) {
|
||||
best_match = mount_entry;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* set best match by directory name if no match was found by devname */
|
||||
if (!best_match) {
|
||||
size_t best_match_len = 0;
|
||||
for (struct mount_entry *mount_entry = mount_list; mount_entry; mount_entry = mount_entry->me_next) {
|
||||
size_t len = strlen(mount_entry->me_mountdir);
|
||||
|
||||
if ((!exact && (best_match_len <= len && len <= name_len &&
|
||||
(len == 1 || strncmp(mount_entry->me_mountdir, elem->name, len) == 0))) ||
|
||||
(exact && strcmp(mount_entry->me_mountdir, elem->name) == 0)) {
|
||||
struct fs_usage fsp;
|
||||
|
||||
if (get_fs_usage(mount_entry->me_mountdir, mount_entry->me_devname, &fsp) >= 0) {
|
||||
best_match = mount_entry;
|
||||
best_match_len = len;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (best_match) {
|
||||
elem->best_match = best_match;
|
||||
} else {
|
||||
elem->best_match = NULL; /* Not sure why this is needed as it should be null on initialisation */
|
||||
}
|
||||
|
||||
// No filesystem without a mount_entry!
|
||||
// assert(elem->best_match != NULL);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,14 +1,34 @@
|
|||
#pragma once
|
||||
/* Header file for utils_disk */
|
||||
|
||||
#include "../../config.h"
|
||||
#include "../../gl/mountlist.h"
|
||||
#include "../../lib/utils_base.h"
|
||||
#include "../../lib/output.h"
|
||||
#include "regex.h"
|
||||
#include <stdint.h>
|
||||
|
||||
typedef enum : unsigned long {
|
||||
Humanized = 0,
|
||||
Bytes = 1,
|
||||
KibiBytes = 1024,
|
||||
MebiBytes = 1024 * KibiBytes,
|
||||
GibiBytes = 1024 * MebiBytes,
|
||||
TebiBytes = 1024 * GibiBytes,
|
||||
PebiBytes = 1024 * TebiBytes,
|
||||
ExbiBytes = 1024 * PebiBytes,
|
||||
KiloBytes = 1000,
|
||||
MegaBytes = 1000 * KiloBytes,
|
||||
GigaBytes = 1000 * MegaBytes,
|
||||
TeraBytes = 1000 * GigaBytes,
|
||||
PetaBytes = 1000 * TeraBytes,
|
||||
ExaBytes = 1000 * PetaBytes
|
||||
} byte_unit;
|
||||
|
||||
typedef struct name_list string_list;
|
||||
struct name_list {
|
||||
char *name;
|
||||
struct name_list *next;
|
||||
string_list *next;
|
||||
};
|
||||
|
||||
struct regex_list {
|
||||
|
|
@ -16,54 +36,120 @@ struct regex_list {
|
|||
struct regex_list *next;
|
||||
};
|
||||
|
||||
typedef struct parameter_list parameter_list_elem;
|
||||
struct parameter_list {
|
||||
char *name;
|
||||
char *group;
|
||||
|
||||
thresholds *freespace_units;
|
||||
thresholds *freespace_percent;
|
||||
thresholds *usedspace_units;
|
||||
thresholds *usedspace_percent;
|
||||
|
||||
thresholds *usedinodes_percent;
|
||||
thresholds *freeinodes_percent;
|
||||
mp_thresholds freespace_units;
|
||||
mp_thresholds freespace_percent;
|
||||
mp_thresholds freeinodes_percent;
|
||||
|
||||
struct mount_entry *best_match;
|
||||
|
||||
uintmax_t total;
|
||||
uintmax_t available;
|
||||
uintmax_t available_to_root;
|
||||
uintmax_t used;
|
||||
uintmax_t inodes_free;
|
||||
uintmax_t inodes_free_to_root;
|
||||
uintmax_t inodes_free;
|
||||
uintmax_t inodes_used;
|
||||
uintmax_t inodes_total;
|
||||
|
||||
double dfree_pct;
|
||||
double dused_pct;
|
||||
uint64_t used_bytes;
|
||||
uint64_t free_bytes;
|
||||
uint64_t total_bytes;
|
||||
|
||||
uint64_t dused_units;
|
||||
uint64_t dfree_units;
|
||||
uint64_t dtotal_units;
|
||||
|
||||
double dused_inodes_percent;
|
||||
double dfree_inodes_percent;
|
||||
|
||||
struct parameter_list *name_next;
|
||||
struct parameter_list *name_prev;
|
||||
parameter_list_elem *next;
|
||||
parameter_list_elem *prev;
|
||||
};
|
||||
|
||||
typedef struct {
|
||||
size_t length;
|
||||
parameter_list_elem *first;
|
||||
} filesystem_list;
|
||||
|
||||
filesystem_list filesystem_list_init();
|
||||
|
||||
typedef struct {
|
||||
char *name;
|
||||
char *filesystem_type;
|
||||
bool is_group;
|
||||
|
||||
mp_thresholds freespace_bytes_thresholds;
|
||||
mp_thresholds freespace_percent_thresholds;
|
||||
mp_thresholds freeinodes_percent_thresholds;
|
||||
|
||||
uintmax_t inodes_free_to_root;
|
||||
uintmax_t inodes_free;
|
||||
uintmax_t inodes_used;
|
||||
uintmax_t inodes_total;
|
||||
|
||||
uintmax_t used_bytes;
|
||||
uintmax_t free_bytes;
|
||||
uintmax_t total_bytes;
|
||||
} measurement_unit;
|
||||
|
||||
typedef struct measurement_unit_list measurement_unit_list;
|
||||
struct measurement_unit_list {
|
||||
measurement_unit unit;
|
||||
measurement_unit_list *next;
|
||||
};
|
||||
|
||||
typedef struct {
|
||||
// Output options
|
||||
bool erronly;
|
||||
bool display_mntp;
|
||||
/* show only local filesystems. */
|
||||
bool show_local_fs;
|
||||
/* show only local filesystems but call stat() on remote ones. */
|
||||
bool stat_remote_fs;
|
||||
bool display_inodes_perfdata;
|
||||
|
||||
bool exact_match;
|
||||
bool freespace_ignore_reserved;
|
||||
|
||||
bool ignore_missing;
|
||||
bool path_ignored;
|
||||
|
||||
/* Linked list of filesystem types to omit.
|
||||
If the list is empty, don't exclude any types. */
|
||||
struct regex_list *fs_exclude_list;
|
||||
/* Linked list of filesystem types to check.
|
||||
If the list is empty, include all types. */
|
||||
struct regex_list *fs_include_list;
|
||||
struct name_list *device_path_exclude_list;
|
||||
filesystem_list path_select_list;
|
||||
/* Linked list of mounted filesystems. */
|
||||
struct mount_entry *mount_list;
|
||||
struct name_list *seen;
|
||||
|
||||
byte_unit display_unit;
|
||||
// byte_unit unit;
|
||||
|
||||
bool output_format_is_set;
|
||||
mp_output_format output_format;
|
||||
} check_disk_config;
|
||||
|
||||
void np_add_name(struct name_list **list, const char *name);
|
||||
bool np_find_name(struct name_list *list, const char *name);
|
||||
bool np_seen_name(struct name_list *list, const char *name);
|
||||
int np_add_regex(struct regex_list **list, const char *regex, int cflags);
|
||||
bool np_find_regmatch(struct regex_list *list, const char *name);
|
||||
|
||||
struct parameter_list *np_add_parameter(struct parameter_list **list, const char *name);
|
||||
struct parameter_list *np_find_parameter(struct parameter_list *list, const char *name);
|
||||
struct parameter_list *np_del_parameter(struct parameter_list *item, struct parameter_list *prev);
|
||||
struct parameter_list parameter_list_init(const char *);
|
||||
parameter_list_elem parameter_list_init(const char *);
|
||||
|
||||
int search_parameter_list(struct parameter_list *list, const char *name);
|
||||
void np_set_best_match(struct parameter_list *desired, struct mount_entry *mount_list, bool exact);
|
||||
parameter_list_elem *mp_int_fs_list_append(filesystem_list *list, const char *name);
|
||||
parameter_list_elem *mp_int_fs_list_find(filesystem_list list, const char *name);
|
||||
parameter_list_elem *mp_int_fs_list_del(filesystem_list *list, parameter_list_elem *item);
|
||||
parameter_list_elem *mp_int_fs_list_get_next(parameter_list_elem *current);
|
||||
void mp_int_fs_list_set_best_match(filesystem_list list, struct mount_entry *mount_list, bool exact);
|
||||
|
||||
measurement_unit measurement_unit_init();
|
||||
measurement_unit_list *add_measurement_list(measurement_unit_list *list, measurement_unit elem);
|
||||
measurement_unit add_filesystem_to_measurement_unit(measurement_unit unit, parameter_list_elem filesystem);
|
||||
measurement_unit create_measurement_unit_from_filesystem(parameter_list_elem filesystem, bool display_mntp);
|
||||
|
||||
int search_parameter_list(parameter_list_elem *list, const char *name);
|
||||
bool np_regex_match_mount_entry(struct mount_entry *, regex_t *);
|
||||
|
||||
char *get_unit_string(byte_unit);
|
||||
check_disk_config check_disk_config_init();
|
||||
|
||||
char *humanize_byte_value(uintmax_t value, bool use_si_units);
|
||||
|
|
|
|||
Loading…
Reference in a new issue