Merge pull request #44297 from thaJeztah/22.06_backport_windows_bits
[22.06 backport] windows cleanups
This commit is contained in:
commit
28c34259c7
4 changed files with 59 additions and 84 deletions
|
@ -10,7 +10,6 @@ import (
|
|||
"os/exec"
|
||||
"path/filepath"
|
||||
"time"
|
||||
"unsafe"
|
||||
|
||||
"github.com/sirupsen/logrus"
|
||||
"github.com/spf13/pflag"
|
||||
|
@ -27,7 +26,6 @@ var (
|
|||
flUnregisterService *bool
|
||||
flRunService *bool
|
||||
|
||||
setStdHandle = windows.NewLazySystemDLL("kernel32.dll").NewProc("SetStdHandle")
|
||||
oldStderr windows.Handle
|
||||
panicFile *os.File
|
||||
|
||||
|
@ -188,35 +186,14 @@ func registerService() error {
|
|||
}
|
||||
defer s.Close()
|
||||
|
||||
// See http://stackoverflow.com/questions/35151052/how-do-i-configure-failure-actions-of-a-windows-service-written-in-go
|
||||
const (
|
||||
scActionNone = 0
|
||||
scActionRestart = 1
|
||||
scActionReboot = 2
|
||||
scActionRunCommand = 3
|
||||
|
||||
serviceConfigFailureActions = 2
|
||||
err = s.SetRecoveryActions(
|
||||
[]mgr.RecoveryAction{
|
||||
{Type: mgr.ServiceRestart, Delay: 15 * time.Second},
|
||||
{Type: mgr.ServiceRestart, Delay: 15 * time.Second},
|
||||
{Type: mgr.NoAction},
|
||||
},
|
||||
uint32(24*time.Hour/time.Second),
|
||||
)
|
||||
|
||||
type serviceFailureActions struct {
|
||||
ResetPeriod uint32
|
||||
RebootMsg *uint16
|
||||
Command *uint16
|
||||
ActionsCount uint32
|
||||
Actions uintptr
|
||||
}
|
||||
|
||||
type scAction struct {
|
||||
Type uint32
|
||||
Delay uint32
|
||||
}
|
||||
t := []scAction{
|
||||
{Type: scActionRestart, Delay: uint32(60 * time.Second / time.Millisecond)},
|
||||
{Type: scActionRestart, Delay: uint32(60 * time.Second / time.Millisecond)},
|
||||
{Type: scActionNone},
|
||||
}
|
||||
lpInfo := serviceFailureActions{ResetPeriod: uint32(24 * time.Hour / time.Second), ActionsCount: uint32(3), Actions: uintptr(unsafe.Pointer(&t[0]))}
|
||||
err = windows.ChangeServiceConfig2(s.Handle, serviceConfigFailureActions, (*byte)(unsafe.Pointer(&lpInfo)))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -264,7 +241,8 @@ func initService(daemonCli *DaemonCli) (bool, bool, error) {
|
|||
return false, false, nil
|
||||
}
|
||||
|
||||
interactive, err := svc.IsAnInteractiveSession()
|
||||
// Check if we're running as a Windows service or interactively.
|
||||
isService, err := svc.IsWindowsService()
|
||||
if err != nil {
|
||||
return false, false, err
|
||||
}
|
||||
|
@ -276,7 +254,7 @@ func initService(daemonCli *DaemonCli) (bool, bool, error) {
|
|||
}
|
||||
|
||||
var log *eventlog.Log
|
||||
if !interactive {
|
||||
if isService {
|
||||
log, err = eventlog.Open(*flServiceName)
|
||||
if err != nil {
|
||||
return false, false, err
|
||||
|
@ -288,10 +266,10 @@ func initService(daemonCli *DaemonCli) (bool, bool, error) {
|
|||
|
||||
service = h
|
||||
go func() {
|
||||
if interactive {
|
||||
err = debug.Run(*flServiceName, h)
|
||||
} else {
|
||||
if isService {
|
||||
err = svc.Run(*flServiceName, h)
|
||||
} else {
|
||||
err = debug.Run(*flServiceName, h)
|
||||
}
|
||||
|
||||
h.fromsvc <- err
|
||||
|
@ -387,21 +365,19 @@ func initPanicFile(path string) error {
|
|||
// Update STD_ERROR_HANDLE to point to the panic file so that Go writes to
|
||||
// it when it panics. Remember the old stderr to restore it before removing
|
||||
// the panic file.
|
||||
sh := uint32(windows.STD_ERROR_HANDLE)
|
||||
h, err := windows.GetStdHandle(sh)
|
||||
h, err := windows.GetStdHandle(windows.STD_ERROR_HANDLE)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
oldStderr = h
|
||||
|
||||
err = windows.SetStdHandle(windows.STD_ERROR_HANDLE, windows.Handle(panicFile.Fd()))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
oldStderr = h
|
||||
|
||||
r, _, err := setStdHandle.Call(uintptr(sh), uintptr(panicFile.Fd()))
|
||||
if r == 0 && err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Reset os.Stderr to the panic file (so fmt.Fprintf(os.Stderr,...) actually gets redirected)
|
||||
os.Stderr = os.NewFile(uintptr(panicFile.Fd()), "/dev/stderr")
|
||||
os.Stderr = os.NewFile(panicFile.Fd(), "/dev/stderr")
|
||||
|
||||
// Force threads that panic to write to stderr (the panicFile handle now), otherwise it will go into the ether
|
||||
log.SetOutput(os.Stderr)
|
||||
|
@ -412,8 +388,7 @@ func initPanicFile(path string) error {
|
|||
func removePanicFile() {
|
||||
if st, err := panicFile.Stat(); err == nil {
|
||||
if st.Size() == 0 {
|
||||
sh := uint32(windows.STD_ERROR_HANDLE)
|
||||
setStdHandle.Call(uintptr(sh), uintptr(oldStderr))
|
||||
windows.SetStdHandle(windows.STD_ERROR_HANDLE, oldStderr)
|
||||
panicFile.Close()
|
||||
os.Remove(panicFile.Name())
|
||||
}
|
||||
|
|
|
@ -16,12 +16,11 @@ import (
|
|||
"strconv"
|
||||
"strings"
|
||||
"sync"
|
||||
"syscall"
|
||||
"time"
|
||||
"unsafe"
|
||||
|
||||
winio "github.com/Microsoft/go-winio"
|
||||
"github.com/Microsoft/go-winio/backuptar"
|
||||
winiofs "github.com/Microsoft/go-winio/pkg/fs"
|
||||
"github.com/Microsoft/go-winio/vhd"
|
||||
"github.com/Microsoft/hcsshim"
|
||||
"github.com/Microsoft/hcsshim/osversion"
|
||||
|
@ -100,7 +99,7 @@ type Driver struct {
|
|||
func InitFilter(home string, options []string, _ idtools.IdentityMapping) (graphdriver.Driver, error) {
|
||||
logrus.Debugf("WindowsGraphDriver InitFilter at %s", home)
|
||||
|
||||
fsType, err := getFileSystemType(string(home[0]))
|
||||
fsType, err := winiofs.GetFileSystemType(home)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@ -137,37 +136,6 @@ func InitFilter(home string, options []string, _ idtools.IdentityMapping) (graph
|
|||
return d, nil
|
||||
}
|
||||
|
||||
// win32FromHresult is a helper function to get the win32 error code from an HRESULT
|
||||
func win32FromHresult(hr uintptr) uintptr {
|
||||
if hr&0x1fff0000 == 0x00070000 {
|
||||
return hr & 0xffff
|
||||
}
|
||||
return hr
|
||||
}
|
||||
|
||||
// getFileSystemType obtains the type of a file system through GetVolumeInformation
|
||||
// https://msdn.microsoft.com/en-us/library/windows/desktop/aa364993(v=vs.85).aspx
|
||||
func getFileSystemType(drive string) (fsType string, hr error) {
|
||||
var (
|
||||
modkernel32 = windows.NewLazySystemDLL("kernel32.dll")
|
||||
procGetVolumeInformation = modkernel32.NewProc("GetVolumeInformationW")
|
||||
buf = make([]uint16, 255)
|
||||
size = windows.MAX_PATH + 1
|
||||
)
|
||||
if len(drive) != 1 {
|
||||
hr = errors.New("getFileSystemType must be called with a drive letter")
|
||||
return
|
||||
}
|
||||
drive += `:\`
|
||||
n := uintptr(unsafe.Pointer(nil))
|
||||
r0, _, _ := syscall.Syscall9(procGetVolumeInformation.Addr(), 8, uintptr(unsafe.Pointer(windows.StringToUTF16Ptr(drive))), n, n, n, n, n, uintptr(unsafe.Pointer(&buf[0])), uintptr(size), 0)
|
||||
if int32(r0) < 0 {
|
||||
hr = syscall.Errno(win32FromHresult(r0))
|
||||
}
|
||||
fsType = windows.UTF16ToString(buf)
|
||||
return
|
||||
}
|
||||
|
||||
// String returns the string representation of a driver. This should match
|
||||
// the name the graph driver has been registered with.
|
||||
func (d *Driver) String() string {
|
||||
|
@ -346,7 +314,6 @@ func (d *Driver) Remove(id string) error {
|
|||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer container.Close()
|
||||
err = container.Terminate()
|
||||
if hcsshim.IsPending(err) {
|
||||
err = container.Wait()
|
||||
|
@ -354,6 +321,7 @@ func (d *Driver) Remove(id string) error {
|
|||
err = nil
|
||||
}
|
||||
|
||||
_ = container.Close()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
|
31
vendor/github.com/Microsoft/go-winio/pkg/fs/fs_windows.go
generated
vendored
Normal file
31
vendor/github.com/Microsoft/go-winio/pkg/fs/fs_windows.go
generated
vendored
Normal file
|
@ -0,0 +1,31 @@
|
|||
package fs
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"path/filepath"
|
||||
|
||||
"golang.org/x/sys/windows"
|
||||
)
|
||||
|
||||
var (
|
||||
// ErrInvalidPath is returned when the location of a file path doesn't begin with a driver letter.
|
||||
ErrInvalidPath = errors.New("the path provided to GetFileSystemType must start with a drive letter")
|
||||
)
|
||||
|
||||
// GetFileSystemType obtains the type of a file system through GetVolumeInformation.
|
||||
// https://msdn.microsoft.com/en-us/library/windows/desktop/aa364993(v=vs.85).aspx
|
||||
func GetFileSystemType(path string) (fsType string, err error) {
|
||||
drive := filepath.VolumeName(path)
|
||||
if len(drive) != 2 {
|
||||
return "", ErrInvalidPath
|
||||
}
|
||||
|
||||
var (
|
||||
buf = make([]uint16, 255)
|
||||
size = uint32(windows.MAX_PATH + 1)
|
||||
)
|
||||
drive += `\`
|
||||
err = windows.GetVolumeInformation(windows.StringToUTF16Ptr(drive), nil, 0, nil, nil, nil, &buf[0], size)
|
||||
fsType = windows.UTF16ToString(buf)
|
||||
return
|
||||
}
|
1
vendor/modules.txt
vendored
1
vendor/modules.txt
vendored
|
@ -24,6 +24,7 @@ github.com/Microsoft/go-winio
|
|||
github.com/Microsoft/go-winio/backuptar
|
||||
github.com/Microsoft/go-winio/pkg/etw
|
||||
github.com/Microsoft/go-winio/pkg/etwlogrus
|
||||
github.com/Microsoft/go-winio/pkg/fs
|
||||
github.com/Microsoft/go-winio/pkg/guid
|
||||
github.com/Microsoft/go-winio/pkg/security
|
||||
github.com/Microsoft/go-winio/vhd
|
||||
|
|
Loading…
Reference in a new issue