diff options
author | Bryn M. Reeves <bmr@redhat.com> | 2018-09-11 12:16:57 -0400 |
---|---|---|
committer | Bryn M. Reeves <bmr@redhat.com> | 2018-09-11 12:16:57 -0400 |
commit | 919e8671a6ab9684d59525eb7f3607b3aab08ee1 (patch) | |
tree | 343f74f386f03d6fabd61cb4926cbdaeab4fa5c0 | |
parent | 3a2453c186084a2b7ef15702775809a76e13c45c (diff) | |
download | sos-919e8671a6ab9684d59525eb7f3607b3aab08ee1.tar.gz |
[archive] fix link rewriting logic in FileCacheArchive.add_link()
When processing link follow up for an original symbolic link, the
add_link() logic incorrectly used the _original_ host link name,
rather than the to-be-created name when calculating relative path
structures. If the prior link is at a greater or lesser level of
directory nesting this will lead to broken relative links in the
archive (one level too high or too low).
In some cases (systemd) this behaviour was masked due to the fact
that identically named links exist at multiple levels of the path
hierarchy.
Signed-off-by: Bryn M. Reeves <bmr@redhat.com>
-rw-r--r-- | sos/archive.py | 30 |
1 files changed, 19 insertions, 11 deletions
diff --git a/sos/archive.py b/sos/archive.py index 528cfa57..7a7717de 100644 --- a/sos/archive.py +++ b/sos/archive.py @@ -417,27 +417,35 @@ class FileCacheArchive(Archive): # Follow-up must be outside the path lock: we recurse into # other monitor methods that will attempt to reacquire it. + self.log_debug("Link follow up: source=%s link_name=%s dest=%s" % + (source, link_name, dest)) + source_dir = os.path.dirname(link_name) - host_source = os.path.join(source_dir, source) - if not os.path.exists(self.dest_path(host_source)): - if os.path.islink(host_source): - link_dir = os.path.dirname(link_name) - link_name = os.path.normpath(os.path.join(link_dir, source)) + host_path_name = os.path.normpath(os.path.join(source_dir, source)) + dest_path_name = self.dest_path(host_path_name) + + if not os.path.exists(dest_path_name): + if os.path.islink(host_path_name): + # Normalised path for the new link_name + link_name = host_path_name + # Containing directory for the new link dest_dir = os.path.dirname(link_name) - source = os.path.join(dest_dir, os.readlink(link_name)) - source = os.path.relpath(source) + # Relative source path of the new link + source = os.path.join(dest_dir, os.readlink(host_path_name)) + source = os.path.relpath(source, dest_dir) self.log_debug("Adding link %s -> %s for link follow up" % (link_name, source)) self.add_link(source, link_name) - elif os.path.isdir(host_source): + elif os.path.isdir(host_path_name): self.log_debug("Adding dir %s for link follow up" % source) - self.add_dir(host_source) - elif os.path.isfile(host_source): + self.add_dir(host_path_name) + elif os.path.isfile(host_path_name): self.log_debug("Adding file %s for link follow up" % source) - self.add_file(host_source) + self.add_file(host_path_name) else: self.log_debug("No link follow up: source=%s link_name=%s" % (source, link_name)) + self.log_debug("leaving add_link()") def add_dir(self, path): """Create a directory in the archive. |