aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBryn M. Reeves <bmr@redhat.com>2012-11-30 16:55:15 +0000
committerBryn M. Reeves <bmr@redhat.com>2012-11-30 16:55:15 +0000
commitcc5313646f61a5272073bfac012e7bf6c1367311 (patch)
treec2cee41b68370e3e1e3d881208a27fd85fca9639
parentb43b3458042a863627aab4ebc82d84dafae1e437 (diff)
downloadsos-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__.py49
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):