func setupDumpStackTrap(root string) { // Windows does not support signals like *nix systems. So instead of // trapping on SIGUSR1 to dump stacks, we wait on a Win32 event to be // signaled. ACL'd to builtin administrators and local system ev := "Global\\docker-daemon-" + fmt.Sprint(os.Getpid()) sd, err := winio.SddlToSecurityDescriptor("D:P(A;;GA;;;BA)(A;;GA;;;SY)") if err != nil { logrus.Errorf("failed to get security descriptor for debug stackdump event %s: %s", ev, err.Error()) return } var sa syscall.SecurityAttributes sa.Length = uint32(unsafe.Sizeof(sa)) sa.InheritHandle = 1 sa.SecurityDescriptor = uintptr(unsafe.Pointer(&sd[0])) h, err := system.CreateEvent(&sa, false, false, ev) if h == 0 || err != nil { logrus.Errorf("failed to create debug stackdump event %s: %s", ev, err.Error()) return } go func() { logrus.Debugf("Stackdump - waiting signal at %s", ev) for { syscall.WaitForSingleObject(h, syscall.INFINITE) signal.DumpStacks(root) } }() }
// 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 syscall.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) error { sa := syscall.SecurityAttributes{Length: 0} sddl := "D:P(A;OICI;GA;;;BA)(A;OICI;GA;;;SY)" sd, err := winio.SddlToSecurityDescriptor(sddl) if err != nil { return &os.PathError{"mkdir", name, err} } sa.Length = uint32(unsafe.Sizeof(sa)) sa.InheritHandle = 1 sa.SecurityDescriptor = uintptr(unsafe.Pointer(&sd[0])) namep, err := syscall.UTF16PtrFromString(name) if err != nil { return &os.PathError{"mkdir", name, err} } e := syscall.CreateDirectory(namep, &sa) if e != nil { return &os.PathError{"mkdir", name, e} } return nil }