Revendor hcsshim to fix image import bug

This change brings in a single new commit from Microsoft/hcsshim. The
commit fixes an issue when unpacking a Windows container layer which
could result in incorrect directory timestamps.

This manifested most significantly in an impact to startup times of
some Windows container images (such as anything based on servercore).

Signed-off-by: Kevin Parsons <kevpar@microsoft.com>
This commit is contained in:
Kevin Parsons 2020-06-09 21:49:06 -07:00
parent a2282777c6
commit 2865478487
4 changed files with 23 additions and 16 deletions

View file

@ -1,5 +1,5 @@
github.com/Azure/go-ansiterm d6e3b3328b783f23731bc4d058875b0371ff8109 github.com/Azure/go-ansiterm d6e3b3328b783f23731bc4d058875b0371ff8109
github.com/Microsoft/hcsshim 5bc557dd210ff2caf615e6e22d398123de77fc11 # v0.8.9 github.com/Microsoft/hcsshim 9dcb42f100215f8d375b4a9265e5bba009217a85 # moby branch
github.com/Microsoft/go-winio 6c72808b55902eae4c5943626030429ff20f3b63 # v0.4.14 github.com/Microsoft/go-winio 6c72808b55902eae4c5943626030429ff20f3b63 # v0.4.14
github.com/docker/libtrust 9cbd2a1374f46905c68a4eb3694a130610adc62a github.com/docker/libtrust 9cbd2a1374f46905c68a4eb3694a130610adc62a
github.com/golang/gddo 72a348e765d293ed6d1ded7b699591f14d6cd921 github.com/golang/gddo 72a348e765d293ed6d1ded7b699591f14d6cd921

View file

@ -37,7 +37,7 @@ type dirInfo struct {
func reapplyDirectoryTimes(root *os.File, dis []dirInfo) error { func reapplyDirectoryTimes(root *os.File, dis []dirInfo) error {
for i := range dis { for i := range dis {
di := &dis[len(dis)-i-1] // reverse order: process child directories first di := &dis[len(dis)-i-1] // reverse order: process child directories first
f, err := safefile.OpenRelative(di.path, root, syscall.GENERIC_READ|syscall.GENERIC_WRITE, syscall.FILE_SHARE_READ, safefile.FILE_OPEN, safefile.FILE_DIRECTORY_FILE) f, err := safefile.OpenRelative(di.path, root, syscall.GENERIC_READ|syscall.GENERIC_WRITE, syscall.FILE_SHARE_READ, safefile.FILE_OPEN, safefile.FILE_DIRECTORY_FILE|syscall.FILE_FLAG_OPEN_REPARSE_POINT)
if err != nil { if err != nil {
return err return err
} }
@ -47,6 +47,7 @@ func reapplyDirectoryTimes(root *os.File, dis []dirInfo) error {
if err != nil { if err != nil {
return err return err
} }
} }
return nil return nil
} }
@ -93,10 +94,8 @@ func (w *baseLayerWriter) Add(name string, fileInfo *winio.FileBasicInfo) (err e
extraFlags := uint32(0) extraFlags := uint32(0)
if fileInfo.FileAttributes&syscall.FILE_ATTRIBUTE_DIRECTORY != 0 { if fileInfo.FileAttributes&syscall.FILE_ATTRIBUTE_DIRECTORY != 0 {
extraFlags |= safefile.FILE_DIRECTORY_FILE extraFlags |= safefile.FILE_DIRECTORY_FILE
if fileInfo.FileAttributes&syscall.FILE_ATTRIBUTE_REPARSE_POINT == 0 {
w.dirInfo = append(w.dirInfo, dirInfo{name, *fileInfo}) w.dirInfo = append(w.dirInfo, dirInfo{name, *fileInfo})
} }
}
mode := uint32(syscall.GENERIC_READ | syscall.GENERIC_WRITE | winio.WRITE_DAC | winio.WRITE_OWNER | winio.ACCESS_SYSTEM_SECURITY) mode := uint32(syscall.GENERIC_READ | syscall.GENERIC_WRITE | winio.WRITE_DAC | winio.WRITE_OWNER | winio.ACCESS_SYSTEM_SECURITY)
f, err = safefile.OpenRelative(name, w.root, mode, syscall.FILE_SHARE_READ, safefile.FILE_CREATE, extraFlags) f, err = safefile.OpenRelative(name, w.root, mode, syscall.FILE_SHARE_READ, safefile.FILE_CREATE, extraFlags)

View file

@ -93,6 +93,19 @@ func (r *legacyLayerWriterWrapper) Close() (err error) {
return err return err
} }
} }
// The reapplyDirectoryTimes must be called AFTER we are done with Tombstone
// deletion and hard link creation. This is because Tombstone deletion and hard link
// creation updates the directory last write timestamps so that will change the
// timestamps added by the `Add` call. Some container applications depend on the
// correctness of these timestamps and so we should change the timestamps back to
// the original value (i.e the value provided in the Add call) after this
// processing is done.
err = reapplyDirectoryTimes(r.destRoot, r.changedDi)
if err != nil {
return err
}
// Prepare the utility VM for use if one is present in the layer. // Prepare the utility VM for use if one is present in the layer.
if r.HasUtilityVM { if r.HasUtilityVM {
err := safefile.EnsureNotReparsePointRelative("UtilityVM", r.destRoot) err := safefile.EnsureNotReparsePointRelative("UtilityVM", r.destRoot)

View file

@ -341,7 +341,7 @@ type legacyLayerWriter struct {
backupWriter *winio.BackupFileWriter backupWriter *winio.BackupFileWriter
Tombstones []string Tombstones []string
HasUtilityVM bool HasUtilityVM bool
uvmDi []dirInfo changedDi []dirInfo
addedFiles map[string]bool addedFiles map[string]bool
PendingLinks []pendingLink PendingLinks []pendingLink
pendingDirs []pendingDir pendingDirs []pendingDir
@ -555,7 +555,7 @@ func cloneTree(srcRoot *os.File, destRoot *os.File, subPath string, mutatedFiles
if err != nil { if err != nil {
return err return err
} }
if isDir && !isReparsePoint { if isDir {
di = append(di, dirInfo{path: relPath, fileInfo: *fi}) di = append(di, dirInfo{path: relPath, fileInfo: *fi})
} }
} else { } else {
@ -583,6 +583,10 @@ func (w *legacyLayerWriter) Add(name string, fileInfo *winio.FileBasicInfo) erro
return w.initUtilityVM() return w.initUtilityVM()
} }
if (fileInfo.FileAttributes & syscall.FILE_ATTRIBUTE_DIRECTORY) != 0 {
w.changedDi = append(w.changedDi, dirInfo{path: name, fileInfo: *fileInfo})
}
name = filepath.Clean(name) name = filepath.Clean(name)
if hasPathPrefix(name, utilityVMPath) { if hasPathPrefix(name, utilityVMPath) {
if !w.HasUtilityVM { if !w.HasUtilityVM {
@ -612,9 +616,6 @@ func (w *legacyLayerWriter) Add(name string, fileInfo *winio.FileBasicInfo) erro
return err return err
} }
} }
if fileInfo.FileAttributes&syscall.FILE_ATTRIBUTE_REPARSE_POINT == 0 {
w.uvmDi = append(w.uvmDi, dirInfo{path: name, fileInfo: *fileInfo})
}
} else { } else {
// Overwrite any existing hard link. // Overwrite any existing hard link.
err := safefile.RemoveRelative(name, w.destRoot) err := safefile.RemoveRelative(name, w.destRoot)
@ -805,11 +806,5 @@ func (w *legacyLayerWriter) Close() error {
return err return err
} }
} }
if w.HasUtilityVM {
err := reapplyDirectoryTimes(w.destRoot, w.uvmDi)
if err != nil {
return err
}
}
return nil return nil
} }