Skip to content

Commit

Permalink
path-rw-test: To avoid race conditions, use a unique filename (fix #283)
Browse files Browse the repository at this point in the history
  • Loading branch information
markuslf committed Sep 16, 2023
1 parent fbabc2e commit a62cd51
Show file tree
Hide file tree
Showing 3 changed files with 30 additions and 31 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,7 @@ Monitoring Plugins:
Monitoring Plugins:

* csv-values: header included in data results despite setting "--skip-header" (fix [#706](https://github.com/Linuxfabrik/monitoring-plugins/issues/706))
* path-rw-test: To avoid race conditions, use a unique filename (fix [#283](https://github.com/Linuxfabrik/monitoring-plugins/issues/283))
* journald-query: Rename perfdata from "sudo journald-query" to "journald-query"
* swap-usage: Fix Traceback `PdhAddEnglishCounterW failed`

Expand Down
17 changes: 9 additions & 8 deletions check-plugins/path-rw-test/README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ Check path-rw-test
Overview
--------

Tests whether a file (``__LINUXFABRIK_PATH_RW_TEST__``) can be written to a specific path and then deleted - much like the "__DIRECT_IO_TEST__" in oVirt. Especially useful with mounted filesystems like NFS or SMB. The local temporary directory is always tested, no matter whether the check is called with or without parameters. May need sudo.
Tests if a temporary file can be created, written to a specified path, read, and then deleted. Especially useful with mounted file systems such as NFS or SMB. The local temporary directory is always tested, regardless of whether the check is called with or without parameters. May require sudo privileges.


Fact Sheet
Expand All @@ -17,7 +17,6 @@ Fact Sheet
"Check Interval Recommendation", "Once a minute"
"Can be called without parameters", "Yes"
"Compiled for", "Linux, Windows"
"3rd Party Python modules", "``psutil``"


Help
Expand All @@ -28,31 +27,33 @@ Help
usage: path-rw-test [-h] [-V] [--always-ok] [--path PATH]
[--severity {warn,crit}]
Tests whether a file can be written to a specific path and then deleted.
Tests if a temporary file can be created, written to a specified path, read,
and then deleted. Especially useful with mounted file systems such as NFS or
SMB. The local temporary directory is always tested, regardless of whether the
check is called with or without parameters. May require sudo privileges.
optional arguments:
options:
-h, --help show this help message and exit
-V, --version show program's version number and exit
--always-ok Always returns OK.
--path PATH Path to which the file is to be written and from which
it will be deleted (repeating). Default: ['/tmp']
--severity {warn,crit}
Severity for alerting. One of "warn" or "crit".
Default: warn
Severity for alerting. Default: warn
Usage Examples
--------------

.. code-block:: bash
./path-rw-test --path /mnt/nfs --path /mnt/smb --path . --severity warn
./path-rw-test --path /mnt/nfs --path /mnt/smb --path /usr --severity warn
Output:

.. code-block:: text
/mnt/nfs: I/O error "Permission denied" while writing /mnt/nfs/__LINUXFABRIK_PATH_RW_TEST__ [WARNING]
Error creating/writing/reading/deleting file in `/usr` ([Errno 13] Permission denied: '/usr/tmptbt8daho'). Tested: /tmp, /mnt/nfs, /mnt/smb, /usr
States
Expand Down
43 changes: 20 additions & 23 deletions check-plugins/path-rw-test/path-rw-test
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@
"""

import argparse # pylint: disable=C0413
import os # pylint: disable=C0413
import sys # pylint: disable=C0413
import tempfile # pylint: disable=C0413

Expand All @@ -22,9 +21,12 @@ from lib.globals import (STATE_CRIT, STATE_OK, # pylint: disable=C0413
STATE_UNKNOWN, STATE_WARN)

__author__ = 'Linuxfabrik GmbH, Zurich/Switzerland'
__version__ = '2023051201'
__version__ = '2023091601'

DESCRIPTION = """Tests whether a file can be written to a specific path and then deleted."""
DESCRIPTION = """Tests if a temporary file can be created, written to a specified path, read,
and then deleted. Especially useful with mounted file systems such as NFS or SMB.
The local temporary directory is always tested, regardless of whether the check is
called with or without parameters. May require sudo privileges."""

DEFAULT_PATH = [tempfile.gettempdir()]
DEFAULT_SEVERITY = 'warn'
Expand All @@ -51,7 +53,7 @@ def parse_args():

parser.add_argument('--path',
help='Path to which the file is to be written and from which it will be deleted '
'(repeating). Default: %(default)s',
'(repeating). Default: %(default)s',
dest='PATH',
default=DEFAULT_PATH,
action='append',
Expand Down Expand Up @@ -82,31 +84,26 @@ def main():
msg = ''
state = STATE_OK

filename = '__LINUXFABRIK_PATH_RW_TEST__'
content = 'Linuxfabrik GmbH, Zurich, Switzerland'
file_state = STATE_CRIT if args.SEVERITY == 'crit' else STATE_WARN

# do the test
for path in args.PATH:
file = os.path.join(path, filename)

# test writing the file
success, result = lib.disk.write_file(file, content)
if not success:
msg += '{}: {}{}, '.format(path, result, lib.base.state2str(file_state, prefix=' '))
state = file_state
else:
# test deleting the file
success, result = lib.disk.rm_file(file)
if not success:
msg += '{}: {}{}, '.format(path, result, lib.base.state2str(file_state, prefix=' '))
state = file_state
try:
fp = tempfile.TemporaryFile(dir=path)
# a bytes-like object is required, not 'str':
fp.write(b'Linuxfabrik GmbH, Zurich, Switzerland')
fp.seek(0)
fp.read()
# close the file, it will be removed
fp.close()
except Exception as e:
msg += '`{}` ({}), '.format(path, e)
state = lib.base.str2state(args.SEVERITY)

# build the message
if msg == '':
msg = 'Everything is ok.'
msg = 'Everything is ok. '
else:
msg = msg[:-2]
msg = 'Error creating/writing/reading/deleting file in {}. '.format(msg[:-2])
msg += 'Tested: {}'.format(', '.join(args.PATH))

# over and out
lib.base.oao(msg, state, always_ok=args.ALWAYS_OK)
Expand Down

0 comments on commit a62cd51

Please sign in to comment.