mirror of
https://github.com/clearlinux/rkt.git
synced 2026-08-27 10:56:02 +00:00
Merge pull request #222 from jonboulle/hardlinks
actool: properly deal with hardlinks when building images
This commit is contained in:
@@ -37,6 +37,8 @@ func init() {
|
||||
}
|
||||
|
||||
func buildWalker(root string, aw aci.ArchiveWriter, rootfs bool) filepath.WalkFunc {
|
||||
// cache of inode -> filepath, used to leverage hard links in the archive
|
||||
inos := map[uint64]string{}
|
||||
return func(path string, info os.FileInfo, err error) error {
|
||||
if err != nil {
|
||||
return err
|
||||
@@ -81,7 +83,12 @@ func buildWalker(root string, aw aci.ArchiveWriter, rootfs bool) filepath.WalkFu
|
||||
// modify the Name field of the returned header to provide the
|
||||
// full path name of the file.
|
||||
hdr.Name = relpath
|
||||
tarheader.Populate(hdr, info)
|
||||
tarheader.Populate(hdr, info, inos)
|
||||
// If the file is a hard link we don't need the contents
|
||||
if hdr.Typeflag == tar.TypeLink {
|
||||
hdr.Size = 0
|
||||
file = nil
|
||||
}
|
||||
aw.AddFile(relpath, hdr, file)
|
||||
|
||||
return nil
|
||||
|
||||
@@ -13,7 +13,7 @@ func init() {
|
||||
populateHeaderStat = append(populateHeaderStat, populateHeaderCtime)
|
||||
}
|
||||
|
||||
func populateHeaderCtime(h *tar.Header, fi os.FileInfo) {
|
||||
func populateHeaderCtime(h *tar.Header, fi os.FileInfo, _ map[uint64]string) {
|
||||
st, ok := fi.Sys().(*syscall.Stat_t)
|
||||
if !ok {
|
||||
return
|
||||
|
||||
@@ -11,7 +11,7 @@ func init() {
|
||||
populateHeaderStat = append(populateHeaderStat, populateHeaderCtime)
|
||||
}
|
||||
|
||||
func populateHeaderCtime(h *tar.Header, fi os.FileInfo) {
|
||||
func populateHeaderCtime(h *tar.Header, fi os.FileInfo, _ map[uint64]string) {
|
||||
st, ok := fi.Sys().(*syscall.Stat_t)
|
||||
if !ok {
|
||||
return
|
||||
|
||||
@@ -10,11 +10,19 @@ func init() {
|
||||
populateHeaderStat = append(populateHeaderStat, populateHeaderUnix)
|
||||
}
|
||||
|
||||
func populateHeaderUnix(h *tar.Header, fi os.FileInfo) {
|
||||
func populateHeaderUnix(h *tar.Header, fi os.FileInfo, seen map[uint64]string) {
|
||||
st, ok := fi.Sys().(*syscall.Stat_t)
|
||||
if !ok {
|
||||
return
|
||||
}
|
||||
h.Uid = int(st.Uid)
|
||||
h.Gid = int(st.Gid)
|
||||
// If we have already seen this inode, generate a hardlink
|
||||
p, ok := seen[uint64(st.Ino)]
|
||||
if ok {
|
||||
h.Linkname = p
|
||||
h.Typeflag = tar.TypeLink
|
||||
} else {
|
||||
seen[uint64(st.Ino)] = h.Name
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,10 +5,10 @@ import (
|
||||
"os"
|
||||
)
|
||||
|
||||
var populateHeaderStat []func(h *tar.Header, fi os.FileInfo)
|
||||
var populateHeaderStat []func(h *tar.Header, fi os.FileInfo, seen map[uint64]string)
|
||||
|
||||
func Populate(h *tar.Header, fi os.FileInfo) {
|
||||
func Populate(h *tar.Header, fi os.FileInfo, seen map[uint64]string) {
|
||||
for _, pop := range populateHeaderStat {
|
||||
pop(h, fi)
|
||||
pop(h, fi, seen)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user