Skip to content

Commit 87ab340

Browse files
committed
check_readonlyfs: new option -x/--exclude
New option -x/--explude to check all but file systems passed as arguments. Feature asked by michaeldcwolf (https://github.com/michaeldcwolf) Signed-off-by: Davide Madrisan <d.madrisan@proton.me>
1 parent 326b550 commit 87ab340

2 files changed

Lines changed: 65 additions & 12 deletions

File tree

lib/mountlist.c

Lines changed: 24 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
// SPDX-License-Identifier: GPL-3.0-or-later
22
/*
33
* License: GPLv3+
4-
* Copyright (c) 2013 Davide Madrisan <davide.madrisan@gmail.com>
4+
* Copyright (c) 2013,2025 Davide Madrisan <davide.madrisan@gmail.com>
55
*
66
* A Nagios plugin to check for readonly filesystems
77
*
@@ -45,25 +45,45 @@
4545
# endif
4646
#endif
4747

48+
/*
49+
* filesystem mountpoint
50+
* -----------------------------------------
51+
* efivarfs /sys/firmware/efi/efivars
52+
* fusectl /sys/fs/fuse/connections
53+
* gvfsd-fuse /run/user/1000/gvfs
54+
* portal /run/user/1000/doc
55+
* systemd-1 /proc/sys/fs/binfmt_misc
56+
*/
4857
#ifndef ME_DUMMY
4958
# define ME_DUMMY(Fs_name, Fs_type) \
50-
(STREQ (Fs_type, "autofs") \
51-
|| STREQ (Fs_type, "proc") \
59+
/* for Linux 4.5 */ \
60+
(STREQ (Fs_type, "cgroup2") \
61+
/* for Linux 4.4 */ \
62+
|| STREQ (Fs_type, "bfs") \
63+
/* for Linux 4.1 */ \
64+
|| STREQ (Fs_type, "tracefs") \
5265
/* for Linux 2.6/3.x */ \
5366
|| STREQ (Fs_type, "cgroup") \
67+
|| STREQ (Fs_type, "configfs") \
5468
|| STREQ (Fs_type, "debugfs") \
5569
|| STREQ (Fs_type, "devpts") \
70+
|| STREQ (Fs_type, "devtmpfs") \
5671
|| STREQ (Fs_type, "fusectl") \
5772
|| STREQ (Fs_type, "hugetlbfs") \
5873
|| STREQ (Fs_type, "mqueue") \
5974
|| STREQ (Fs_type, "pstore") \
6075
|| STREQ (Fs_type, "rpc_pipefs") \
6176
|| STREQ (Fs_type, "securityfs") \
77+
|| STREQ (Fs_type, "selinuxfs") \
6278
|| STREQ (Fs_type, "sysfs") \
6379
/* Linux 2.4 */ \
6480
|| STREQ (Fs_type, "devfs") \
6581
|| STREQ (Fs_type, "binfmt_misc") \
66-
|| STREQ (Fs_type, "none"))
82+
|| STREQ (Fs_type, "none") \
83+
/* Linux 2.1 */ \
84+
|| STREQ (Fs_type, "autofs") \
85+
/* Linux 1.3 */ \
86+
|| STREQ (Fs_type, "proc"))
6787
#endif
6888

6989
#ifndef ME_REMOTE

plugins/check_readonlyfs.c

Lines changed: 41 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
// SPDX-License-Identifier: GPL-3.0-or-later
22
/*
33
* License: GPLv3+
4-
* Copyright (c) 2013-2015 Davide Madrisan <davide.madrisan@gmail.com>
4+
* Copyright (c) 2013-2015,2025 Davide Madrisan <davide.madrisan@gmail.com>
55
*
66
* A Nagios plugin to check for readonly filesystems.
77
*
@@ -38,7 +38,7 @@
3838
#include "progversion.h"
3939

4040
static const char *program_copyright =
41-
"Copyright (C) 2013-2015 Davide Madrisan <" PACKAGE_BUGREPORT ">\n";
41+
"Copyright (C) 2013-2015,2025 Davide Madrisan <" PACKAGE_BUGREPORT ">\n";
4242

4343
/* A file system type to display. */
4444

@@ -83,6 +83,7 @@ static struct option const longopts[] = {
8383
{(char *) "all", no_argument, NULL, 'a'},
8484
{(char *) "local", no_argument, NULL, 'l'},
8585
{(char *) "type", required_argument, NULL, 'T'},
86+
{(char *) "exclude", no_argument, NULL, 'x'},
8687
{(char *) "exclude-type", required_argument, NULL, 'X'},
8788
{(char *) "verbose", no_argument, NULL, 'v'},
8889
{(char *) "help", no_argument, NULL, GETOPT_HELP_CHAR},
@@ -104,6 +105,8 @@ usage (FILE * out)
104105
out);
105106
fputs (" -T, --type=TYPE limit listing to file systems of type TYPE\n",
106107
out);
108+
fputs (" -x, --exclude "
109+
"check all but file systems passed as arguments\n", out);
107110
fputs (" -X, --exclude-type=TYPE "
108111
"limit listing to file systems not of type TYPE\n", out);
109112
fputs (" -v, --verbose show details for command-line debugging "
@@ -113,6 +116,8 @@ usage (FILE * out)
113116
fputs (USAGE_EXAMPLES, out);
114117
fprintf (out, " %s -l -T ext3 -T ext4\n", program_name);
115118
fprintf (out, " %s -l -X vfat\n", program_name);
119+
fprintf (out, " %s -x /run/credentials/systemd-journald.service /dev/sr0\n",
120+
program_name);
116121

117122
exit (out == stderr ? STATE_UNKNOWN : STATE_OK);
118123
}
@@ -199,22 +204,36 @@ skip_mount_entry (struct mount_entry *me)
199204
}
200205

