Update add to tar to correctly handle hard links
This commit is contained in:
parent
3195b84c25
commit
6668fa0d6f
|
|
@ -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
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue