1
0
Fork 0
mirror of https://github.com/moby/moby.git synced 2022-11-09 12:21:53 -05:00

Image: Fix time setting for old kernels

This is a better fix for futimes() on kernels not supporting O_PATH.
The previous fix broke when copying a device, as it tried to open it
and got and error.
This commit is contained in:
Alexander Larsson 2013-09-26 21:12:12 +02:00 committed by Tianon Gravi
parent 152302e379
commit 55e1782d66

View file

@ -151,6 +151,7 @@ func (image *Image) TarLayer(compression Compression) (Archive, error) {
type TimeUpdate struct { type TimeUpdate struct {
path string path string
time []syscall.Timeval time []syscall.Timeval
mode uint32
} }
func (image *Image) applyLayer(layer, target string) error { func (image *Image) applyLayer(layer, target string) error {
@ -291,6 +292,7 @@ func (image *Image) applyLayer(layer, target string) error {
u := TimeUpdate{ u := TimeUpdate{
path: targetPath, path: targetPath,
time: ts, time: ts,
mode: srcStat.Mode,
} }
// Delay time updates until all other changes done, or it is // Delay time updates until all other changes done, or it is
@ -308,21 +310,24 @@ func (image *Image) applyLayer(layer, target string) error {
update := updateTimes[i] update := updateTimes[i]
O_PATH := 010000000 // Not in syscall yet O_PATH := 010000000 // Not in syscall yet
fd, err := syscall.Open(update.path, syscall.O_RDWR|O_PATH|syscall.O_NOFOLLOW, 0600) var err error = nil
if err == syscall.EISDIR || err == syscall.ELOOP { if update.mode&syscall.S_IFLNK == syscall.S_IFLNK {
// O_PATH not supported, use Utimes except on symlinks where Utimes doesn't work // Update time on the symlink via O_PATH + futimes(), if supported by the kernel
if err != syscall.ELOOP {
err = syscall.Utimes(update.path, update.time) fd, err := syscall.Open(update.path, syscall.O_RDWR|O_PATH|syscall.O_NOFOLLOW, 0600)
if err != nil { if err == syscall.EISDIR || err == syscall.ELOOP {
return err // O_PATH not supported by kernel, nothing to do, ignore
} } else if err != nil {
return err
} else {
syscall.Futimes(fd, update.time)
_ = syscall.Close(fd)
} }
} else { } else {
err = syscall.Utimes(update.path, update.time)
if err != nil { if err != nil {
return err return err
} }
syscall.Futimes(fd, update.time)
_ = syscall.Close(fd)
} }
} }