diff options
author | Bryn M. Reeves <bmr@redhat.com> | 2014-07-04 14:29:11 +0100 |
---|---|---|
committer | Bryn M. Reeves <bmr@redhat.com> | 2014-07-04 14:45:34 +0100 |
commit | 4dbba1371ada73ccf0bd1c05ebb3d161d3bd7d08 (patch) | |
tree | b1b57623a0b35b6ee1219260c28a10f59b28928e | |
parent | 65c47f29b469f4b622dea4f01bbc3931fce8450f (diff) | |
download | sos-4dbba1371ada73ccf0bd1c05ebb3d161d3bd7d08.tar.gz |
[archive, plugin] handle special file system nodes
Historically sos has ignored all types of file system node that
are not regular files or directories. Add support for collecting
block, character, fifo and socket special nodes by creating
matching nodes in the archive and propagating permissions from
the host file system.
Signed-off-by: Bryn M. Reeves <bmr@redhat.com>
-rw-r--r-- | sos/archive.py | 10 | ||||
-rw-r--r-- | sos/plugins/__init__.py | 30 |
2 files changed, 36 insertions, 4 deletions
diff --git a/sos/archive.py b/sos/archive.py index bfc8a120..c38e5f64 100644 --- a/sos/archive.py +++ b/sos/archive.py @@ -79,6 +79,9 @@ class Archive(object): def add_dir(self, path): raise NotImplementedError + def add_node(self, path, mode, device): + raise NotImplementedError + def get_tmp_dir(self): """Return a temporary directory that clients of the archive may use to write content to. The content of the path is guaranteed @@ -180,6 +183,13 @@ class FileCacheArchive(Archive): def add_dir(self, path): self.makedirs(path) + def add_node(self, path, mode, device): + dest = self.dest_path(path) + self._check_path(dest) + if not os.path.exists(dest): + os.mknod(dest, mode, device) + shutil.copystat(path, dest) + def _makedirs(self, path, mode=0o700): os.makedirs(path, mode) diff --git a/sos/plugins/__init__.py b/sos/plugins/__init__.py index eac78153..4c34bda9 100644 --- a/sos/plugins/__init__.py +++ b/sos/plugins/__init__.py @@ -63,6 +63,20 @@ def mangle_command(command): def _path_in_path_list(path, path_list): return any(p in path for p in path_list) +def _node_type(st): + """ return a string indicating the type of special node represented by + the stat buffer st (block, character, fifo, socket). + """ + _types = [ + ( stat.S_ISBLK, "block device" ), + ( stat.S_ISCHR, "character device" ), + ( stat.S_ISFIFO, "named pipe" ), + ( stat.S_ISSOCK, "socket" ) + ] + for t in _types: + if t[0](st.st_mode): + return t[1] + class Plugin(object): """ This is the base class for sosreport plugins. Plugins should subclass this and set the class variables where applicable. @@ -276,6 +290,12 @@ class Plugin(object): def is_forbidden_path(self, path): return _path_in_path_list(path, self.forbidden_paths) + def copy_node(self, path, st): + dev_maj = os.major(st.st_rdev) + dev_min = os.minor(st.st_rdev) + mode = st.st_mode + self.archive.add_node(path, mode, os.makedev(dev_maj, dev_min)) + # Methods for copying files and shelling out def do_copy_path(self, srcpath, dest=None): # pylint: disable-msg = R0912 @@ -305,10 +325,12 @@ class Plugin(object): self.copy_dir(srcpath) return - # filter out device nodes - if stat.S_ISBLK(st.st_mode) or stat.S_ISCHR(st.st_mode): - devtype = "block" if stat.S_ISBLK(stat.st_mode) else "character" - self.log_debug("skipping %s device node %s" % (devtype, srcpath)) + # handle special nodes (block, char, fifo, socket) + if not (stat.S_ISREG(st.st_mode) or stat.S_ISDIR(st.st_mode)): + ntype = _node_type(st) + self.log_debug("creating %s node at archive:'%s'" % (ntype, srcpath)) + self.copy_node(srcpath, st) + return # if we get here, it's definitely a regular file (not a symlink or dir) self.log_debug("copying path '%s' to archive:'%s'" % (srcpath,dest)) |