summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBrian Coca <bcoca@users.noreply.github.com>2021-03-23 10:27:53 -0400
committerGitHub <noreply@github.com>2021-03-23 10:27:53 -0400
commit232eeee206df090448c3f8889b3430c6f3c42632 (patch)
tree5faed60f456ebeea3d4a01674138dc95cf0b83d8
parent2bff120db6bf96dd0085c6ce1b29f3999b872db4 (diff)
downloadansible-232eeee206df090448c3f8889b3430c6f3c42632.tar.gz
less blocking on fact reading (#73951)
* less blocking on fact reading Co-authored-by: Martin Krizek <martin.krizek@gmail.com>
-rw-r--r--changelogs/fragments/less_blocks_on_facts.yml2
-rw-r--r--lib/ansible/module_utils/facts/utils.py41
2 files changed, 33 insertions, 10 deletions
diff --git a/changelogs/fragments/less_blocks_on_facts.yml b/changelogs/fragments/less_blocks_on_facts.yml
new file mode 100644
index 0000000000..68407df122
--- /dev/null
+++ b/changelogs/fragments/less_blocks_on_facts.yml
@@ -0,0 +1,2 @@
+bugfixes:
+ - Try to avoid kernel 'blocking' state on reading files while fact gathering.
diff --git a/lib/ansible/module_utils/facts/utils.py b/lib/ansible/module_utils/facts/utils.py
index 9fd00afd49..08d59c036f 100644
--- a/lib/ansible/module_utils/facts/utils.py
+++ b/lib/ansible/module_utils/facts/utils.py
@@ -16,26 +16,47 @@
from __future__ import (absolute_import, division, print_function)
__metaclass__ = type
+import fcntl
import os
def get_file_content(path, default=None, strip=True):
+ '''
+ Return the contents of a given file path
+
+ :args path: path to file to return contents from
+ :args default: value to return if we could not read file
+ :args strip: controls if we strip whitespace from the result or not
+
+ :returns: String with file contents (optionally stripped) or 'default' value
+ '''
data = default
if os.path.exists(path) and os.access(path, os.R_OK):
try:
+ datafile = open(path)
try:
- datafile = open(path)
- data = datafile.read()
- if strip:
- data = data.strip()
- if len(data) == 0:
- data = default
- finally:
- datafile.close()
+ # try to not enter kernel 'block' mode, which prevents timeouts
+ fd = datafile.fileno()
+ flag = fcntl.fcntl(fd, fcntl.F_GETFL)
+ fcntl.fcntl(fd, fcntl.F_SETFL, flag | os.O_NONBLOCK)
+ except Exception:
+ pass # not required to operate, but would have been nice!
+
+ # actually read the data
+ data = datafile.read()
+
+ if strip:
+ data = data.strip()
+
+ if len(data) == 0:
+ data = default
+
except Exception:
- # ignore errors as some jails/containers might have readable permissions but not allow reads to proc
- # done in 2 blocks for 2.4 compat
+ # ignore errors as some jails/containers might have readable permissions but not allow reads
pass
+ finally:
+ datafile.close()
+
return data