aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBryn M. Reeves <bmr@redhat.com>2014-10-20 16:12:01 +0100
committerBryn M. Reeves <bmr@redhat.com>2014-10-20 16:12:01 +0100
commit48a99c95078bab306cb56bb1a05420d88bf15a64 (patch)
tree00e16abc1775098f3b9746870d1fe4dc2919b8e1
parent6ce502113f550c027424fa477edc091283c32e50 (diff)
downloadsos-48a99c95078bab306cb56bb1a05420d88bf15a64.tar.gz
[plugin] limit names to PC_NAME_MAX
Commit 8bf7b0c removed the truncation of mangled command names to 64 chars. This causes problems for some plugins (e.g. Issue #415) that generate long enough command lines to hit system name length limits. Instead of arbitrarily limiting to 64 characters limit to the lesser of the archive format limit (if present) or the value of PC_NAME_MAX for any intermediate FileCacheArchive path. Signed-off-by: Bryn M. Reeves <bmr@redhat.com>
-rw-r--r--sos/archive.py18
-rw-r--r--sos/plugins/__init__.py7
-rw-r--r--tests/plugin_tests.py12
3 files changed, 30 insertions, 7 deletions
diff --git a/sos/archive.py b/sos/archive.py
index 2e42bbd0..60636251 100644
--- a/sos/archive.py
+++ b/sos/archive.py
@@ -98,6 +98,12 @@ class Archive(object):
to be included in the generated archive."""
raise NotImplementedError
+ def name_max(self):
+ """Return the maximum file name length this archive can support.
+ This is the lesser of the name length limit of the archive
+ format and any temporary file system based cache."""
+ raise NotImplementedError
+
def get_archive_path(self):
"""Return a string representing the path to the temporary
archive. For archive classes that implement in-line handling
@@ -206,6 +212,13 @@ class FileCacheArchive(Archive):
def _makedirs(self, path, mode=0o700):
os.makedirs(path, mode)
+ def name_max(self):
+ if 'PC_NAME_MAX' in os.pathconf_names:
+ pc_name_max = os.pathconf_names['PC_NAME_MAX']
+ return os.pathconf(self._archive_root, pc_name_max)
+ else:
+ return 255
+
def get_tmp_dir(self):
return self._archive_root
@@ -355,6 +368,11 @@ class TarFileArchive(FileCacheArchive):
def name(self):
return "%s.%s" % (self._name, self._suffix)
+ def name_max(self):
+ # GNU Tar format supports unlimited file name length. Just return
+ # the limit of the underlying FileCacheArchive.
+ return super(TarFileArchive, self).name_max()
+
def _build_archive(self):
# python2.6 TarFile lacks the filter parameter
if not six.PY3 and sys.version_info[1] < 7:
diff --git a/sos/plugins/__init__.py b/sos/plugins/__init__.py
index 3e391005..b2891444 100644
--- a/sos/plugins/__init__.py
+++ b/sos/plugins/__init__.py
@@ -42,11 +42,11 @@ def regex_findall(regex, fname):
return []
-def _mangle_command(command):
- # FIXME: this can be improved
+def _mangle_command(command, name_max):
mangledname = re.sub(r"^/(usr/|)(bin|sbin)/", "", command)
mangledname = re.sub(r"[^\w\-\.\/]+", "_", mangledname)
mangledname = re.sub(r"/", ".", mangledname).strip(" ._-")
+ mangledname = mangledname[0:name_max]
return mangledname
@@ -518,7 +518,8 @@ class Plugin(object):
return grep(regexp, *fnames)
def _mangle_command(self, exe):
- return _mangle_command(exe)
+ name_max = self.archive.name_max()
+ return _mangle_command(exe, name_max)
def _make_command_filename(self, exe):
"""The internal function to build up a filename based on a command."""
diff --git a/tests/plugin_tests.py b/tests/plugin_tests.py
index 817e4f23..f73a003a 100644
--- a/tests/plugin_tests.py
+++ b/tests/plugin_tests.py
@@ -115,10 +115,14 @@ class PluginToolTests(unittest.TestCase):
self.assertEquals(matches, [])
def test_mangle_command(self):
- self.assertEquals("foo", _mangle_command("/usr/bin/foo"))
- self.assertEquals("foo_-x", _mangle_command("/usr/bin/foo -x"))
- self.assertEquals("foo_--verbose", _mangle_command("/usr/bin/foo --verbose"))
- self.assertEquals("foo_.path.to.stuff", _mangle_command("/usr/bin/foo /path/to/stuff"))
+ name_max = 255
+ self.assertEquals("foo", _mangle_command("/usr/bin/foo", name_max))
+ self.assertEquals("foo_-x", _mangle_command("/usr/bin/foo -x", name_max))
+ self.assertEquals("foo_--verbose", _mangle_command("/usr/bin/foo --verbose", name_max))
+ self.assertEquals("foo_.path.to.stuff", _mangle_command("/usr/bin/foo /path/to/stuff", name_max))
+ longcmd ="foo is " + "a" * 256 + " long_command"
+ expected = longcmd[0:name_max].replace(' ', '_')
+ self.assertEquals(expected, _mangle_command(longcmd, name_max))
class PluginTests(unittest.TestCase):