201206
static int
202-
check_all_entries (char **ro_filesystems)
207+
check_all_entries (char **ro_filesystems, char **fs_exclude)
203208
{
204209
struct mount_entry *me;
205210
int status = STATE_OK;
211+
bool ignore;
206212
char *p;
213+
char **fs;
207214
size_t len;
208215

209216
for (me = mount_list; me; me = me->me_next)
210217
{
218+
ignore = false;
219+
if (fs_exclude)
220+
for (fs = fs_exclude; *fs; fs++)
221+
if (STREQ(*fs, me->me_devname) || STREQ(*fs, me->me_mountdir))
222+
{
223+
ignore = true;
224+
break;
225+
}
226+
if (ignore)
227+
continue;
228+
211229
if (skip_mount_entry (me))
212230
continue;
213231

214232
if (verbose)
215233
printf ("%-10s %s type %s (%s) %s\n",
216234
me->me_devname, me->me_mountdir, me->me_type, me->me_opts,
217235
(me->me_readonly) ? "<< read-only" : "");
236+
218237
if (me->me_readonly)
219238
{
220239
if (*ro_filesystems == NULL)
@@ -262,6 +281,7 @@ check_entry (char const *name)
262281
int
263282
main (int argc, char **argv)
264283
{
284+
bool exclude_mode = false;
265285
int c, i;
266286
int status = STATE_OK;
267287
char *ro_filesystems = NULL;
@@ -290,6 +310,9 @@ main (int argc, char **argv)
290310
case 'T':
291311
add_fs_type (optarg);
292312
break;
313+
case 'x':
314+
exclude_mode = true;
315+
break;
293316
case 'X':
294317
add_excluded_fs_type (optarg);
295318
break;
@@ -320,7 +343,7 @@ main (int argc, char **argv)
320343
}
321344
}
322345

323-
if (optind < argc)
346+
if (optind < argc && !exclude_mode)
324347
{
325348
/* Open each of the given entries to make sure any corresponding
326349
* partition is automounted. This must be done before reading the
@@ -333,6 +356,9 @@ main (int argc, char **argv)
333356
close (fd);
334357
}
335358
}
359+
else if (optind == argc && exclude_mode)
360+
plugin_error (STATE_UNKNOWN, 0,
361+
"the --exclude option requires a list of file systems");
336362

337363
mount_list =
338364
read_file_system_list ((fs_select_list != NULL
@@ -341,9 +367,9 @@ main (int argc, char **argv)
341367
if (NULL == mount_list)
342368
/* Couldn't read the table of mounted file systems. */
343369
plugin_error (STATE_UNKNOWN, 0,
344-
"cannot read table of mounted file systems");
370+
"cannot read table of mounted file systems");
345371

346-
if (optind < argc)
372+
if (!exclude_mode && optind < argc)
347373
{
348374
for (i = optind; i < argc; ++i)
349375
{
@@ -365,8 +391,15 @@ main (int argc, char **argv)
365391
putchar ('\n');
366392
return status;
367393
}
368-
369-
status = check_all_entries (&ro_filesystems);
394+
else if (exclude_mode)
395+
{
396+
char **arg;
397+
for (arg = argv + optind; *arg; arg++)
398+
printf("remaining argv = %s\n", *arg);
399+
status = check_all_entries (&ro_filesystems, argv + optind);
400+
}
401+
else
402+
status = check_all_entries (&ro_filesystems, NULL);
370403

371404
if (STATE_CRITICAL == status)
372405
{

0 commit comments

Comments
 (0)