Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Make the order of directory entries deterministic #242

Merged
merged 1 commit into from
Jan 18, 2021

Conversation

ktock
Copy link
Member

@ktock ktock commented Jan 18, 2021

Currently, *node.Readdir returns directory entries in undeterministic order
on each call. Though the order of directory entries is up to the filesystem
implementation, undeterministic order on each call results in that the
filesystem clients see random file name on each call of getdents even to the
same seek position in that directory. This commit fixes this issue by sorting
the directory entries by the name.

repro:

package main

import (
	"fmt"
	"os"
	"syscall"
)

func printEntry(f *os.File, position int64) error {
	if _, err := syscall.Seek(int(f.Fd()), position, 0); err != nil {
		return err
	}
	buf := make([]byte, 1024)
	if _, err := syscall.Getdents(int(f.Fd()), buf); err != nil {
		return err
	}
	names := make([]string, 0, 1)
	_, c, newnames := syscall.ParseDirent(buf, 1, names)
	if c < 1 {
		return fmt.Errorf("at least one entry must be parsed")
	}
	fmt.Println(position, ":", newnames[0])
	return nil
}

func main() {
	f, err := os.Open("/usr/local/go/src/runtime")
	if err != nil {
		fmt.Println("Open", err)
		return
	}
	defer f.Close()

	if err := printEntry(f, 10); err != nil {
		panic(err)
	}
	if err := printEntry(f, 10); err != nil {
		panic(err)
	}
}

On the host (expected):

10 : defs_darwin_arm64.go
10 : defs_darwin_arm64.go

In the container (unexpected):

10 : atomic_ppc64x.s
10 : error.go

Currently, `*node.Readdir` returns directory entries in undeterministic order
*on each call*. Though the order of directory entries is up to the filesystem
implementation, undeterministic order *on each call* results in that the
filesystem clients see random file name on each call of `getdents` even to the
same seek position in that directory. This commit fixes this issue by sorting
the directory entries by the name.

Signed-off-by: Kohei Tokunaga <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants