switch to client provided services and address nits

Signed-off-by: Mike Brown <brownwm@us.ibm.com>
This commit is contained in:
Mike Brown 2017-06-20 13:13:12 -05:00
parent 0fe8c17fdf
commit 97063a0e34
19 changed files with 261 additions and 184 deletions

4
Godeps/Godeps.json generated
View File

@ -8,8 +8,8 @@
"Deps": [ "Deps": [
{ {
"ImportPath": "github.com/Microsoft/go-winio", "ImportPath": "github.com/Microsoft/go-winio",
"Comment": "v0.3.8", "Comment": "v0.4.1",
"Rev": "fff283ad5116362ca252298cfc9b95828956d85d" "Rev": "706941bedd2d9b3a8c88e4022bd0078101f233f2"
}, },
{ {
"ImportPath": "github.com/Sirupsen/logrus", "ImportPath": "github.com/Sirupsen/logrus",

View File

@ -37,14 +37,8 @@ func main() {
os.Exit(0) os.Exit(0)
} }
glog.V(2).Infof("Connect to containerd endpoint %q with timeout %v", o.ContainerdEndpoint, o.ContainerdConnectionTimeout)
conn, err := server.ConnectToContainerd(o.ContainerdEndpoint, o.ContainerdConnectionTimeout)
if err != nil {
glog.Exitf("Failed to connect containerd endpoint %q: %v", o.ContainerdEndpoint, err)
}
glog.V(2).Infof("Run cri-containerd grpc server on socket %q", o.SocketPath) glog.V(2).Infof("Run cri-containerd grpc server on socket %q", o.SocketPath)
service, err := server.NewCRIContainerdService(conn, o.ContainerdEndpoint, o.RootDir, o.NetworkPluginBinDir, o.NetworkPluginConfDir) service, err := server.NewCRIContainerdService(o.ContainerdEndpoint, o.RootDir, o.NetworkPluginBinDir, o.NetworkPluginConfDir)
if err != nil { if err != nil {
glog.Exitf("Failed to create CRI containerd service %+v: %v", o, err) glog.Exitf("Failed to create CRI containerd service %+v: %v", o, err)
} }

View File

@ -24,6 +24,7 @@ for d in $(find . -type d -a \( -iwholename './pkg*' -o -iwholename './cmd*' \))
--exclude='.*_test\.go:.*error return value not checked.*\(errcheck\)$' \ --exclude='.*_test\.go:.*error return value not checked.*\(errcheck\)$' \
--exclude='duplicate of.*_test.go.*\(dupl\)$' \ --exclude='duplicate of.*_test.go.*\(dupl\)$' \
--exclude='.*/mock_.*\.go:.*\(golint\)$' \ --exclude='.*/mock_.*\.go:.*\(golint\)$' \
--exclude='declaration of "err" shadows declaration.*\(vetshadow\)$' \
--disable=aligncheck \ --disable=aligncheck \
--disable=gotype \ --disable=gotype \
--disable=gas \ --disable=gas \

View File

@ -58,7 +58,7 @@ func (c *criContainerdService) CreateContainer(ctx context.Context, r *runtime.C
// the same container. // the same container.
id := generateID() id := generateID()
name := makeContainerName(config.GetMetadata(), sandboxConfig.GetMetadata()) name := makeContainerName(config.GetMetadata(), sandboxConfig.GetMetadata())
if err = c.containerNameIndex.Reserve(name, id); err != nil { if err := c.containerNameIndex.Reserve(name, id); err != nil {
return nil, fmt.Errorf("failed to reserve container name %q: %v", name, err) return nil, fmt.Errorf("failed to reserve container name %q: %v", name, err)
} }
defer func() { defer func() {
@ -101,17 +101,17 @@ func (c *criContainerdService) CreateContainer(ctx context.Context, r *runtime.C
// Prepare container rootfs. // Prepare container rootfs.
if config.GetLinux().GetSecurityContext().GetReadonlyRootfs() { if config.GetLinux().GetSecurityContext().GetReadonlyRootfs() {
if _, err = c.snapshotService.View(ctx, id, imageMeta.ChainID); err != nil { if _, err := c.snapshotService.View(ctx, id, imageMeta.ChainID); err != nil {
return nil, fmt.Errorf("failed to view container rootfs %q: %v", imageMeta.ChainID, err) return nil, fmt.Errorf("failed to view container rootfs %q: %v", imageMeta.ChainID, err)
} }
} else { } else {
if _, err = c.snapshotService.Prepare(ctx, id, imageMeta.ChainID); err != nil { if _, err := c.snapshotService.Prepare(ctx, id, imageMeta.ChainID); err != nil {
return nil, fmt.Errorf("failed to prepare container rootfs %q: %v", imageMeta.ChainID, err) return nil, fmt.Errorf("failed to prepare container rootfs %q: %v", imageMeta.ChainID, err)
} }
} }
defer func() { defer func() {
if retErr != nil { if retErr != nil {
if err = c.snapshotService.Remove(ctx, id); err != nil { if err := c.snapshotService.Remove(ctx, id); err != nil {
glog.Errorf("Failed to remove container snapshot %q: %v", id, err) glog.Errorf("Failed to remove container snapshot %q: %v", id, err)
} }
} }
@ -120,14 +120,14 @@ func (c *criContainerdService) CreateContainer(ctx context.Context, r *runtime.C
// Create container root directory. // Create container root directory.
containerRootDir := getContainerRootDir(c.rootDir, id) containerRootDir := getContainerRootDir(c.rootDir, id)
if err = c.os.MkdirAll(containerRootDir, 0755); err != nil { if err := c.os.MkdirAll(containerRootDir, 0755); err != nil {
return nil, fmt.Errorf("failed to create container root directory %q: %v", return nil, fmt.Errorf("failed to create container root directory %q: %v",
containerRootDir, err) containerRootDir, err)
} }
defer func() { defer func() {
if retErr != nil { if retErr != nil {
// Cleanup the container root directory. // Cleanup the container root directory.
if err = c.os.RemoveAll(containerRootDir); err != nil { if err := c.os.RemoveAll(containerRootDir); err != nil {
glog.Errorf("Failed to remove container root directory %q: %v", glog.Errorf("Failed to remove container root directory %q: %v",
containerRootDir, err) containerRootDir, err)
} }

View File

@ -552,11 +552,11 @@ func TestCreateContainer(t *testing.T) {
"container name should be released") "container name should be released")
} }
assert.Empty(t, fakeSnapshotClient.ListMounts(), "snapshot should be cleaned up") assert.Empty(t, fakeSnapshotClient.ListMounts(), "snapshot should be cleaned up")
listResp, listerr := fake.List(context.Background(), &containers.ListContainersRequest{}) listResp, err := fake.List(context.Background(), &containers.ListContainersRequest{})
assert.NoError(t, listerr) assert.NoError(t, err)
assert.Empty(t, listResp.Containers, "containerd container should be cleaned up") assert.Empty(t, listResp.Containers, "containerd container should be cleaned up")
metas, metaserr := c.containerStore.List() metas, err := c.containerStore.List()
assert.NoError(t, metaserr) assert.NoError(t, err)
assert.Empty(t, metas, "container metadata should not be created") assert.Empty(t, metas, "container metadata should not be created")
continue continue
} }

View File

@ -202,8 +202,8 @@ func TestRemoveContainer(t *testing.T) {
if !test.expectUnsetRemoving { if !test.expectUnsetRemoving {
continue continue
} }
meta, metaerr := c.containerStore.Get(testID) meta, err := c.containerStore.Get(testID)
assert.NoError(t, metaerr) assert.NoError(t, err)
require.NotNil(t, meta) require.NotNil(t, meta)
// Also covers resetContainerRemoving. // Also covers resetContainerRemoving.
assert.False(t, meta.Removing, "removing state should be unset") assert.False(t, meta.Removing, "removing state should be unset")

View File

@ -137,12 +137,12 @@ func (c *criContainerdService) startContainer(ctx context.Context, id string, me
if config.GetLogPath() != "" { if config.GetLogPath() != "" {
// Only generate container log when log path is specified. // Only generate container log when log path is specified.
logPath := filepath.Join(sandboxConfig.GetLogDirectory(), config.GetLogPath()) logPath := filepath.Join(sandboxConfig.GetLogDirectory(), config.GetLogPath())
if err = c.agentFactory.NewContainerLogger(logPath, agents.Stdout, stdoutPipe).Start(); err != nil { if err := c.agentFactory.NewContainerLogger(logPath, agents.Stdout, stdoutPipe).Start(); err != nil {
return fmt.Errorf("failed to start container stdout logger: %v", err) return fmt.Errorf("failed to start container stdout logger: %v", err)
} }
// Only redirect stderr when there is no tty. // Only redirect stderr when there is no tty.
if !config.GetTty() { if !config.GetTty() {
if err = c.agentFactory.NewContainerLogger(logPath, agents.Stderr, stderrPipe).Start(); err != nil { if err := c.agentFactory.NewContainerLogger(logPath, agents.Stderr, stderrPipe).Start(); err != nil {
return fmt.Errorf("failed to start container stderr logger: %v", err) return fmt.Errorf("failed to start container stderr logger: %v", err)
} }
} }

View File

@ -223,7 +223,7 @@ func TestStartContainer(t *testing.T) {
assert.EqualValues(t, errorStartExitCode, meta.ExitCode) assert.EqualValues(t, errorStartExitCode, meta.ExitCode)
assert.Equal(t, errorStartReason, meta.Reason) assert.Equal(t, errorStartReason, meta.Reason)
assert.NotEmpty(t, meta.Message) assert.NotEmpty(t, meta.Message)
_, err = fake.Info(context.Background(), &execution.InfoRequest{ContainerID: testID}) _, err := fake.Info(context.Background(), &execution.InfoRequest{ContainerID: testID})
assert.True(t, isContainerdGRPCNotFoundError(err), assert.True(t, isContainerdGRPCNotFoundError(err),
"containerd task should be cleaned up when fail to start") "containerd task should be cleaned up when fail to start")
continue continue

View File

@ -346,21 +346,21 @@ func (c *criContainerdService) localResolve(ctx context.Context, ref string) (*m
_, err := imagedigest.Parse(ref) _, err := imagedigest.Parse(ref)
if err != nil { if err != nil {
// ref is not image id, try to resolve it locally. // ref is not image id, try to resolve it locally.
normalized, nerr := normalizeImageRef(ref) normalized, err := normalizeImageRef(ref)
if err != nil { if err != nil {
return nil, fmt.Errorf("invalid image reference %q: %v", ref, nerr) return nil, fmt.Errorf("invalid image reference %q: %v", ref, err)
} }
image, gerr := c.imageStoreService.Get(ctx, normalized.String()) image, err := c.imageStoreService.Get(ctx, normalized.String())
if gerr != nil { if err != nil {
if containerdmetadata.IsNotFound(gerr) { if containerdmetadata.IsNotFound(err) {
return nil, nil return nil, nil
} }
return nil, fmt.Errorf("an error occurred when getting image %q from containerd image store: %v", return nil, fmt.Errorf("an error occurred when getting image %q from containerd image store: %v",
normalized.String(), gerr) normalized.String(), err)
} }
desc, cerr := image.Config(ctx, c.contentStoreService) desc, err := image.Config(ctx, c.contentStoreService)
if cerr != nil { if err != nil {
return nil, fmt.Errorf("failed to get image config descriptor: %v", cerr) return nil, fmt.Errorf("failed to get image config descriptor: %v", err)
} }
ref = desc.Digest.String() ref = desc.Digest.String()
} }

View File

@ -118,7 +118,7 @@ func (c *criContainerdService) PullImage(ctx context.Context, r *runtime.PullIma
// recover in-memory state during startup. // recover in-memory state during startup.
if err == nil { if err == nil {
// Update existing image metadata. // Update existing image metadata.
if err = c.imageMetadataStore.Update(imageID, func(m metadata.ImageMetadata) (metadata.ImageMetadata, error) { if err := c.imageMetadataStore.Update(imageID, func(m metadata.ImageMetadata) (metadata.ImageMetadata, error) {
updateImageMetadata(&m, repoTag, repoDigest) updateImageMetadata(&m, repoTag, repoDigest)
return m, nil return m, nil
}); err != nil { }); err != nil {
@ -246,7 +246,7 @@ func (c *criContainerdService) pullImage(ctx context.Context, ref string) (
glog.V(5).Infof("Dispatch for %q returns error: %v", ref, err) glog.V(5).Infof("Dispatch for %q returns error: %v", ref, err)
} }
// Wait for the image pulling to finish // Wait for the image pulling to finish
if err = c.waitForResourcesDownloading(ctx, resources.all()); err != nil { if err := c.waitForResourcesDownloading(ctx, resources.all()); err != nil {
return "", "", fmt.Errorf("failed to wait for image %q downloading: %v", ref, err) return "", "", fmt.Errorf("failed to wait for image %q downloading: %v", ref, err)
} }
glog.V(4).Infof("Finished downloading resources for image %q", ref) glog.V(4).Infof("Finished downloading resources for image %q", ref)
@ -283,7 +283,7 @@ func (c *criContainerdService) pullImage(ctx context.Context, ref string) (
return "", "", fmt.Errorf("readblob failed for manifest digest %q: %v", manifestDigest, err) return "", "", fmt.Errorf("readblob failed for manifest digest %q: %v", manifestDigest, err)
} }
var manifest imagespec.Manifest var manifest imagespec.Manifest
if err = json.Unmarshal(p, &manifest); err != nil { if err := json.Unmarshal(p, &manifest); err != nil {
return "", "", fmt.Errorf("unmarshal blob to manifest failed for manifest digest %q: %v", return "", "", fmt.Errorf("unmarshal blob to manifest failed for manifest digest %q: %v",
manifestDigest, err) manifestDigest, err)
} }

View File

@ -64,7 +64,7 @@ func (c *criContainerdService) RemovePodSandbox(ctx context.Context, r *runtime.
} }
// Remove sandbox container snapshot. // Remove sandbox container snapshot.
if err = c.snapshotService.Remove(ctx, id); err != nil { if err := c.snapshotService.Remove(ctx, id); err != nil {
if !snapshot.IsNotExist(err) { if !snapshot.IsNotExist(err) {
return nil, fmt.Errorf("failed to remove sandbox container snapshot %q: %v", id, err) return nil, fmt.Errorf("failed to remove sandbox container snapshot %q: %v", id, err)
} }

View File

@ -94,7 +94,7 @@ func (c *criContainerdService) RunPodSandbox(ctx context.Context, r *runtime.Run
} }
defer func() { defer func() {
if retErr != nil { if retErr != nil {
if err = c.snapshotService.Remove(ctx, id); err != nil { if err := c.snapshotService.Remove(ctx, id); err != nil {
glog.Errorf("Failed to remove sandbox container snapshot %q: %v", id, err) glog.Errorf("Failed to remove sandbox container snapshot %q: %v", id, err)
} }
} }
@ -135,7 +135,7 @@ func (c *criContainerdService) RunPodSandbox(ctx context.Context, r *runtime.Run
} }
defer func() { defer func() {
if retErr != nil { if retErr != nil {
if _, err = c.containerService.Delete(ctx, &containers.DeleteContainerRequest{ID: id}); err != nil { if _, err := c.containerService.Delete(ctx, &containers.DeleteContainerRequest{ID: id}); err != nil {
glog.Errorf("Failed to delete containerd container%q: %v", id, err) glog.Errorf("Failed to delete containerd container%q: %v", id, err)
} }
} }
@ -144,14 +144,14 @@ func (c *criContainerdService) RunPodSandbox(ctx context.Context, r *runtime.Run
// Create sandbox container root directory. // Create sandbox container root directory.
// Prepare streaming named pipe. // Prepare streaming named pipe.
sandboxRootDir := getSandboxRootDir(c.rootDir, id) sandboxRootDir := getSandboxRootDir(c.rootDir, id)
if err = c.os.MkdirAll(sandboxRootDir, 0755); err != nil { if err := c.os.MkdirAll(sandboxRootDir, 0755); err != nil {
return nil, fmt.Errorf("failed to create sandbox root directory %q: %v", return nil, fmt.Errorf("failed to create sandbox root directory %q: %v",
sandboxRootDir, err) sandboxRootDir, err)
} }
defer func() { defer func() {
if retErr != nil { if retErr != nil {
// Cleanup the sandbox root directory. // Cleanup the sandbox root directory.
if err = c.os.RemoveAll(sandboxRootDir); err != nil { if err := c.os.RemoveAll(sandboxRootDir); err != nil {
glog.Errorf("Failed to remove sandbox root directory %q: %v", glog.Errorf("Failed to remove sandbox root directory %q: %v",
sandboxRootDir, err) sandboxRootDir, err)
} }
@ -170,10 +170,10 @@ func (c *criContainerdService) RunPodSandbox(ctx context.Context, r *runtime.Run
stderrPipe.Close() stderrPipe.Close()
} }
}() }()
if err = c.agentFactory.NewSandboxLogger(stdoutPipe).Start(); err != nil { if err := c.agentFactory.NewSandboxLogger(stdoutPipe).Start(); err != nil {
return nil, fmt.Errorf("failed to start sandbox stdout logger: %v", err) return nil, fmt.Errorf("failed to start sandbox stdout logger: %v", err)
} }
if err = c.agentFactory.NewSandboxLogger(stderrPipe).Start(); err != nil { if err := c.agentFactory.NewSandboxLogger(stderrPipe).Start(); err != nil {
return nil, fmt.Errorf("failed to start sandbox stderr logger: %v", err) return nil, fmt.Errorf("failed to start sandbox stderr logger: %v", err)
} }

View File

@ -21,22 +21,15 @@ import (
"net" "net"
"os" "os"
"syscall" "syscall"
"time"
"github.com/containerd/containerd/namespaces"
"github.com/golang/glog" "github.com/golang/glog"
"golang.org/x/net/context"
"google.golang.org/grpc" "google.golang.org/grpc"
runtime "k8s.io/kubernetes/pkg/kubelet/apis/cri/v1alpha1" runtime "k8s.io/kubernetes/pkg/kubelet/apis/cri/v1alpha1"
"k8s.io/kubernetes/pkg/util/interrupt" "k8s.io/kubernetes/pkg/util/interrupt"
) )
const (
// unixProtocol is the network protocol of unix socket. // unixProtocol is the network protocol of unix socket.
unixProtocol = "unix" const unixProtocol = "unix"
// k8sContainerdNamespace is the namespace we use to connect containerd.
k8sContainerdNamespace = "k8s.io"
)
// CRIContainerdServer is the grpc server of cri-containerd. // CRIContainerdServer is the grpc server of cri-containerd.
type CRIContainerdServer struct { type CRIContainerdServer struct {
@ -79,38 +72,3 @@ func (s *CRIContainerdServer) Run() error {
h := interrupt.New(nil, s.server.Stop) h := interrupt.New(nil, s.server.Stop)
return h.Run(func() error { return s.server.Serve(l) }) return h.Run(func() error { return s.server.Serve(l) })
} }
// ConnectToContainerd returns a grpc client for containerd.
func ConnectToContainerd(path string, connectionTimeout time.Duration) (*grpc.ClientConn, error) {
// get the containerd client
dialOpts := []grpc.DialOption{
grpc.WithInsecure(),
grpc.WithTimeout(connectionTimeout),
grpc.WithDialer(func(addr string, timeout time.Duration) (net.Conn, error) {
return net.DialTimeout(unixProtocol, path, timeout)
}),
grpc.WithUnaryInterceptor(grpc.UnaryClientInterceptor(unary)),
grpc.WithStreamInterceptor(grpc.StreamClientInterceptor(stream)),
}
return grpc.Dial(fmt.Sprintf("%s://%s", unixProtocol, path), dialOpts...)
}
// TODO(random-liu): Get rid of following functions after switching to containerd client.
// unary is a wrapper to apply kubernetes namespace in each grpc unary call.
func unary(ctx context.Context, method string, req, reply interface{}, cc *grpc.ClientConn, invoker grpc.UnaryInvoker, opts ...grpc.CallOption) error {
_, ok := namespaces.Namespace(ctx)
if !ok {
ctx = namespaces.WithNamespace(ctx, k8sContainerdNamespace)
}
return invoker(ctx, method, req, reply, cc, opts...)
}
// stream is a wrapper to apply kubernetes namespace in each grpc stream call.
func stream(ctx context.Context, desc *grpc.StreamDesc, cc *grpc.ClientConn, method string, streamer grpc.Streamer, opts ...grpc.CallOption) (grpc.ClientStream, error) {
_, ok := namespaces.Namespace(ctx)
if !ok {
ctx = namespaces.WithNamespace(ctx, k8sContainerdNamespace)
}
return streamer(ctx, desc, cc, method, opts...)
}

View File

@ -21,22 +21,14 @@ import (
"github.com/containerd/containerd" "github.com/containerd/containerd"
"github.com/containerd/containerd/api/services/containers" "github.com/containerd/containerd/api/services/containers"
contentapi "github.com/containerd/containerd/api/services/content"
diffapi "github.com/containerd/containerd/api/services/diff"
"github.com/containerd/containerd/api/services/execution" "github.com/containerd/containerd/api/services/execution"
imagesapi "github.com/containerd/containerd/api/services/images"
snapshotapi "github.com/containerd/containerd/api/services/snapshot"
versionapi "github.com/containerd/containerd/api/services/version" versionapi "github.com/containerd/containerd/api/services/version"
"github.com/containerd/containerd/content" "github.com/containerd/containerd/content"
"github.com/containerd/containerd/images" "github.com/containerd/containerd/images"
contentservice "github.com/containerd/containerd/services/content"
diffservice "github.com/containerd/containerd/services/diff" diffservice "github.com/containerd/containerd/services/diff"
imagesservice "github.com/containerd/containerd/services/images"
snapshotservice "github.com/containerd/containerd/services/snapshot"
"github.com/containerd/containerd/snapshot" "github.com/containerd/containerd/snapshot"
"github.com/docker/docker/pkg/truncindex" "github.com/docker/docker/pkg/truncindex"
"github.com/kubernetes-incubator/cri-o/pkg/ocicni" "github.com/kubernetes-incubator/cri-o/pkg/ocicni"
"google.golang.org/grpc"
healthapi "google.golang.org/grpc/health/grpc_health_v1" healthapi "google.golang.org/grpc/health/grpc_health_v1"
runtime "k8s.io/kubernetes/pkg/kubelet/apis/cri/v1alpha1" runtime "k8s.io/kubernetes/pkg/kubelet/apis/cri/v1alpha1"
@ -47,6 +39,9 @@ import (
"github.com/kubernetes-incubator/cri-containerd/pkg/server/agents" "github.com/kubernetes-incubator/cri-containerd/pkg/server/agents"
) )
// k8sContainerdNamespace is the namespace we use to connect containerd.
const k8sContainerdNamespace = "k8s.io"
// CRIContainerdService is the interface implement CRI remote service server. // CRIContainerdService is the interface implement CRI remote service server.
type CRIContainerdService interface { type CRIContainerdService interface {
Start() Start()
@ -105,12 +100,12 @@ type criContainerdService struct {
} }
// NewCRIContainerdService returns a new instance of CRIContainerdService // NewCRIContainerdService returns a new instance of CRIContainerdService
func NewCRIContainerdService(conn *grpc.ClientConn, containerdEndpoint, rootDir, networkPluginBinDir, networkPluginConfDir string) (CRIContainerdService, error) { func NewCRIContainerdService(containerdEndpoint, rootDir, networkPluginBinDir, networkPluginConfDir string) (CRIContainerdService, error) {
// TODO(random-liu): [P2] Recover from runtime state and metadata store. // TODO(random-liu): [P2] Recover from runtime state and metadata store.
client, err := containerd.New(containerdEndpoint) client, err := containerd.New(containerdEndpoint, containerd.WithDefaultNamespace(k8sContainerdNamespace))
if err != nil { if err != nil {
return nil, fmt.Errorf("failed to initialize client: %v", err) return nil, fmt.Errorf("failed to initialize containerd client with endpoint %q: %v", containerdEndpoint, err)
} }
c := &criContainerdService{ c := &criContainerdService{
@ -126,14 +121,14 @@ func NewCRIContainerdService(conn *grpc.ClientConn, containerdEndpoint, rootDir,
sandboxIDIndex: truncindex.NewTruncIndex(nil), sandboxIDIndex: truncindex.NewTruncIndex(nil),
// TODO(random-liu): Add container id index. // TODO(random-liu): Add container id index.
containerNameIndex: registrar.NewRegistrar(), containerNameIndex: registrar.NewRegistrar(),
containerService: containers.NewContainersClient(conn), containerService: client.ContainerService(),
taskService: execution.NewTasksClient(conn), taskService: client.TaskService(),
imageStoreService: imagesservice.NewStoreFromClient(imagesapi.NewImagesClient(conn)), imageStoreService: client.ImageService(),
contentStoreService: contentservice.NewStoreFromClient(contentapi.NewContentClient(conn)), contentStoreService: client.ContentStore(),
snapshotService: snapshotservice.NewSnapshotterFromClient(snapshotapi.NewSnapshotClient(conn)), snapshotService: client.SnapshotService(),
diffService: diffservice.NewDiffServiceFromClient(diffapi.NewDiffClient(conn)), diffService: client.DiffService(),
versionService: versionapi.NewVersionClient(conn), versionService: client.VersionService(),
healthService: healthapi.NewHealthClient(conn), healthService: client.HealthService(),
agentFactory: agents.NewAgentFactory(), agentFactory: agents.NewAgentFactory(),
client: client, client: client,
} }

View File

@ -185,7 +185,6 @@ type BackupFileReader struct {
// Read will attempt to read the security descriptor of the file. // Read will attempt to read the security descriptor of the file.
func NewBackupFileReader(f *os.File, includeSecurity bool) *BackupFileReader { func NewBackupFileReader(f *os.File, includeSecurity bool) *BackupFileReader {
r := &BackupFileReader{f, includeSecurity, 0} r := &BackupFileReader{f, includeSecurity, 0}
runtime.SetFinalizer(r, func(r *BackupFileReader) { r.Close() })
return r return r
} }
@ -196,6 +195,7 @@ func (r *BackupFileReader) Read(b []byte) (int, error) {
if err != nil { if err != nil {
return 0, &os.PathError{"BackupRead", r.f.Name(), err} return 0, &os.PathError{"BackupRead", r.f.Name(), err}
} }
runtime.KeepAlive(r.f)
if bytesRead == 0 { if bytesRead == 0 {
return 0, io.EOF return 0, io.EOF
} }
@ -207,6 +207,7 @@ func (r *BackupFileReader) Read(b []byte) (int, error) {
func (r *BackupFileReader) Close() error { func (r *BackupFileReader) Close() error {
if r.ctx != 0 { if r.ctx != 0 {
backupRead(syscall.Handle(r.f.Fd()), nil, nil, true, false, &r.ctx) backupRead(syscall.Handle(r.f.Fd()), nil, nil, true, false, &r.ctx)
runtime.KeepAlive(r.f)
r.ctx = 0 r.ctx = 0
} }
return nil return nil
@ -223,7 +224,6 @@ type BackupFileWriter struct {
// Write() will attempt to restore the security descriptor from the stream. // Write() will attempt to restore the security descriptor from the stream.
func NewBackupFileWriter(f *os.File, includeSecurity bool) *BackupFileWriter { func NewBackupFileWriter(f *os.File, includeSecurity bool) *BackupFileWriter {
w := &BackupFileWriter{f, includeSecurity, 0} w := &BackupFileWriter{f, includeSecurity, 0}
runtime.SetFinalizer(w, func(w *BackupFileWriter) { w.Close() })
return w return w
} }
@ -234,6 +234,7 @@ func (w *BackupFileWriter) Write(b []byte) (int, error) {
if err != nil { if err != nil {
return 0, &os.PathError{"BackupWrite", w.f.Name(), err} return 0, &os.PathError{"BackupWrite", w.f.Name(), err}
} }
runtime.KeepAlive(w.f)
if int(bytesWritten) != len(b) { if int(bytesWritten) != len(b) {
return int(bytesWritten), errors.New("not all bytes could be written") return int(bytesWritten), errors.New("not all bytes could be written")
} }
@ -245,6 +246,7 @@ func (w *BackupFileWriter) Write(b []byte) (int, error) {
func (w *BackupFileWriter) Close() error { func (w *BackupFileWriter) Close() error {
if w.ctx != 0 { if w.ctx != 0 {
backupWrite(syscall.Handle(w.f.Fd()), nil, nil, true, false, &w.ctx) backupWrite(syscall.Handle(w.f.Fd()), nil, nil, true, false, &w.ctx)
runtime.KeepAlive(w.f)
w.ctx = 0 w.ctx = 0
} }
return nil return nil

View File

@ -7,6 +7,7 @@ import (
"io" "io"
"runtime" "runtime"
"sync" "sync"
"sync/atomic"
"syscall" "syscall"
"time" "time"
) )
@ -17,6 +18,12 @@ import (
//sys setFileCompletionNotificationModes(h syscall.Handle, flags uint8) (err error) = SetFileCompletionNotificationModes //sys setFileCompletionNotificationModes(h syscall.Handle, flags uint8) (err error) = SetFileCompletionNotificationModes
//sys timeBeginPeriod(period uint32) (n int32) = winmm.timeBeginPeriod //sys timeBeginPeriod(period uint32) (n int32) = winmm.timeBeginPeriod
type atomicBool int32
func (b *atomicBool) isSet() bool { return atomic.LoadInt32((*int32)(b)) != 0 }
func (b *atomicBool) setFalse() { atomic.StoreInt32((*int32)(b), 0) }
func (b *atomicBool) setTrue() { atomic.StoreInt32((*int32)(b), 1) }
const ( const (
cFILE_SKIP_COMPLETION_PORT_ON_SUCCESS = 1 cFILE_SKIP_COMPLETION_PORT_ON_SUCCESS = 1
cFILE_SKIP_SET_EVENT_ON_HANDLE = 2 cFILE_SKIP_SET_EVENT_ON_HANDLE = 2
@ -33,6 +40,8 @@ func (e *timeoutError) Error() string { return "i/o timeout" }
func (e *timeoutError) Timeout() bool { return true } func (e *timeoutError) Timeout() bool { return true }
func (e *timeoutError) Temporary() bool { return true } func (e *timeoutError) Temporary() bool { return true }
type timeoutChan chan struct{}
var ioInitOnce sync.Once var ioInitOnce sync.Once
var ioCompletionPort syscall.Handle var ioCompletionPort syscall.Handle
@ -63,8 +72,16 @@ type win32File struct {
handle syscall.Handle handle syscall.Handle
wg sync.WaitGroup wg sync.WaitGroup
closing bool closing bool
readDeadline time.Time readDeadline deadlineHandler
writeDeadline time.Time writeDeadline deadlineHandler
}
type deadlineHandler struct {
setLock sync.Mutex
channel timeoutChan
channelLock sync.RWMutex
timer *time.Timer
timedout atomicBool
} }
// makeWin32File makes a new win32File from an existing file handle // makeWin32File makes a new win32File from an existing file handle
@ -79,7 +96,8 @@ func makeWin32File(h syscall.Handle) (*win32File, error) {
if err != nil { if err != nil {
return nil, err return nil, err
} }
runtime.SetFinalizer(f, (*win32File).closeHandle) f.readDeadline.channel = make(timeoutChan)
f.writeDeadline.channel = make(timeoutChan)
return f, nil return f, nil
} }
@ -103,11 +121,11 @@ func (f *win32File) closeHandle() {
// Close closes a win32File. // Close closes a win32File.
func (f *win32File) Close() error { func (f *win32File) Close() error {
f.closeHandle() f.closeHandle()
runtime.SetFinalizer(f, nil)
return nil return nil
} }
// prepareIo prepares for a new IO operation // prepareIo prepares for a new IO operation.
// The caller must call f.wg.Done() when the IO is finished, prior to Close() returning.
func (f *win32File) prepareIo() (*ioOperation, error) { func (f *win32File) prepareIo() (*ioOperation, error) {
f.wg.Add(1) f.wg.Add(1)
if f.closing { if f.closing {
@ -136,48 +154,46 @@ func ioCompletionProcessor(h syscall.Handle) {
// asyncIo processes the return value from ReadFile or WriteFile, blocking until // asyncIo processes the return value from ReadFile or WriteFile, blocking until
// the operation has actually completed. // the operation has actually completed.
func (f *win32File) asyncIo(c *ioOperation, deadline time.Time, bytes uint32, err error) (int, error) { func (f *win32File) asyncIo(c *ioOperation, d *deadlineHandler, bytes uint32, err error) (int, error) {
if err != syscall.ERROR_IO_PENDING { if err != syscall.ERROR_IO_PENDING {
f.wg.Done()
return int(bytes), err return int(bytes), err
} else { }
var r ioResult
wait := true
timedout := false
if f.closing { if f.closing {
cancelIoEx(f.handle, &c.o) cancelIoEx(f.handle, &c.o)
} else if !deadline.IsZero() { }
now := time.Now()
if !deadline.After(now) { var timeout timeoutChan
timedout = true if d != nil {
} else { d.channelLock.Lock()
timeout := time.After(deadline.Sub(now)) timeout = d.channel
d.channelLock.Unlock()
}
var r ioResult
select { select {
case r = <-c.ch: case r = <-c.ch:
wait = false
case <-timeout:
timedout = true
}
}
}
if timedout {
cancelIoEx(f.handle, &c.o)
}
if wait {
r = <-c.ch
}
err = r.err err = r.err
if err == syscall.ERROR_OPERATION_ABORTED { if err == syscall.ERROR_OPERATION_ABORTED {
if f.closing { if f.closing {
err = ErrFileClosed err = ErrFileClosed
} else if timedout { }
}
case <-timeout:
cancelIoEx(f.handle, &c.o)
r = <-c.ch
err = r.err
if err == syscall.ERROR_OPERATION_ABORTED {
err = ErrTimeout err = ErrTimeout
} }
} }
f.wg.Done()
// runtime.KeepAlive is needed, as c is passed via native
// code to ioCompletionProcessor, c must remain alive
// until the channel read is complete.
runtime.KeepAlive(c)
return int(r.bytes), err return int(r.bytes), err
} }
}
// Read reads from a file handle. // Read reads from a file handle.
func (f *win32File) Read(b []byte) (int, error) { func (f *win32File) Read(b []byte) (int, error) {
@ -185,9 +201,16 @@ func (f *win32File) Read(b []byte) (int, error) {
if err != nil { if err != nil {
return 0, err return 0, err
} }
defer f.wg.Done()
if f.readDeadline.timedout.isSet() {
return 0, ErrTimeout
}
var bytes uint32 var bytes uint32
err = syscall.ReadFile(f.handle, b, &bytes, &c.o) err = syscall.ReadFile(f.handle, b, &bytes, &c.o)
n, err := f.asyncIo(c, f.readDeadline, bytes, err) n, err := f.asyncIo(c, &f.readDeadline, bytes, err)
runtime.KeepAlive(b)
// Handle EOF conditions. // Handle EOF conditions.
if err == nil && n == 0 && len(b) != 0 { if err == nil && n == 0 && len(b) != 0 {
@ -205,17 +228,68 @@ func (f *win32File) Write(b []byte) (int, error) {
if err != nil { if err != nil {
return 0, err return 0, err
} }
defer f.wg.Done()
if f.writeDeadline.timedout.isSet() {
return 0, ErrTimeout
}
var bytes uint32 var bytes uint32
err = syscall.WriteFile(f.handle, b, &bytes, &c.o) err = syscall.WriteFile(f.handle, b, &bytes, &c.o)
return f.asyncIo(c, f.writeDeadline, bytes, err) n, err := f.asyncIo(c, &f.writeDeadline, bytes, err)
runtime.KeepAlive(b)
return n, err
} }
func (f *win32File) SetReadDeadline(t time.Time) error { func (f *win32File) SetReadDeadline(deadline time.Time) error {
f.readDeadline = t return f.readDeadline.set(deadline)
}
func (f *win32File) SetWriteDeadline(deadline time.Time) error {
return f.writeDeadline.set(deadline)
}
func (f *win32File) Flush() error {
return syscall.FlushFileBuffers(f.handle)
}
func (d *deadlineHandler) set(deadline time.Time) error {
d.setLock.Lock()
defer d.setLock.Unlock()
if d.timer != nil {
if !d.timer.Stop() {
<-d.channel
}
d.timer = nil
}
d.timedout.setFalse()
select {
case <-d.channel:
d.channelLock.Lock()
d.channel = make(chan struct{})
d.channelLock.Unlock()
default:
}
if deadline.IsZero() {
return nil return nil
} }
func (f *win32File) SetWriteDeadline(t time.Time) error { timeoutIO := func() {
f.writeDeadline = t d.timedout.setTrue()
close(d.channel)
}
now := time.Now()
duration := deadline.Sub(now)
if deadline.After(now) {
// Deadline is in the future, set a timer to wait
d.timer = time.AfterFunc(duration, timeoutIO)
} else {
// Deadline is in the past. Cancel all pending IO now.
timeoutIO()
}
return nil return nil
} }

View File

@ -4,6 +4,7 @@ package winio
import ( import (
"os" "os"
"runtime"
"syscall" "syscall"
"unsafe" "unsafe"
) )
@ -28,6 +29,7 @@ func GetFileBasicInfo(f *os.File) (*FileBasicInfo, error) {
if err := getFileInformationByHandleEx(syscall.Handle(f.Fd()), fileBasicInfo, (*byte)(unsafe.Pointer(bi)), uint32(unsafe.Sizeof(*bi))); err != nil { if err := getFileInformationByHandleEx(syscall.Handle(f.Fd()), fileBasicInfo, (*byte)(unsafe.Pointer(bi)), uint32(unsafe.Sizeof(*bi))); err != nil {
return nil, &os.PathError{Op: "GetFileInformationByHandleEx", Path: f.Name(), Err: err} return nil, &os.PathError{Op: "GetFileInformationByHandleEx", Path: f.Name(), Err: err}
} }
runtime.KeepAlive(f)
return bi, nil return bi, nil
} }
@ -36,6 +38,7 @@ func SetFileBasicInfo(f *os.File, bi *FileBasicInfo) error {
if err := setFileInformationByHandle(syscall.Handle(f.Fd()), fileBasicInfo, (*byte)(unsafe.Pointer(bi)), uint32(unsafe.Sizeof(*bi))); err != nil { if err := setFileInformationByHandle(syscall.Handle(f.Fd()), fileBasicInfo, (*byte)(unsafe.Pointer(bi)), uint32(unsafe.Sizeof(*bi))); err != nil {
return &os.PathError{Op: "SetFileInformationByHandle", Path: f.Name(), Err: err} return &os.PathError{Op: "SetFileInformationByHandle", Path: f.Name(), Err: err}
} }
runtime.KeepAlive(f)
return nil return nil
} }
@ -52,5 +55,6 @@ func GetFileID(f *os.File) (*FileIDInfo, error) {
if err := getFileInformationByHandleEx(syscall.Handle(f.Fd()), fileIDInfo, (*byte)(unsafe.Pointer(fileID)), uint32(unsafe.Sizeof(*fileID))); err != nil { if err := getFileInformationByHandleEx(syscall.Handle(f.Fd()), fileIDInfo, (*byte)(unsafe.Pointer(fileID)), uint32(unsafe.Sizeof(*fileID))); err != nil {
return nil, &os.PathError{Op: "GetFileInformationByHandleEx", Path: f.Name(), Err: err} return nil, &os.PathError{Op: "GetFileInformationByHandleEx", Path: f.Name(), Err: err}
} }
runtime.KeepAlive(f)
return fileID, nil return fileID, nil
} }

View File

@ -18,10 +18,12 @@ import (
//sys waitNamedPipe(name string, timeout uint32) (err error) = WaitNamedPipeW //sys waitNamedPipe(name string, timeout uint32) (err error) = WaitNamedPipeW
//sys getNamedPipeInfo(pipe syscall.Handle, flags *uint32, outSize *uint32, inSize *uint32, maxInstances *uint32) (err error) = GetNamedPipeInfo //sys getNamedPipeInfo(pipe syscall.Handle, flags *uint32, outSize *uint32, inSize *uint32, maxInstances *uint32) (err error) = GetNamedPipeInfo
//sys getNamedPipeHandleState(pipe syscall.Handle, state *uint32, curInstances *uint32, maxCollectionCount *uint32, collectDataTimeout *uint32, userName *uint16, maxUserNameSize uint32) (err error) = GetNamedPipeHandleStateW //sys getNamedPipeHandleState(pipe syscall.Handle, state *uint32, curInstances *uint32, maxCollectionCount *uint32, collectDataTimeout *uint32, userName *uint16, maxUserNameSize uint32) (err error) = GetNamedPipeHandleStateW
//sys localAlloc(uFlags uint32, length uint32) (ptr uintptr) = LocalAlloc
//sys copyMemory(dst uintptr, src uintptr, length uint32) = RtlCopyMemory
type securityAttributes struct { type securityAttributes struct {
Length uint32 Length uint32
SecurityDescriptor *byte SecurityDescriptor uintptr
InheritHandle uint32 InheritHandle uint32
} }
@ -87,7 +89,11 @@ func (f *win32MessageBytePipe) CloseWrite() error {
if f.writeClosed { if f.writeClosed {
return errPipeWriteClosed return errPipeWriteClosed
} }
_, err := f.win32File.Write(nil) err := f.win32File.Flush()
if err != nil {
return err
}
_, err = f.win32File.Write(nil)
if err != nil { if err != nil {
return err return err
} }
@ -227,12 +233,15 @@ func makeServerPipeHandle(path string, securityDescriptor []byte, c *PipeConfig,
mode |= cPIPE_TYPE_MESSAGE mode |= cPIPE_TYPE_MESSAGE
} }
var sa securityAttributes sa := &securityAttributes{}
sa.Length = uint32(unsafe.Sizeof(sa)) sa.Length = uint32(unsafe.Sizeof(*sa))
if securityDescriptor != nil { if securityDescriptor != nil {
sa.SecurityDescriptor = &securityDescriptor[0] len := uint32(len(securityDescriptor))
sa.SecurityDescriptor = localAlloc(0, len)
defer localFree(sa.SecurityDescriptor)
copyMemory(sa.SecurityDescriptor, uintptr(unsafe.Pointer(&securityDescriptor[0])), len)
} }
h, err := createNamedPipe(path, flags, mode, cPIPE_UNLIMITED_INSTANCES, uint32(c.OutputBufferSize), uint32(c.InputBufferSize), 0, &sa) h, err := createNamedPipe(path, flags, mode, cPIPE_UNLIMITED_INSTANCES, uint32(c.OutputBufferSize), uint32(c.InputBufferSize), 0, sa)
if err != nil { if err != nil {
return 0, &os.PathError{Op: "open", Path: path, Err: err} return 0, &os.PathError{Op: "open", Path: path, Err: err}
} }
@ -358,8 +367,10 @@ func connectPipe(p *win32File) error {
if err != nil { if err != nil {
return err return err
} }
defer p.wg.Done()
err = connectNamedPipe(p.handle, &c.o) err = connectNamedPipe(p.handle, &c.o)
_, err = p.asyncIo(c, time.Time{}, 0, err) _, err = p.asyncIo(c, nil, 0, err)
if err != nil && err != cERROR_PIPE_CONNECTED { if err != nil && err != cERROR_PIPE_CONNECTED {
return err return err
} }

View File

@ -11,6 +11,31 @@ import (
var _ unsafe.Pointer var _ unsafe.Pointer
// Do the interface allocations only once for common
// Errno values.
const (
errnoERROR_IO_PENDING = 997
)
var (
errERROR_IO_PENDING error = syscall.Errno(errnoERROR_IO_PENDING)
)
// errnoErr returns common boxed Errno values, to prevent
// allocations at runtime.
func errnoErr(e syscall.Errno) error {
switch e {
case 0:
return nil
case errnoERROR_IO_PENDING:
return errERROR_IO_PENDING
}
// TODO: add more here, after collecting data on the common
// error values see on Windows. (perhaps when running
// all.bat?)
return e
}
var ( var (
modkernel32 = windows.NewLazySystemDLL("kernel32.dll") modkernel32 = windows.NewLazySystemDLL("kernel32.dll")
modwinmm = windows.NewLazySystemDLL("winmm.dll") modwinmm = windows.NewLazySystemDLL("winmm.dll")
@ -27,6 +52,8 @@ var (
procWaitNamedPipeW = modkernel32.NewProc("WaitNamedPipeW") procWaitNamedPipeW = modkernel32.NewProc("WaitNamedPipeW")
procGetNamedPipeInfo = modkernel32.NewProc("GetNamedPipeInfo") procGetNamedPipeInfo = modkernel32.NewProc("GetNamedPipeInfo")
procGetNamedPipeHandleStateW = modkernel32.NewProc("GetNamedPipeHandleStateW") procGetNamedPipeHandleStateW = modkernel32.NewProc("GetNamedPipeHandleStateW")
procLocalAlloc = modkernel32.NewProc("LocalAlloc")
procRtlCopyMemory = modkernel32.NewProc("RtlCopyMemory")
procLookupAccountNameW = modadvapi32.NewProc("LookupAccountNameW") procLookupAccountNameW = modadvapi32.NewProc("LookupAccountNameW")
procConvertSidToStringSidW = modadvapi32.NewProc("ConvertSidToStringSidW") procConvertSidToStringSidW = modadvapi32.NewProc("ConvertSidToStringSidW")
procConvertStringSecurityDescriptorToSecurityDescriptorW = modadvapi32.NewProc("ConvertStringSecurityDescriptorToSecurityDescriptorW") procConvertStringSecurityDescriptorToSecurityDescriptorW = modadvapi32.NewProc("ConvertStringSecurityDescriptorToSecurityDescriptorW")
@ -51,7 +78,7 @@ func cancelIoEx(file syscall.Handle, o *syscall.Overlapped) (err error) {
r1, _, e1 := syscall.Syscall(procCancelIoEx.Addr(), 2, uintptr(file), uintptr(unsafe.Pointer(o)), 0) r1, _, e1 := syscall.Syscall(procCancelIoEx.Addr(), 2, uintptr(file), uintptr(unsafe.Pointer(o)), 0)
if r1 == 0 { if r1 == 0 {
if e1 != 0 { if e1 != 0 {
err = error(e1) err = errnoErr(e1)
} else { } else {
err = syscall.EINVAL err = syscall.EINVAL
} }
@ -64,7 +91,7 @@ func createIoCompletionPort(file syscall.Handle, port syscall.Handle, key uintpt
newport = syscall.Handle(r0) newport = syscall.Handle(r0)
if newport == 0 { if newport == 0 {
if e1 != 0 { if e1 != 0 {
err = error(e1) err = errnoErr(e1)
} else { } else {
err = syscall.EINVAL err = syscall.EINVAL
} }
@ -76,7 +103,7 @@ func getQueuedCompletionStatus(port syscall.Handle, bytes *uint32, key *uintptr,
r1, _, e1 := syscall.Syscall6(procGetQueuedCompletionStatus.Addr(), 5, uintptr(port), uintptr(unsafe.Pointer(bytes)), uintptr(unsafe.Pointer(key)), uintptr(unsafe.Pointer(o)), uintptr(timeout), 0) r1, _, e1 := syscall.Syscall6(procGetQueuedCompletionStatus.Addr(), 5, uintptr(port), uintptr(unsafe.Pointer(bytes)), uintptr(unsafe.Pointer(key)), uintptr(unsafe.Pointer(o)), uintptr(timeout), 0)
if r1 == 0 { if r1 == 0 {
if e1 != 0 { if e1 != 0 {
err = error(e1) err = errnoErr(e1)
} else { } else {
err = syscall.EINVAL err = syscall.EINVAL
} }
@ -88,7 +115,7 @@ func setFileCompletionNotificationModes(h syscall.Handle, flags uint8) (err erro
r1, _, e1 := syscall.Syscall(procSetFileCompletionNotificationModes.Addr(), 2, uintptr(h), uintptr(flags), 0) r1, _, e1 := syscall.Syscall(procSetFileCompletionNotificationModes.Addr(), 2, uintptr(h), uintptr(flags), 0)
if r1 == 0 { if r1 == 0 {
if e1 != 0 { if e1 != 0 {
err = error(e1) err = errnoErr(e1)
} else { } else {
err = syscall.EINVAL err = syscall.EINVAL
} }
@ -106,7 +133,7 @@ func connectNamedPipe(pipe syscall.Handle, o *syscall.Overlapped) (err error) {
r1, _, e1 := syscall.Syscall(procConnectNamedPipe.Addr(), 2, uintptr(pipe), uintptr(unsafe.Pointer(o)), 0) r1, _, e1 := syscall.Syscall(procConnectNamedPipe.Addr(), 2, uintptr(pipe), uintptr(unsafe.Pointer(o)), 0)
if r1 == 0 { if r1 == 0 {
if e1 != 0 { if e1 != 0 {
err = error(e1) err = errnoErr(e1)
} else { } else {
err = syscall.EINVAL err = syscall.EINVAL
} }
@ -128,7 +155,7 @@ func _createNamedPipe(name *uint16, flags uint32, pipeMode uint32, maxInstances
handle = syscall.Handle(r0) handle = syscall.Handle(r0)
if handle == syscall.InvalidHandle { if handle == syscall.InvalidHandle {
if e1 != 0 { if e1 != 0 {
err = error(e1) err = errnoErr(e1)
} else { } else {
err = syscall.EINVAL err = syscall.EINVAL
} }
@ -150,7 +177,7 @@ func _createFile(name *uint16, access uint32, mode uint32, sa *securityAttribute
handle = syscall.Handle(r0) handle = syscall.Handle(r0)
if handle == syscall.InvalidHandle { if handle == syscall.InvalidHandle {
if e1 != 0 { if e1 != 0 {
err = error(e1) err = errnoErr(e1)
} else { } else {
err = syscall.EINVAL err = syscall.EINVAL
} }
@ -171,7 +198,7 @@ func _waitNamedPipe(name *uint16, timeout uint32) (err error) {
r1, _, e1 := syscall.Syscall(procWaitNamedPipeW.Addr(), 2, uintptr(unsafe.Pointer(name)), uintptr(timeout), 0) r1, _, e1 := syscall.Syscall(procWaitNamedPipeW.Addr(), 2, uintptr(unsafe.Pointer(name)), uintptr(timeout), 0)
if r1 == 0 { if r1 == 0 {
if e1 != 0 { if e1 != 0 {
err = error(e1) err = errnoErr(e1)
} else { } else {
err = syscall.EINVAL err = syscall.EINVAL
} }
@ -183,7 +210,7 @@ func getNamedPipeInfo(pipe syscall.Handle, flags *uint32, outSize *uint32, inSiz
r1, _, e1 := syscall.Syscall6(procGetNamedPipeInfo.Addr(), 5, uintptr(pipe), uintptr(unsafe.Pointer(flags)), uintptr(unsafe.Pointer(outSize)), uintptr(unsafe.Pointer(inSize)), uintptr(unsafe.Pointer(maxInstances)), 0) r1, _, e1 := syscall.Syscall6(procGetNamedPipeInfo.Addr(), 5, uintptr(pipe), uintptr(unsafe.Pointer(flags)), uintptr(unsafe.Pointer(outSize)), uintptr(unsafe.Pointer(inSize)), uintptr(unsafe.Pointer(maxInstances)), 0)
if r1 == 0 { if r1 == 0 {
if e1 != 0 { if e1 != 0 {
err = error(e1) err = errnoErr(e1)
} else { } else {
err = syscall.EINVAL err = syscall.EINVAL
} }
@ -195,7 +222,7 @@ func getNamedPipeHandleState(pipe syscall.Handle, state *uint32, curInstances *u
r1, _, e1 := syscall.Syscall9(procGetNamedPipeHandleStateW.Addr(), 7, uintptr(pipe), uintptr(unsafe.Pointer(state)), uintptr(unsafe.Pointer(curInstances)), uintptr(unsafe.Pointer(maxCollectionCount)), uintptr(unsafe.Pointer(collectDataTimeout)), uintptr(unsafe.Pointer(userName)), uintptr(maxUserNameSize), 0, 0) r1, _, e1 := syscall.Syscall9(procGetNamedPipeHandleStateW.Addr(), 7, uintptr(pipe), uintptr(unsafe.Pointer(state)), uintptr(unsafe.Pointer(curInstances)), uintptr(unsafe.Pointer(maxCollectionCount)), uintptr(unsafe.Pointer(collectDataTimeout)), uintptr(unsafe.Pointer(userName)), uintptr(maxUserNameSize), 0, 0)
if r1 == 0 { if r1 == 0 {
if e1 != 0 { if e1 != 0 {
err = error(e1) err = errnoErr(e1)
} else { } else {
err = syscall.EINVAL err = syscall.EINVAL
} }
@ -203,6 +230,17 @@ func getNamedPipeHandleState(pipe syscall.Handle, state *uint32, curInstances *u
return return
} }
func localAlloc(uFlags uint32, length uint32) (ptr uintptr) {
r0, _, _ := syscall.Syscall(procLocalAlloc.Addr(), 2, uintptr(uFlags), uintptr(length), 0)
ptr = uintptr(r0)
return
}
func copyMemory(dst uintptr, src uintptr, length uint32) {
syscall.Syscall(procRtlCopyMemory.Addr(), 3, uintptr(dst), uintptr(src), uintptr(length))
return
}
func lookupAccountName(systemName *uint16, accountName string, sid *byte, sidSize *uint32, refDomain *uint16, refDomainSize *uint32, sidNameUse *uint32) (err error) { func lookupAccountName(systemName *uint16, accountName string, sid *byte, sidSize *uint32, refDomain *uint16, refDomainSize *uint32, sidNameUse *uint32) (err error) {
var _p0 *uint16 var _p0 *uint16
_p0, err = syscall.UTF16PtrFromString(accountName) _p0, err = syscall.UTF16PtrFromString(accountName)
@ -216,7 +254,7 @@ func _lookupAccountName(systemName *uint16, accountName *uint16, sid *byte, sidS
r1, _, e1 := syscall.Syscall9(procLookupAccountNameW.Addr(), 7, uintptr(unsafe.Pointer(systemName)), uintptr(unsafe.Pointer(accountName)), uintptr(unsafe.Pointer(sid)), uintptr(unsafe.Pointer(sidSize)), uintptr(unsafe.Pointer(refDomain)), uintptr(unsafe.Pointer(refDomainSize)), uintptr(unsafe.Pointer(sidNameUse)), 0, 0) r1, _, e1 := syscall.Syscall9(procLookupAccountNameW.Addr(), 7, uintptr(unsafe.Pointer(systemName)), uintptr(unsafe.Pointer(accountName)), uintptr(unsafe.Pointer(sid)), uintptr(unsafe.Pointer(sidSize)), uintptr(unsafe.Pointer(refDomain)), uintptr(unsafe.Pointer(refDomainSize)), uintptr(unsafe.Pointer(sidNameUse)), 0, 0)
if r1 == 0 { if r1 == 0 {
if e1 != 0 { if e1 != 0 {
err = error(e1) err = errnoErr(e1)
} else { } else {
err = syscall.EINVAL err = syscall.EINVAL
} }
@ -228,7 +266,7 @@ func convertSidToStringSid(sid *byte, str **uint16) (err error) {
r1, _, e1 := syscall.Syscall(procConvertSidToStringSidW.Addr(), 2, uintptr(unsafe.Pointer(sid)), uintptr(unsafe.Pointer(str)), 0) r1, _, e1 := syscall.Syscall(procConvertSidToStringSidW.Addr(), 2, uintptr(unsafe.Pointer(sid)), uintptr(unsafe.Pointer(str)), 0)
if r1 == 0 { if r1 == 0 {
if e1 != 0 { if e1 != 0 {
err = error(e1) err = errnoErr(e1)
} else { } else {
err = syscall.EINVAL err = syscall.EINVAL
} }
@ -249,7 +287,7 @@ func _convertStringSecurityDescriptorToSecurityDescriptor(str *uint16, revision
r1, _, e1 := syscall.Syscall6(procConvertStringSecurityDescriptorToSecurityDescriptorW.Addr(), 4, uintptr(unsafe.Pointer(str)), uintptr(revision), uintptr(unsafe.Pointer(sd)), uintptr(unsafe.Pointer(size)), 0, 0) r1, _, e1 := syscall.Syscall6(procConvertStringSecurityDescriptorToSecurityDescriptorW.Addr(), 4, uintptr(unsafe.Pointer(str)), uintptr(revision), uintptr(unsafe.Pointer(sd)), uintptr(unsafe.Pointer(size)), 0, 0)
if r1 == 0 { if r1 == 0 {
if e1 != 0 { if e1 != 0 {
err = error(e1) err = errnoErr(e1)
} else { } else {
err = syscall.EINVAL err = syscall.EINVAL
} }
@ -261,7 +299,7 @@ func convertSecurityDescriptorToStringSecurityDescriptor(sd *byte, revision uint
r1, _, e1 := syscall.Syscall6(procConvertSecurityDescriptorToStringSecurityDescriptorW.Addr(), 5, uintptr(unsafe.Pointer(sd)), uintptr(revision), uintptr(secInfo), uintptr(unsafe.Pointer(sddl)), uintptr(unsafe.Pointer(sddlSize)), 0) r1, _, e1 := syscall.Syscall6(procConvertSecurityDescriptorToStringSecurityDescriptorW.Addr(), 5, uintptr(unsafe.Pointer(sd)), uintptr(revision), uintptr(secInfo), uintptr(unsafe.Pointer(sddl)), uintptr(unsafe.Pointer(sddlSize)), 0)
if r1 == 0 { if r1 == 0 {
if e1 != 0 { if e1 != 0 {
err = error(e1) err = errnoErr(e1)
} else { } else {
err = syscall.EINVAL err = syscall.EINVAL
} }
@ -284,7 +322,7 @@ func getFileInformationByHandleEx(h syscall.Handle, class uint32, buffer *byte,
r1, _, e1 := syscall.Syscall6(procGetFileInformationByHandleEx.Addr(), 4, uintptr(h), uintptr(class), uintptr(unsafe.Pointer(buffer)), uintptr(size), 0, 0) r1, _, e1 := syscall.Syscall6(procGetFileInformationByHandleEx.Addr(), 4, uintptr(h), uintptr(class), uintptr(unsafe.Pointer(buffer)), uintptr(size), 0, 0)
if r1 == 0 { if r1 == 0 {
if e1 != 0 { if e1 != 0 {
err = error(e1) err = errnoErr(e1)
} else { } else {
err = syscall.EINVAL err = syscall.EINVAL
} }
@ -296,7 +334,7 @@ func setFileInformationByHandle(h syscall.Handle, class uint32, buffer *byte, si
r1, _, e1 := syscall.Syscall6(procSetFileInformationByHandle.Addr(), 4, uintptr(h), uintptr(class), uintptr(unsafe.Pointer(buffer)), uintptr(size), 0, 0) r1, _, e1 := syscall.Syscall6(procSetFileInformationByHandle.Addr(), 4, uintptr(h), uintptr(class), uintptr(unsafe.Pointer(buffer)), uintptr(size), 0, 0)
if r1 == 0 { if r1 == 0 {
if e1 != 0 { if e1 != 0 {
err = error(e1) err = errnoErr(e1)
} else { } else {
err = syscall.EINVAL err = syscall.EINVAL
} }
@ -315,7 +353,7 @@ func adjustTokenPrivileges(token windows.Token, releaseAll bool, input *byte, ou
success = r0 != 0 success = r0 != 0
if true { if true {
if e1 != 0 { if e1 != 0 {
err = error(e1) err = errnoErr(e1)
} else { } else {
err = syscall.EINVAL err = syscall.EINVAL
} }
@ -327,7 +365,7 @@ func impersonateSelf(level uint32) (err error) {
r1, _, e1 := syscall.Syscall(procImpersonateSelf.Addr(), 1, uintptr(level), 0, 0) r1, _, e1 := syscall.Syscall(procImpersonateSelf.Addr(), 1, uintptr(level), 0, 0)
if r1 == 0 { if r1 == 0 {
if e1 != 0 { if e1 != 0 {
err = error(e1) err = errnoErr(e1)
} else { } else {
err = syscall.EINVAL err = syscall.EINVAL
} }
@ -339,7 +377,7 @@ func revertToSelf() (err error) {
r1, _, e1 := syscall.Syscall(procRevertToSelf.Addr(), 0, 0, 0, 0) r1, _, e1 := syscall.Syscall(procRevertToSelf.Addr(), 0, 0, 0, 0)
if r1 == 0 { if r1 == 0 {
if e1 != 0 { if e1 != 0 {
err = error(e1) err = errnoErr(e1)
} else { } else {
err = syscall.EINVAL err = syscall.EINVAL
} }
@ -357,7 +395,7 @@ func openThreadToken(thread syscall.Handle, accessMask uint32, openAsSelf bool,
r1, _, e1 := syscall.Syscall6(procOpenThreadToken.Addr(), 4, uintptr(thread), uintptr(accessMask), uintptr(_p0), uintptr(unsafe.Pointer(token)), 0, 0) r1, _, e1 := syscall.Syscall6(procOpenThreadToken.Addr(), 4, uintptr(thread), uintptr(accessMask), uintptr(_p0), uintptr(unsafe.Pointer(token)), 0, 0)
if r1 == 0 { if r1 == 0 {
if e1 != 0 { if e1 != 0 {
err = error(e1) err = errnoErr(e1)
} else { } else {
err = syscall.EINVAL err = syscall.EINVAL
} }
@ -389,7 +427,7 @@ func _lookupPrivilegeValue(systemName *uint16, name *uint16, luid *uint64) (err
r1, _, e1 := syscall.Syscall(procLookupPrivilegeValueW.Addr(), 3, uintptr(unsafe.Pointer(systemName)), uintptr(unsafe.Pointer(name)), uintptr(unsafe.Pointer(luid))) r1, _, e1 := syscall.Syscall(procLookupPrivilegeValueW.Addr(), 3, uintptr(unsafe.Pointer(systemName)), uintptr(unsafe.Pointer(name)), uintptr(unsafe.Pointer(luid)))
if r1 == 0 { if r1 == 0 {
if e1 != 0 { if e1 != 0 {
err = error(e1) err = errnoErr(e1)
} else { } else {
err = syscall.EINVAL err = syscall.EINVAL
} }
@ -410,7 +448,7 @@ func _lookupPrivilegeName(systemName *uint16, luid *uint64, buffer *uint16, size
r1, _, e1 := syscall.Syscall6(procLookupPrivilegeNameW.Addr(), 4, uintptr(unsafe.Pointer(systemName)), uintptr(unsafe.Pointer(luid)), uintptr(unsafe.Pointer(buffer)), uintptr(unsafe.Pointer(size)), 0, 0) r1, _, e1 := syscall.Syscall6(procLookupPrivilegeNameW.Addr(), 4, uintptr(unsafe.Pointer(systemName)), uintptr(unsafe.Pointer(luid)), uintptr(unsafe.Pointer(buffer)), uintptr(unsafe.Pointer(size)), 0, 0)
if r1 == 0 { if r1 == 0 {
if e1 != 0 { if e1 != 0 {
err = error(e1) err = errnoErr(e1)
} else { } else {
err = syscall.EINVAL err = syscall.EINVAL
} }
@ -431,7 +469,7 @@ func _lookupPrivilegeDisplayName(systemName *uint16, name *uint16, buffer *uint1
r1, _, e1 := syscall.Syscall6(procLookupPrivilegeDisplayNameW.Addr(), 5, uintptr(unsafe.Pointer(systemName)), uintptr(unsafe.Pointer(name)), uintptr(unsafe.Pointer(buffer)), uintptr(unsafe.Pointer(size)), uintptr(unsafe.Pointer(languageId)), 0) r1, _, e1 := syscall.Syscall6(procLookupPrivilegeDisplayNameW.Addr(), 5, uintptr(unsafe.Pointer(systemName)), uintptr(unsafe.Pointer(name)), uintptr(unsafe.Pointer(buffer)), uintptr(unsafe.Pointer(size)), uintptr(unsafe.Pointer(languageId)), 0)
if r1 == 0 { if r1 == 0 {
if e1 != 0 { if e1 != 0 {
err = error(e1) err = errnoErr(e1)
} else { } else {
err = syscall.EINVAL err = syscall.EINVAL
} }
@ -459,7 +497,7 @@ func backupRead(h syscall.Handle, b []byte, bytesRead *uint32, abort bool, proce
r1, _, e1 := syscall.Syscall9(procBackupRead.Addr(), 7, uintptr(h), uintptr(unsafe.Pointer(_p0)), uintptr(len(b)), uintptr(unsafe.Pointer(bytesRead)), uintptr(_p1), uintptr(_p2), uintptr(unsafe.Pointer(context)), 0, 0) r1, _, e1 := syscall.Syscall9(procBackupRead.Addr(), 7, uintptr(h), uintptr(unsafe.Pointer(_p0)), uintptr(len(b)), uintptr(unsafe.Pointer(bytesRead)), uintptr(_p1), uintptr(_p2), uintptr(unsafe.Pointer(context)), 0, 0)
if r1 == 0 { if r1 == 0 {
if e1 != 0 { if e1 != 0 {
err = error(e1) err = errnoErr(e1)
} else { } else {
err = syscall.EINVAL err = syscall.EINVAL
} }
@ -487,7 +525,7 @@ func backupWrite(h syscall.Handle, b []byte, bytesWritten *uint32, abort bool, p
r1, _, e1 := syscall.Syscall9(procBackupWrite.Addr(), 7, uintptr(h), uintptr(unsafe.Pointer(_p0)), uintptr(len(b)), uintptr(unsafe.Pointer(bytesWritten)), uintptr(_p1), uintptr(_p2), uintptr(unsafe.Pointer(context)), 0, 0) r1, _, e1 := syscall.Syscall9(procBackupWrite.Addr(), 7, uintptr(h), uintptr(unsafe.Pointer(_p0)), uintptr(len(b)), uintptr(unsafe.Pointer(bytesWritten)), uintptr(_p1), uintptr(_p2), uintptr(unsafe.Pointer(context)), 0, 0)
if r1 == 0 { if r1 == 0 {
if e1 != 0 { if e1 != 0 {
err = error(e1) err = errnoErr(e1)
} else { } else {
err = syscall.EINVAL err = syscall.EINVAL
} }