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 *
3838#include "progversion.h"
3939
4040static 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
201206static 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)
262281int
263282main (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