Update add to tar to correctly handle hard links

This commit is contained in:
Priya Wadhwa 2018-03-07 15:34:14 -08:00
parent 3195b84c25
commit 6668fa0d6f
No known key found for this signature in database
GPG Key ID: 0D0DAFD8F7AA73AE
1 changed files with 33 additions and 2 deletions

View File

@ -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
}