Vendor in latest containers/storage
Fixes store.lock issue comming up when using store.Names Signed-off-by: umohnani8 <umohnani@redhat.com>
This commit is contained in:
parent
400713a58b
commit
cfc2393d58
119 changed files with 2846 additions and 1730 deletions
17
vendor/github.com/containers/storage/pkg/system/chtimes.go
generated
vendored
17
vendor/github.com/containers/storage/pkg/system/chtimes.go
generated
vendored
|
@ -2,26 +2,9 @@ package system
|
|||
|
||||
import (
|
||||
"os"
|
||||
"syscall"
|
||||
"time"
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
var (
|
||||
maxTime time.Time
|
||||
)
|
||||
|
||||
func init() {
|
||||
if unsafe.Sizeof(syscall.Timespec{}.Nsec) == 8 {
|
||||
// This is a 64 bit timespec
|
||||
// os.Chtimes limits time to the following
|
||||
maxTime = time.Unix(0, 1<<63-1)
|
||||
} else {
|
||||
// This is a 32 bit timespec
|
||||
maxTime = time.Unix(1<<31-1, 0)
|
||||
}
|
||||
}
|
||||
|
||||
// Chtimes changes the access time and modified time of a file at the given path
|
||||
func Chtimes(name string, atime time.Time, mtime time.Time) error {
|
||||
unixMinTime := time.Unix(0, 0)
|
||||
|
|
19
vendor/github.com/containers/storage/pkg/system/chtimes_windows.go
generated
vendored
19
vendor/github.com/containers/storage/pkg/system/chtimes_windows.go
generated
vendored
|
@ -3,25 +3,26 @@
|
|||
package system
|
||||
|
||||
import (
|
||||
"syscall"
|
||||
"time"
|
||||
|
||||
"golang.org/x/sys/windows"
|
||||
)
|
||||
|
||||
//setCTime will set the create time on a file. On Windows, this requires
|
||||
//calling SetFileTime and explicitly including the create time.
|
||||
func setCTime(path string, ctime time.Time) error {
|
||||
ctimespec := syscall.NsecToTimespec(ctime.UnixNano())
|
||||
pathp, e := syscall.UTF16PtrFromString(path)
|
||||
ctimespec := windows.NsecToTimespec(ctime.UnixNano())
|
||||
pathp, e := windows.UTF16PtrFromString(path)
|
||||
if e != nil {
|
||||
return e
|
||||
}
|
||||
h, e := syscall.CreateFile(pathp,
|
||||
syscall.FILE_WRITE_ATTRIBUTES, syscall.FILE_SHARE_WRITE, nil,
|
||||
syscall.OPEN_EXISTING, syscall.FILE_FLAG_BACKUP_SEMANTICS, 0)
|
||||
h, e := windows.CreateFile(pathp,
|
||||
windows.FILE_WRITE_ATTRIBUTES, windows.FILE_SHARE_WRITE, nil,
|
||||
windows.OPEN_EXISTING, windows.FILE_FLAG_BACKUP_SEMANTICS, 0)
|
||||
if e != nil {
|
||||
return e
|
||||
}
|
||||
defer syscall.Close(h)
|
||||
c := syscall.NsecToFiletime(syscall.TimespecToNsec(ctimespec))
|
||||
return syscall.SetFileTime(h, &c, nil, nil)
|
||||
defer windows.Close(h)
|
||||
c := windows.NsecToFiletime(windows.TimespecToNsec(ctimespec))
|
||||
return windows.SetFileTime(h, &c, nil, nil)
|
||||
}
|
||||
|
|
83
vendor/github.com/containers/storage/pkg/system/events_windows.go
generated
vendored
83
vendor/github.com/containers/storage/pkg/system/events_windows.go
generated
vendored
|
@ -1,83 +0,0 @@
|
|||
package system
|
||||
|
||||
// This file implements syscalls for Win32 events which are not implemented
|
||||
// in golang.
|
||||
|
||||
import (
|
||||
"syscall"
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
var (
|
||||
procCreateEvent = modkernel32.NewProc("CreateEventW")
|
||||
procOpenEvent = modkernel32.NewProc("OpenEventW")
|
||||
procSetEvent = modkernel32.NewProc("SetEvent")
|
||||
procResetEvent = modkernel32.NewProc("ResetEvent")
|
||||
procPulseEvent = modkernel32.NewProc("PulseEvent")
|
||||
)
|
||||
|
||||
// CreateEvent implements win32 CreateEventW func in golang. It will create an event object.
|
||||
func CreateEvent(eventAttributes *syscall.SecurityAttributes, manualReset bool, initialState bool, name string) (handle syscall.Handle, err error) {
|
||||
namep, _ := syscall.UTF16PtrFromString(name)
|
||||
var _p1 uint32
|
||||
if manualReset {
|
||||
_p1 = 1
|
||||
}
|
||||
var _p2 uint32
|
||||
if initialState {
|
||||
_p2 = 1
|
||||
}
|
||||
r0, _, e1 := procCreateEvent.Call(uintptr(unsafe.Pointer(eventAttributes)), uintptr(_p1), uintptr(_p2), uintptr(unsafe.Pointer(namep)))
|
||||
use(unsafe.Pointer(namep))
|
||||
handle = syscall.Handle(r0)
|
||||
if handle == syscall.InvalidHandle {
|
||||
err = e1
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// OpenEvent implements win32 OpenEventW func in golang. It opens an event object.
|
||||
func OpenEvent(desiredAccess uint32, inheritHandle bool, name string) (handle syscall.Handle, err error) {
|
||||
namep, _ := syscall.UTF16PtrFromString(name)
|
||||
var _p1 uint32
|
||||
if inheritHandle {
|
||||
_p1 = 1
|
||||
}
|
||||
r0, _, e1 := procOpenEvent.Call(uintptr(desiredAccess), uintptr(_p1), uintptr(unsafe.Pointer(namep)))
|
||||
use(unsafe.Pointer(namep))
|
||||
handle = syscall.Handle(r0)
|
||||
if handle == syscall.InvalidHandle {
|
||||
err = e1
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// SetEvent implements win32 SetEvent func in golang.
|
||||
func SetEvent(handle syscall.Handle) (err error) {
|
||||
return setResetPulse(handle, procSetEvent)
|
||||
}
|
||||
|
||||
// ResetEvent implements win32 ResetEvent func in golang.
|
||||
func ResetEvent(handle syscall.Handle) (err error) {
|
||||
return setResetPulse(handle, procResetEvent)
|
||||
}
|
||||
|
||||
// PulseEvent implements win32 PulseEvent func in golang.
|
||||
func PulseEvent(handle syscall.Handle) (err error) {
|
||||
return setResetPulse(handle, procPulseEvent)
|
||||
}
|
||||
|
||||
func setResetPulse(handle syscall.Handle, proc *syscall.LazyProc) (err error) {
|
||||
r0, _, _ := proc.Call(uintptr(handle))
|
||||
if r0 != 0 {
|
||||
err = syscall.Errno(r0)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
var temp unsafe.Pointer
|
||||
|
||||
// use ensures a variable is kept alive without the GC freeing while still needed
|
||||
func use(p unsafe.Pointer) {
|
||||
temp = p
|
||||
}
|
33
vendor/github.com/containers/storage/pkg/system/exitcode.go
generated
vendored
Normal file
33
vendor/github.com/containers/storage/pkg/system/exitcode.go
generated
vendored
Normal file
|
@ -0,0 +1,33 @@
|
|||
package system
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os/exec"
|
||||
"syscall"
|
||||
)
|
||||
|
||||
// GetExitCode returns the ExitStatus of the specified error if its type is
|
||||
// exec.ExitError, returns 0 and an error otherwise.
|
||||
func GetExitCode(err error) (int, error) {
|
||||
exitCode := 0
|
||||
if exiterr, ok := err.(*exec.ExitError); ok {
|
||||
if procExit, ok := exiterr.Sys().(syscall.WaitStatus); ok {
|
||||
return procExit.ExitStatus(), nil
|
||||
}
|
||||
}
|
||||
return exitCode, fmt.Errorf("failed to get exit code")
|
||||
}
|
||||
|
||||
// ProcessExitCode process the specified error and returns the exit status code
|
||||
// if the error was of type exec.ExitError, returns nothing otherwise.
|
||||
func ProcessExitCode(err error) (exitCode int) {
|
||||
if err != nil {
|
||||
var exiterr error
|
||||
if exitCode, exiterr = GetExitCode(err); exiterr != nil {
|
||||
// TODO: Fix this so we check the error's text.
|
||||
// we've failed to retrieve exit code, so we set it to 127
|
||||
exitCode = 127
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
50
vendor/github.com/containers/storage/pkg/system/filesys.go
generated
vendored
50
vendor/github.com/containers/storage/pkg/system/filesys.go
generated
vendored
|
@ -3,13 +3,19 @@
|
|||
package system
|
||||
|
||||
import (
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"path/filepath"
|
||||
)
|
||||
|
||||
// MkdirAllWithACL is a wrapper for MkdirAll on unix systems.
|
||||
func MkdirAllWithACL(path string, perm os.FileMode, sddl string) error {
|
||||
return MkdirAll(path, perm, sddl)
|
||||
}
|
||||
|
||||
// MkdirAll creates a directory named path along with any necessary parents,
|
||||
// with permission specified by attribute perm for all dir created.
|
||||
func MkdirAll(path string, perm os.FileMode) error {
|
||||
func MkdirAll(path string, perm os.FileMode, sddl string) error {
|
||||
return os.MkdirAll(path, perm)
|
||||
}
|
||||
|
||||
|
@ -17,3 +23,45 @@ func MkdirAll(path string, perm os.FileMode) error {
|
|||
func IsAbs(path string) bool {
|
||||
return filepath.IsAbs(path)
|
||||
}
|
||||
|
||||
// The functions below here are wrappers for the equivalents in the os and ioutils packages.
|
||||
// They are passthrough on Unix platforms, and only relevant on Windows.
|
||||
|
||||
// CreateSequential creates the named file with mode 0666 (before umask), truncating
|
||||
// it if it already exists. If successful, methods on the returned
|
||||
// File can be used for I/O; the associated file descriptor has mode
|
||||
// O_RDWR.
|
||||
// If there is an error, it will be of type *PathError.
|
||||
func CreateSequential(name string) (*os.File, error) {
|
||||
return os.Create(name)
|
||||
}
|
||||
|
||||
// OpenSequential opens the named file for reading. If successful, methods on
|
||||
// the returned file can be used for reading; the associated file
|
||||
// descriptor has mode O_RDONLY.
|
||||
// If there is an error, it will be of type *PathError.
|
||||
func OpenSequential(name string) (*os.File, error) {
|
||||
return os.Open(name)
|
||||
}
|
||||
|
||||
// OpenFileSequential is the generalized open call; most users will use Open
|
||||
// or Create instead. It opens the named file with specified flag
|
||||
// (O_RDONLY etc.) and perm, (0666 etc.) if applicable. If successful,
|
||||
// methods on the returned File can be used for I/O.
|
||||
// If there is an error, it will be of type *PathError.
|
||||
func OpenFileSequential(name string, flag int, perm os.FileMode) (*os.File, error) {
|
||||
return os.OpenFile(name, flag, perm)
|
||||
}
|
||||
|
||||
// TempFileSequential creates a new temporary file in the directory dir
|
||||
// with a name beginning with prefix, opens the file for reading
|
||||
// and writing, and returns the resulting *os.File.
|
||||
// If dir is the empty string, TempFile uses the default directory
|
||||
// for temporary files (see os.TempDir).
|
||||
// Multiple programs calling TempFile simultaneously
|
||||
// will not choose the same file. The caller can use f.Name()
|
||||
// to find the pathname of the file. It is the caller's responsibility
|
||||
// to remove the file when no longer needed.
|
||||
func TempFileSequential(dir, prefix string) (f *os.File, err error) {
|
||||
return ioutil.TempFile(dir, prefix)
|
||||
}
|
||||
|
|
226
vendor/github.com/containers/storage/pkg/system/filesys_windows.go
generated
vendored
226
vendor/github.com/containers/storage/pkg/system/filesys_windows.go
generated
vendored
|
@ -6,17 +6,44 @@ import (
|
|||
"os"
|
||||
"path/filepath"
|
||||
"regexp"
|
||||
"strconv"
|
||||
"strings"
|
||||
"sync"
|
||||
"syscall"
|
||||
"time"
|
||||
"unsafe"
|
||||
|
||||
winio "github.com/Microsoft/go-winio"
|
||||
"golang.org/x/sys/windows"
|
||||
)
|
||||
|
||||
const (
|
||||
// SddlAdministratorsLocalSystem is local administrators plus NT AUTHORITY\System
|
||||
SddlAdministratorsLocalSystem = "D:P(A;OICI;GA;;;BA)(A;OICI;GA;;;SY)"
|
||||
// SddlNtvmAdministratorsLocalSystem is NT VIRTUAL MACHINE\Virtual Machines plus local administrators plus NT AUTHORITY\System
|
||||
SddlNtvmAdministratorsLocalSystem = "D:P(A;OICI;GA;;;S-1-5-83-0)(A;OICI;GA;;;BA)(A;OICI;GA;;;SY)"
|
||||
)
|
||||
|
||||
// MkdirAllWithACL is a wrapper for MkdirAll that creates a directory
|
||||
// with an appropriate SDDL defined ACL.
|
||||
func MkdirAllWithACL(path string, perm os.FileMode, sddl string) error {
|
||||
return mkdirall(path, true, sddl)
|
||||
}
|
||||
|
||||
// MkdirAll implementation that is volume path aware for Windows.
|
||||
func MkdirAll(path string, perm os.FileMode) error {
|
||||
func MkdirAll(path string, _ os.FileMode, sddl string) error {
|
||||
return mkdirall(path, false, sddl)
|
||||
}
|
||||
|
||||
// mkdirall is a custom version of os.MkdirAll modified for use on Windows
|
||||
// so that it is both volume path aware, and can create a directory with
|
||||
// a DACL.
|
||||
func mkdirall(path string, applyACL bool, sddl string) error {
|
||||
if re := regexp.MustCompile(`^\\\\\?\\Volume{[a-z0-9-]+}$`); re.MatchString(path) {
|
||||
return nil
|
||||
}
|
||||
|
||||
// The rest of this method is copied from os.MkdirAll and should be kept
|
||||
// The rest of this method is largely copied from os.MkdirAll and should be kept
|
||||
// as-is to ensure compatibility.
|
||||
|
||||
// Fast path: if we can tell whether path is a directory or file, stop with success or error.
|
||||
|
@ -45,14 +72,19 @@ func MkdirAll(path string, perm os.FileMode) error {
|
|||
|
||||
if j > 1 {
|
||||
// Create parent
|
||||
err = MkdirAll(path[0:j-1], perm)
|
||||
err = mkdirall(path[0:j-1], false, sddl)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
// Parent now exists; invoke Mkdir and use its result.
|
||||
err = os.Mkdir(path, perm)
|
||||
// Parent now exists; invoke os.Mkdir or mkdirWithACL and use its result.
|
||||
if applyACL {
|
||||
err = mkdirWithACL(path, sddl)
|
||||
} else {
|
||||
err = os.Mkdir(path, 0)
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
// Handle arguments like "foo/." by
|
||||
// double-checking that directory doesn't exist.
|
||||
|
@ -65,6 +97,35 @@ func MkdirAll(path string, perm os.FileMode) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
// mkdirWithACL creates a new directory. If there is an error, it will be of
|
||||
// type *PathError. .
|
||||
//
|
||||
// This is a modified and combined version of os.Mkdir and windows.Mkdir
|
||||
// in golang to cater for creating a directory am ACL permitting full
|
||||
// access, with inheritance, to any subfolder/file for Built-in Administrators
|
||||
// and Local System.
|
||||
func mkdirWithACL(name string, sddl string) error {
|
||||
sa := windows.SecurityAttributes{Length: 0}
|
||||
sd, err := winio.SddlToSecurityDescriptor(sddl)
|
||||
if err != nil {
|
||||
return &os.PathError{Op: "mkdir", Path: name, Err: err}
|
||||
}
|
||||
sa.Length = uint32(unsafe.Sizeof(sa))
|
||||
sa.InheritHandle = 1
|
||||
sa.SecurityDescriptor = uintptr(unsafe.Pointer(&sd[0]))
|
||||
|
||||
namep, err := windows.UTF16PtrFromString(name)
|
||||
if err != nil {
|
||||
return &os.PathError{Op: "mkdir", Path: name, Err: err}
|
||||
}
|
||||
|
||||
e := windows.CreateDirectory(namep, &sa)
|
||||
if e != nil {
|
||||
return &os.PathError{Op: "mkdir", Path: name, Err: e}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// IsAbs is a platform-specific wrapper for filepath.IsAbs. On Windows,
|
||||
// golang filepath.IsAbs does not consider a path \windows\system32 as absolute
|
||||
// as it doesn't start with a drive-letter/colon combination. However, in
|
||||
|
@ -80,3 +141,158 @@ func IsAbs(path string) bool {
|
|||
}
|
||||
return true
|
||||
}
|
||||
|
||||
// The origin of the functions below here are the golang OS and windows packages,
|
||||
// slightly modified to only cope with files, not directories due to the
|
||||
// specific use case.
|
||||
//
|
||||
// The alteration is to allow a file on Windows to be opened with
|
||||
// FILE_FLAG_SEQUENTIAL_SCAN (particular for docker load), to avoid eating
|
||||
// the standby list, particularly when accessing large files such as layer.tar.
|
||||
|
||||
// CreateSequential creates the named file with mode 0666 (before umask), truncating
|
||||
// it if it already exists. If successful, methods on the returned
|
||||
// File can be used for I/O; the associated file descriptor has mode
|
||||
// O_RDWR.
|
||||
// If there is an error, it will be of type *PathError.
|
||||
func CreateSequential(name string) (*os.File, error) {
|
||||
return OpenFileSequential(name, os.O_RDWR|os.O_CREATE|os.O_TRUNC, 0)
|
||||
}
|
||||
|
||||
// OpenSequential opens the named file for reading. If successful, methods on
|
||||
// the returned file can be used for reading; the associated file
|
||||
// descriptor has mode O_RDONLY.
|
||||
// If there is an error, it will be of type *PathError.
|
||||
func OpenSequential(name string) (*os.File, error) {
|
||||
return OpenFileSequential(name, os.O_RDONLY, 0)
|
||||
}
|
||||
|
||||
// OpenFileSequential is the generalized open call; most users will use Open
|
||||
// or Create instead.
|
||||
// If there is an error, it will be of type *PathError.
|
||||
func OpenFileSequential(name string, flag int, _ os.FileMode) (*os.File, error) {
|
||||
if name == "" {
|
||||
return nil, &os.PathError{Op: "open", Path: name, Err: syscall.ENOENT}
|
||||
}
|
||||
r, errf := windowsOpenFileSequential(name, flag, 0)
|
||||
if errf == nil {
|
||||
return r, nil
|
||||
}
|
||||
return nil, &os.PathError{Op: "open", Path: name, Err: errf}
|
||||
}
|
||||
|
||||
func windowsOpenFileSequential(name string, flag int, _ os.FileMode) (file *os.File, err error) {
|
||||
r, e := windowsOpenSequential(name, flag|windows.O_CLOEXEC, 0)
|
||||
if e != nil {
|
||||
return nil, e
|
||||
}
|
||||
return os.NewFile(uintptr(r), name), nil
|
||||
}
|
||||
|
||||
func makeInheritSa() *windows.SecurityAttributes {
|
||||
var sa windows.SecurityAttributes
|
||||
sa.Length = uint32(unsafe.Sizeof(sa))
|
||||
sa.InheritHandle = 1
|
||||
return &sa
|
||||
}
|
||||
|
||||
func windowsOpenSequential(path string, mode int, _ uint32) (fd windows.Handle, err error) {
|
||||
if len(path) == 0 {
|
||||
return windows.InvalidHandle, windows.ERROR_FILE_NOT_FOUND
|
||||
}
|
||||
pathp, err := windows.UTF16PtrFromString(path)
|
||||
if err != nil {
|
||||
return windows.InvalidHandle, err
|
||||
}
|
||||
var access uint32
|
||||
switch mode & (windows.O_RDONLY | windows.O_WRONLY | windows.O_RDWR) {
|
||||
case windows.O_RDONLY:
|
||||
access = windows.GENERIC_READ
|
||||
case windows.O_WRONLY:
|
||||
access = windows.GENERIC_WRITE
|
||||
case windows.O_RDWR:
|
||||
access = windows.GENERIC_READ | windows.GENERIC_WRITE
|
||||
}
|
||||
if mode&windows.O_CREAT != 0 {
|
||||
access |= windows.GENERIC_WRITE
|
||||
}
|
||||
if mode&windows.O_APPEND != 0 {
|
||||
access &^= windows.GENERIC_WRITE
|
||||
access |= windows.FILE_APPEND_DATA
|
||||
}
|
||||
sharemode := uint32(windows.FILE_SHARE_READ | windows.FILE_SHARE_WRITE)
|
||||
var sa *windows.SecurityAttributes
|
||||
if mode&windows.O_CLOEXEC == 0 {
|
||||
sa = makeInheritSa()
|
||||
}
|
||||
var createmode uint32
|
||||
switch {
|
||||
case mode&(windows.O_CREAT|windows.O_EXCL) == (windows.O_CREAT | windows.O_EXCL):
|
||||
createmode = windows.CREATE_NEW
|
||||
case mode&(windows.O_CREAT|windows.O_TRUNC) == (windows.O_CREAT | windows.O_TRUNC):
|
||||
createmode = windows.CREATE_ALWAYS
|
||||
case mode&windows.O_CREAT == windows.O_CREAT:
|
||||
createmode = windows.OPEN_ALWAYS
|
||||
case mode&windows.O_TRUNC == windows.O_TRUNC:
|
||||
createmode = windows.TRUNCATE_EXISTING
|
||||
default:
|
||||
createmode = windows.OPEN_EXISTING
|
||||
}
|
||||
// Use FILE_FLAG_SEQUENTIAL_SCAN rather than FILE_ATTRIBUTE_NORMAL as implemented in golang.
|
||||
//https://msdn.microsoft.com/en-us/library/windows/desktop/aa363858(v=vs.85).aspx
|
||||
const fileFlagSequentialScan = 0x08000000 // FILE_FLAG_SEQUENTIAL_SCAN
|
||||
h, e := windows.CreateFile(pathp, access, sharemode, sa, createmode, fileFlagSequentialScan, 0)
|
||||
return h, e
|
||||
}
|
||||
|
||||
// Helpers for TempFileSequential
|
||||
var rand uint32
|
||||
var randmu sync.Mutex
|
||||
|
||||
func reseed() uint32 {
|
||||
return uint32(time.Now().UnixNano() + int64(os.Getpid()))
|
||||
}
|
||||
func nextSuffix() string {
|
||||
randmu.Lock()
|
||||
r := rand
|
||||
if r == 0 {
|
||||
r = reseed()
|
||||
}
|
||||
r = r*1664525 + 1013904223 // constants from Numerical Recipes
|
||||
rand = r
|
||||
randmu.Unlock()
|
||||
return strconv.Itoa(int(1e9 + r%1e9))[1:]
|
||||
}
|
||||
|
||||
// TempFileSequential is a copy of ioutil.TempFile, modified to use sequential
|
||||
// file access. Below is the original comment from golang:
|
||||
// TempFile creates a new temporary file in the directory dir
|
||||
// with a name beginning with prefix, opens the file for reading
|
||||
// and writing, and returns the resulting *os.File.
|
||||
// If dir is the empty string, TempFile uses the default directory
|
||||
// for temporary files (see os.TempDir).
|
||||
// Multiple programs calling TempFile simultaneously
|
||||
// will not choose the same file. The caller can use f.Name()
|
||||
// to find the pathname of the file. It is the caller's responsibility
|
||||
// to remove the file when no longer needed.
|
||||
func TempFileSequential(dir, prefix string) (f *os.File, err error) {
|
||||
if dir == "" {
|
||||
dir = os.TempDir()
|
||||
}
|
||||
|
||||
nconflict := 0
|
||||
for i := 0; i < 10000; i++ {
|
||||
name := filepath.Join(dir, prefix+nextSuffix())
|
||||
f, err = OpenFileSequential(name, os.O_RDWR|os.O_CREATE|os.O_EXCL, 0600)
|
||||
if os.IsExist(err) {
|
||||
if nconflict++; nconflict > 10 {
|
||||
randmu.Lock()
|
||||
rand = reseed()
|
||||
randmu.Unlock()
|
||||
}
|
||||
continue
|
||||
}
|
||||
break
|
||||
}
|
||||
return
|
||||
}
|
||||
|
|
22
vendor/github.com/containers/storage/pkg/system/init.go
generated
vendored
Normal file
22
vendor/github.com/containers/storage/pkg/system/init.go
generated
vendored
Normal file
|
@ -0,0 +1,22 @@
|
|||
package system
|
||||
|
||||
import (
|
||||
"syscall"
|
||||
"time"
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
// Used by chtimes
|
||||
var maxTime time.Time
|
||||
|
||||
func init() {
|
||||
// chtimes initialization
|
||||
if unsafe.Sizeof(syscall.Timespec{}.Nsec) == 8 {
|
||||
// This is a 64 bit timespec
|
||||
// os.Chtimes limits time to the following
|
||||
maxTime = time.Unix(0, 1<<63-1)
|
||||
} else {
|
||||
// This is a 32 bit timespec
|
||||
maxTime = time.Unix(1<<31-1, 0)
|
||||
}
|
||||
}
|
17
vendor/github.com/containers/storage/pkg/system/init_windows.go
generated
vendored
Normal file
17
vendor/github.com/containers/storage/pkg/system/init_windows.go
generated
vendored
Normal file
|
@ -0,0 +1,17 @@
|
|||
package system
|
||||
|
||||
import "os"
|
||||
|
||||
// LCOWSupported determines if Linux Containers on Windows are supported.
|
||||
// Note: This feature is in development (06/17) and enabled through an
|
||||
// environment variable. At a future time, it will be enabled based
|
||||
// on build number. @jhowardmsft
|
||||
var lcowSupported = false
|
||||
|
||||
func init() {
|
||||
// LCOW initialization
|
||||
if os.Getenv("LCOW_SUPPORTED") != "" {
|
||||
lcowSupported = true
|
||||
}
|
||||
|
||||
}
|
8
vendor/github.com/containers/storage/pkg/system/lcow_unix.go
generated
vendored
Normal file
8
vendor/github.com/containers/storage/pkg/system/lcow_unix.go
generated
vendored
Normal file
|
@ -0,0 +1,8 @@
|
|||
// +build !windows
|
||||
|
||||
package system
|
||||
|
||||
// LCOWSupported returns true if Linux containers on Windows are supported.
|
||||
func LCOWSupported() bool {
|
||||
return false
|
||||
}
|
6
vendor/github.com/containers/storage/pkg/system/lcow_windows.go
generated
vendored
Normal file
6
vendor/github.com/containers/storage/pkg/system/lcow_windows.go
generated
vendored
Normal file
|
@ -0,0 +1,6 @@
|
|||
package system
|
||||
|
||||
// LCOWSupported returns true if Linux containers on Windows are supported.
|
||||
func LCOWSupported() bool {
|
||||
return lcowSupported
|
||||
}
|
15
vendor/github.com/containers/storage/pkg/system/lstat_windows.go
generated
vendored
15
vendor/github.com/containers/storage/pkg/system/lstat_windows.go
generated
vendored
|
@ -1,25 +1,14 @@
|
|||
// +build windows
|
||||
|
||||
package system
|
||||
|
||||
import (
|
||||
"os"
|
||||
)
|
||||
import "os"
|
||||
|
||||
// Lstat calls os.Lstat to get a fileinfo interface back.
|
||||
// This is then copied into our own locally defined structure.
|
||||
// Note the Linux version uses fromStatT to do the copy back,
|
||||
// but that not strictly necessary when already in an OS specific module.
|
||||
func Lstat(path string) (*StatT, error) {
|
||||
fi, err := os.Lstat(path)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &StatT{
|
||||
name: fi.Name(),
|
||||
size: fi.Size(),
|
||||
mode: fi.Mode(),
|
||||
modTime: fi.ModTime(),
|
||||
isDir: fi.IsDir()}, nil
|
||||
return fromStatT(&fi)
|
||||
}
|
||||
|
|
3
vendor/github.com/containers/storage/pkg/system/meminfo_solaris.go
generated
vendored
3
vendor/github.com/containers/storage/pkg/system/meminfo_solaris.go
generated
vendored
|
@ -7,6 +7,7 @@ import (
|
|||
"unsafe"
|
||||
)
|
||||
|
||||
// #cgo CFLAGS: -std=c99
|
||||
// #cgo LDFLAGS: -lkstat
|
||||
// #include <unistd.h>
|
||||
// #include <stdlib.h>
|
||||
|
@ -89,7 +90,7 @@ func ReadMemInfo() (*MemInfo, error) {
|
|||
|
||||
if ppKernel < 0 || MemTotal < 0 || MemFree < 0 || SwapTotal < 0 ||
|
||||
SwapFree < 0 {
|
||||
return nil, fmt.Errorf("Error getting system memory info %v\n", err)
|
||||
return nil, fmt.Errorf("error getting system memory info %v\n", err)
|
||||
}
|
||||
|
||||
meminfo := &MemInfo{}
|
||||
|
|
5
vendor/github.com/containers/storage/pkg/system/meminfo_windows.go
generated
vendored
5
vendor/github.com/containers/storage/pkg/system/meminfo_windows.go
generated
vendored
|
@ -1,12 +1,13 @@
|
|||
package system
|
||||
|
||||
import (
|
||||
"syscall"
|
||||
"unsafe"
|
||||
|
||||
"golang.org/x/sys/windows"
|
||||
)
|
||||
|
||||
var (
|
||||
modkernel32 = syscall.NewLazyDLL("kernel32.dll")
|
||||
modkernel32 = windows.NewLazySystemDLL("kernel32.dll")
|
||||
|
||||
procGlobalMemoryStatusEx = modkernel32.NewProc("GlobalMemoryStatusEx")
|
||||
)
|
||||
|
|
4
vendor/github.com/containers/storage/pkg/system/mknod.go
generated
vendored
4
vendor/github.com/containers/storage/pkg/system/mknod.go
generated
vendored
|
@ -3,13 +3,13 @@
|
|||
package system
|
||||
|
||||
import (
|
||||
"syscall"
|
||||
"golang.org/x/sys/unix"
|
||||
)
|
||||
|
||||
// Mknod creates a filesystem node (file, device special file or named pipe) named path
|
||||
// with attributes specified by mode and dev.
|
||||
func Mknod(path string, mode uint32, dev int) error {
|
||||
return syscall.Mknod(path, mode, dev)
|
||||
return unix.Mknod(path, mode, dev)
|
||||
}
|
||||
|
||||
// Mkdev is used to build the value of linux devices (in /dev/) which specifies major
|
||||
|
|
21
vendor/github.com/containers/storage/pkg/system/path.go
generated
vendored
Normal file
21
vendor/github.com/containers/storage/pkg/system/path.go
generated
vendored
Normal file
|
@ -0,0 +1,21 @@
|
|||
package system
|
||||
|
||||
import "runtime"
|
||||
|
||||
const defaultUnixPathEnv = "/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
|
||||
|
||||
// DefaultPathEnv is unix style list of directories to search for
|
||||
// executables. Each directory is separated from the next by a colon
|
||||
// ':' character .
|
||||
func DefaultPathEnv(platform string) string {
|
||||
if runtime.GOOS == "windows" {
|
||||
if platform != runtime.GOOS && LCOWSupported() {
|
||||
return defaultUnixPathEnv
|
||||
}
|
||||
// Deliberately empty on Windows containers on Windows as the default path will be set by
|
||||
// the container. Docker has no context of what the default path should be.
|
||||
return ""
|
||||
}
|
||||
return defaultUnixPathEnv
|
||||
|
||||
}
|
5
vendor/github.com/containers/storage/pkg/system/path_unix.go
generated
vendored
5
vendor/github.com/containers/storage/pkg/system/path_unix.go
generated
vendored
|
@ -2,11 +2,6 @@
|
|||
|
||||
package system
|
||||
|
||||
// DefaultPathEnv is unix style list of directories to search for
|
||||
// executables. Each directory is separated from the next by a colon
|
||||
// ':' character .
|
||||
const DefaultPathEnv = "/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
|
||||
|
||||
// CheckSystemDriveAndRemoveDriveLetter verifies that a path, if it includes a drive letter,
|
||||
// is the system drive. This is a no-op on Linux.
|
||||
func CheckSystemDriveAndRemoveDriveLetter(path string) (string, error) {
|
||||
|
|
6
vendor/github.com/containers/storage/pkg/system/path_windows.go
generated
vendored
6
vendor/github.com/containers/storage/pkg/system/path_windows.go
generated
vendored
|
@ -8,15 +8,11 @@ import (
|
|||
"strings"
|
||||
)
|
||||
|
||||
// DefaultPathEnv is deliberately empty on Windows as the default path will be set by
|
||||
// the container. Docker has no context of what the default path should be.
|
||||
const DefaultPathEnv = ""
|
||||
|
||||
// CheckSystemDriveAndRemoveDriveLetter verifies and manipulates a Windows path.
|
||||
// This is used, for example, when validating a user provided path in docker cp.
|
||||
// If a drive letter is supplied, it must be the system drive. The drive letter
|
||||
// is always removed. Also, it translates it to OS semantics (IOW / to \). We
|
||||
// need the path in this syntax so that it can ultimately be contatenated with
|
||||
// need the path in this syntax so that it can ultimately be concatenated with
|
||||
// a Windows long-path which doesn't support drive-letters. Examples:
|
||||
// C: --> Fail
|
||||
// C:\ --> \
|
||||
|
|
24
vendor/github.com/containers/storage/pkg/system/process_unix.go
generated
vendored
Normal file
24
vendor/github.com/containers/storage/pkg/system/process_unix.go
generated
vendored
Normal file
|
@ -0,0 +1,24 @@
|
|||
// +build linux freebsd solaris darwin
|
||||
|
||||
package system
|
||||
|
||||
import (
|
||||
"syscall"
|
||||
|
||||
"golang.org/x/sys/unix"
|
||||
)
|
||||
|
||||
// IsProcessAlive returns true if process with a given pid is running.
|
||||
func IsProcessAlive(pid int) bool {
|
||||
err := unix.Kill(pid, syscall.Signal(0))
|
||||
if err == nil || err == unix.EPERM {
|
||||
return true
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
// KillProcess force-stops a process.
|
||||
func KillProcess(pid int) {
|
||||
unix.Kill(pid, unix.SIGKILL)
|
||||
}
|
80
vendor/github.com/containers/storage/pkg/system/rm.go
generated
vendored
Normal file
80
vendor/github.com/containers/storage/pkg/system/rm.go
generated
vendored
Normal file
|
@ -0,0 +1,80 @@
|
|||
package system
|
||||
|
||||
import (
|
||||
"os"
|
||||
"syscall"
|
||||
"time"
|
||||
|
||||
"github.com/containers/storage/pkg/mount"
|
||||
"github.com/pkg/errors"
|
||||
)
|
||||
|
||||
// EnsureRemoveAll wraps `os.RemoveAll` to check for specific errors that can
|
||||
// often be remedied.
|
||||
// Only use `EnsureRemoveAll` if you really want to make every effort to remove
|
||||
// a directory.
|
||||
//
|
||||
// Because of the way `os.Remove` (and by extension `os.RemoveAll`) works, there
|
||||
// can be a race between reading directory entries and then actually attempting
|
||||
// to remove everything in the directory.
|
||||
// These types of errors do not need to be returned since it's ok for the dir to
|
||||
// be gone we can just retry the remove operation.
|
||||
//
|
||||
// This should not return a `os.ErrNotExist` kind of error under any circumstances
|
||||
func EnsureRemoveAll(dir string) error {
|
||||
notExistErr := make(map[string]bool)
|
||||
|
||||
// track retries
|
||||
exitOnErr := make(map[string]int)
|
||||
maxRetry := 5
|
||||
|
||||
// Attempt to unmount anything beneath this dir first
|
||||
mount.RecursiveUnmount(dir)
|
||||
|
||||
for {
|
||||
err := os.RemoveAll(dir)
|
||||
if err == nil {
|
||||
return err
|
||||
}
|
||||
|
||||
pe, ok := err.(*os.PathError)
|
||||
if !ok {
|
||||
return err
|
||||
}
|
||||
|
||||
if os.IsNotExist(err) {
|
||||
if notExistErr[pe.Path] {
|
||||
return err
|
||||
}
|
||||
notExistErr[pe.Path] = true
|
||||
|
||||
// There is a race where some subdir can be removed but after the parent
|
||||
// dir entries have been read.
|
||||
// So the path could be from `os.Remove(subdir)`
|
||||
// If the reported non-existent path is not the passed in `dir` we
|
||||
// should just retry, but otherwise return with no error.
|
||||
if pe.Path == dir {
|
||||
return nil
|
||||
}
|
||||
continue
|
||||
}
|
||||
|
||||
if pe.Err != syscall.EBUSY {
|
||||
return err
|
||||
}
|
||||
|
||||
if mounted, _ := mount.Mounted(pe.Path); mounted {
|
||||
if e := mount.Unmount(pe.Path); e != nil {
|
||||
if mounted, _ := mount.Mounted(pe.Path); mounted {
|
||||
return errors.Wrapf(e, "error while removing %s", dir)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if exitOnErr[pe.Path] == maxRetry {
|
||||
return err
|
||||
}
|
||||
exitOnErr[pe.Path]++
|
||||
time.Sleep(100 * time.Millisecond)
|
||||
}
|
||||
}
|
|
@ -1,12 +1,8 @@
|
|||
// +build !linux,!windows,!freebsd,!solaris,!openbsd
|
||||
|
||||
package system
|
||||
|
||||
import (
|
||||
"syscall"
|
||||
)
|
||||
import "syscall"
|
||||
|
||||
// fromStatT creates a system.StatT type from a syscall.Stat_t type
|
||||
// fromStatT converts a syscall.Stat_t type to a system.Stat_t type
|
||||
func fromStatT(s *syscall.Stat_t) (*StatT, error) {
|
||||
return &StatT{size: s.Size,
|
||||
mode: uint32(s.Mode),
|
16
vendor/github.com/containers/storage/pkg/system/stat_freebsd.go
generated
vendored
16
vendor/github.com/containers/storage/pkg/system/stat_freebsd.go
generated
vendored
|
@ -1,8 +1,6 @@
|
|||
package system
|
||||
|
||||
import (
|
||||
"syscall"
|
||||
)
|
||||
import "syscall"
|
||||
|
||||
// fromStatT converts a syscall.Stat_t type to a system.Stat_t type
|
||||
func fromStatT(s *syscall.Stat_t) (*StatT, error) {
|
||||
|
@ -13,15 +11,3 @@ func fromStatT(s *syscall.Stat_t) (*StatT, error) {
|
|||
rdev: uint64(s.Rdev),
|
||||
mtim: s.Mtimespec}, nil
|
||||
}
|
||||
|
||||
// Stat takes a path to a file and returns
|
||||
// a system.Stat_t type pertaining to that file.
|
||||
//
|
||||
// Throws an error if the file does not exist
|
||||
func Stat(path string) (*StatT, error) {
|
||||
s := &syscall.Stat_t{}
|
||||
if err := syscall.Stat(path, s); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return fromStatT(s)
|
||||
}
|
||||
|
|
20
vendor/github.com/containers/storage/pkg/system/stat_linux.go
generated
vendored
20
vendor/github.com/containers/storage/pkg/system/stat_linux.go
generated
vendored
|
@ -1,8 +1,6 @@
|
|||
package system
|
||||
|
||||
import (
|
||||
"syscall"
|
||||
)
|
||||
import "syscall"
|
||||
|
||||
// fromStatT converts a syscall.Stat_t type to a system.Stat_t type
|
||||
func fromStatT(s *syscall.Stat_t) (*StatT, error) {
|
||||
|
@ -14,20 +12,8 @@ func fromStatT(s *syscall.Stat_t) (*StatT, error) {
|
|||
mtim: s.Mtim}, nil
|
||||
}
|
||||
|
||||
// FromStatT exists only on linux, and loads a system.StatT from a
|
||||
// syscal.Stat_t.
|
||||
// FromStatT converts a syscall.Stat_t type to a system.Stat_t type
|
||||
// This is exposed on Linux as pkg/archive/changes uses it.
|
||||
func FromStatT(s *syscall.Stat_t) (*StatT, error) {
|
||||
return fromStatT(s)
|
||||
}
|
||||
|
||||
// Stat takes a path to a file and returns
|
||||
// a system.StatT type pertaining to that file.
|
||||
//
|
||||
// Throws an error if the file does not exist
|
||||
func Stat(path string) (*StatT, error) {
|
||||
s := &syscall.Stat_t{}
|
||||
if err := syscall.Stat(path, s); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return fromStatT(s)
|
||||
}
|
||||
|
|
6
vendor/github.com/containers/storage/pkg/system/stat_openbsd.go
generated
vendored
6
vendor/github.com/containers/storage/pkg/system/stat_openbsd.go
generated
vendored
|
@ -1,10 +1,8 @@
|
|||
package system
|
||||
|
||||
import (
|
||||
"syscall"
|
||||
)
|
||||
import "syscall"
|
||||
|
||||
// fromStatT creates a system.StatT type from a syscall.Stat_t type
|
||||
// fromStatT converts a syscall.Stat_t type to a system.Stat_t type
|
||||
func fromStatT(s *syscall.Stat_t) (*StatT, error) {
|
||||
return &StatT{size: s.Size,
|
||||
mode: uint32(s.Mode),
|
||||
|
|
25
vendor/github.com/containers/storage/pkg/system/stat_solaris.go
generated
vendored
25
vendor/github.com/containers/storage/pkg/system/stat_solaris.go
generated
vendored
|
@ -1,12 +1,8 @@
|
|||
// +build solaris
|
||||
|
||||
package system
|
||||
|
||||
import (
|
||||
"syscall"
|
||||
)
|
||||
import "syscall"
|
||||
|
||||
// fromStatT creates a system.StatT type from a syscall.Stat_t type
|
||||
// fromStatT converts a syscall.Stat_t type to a system.Stat_t type
|
||||
func fromStatT(s *syscall.Stat_t) (*StatT, error) {
|
||||
return &StatT{size: s.Size,
|
||||
mode: uint32(s.Mode),
|
||||
|
@ -15,20 +11,3 @@ func fromStatT(s *syscall.Stat_t) (*StatT, error) {
|
|||
rdev: uint64(s.Rdev),
|
||||
mtim: s.Mtim}, nil
|
||||
}
|
||||
|
||||
// FromStatT loads a system.StatT from a syscal.Stat_t.
|
||||
func FromStatT(s *syscall.Stat_t) (*StatT, error) {
|
||||
return fromStatT(s)
|
||||
}
|
||||
|
||||
// Stat takes a path to a file and returns
|
||||
// a system.StatT type pertaining to that file.
|
||||
//
|
||||
// Throws an error if the file does not exist
|
||||
func Stat(path string) (*StatT, error) {
|
||||
s := &syscall.Stat_t{}
|
||||
if err := syscall.Stat(path, s); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return fromStatT(s)
|
||||
}
|
||||
|
|
|
@ -47,7 +47,14 @@ func (s StatT) Mtim() syscall.Timespec {
|
|||
return s.mtim
|
||||
}
|
||||
|
||||
// GetLastModification returns file's last modification time.
|
||||
func (s StatT) GetLastModification() syscall.Timespec {
|
||||
return s.Mtim()
|
||||
// Stat takes a path to a file and returns
|
||||
// a system.StatT type pertaining to that file.
|
||||
//
|
||||
// Throws an error if the file does not exist
|
||||
func Stat(path string) (*StatT, error) {
|
||||
s := &syscall.Stat_t{}
|
||||
if err := syscall.Stat(path, s); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return fromStatT(s)
|
||||
}
|
46
vendor/github.com/containers/storage/pkg/system/stat_windows.go
generated
vendored
46
vendor/github.com/containers/storage/pkg/system/stat_windows.go
generated
vendored
|
@ -1,5 +1,3 @@
|
|||
// +build windows
|
||||
|
||||
package system
|
||||
|
||||
import (
|
||||
|
@ -8,18 +6,11 @@ import (
|
|||
)
|
||||
|
||||
// StatT type contains status of a file. It contains metadata
|
||||
// like name, permission, size, etc about a file.
|
||||
// like permission, size, etc about a file.
|
||||
type StatT struct {
|
||||
name string
|
||||
size int64
|
||||
mode os.FileMode
|
||||
modTime time.Time
|
||||
isDir bool
|
||||
}
|
||||
|
||||
// Name returns file's name.
|
||||
func (s StatT) Name() string {
|
||||
return s.name
|
||||
mode os.FileMode
|
||||
size int64
|
||||
mtim time.Time
|
||||
}
|
||||
|
||||
// Size returns file's size.
|
||||
|
@ -29,15 +20,30 @@ func (s StatT) Size() int64 {
|
|||
|
||||
// Mode returns file's permission mode.
|
||||
func (s StatT) Mode() os.FileMode {
|
||||
return s.mode
|
||||
return os.FileMode(s.mode)
|
||||
}
|
||||
|
||||
// ModTime returns file's last modification time.
|
||||
func (s StatT) ModTime() time.Time {
|
||||
return s.modTime
|
||||
// Mtim returns file's last modification time.
|
||||
func (s StatT) Mtim() time.Time {
|
||||
return time.Time(s.mtim)
|
||||
}
|
||||
|
||||
// IsDir returns whether file is actually a directory.
|
||||
func (s StatT) IsDir() bool {
|
||||
return s.isDir
|
||||
// Stat takes a path to a file and returns
|
||||
// a system.StatT type pertaining to that file.
|
||||
//
|
||||
// Throws an error if the file does not exist
|
||||
func Stat(path string) (*StatT, error) {
|
||||
fi, err := os.Stat(path)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return fromStatT(&fi)
|
||||
}
|
||||
|
||||
// fromStatT converts a os.FileInfo type to a system.StatT type
|
||||
func fromStatT(fi *os.FileInfo) (*StatT, error) {
|
||||
return &StatT{
|
||||
size: (*fi).Size(),
|
||||
mode: (*fi).Mode(),
|
||||
mtim: (*fi).ModTime()}, nil
|
||||
}
|
||||
|
|
4
vendor/github.com/containers/storage/pkg/system/syscall_unix.go
generated
vendored
4
vendor/github.com/containers/storage/pkg/system/syscall_unix.go
generated
vendored
|
@ -2,12 +2,12 @@
|
|||
|
||||
package system
|
||||
|
||||
import "syscall"
|
||||
import "golang.org/x/sys/unix"
|
||||
|
||||
// Unmount is a platform-specific helper function to call
|
||||
// the unmount syscall.
|
||||
func Unmount(dest string) error {
|
||||
return syscall.Unmount(dest, 0)
|
||||
return unix.Unmount(dest, 0)
|
||||
}
|
||||
|
||||
// CommandLineToArgv should not be used on Unix.
|
||||
|
|
35
vendor/github.com/containers/storage/pkg/system/syscall_windows.go
generated
vendored
35
vendor/github.com/containers/storage/pkg/system/syscall_windows.go
generated
vendored
|
@ -1,15 +1,16 @@
|
|||
package system
|
||||
|
||||
import (
|
||||
"syscall"
|
||||
"unsafe"
|
||||
|
||||
"github.com/sirupsen/logrus"
|
||||
"golang.org/x/sys/windows"
|
||||
)
|
||||
|
||||
var (
|
||||
ntuserApiset = syscall.NewLazyDLL("ext-ms-win-ntuser-window-l1-1-0")
|
||||
procGetVersionExW = modkernel32.NewProc("GetVersionExW")
|
||||
ntuserApiset = windows.NewLazyDLL("ext-ms-win-ntuser-window-l1-1-0")
|
||||
procGetVersionExW = modkernel32.NewProc("GetVersionExW")
|
||||
procGetProductInfo = modkernel32.NewProc("GetProductInfo")
|
||||
)
|
||||
|
||||
// OSVersion is a wrapper for Windows version information
|
||||
|
@ -41,7 +42,7 @@ type osVersionInfoEx struct {
|
|||
func GetOSVersion() OSVersion {
|
||||
var err error
|
||||
osv := OSVersion{}
|
||||
osv.Version, err = syscall.GetVersion()
|
||||
osv.Version, err = windows.GetVersion()
|
||||
if err != nil {
|
||||
// GetVersion never fails.
|
||||
panic(err)
|
||||
|
@ -53,6 +54,8 @@ func GetOSVersion() OSVersion {
|
|||
}
|
||||
|
||||
// IsWindowsClient returns true if the SKU is client
|
||||
// @engine maintainers - this function should not be removed or modified as it
|
||||
// is used to enforce licensing restrictions on Windows.
|
||||
func IsWindowsClient() bool {
|
||||
osviex := &osVersionInfoEx{OSVersionInfoSize: 284}
|
||||
r1, _, err := procGetVersionExW.Call(uintptr(unsafe.Pointer(osviex)))
|
||||
|
@ -64,6 +67,22 @@ func IsWindowsClient() bool {
|
|||
return osviex.ProductType == verNTWorkstation
|
||||
}
|
||||
|
||||
// IsIoTCore returns true if the currently running image is based off of
|
||||
// Windows 10 IoT Core.
|
||||
// @engine maintainers - this function should not be removed or modified as it
|
||||
// is used to enforce licensing restrictions on Windows.
|
||||
func IsIoTCore() bool {
|
||||
var returnedProductType uint32
|
||||
r1, _, err := procGetProductInfo.Call(6, 1, 0, 0, uintptr(unsafe.Pointer(&returnedProductType)))
|
||||
if r1 == 0 {
|
||||
logrus.Warnf("GetProductInfo failed - assuming this is not IoT: %v", err)
|
||||
return false
|
||||
}
|
||||
const productIoTUAP = 0x0000007B
|
||||
const productIoTUAPCommercial = 0x00000083
|
||||
return returnedProductType == productIoTUAP || returnedProductType == productIoTUAPCommercial
|
||||
}
|
||||
|
||||
// Unmount is a platform-specific helper function to call
|
||||
// the unmount syscall. Not supported on Windows
|
||||
func Unmount(dest string) error {
|
||||
|
@ -74,20 +93,20 @@ func Unmount(dest string) error {
|
|||
func CommandLineToArgv(commandLine string) ([]string, error) {
|
||||
var argc int32
|
||||
|
||||
argsPtr, err := syscall.UTF16PtrFromString(commandLine)
|
||||
argsPtr, err := windows.UTF16PtrFromString(commandLine)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
argv, err := syscall.CommandLineToArgv(argsPtr, &argc)
|
||||
argv, err := windows.CommandLineToArgv(argsPtr, &argc)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer syscall.LocalFree(syscall.Handle(uintptr(unsafe.Pointer(argv))))
|
||||
defer windows.LocalFree(windows.Handle(uintptr(unsafe.Pointer(argv))))
|
||||
|
||||
newArgs := make([]string, argc)
|
||||
for i, v := range (*argv)[:argc] {
|
||||
newArgs[i] = string(syscall.UTF16ToString((*v)[:]))
|
||||
newArgs[i] = string(windows.UTF16ToString((*v)[:]))
|
||||
}
|
||||
|
||||
return newArgs, nil
|
||||
|
|
4
vendor/github.com/containers/storage/pkg/system/umask.go
generated
vendored
4
vendor/github.com/containers/storage/pkg/system/umask.go
generated
vendored
|
@ -3,11 +3,11 @@
|
|||
package system
|
||||
|
||||
import (
|
||||
"syscall"
|
||||
"golang.org/x/sys/unix"
|
||||
)
|
||||
|
||||
// Umask sets current process's file mode creation mask to newmask
|
||||
// and returns oldmask.
|
||||
func Umask(newmask int) (oldmask int, err error) {
|
||||
return syscall.Umask(newmask), nil
|
||||
return unix.Umask(newmask), nil
|
||||
}
|
||||
|
|
8
vendor/github.com/containers/storage/pkg/system/utimes_darwin.go
generated
vendored
8
vendor/github.com/containers/storage/pkg/system/utimes_darwin.go
generated
vendored
|
@ -1,8 +0,0 @@
|
|||
package system
|
||||
|
||||
import "syscall"
|
||||
|
||||
// LUtimesNano is not supported by darwin platform.
|
||||
func LUtimesNano(path string, ts []syscall.Timespec) error {
|
||||
return ErrNotSupportedPlatform
|
||||
}
|
8
vendor/github.com/containers/storage/pkg/system/utimes_freebsd.go
generated
vendored
8
vendor/github.com/containers/storage/pkg/system/utimes_freebsd.go
generated
vendored
|
@ -3,18 +3,20 @@ package system
|
|||
import (
|
||||
"syscall"
|
||||
"unsafe"
|
||||
|
||||
"golang.org/x/sys/unix"
|
||||
)
|
||||
|
||||
// LUtimesNano is used to change access and modification time of the specified path.
|
||||
// It's used for symbol link file because syscall.UtimesNano doesn't support a NOFOLLOW flag atm.
|
||||
// It's used for symbol link file because unix.UtimesNano doesn't support a NOFOLLOW flag atm.
|
||||
func LUtimesNano(path string, ts []syscall.Timespec) error {
|
||||
var _path *byte
|
||||
_path, err := syscall.BytePtrFromString(path)
|
||||
_path, err := unix.BytePtrFromString(path)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if _, _, err := syscall.Syscall(syscall.SYS_LUTIMES, uintptr(unsafe.Pointer(_path)), uintptr(unsafe.Pointer(&ts[0])), 0); err != 0 && err != syscall.ENOSYS {
|
||||
if _, _, err := unix.Syscall(unix.SYS_LUTIMES, uintptr(unsafe.Pointer(_path)), uintptr(unsafe.Pointer(&ts[0])), 0); err != 0 && err != unix.ENOSYS {
|
||||
return err
|
||||
}
|
||||
|
||||
|
|
13
vendor/github.com/containers/storage/pkg/system/utimes_linux.go
generated
vendored
13
vendor/github.com/containers/storage/pkg/system/utimes_linux.go
generated
vendored
|
@ -3,22 +3,21 @@ package system
|
|||
import (
|
||||
"syscall"
|
||||
"unsafe"
|
||||
|
||||
"golang.org/x/sys/unix"
|
||||
)
|
||||
|
||||
// LUtimesNano is used to change access and modification time of the specified path.
|
||||
// It's used for symbol link file because syscall.UtimesNano doesn't support a NOFOLLOW flag atm.
|
||||
// It's used for symbol link file because unix.UtimesNano doesn't support a NOFOLLOW flag atm.
|
||||
func LUtimesNano(path string, ts []syscall.Timespec) error {
|
||||
// These are not currently available in syscall
|
||||
atFdCwd := -100
|
||||
atSymLinkNoFollow := 0x100
|
||||
atFdCwd := unix.AT_FDCWD
|
||||
|
||||
var _path *byte
|
||||
_path, err := syscall.BytePtrFromString(path)
|
||||
_path, err := unix.BytePtrFromString(path)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if _, _, err := syscall.Syscall6(syscall.SYS_UTIMENSAT, uintptr(atFdCwd), uintptr(unsafe.Pointer(_path)), uintptr(unsafe.Pointer(&ts[0])), uintptr(atSymLinkNoFollow), 0, 0); err != 0 && err != syscall.ENOSYS {
|
||||
if _, _, err := unix.Syscall6(unix.SYS_UTIMENSAT, uintptr(atFdCwd), uintptr(unsafe.Pointer(_path)), uintptr(unsafe.Pointer(&ts[0])), unix.AT_SYMLINK_NOFOLLOW, 0, 0); err != 0 && err != unix.ENOSYS {
|
||||
return err
|
||||
}
|
||||
|
||||
|
|
4
vendor/github.com/containers/storage/pkg/system/utimes_unsupported.go
generated
vendored
4
vendor/github.com/containers/storage/pkg/system/utimes_unsupported.go
generated
vendored
|
@ -1,10 +1,10 @@
|
|||
// +build !linux,!freebsd,!darwin
|
||||
// +build !linux,!freebsd
|
||||
|
||||
package system
|
||||
|
||||
import "syscall"
|
||||
|
||||
// LUtimesNano is not supported on platforms other than linux, freebsd and darwin.
|
||||
// LUtimesNano is only supported on linux and freebsd.
|
||||
func LUtimesNano(path string, ts []syscall.Timespec) error {
|
||||
return ErrNotSupportedPlatform
|
||||
}
|
||||
|
|
48
vendor/github.com/containers/storage/pkg/system/xattrs_linux.go
generated
vendored
48
vendor/github.com/containers/storage/pkg/system/xattrs_linux.go
generated
vendored
|
@ -1,63 +1,29 @@
|
|||
package system
|
||||
|
||||
import (
|
||||
"syscall"
|
||||
"unsafe"
|
||||
)
|
||||
import "golang.org/x/sys/unix"
|
||||
|
||||
// Lgetxattr retrieves the value of the extended attribute identified by attr
|
||||
// and associated with the given path in the file system.
|
||||
// It will returns a nil slice and nil error if the xattr is not set.
|
||||
func Lgetxattr(path string, attr string) ([]byte, error) {
|
||||
pathBytes, err := syscall.BytePtrFromString(path)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
attrBytes, err := syscall.BytePtrFromString(attr)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
dest := make([]byte, 128)
|
||||
destBytes := unsafe.Pointer(&dest[0])
|
||||
sz, _, errno := syscall.Syscall6(syscall.SYS_LGETXATTR, uintptr(unsafe.Pointer(pathBytes)), uintptr(unsafe.Pointer(attrBytes)), uintptr(destBytes), uintptr(len(dest)), 0, 0)
|
||||
if errno == syscall.ENODATA {
|
||||
sz, errno := unix.Lgetxattr(path, attr, dest)
|
||||
if errno == unix.ENODATA {
|
||||
return nil, nil
|
||||
}
|
||||
if errno == syscall.ERANGE {
|
||||
if errno == unix.ERANGE {
|
||||
dest = make([]byte, sz)
|
||||
destBytes := unsafe.Pointer(&dest[0])
|
||||
sz, _, errno = syscall.Syscall6(syscall.SYS_LGETXATTR, uintptr(unsafe.Pointer(pathBytes)), uintptr(unsafe.Pointer(attrBytes)), uintptr(destBytes), uintptr(len(dest)), 0, 0)
|
||||
sz, errno = unix.Lgetxattr(path, attr, dest)
|
||||
}
|
||||
if errno != 0 {
|
||||
if errno != nil {
|
||||
return nil, errno
|
||||
}
|
||||
|
||||
return dest[:sz], nil
|
||||
}
|
||||
|
||||
var _zero uintptr
|
||||
|
||||
// Lsetxattr sets the value of the extended attribute identified by attr
|
||||
// and associated with the given path in the file system.
|
||||
func Lsetxattr(path string, attr string, data []byte, flags int) error {
|
||||
pathBytes, err := syscall.BytePtrFromString(path)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
attrBytes, err := syscall.BytePtrFromString(attr)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
var dataBytes unsafe.Pointer
|
||||
if len(data) > 0 {
|
||||
dataBytes = unsafe.Pointer(&data[0])
|
||||
} else {
|
||||
dataBytes = unsafe.Pointer(&_zero)
|
||||
}
|
||||
_, _, errno := syscall.Syscall6(syscall.SYS_LSETXATTR, uintptr(unsafe.Pointer(pathBytes)), uintptr(unsafe.Pointer(attrBytes)), uintptr(dataBytes), uintptr(len(data)), uintptr(flags), 0)
|
||||
if errno != 0 {
|
||||
return errno
|
||||
}
|
||||
return nil
|
||||
return unix.Lsetxattr(path, attr, data, flags)
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue