diff --git a/daemon/graphdriver/copy/copy.go b/daemon/graphdriver/copy/copy.go index 70ae9ce230..f8125403c4 100644 --- a/daemon/graphdriver/copy/copy.go +++ b/daemon/graphdriver/copy/copy.go @@ -2,14 +2,6 @@ package copy // import "github.com/docker/docker/daemon/graphdriver/copy" -/* -#include - -#ifndef FICLONE -#define FICLONE _IOW(0x94, 9, int) -#endif -*/ -import "C" import ( "container/list" "fmt" @@ -50,7 +42,7 @@ func copyRegular(srcPath, dstPath string, fileinfo os.FileInfo, copyWithFileRang defer dstFile.Close() if *copyWithFileClone { - _, _, err = unix.Syscall(unix.SYS_IOCTL, dstFile.Fd(), C.FICLONE, srcFile.Fd()) + err = fiClone(srcFile, dstFile) if err == nil { return nil } diff --git a/daemon/graphdriver/copy/copy_cgo.go b/daemon/graphdriver/copy/copy_cgo.go new file mode 100644 index 0000000000..6bd34864fb --- /dev/null +++ b/daemon/graphdriver/copy/copy_cgo.go @@ -0,0 +1,22 @@ +// +build linux,cgo + +package copy // import "github.com/docker/docker/daemon/graphdriver/copy" + +/* +#include + +#ifndef FICLONE +#define FICLONE _IOW(0x94, 9, int) +#endif +*/ +import "C" +import ( + "os" + + "golang.org/x/sys/unix" +) + +func fiClone(srcFile, dstFile *os.File) error { + _, _, err := unix.Syscall(unix.SYS_IOCTL, dstFile.Fd(), C.FICLONE, srcFile.Fd()) + return err +} diff --git a/daemon/graphdriver/copy/copy_nocgo.go b/daemon/graphdriver/copy/copy_nocgo.go new file mode 100644 index 0000000000..89e3c7f51e --- /dev/null +++ b/daemon/graphdriver/copy/copy_nocgo.go @@ -0,0 +1,13 @@ +// +build linux,!cgo + +package copy // import "github.com/docker/docker/daemon/graphdriver/copy" + +import ( + "os" + + "golang.org/x/sys/unix" +) + +func fiClone(srcFile, dstFile *os.File) error { + return unix.ENOSYS +} diff --git a/daemon/graphdriver/quota/projectquota.go b/daemon/graphdriver/quota/projectquota.go index 93e85823af..beda0f82c0 100644 --- a/daemon/graphdriver/quota/projectquota.go +++ b/daemon/graphdriver/quota/projectquota.go @@ -1,4 +1,4 @@ -// +build linux +// +build linux,!exclude_disk_quota // // projectquota.go - implements XFS project quota controls @@ -63,19 +63,6 @@ import ( "golang.org/x/sys/unix" ) -// Quota limit params - currently we only control blocks hard limit -type Quota struct { - Size uint64 -} - -// Control - Context to be used by storage driver (e.g. overlay) -// who wants to apply project quotas to container dirs -type Control struct { - backingFsBlockDev string - nextProjectID uint32 - quotas map[string]uint32 -} - // NewControl - initialize project quota support. // Test to make sure that quota can be set on a test dir and find // the first project id to be used for the next container create. @@ -166,9 +153,11 @@ func NewControl(basePath string) (*Control, error) { // SetQuota - assign a unique project id to directory and set the quota limits // for that project id func (q *Control) SetQuota(targetPath string, quota Quota) error { - + q.RLock() projectID, ok := q.quotas[targetPath] + q.RUnlock() if !ok { + q.Lock() projectID = q.nextProjectID // @@ -176,11 +165,12 @@ func (q *Control) SetQuota(targetPath string, quota Quota) error { // err := setProjectID(targetPath, projectID) if err != nil { + q.Unlock() return err } - q.quotas[targetPath] = projectID q.nextProjectID++ + q.Unlock() } // @@ -217,8 +207,9 @@ func setProjectQuota(backingFsBlockDev string, projectID uint32, quota Quota) er // GetQuota - get the quota limits of a directory that was configured with SetQuota func (q *Control) GetQuota(targetPath string, quota *Quota) error { - + q.RLock() projectID, ok := q.quotas[targetPath] + q.RUnlock() if !ok { return fmt.Errorf("quota not found for path : %s", targetPath) } @@ -289,6 +280,8 @@ func setProjectID(targetPath string, projectID uint32) error { // findNextProjectID - find the next project id to be used for containers // by scanning driver home directory to find used project ids func (q *Control) findNextProjectID(home string) error { + q.Lock() + defer q.Unlock() files, err := ioutil.ReadDir(home) if err != nil { return fmt.Errorf("read directory failed : %s", home) diff --git a/daemon/graphdriver/quota/projectquota_unsupported.go b/daemon/graphdriver/quota/projectquota_unsupported.go new file mode 100644 index 0000000000..7422d5b432 --- /dev/null +++ b/daemon/graphdriver/quota/projectquota_unsupported.go @@ -0,0 +1,18 @@ +// +build linux,exclude_disk_quota + +package quota // import "github.com/docker/docker/daemon/graphdriver/quota" + +func NewControl(basePath string) (*Control, error) { + return nil, ErrQuotaNotSupported +} + +// SetQuota - assign a unique project id to directory and set the quota limits +// for that project id +func (q *Control) SetQuota(targetPath string, quota Quota) error { + return ErrQuotaNotSupported +} + +// GetQuota - get the quota limits of a directory that was configured with SetQuota +func (q *Control) GetQuota(targetPath string, quota *Quota) error { + return ErrQuotaNotSupported +} diff --git a/daemon/graphdriver/quota/types.go b/daemon/graphdriver/quota/types.go new file mode 100644 index 0000000000..036c3249a1 --- /dev/null +++ b/daemon/graphdriver/quota/types.go @@ -0,0 +1,19 @@ +// +build linux + +package quota // import "github.com/docker/docker/daemon/graphdriver/quota" + +import "sync" + +// Quota limit params - currently we only control blocks hard limit +type Quota struct { + Size uint64 +} + +// Control - Context to be used by storage driver (e.g. overlay) +// who wants to apply project quotas to container dirs +type Control struct { + backingFsBlockDev string + sync.RWMutex // protect nextProjectID and quotas map + nextProjectID uint32 + quotas map[string]uint32 +} diff --git a/daemon/stats/collector_unix.go b/daemon/stats/collector_unix.go index 2480aceb51..dbc9e6081e 100644 --- a/daemon/stats/collector_unix.go +++ b/daemon/stats/collector_unix.go @@ -9,13 +9,9 @@ import ( "strings" "github.com/opencontainers/runc/libcontainer/system" + "golang.org/x/sys/unix" ) -/* -#include -*/ -import "C" - // platformNewStatsCollector performs platform specific initialisation of the // Collector structure. func platformNewStatsCollector(s *Collector) { @@ -71,13 +67,10 @@ func (s *Collector) getSystemCPUUsage() (uint64, error) { } func (s *Collector) getNumberOnlineCPUs() (uint32, error) { - i, err := C.sysconf(C._SC_NPROCESSORS_ONLN) - // According to POSIX - errno is undefined after successful - // sysconf, and can be non-zero in several cases, so look for - // error in returned value not in errno. - // (https://sourceware.org/bugzilla/show_bug.cgi?id=21536) - if i == -1 { + var cpuset unix.CPUSet + err := unix.SchedGetaffinity(0, &cpuset) + if err != nil { return 0, err } - return uint32(i), nil + return uint32(cpuset.Count()), nil }