Skip to content
This repository has been archived by the owner on Oct 13, 2023. It is now read-only.

Commit

Permalink
Graphdriver: fix "device" mode not being detected if "character-devic…
Browse files Browse the repository at this point in the history
…e" bit is set

Due to a bug in Golang (github.com/golang#27640), the "character device"
bit was omitted when checking file-modes with `os.ModeType`.

This bug was resolved in Go 1.12, but as a result, graphdrivers
would no longer recognize "device" files, causing pulling of
images that have a file with this filemode to fail;

    failed to register layer:
    unknown file type for /var/lib/docker/vfs/dir/.../dev/console

The current code checked for an exact match of Modes to be set. The
`os.ModeCharDevice` and `os.ModeDevice` bits will always be set in
tandem, however, because the code was only looking for an exact
match, this detection broke now that `os.ModeCharDevice` was added.

This patch changes the code to be more defensive, and instead
check if the `os.ModeDevice` bit is set (either with, or without
the `os.ModeCharDevice` bit).

In addition, some information was added to the error-message if
no type was matched, to assist debugging in case additional types
are added in future.

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
  • Loading branch information
thaJeztah committed Feb 20, 2019
1 parent c093c1e commit c7a38c2
Showing 1 changed file with 8 additions and 8 deletions.
16 changes: 8 additions & 8 deletions daemon/graphdriver/copy/copy.go
Original file line number Diff line number Diff line change
Expand Up @@ -152,8 +152,8 @@ func DirCopy(srcDir, dstDir string, copyMode Mode, copyXattrs bool) error {

isHardlink := false

switch f.Mode() & os.ModeType {
case 0: // Regular file
switch mode := f.Mode(); {
case mode.IsRegular():
id := fileID{dev: stat.Dev, ino: stat.Ino}
if copyMode == Hardlink {
isHardlink = true
Expand All @@ -171,12 +171,12 @@ func DirCopy(srcDir, dstDir string, copyMode Mode, copyXattrs bool) error {
copiedFiles[id] = dstPath
}

case os.ModeDir:
case mode.IsDir():
if err := os.Mkdir(dstPath, f.Mode()); err != nil && !os.IsExist(err) {
return err
}

case os.ModeSymlink:
case mode&os.ModeSymlink != 0:
link, err := os.Readlink(srcPath)
if err != nil {
return err
Expand All @@ -186,14 +186,14 @@ func DirCopy(srcDir, dstDir string, copyMode Mode, copyXattrs bool) error {
return err
}

case os.ModeNamedPipe:
case mode&os.ModeNamedPipe != 0:
fallthrough
case os.ModeSocket:
case mode&os.ModeSocket != 0:
if err := unix.Mkfifo(dstPath, stat.Mode); err != nil {
return err
}

case os.ModeDevice:
case mode&os.ModeDevice != 0:
if rsystem.RunningInUserNS() {
// cannot create a device if running in user namespace
return nil
Expand All @@ -203,7 +203,7 @@ func DirCopy(srcDir, dstDir string, copyMode Mode, copyXattrs bool) error {
}

default:
return fmt.Errorf("unknown file type for %s", srcPath)
return fmt.Errorf("unknown file type (%d / %s) for %s", f.Mode(), f.Mode().String(), srcPath)
}

// Everything below is copying metadata from src to dst. All this metadata
Expand Down

0 comments on commit c7a38c2

Please sign in to comment.