New upstream version 2.3.4

This commit is contained in:
Jan Wagner 2023-10-18 07:29:37 +00:00
parent e7bdd1c6c6
commit de72f6f588
556 changed files with 90432 additions and 53391 deletions

View file

@ -93,11 +93,11 @@ static int stat_remote_fs = 0;
/* Linked list of filesystem types to omit.
If the list is empty, don't exclude any types. */
static struct name_list *fs_exclude_list;
static struct regex_list *fs_exclude_list = NULL;
/* Linked list of filesystem types to check.
If the list is empty, include all types. */
static struct name_list *fs_include_list;
static struct regex_list *fs_include_list;
static struct name_list *dp_exclude_list;
@ -112,11 +112,12 @@ enum
{
SYNC_OPTION = CHAR_MAX + 1,
NO_SYNC_OPTION,
BLOCK_SIZE_OPTION
BLOCK_SIZE_OPTION,
IGNORE_MISSING
};
#ifdef _AIX
#pragma alloca
#pragma alloca
#endif
int process_arguments (int, char **);
@ -126,13 +127,10 @@ int validate_arguments (uintmax_t, uintmax_t, double, double, double, double, ch
void print_help (void);
void print_usage (void);
double calculate_percent(uintmax_t, uintmax_t);
void stat_path (struct parameter_list *p);
bool stat_path (struct parameter_list *p);
void get_stats (struct parameter_list *p, struct fs_usage *fsp);
void get_path_stats (struct parameter_list *p, struct fs_usage *fsp);
double w_dfp = -1.0;
double c_dfp = -1.0;
char *path;
char *exclude_device;
char *units;
uintmax_t mult = 1024 * 1024;
@ -140,6 +138,7 @@ int verbose = 0;
int erronly = FALSE;
int display_mntp = FALSE;
int exact_match = FALSE;
bool ignore_missing = false;
int freespace_ignore_reserved = FALSE;
int display_inodes_perfdata = FALSE;
char *warn_freespace_units = NULL;
@ -155,6 +154,7 @@ char *crit_usedinodes_percent = NULL;
char *warn_freeinodes_percent = NULL;
char *crit_freeinodes_percent = NULL;
int path_selected = FALSE;
bool path_ignored = false;
char *group = NULL;
struct stat *stat_buf;
struct name_list *seen = NULL;
@ -166,10 +166,12 @@ main (int argc, char **argv)
int result = STATE_UNKNOWN;
int disk_result = STATE_UNKNOWN;
char *output;
char *ignored;
char *details;
char *perf;
char *perf_ilabel;
char *preamble;
char *preamble = " - free space:";
char *ignored_preamble = " - ignored paths:";
char *flag_header;
int temp_result;
@ -181,8 +183,8 @@ main (int argc, char **argv)
char mountdir[32];
#endif
preamble = strdup (" - free space:");
output = strdup ("");
ignored = strdup ("");
details = strdup ("");
perf = strdup ("");
perf_ilabel = strdup ("");
@ -203,7 +205,7 @@ main (int argc, char **argv)
/* If a list of paths has not been selected, find entire
mount list and create list of paths
*/
if (path_selected == FALSE) {
if (path_selected == FALSE && path_ignored == false) {
for (me = mount_list; me; me = me->me_next) {
if (! (path = np_find_parameter(path_select_list, me->me_mountdir))) {
path = np_add_parameter(&path_select_list, me->me_mountdir);
@ -213,17 +215,40 @@ main (int argc, char **argv)
set_all_thresholds(path);
}
}
np_set_best_match(path_select_list, mount_list, exact_match);
if (path_ignored == false) {
np_set_best_match(path_select_list, mount_list, exact_match);
}
/* Error if no match found for specified paths */
temp_list = path_select_list;
while (temp_list) {
if (! temp_list->best_match) {
die (STATE_CRITICAL, _("DISK %s: %s not found\n"), _("CRITICAL"), temp_list->name);
while (path_select_list) {
if (! path_select_list->best_match && ignore_missing == true) {
/* If the first element will be deleted, the temp_list must be updated with the new start address as well */
if (path_select_list == temp_list) {
temp_list = path_select_list->name_next;
}
/* Add path argument to list of ignored paths to inform about missing paths being ignored and not alerted */
xasprintf (&ignored, "%s %s;", ignored, path_select_list->name);
/* Delete the path from the list so that it is not stat-checked later in the code. */
path_select_list = np_del_parameter(path_select_list, path_select_list->name_prev);
} else if (! path_select_list->best_match) {
/* Without --ignore-missing option, exit with Critical state. */
die (STATE_CRITICAL, _("DISK %s: %s not found\n"), _("CRITICAL"), path_select_list->name);
} else {
/* Continue jumping through the list */
path_select_list = path_select_list->name_next;
}
}
temp_list = temp_list->name_next;
path_select_list = temp_list;
if (! path_select_list && ignore_missing == true) {
result = STATE_OK;
if (verbose >= 2) {
printf ("None of the provided paths were found\n");
}
}
/* Process for every path in list */
@ -242,6 +267,10 @@ main (int argc, char **argv)
me = path->best_match;
if (!me) {
continue;
}
#ifdef __CYGWIN__
if (strncmp(path->name, "/cygdrive/", 10) != 0 || strlen(path->name) > 11)
continue;
@ -260,14 +289,18 @@ main (int argc, char **argv)
if (path->group == NULL) {
/* Skip remote filesystems if we're not interested in them */
if (me->me_remote && show_local_fs) {
if (stat_remote_fs)
stat_path(path);
if (stat_remote_fs) {
if (!stat_path(path) && ignore_missing == true) {
result = STATE_OK;
xasprintf (&ignored, "%s %s;", ignored, path->name);
}
}
continue;
/* Skip pseudo fs's if we haven't asked for all fs's */
} else if (me->me_dummy && !show_all_fs) {
continue;
/* Skip excluded fstypes */
} else if (fs_exclude_list && np_find_name (fs_exclude_list, me->me_type)) {
} else if (fs_exclude_list && np_find_regmatch (fs_exclude_list, me->me_type)) {
continue;
/* Skip excluded fs's */
} else if (dp_exclude_list &&
@ -275,12 +308,18 @@ main (int argc, char **argv)
np_find_name (dp_exclude_list, me->me_mountdir))) {
continue;
/* Skip not included fstypes */
} else if (fs_include_list && !np_find_name (fs_include_list, me->me_type)) {
} else if (fs_include_list && !np_find_regmatch(fs_include_list, me->me_type)) {
continue;
}
}
stat_path(path);
if (!stat_path(path)) {
if (ignore_missing == true) {
result = STATE_OK;
xasprintf (&ignored, "%s %s;", ignored, path->name);
}
continue;
}
get_fs_usage (me->me_mountdir, me->me_devname, &fsp);
if (fsp.fsu_blocks && strcmp ("none", me->me_mountdir)) {
@ -411,8 +450,12 @@ main (int argc, char **argv)
if (verbose >= 2)
xasprintf (&output, "%s%s", output, details);
if (strcmp(output, "") == 0 && ! erronly) {
preamble = "";
xasprintf (&output, " - No disks were found for provided parameters;");
}
printf ("DISK %s%s%s|%s\n", state_text (result), (erronly && result==STATE_OK) ? "" : preamble, output, perf);
printf ("DISK %s%s%s%s%s|%s\n", state_text (result), ((erronly && result==STATE_OK)) ? "" : preamble, output, (strcmp(ignored, "") == 0) ? "" : ignored_preamble, ignored, perf);
return result;
}
@ -481,6 +524,7 @@ process_arguments (int argc, char **argv)
{"ignore-ereg-partition", required_argument, 0, 'i'},
{"ignore-eregi-path", required_argument, 0, 'I'},
{"ignore-eregi-partition", required_argument, 0, 'I'},
{"ignore-missing", no_argument, 0, IGNORE_MISSING},
{"local", no_argument, 0, 'l'},
{"stat-remote-fs", no_argument, 0, 'L'},
{"iperfdata", no_argument, 0, 'P'},
@ -499,7 +543,7 @@ process_arguments (int argc, char **argv)
if (argc < 2)
return ERROR;
np_add_name(&fs_exclude_list, "iso9660");
np_add_regex(&fs_exclude_list, "iso9660", REG_EXTENDED);
for (c = 1; c < argc; c++)
if (strcmp ("-to", argv[c]) == 0)
@ -540,7 +584,7 @@ process_arguments (int argc, char **argv)
/* Awful mistake where the range values do not make sense. Normally,
you alert if the value is within the range, but since we are using
freespace, we have to alert if outside the range. Thus we artifically
freespace, we have to alert if outside the range. Thus we artificially
force @ at the beginning of the range, so that it is backwards compatible
*/
case 'c': /* critical threshold */
@ -579,21 +623,36 @@ process_arguments (int argc, char **argv)
if (! strcasecmp (optarg, "bytes")) {
mult = (uintmax_t)1;
units = strdup ("B");
} else if ( (! strcmp (optarg, "kB")) || (!strcmp(optarg, "KiB")) ) {
} else if (!strcmp(optarg, "KiB")) {
mult = (uintmax_t)1024;
units = strdup ("kiB");
} else if ( (! strcmp (optarg, "MB")) || (!strcmp(optarg, "MiB")) ) {
units = strdup ("KiB");
} else if (! strcmp (optarg, "kB")) {
mult = (uintmax_t)1000;
units = strdup ("kB");
} else if (!strcmp(optarg, "MiB")) {
mult = (uintmax_t)1024 * 1024;
units = strdup ("MiB");
} else if ( (! strcmp (optarg, "GB")) || (!strcmp(optarg, "GiB")) ) {
} else if (! strcmp (optarg, "MB")) {
mult = (uintmax_t)1000 * 1000;
units = strdup ("MB");
} else if (!strcmp(optarg, "GiB")) {
mult = (uintmax_t)1024 * 1024 * 1024;
units = strdup ("GiB");
} else if ( (! strcmp (optarg, "TB")) || (!strcmp(optarg, "TiB")) ) {
} else if (! strcmp (optarg, "GB")){
mult = (uintmax_t)1000 * 1000 * 1000;
units = strdup ("GB");
} else if (!strcmp(optarg, "TiB")) {
mult = (uintmax_t)1024 * 1024 * 1024 * 1024;
units = strdup ("TiB");
} else if ( (! strcmp (optarg, "PB")) || (!strcmp(optarg, "PiB")) ) {
} else if (! strcmp (optarg, "TB")) {
mult = (uintmax_t)1000 * 1000 * 1000 * 1000;
units = strdup ("TB");
} else if (!strcmp(optarg, "PiB")) {
mult = (uintmax_t)1024 * 1024 * 1024 * 1024 * 1024;
units = strdup ("PiB");
} else if (! strcmp (optarg, "PB")){
mult = (uintmax_t)1000 * 1000 * 1000 * 1000 * 1000;
units = strdup ("PB");
} else {
die (STATE_UNKNOWN, _("unit type %s not known\n"), optarg);
}
@ -632,12 +691,19 @@ process_arguments (int argc, char **argv)
/* add parameter if not found. overwrite thresholds if path has already been added */
if (! (se = np_find_parameter(path_select_list, optarg))) {
se = np_add_parameter(&path_select_list, optarg);
if (stat(optarg, &stat_buf[0]) && ignore_missing == true) {
path_ignored = true;
break;
}
}
se->group = group;
set_all_thresholds(se);
/* With autofs, it is required to stat() the path before re-populating the mount_list */
stat_path(se);
if (!stat_path(se)) {
break;
}
/* NB: We can't free the old mount_list "just like that": both list pointers and struct
* pointers are copied around. One of the reason it wasn't done yet is that other parts
* of check_disk need the same kind of cleanup so it'd better be done as a whole */
@ -650,10 +716,18 @@ process_arguments (int argc, char **argv)
np_add_name(&dp_exclude_list, optarg);
break;
case 'X': /* exclude file system type */
np_add_name(&fs_exclude_list, optarg);
err = np_add_regex(&fs_exclude_list, optarg, REG_EXTENDED);
if (err != 0) {
regerror (err, &fs_exclude_list->regex, errbuf, MAX_INPUT_BUFFER);
die (STATE_UNKNOWN, "DISK %s: %s - %s\n",_("UNKNOWN"), _("Could not compile regular expression"), errbuf);
}
break;
case 'N': /* include file system type */
np_add_name(&fs_include_list, optarg);
err = np_add_regex(&fs_include_list, optarg, REG_EXTENDED);
if (err != 0) {
regerror (err, &fs_exclude_list->regex, errbuf, MAX_INPUT_BUFFER);
die (STATE_UNKNOWN, "DISK %s: %s - %s\n",_("UNKNOWN"), _("Could not compile regular expression"), errbuf);
}
break;
case 'v': /* verbose */
verbose++;
@ -718,6 +792,9 @@ process_arguments (int argc, char **argv)
cflags = default_cflags;
break;
case IGNORE_MISSING:
ignore_missing = true;
break;
case 'A':
optarg = strdup(".*");
// Intentional fallthrough
@ -729,7 +806,7 @@ process_arguments (int argc, char **argv)
crit_freespace_percent || warn_usedspace_units || crit_usedspace_units ||
warn_usedspace_percent || crit_usedspace_percent || warn_usedinodes_percent ||
crit_usedinodes_percent || warn_freeinodes_percent || crit_freeinodes_percent )) {
die (STATE_UNKNOWN, "DISK %s: %s", _("UNKNOWN"), _("Must set a threshold value before using -r/-R\n"));
die (STATE_UNKNOWN, "DISK %s: %s", _("UNKNOWN"), _("Must set a threshold value before using -r/-R/-A (--ereg-path/--eregi-path/--all)\n"));
}
err = regcomp(&re, optarg, cflags);
@ -753,7 +830,11 @@ process_arguments (int argc, char **argv)
}
}
if (!fnd)
if (!fnd && ignore_missing == true) {
path_ignored = true;
/* path_selected = TRUE;*/
break;
} else if (!fnd)
die (STATE_UNKNOWN, "DISK %s: %s - %s\n",_("UNKNOWN"),
_("Regular expression did not match any path or disk"), optarg);
@ -813,7 +894,7 @@ process_arguments (int argc, char **argv)
if (crit_usedspace_percent == NULL && argc > c && is_intnonneg (argv[c]))
crit_usedspace_percent = argv[c++];
if (argc > c && path == NULL) {
if (argc > c) {
se = np_add_parameter(&path_select_list, strdup(argv[c++]));
path_selected = TRUE;
set_all_thresholds(se);
@ -923,22 +1004,33 @@ print_help (void)
printf (" %s\n", _("Regular expression to ignore selected path/partition (case insensitive) (may be repeated)"));
printf (" %s\n", "-i, --ignore-ereg-path=PATH, --ignore-ereg-partition=PARTITION");
printf (" %s\n", _("Regular expression to ignore selected path or partition (may be repeated)"));
printf (" %s\n", "--ignore-missing");
printf (" %s\n", _("Return OK if no filesystem matches, filesystem does not exist or is inaccessible."));
printf (" %s\n", _("(Provide this option before -p / -r / --ereg-path if used)"));
printf (UT_PLUG_TIMEOUT, DEFAULT_SOCKET_TIMEOUT);
printf (" %s\n", "-u, --units=STRING");
printf (" %s\n", _("Choose bytes, kB, MB, GB, TB (default: MB)"));
printf (UT_VERBOSE);
printf (" %s\n", "-X, --exclude-type=TYPE");
printf (" %s\n", _("Ignore all filesystems of indicated type (may be repeated)"));
printf (" %s\n", "-N, --include-type=TYPE");
printf (" %s\n", _("Check only filesystems of indicated type (may be repeated)"));
printf (" %s\n", "-X, --exclude-type=TYPE_REGEX");
printf (" %s\n", _("Ignore all filesystems of types matching given regex(7) (may be repeated)"));
printf (" %s\n", "-N, --include-type=TYPE_REGEX");
printf (" %s\n", _("Check only filesystems where the type matches this given regex(7) (may be repeated)"));
printf ("\n");
printf ("%s\n", _("General usage hints:"));
printf (" %s\n", _("- Arguments are positional! \"-w 5 -c 1 -p /foo -w6 -c2 -p /bar\" is not the same as"));
printf (" %s\n", _("\"-w 5 -c 1 -p /bar w6 -c2 -p /foo\"."));
printf (" %s\n", _("- The syntax is broadly: \"{thresholds a} {paths a} -C {thresholds b} {thresholds b} ...\""));
printf ("\n");
printf ("%s\n", _("Examples:"));
printf (" %s\n", "check_disk -w 10% -c 5% -p /tmp -p /var -C -w 100000 -c 50000 -p /");
printf (" %s\n", _("Checks /tmp and /var at 10% and 5%, and / at 100MB and 50MB"));
printf (" %s\n\n", _("Checks /tmp and /var at 10% and 5%, and / at 100MB and 50MB"));
printf (" %s\n", "check_disk -w 100 -c 50 -C -w 1000 -c 500 -g sidDATA -r '^/oracle/SID/data.*$'");
printf (" %s\n", _("Checks all filesystems not matching -r at 100M and 50M. The fs matching the -r regex"));
printf (" %s\n", _("are grouped which means the freespace thresholds are applied to all disks together"));
printf (" %s\n\n", _("are grouped which means the freespace thresholds are applied to all disks together"));
printf (" %s\n", "check_disk -w 100 -c 50 -C -w 1000 -c 500 -p /foo -C -w 5% -c 3% -p /bar");
printf (" %s\n", _("Checks /foo for 1000M/500M and /bar for 5/3%. All remaining volumes use 100M/50M"));
@ -951,12 +1043,12 @@ void
print_usage (void)
{
printf ("%s\n", _("Usage:"));
printf (" %s {-w absolute_limit |-w percentage_limit% | -W inode_percentage_limit } {-c absolute_limit|-c percentage_limit% | -K inode_percentage_limit } {-p path | -x device}\n", progname);
printf (" %s {-w absolute_limit |-w percentage_limit%% | -W inode_percentage_limit } {-c absolute_limit|-c percentage_limit%% | -K inode_percentage_limit } {-p path | -x device}\n", progname);
printf ("[-C] [-E] [-e] [-f] [-g group ] [-k] [-l] [-M] [-m] [-R path ] [-r path ]\n");
printf ("[-t timeout] [-u unit] [-v] [-X type] [-N type]\n");
printf ("[-t timeout] [-u unit] [-v] [-X type_regex] [-N type]\n");
}
void
bool
stat_path (struct parameter_list *p)
{
/* Stat entry to check that dir exists and is accessible */
@ -965,9 +1057,14 @@ stat_path (struct parameter_list *p)
if (stat (p->name, &stat_buf[0])) {
if (verbose >= 3)
printf("stat failed on %s\n", p->name);
printf("DISK %s - ", _("CRITICAL"));
die (STATE_CRITICAL, _("%s %s: %s\n"), p->name, _("is not accessible"), strerror(errno));
if (ignore_missing == true) {
return false;
} else {
printf("DISK %s - ", _("CRITICAL"));
die (STATE_CRITICAL, _("%s %s: %s\n"), p->name, _("is not accessible"), strerror(errno));
}
}
return true;
}
@ -987,7 +1084,8 @@ get_stats (struct parameter_list *p, struct fs_usage *fsp) {
continue;
#endif
if (p_list->group && ! (strcmp(p_list->group, p->group))) {
stat_path(p_list);
if (! stat_path(p_list))
continue;
get_fs_usage (p_list->best_match->me_mountdir, p_list->best_match->me_devname, &tmpfsp);
get_path_stats(p_list, &tmpfsp);
if (verbose >= 3)
@ -1045,7 +1143,7 @@ get_path_stats (struct parameter_list *p, struct fs_usage *fsp) {
p->available_to_root = fsp->fsu_bfree;
p->used = fsp->fsu_blocks - fsp->fsu_bfree;
if (freespace_ignore_reserved) {
/* option activated : we substract the root-reserved space from the total */
/* option activated : we subtract the root-reserved space from the total */
p->total = fsp->fsu_blocks - p->available_to_root + p->available;
} else {
/* default behaviour : take all the blocks into account */
@ -1056,11 +1154,11 @@ get_path_stats (struct parameter_list *p, struct fs_usage *fsp) {
p->dfree_units = p->available*fsp->fsu_blocksize/mult;
p->dtotal_units = p->total*fsp->fsu_blocksize/mult;
/* Free file nodes. Not sure the workaround is required, but in case...*/
p->inodes_free = fsp->fsu_favail > fsp->fsu_ffree ? 0 : fsp->fsu_favail;
p->inodes_free = fsp->fsu_ffree;
p->inodes_free_to_root = fsp->fsu_ffree; /* Free file nodes for root. */
p->inodes_used = fsp->fsu_files - fsp->fsu_ffree;
if (freespace_ignore_reserved) {
/* option activated : we substract the root-reserved inodes from the total */
/* option activated : we subtract the root-reserved inodes from the total */
/* not all OS report fsp->fsu_favail, only the ones with statvfs syscall */
/* for others, fsp->fsu_ffree == fsp->fsu_favail */
p->inodes_total = fsp->fsu_files - p->inodes_free_to_root + p->inodes_free;