diff options
author | Bryn M. Reeves <bmr@redhat.com> | 2012-11-30 16:55:15 +0000 |
---|---|---|
committer | Bryn M. Reeves <bmr@redhat.com> | 2012-11-30 16:55:15 +0000 |
commit | cc5313646f61a5272073bfac012e7bf6c1367311 (patch) | |
tree | c2cee41b68370e3e1e3d881208a27fd85fca9639 | |
parent | b43b3458042a863627aab4ebc82d84dafae1e437 (diff) | |
download | sos-cc5313646f61a5272073bfac012e7bf6c1367311.tar.gz |
Fix symlink handling in doCopyFileOrDir()
Symlinks need special treatment when we're copying them into the
report. The target path stored in the report must always be
relative but we need to pass an absolute path for the target to
the recursive doCopyFileOrDir() call that picks up the target for
us.
There are further problems with the current code but these cannot
be fixed trivially: symbolic links to directories are currently
ignored but are fundamental to the layout of file systems like sys
(and to a lesser extent proc). Supporting this properly requires
an algorithm that can cope with arbitrary symlink loops in the
tree being copied and that correctly copies-in any links that may
point outside of the tree currently being copied.
See Issues #71, #72 for more details.
-rw-r--r-- | sos/plugins/__init__.py | 49 |
1 files changed, 34 insertions, 15 deletions
diff --git a/sos/plugins/__init__.py b/sos/plugins/__init__.py index edd7b73e..63adc94c 100644 --- a/sos/plugins/__init__.py +++ b/sos/plugins/__init__.py @@ -196,31 +196,50 @@ class Plugin(object): return False def copy_symlink(self, srcpath, sub=None): - link = os.readlink(srcpath) - if not os.path.isabs(link): - link = os.path.normpath( - os.path.join( - os.path.dirname(srcpath), - link) - ) - - if os.path.isdir(link): - self.soslog.debug("link %s is a directory, skipping..." % link) + # the target stored in the original symlink + linkdest = os.readlink(srcpath) + self.soslog.debug("copying link %s pointing to %s with sub=%s" + % (srcpath, linkdest, sub)) + + if os.path.isdir(linkdest): + self.soslog.debug("link %s is a directory, skipping..." + % linkdest) return - dest = link + # adjust the target used inside the report to always be relative + if os.path.isabs(linkdest): + adjdest = os.path.relpath(linkdest, + os.path.dirname(srcpath)) + self.soslog.debug("made link target %s relative as %s" + % (linkdest, adjdest)) + else: + adjdest = linkdest if sub: old, new = sub - dest = srcpath.replace(old, new) + adjdest = srcpath.replace(old, new) + + self.archive.add_link(adjdest,srcpath) + + # copy the symlink target translating relative targets + # to absolute paths to pass to doCopyFileOrDir. + self.soslog.debug("copying target %s for link %s" + % (linkdest, srcpath)) - self.archive.add_file(link, dest=dest) + if(os.path.isabs(linkdest)): + self.doCopyFileOrDir(linkdest) + else: + absdest = os.path.normpath(os.path.join( + os.path.dirname(srcpath), linkdest)) + self.soslog.debug("normalized link target %s as %s" + %(linkdest, absdest)) + self.doCopyFileOrDir(absdest) self.copiedFiles.append({ 'srcpath':srcpath, - 'dstpath':dest, + 'dstpath':srcpath, 'symlink':"yes", - 'pointsto':link}) + 'pointsto':linkdest}) def copy_dir(self, srcpath, sub=None): for afile in os.listdir(srcpath): |