From 6668fa0d6fe81a2632a071b07bfa74fb05a1bf1e Mon Sep 17 00:00:00 2001 From: Priya Wadhwa Date: Wed, 7 Mar 2018 15:34:14 -0800 Subject: [PATCH] Update add to tar to correctly handle hard links --- pkg/util/tar_util.go | 35 +++++++++++++++++++++++++++++++++-- 1 file changed, 33 insertions(+), 2 deletions(-) diff --git a/pkg/util/tar_util.go b/pkg/util/tar_util.go index 30e036c38..048200be8 100644 --- a/pkg/util/tar_util.go +++ b/pkg/util/tar_util.go @@ -18,10 +18,14 @@ package util import ( "archive/tar" + "github.com/sirupsen/logrus" "io" "os" + "syscall" ) +var hardlinks = make(map[uint64]string) + // AddToTar adds the file i to tar w at path p func AddToTar(p string, i os.FileInfo, w *tar.Writer) error { linkDst := "" @@ -32,19 +36,46 @@ func AddToTar(p string, i os.FileInfo, w *tar.Writer) error { return err } } + + hardlink := false + if sys := i.Sys(); sys != nil { + if stat, ok := sys.(*syscall.Stat_t); ok { + nlinks := stat.Nlink + if nlinks > 1 { + inode := stat.Ino + if original, exists := hardlinks[inode]; exists && original != p { + hardlink = true + logrus.Infof("%s inode exists in hardlinks map, linking to %s", p, original) + linkDst = original + } else { + hardlinks[inode] = p + } + } + } + } + hdr, err := tar.FileInfoHeader(i, linkDst) if err != nil { return err } hdr.Name = p - w.WriteHeader(hdr) - if !i.Mode().IsRegular() { + + if hardlink { + hdr.Linkname = linkDst + hdr.Typeflag = tar.TypeLink + hdr.Size = 0 + } + if err := w.WriteHeader(hdr); err != nil { + return err + } + if !(i.Mode().IsRegular()) || hardlink { return nil } r, err := os.Open(p) if err != nil { return err } + defer r.Close() if _, err := io.Copy(w, r); err != nil { return err }