diff --git a/commands/requests.go b/commands/requests.go new file mode 100644 index 00000000..c4af2795 --- /dev/null +++ b/commands/requests.go @@ -0,0 +1,82 @@ +package commands + +import ( + "bufio" + "fmt" + "io" + "strings" + + "github.com/docker/model-cli/commands/completion" + "github.com/spf13/cobra" +) + +func newRequestsCmd() *cobra.Command { + var model string + var follow bool + var includeExisting bool + c := &cobra.Command{ + Use: "requests [OPTIONS]", + Short: "Fetch requests+responses from Docker Model Runner", + PreRunE: func(cmd *cobra.Command, args []string) error { + // Make --include-existing only available when --follow is set. + if includeExisting && !follow { + return fmt.Errorf("--include-existing can only be used with --follow") + } + return nil + }, + RunE: func(cmd *cobra.Command, args []string) error { + if _, err := ensureStandaloneRunnerAvailable(cmd.Context(), cmd); err != nil { + return fmt.Errorf("unable to initialize standalone model runner: %w", err) + } + + responseBody, cancel, err := desktopClient.Requests(model, follow, includeExisting) + if err != nil { + errMsg := "Failed to get requests" + if model != "" { + errMsg = errMsg + " for " + model + } + err = handleClientError(err, errMsg) + return handleNotRunningError(err) + } + defer cancel() + + if follow { + scanner := bufio.NewScanner(responseBody) + cmd.Println("Connected to request stream. Press Ctrl+C to stop.") + var currentEvent string + for scanner.Scan() { + select { + case <-cmd.Context().Done(): + return nil + default: + } + line := scanner.Text() + if strings.HasPrefix(line, "event: ") { + currentEvent = strings.TrimPrefix(line, "event: ") + } else if strings.HasPrefix(line, "data: ") && + (currentEvent == "new_request" || currentEvent == "existing_request") { + data := strings.TrimPrefix(line, "data: ") + cmd.Println(data) + } + } + cmd.Println("Stream closed by server.") + } else { + body, err := io.ReadAll(responseBody) + if err != nil { + return fmt.Errorf("failed to read response body: %w", err) + } + cmd.Print(string(body)) + } + + return nil + }, + ValidArgsFunction: completion.NoComplete, + } + c.Flags().BoolVarP(&follow, "follow", "f", false, "Follow requests stream") + c.Flags().BoolVar(&includeExisting, "include-existing", false, + "Include existing requests when starting to follow (only available with --follow)") + c.Flags().StringVar(&model, "model", "", "Specify the model to filter requests") + // Enable completion for the --model flag. + _ = c.RegisterFlagCompletionFunc("model", completion.ModelNames(getDesktopClient, 1)) + return c +} diff --git a/commands/root.go b/commands/root.go index dd5b285f..5b0646d2 100644 --- a/commands/root.go +++ b/commands/root.go @@ -110,6 +110,7 @@ func NewRootCmd(cli *command.DockerCli) *cobra.Command { newPSCmd(), newDFCmd(), newUnloadCmd(), + newRequestsCmd(), ) return rootCmd } diff --git a/desktop/desktop.go b/desktop/desktop.go index 3fff3bfd..8dc722c0 100644 --- a/desktop/desktop.go +++ b/desktop/desktop.go @@ -9,6 +9,7 @@ import ( "html" "io" "net/http" + "net/url" "strconv" "strings" "time" @@ -657,6 +658,63 @@ func (c *Client) ConfigureBackend(request scheduling.ConfigureRequest) error { return nil } +// Requests returns a response body and a cancel function to ensure proper cleanup. +func (c *Client) Requests(modelFilter string, streaming bool, includeExisting bool) (io.ReadCloser, func(), error) { + path := c.modelRunner.URL(inference.InferencePrefix + "/requests") + var queryParams []string + if modelFilter != "" { + queryParams = append(queryParams, "model="+url.QueryEscape(modelFilter)) + } + if includeExisting && streaming { + queryParams = append(queryParams, "include_existing=true") + } + if len(queryParams) > 0 { + path += "?" + strings.Join(queryParams, "&") + } + + req, err := http.NewRequest(http.MethodGet, path, nil) + if err != nil { + return nil, nil, fmt.Errorf("failed to create request: %w", err) + } + + if streaming { + req.Header.Set("Accept", "text/event-stream") + req.Header.Set("Cache-Control", "no-cache") + } else { + req.Header.Set("Accept", "application/json") + } + req.Header.Set("User-Agent", "docker-model-cli/"+Version) + + resp, err := c.modelRunner.Client().Do(req) + if err != nil { + if streaming { + return nil, nil, c.handleQueryError(fmt.Errorf("failed to connect to stream: %w", err), path) + } + return nil, nil, c.handleQueryError(err, path) + } + + if resp.StatusCode != http.StatusOK { + if resp.StatusCode == http.StatusNotFound { + body, _ := io.ReadAll(resp.Body) + resp.Body.Close() + return nil, nil, fmt.Errorf("%s", strings.TrimSpace(string(body))) + } + + resp.Body.Close() + if streaming { + return nil, nil, fmt.Errorf("stream request failed with status: %d", resp.StatusCode) + } + return nil, nil, fmt.Errorf("failed to list requests: %s", resp.Status) + } + + // Return the response body and a cancel function that closes it. + cancel := func() { + resp.Body.Close() + } + + return resp.Body, cancel, nil +} + // doRequest is a helper function that performs HTTP requests and handles 503 responses func (c *Client) doRequest(method, path string, body io.Reader) (*http.Response, error) { return c.doRequestWithAuth(method, path, body, "", "") diff --git a/docs/reference/docker_model.yaml b/docs/reference/docker_model.yaml index d64e07cd..19c4c711 100644 --- a/docs/reference/docker_model.yaml +++ b/docs/reference/docker_model.yaml @@ -15,6 +15,7 @@ cname: - docker model ps - docker model pull - docker model push + - docker model requests - docker model rm - docker model run - docker model status @@ -32,6 +33,7 @@ clink: - docker_model_ps.yaml - docker_model_pull.yaml - docker_model_push.yaml + - docker_model_requests.yaml - docker_model_rm.yaml - docker_model_run.yaml - docker_model_status.yaml diff --git a/docs/reference/docker_model_requests.yaml b/docs/reference/docker_model_requests.yaml new file mode 100644 index 00000000..eecab3ba --- /dev/null +++ b/docs/reference/docker_model_requests.yaml @@ -0,0 +1,45 @@ +command: docker model requests +short: Fetch requests+responses from Docker Model Runner +long: Fetch requests+responses from Docker Model Runner +usage: docker model requests [OPTIONS] +pname: docker model +plink: docker_model.yaml +options: + - option: follow + shorthand: f + value_type: bool + default_value: "false" + description: Follow requests stream + deprecated: false + hidden: false + experimental: false + experimentalcli: false + kubernetes: false + swarm: false + - option: include-existing + value_type: bool + default_value: "false" + description: | + Include existing requests when starting to follow (only available with --follow) + deprecated: false + hidden: false + experimental: false + experimentalcli: false + kubernetes: false + swarm: false + - option: model + value_type: string + description: Specify the model to filter requests + deprecated: false + hidden: false + experimental: false + experimentalcli: false + kubernetes: false + swarm: false +deprecated: false +hidden: false +experimental: false +experimentalcli: false +kubernetes: false +swarm: false + diff --git a/docs/reference/model.md b/docs/reference/model.md index 75ada31f..ecfefdd3 100644 --- a/docs/reference/model.md +++ b/docs/reference/model.md @@ -16,6 +16,7 @@ Docker Model Runner | [`ps`](model_ps.md) | List running models | | [`pull`](model_pull.md) | Pull a model from Docker Hub or HuggingFace to your local environment | | [`push`](model_push.md) | Push a model to Docker Hub | +| [`requests`](model_requests.md) | Fetch requests+responses from Docker Model Runner | | [`rm`](model_rm.md) | Remove local models downloaded from Docker Hub | | [`run`](model_run.md) | Run a model and interact with it using a submitted prompt or chat mode | | [`status`](model_status.md) | Check if the Docker Model Runner is running | diff --git a/docs/reference/model_requests.md b/docs/reference/model_requests.md new file mode 100644 index 00000000..970dc3c3 --- /dev/null +++ b/docs/reference/model_requests.md @@ -0,0 +1,16 @@ +# docker model requests + + +Fetch requests+responses from Docker Model Runner + +### Options + +| Name | Type | Default | Description | +|:---------------------|:---------|:--------|:---------------------------------------------------------------------------------| +| `-f`, `--follow` | `bool` | | Follow requests stream | +| `--include-existing` | `bool` | | Include existing requests when starting to follow (only available with --follow) | +| `--model` | `string` | | Specify the model to filter requests | + + + + diff --git a/go.mod b/go.mod index 5259d6bf..6ac2df9c 100644 --- a/go.mod +++ b/go.mod @@ -11,8 +11,8 @@ require ( github.com/docker/docker v28.2.2+incompatible github.com/docker/go-connections v0.5.0 github.com/docker/go-units v0.5.0 - github.com/docker/model-distribution v0.0.0-20250822172258-8fe9daa4a4da - github.com/docker/model-runner v0.0.0-20250822173738-5341c9fc2974 + github.com/docker/model-distribution v0.0.0-20250905083217-3f098b3d8058 + github.com/docker/model-runner v0.0.0-20250911130340-38bb0171c947 github.com/fatih/color v1.15.0 github.com/google/go-containerregistry v0.20.6 github.com/mattn/go-isatty v0.0.20 @@ -63,6 +63,7 @@ require ( github.com/jaypipes/pcidb v1.0.1 // indirect github.com/json-iterator/go v1.1.12 // indirect github.com/klauspost/compress v1.18.0 // indirect + github.com/kolesnikovae/go-winjob v1.0.0 // indirect github.com/mattn/go-colorable v0.1.13 // indirect github.com/mattn/go-runewidth v0.0.16 // indirect github.com/mattn/go-shellwords v1.0.12 // indirect @@ -103,7 +104,7 @@ require ( golang.org/x/exp v0.0.0-20250106191152-7588d65b2ba8 // indirect golang.org/x/mod v0.25.0 // indirect golang.org/x/net v0.41.0 // indirect - golang.org/x/sys v0.33.0 // indirect + golang.org/x/sys v0.35.0 // indirect golang.org/x/text v0.26.0 // indirect golang.org/x/time v0.9.0 // indirect golang.org/x/tools v0.34.0 // indirect @@ -117,3 +118,5 @@ require ( gotest.tools/v3 v3.5.2 // indirect howett.net/plist v1.0.1 // indirect ) + +replace github.com/kolesnikovae/go-winjob => github.com/docker/go-winjob v0.0.0-20250829235554-57b487ebcbc5 diff --git a/go.sum b/go.sum index 997998e1..98238031 100644 --- a/go.sum +++ b/go.sum @@ -77,11 +77,13 @@ github.com/docker/go-metrics v0.0.1 h1:AgB/0SvBxihN0X8OR4SjsblXkbMvalQ8cjmtKQ2rQ github.com/docker/go-metrics v0.0.1/go.mod h1:cG1hvH2utMXtqgqqYE9plW6lDxS3/5ayHzueweSI3Vw= github.com/docker/go-units v0.5.0 h1:69rxXcBk27SvSaaxTtLh/8llcHD8vYHT7WSdRZ/jvr4= github.com/docker/go-units v0.5.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk= +github.com/docker/go-winjob v0.0.0-20250829235554-57b487ebcbc5 h1:dxSFEb0EEmvceIawSFNDMrvKakRz2t+2WYpY3dFAT04= +github.com/docker/go-winjob v0.0.0-20250829235554-57b487ebcbc5/go.mod h1:ICOGmIXdwhfid7rQP+tLvDJqVg0lHdEk3pI5nsapTtg= github.com/docker/libtrust v0.0.0-20160708172513-aabc10ec26b7/go.mod h1:cyGadeNEkKy96OOhEzfZl+yxihPEzKnqJwvfuSUqbZE= -github.com/docker/model-distribution v0.0.0-20250822172258-8fe9daa4a4da h1:ml99WBfcLnsy1frXQR4X+5WAC0DoGtwZyGoU/xBsDQM= -github.com/docker/model-distribution v0.0.0-20250822172258-8fe9daa4a4da/go.mod h1:dThpO9JoG5Px3i+rTluAeZcqLGw8C0qepuEL4gL2o/c= -github.com/docker/model-runner v0.0.0-20250822173738-5341c9fc2974 h1:/uF17tBEtsE6T2Xgg4cgrrqNcQ02gY5Lp98je+2K0nQ= -github.com/docker/model-runner v0.0.0-20250822173738-5341c9fc2974/go.mod h1:1Q2QRB5vob542x6P5pQXlGTYs5bYPxNG6ePcjTndA0A= +github.com/docker/model-distribution v0.0.0-20250905083217-3f098b3d8058 h1:whffgQ1pmiMFVrxRhJKA9yyCJXvmVX6iiohU9ezKCx0= +github.com/docker/model-distribution v0.0.0-20250905083217-3f098b3d8058/go.mod h1:dThpO9JoG5Px3i+rTluAeZcqLGw8C0qepuEL4gL2o/c= +github.com/docker/model-runner v0.0.0-20250911130340-38bb0171c947 h1:6Dz1SFZONEd8tlKetn2Gu6v5HDJI/YtUFwkqHGwrsV0= +github.com/docker/model-runner v0.0.0-20250911130340-38bb0171c947/go.mod h1:cl7panafjkSHllYCCGYAzty2aUvbwk55Gi35v06XL80= github.com/dvsekhvalnov/jose2go v0.0.0-20170216131308-f21a8cedbbae/go.mod h1:7BvyPhdbLxMXIYTFPLsyJRFMsKmOZnQmzh6Gb+uquuM= github.com/elastic/go-sysinfo v1.15.3 h1:W+RnmhKFkqPTCRoFq2VCTmsT4p/fwpo+3gKNQsn1XU0= github.com/elastic/go-sysinfo v1.15.3/go.mod h1:K/cNrqYTDrSoMh2oDkYEMS2+a72GRxMvNP+GC+vRIlo= @@ -345,8 +347,8 @@ golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.33.0 h1:q3i8TbbEz+JRD9ywIRlyRAQbM0qF7hu24q3teo2hbuw= -golang.org/x/sys v0.33.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k= +golang.org/x/sys v0.35.0 h1:vz1N37gP5bs89s7He8XuIYXpyY0+QlsKmzipCbUtyxI= +golang.org/x/sys v0.35.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k= golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw= golang.org/x/term v0.32.0 h1:DR4lr0TjUs3epypdhTOkMmuF5CDFJ/8pOnbzMZPQ7bg= golang.org/x/term v0.32.0/go.mod h1:uZG1FhGx848Sqfsq4/DlJr3xGGsYMu/L5GW4abiaEPQ= diff --git a/vendor/github.com/docker/model-runner/pkg/inference/backend.go b/vendor/github.com/docker/model-runner/pkg/inference/backend.go index 26bd3fdf..20ddda2a 100644 --- a/vendor/github.com/docker/model-runner/pkg/inference/backend.go +++ b/vendor/github.com/docker/model-runner/pkg/inference/backend.go @@ -91,5 +91,5 @@ type Backend interface { GetDiskUsage() (int64, error) // GetRequiredMemoryForModel returns the required working memory for a given // model. - GetRequiredMemoryForModel(ctx context.Context, model string, config *BackendConfiguration) (*RequiredMemory, error) + GetRequiredMemoryForModel(ctx context.Context, model string, config *BackendConfiguration) (RequiredMemory, error) } diff --git a/vendor/github.com/docker/model-runner/pkg/inference/backends/llamacpp/llamacpp.go b/vendor/github.com/docker/model-runner/pkg/inference/backends/llamacpp/llamacpp.go index a4913865..f28eef6c 100644 --- a/vendor/github.com/docker/model-runner/pkg/inference/backends/llamacpp/llamacpp.go +++ b/vendor/github.com/docker/model-runner/pkg/inference/backends/llamacpp/llamacpp.go @@ -2,6 +2,7 @@ package llamacpp import ( "bufio" + "bytes" "context" "errors" "fmt" @@ -24,6 +25,7 @@ import ( "github.com/docker/model-runner/pkg/inference/config" "github.com/docker/model-runner/pkg/inference/models" "github.com/docker/model-runner/pkg/logging" + "github.com/docker/model-runner/pkg/sandbox" "github.com/docker/model-runner/pkg/tailbuffer" ) @@ -153,30 +155,33 @@ func (l *llamaCpp) Run(ctx context.Context, socket, model string, mode inference } l.log.Infof("llamaCppArgs: %v", args) - llamaCppProcess := exec.CommandContext( + tailBuf := tailbuffer.NewTailBuffer(1024) + serverLogStream := l.serverLog.Writer() + out := io.MultiWriter(serverLogStream, tailBuf) + llamaCppSandbox, err := sandbox.Create( ctx, + sandbox.ConfigurationLlamaCpp, + func(command *exec.Cmd) { + command.Cancel = func() error { + if runtime.GOOS == "windows" { + return command.Process.Kill() + } + return command.Process.Signal(os.Interrupt) + } + command.Stdout = serverLogStream + command.Stderr = out + }, filepath.Join(binPath, "com.docker.llama-server"), args..., ) - llamaCppProcess.Cancel = func() error { - if runtime.GOOS == "windows" { - return llamaCppProcess.Process.Kill() - } - return llamaCppProcess.Process.Signal(os.Interrupt) - } - tailBuf := tailbuffer.NewTailBuffer(1024) - serverLogStream := l.serverLog.Writer() - out := io.MultiWriter(serverLogStream, tailBuf) - llamaCppProcess.Stdout = serverLogStream - llamaCppProcess.Stderr = out - - if err := llamaCppProcess.Start(); err != nil { + if err != nil { return fmt.Errorf("unable to start llama.cpp: %w", err) } + defer llamaCppSandbox.Close() llamaCppErrors := make(chan error, 1) go func() { - llamaCppErr := llamaCppProcess.Wait() + llamaCppErr := llamaCppSandbox.Command().Wait() serverLogStream.Close() errOutput := new(strings.Builder) @@ -225,22 +230,22 @@ func (l *llamaCpp) GetDiskUsage() (int64, error) { return size, nil } -func (l *llamaCpp) GetRequiredMemoryForModel(ctx context.Context, model string, config *inference.BackendConfiguration) (*inference.RequiredMemory, error) { +func (l *llamaCpp) GetRequiredMemoryForModel(ctx context.Context, model string, config *inference.BackendConfiguration) (inference.RequiredMemory, error) { var mdlGguf *parser.GGUFFile var mdlConfig types.Config inStore, err := l.modelManager.IsModelInStore(model) if err != nil { - return nil, fmt.Errorf("checking if model is in local store: %w", err) + return inference.RequiredMemory{}, fmt.Errorf("checking if model is in local store: %w", err) } if inStore { mdlGguf, mdlConfig, err = l.parseLocalModel(model) if err != nil { - return nil, &inference.ErrGGUFParse{Err: err} + return inference.RequiredMemory{}, &inference.ErrGGUFParse{Err: err} } } else { mdlGguf, mdlConfig, err = l.parseRemoteModel(ctx, model) if err != nil { - return nil, &inference.ErrGGUFParse{Err: err} + return inference.RequiredMemory{}, &inference.ErrGGUFParse{Err: err} } } @@ -251,7 +256,7 @@ func (l *llamaCpp) GetRequiredMemoryForModel(ctx context.Context, model string, if runtime.GOOS == "windows" && runtime.GOARCH == "arm64" && mdlConfig.Quantization != "Q4_0" { ngl = 0 // only Q4_0 models can be accelerated on Adreno } - ngl = 100 + ngl = 999 } // TODO(p1-0tr): for now assume we are running on GPU (single one) - Devices[1]; @@ -273,7 +278,7 @@ func (l *llamaCpp) GetRequiredMemoryForModel(ctx context.Context, model string, vram = 1 } - return &inference.RequiredMemory{ + return inference.RequiredMemory{ RAM: ram, VRAM: vram, }, nil @@ -351,16 +356,27 @@ func (l *llamaCpp) checkGPUSupport(ctx context.Context) bool { if l.updatedLlamaCpp { binPath = l.updatedServerStoragePath } - out, err := exec.CommandContext( + var output bytes.Buffer + llamaCppSandbox, err := sandbox.Create( ctx, + sandbox.ConfigurationLlamaCpp, + func(command *exec.Cmd) { + command.Stdout = &output + command.Stderr = &output + }, filepath.Join(binPath, "com.docker.llama-server"), "--list-devices", - ).CombinedOutput() + ) if err != nil { - l.log.Warnf("Failed to determine if llama-server is built with GPU support: %s", err) + l.log.Warnf("Failed to start sandboxed llama.cpp process to probe GPU support: %v", err) + return false + } + defer llamaCppSandbox.Close() + if err := llamaCppSandbox.Command().Wait(); err != nil { + l.log.Warnf("Failed to determine if llama-server is built with GPU support: %v", err) return false } - sc := bufio.NewScanner(strings.NewReader(string(out))) + sc := bufio.NewScanner(strings.NewReader(string(output.Bytes()))) expectDev := false devRe := regexp.MustCompile(`\s{2}.*:\s`) ndevs := 0 diff --git a/vendor/github.com/docker/model-runner/pkg/inference/backends/llamacpp/llamacpp_config.go b/vendor/github.com/docker/model-runner/pkg/inference/backends/llamacpp/llamacpp_config.go index f8b1fe5c..aa089f23 100644 --- a/vendor/github.com/docker/model-runner/pkg/inference/backends/llamacpp/llamacpp_config.go +++ b/vendor/github.com/docker/model-runner/pkg/inference/backends/llamacpp/llamacpp_config.go @@ -18,7 +18,7 @@ type Config struct { // NewDefaultLlamaCppConfig creates a new LlamaCppConfig with default values. func NewDefaultLlamaCppConfig() *Config { - args := append([]string{"--jinja", "-ngl", "100", "--metrics"}) + args := append([]string{"--jinja", "-ngl", "999", "--metrics"}) // Special case for Windows ARM64 if runtime.GOOS == "windows" && runtime.GOARCH == "arm64" { diff --git a/vendor/github.com/docker/model-runner/pkg/inference/memory/estimator.go b/vendor/github.com/docker/model-runner/pkg/inference/memory/estimator.go index 6d66e7f6..d369553b 100644 --- a/vendor/github.com/docker/model-runner/pkg/inference/memory/estimator.go +++ b/vendor/github.com/docker/model-runner/pkg/inference/memory/estimator.go @@ -10,12 +10,12 @@ import ( type MemoryEstimator interface { SetDefaultBackend(MemoryEstimatorBackend) - GetRequiredMemoryForModel(context.Context, string, *inference.BackendConfiguration) (*inference.RequiredMemory, error) - HaveSufficientMemoryForModel(ctx context.Context, model string, config *inference.BackendConfiguration) (bool, error) + GetRequiredMemoryForModel(context.Context, string, *inference.BackendConfiguration) (inference.RequiredMemory, error) + HaveSufficientMemoryForModel(ctx context.Context, model string, config *inference.BackendConfiguration) (bool, inference.RequiredMemory, inference.RequiredMemory, error) } type MemoryEstimatorBackend interface { - GetRequiredMemoryForModel(context.Context, string, *inference.BackendConfiguration) (*inference.RequiredMemory, error) + GetRequiredMemoryForModel(context.Context, string, *inference.BackendConfiguration) (inference.RequiredMemory, error) } type memoryEstimator struct { @@ -31,18 +31,18 @@ func (m *memoryEstimator) SetDefaultBackend(backend MemoryEstimatorBackend) { m.defaultBackend = backend } -func (m *memoryEstimator) GetRequiredMemoryForModel(ctx context.Context, model string, config *inference.BackendConfiguration) (*inference.RequiredMemory, error) { +func (m *memoryEstimator) GetRequiredMemoryForModel(ctx context.Context, model string, config *inference.BackendConfiguration) (inference.RequiredMemory, error) { if m.defaultBackend == nil { - return nil, errors.New("default backend not configured") + return inference.RequiredMemory{}, errors.New("default backend not configured") } return m.defaultBackend.GetRequiredMemoryForModel(ctx, model, config) } -func (m *memoryEstimator) HaveSufficientMemoryForModel(ctx context.Context, model string, config *inference.BackendConfiguration) (bool, error) { +func (m *memoryEstimator) HaveSufficientMemoryForModel(ctx context.Context, model string, config *inference.BackendConfiguration) (bool, inference.RequiredMemory, inference.RequiredMemory, error) { req, err := m.GetRequiredMemoryForModel(ctx, model, config) if err != nil { - return false, fmt.Errorf("estimating required memory for model: %w", err) + return false, inference.RequiredMemory{}, inference.RequiredMemory{}, fmt.Errorf("estimating required memory for model: %w", err) } - return m.systemMemoryInfo.HaveSufficientMemory(*req), nil + return m.systemMemoryInfo.HaveSufficientMemory(req), req, m.systemMemoryInfo.GetTotalMemory(), nil } diff --git a/vendor/github.com/docker/model-runner/pkg/inference/models/manager.go b/vendor/github.com/docker/model-runner/pkg/inference/models/manager.go index 7f84c34e..de65d8ff 100644 --- a/vendor/github.com/docker/model-runner/pkg/inference/models/manager.go +++ b/vendor/github.com/docker/model-runner/pkg/inference/models/manager.go @@ -19,6 +19,7 @@ import ( "github.com/docker/model-runner/pkg/inference" "github.com/docker/model-runner/pkg/inference/memory" "github.com/docker/model-runner/pkg/logging" + "github.com/docker/model-runner/pkg/middleware" v1 "github.com/google/go-containerregistry/pkg/v1" "github.com/sirupsen/logrus" ) @@ -38,6 +39,9 @@ type Manager struct { pullTokens chan struct{} // router is the HTTP request router. router *http.ServeMux + // httpHandler is the HTTP request handler, which wraps router with + // the server-level middleware. + httpHandler http.Handler // distributionClient is the client for model distribution. distributionClient *distribution.Client // registryClient is the client for model registry. @@ -95,10 +99,12 @@ func NewManager(log logging.Logger, c ClientConfig, allowedOrigins []string, mem http.Error(w, "not found", http.StatusNotFound) }) - for route, handler := range m.routeHandlers(allowedOrigins) { + for route, handler := range m.routeHandlers() { m.router.HandleFunc(route, handler) } + m.RebuildRoutes(allowedOrigins) + // Populate the pull concurrency semaphore. for i := 0; i < maximumConcurrentModelPulls; i++ { m.pullTokens <- struct{}{} @@ -111,19 +117,12 @@ func NewManager(log logging.Logger, c ClientConfig, allowedOrigins []string, mem func (m *Manager) RebuildRoutes(allowedOrigins []string) { m.lock.Lock() defer m.lock.Unlock() - // Clear existing routes and re-register them. - m.router = http.NewServeMux() - // Register routes. - m.router.HandleFunc("/", func(w http.ResponseWriter, _ *http.Request) { - http.Error(w, "not found", http.StatusNotFound) - }) - for route, handler := range m.routeHandlers(allowedOrigins) { - m.router.HandleFunc(route, handler) - } + // Update handlers that depend on the allowed origins. + m.httpHandler = middleware.CorsMiddleware(allowedOrigins, m.router) } -func (m *Manager) routeHandlers(allowedOrigins []string) map[string]http.HandlerFunc { - handlers := map[string]http.HandlerFunc{ +func (m *Manager) routeHandlers() map[string]http.HandlerFunc { + return map[string]http.HandlerFunc{ "POST " + inference.ModelsPrefix + "/create": m.handleCreateModel, "POST " + inference.ModelsPrefix + "/load": m.handleLoadModel, "GET " + inference.ModelsPrefix: m.handleGetModels, @@ -135,16 +134,10 @@ func (m *Manager) routeHandlers(allowedOrigins []string) map[string]http.Handler "GET " + inference.InferencePrefix + "/v1/models": m.handleOpenAIGetModels, "GET " + inference.InferencePrefix + "/v1/models/{name...}": m.handleOpenAIGetModel, } - for route, handler := range handlers { - if strings.HasPrefix(route, "GET ") { - handlers[route] = inference.CorsMiddleware(allowedOrigins, handler).ServeHTTP - } - } - return handlers } func (m *Manager) GetRoutes() []string { - routeHandlers := m.routeHandlers(nil) + routeHandlers := m.routeHandlers() routes := make([]string, 0, len(routeHandlers)) for route := range routeHandlers { routes = append(routes, route) @@ -170,15 +163,16 @@ func (m *Manager) handleCreateModel(w http.ResponseWriter, r *http.Request) { // besides pulling (such as model building). if !request.IgnoreRuntimeMemoryCheck { m.log.Infof("Will estimate memory required for %q", request.From) - proceed, err := m.memoryEstimator.HaveSufficientMemoryForModel(r.Context(), request.From, nil) + proceed, req, totalMem, err := m.memoryEstimator.HaveSufficientMemoryForModel(r.Context(), request.From, nil) if err != nil { m.log.Warnf("Failed to calculate memory required for model %q: %s", request.From, err) // Prefer staying functional in case of unexpected estimation errors. proceed = true } if !proceed { - m.log.Warnf("Runtime memory requirement for model %q exceeds total system memory", request.From) - http.Error(w, "Runtime memory requirement for model exceeds total system memory", http.StatusInsufficientStorage) + errstr := fmt.Sprintf("Runtime memory requirement for model %q exceeds total system memory: required %d RAM %d VRAM, system %d RAM %d VRAM", request.From, req.RAM, req.VRAM, totalMem.RAM, totalMem.VRAM) + m.log.Warnf(errstr) + http.Error(w, errstr, http.StatusInsufficientStorage) return } } @@ -578,7 +572,7 @@ func (m *Manager) GetDiskUsage() (int64, error, int) { func (m *Manager) ServeHTTP(w http.ResponseWriter, r *http.Request) { m.lock.RLock() defer m.lock.RUnlock() - m.router.ServeHTTP(w, r) + m.httpHandler.ServeHTTP(w, r) } // IsModelInStore checks if a given model is in the local store. diff --git a/vendor/github.com/docker/model-runner/pkg/inference/scheduling/loader.go b/vendor/github.com/docker/model-runner/pkg/inference/scheduling/loader.go index 69166e06..a6fdd054 100644 --- a/vendor/github.com/docker/model-runner/pkg/inference/scheduling/loader.go +++ b/vendor/github.com/docker/model-runner/pkg/inference/scheduling/loader.go @@ -401,7 +401,7 @@ func (l *loader) load(ctx context.Context, backendName, modelID, modelRef string // e.g. model is too new for gguf-parser-go to know. We should provide a cleaner // way to bypass these checks. l.log.Warnf("Could not parse model(%s), memory checks will be ignored for it. Error: %s", modelID, parseErr) - memory = &inference.RequiredMemory{ + memory = inference.RequiredMemory{ RAM: 0, VRAM: 0, } diff --git a/vendor/github.com/docker/model-runner/pkg/inference/scheduling/scheduler.go b/vendor/github.com/docker/model-runner/pkg/inference/scheduling/scheduler.go index b99db11a..b6d7ac08 100644 --- a/vendor/github.com/docker/model-runner/pkg/inference/scheduling/scheduler.go +++ b/vendor/github.com/docker/model-runner/pkg/inference/scheduling/scheduler.go @@ -8,7 +8,6 @@ import ( "fmt" "io" "net/http" - "strings" "sync" "time" @@ -18,6 +17,7 @@ import ( "github.com/docker/model-runner/pkg/inference/models" "github.com/docker/model-runner/pkg/logging" "github.com/docker/model-runner/pkg/metrics" + "github.com/docker/model-runner/pkg/middleware" "github.com/mattn/go-shellwords" "golang.org/x/sync/errgroup" ) @@ -39,6 +39,9 @@ type Scheduler struct { loader *loader // router is the HTTP request router. router *http.ServeMux + // httpHandler is the HTTP request handler, which wraps router with + // the server-level middleware. + httpHandler http.Handler // tracker is the metrics tracker. tracker *metrics.Tracker // openAIRecorder is used to record OpenAI API inference requests and responses. @@ -78,10 +81,12 @@ func NewScheduler( http.Error(w, "not found", http.StatusNotFound) }) - for route, handler := range s.routeHandlers(allowedOrigins) { + for route, handler := range s.routeHandlers() { s.router.HandleFunc(route, handler) } + s.RebuildRoutes(allowedOrigins) + // Scheduler successfully initialized. return s } @@ -89,18 +94,11 @@ func NewScheduler( func (s *Scheduler) RebuildRoutes(allowedOrigins []string) { s.lock.Lock() defer s.lock.Unlock() - // Clear existing routes and re-register them. - s.router = http.NewServeMux() - // Register routes. - s.router.HandleFunc("/", func(w http.ResponseWriter, _ *http.Request) { - http.Error(w, "not found", http.StatusNotFound) - }) - for route, handler := range s.routeHandlers(allowedOrigins) { - s.router.HandleFunc(route, handler) - } + // Update handlers that depend on the allowed origins. + s.httpHandler = middleware.CorsMiddleware(allowedOrigins, s.router) } -func (s *Scheduler) routeHandlers(allowedOrigins []string) map[string]http.HandlerFunc { +func (s *Scheduler) routeHandlers() map[string]http.HandlerFunc { openAIRoutes := []string{ "POST " + inference.InferencePrefix + "/{backend}/v1/chat/completions", "POST " + inference.InferencePrefix + "/{backend}/v1/completions", @@ -111,10 +109,7 @@ func (s *Scheduler) routeHandlers(allowedOrigins []string) map[string]http.Handl } m := make(map[string]http.HandlerFunc) for _, route := range openAIRoutes { - m[route] = inference.CorsMiddleware(allowedOrigins, http.HandlerFunc(s.handleOpenAIInference)).ServeHTTP - // Register OPTIONS for CORS preflight. - optionsRoute := "OPTIONS " + route[strings.Index(route, " "):] - m[optionsRoute] = inference.CorsMiddleware(allowedOrigins, http.HandlerFunc(s.handleOpenAIInference)).ServeHTTP + m[route] = s.handleOpenAIInference } m["GET "+inference.InferencePrefix+"/status"] = s.GetBackendStatus m["GET "+inference.InferencePrefix+"/ps"] = s.GetRunningBackends @@ -122,12 +117,12 @@ func (s *Scheduler) routeHandlers(allowedOrigins []string) map[string]http.Handl m["POST "+inference.InferencePrefix+"/unload"] = s.Unload m["POST "+inference.InferencePrefix+"/{backend}/_configure"] = s.Configure m["POST "+inference.InferencePrefix+"/_configure"] = s.Configure - m["GET "+inference.InferencePrefix+"/requests"] = s.openAIRecorder.GetRecordsByModelHandler() + m["GET "+inference.InferencePrefix+"/requests"] = s.openAIRecorder.GetRecordsHandler() return m } func (s *Scheduler) GetRoutes() []string { - routeHandlers := s.routeHandlers(nil) + routeHandlers := s.routeHandlers() routes := make([]string, 0, len(routeHandlers)) for route := range routeHandlers { routes = append(routes, route) @@ -514,5 +509,5 @@ func parseBackendMode(mode string) inference.BackendMode { func (s *Scheduler) ServeHTTP(w http.ResponseWriter, r *http.Request) { s.lock.RLock() defer s.lock.RUnlock() - s.router.ServeHTTP(w, r) + s.httpHandler.ServeHTTP(w, r) } diff --git a/vendor/github.com/docker/model-runner/pkg/metrics/metrics.go b/vendor/github.com/docker/model-runner/pkg/metrics/metrics.go index 5b58f6f8..09e819aa 100644 --- a/vendor/github.com/docker/model-runner/pkg/metrics/metrics.go +++ b/vendor/github.com/docker/model-runner/pkg/metrics/metrics.go @@ -26,10 +26,9 @@ type TrackerRoundTripper struct { } func (h *TrackerRoundTripper) RoundTrip(req *http.Request) (*http.Response, error) { - clonedReq := req.Clone(req.Context()) - ctx, cancel := context.WithTimeout(clonedReq.Context(), 5*time.Second) + ctx, cancel := context.WithTimeout(req.Context(), 5*time.Second) defer cancel() - clonedReq = clonedReq.WithContext(ctx) + clonedReq := req.Clone(ctx) clonedReq.Header.Set("x-docker-model-runner", "true") return h.Transport.RoundTrip(clonedReq) } diff --git a/vendor/github.com/docker/model-runner/pkg/metrics/openai_recorder.go b/vendor/github.com/docker/model-runner/pkg/metrics/openai_recorder.go index d3d11946..f7ac8c3c 100644 --- a/vendor/github.com/docker/model-runner/pkg/metrics/openai_recorder.go +++ b/vendor/github.com/docker/model-runner/pkg/metrics/openai_recorder.go @@ -41,16 +41,16 @@ func (rr *responseRecorder) Flush() { } type RequestResponsePair struct { - ID string `json:"id"` - Model string `json:"model"` - Method string `json:"method"` - URL string `json:"url"` - Request string `json:"request"` - Response string `json:"response,omitempty"` - Error string `json:"error,omitempty"` - Timestamp time.Time `json:"timestamp"` - StatusCode int `json:"status_code"` - UserAgent string `json:"user_agent,omitempty"` + ID string `json:"id"` + Model string `json:"model"` + Method string `json:"method"` + URL string `json:"url"` + Request string `json:"request"` + Response string `json:"response,omitempty"` + Error string `json:"error,omitempty"` + Timestamp int64 `json:"timestamp"` + StatusCode int `json:"status_code"` + UserAgent string `json:"user_agent,omitempty"` } type ModelData struct { @@ -58,6 +58,12 @@ type ModelData struct { Records []*RequestResponsePair `json:"records"` } +type ModelRecordsResponse struct { + Count int `json:"count"` + Model string `json:"model"` + ModelData +} + type OpenAIRecorder struct { log logging.Logger records map[string]*ModelData // key is model ID @@ -108,7 +114,7 @@ func (r *OpenAIRecorder) RecordRequest(model string, req *http.Request, body []b Method: req.Method, URL: req.URL.Path, Request: string(body), - Timestamp: time.Now(), + Timestamp: time.Now().Unix(), UserAgent: req.UserAgent(), } @@ -143,7 +149,7 @@ func (r *OpenAIRecorder) NewResponseRecorder(w http.ResponseWriter) http.Respons rc := &responseRecorder{ ResponseWriter: w, body: &bytes.Buffer{}, - statusCode: http.StatusOK, + statusCode: 0, } return rc } @@ -153,6 +159,10 @@ func (r *OpenAIRecorder) RecordResponse(id, model string, rw http.ResponseWriter responseBody := rr.body.String() statusCode := rr.statusCode + if statusCode == 0 { + // No status code was written (request canceled or failed before response). + statusCode = http.StatusRequestTimeout + } var response string if strings.Contains(responseBody, "data: ") { @@ -190,7 +200,8 @@ func (r *OpenAIRecorder) RecordResponse(id, model string, rw http.ResponseWriter func (r *OpenAIRecorder) convertStreamingResponse(streamingBody string) string { lines := strings.Split(streamingBody, "\n") var contentBuilder strings.Builder - var lastChunk map[string]interface{} + var reasoningContentBuilder strings.Builder + var lastChoice, lastChunk map[string]interface{} for _, line := range lines { if strings.HasPrefix(line, "data: ") { @@ -208,10 +219,14 @@ func (r *OpenAIRecorder) convertStreamingResponse(streamingBody string) string { if choices, ok := chunk["choices"].([]interface{}); ok && len(choices) > 0 { if choice, ok := choices[0].(map[string]interface{}); ok { + lastChoice = choice if delta, ok := choice["delta"].(map[string]interface{}); ok { if content, ok := delta["content"].(string); ok { contentBuilder.WriteString(content) } + if content, ok := delta["reasoning_content"].(string); ok { + reasoningContentBuilder.WriteString(content) + } } } } @@ -227,13 +242,18 @@ func (r *OpenAIRecorder) convertStreamingResponse(streamingBody string) string { for key, value := range lastChunk { finalResponse[key] = value } + finalResponse["choices"] = []interface{}{lastChoice} if choices, ok := finalResponse["choices"].([]interface{}); ok && len(choices) > 0 { if choice, ok := choices[0].(map[string]interface{}); ok { - choice["message"] = map[string]interface{}{ + message := map[string]interface{}{ "role": "assistant", "content": contentBuilder.String(), } + if reasoningContentBuilder.Len() > 0 { + message["reasoning_content"] = reasoningContentBuilder.String() + } + choice["message"] = message delete(choice, "delta") if _, ok := choice["finish_reason"]; !ok { @@ -252,30 +272,34 @@ func (r *OpenAIRecorder) convertStreamingResponse(streamingBody string) string { return string(jsonResult) } -func (r *OpenAIRecorder) GetRecordsByModelHandler() http.HandlerFunc { +func (r *OpenAIRecorder) GetRecordsHandler() http.HandlerFunc { return func(w http.ResponseWriter, req *http.Request) { w.Header().Set("Content-Type", "application/json") model := req.URL.Query().Get("model") if model == "" { - http.Error(w, "A 'model' query parameter is required", http.StatusBadRequest) + // Retrieve all records for all models. + allRecords := r.getAllRecords() + if allRecords == nil { + // No records found. + http.Error(w, "No records found", http.StatusNotFound) + return + } + if err := json.NewEncoder(w).Encode(allRecords); err != nil { + http.Error(w, fmt.Sprintf("Failed to encode all records: %v", err), + http.StatusInternalServerError) + return + } } else { // Retrieve records for the specified model. - records := r.GetRecordsByModel(model) + records := r.getRecordsByModel(model) if records == nil { // No records found for the specified model. http.Error(w, fmt.Sprintf("No records found for model '%s'", model), http.StatusNotFound) return } - - modelID := r.modelManager.ResolveModelID(model) - if err := json.NewEncoder(w).Encode(map[string]interface{}{ - "model": model, - "records": records, - "count": len(records), - "config": r.records[modelID].Config, - }); err != nil { + if err := json.NewEncoder(w).Encode(records); err != nil { http.Error(w, fmt.Sprintf("Failed to encode records for model '%s': %v", model, err), http.StatusInternalServerError) return @@ -284,16 +308,45 @@ func (r *OpenAIRecorder) GetRecordsByModelHandler() http.HandlerFunc { } } -func (r *OpenAIRecorder) GetRecordsByModel(model string) []*RequestResponsePair { +func (r *OpenAIRecorder) getAllRecords() []ModelRecordsResponse { + r.m.RLock() + defer r.m.RUnlock() + + if len(r.records) == 0 { + return nil + } + + result := make([]ModelRecordsResponse, 0, len(r.records)) + + for modelID, modelData := range r.records { + result = append(result, ModelRecordsResponse{ + Count: len(modelData.Records), + Model: modelID, + ModelData: ModelData{ + Config: modelData.Config, + Records: modelData.Records, + }, + }) + } + + return result +} + +func (r *OpenAIRecorder) getRecordsByModel(model string) []ModelRecordsResponse { modelID := r.modelManager.ResolveModelID(model) r.m.RLock() defer r.m.RUnlock() if modelData, exists := r.records[modelID]; exists { - result := make([]*RequestResponsePair, len(modelData.Records)) - copy(result, modelData.Records) - return result + return []ModelRecordsResponse{{ + Count: len(modelData.Records), + Model: modelID, + ModelData: ModelData{ + Config: modelData.Config, + Records: modelData.Records, + }, + }} } return nil diff --git a/vendor/github.com/docker/model-runner/pkg/inference/cors.go b/vendor/github.com/docker/model-runner/pkg/middleware/cors.go similarity index 96% rename from vendor/github.com/docker/model-runner/pkg/inference/cors.go rename to vendor/github.com/docker/model-runner/pkg/middleware/cors.go index 1bd468f2..cabb6447 100644 --- a/vendor/github.com/docker/model-runner/pkg/inference/cors.go +++ b/vendor/github.com/docker/model-runner/pkg/middleware/cors.go @@ -1,4 +1,4 @@ -package inference +package middleware import ( "net/http" @@ -34,7 +34,7 @@ func CorsMiddleware(allowedOrigins []string, next http.Handler) http.Handler { w.Header().Set("Access-Control-Allow-Credentials", "true") w.Header().Set("Access-Control-Allow-Methods", "GET, POST") w.Header().Set("Access-Control-Allow-Headers", "*") - w.WriteHeader(http.StatusOK) + w.WriteHeader(http.StatusNoContent) return } diff --git a/vendor/github.com/docker/model-runner/pkg/sandbox/sandbox.go b/vendor/github.com/docker/model-runner/pkg/sandbox/sandbox.go new file mode 100644 index 00000000..261c30db --- /dev/null +++ b/vendor/github.com/docker/model-runner/pkg/sandbox/sandbox.go @@ -0,0 +1,13 @@ +package sandbox + +import ( + "os/exec" +) + +// Sandbox encapsulates a single running sandboxed process. +type Sandbox interface { + // Command returns the sandboxed process handle. + Command() *exec.Cmd + // Close closes the sandbox, terminating the process if it's still running. + Close() error +} diff --git a/vendor/github.com/docker/model-runner/pkg/sandbox/sandbox_darwin.go b/vendor/github.com/docker/model-runner/pkg/sandbox/sandbox_darwin.go new file mode 100644 index 00000000..7503da51 --- /dev/null +++ b/vendor/github.com/docker/model-runner/pkg/sandbox/sandbox_darwin.go @@ -0,0 +1,158 @@ +package sandbox + +import ( + "context" + "fmt" + "os" + "os/exec" + "os/user" + "strings" +) + +// ConfigurationLlamaCpp is the sandbox configuration for llama.cpp processes. +const ConfigurationLlamaCpp = `(version 1) + +;;; Keep a default allow policy (because encoding things like DYLD support and +;;; device access is quite difficult), but deny critical exploitation targets +;;; (generally aligned with the App Sandbox entitlements that aren't on by +;;; default). In theory we'll be subject to the Docker.app sandbox as well +;;; (unless we're running standalone), but even Docker.app has a very privileged +;;; sandbox, so we need additional constraints. +;;; +;;; Note: The following are known to be required at some level for llama.cpp +;;; (though we could further experiment to deny certain sub-permissions): +;;; - authorization +;;; - darwin +;;; - iokit +;;; - mach +;;; - socket +;;; - syscall +;;; - process +(allow default) + +;;; Deny network access, except for our IPC sockets. +;;; NOTE: We use different socket nomenclature when running in Docker Desktop +;;; (inference-N.sock) vs. standalone (inference-runner-N.sock), so we use a +;;; wildcard to support both. +(deny network*) +(allow network-bind network-inbound + (regex #"inference.*-[0-9]+\.sock$")) + +;;; Deny access to the camera and microphone. +(deny device*) + +;;; Deny access to NVRAM settings. +(deny nvram*) + +;;; Deny access to system-level privileges. +(deny system*) + +;;; Deny access to job creation. +(deny job-creation) + +;;; Don't allow new executable code to be created in memory at runtime. +(deny dynamic-code-generation) + +;;; Disable access to user preferences. +(deny user-preference*) + +;;; Restrict file access. +;;; NOTE: For some reason, the (home-subpath "...") predicate used in system +;;; sandbox profiles doesn't work with sandbox-exec. +;;; NOTE: We have to allow access to the working directory for standalone mode. +;;; NOTE: We have to allow access to a regex-based Docker.app location to +;;; support Docker Desktop development as well as Docker.app installs that don't +;;; live inside /Applications. +;;; NOTE: For some reason (deny file-read*) really doesn't like to play nice +;;; with llama.cpp, so for that reason we'll avoid a blanket ban and just ban +;;; directories that might contain sensitive data. +(deny file-map-executable) +(deny file-write*) +(deny file-read* + (subpath "/Applications") + (subpath "/private/etc") + (subpath "/Library") + (subpath "/Users") + (subpath "/Volumes")) +(allow file-read* file-map-executable + (subpath "/usr") + (subpath "/System") + (regex #"Docker\.app/Contents/Resources/model-runner") + (subpath "[HOMEDIR]/.docker/bin/inference") + (subpath "[HOMEDIR]/.docker/bin/lib")) +(allow file-write* + (literal "/dev/null") + (subpath "/private/var") + (subpath "[HOMEDIR]/Library/Containers/com.docker.docker/Data") + (subpath "[WORKDIR]")) +(allow file-read* + (subpath "[HOMEDIR]/.docker/models") + (subpath "[HOMEDIR]/Library/Containers/com.docker.docker/Data") + (subpath "[WORKDIR]")) +` + +// sandbox is the Darwin sandbox implementation. +type sandbox struct { + // cancel cancels the context associated with the process. + cancel context.CancelFunc + // command is the sandboxed process handle. + command *exec.Cmd +} + +// Command implements Sandbox.Command. +func (s *sandbox) Command() *exec.Cmd { + return s.command +} + +// Command implements Sandbox.Close. +func (s *sandbox) Close() error { + s.cancel() + return nil +} + +// Create creates a sandbox containing a single process that has been started. +// The ctx, name, and arg arguments correspond to their counterparts in +// os/exec.CommandContext. The configuration argument specifies the sandbox +// configuration, for which a pre-defined value should be used. The modifier +// function allows for an optional callback (which may be nil) to configure the +// command before it is started. +func Create(ctx context.Context, configuration string, modifier func(*exec.Cmd), name string, arg ...string) (Sandbox, error) { + // Look up the user's home directory. + currentUser, err := user.Current() + if err != nil { + return nil, fmt.Errorf("unable to lookup user: %w", err) + } + + // Look up the working directory. + currentDirectory, err := os.Getwd() + if err != nil { + return nil, fmt.Errorf("unable to determine working directory: %w", err) + } + + // Process template arguments in the configuration. We should switch to + // text/template if this gets any more complex. + profile := strings.ReplaceAll(configuration, "[HOMEDIR]", currentUser.HomeDir) + profile = strings.ReplaceAll(profile, "[WORKDIR]", currentDirectory) + + // Create a subcontext we can use to regulate the process lifetime. + ctx, cancel := context.WithCancel(ctx) + + // Create and configure the command. + sandboxedArgs := make([]string, 0, len(arg)+3) + sandboxedArgs = append(sandboxedArgs, "-p", profile, name) + sandboxedArgs = append(sandboxedArgs, arg...) + command := exec.CommandContext(ctx, "sandbox-exec", sandboxedArgs...) + if modifier != nil { + modifier(command) + } + + // Start the process. + if err := command.Start(); err != nil { + cancel() + return nil, fmt.Errorf("unable to start sandboxed process: %w", err) + } + return &sandbox{ + cancel: cancel, + command: command, + }, nil +} diff --git a/vendor/github.com/docker/model-runner/pkg/sandbox/sandbox_other.go b/vendor/github.com/docker/model-runner/pkg/sandbox/sandbox_other.go new file mode 100644 index 00000000..81acf6f4 --- /dev/null +++ b/vendor/github.com/docker/model-runner/pkg/sandbox/sandbox_other.go @@ -0,0 +1,58 @@ +//go:build !darwin && !windows + +package sandbox + +import ( + "context" + "fmt" + "os/exec" +) + +// ConfigurationLlamaCpp is the sandbox configuration for llama.cpp processes. +const ConfigurationLlamaCpp = `` + +// sandbox is the non-Darwin POSIX sandbox implementation. +type sandbox struct { + // cancel cancels the context associated with the process. + cancel context.CancelFunc + // command is the sandboxed process handle. + command *exec.Cmd +} + +// Command implements Sandbox.Command. +func (s *sandbox) Command() *exec.Cmd { + return s.command +} + +// Command implements Sandbox.Close. +func (s *sandbox) Close() error { + s.cancel() + return nil +} + +// Create creates a sandbox containing a single process that has been started. +// The ctx, name, and arg arguments correspond to their counterparts in +// os/exec.CommandContext. The configuration argument specifies the sandbox +// configuration, for which a pre-defined value should be used. The modifier +// function allows for an optional callback (which may be nil) to configure the +// command before it is started. +func Create(ctx context.Context, configuration string, modifier func(*exec.Cmd), name string, arg ...string) (Sandbox, error) { + // Create a subcontext we can use to regulate the process lifetime. + ctx, cancel := context.WithCancel(ctx) + + // Create and configure the command. + command := exec.CommandContext(ctx, name, arg...) + if modifier != nil { + modifier(command) + } + + // Start the process. + if err := command.Start(); err != nil { + cancel() + return nil, fmt.Errorf("unable to start process: %w", err) + } + return &sandbox{ + cancel: cancel, + command: command, + }, nil +} diff --git a/vendor/github.com/docker/model-runner/pkg/sandbox/sandbox_windows.go b/vendor/github.com/docker/model-runner/pkg/sandbox/sandbox_windows.go new file mode 100644 index 00000000..99bd9d01 --- /dev/null +++ b/vendor/github.com/docker/model-runner/pkg/sandbox/sandbox_windows.go @@ -0,0 +1,95 @@ +package sandbox + +import ( + "context" + "fmt" + "os/exec" + "regexp" + + "github.com/kolesnikovae/go-winjob" +) + +// limitTokenMatcher finds limit tokens in a sandbox configuration. +var limitTokenMatcher = regexp.MustCompile(`\(With[a-zA-Z]+\)`) + +// limitTokenToGenerator maps limit tokens to their corresponding generators. +var limitTokenToGenerator = map[string]func() winjob.Limit{ + "(WithDesktopLimit)": winjob.WithDesktopLimit, + "(WithDieOnUnhandledException)": winjob.WithDieOnUnhandledException, + "(WithDisplaySettingsLimit)": winjob.WithDisplaySettingsLimit, + "(WithExitWindowsLimit)": winjob.WithExitWindowsLimit, + "(WithGlobalAtomsLimit)": winjob.WithGlobalAtomsLimit, + "(WithHandlesLimit)": winjob.WithHandlesLimit, + "(WithDisableOutgoingNetworking)": func() winjob.Limit { + return winjob.WithOutgoingBandwidthLimit(0) + }, + "(WithReadClipboardLimit)": winjob.WithReadClipboardLimit, + "(WithSystemParametersLimit)": winjob.WithSystemParametersLimit, + "(WithWriteClipboardLimit)": winjob.WithWriteClipboardLimit, +} + +// ConfigurationLlamaCpp is the sandbox configuration for llama.cpp processes. +const ConfigurationLlamaCpp = `(WithDesktopLimit) +(WithDieOnUnhandledException) +(WithDisplaySettingsLimit) +(WithExitWindowsLimit) +(WithGlobalAtomsLimit) +(WithHandlesLimit) +(WithDisableOutgoingNetworking) +(WithReadClipboardLimit) +(WithSystemParametersLimit) +(WithWriteClipboardLimit) +` + +// sandbox is the Windows sandbox implementation. +type sandbox struct { + // job is the Windows Job object that encapsulates the process. + job *winjob.JobObject + // command is the sandboxed process handle. + command *exec.Cmd +} + +// Command implements Sandbox.Command. +func (s *sandbox) Command() *exec.Cmd { + return s.command +} + +// Command implements Sandbox.Close. +func (s *sandbox) Close() error { + return s.job.Close() +} + +// Create creates a sandbox containing a single process that has been started. +// The ctx, name, and arg arguments correspond to their counterparts in +// os/exec.CommandContext. The configuration argument specifies the sandbox +// configuration, for which a pre-defined value should be used. The modifier +// function allows for an optional callback (which may be nil) to configure the +// command before it is started. +func Create(ctx context.Context, configuration string, modifier func(*exec.Cmd), name string, arg ...string) (Sandbox, error) { + // Parse the configuration and configure limits. + limits := []winjob.Limit{winjob.WithKillOnJobClose()} + tokens := limitTokenMatcher.FindAllString(configuration, -1) + for _, token := range tokens { + if generator, ok := limitTokenToGenerator[token]; ok { + limits = append(limits, generator()) + } else { + return nil, fmt.Errorf("unknown limit token: %q", token) + } + } + + // Create and configure the command. + command := exec.CommandContext(ctx, name, arg...) + if modifier != nil { + modifier(command) + } + + // Create the and start the job. + job, err := winjob.Start(command, limits...) + if err != nil { + return nil, fmt.Errorf("unable to start sandboxed process: %w", err) + } + return &sandbox{ + job: job, + command: command, + }, nil +} diff --git a/vendor/github.com/kolesnikovae/go-winjob/.gitignore b/vendor/github.com/kolesnikovae/go-winjob/.gitignore new file mode 100644 index 00000000..8cf03a0a --- /dev/null +++ b/vendor/github.com/kolesnikovae/go-winjob/.gitignore @@ -0,0 +1,19 @@ +# Binaries for programs and plugins +*.exe +*.exe~ +*.dll +*.so +*.dylib + +# Test binary, built with `go test -c` +*.test + +# Output of the go coverage tool, specifically when used with LiteIDE +*.out + +# Dependency directories (remove the comment below to include it) +# vendor/ + +.golangci-lint.yaml +.idea +.DS_Store diff --git a/vendor/github.com/kolesnikovae/go-winjob/LICENSE b/vendor/github.com/kolesnikovae/go-winjob/LICENSE new file mode 100644 index 00000000..b371d095 --- /dev/null +++ b/vendor/github.com/kolesnikovae/go-winjob/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2020 kolesnikovae + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/vendor/github.com/kolesnikovae/go-winjob/README.md b/vendor/github.com/kolesnikovae/go-winjob/README.md new file mode 100644 index 00000000..6b078953 --- /dev/null +++ b/vendor/github.com/kolesnikovae/go-winjob/README.md @@ -0,0 +1,197 @@ +# go-winjob +[![GoDoc](https://godoc.org/github.com/kolesnikovae/go-winjob?status.svg)](https://godoc.org/github.com/kolesnikovae/go-winjob/) +[![Go Report Card](https://goreportcard.com/badge/github.com/kolesnikovae/go-winjob)](https://goreportcard.com/report/github.com/kolesnikovae/go-winjob) +[![Build status](https://ci.appveyor.com/api/projects/status/yim6v5uws84x8ip6/branch/master?svg=true)](https://ci.appveyor.com/project/kolesnikovae/go-winjob/branch/master) +[![CodeCov](https://codecov.io/gh/kolesnikovae/go-winjob/branch/master/graph/badge.svg)](https://codecov.io/gh/kolesnikovae/go-winjob) + +Go bindings for [Windows Job Objects](https://docs.microsoft.com/en-us/windows/win32/procthread/job-objects): +> A job object allows groups of processes to be managed as a unit. Job objects are namable, securable, sharable objects that control attributes of the processes associated with them. Operations performed on a job object affect all processes associated with the job object. Examples include enforcing limits such as working set size and process priority or terminating all processes associated with a job. + +The package provides means to manage windows jobs. **jobapi** sub-package holds supplemental types and functions for low-level interactions with the operating system. + +## Installation + +To start using **go-winjob**, install Go 1.11 or above and run go get: +``` +$ go get github.com/kolesnikovae/go-winjob +``` + +## Usage +### Creating and Managing Jobs + +The example below demonstrates an efficient way to ensure no descendant processes will be left after the process exit: +```go +cmd := exec.Cmd("app.exe") +job, err := winjob.Start(cmd, + winjob.LimitKillOnJobClose, + winjob.LimitBreakawayOK) + +if err != nil { + // ... +} + +defer job.Close() +if err := cmd.Wait(); err != nil { + // ... +} +``` + +`LimitKillOnJobClose` acts similarly to `prctl(PR_SET_PDEATHSIG, SIGKILL)` in Linux: the job is destroyed when its last handle has been closed and all associated processes have been terminated. However, if the job has the `LimitKillOnJobClose`, closing the last job object handle terminates all associated processes and then destroys the job object itself. + +The same result can be achieved by manual assignment: +
+ Show example + + ```go + job, _ := winjob.Create("", + winjob.LimitKillOnJobClose, + winjob.LimitBreakawayOK) + + cmd := exec.Cmd("app.exe") + cmd.SysProcAttr = &windows.SysProcAttr{ + CreationFlags: windows.CREATE_SUSPENDED, + } + + if err := cmd.Start(); err != nil { + // ... + } + + if err := job.Assign(cmd.Process); err != nil { + // ... + } + + if err := winjob.ResumeProcess(cmd.Process); err != nil { + // ... + } + + if err := cmd.Wait(); err != nil { + // ... + } + ``` + +
+ +### Job Limits + +**go-winjob** manages limits of the following types: + - [x] Basic Limits + - [x] Extended Limits + - [x] UI Restriction + - [x] CPU Rate Control + - [x] Net Rate Control + - [ ] IO Rate Control (Deprecated) + - [ ] Notifications Limits + - [ ] Violations Limits + +Limits can be applied to a job object at any time either by one, or all together +(a full list can be found in the package documentation): +```go +limits := []winjob.Limit{ + winjob.WithKillOnJobClose(), + winjob.WithWorkingSetLimit(1<<20, 8<<20), + winjob.WithCPUHardCapLimit(5000), + winjob.WithDSCPTag(0x14), +} + +if err := job.SetLimits(limits...); err != nil { + // ... +} + +if err := job.ResetLimit(winjob.LimitKillOnJobClose); err != nil { + // ... +} +``` + +Also, a particular limit value can be examined: +```go +if err := job.QueryLimits(); err != nil { + // ... +} + +winjob.LimitCPU(job).LimitValue() +// Output: {Min:0 Max:0 Weight:0 HardCap:500} +``` +Alternatively, limit values are accessible via `JobInfo` member of a `JobObject`. + +**Note**: limits should be explicitly queried with `job.QueryLimits()` before accessing their values. + +### Job Notifications + +A job can also set limits that trigger a notification when they are exceeded but allow the job to continue to run. + +It is best to do this when the job is inactive, to reduce the chance of missing notifications for processes whose states change during the association of the completion port. +```go +c := make(chan winjob.Notification, 1) +s, err := winjob.Notify(c, job) +if err != nil { + // ... +} + +go func() { + defer s.Close() + for { + select { + case <-ctx.Done(): + return + case n := <-c: + switch n.Type { + case winjob.NotificationNewProcess: + // ... + case winjob.NotificationExitProcess: + // ... + case winjob.NotificationNotificationLimit: + // Query limit violations. + default: + log.Println(n.Type, n.PID) + } + } + } +}() + +if err := winjob.Start(cmd, limits...); err != nil { + // ... +} +``` + +A full list of supported notification types can be found in the package documentation. + +Note that, with the exception of limits set with the `JobObjectNotificationLimitInformation` information class explicitly, delivery of messages to the completion port is not guaranteed; failure of a message to arrive does not necessarily mean that the event did not occur. + +Refer to `examples/job` for a full example. + +### Resource Accounting for Jobs + +A job object records basic and IO accounting information for all its associated processes, including those that have terminated: +```go +c, err := job.Counters() +if err != nil { + // ... +} +``` + +JSON output: +```json +{ + "TotalUserTime": 156250, + "TotalKernelTime": 156250, + "ThisPeriodTotalUserTime": 156250, + "ThisPeriodTotalKernelTime": 156250, + "TotalPageFaultCount": 7900, + "TotalProcesses": 2, + "ActiveProcesses": 0, + "TotalTerminatedProcesses": 0, + "ReadOperationCount": 52, + "WriteOperationCount": 0, + "OtherOperationCount": 638, + "ReadTransferCount": 202300, + "WriteTransferCount": 0, + "OtherTransferCount": 638 +} +``` +In order to avoid unnecessary allocations, `QueryCounters` method can be used instead: +```go +var counters winjob.Counters +if err := job.QueryCounters(&counters); err != nil { + // ... +} +``` diff --git a/vendor/github.com/kolesnikovae/go-winjob/appveyor.yml b/vendor/github.com/kolesnikovae/go-winjob/appveyor.yml new file mode 100644 index 00000000..2b529b4c --- /dev/null +++ b/vendor/github.com/kolesnikovae/go-winjob/appveyor.yml @@ -0,0 +1,26 @@ +version: "{build}" + +os: Windows Server 2012 R2 + +platform: x64 + +clone_folder: c:\gopath\src\github.com\kolesnikovae\go-winjob + +environment: + GOVERSION: 1.14 + GOPATH: c:\gopath + GO111MODULE: on + +build_script: + - cd c:\gopath\src\github.com\kolesnikovae\go-winjob + - git branch + - go get -t ./... + +test_script: + - ps: Add-AppveyorTest "Unit Tests" -Outcome Running + - go test -v --cover --coverprofile=coverage.txt github.com/kolesnikovae/go-winjob/... + - choco install codecov --yes + - codecov -f coverage.txt -X fix + - ps: Update-AppveyorTest "Unit Tests" -Outcome Passed + +deploy: off diff --git a/vendor/github.com/kolesnikovae/go-winjob/codecov.yml b/vendor/github.com/kolesnikovae/go-winjob/codecov.yml new file mode 100644 index 00000000..c3a812f0 --- /dev/null +++ b/vendor/github.com/kolesnikovae/go-winjob/codecov.yml @@ -0,0 +1,20 @@ +codecov: + notify: + require_ci_to_pass: yes + + comment: + layout: "reach, diff" + behavior: default + + coverage: + range: 50..80 + round: down + precision: 0 + status: + project: + default: + target: 80 + patch: + default: + target: auto + threshold: 5 diff --git a/vendor/github.com/kolesnikovae/go-winjob/doc.go b/vendor/github.com/kolesnikovae/go-winjob/doc.go new file mode 100644 index 00000000..2116cada --- /dev/null +++ b/vendor/github.com/kolesnikovae/go-winjob/doc.go @@ -0,0 +1,7 @@ +//go:build windows +// +build windows + +// Package go-winjob provides means to manage windows job objects. +// +// Refer to Microsoft Documentation for details: https://docs.microsoft.com/en-us/windows/win32/procthread/job-objects. +package winjob diff --git a/vendor/github.com/kolesnikovae/go-winjob/job_object.go b/vendor/github.com/kolesnikovae/go-winjob/job_object.go new file mode 100644 index 00000000..9e439aac --- /dev/null +++ b/vendor/github.com/kolesnikovae/go-winjob/job_object.go @@ -0,0 +1,350 @@ +//go:build windows +// +build windows + +package winjob + +import ( + "os" + "syscall" + + "github.com/kolesnikovae/go-winjob/jobapi" + + "golang.org/x/sys/windows" +) + +// JobObject represents windows job object. Microsoft documentation says the +// following: A job object allows groups of processes to be managed as a unit. +// Job objects are namable, securable, sharable objects that control attributes +// of the processes associated with them. Operations performed on a job object +// affect all processes associated with the job object. Examples include +// enforcing limits such as working set size and process priority or +// terminating all processes associated with a job. +// +// https://docs.microsoft.com/en-us/windows/desktop/procthread/job-objects. +type JobObject struct { + Name string + Handle syscall.Handle + JobInfo +} + +// Limit manages a job object limits. +// +// Microsoft documentation says the following: A job can enforce limits such as +// working set size, process priority, and end-of-job time limit on each +// process that is associated with the job. If a process associated with a +// job attempts to increase its working set size or process priority from the +// limit established by the job, the function calls succeed but are silently +// ignored. A job can also set limits that trigger a notification when they +// are exceeded but allow the job to continue to run. +// +// https://docs.microsoft.com/en-us/windows/desktop/procthread/job-objects +type Limit interface { + + // IsSet reports whether the limit is set for the job object. + IsSet(*JobObject) bool + + // Value returns actual limit value for the job object. + // A Limit implementation may provide specific methods for + // accessing its values of a concrete type, if applicable. + Value(*JobObject) interface{} + + set(*JobObject) + reset(*JobObject) +} + +// Counters contains basic accounting information and I/O counters +// of a job object. +type Counters struct { + TotalUserTime uint64 + TotalKernelTime uint64 + ThisPeriodTotalUserTime uint64 + ThisPeriodTotalKernelTime uint64 + TotalPageFaultCount uint32 + TotalProcesses uint32 + ActiveProcesses uint32 + TotalTerminatedProcesses uint32 + + ReadOperationCount uint64 + WriteOperationCount uint64 + OtherOperationCount uint64 + ReadTransferCount uint64 + WriteTransferCount uint64 + OtherTransferCount uint64 +} + +type JobInfo struct { + ExtendedLimits windows.JOBOBJECT_EXTENDED_LIMIT_INFORMATION + UIRestrictions jobapi.JOBOBJECT_BASIC_UI_RESTRICTIONS + AccountingInfo jobapi.JOBOBJECT_BASIC_AND_IO_ACCOUNTING_INFORMATION + CPURateControl jobapi.JOBOBJECT_CPU_RATE_CONTROL_INFORMATION + NetRateControl jobapi.JOBOBJECT_NET_RATE_CONTROL_INFORMATION +} + +// Create creates a new job object. An anonymous job object will be created, +// if a name is not provided. One or more job object limits may be specified: +// refer to limits documentation for details. If limits fail to apply, created +// job object will be disposed. +func Create(name string, limits ...Limit) (*JobObject, error) { + hJobObject, err := jobapi.CreateJobObject(name, jobapi.MakeSA()) + if err != nil { + return nil, err + } + job := JobObject{ + Name: name, + Handle: hJobObject, + } + if len(limits) != 0 { + if err := job.SetLimit(limits...); err != nil { + _ = job.Close() + return nil, err + } + } + return &job, nil +} + +// Open opens existing job object by its name. A job is being opened with +// JOB_OBJECT_ALL_ACCESS access rights. +func Open(name string) (*JobObject, error) { + return OpenWithAccess(name, jobapi.JOB_OBJECT_ALL_ACCESS) +} + +// Open opens existing job object by its name with access rights specified. +func OpenWithAccess(name string, access uintptr) (*JobObject, error) { + hJobObject, err := jobapi.OpenJobObject(access, 0, name) + if err != nil { + return nil, err + } + job := JobObject{ + Name: name, + Handle: hJobObject, + } + return &job, nil +} + +// Close closes job object handle. +func (job *JobObject) Close() error { + return syscall.Close(job.Handle) +} + +// Terminate destroys the job object and all the associated processes. +// If the job is nested, this function terminates all child jobs in the +// hierarchy. All the processes and threads in the job object will use +// exit code 1. +func (job *JobObject) Terminate() error { + return job.TerminateWithExitCode(1) +} + +// TerminateWithExitCode terminates the job object. All the processes and +// threads in the job object will use the exit code provided. +func (job *JobObject) TerminateWithExitCode(exitCode uint32) error { + return jobapi.TerminateJobObject(job.Handle, exitCode) +} + +// Assign opens specified process by PID and adds it to the job object. +// When a process is associated with a job, the association cannot be +// broken. A process can be associated with more than one job object in a +// hierarchy of nested jobs (OS-dependent). The process is opened with +// PROCESS_ALL_ACCESS access rights. +func (job *JobObject) Assign(p *os.Process) error { + desiredAccess := jobapi.PROCESS_ALL_ACCESS + return withProcessHandle(p.Pid, desiredAccess, func(h syscall.Handle) error { + return jobapi.AssignProcessToJobObject(job.Handle, h) + }) +} + +// Contains returns true if the process is running in the job object. +// The process is opened with PROCESS_QUERY_LIMITED_INFORMATION access +// rights. +func (job *JobObject) Contains(p *os.Process) (found bool, err error) { + desiredAccess := jobapi.PROCESS_QUERY_LIMITED_INFORMATION + err = withProcessHandle(p.Pid, desiredAccess, func(h syscall.Handle) error { + found, err = jobapi.IsProcessInJob(h, job.Handle) + return err + }) + return found, err +} + +func withProcessHandle(pid, access int, fn func(h syscall.Handle) error) error { + hProcess, err := syscall.OpenProcess(uint32(access), false, uint32(pid)) + if err != nil { + return err + } + defer func() { + _ = syscall.CloseHandle(hProcess) + }() + return fn(hProcess) +} + +// Counters creates a new Counters and queries the given job object for basic +// and I/O accounting information. If job counters are queried on interval, +// returned Counters should be used with consequent QueryCounters calls in +// order to reduce the number of allocations. +func (job *JobObject) Counters() (*Counters, error) { + var c Counters + if err := job.QueryCounters(&c); err != nil { + return nil, err + } + return &c, nil +} + +// QueryCounters queries the job object for basic and I/O accounting +// information and fills provided Counters with the data retrieved. +func (job *JobObject) QueryCounters(c *Counters) error { + err := job.sync(jobapi.QueryInfo, jobapi.JobObjectBasicAndIoAccountingInformation) + if err != nil { + return err + } + + c.TotalUserTime = job.AccountingInfo.TotalUserTime + c.TotalKernelTime = job.AccountingInfo.TotalUserTime + c.ThisPeriodTotalUserTime = job.AccountingInfo.TotalUserTime + c.ThisPeriodTotalKernelTime = job.AccountingInfo.TotalUserTime + + c.TotalPageFaultCount = job.AccountingInfo.TotalPageFaultCount + c.TotalProcesses = job.AccountingInfo.TotalProcesses + c.ActiveProcesses = job.AccountingInfo.ActiveProcesses + c.TotalTerminatedProcesses = job.AccountingInfo.TotalTerminatedProcesses + + c.ReadOperationCount = job.AccountingInfo.ReadOperationCount + c.WriteOperationCount = job.AccountingInfo.WriteOperationCount + c.OtherOperationCount = job.AccountingInfo.OtherOperationCount + c.ReadTransferCount = job.AccountingInfo.ReadTransferCount + c.WriteTransferCount = job.AccountingInfo.WriteTransferCount + c.OtherTransferCount = job.AccountingInfo.OtherOperationCount + + return nil +} + +// QueryLimits queries all supported limit information for the job object. +func (job *JobObject) QueryLimits() error { + return job.sync(jobapi.QueryInfo, + jobapi.JobObjectExtendedLimitInformation, + jobapi.JobObjectBasicUIRestrictions, + jobapi.JobObjectCpuRateControlInformation, + jobapi.JobObjectNetRateControlInformation) +} + +// SetLimit applies given limits to the job object. +func (job *JobObject) SetLimit(limits ...Limit) error { + return job.applyLimit(true, limits...) +} + +// HasLimits returns true if any limit is set on the job object. +func (job *JobObject) HasLimits() (bool, error) { + if err := job.QueryLimits(); err != nil { + return false, err + } + return len(job.limitInfoClassesSet()) > 0, nil +} + +// ResetLimits resets all the job object limits. +func (job *JobObject) ResetLimits() error { + if err := job.QueryLimits(); err != nil { + return err + } + infoClasses := job.limitInfoClassesSet() + job.JobInfo = JobInfo{} + return job.sync(jobapi.SetInfo, infoClasses...) +} + +// ResetLimit resets given limits of the job object. +func (job *JobObject) ResetLimit(limits ...Limit) error { + return job.applyLimit(false, limits...) +} + +// applyLimits queries required limit information and sets or resets +// the limits specified. +func (job *JobObject) applyLimit(set bool, limits ...Limit) error { + classesSet := make(map[jobapi.JobObjectInformationClass]struct{}) + for _, limit := range limits { + infoClass := resolveRequiredInfoClass(limit) + if _, queried := classesSet[infoClass]; !queried { + if err := job.sync(jobapi.QueryInfo, infoClass); err != nil { + return err + } + } + classesSet[infoClass] = struct{}{} + if set { + limit.set(job) + continue + } + limit.reset(job) + } + + infoClasses := make([]jobapi.JobObjectInformationClass, 0) + for k := range classesSet { + infoClasses = append(infoClasses, k) + } + + return job.sync(jobapi.SetInfo, infoClasses...) +} + +func resolveRequiredInfoClass(limit Limit) jobapi.JobObjectInformationClass { + switch limit.(type) { + default: + return jobapi.JobObjectExtendedLimitInformation + case uiRestriction: + return jobapi.JobObjectBasicUIRestrictions + case cpuLimit: + return jobapi.JobObjectCpuRateControlInformation + case netBandwidthLimit, netDSCPTagLimit: + return jobapi.JobObjectNetRateControlInformation + } +} + +func (job *JobObject) infoPtr(infoClass jobapi.JobObjectInformationClass) interface{} { + switch infoClass { + case jobapi.JobObjectBasicAndIoAccountingInformation: + return &job.AccountingInfo + case jobapi.JobObjectExtendedLimitInformation: + return &job.ExtendedLimits + case jobapi.JobObjectBasicUIRestrictions: + return &job.UIRestrictions + case jobapi.JobObjectCpuRateControlInformation: + return &job.CPURateControl + case jobapi.JobObjectNetRateControlInformation: + return &job.NetRateControl + default: + return nil + } +} + +func (job *JobObject) limitInfoClassesSet() (classes []jobapi.JobObjectInformationClass) { + for _, info := range []struct { + isSet bool + class jobapi.JobObjectInformationClass + }{ + { + job.ExtendedLimits.BasicLimitInformation.LimitFlags > 0, + jobapi.JobObjectExtendedLimitInformation, + }, + { + job.UIRestrictions.UIRestrictionsClass > 0, + jobapi.JobObjectBasicUIRestrictions, + }, + { + job.CPURateControl.ControlFlags > 0, + jobapi.JobObjectCpuRateControlInformation, + }, + { + job.NetRateControl.ControlFlags > 0, + jobapi.JobObjectNetRateControlInformation, + }, + } { + if info.isSet { + classes = append(classes, info.class) + } + } + return classes +} + +type infoClassSync func(syscall.Handle, jobapi.JobObjectInformationClass, interface{}) error + +func (job *JobObject) sync(fn infoClassSync, infoClasses ...jobapi.JobObjectInformationClass) error { + for _, infoClass := range infoClasses { + if err := fn(job.Handle, infoClass, job.infoPtr(infoClass)); err != nil { + return err + } + } + return nil +} diff --git a/vendor/github.com/kolesnikovae/go-winjob/jobapi/README.md b/vendor/github.com/kolesnikovae/go-winjob/jobapi/README.md new file mode 100644 index 00000000..381e11e6 --- /dev/null +++ b/vendor/github.com/kolesnikovae/go-winjob/jobapi/README.md @@ -0,0 +1,14 @@ +# jobapi + +Go bindings for [Windows Job Objects](https://docs.microsoft.com/en-us/windows/win32/procthread/job-objects): +> A job object allows groups of processes to be managed as a unit. Job objects are namable, securable, sharable objects that control attributes of the processes associated with them. Operations performed on a job object affect all processes associated with the job object. Examples include enforcing limits such as working set size and process priority or terminating all processes associated with a job. + +The package holds supplemental types and functions for low-level interactions with the operating system. + +Golang naming convention is sacrificed in favor of straight name mapping: WinAPI uses mixed ALL_CAPS and CaseCamel. To avoid any confusion, naming conforms Microsoft documentation. + +### Limitations + - Sessions/Terminal Services: all processes within a job must run within the same session as the job. An attempt to assign a process from another session will fail with `ERROR_ACCESS_DENIED`. + - [Nested jobs](https://docs.microsoft.com/en-us/windows/win32/procthread/nested-jobs) were introduced in Windows 8 and Windows Server 2012. On Windows 7 `AssignProcessToJob` call will fail with `ERROR_ACCESS_DENIED`, if the process is already assigned to a job. + - IO rate controls had been introduced into api-ms-win-core-job-l2-1-1.dll in 10.0.10240 and removed in 10.0.15063. + - Support for `JOBOBJECT_SECURITY_LIMIT_INFORMATION` was removed starting with Windows Vista. diff --git a/vendor/github.com/kolesnikovae/go-winjob/jobapi/doc.go b/vendor/github.com/kolesnikovae/go-winjob/jobapi/doc.go new file mode 100644 index 00000000..ddda15a2 --- /dev/null +++ b/vendor/github.com/kolesnikovae/go-winjob/jobapi/doc.go @@ -0,0 +1,9 @@ +// +build windows + +// Package jobapi provides supplemental types and functions for low-level +// interactions with the operating system to control job objects. +// +// Golang naming convention is sacrificed in favor of straight name mapping: +// WinAPI uses mixed ALL_CAPS and CaseCamel. To avoid any confusion, naming +// conforms Microsoft documentation. +package jobapi diff --git a/vendor/github.com/kolesnikovae/go-winjob/jobapi/jobapi.go b/vendor/github.com/kolesnikovae/go-winjob/jobapi/jobapi.go new file mode 100644 index 00000000..d6ed4d97 --- /dev/null +++ b/vendor/github.com/kolesnikovae/go-winjob/jobapi/jobapi.go @@ -0,0 +1,638 @@ +//go:build windows +// +build windows + +package jobapi + +import ( + "os" + "reflect" + "syscall" + "unsafe" +) + +var ( + modKernel32 = syscall.NewLazyDLL("kernel32.dll") + openJobObject = modKernel32.NewProc("OpenJobObjectW") + createJobObject = modKernel32.NewProc("CreateJobObjectW") + terminateJobObject = modKernel32.NewProc("TerminateJobObject") + isProcessInJob = modKernel32.NewProc("IsProcessInJob") + assignProcessToJobObject = modKernel32.NewProc("AssignProcessToJobObject") + setInformationJobObject = modKernel32.NewProc("SetInformationJobObject") + queryInformationJobObject = modKernel32.NewProc("QueryInformationJobObject") +) + +// ErrAbandoned specifies that the completion port handle had been closed +// while a GetQueuedCompletionStatus call was outstanding. +// The original error code is ERROR_ABANDONED_WAIT_0 (0x2df). +var ErrAbandoned = syscall.Errno(0x2df) + +// Process Security and Access Rights. +// +// https://docs.microsoft.com/en-us/windows/desktop/procthread/process-security-and-access-rights +const ( + PROCESS_TERMINATE = 0x000001 + PROCESS_DUP_HANDLE = 0x000040 + PROCESS_SET_QUOTA = 0x000100 + PROCESS_SET_INFORMATION = 0x000200 + PROCESS_QUERY_INFORMATION = 0x000400 + PROCESS_QUERY_LIMITED_INFORMATION = 0x001000 + PROCESS_ALL_ACCESS = 0x1F0FFF + PROCESS_VM_OPERATION = 0x000008 + PROCESS_VM_READ = 0x000010 + PROCESS_VM_WRITE = 0x000020 +) + +// Job Object Security and Access Rights. +// +// https://docs.microsoft.com/en-us/windows/desktop/ProcThread/job-object-security-and-access-rights +const ( + JOB_OBJECT_ASSIGN_PROCESS = 1 << iota + JOB_OBJECT_SET_ATTRIBUTES + JOB_OBJECT_QUERY + JOB_OBJECT_TERMINATE + // JOB_OBJECT_SET_SECURITY_ATTRIBUTES flag is not supported. You must set + // security limitations individually for each process associated with a job. + // JOB_OBJECT_SET_SECURITY_ATTRIBUTES // 0x000010 + JOB_OBJECT_ALL_ACCESS = 0x1F001F +) + +// PriorityClass is a priority class of the process. +// +// https://docs.microsoft.com/en-us/windows/desktop/procthread/scheduling-priorities +type PriorityClass uint32 + +// Process priority classes. +const ( + NORMAL_PRIORITY_CLASS PriorityClass = 0x00000020 + IDLE_PRIORITY_CLASS PriorityClass = 0x00000040 + HIGH_PRIORITY_CLASS PriorityClass = 0x00000080 + REALTIME_PRIORITY_CLASS PriorityClass = 0x00000100 + BELOW_NORMAL_PRIORITY_CLASS PriorityClass = 0x00004000 + ABOVE_NORMAL_PRIORITY_CLASS PriorityClass = 0x00008000 + PROCESS_MODE_BACKGROUND_BEGIN PriorityClass = 0x00100000 + PROCESS_MODE_BACKGROUND_END PriorityClass = 0x00200000 +) + +// JobObjectInformationClass is an information class for the limits to be set or queried. +// +// https://docs.microsoft.com/en-us/windows/desktop/api/jobapi2/nf-jobapi2-setinformationjobobject +// https://docs.microsoft.com/en-us/windows/desktop/api/jobapi2/nf-jobapi2-queryinformationjobobject +type JobObjectInformationClass uint32 + +// Job object information classes. +const ( + JobObjectBasicAccountingInformation JobObjectInformationClass = iota + 1 + JobObjectBasicLimitInformation + JobObjectBasicProcessIdList + JobObjectBasicUIRestrictions + JobObjectSecurityLimitInformation + JobObjectEndOfJobTimeInformation + JobObjectAssociateCompletionPortInformation + JobObjectBasicAndIoAccountingInformation + JobObjectExtendedLimitInformation + JobObjectJobSetInformation + JobObjectGroupInformation + JobObjectNotificationLimitInformation + JobObjectLimitViolationInformation + JobObjectGroupInformationEx + JobObjectCpuRateControlInformation + JobObjectCompletionFilter + JobObjectCompletionCounter + JobObjectFreezeInformation + JobObjectExtendedAccountingInformation + JobObjectWakeInformation + JobObjectBackgroundInformation + JobObjectSchedulingRankBiasInformation + JobObjectTimerVirtualizationInformation + JobObjectCycleTimeNotification + JobObjectClearEvent + JobObjectInterferenceInformation + JobObjectClearPeakJobMemoryUsed + JobObjectMemoryUsageInformation + JobObjectSharedCommit + JobObjectContainerId + JobObjectIoRateControlInformation + JobObjectNetRateControlInformation + JobObjectNotificationLimitInformation2 + JobObjectLimitViolationInformation2 + JobObjectCreateSilo + JobObjectSiloBasicInformation + JobObjectSiloRootDirectory + JobObjectServerSiloBasicInformation + JobObjectServerSiloUserSharedData + JobObjectServerSiloInitialize + JobObjectServerSiloRunningState + JobObjectIoAttribution + JobObjectMemoryPartitionInformation + JobObjectContainerTelemetryId + JobObjectSiloSystemRoot + JobObjectEnergyTrackingState + JobObjectThreadImpersonationInformation +) + +// LimitFlag specifies the limit flags that are in effect. This type is a +// bitfield that defines whether other structure members of JOBOBJECT_BASIC_LIMIT_INFORMATION +// are used. +// +// https://docs.microsoft.com/en-us/windows/desktop/api/winnt/ns-winnt-jobobject_basic_limit_information +// https://docs.microsoft.com/en-us/windows/desktop/api/winnt/ns-winnt-jobobject_extended_limit_information +type LimitFlag uint32 + +// Job object limit flags. +const ( + JOB_OBJECT_LIMIT_WORKINGSET LimitFlag = 1 << iota + JOB_OBJECT_LIMIT_PROCESS_TIME + JOB_OBJECT_LIMIT_JOB_TIME + JOB_OBJECT_LIMIT_ACTIVE_PROCESS + JOB_OBJECT_LIMIT_AFFINITY + JOB_OBJECT_LIMIT_PRIORITY_CLASS + JOB_OBJECT_LIMIT_PRESERVE_JOB_TIME + JOB_OBJECT_LIMIT_SCHEDULING_CLASS + JOB_OBJECT_LIMIT_PROCESS_MEMORY + JOB_OBJECT_LIMIT_JOB_MEMORY + JOB_OBJECT_LIMIT_DIE_ON_UNHANDLED_EXCEPTION + JOB_OBJECT_LIMIT_BREAKAWAY_OK + JOB_OBJECT_LIMIT_SILENT_BREAKAWAY_OK + JOB_OBJECT_LIMIT_KILL_ON_JOB_CLOSE + JOB_OBJECT_LIMIT_SUBSET_AFFINITY + JOB_OBJECT_LIMIT_JOB_MEMORY_LOW + JOB_OBJECT_LIMIT_JOB_READ_BYTES + JOB_OBJECT_LIMIT_JOB_WRITE_BYTES + JOB_OBJECT_LIMIT_RATE_CONTROL + JOB_OBJECT_LIMIT_IO_RATE_CONTROL + JOB_OBJECT_LIMIT_NET_RATE_CONTROL + + JOB_OBJECT_LIMIT_CPU_RATE_CONTROL = JOB_OBJECT_LIMIT_RATE_CONTROL + JOB_OBJECT_LIMIT_JOB_MEMORY_HIGH = JOB_OBJECT_LIMIT_JOB_MEMORY +) + +// UIRestrictionsClass is a restriction class for the user interface. +// +// https://docs.microsoft.com/en-us/windows/desktop/api/winnt/ns-winnt-jobobject_basic_ui_restrictions +type UIRestrictionsClass uint32 + +// User-interface restrictions for a job object. +const ( + JOB_OBJECT_UILIMIT_HANDLES UIRestrictionsClass = 1 << iota + JOB_OBJECT_UILIMIT_READCLIPBOARD + JOB_OBJECT_UILIMIT_WRITECLIPBOARD + JOB_OBJECT_UILIMIT_SYSTEMPARAMETERS + JOB_OBJECT_UILIMIT_DISPLAYSETTINGS + JOB_OBJECT_UILIMIT_GLOBALATOMS + JOB_OBJECT_UILIMIT_DESKTOP + JOB_OBJECT_UILIMIT_EXITWINDOWS +) + +// CPUControlFlag is a scheduling policy for CPU rate control. +// +// https://docs.microsoft.com/en-us/windows/desktop/api/winnt/ns-winnt-jobobject_cpu_rate_control_information +type CPUControlFlag uint32 + +// CPU rate control flags. +const ( + JOB_OBJECT_CPU_RATE_CONTROL_ENABLE CPUControlFlag = 1 << iota + JOB_OBJECT_CPU_RATE_CONTROL_WEIGHT_BASED + JOB_OBJECT_CPU_RATE_CONTROL_HARD_CAP + JOB_OBJECT_CPU_RATE_CONTROL_NOTIFY + JOB_OBJECT_CPU_RATE_CONTROL_MIN_MAX_RATE +) + +// https://docs.microsoft.com/en-us/windows/desktop/api/winnt/ns-winnt-jobobject_associate_completion_port +type CompletionPortMessage uint32 + +// Job object completion port message types. +const ( + JOB_OBJECT_MSG_END_OF_JOB_TIME CompletionPortMessage = iota + 1 + JOB_OBJECT_MSG_END_OF_PROCESS_TIME + JOB_OBJECT_MSG_ACTIVE_PROCESS_LIMIT + JOB_OBJECT_MSG_ACTIVE_PROCESS_ZERO + _ + JOB_OBJECT_MSG_NEW_PROCESS + JOB_OBJECT_MSG_EXIT_PROCESS + JOB_OBJECT_MSG_ABNORMAL_EXIT_PROCESS + JOB_OBJECT_MSG_PROCESS_MEMORY_LIMIT + JOB_OBJECT_MSG_JOB_MEMORY_LIMIT + JOB_OBJECT_MSG_NOTIFICATION_LIMIT + JOB_OBJECT_MSG_JOB_CYCLE_TIME_LIMIT + JOB_OBJECT_MSG_SILO_TERMINATED + + JOB_OBJECT_MSG_MINIMUM = JOB_OBJECT_MSG_END_OF_JOB_TIME + JOB_OBJECT_MSG_MAXIMUM = JOB_OBJECT_MSG_SILO_TERMINATED +) + +// EndOfJobTimeAction specifies the action that the system will perform when +// the end-of-job time limit has been exceeded. +// +// https://docs.microsoft.com/en-us/windows/desktop/api/winnt/ns-winnt-jobobject_end_of_job_time_information +type EndOfJobTimeAction uint32 + +// End-of-time actions. +const ( + JOB_OBJECT_TERMINATE_AT_END_OF_JOB EndOfJobTimeAction = iota + JOB_OBJECT_POST_AT_END_OF_JOB +) + +// https://docs.microsoft.com/en-us/windows/desktop/api/winnt/ns-winnt-jobobject_notification_limit_information +// https://docs.microsoft.com/en-us/windows/desktop/api/winnt/ns-winnt-jobobject_notification_limit_information_2 +type JOBOBJECT_RATE_CONTROL_TOLERANCE uint32 + +// Rate control tolerance levels. +const ( + ToleranceLow JOBOBJECT_RATE_CONTROL_TOLERANCE = iota + 1 + ToleranceMedium + ToleranceHigh +) + +// https://docs.microsoft.com/en-us/windows/desktop/api/winnt/ns-winnt-jobobject_notification_limit_information +// https://docs.microsoft.com/en-us/windows/desktop/api/winnt/ns-winnt-jobobject_notification_limit_information_2 +type JOBOBJECT_RATE_CONTROL_TOLERANCE_INTERVAL uint32 + +// Rate control tolerance intervals. +const ( + ToleranceIntervalShort JOBOBJECT_RATE_CONTROL_TOLERANCE_INTERVAL = iota + 1 + ToleranceIntervalMedium + ToleranceIntervalLong +) + +// JOBOBJECT_BASIC_LIMIT_INFORMATION contains basic limit information for a job object. +// +// https://docs.microsoft.com/en-us/windows/desktop/api/winnt/ns-winnt-jobobject_basic_limit_information +type JOBOBJECT_BASIC_LIMIT_INFORMATION struct { + PerProcessUserTimeLimit int64 + PerJobUserTimeLimit int64 + LimitFlags LimitFlag + MinimumWorkingSetSize uintptr + MaximumWorkingSetSize uintptr + ActiveProcessLimit uint32 + Affinity uintptr + PriorityClass PriorityClass + SchedulingClass uint32 +} + +// JOBOBJECT_BASIC_UI_RESTRICTIONS contains basic user-interface restrictions for a job object. +// +// https://docs.microsoft.com/en-us/windows/desktop/api/winnt/ns-winnt-jobobject_basic_ui_restrictions +type JOBOBJECT_BASIC_UI_RESTRICTIONS struct { + UIRestrictionsClass +} + +// JOBOBJECT_BASIC_AND_IO_ACCOUNTING_INFORMATION contains basic accounting +// and I/O accounting information for a job object. +// +// https://docs.microsoft.com/en-us/windows/desktop/api/winnt/ns-winnt-jobobject_basic_and_io_accounting_information +type JOBOBJECT_BASIC_AND_IO_ACCOUNTING_INFORMATION struct { + JOBOBJECT_BASIC_ACCOUNTING_INFORMATION + IO_COUNTERS +} + +// JOBOBJECT_BASIC_ACCOUNTING_INFORMATION contains basic accounting information for a job object. +// +// https://docs.microsoft.com/en-us/windows/desktop/api/winnt/ns-winnt-jobobject_basic_accounting_information +type JOBOBJECT_BASIC_ACCOUNTING_INFORMATION struct { + TotalUserTime uint64 + TotalKernelTime uint64 + ThisPeriodTotalUserTime uint64 + ThisPeriodTotalKernelTime uint64 + TotalPageFaultCount uint32 + TotalProcesses uint32 + ActiveProcesses uint32 + TotalTerminatedProcesses uint32 +} + +// IO_COUNTERS contains I/O accounting information for a process or a job +// object. For a job object, the counters include all operations performed +// by all processes that have ever been associated with the job, in addition to +// all processes currently associated with the job. +// +// https://docs.microsoft.com/en-us/windows/desktop/api/winnt/ns-winnt-io_counters +type IO_COUNTERS struct { + ReadOperationCount uint64 + WriteOperationCount uint64 + OtherOperationCount uint64 + ReadTransferCount uint64 + WriteTransferCount uint64 + OtherTransferCount uint64 +} + +// JOBOBJECT_BASIC_PROCESS_ID_LIST contains the process identifier list for +// a job object. If the job is nested, the process identifier list consists +// of all processes associated with the job and its child jobs. +// +// https://docs.microsoft.com/en-us/windows/desktop/api/winnt/ns-winnt-jobobject_basic_process_id_list +type JOBOBJECT_BASIC_PROCESS_ID_LIST struct { + NumberOfAssignedProcesses uint32 + NumberOfProcessIdsInList uint32 + ProcessIDList uintptr +} + +// JOBOBJECT_CPU_RATE_CONTROL_INFORMATION contains CPU rate control information +// for a job object. The original structure contains a union that was replaced +// with a single Value member. +// +// https://docs.microsoft.com/en-us/windows/desktop/api/winnt/ns-winnt-jobobject_cpu_rate_control_information +type JOBOBJECT_CPU_RATE_CONTROL_INFORMATION struct { + ControlFlags CPUControlFlag + Value uint32 +} + +// JOBOBJECT_NET_RATE_CONTROL_INFORMATION contains information used to control +// the network traffic for a job. This structure is used by the +// SetInformationJobObject and QueryInformationJobObject functions with the +// JobObjectNetRateControlInformation information class. +// +// https://docs.microsoft.com/en-us/windows/win32/api/winnt/ns-winnt-jobobject_net_rate_control_information. +type JOBOBJECT_NET_RATE_CONTROL_INFORMATION struct { + MaxBandwidth uint64 + ControlFlags JOB_OBJECT_NET_RATE_CONTROL_FLAGS + DscpTag byte + _ [3]byte +} + +type JOB_OBJECT_NET_RATE_CONTROL_FLAGS uint32 + +const ( + JOB_OBJECT_NET_RATE_CONTROL_ENABLE JOB_OBJECT_NET_RATE_CONTROL_FLAGS = 1 << iota + JOB_OBJECT_NET_RATE_CONTROL_MAX_BANDWIDTH + JOB_OBJECT_NET_RATE_CONTROL_DSCP_TAG + JOB_OBJECT_NET_RATE_CONTROL_VALID_FLAGS JOB_OBJECT_NET_RATE_CONTROL_FLAGS = 7 +) + +// JOBOBJECT_END_OF_JOB_TIME_INFORMATION specifies the action the system will +// perform when an end-of-job time limit is exceeded. +// +// https://docs.microsoft.com/en-us/windows/desktop/api/winnt/ns-winnt-jobobject_end_of_job_time_information +type JOBOBJECT_END_OF_JOB_TIME_INFORMATION struct { + EndOfJobTimeAction EndOfJobTimeAction +} + +// JOBOBJECT_ASSOCIATE_COMPLETION_PORT contains information used to associate +// a completion port with a job. You can associate one completion port with a job. +// +// https://docs.microsoft.com/en-us/windows/desktop/api/winnt/ns-winnt-jobobject_associate_completion_port +type JOBOBJECT_ASSOCIATE_COMPLETION_PORT struct { + CompletionKey syscall.Handle + CompletionPort syscall.Handle +} + +// https://docs.microsoft.com/en-us/windows/desktop/api/winnt/ns-winnt-jobobject_notification_limit_information +type JOBOBJECT_NOTIFICATION_LIMIT_INFORMATION struct { + IoReadBytesLimit uint64 + IoWriteBytesLimit uint64 + PerJobUserTimeLimit int64 + JobMemoryLimit uint64 + RateControlTolerance JOBOBJECT_RATE_CONTROL_TOLERANCE + RateControlToleranceInterval JOBOBJECT_RATE_CONTROL_TOLERANCE_INTERVAL + LimitFlags LimitFlag +} + +// https://docs.microsoft.com/en-us/windows/desktop/api/winnt/ns-winnt-jobobject_notification_limit_information_2 +type JOBOBJECT_NOTIFICATION_LIMIT_INFORMATION_2 struct { + IoReadBytesLimit uint64 + IoWriteBytesLimit uint64 + PerJobUserTimeLimit int64 + JobHighMemoryLimit uint64 + CpuRateControlTolerance JOBOBJECT_RATE_CONTROL_TOLERANCE + CpuRateControlToleranceInterval JOBOBJECT_RATE_CONTROL_TOLERANCE_INTERVAL + LimitFlags LimitFlag + IoRateControlTolerance JOBOBJECT_RATE_CONTROL_TOLERANCE + JobLowMemoryLimit uint64 + IoRateControlToleranceInterval JOBOBJECT_RATE_CONTROL_TOLERANCE_INTERVAL + NetRateControlTolerance JOBOBJECT_RATE_CONTROL_TOLERANCE + NetRateControlToleranceInterval JOBOBJECT_RATE_CONTROL_TOLERANCE_INTERVAL +} + +// https://docs.microsoft.com/en-us/windows/desktop/api/winnt/ns-winnt-jobobject_limit_violation_information +type JOBOBJECT_LIMIT_VIOLATION_INFORMATION struct { + LimitFlags LimitFlag + ViolationLimitFlags LimitFlag + IoReadBytes uint64 + IoReadBytesLimit uint64 + IoWriteBytes uint64 + IoWriteBytesLimit uint64 + PerJobUserTime int64 + PerJobUserTimeLimit int64 + JobMemory uint64 + JobMemoryLimit uint64 + RateControlTolerance JOBOBJECT_RATE_CONTROL_TOLERANCE + RateControlToleranceLimit JOBOBJECT_RATE_CONTROL_TOLERANCE +} + +// https://docs.microsoft.com/en-us/windows/desktop/api/winnt/ns-winnt-jobobject_limit_violation_information_2 +type JOBOBJECT_LIMIT_VIOLATION_INFORMATION_2 struct { + LimitFlags LimitFlag + ViolationLimitFlags LimitFlag + IoReadBytes uint64 + IoReadBytesLimit uint64 + IoWriteBytes uint64 + IoWriteBytesLimit uint64 + PerJobUserTime uint64 + PerJobUserTimeLimit uint64 + JobMemory uint64 + JobHighMemoryLimit uint64 + CpuRateControlTolerance JOBOBJECT_RATE_CONTROL_TOLERANCE + CpuRateControlToleranceLimit JOBOBJECT_RATE_CONTROL_TOLERANCE + JobLowMemoryLimit uint64 + IORateControlTolerance JOBOBJECT_RATE_CONTROL_TOLERANCE + IORateControlToleranceLimit JOBOBJECT_RATE_CONTROL_TOLERANCE + NetRateControlTolerance JOBOBJECT_RATE_CONTROL_TOLERANCE + NetRateControlToleranceLimit JOBOBJECT_RATE_CONTROL_TOLERANCE +} + +// IsProcessInJob determines whether the process is running in a job object. +// +// https://docs.microsoft.com/en-us/windows/desktop/api/jobapi/nf-jobapi-isprocessinjob +func IsProcessInJob(hProcess, hJobObject syscall.Handle) (bool, error) { + var found bool + ret, _, lastErr := isProcessInJob.Call( + uintptr(hProcess), + uintptr(hJobObject), + uintptr(unsafe.Pointer(&found))) + if ret == 0 { + return found, os.NewSyscallError("IsProcessInJob", lastErr) + } + return found, nil +} + +// OpenJobObject opens an existing job object. +// +// https://docs.microsoft.com/en-us/windows/desktop/api/jobapi2/nf-jobapi2-openjobobjectw +func OpenJobObject(desiredAccess, inheritHandles uintptr, jobName string) (syscall.Handle, error) { + n, err := syscall.UTF16PtrFromString(jobName) + if err != nil { + return syscall.InvalidHandle, err + } + h, _, lastErr := openJobObject.Call( + desiredAccess, + inheritHandles, + uintptr(unsafe.Pointer(n))) + if h == 0 { + return syscall.InvalidHandle, os.NewSyscallError("OpenJobObject", lastErr) + } + return syscall.Handle(h), nil +} + +// CreateJobObject creates or opens a job object. +// +// https://docs.microsoft.com/en-us/windows/desktop/api/jobapi2/nf-jobapi2-createjobobjectw +func CreateJobObject(jobName string, sa *syscall.SecurityAttributes) (syscall.Handle, error) { + n, err := syscall.UTF16PtrFromString(jobName) + if err != nil { + return syscall.InvalidHandle, err + } + h, _, lastErr := createJobObject.Call( + uintptr(unsafe.Pointer(sa)), + uintptr(unsafe.Pointer(n))) + if h == 0 { + return syscall.InvalidHandle, os.NewSyscallError("CreateJobObject", lastErr) + } + return syscall.Handle(h), nil +} + +// TerminateJobObject terminates all processes currently associated with the +// job and removes the job object. exitCode it the exit code to be used by +// all processes and threads in the job object. +// +// https://docs.microsoft.com/en-us/windows/desktop/api/jobapi2/nf-jobapi2-terminatejobobject +func TerminateJobObject(hJobObject syscall.Handle, exitCode uint32) error { + ret, _, lastErr := terminateJobObject.Call( + uintptr(hJobObject), + uintptr(exitCode)) + if ret == 0 { + return os.NewSyscallError("TerminateJobObject", lastErr) + } + return nil +} + +// AssignProcessToJobObject assigns a process to an existing job object. +// +// https://docs.microsoft.com/en-us/windows/desktop/api/jobapi2/nf-jobapi2-assignprocesstojobobject +func AssignProcessToJobObject(hJobObject, hProcess syscall.Handle) error { + ret, _, lastErr := assignProcessToJobObject.Call( + uintptr(hJobObject), + uintptr(hProcess)) + if ret == 0 { + return os.NewSyscallError("AssignProcessToJobObject", lastErr) + } + return nil +} + +// QueryInformationJobObject retrieves limit and job state information for a job object. +// +// https://docs.microsoft.com/en-us/windows/desktop/api/jobapi2/nf-jobapi2-queryinformationjobobject +func QueryInformationJobObject( + hJobObject syscall.Handle, + infoClass JobObjectInformationClass, + jobObjectInfo unsafe.Pointer, + length uint32, + retLen unsafe.Pointer) error { + ret, _, lastErr := queryInformationJobObject.Call( + uintptr(hJobObject), + uintptr(infoClass), + uintptr(jobObjectInfo), + uintptr(length), + uintptr(retLen)) + if ret == 0 { + return os.NewSyscallError("QueryInformationJobObject", lastErr) + } + return nil +} + +// SetInformationJobObject sets information for a job object. +// +// https://docs.microsoft.com/en-us/windows/desktop/api/jobapi2/nf-jobapi2-setinformationjobobject +func SetInformationJobObject( + hJobObject syscall.Handle, + infoClass JobObjectInformationClass, + jobObjectInfo unsafe.Pointer, + length uint32) error { + ret, _, lastErr := setInformationJobObject.Call( + uintptr(hJobObject), + uintptr(infoClass), + uintptr(jobObjectInfo), + uintptr(length)) + if ret == 0 { + return os.NewSyscallError("SetInformationJobObject", lastErr) + } + return nil +} + +// QueryInfo performs QueryInformationJobObject call for the information class specified. +// A pointer to the appropriate information type must be provided. +func QueryInfo(hJobObject syscall.Handle, infoClass JobObjectInformationClass, v interface{}) error { + var retLen uint32 + return QueryInformationJobObject(hJobObject, infoClass, + unsafe.Pointer(reflect.ValueOf(v).Pointer()), + uint32(reflect.TypeOf(v).Elem().Size()), + unsafe.Pointer(&retLen)) +} + +// QueryInfo performs SetInformationJobObject call for the information class specified. +// A pointer to the appropriate information type must be provided. +func SetInfo(hJobObject syscall.Handle, infoClass JobObjectInformationClass, v interface{}) error { + return SetInformationJobObject(hJobObject, infoClass, + unsafe.Pointer(reflect.ValueOf(v).Pointer()), + uint32(reflect.TypeOf(v).Elem().Size())) +} + +// MakeSA creates a SECURITY_ATTRIBUTES structure that specifies the +// security descriptor for the job object and determines that child +// processes can not inherit the handle. +// +// https://docs.microsoft.com/en-us/previous-versions/windows/desktop/legacy/aa379560(v=vs.85) +func MakeSA() *syscall.SecurityAttributes { + var sa syscall.SecurityAttributes + sa.Length = uint32(unsafe.Sizeof(sa)) + sa.InheritHandle = 0 + return &sa +} + +// AssociateCompletionPort associates a job object with a completion port. +// The system sends messages to the I/O completion port associated with a job +// when certain events occur. If the job is nested, the message is sent to +// every I/O completion port associated with any job in the parent job chain of +// the job that triggered the message. +// +// https://docs.microsoft.com/en-us/windows/desktop/api/winnt/ns-winnt-jobobject_associate_completion_port +func AssociateCompletionPort(hJobObject, hPort syscall.Handle) error { + jacp := JOBOBJECT_ASSOCIATE_COMPLETION_PORT{ + CompletionKey: hJobObject, + CompletionPort: hPort, + } + err := SetInformationJobObject( + hJobObject, + JobObjectAssociateCompletionPortInformation, + unsafe.Pointer(&jacp), + uint32(unsafe.Sizeof(jacp))) + if err != nil { + return os.NewSyscallError("SetInformationJobObject", err) + } + return err +} + +// GetQueuedCompletionStatus attempts to dequeue an I/O completion packet from +// the specified I/O completion port. If there is no completion packet queued, +// the function waits for a pending I/O operation associated with the +// completion port to complete. +// +// Timout is the number of milliseconds that the caller is willing to wait for +// a completion packet to appear at the completion port. If a completion packet +// does not appear within the specified time, the function times out. For +// infinite timeout syscall.INFINITE should be used. +// +// https://docs.microsoft.com/en-us/windows/desktop/api/winnt/ns-winnt-jobobject_associate_completion_port +func GetQueuedCompletionStatus(hPort syscall.Handle, timeout uint32) (mType uint32, pid uintptr, err error) { + var ( + completionKey uint32 + overlapped *syscall.Overlapped + ) + err = syscall.GetQueuedCompletionStatus( + hPort, + &mType, + &completionKey, + &overlapped, + timeout) + if err != nil { + return 0, 0, os.NewSyscallError("GetQueuedCompletionStatus", err) + } + return mType, uintptr(unsafe.Pointer(overlapped)), nil +} diff --git a/vendor/github.com/kolesnikovae/go-winjob/limits.go b/vendor/github.com/kolesnikovae/go-winjob/limits.go new file mode 100644 index 00000000..f3fb7ae2 --- /dev/null +++ b/vendor/github.com/kolesnikovae/go-winjob/limits.go @@ -0,0 +1,453 @@ +//go:build windows +// +build windows + +package winjob + +import ( + "time" + + "github.com/kolesnikovae/go-winjob/jobapi" +) + +// WithBreakawayOK allows any process associated with the job to create child +// processes that are not associated with the job, if the process created with +// CREATE_BREAKAWAY_FROM_JOB flag. +func WithBreakawayOK() Limit { + return LimitBreakawayOK +} + +// WithSilentBreakawayOK allows any process associated with the job to create +// child processes that are not associated with the job. If the job is nested +// and its immediate job object allows breakaway, the child process breaks away +// from the immediate job object and from each job in the parent job chain, +// moving up the hierarchy until it reaches a job that does not permit breakaway. +// If the immediate job object does not allow breakaway, the child process does +// not break away even if jobs in its parent job chain allow it. +func WithSilentBreakawayOK() Limit { + return LimitSilentBreakawayOK +} + +// WithDieOnUnhandledException forces a call to the SetErrorMode function with +// the SEM_NOGPFAULTERRORBOX flag for each process associated with the job. +// +// If an exception occurs and the system calls the UnhandledExceptionFilter +// function, the debugger will be given a chance to act. If there is no +// debugger, the functions returns EXCEPTION_EXECUTE_HANDLER. Normally, this +// will cause termination of the process with the exception code as the exit +// status. +func WithDieOnUnhandledException() Limit { + return LimitDieOnUnhandledException +} + +// WithKillOnJobClose causes all processes associated with the job to terminate +// when the last handle to the job is closed. +func WithKillOnJobClose() Limit { + return LimitKillOnJobClose +} + +// WithPreserveJobTime preserves any job time limits you previously set. As +// long as this limit is set, you can establish a per-job time limit once, then +// alter other limits in subsequent calls. +// +// This flag cannot be used with LimitJobMemory. +func WithPreserveJobTime() Limit { + return LimitPreserveJobTime +} + +// WithSubsetAffinity allows processes to use a subset of the processor +// affinity for all processes associated with the job. +// +// This limit must be combined with LimitAffinity. +func WithSubsetAffinity() Limit { + return LimitSubsetAffinity +} + +// WithAffinity causes all processes associated with the job to use the same +// processor affinity. +// +// The value specified must be a subset of the system affinity mask obtained by +// calling the GetProcessAffinityMask function. The affinity of each thread is +// set to this value, but threads are free to subsequently set their affinity, +// as long as it is a subset of the specified affinity mask. Processes cannot +// set their own affinity mask. +// +// A process affinity mask is a bit vector in which each bit represents the +// processors that a process is allowed to run on. A system affinity mask is a +// bit vector in which each bit represents the processors that are configured +// into a system. +// +// A process affinity mask is a subset of the system affinity mask. A process +// is only allowed to run on the processors configured into a system. +// Therefore, the process affinity mask cannot specify a 1 bit for a processor +// when the system affinity mask specifies a 0 bit for that processor. +// +// If the job is nested, the specified processor affinity must be a subset of +// the effective affinity of the parent job. If the specified affinity a +// superset of the affinity of the parent job, it is ignored and the affinity +// of the parent job is used. +// +// This limit must be combined with LimitSubsetAffinity. +func WithAffinity(x uintptr) Limit { + return LimitAffinity.WithValue(x) +} + +// WithJobMemoryLimit causes all processes associated with the job to limit the +// job-wide sum of their committed memory. When a process attempts to commit +// memory that would exceed the job-wide limit, it fails. +// +// The value specifies the limit for the virtual memory that can be committed +// for the job object in bytes. +// +// If the job object is associated with a completion port, a +// JOB_OBJECT_MSG_JOB_MEMORY_LIMIT message is sent to the completion port. +func WithJobMemoryLimit(x uintptr) Limit { + return LimitJobMemory.WithValue(x) +} + +// WithJobTimeLimit establishes a user-mode execution time limit for the job. +// +// The system adds the current time of the processes associated with the job to +// this limit. For example, if you set this limit to 1 minute, and the job has +// a process that has accumulated 5 minutes of user-mode time, the limit +// actually enforced is 6 minutes. +// +// The system periodically checks to determine whether the sum of the user-mode +// execution time for all processes is greater than this end-of-job limit. +// By default, all processes are terminated and the status code is set to +// ERROR_NOT_ENOUGH_QUOTA. +func WithJobTimeLimit(x time.Duration) Limit { + return LimitJobTime.WithValue(x) +} + +// WithProcessMemoryLimit causes all processes associated with the job to limit +// their committed memory. When a process attempts to commit memory that would +// exceed the per-process limit, it fails. +// +// If the job object is associated with a completion port, a +// JOB_OBJECT_MSG_PROCESS_MEMORY_LIMIT message is sent to the completion port. +// +// If the job is nested, the effective memory limit is the most restrictive +// memory limit in the job chain. +func WithProcessMemoryLimit(x uintptr) Limit { + return LimitProcessMemory.WithValue(x) +} + +// WithProcessTimeLimit establishes a user-mode execution time limit for each +// currently active process and for all future processes associated with the +// job. +// +// The system periodically checks to determine whether each process associated +// with the job has accumulated more user-mode time than the set limit. If it +// has, the process is terminated. +// +// If the job is nested, the effective limit is the most restrictive limit in +// the job chain. +func WithProcessTimeLimit(x time.Duration) Limit { + return LimitProcessTime.WithValue(x) +} + +// WithActiveProcessLimit establishes a maximum number of simultaneously active +// processes associated with the job. The ActiveProcessLimit member contains +// additional information. +// +// If you try to associate a process with a job, and this causes the active +// process count to exceed this limit, the process is terminated and the +// association fails. +func WithActiveProcessLimit(x uint32) Limit { + return LimitActiveProcess.WithValue(x) +} + +// WithWorkingSetLimit causes all processes associated with the job to use the +// same minimum and maximum working set sizes (specified in bytes). +// +// If maximum working set size is nonzero, minimum working set cannot be zero, +// and vice-versa. The actual limit values can be retrieved with +// MinWorkingSetSize() and MaxWorkingSetSize() methods of LimitWorkingSet. +// +// If the job is nested, the effective working set size is the smallest +// working set size in the job chain. +// +// Note: processes can still empty their working sets using +// SetProcessWorkingSetSize, even when is used. However, you cannot use +// SetProcessWorkingSetSize change the minimum or maximum working set size +// of a process in a job object. +func WithWorkingSetLimit(min, max uintptr) Limit { + return LimitWorkingSet.WithValue(min, max) +} + +// WithPriorityClassLimit causes all processes associated with the job to use +// the same priority class. +// +// If the job is nested, the effective priority class is the lowest priority +// class in the job chain. +// +// Processes and threads cannot modify their priority class. The calling +// process must enable the SE_INC_BASE_PRIORITY_NAME privilege. +func WithPriorityClassLimit(x jobapi.PriorityClass) Limit { + return LimitPriorityClass.WithValue(x) +} + +// WithSchedulingClassLimit causes all processes in the job to use the same +// scheduling class. +// +// If the job is nested, the effective scheduling class is the lowest +// scheduling class in the job chain. +// +// The valid values are 0 to 9. Use 0 for the least favorable scheduling class +// relative to other threads, and 9 for the most favorable scheduling class +// relative to other threads. By default, this value is 5. To use a scheduling +// class greater than 5, the calling process must enable the +// SE_INC_BASE_PRIORITY_NAME privilege. +func WithSchedulingClassLimit(x uint32) Limit { + return LimitSchedulingClass.WithValue(x) +} + +var ( + LimitBreakawayOK = basicLimit(jobapi.JOB_OBJECT_LIMIT_BREAKAWAY_OK) + LimitDieOnUnhandledException = basicLimit(jobapi.JOB_OBJECT_LIMIT_DIE_ON_UNHANDLED_EXCEPTION) + LimitKillOnJobClose = basicLimit(jobapi.JOB_OBJECT_LIMIT_KILL_ON_JOB_CLOSE) + LimitPreserveJobTime = basicLimit(jobapi.JOB_OBJECT_LIMIT_PRESERVE_JOB_TIME) + LimitSubsetAffinity = basicLimit(jobapi.JOB_OBJECT_LIMIT_SUBSET_AFFINITY) + LimitSilentBreakawayOK = basicLimit(jobapi.JOB_OBJECT_LIMIT_SILENT_BREAKAWAY_OK) + + LimitAffinity = affinityLimit{basicLimit: basicLimit(jobapi.JOB_OBJECT_LIMIT_AFFINITY)} + LimitJobMemory = jobMemoryLimit{basicLimit: basicLimit(jobapi.JOB_OBJECT_LIMIT_JOB_MEMORY)} + LimitJobTime = jobTimeLimit{basicLimit: basicLimit(jobapi.JOB_OBJECT_LIMIT_JOB_TIME)} + LimitProcessMemory = processMemoryLimit{basicLimit: basicLimit(jobapi.JOB_OBJECT_LIMIT_PROCESS_MEMORY)} + LimitProcessTime = processTimeLimit{basicLimit: basicLimit(jobapi.JOB_OBJECT_LIMIT_PROCESS_TIME)} + LimitActiveProcess = activeProcessLimit{basicLimit: basicLimit(jobapi.JOB_OBJECT_LIMIT_ACTIVE_PROCESS)} + LimitWorkingSet = workingSetLimit{basicLimit: basicLimit(jobapi.JOB_OBJECT_LIMIT_WORKINGSET)} + LimitPriorityClass = priorityClassLimit{basicLimit: basicLimit(jobapi.JOB_OBJECT_LIMIT_PRIORITY_CLASS)} + LimitSchedulingClass = schedulingClassLimit{basicLimit: basicLimit(jobapi.JOB_OBJECT_LIMIT_SCHEDULING_CLASS)} +) + +type basicLimit jobapi.LimitFlag + +func (l basicLimit) set(job *JobObject) { + job.ExtendedLimits.BasicLimitInformation.LimitFlags |= uint32(l) +} + +func (l basicLimit) reset(job *JobObject) { + job.ExtendedLimits.BasicLimitInformation.LimitFlags &^= uint32(l) +} + +func (l basicLimit) IsSet(job *JobObject) bool { + return job.ExtendedLimits.BasicLimitInformation.LimitFlags&uint32(l) > 0 +} + +func (l basicLimit) Value(job *JobObject) interface{} { + return l.IsSet(job) +} + +type affinityLimit struct { + basicLimit + affinity uintptr +} + +func (l affinityLimit) WithValue(x uintptr) affinityLimit { + l.affinity = x + return l +} + +func (l affinityLimit) LimitValue(job *JobObject) uintptr { + return job.ExtendedLimits.BasicLimitInformation.Affinity +} + +func (l affinityLimit) set(job *JobObject) { + job.ExtendedLimits.BasicLimitInformation.Affinity = l.affinity + l.basicLimit.set(job) +} + +func (l affinityLimit) Value(job *JobObject) interface{} { + return l.LimitValue(job) +} + +type jobMemoryLimit struct { + basicLimit + jobMemory uintptr +} + +func (l jobMemoryLimit) WithValue(x uintptr) jobMemoryLimit { + l.jobMemory = x + return l +} + +func (l jobMemoryLimit) LimitValue(job *JobObject) uintptr { + return job.ExtendedLimits.JobMemoryLimit +} + +func (l jobMemoryLimit) set(job *JobObject) { + job.ExtendedLimits.JobMemoryLimit = l.jobMemory + l.basicLimit.set(job) +} + +func (l jobMemoryLimit) Value(job *JobObject) interface{} { + return l.LimitValue(job) +} + +type jobTimeLimit struct { + basicLimit + jobTime int64 +} + +// Time limits and counters are specified in 100-nanosecond ticks. +const timeFraction = 100 + +func (l jobTimeLimit) WithValue(x time.Duration) jobTimeLimit { + l.jobTime = x.Nanoseconds() / timeFraction + return l +} + +func (l jobTimeLimit) LimitValue(job *JobObject) time.Duration { + return time.Duration(job.ExtendedLimits.BasicLimitInformation.PerJobUserTimeLimit * timeFraction) +} + +func (l jobTimeLimit) set(job *JobObject) { + job.ExtendedLimits.BasicLimitInformation.PerJobUserTimeLimit = l.jobTime + l.basicLimit.set(job) +} + +func (l jobTimeLimit) Value(job *JobObject) interface{} { + return l.LimitValue(job) +} + +type processMemoryLimit struct { + basicLimit + processMemory uintptr +} + +func (l processMemoryLimit) WithValue(x uintptr) processMemoryLimit { + l.processMemory = x + return l +} + +func (l processMemoryLimit) LimitValue(job *JobObject) uintptr { + return job.ExtendedLimits.ProcessMemoryLimit +} + +func (l processMemoryLimit) set(job *JobObject) { + job.ExtendedLimits.ProcessMemoryLimit = l.processMemory + l.basicLimit.set(job) +} + +func (l processMemoryLimit) Value(job *JobObject) interface{} { + return l.LimitValue(job) +} + +type processTimeLimit struct { + basicLimit + processTime int64 +} + +func (l processTimeLimit) WithValue(x time.Duration) processTimeLimit { + l.processTime = x.Nanoseconds() / timeFraction + return l +} + +func (l processTimeLimit) LimitValue(job *JobObject) time.Duration { + return time.Duration(job.ExtendedLimits.BasicLimitInformation.PerProcessUserTimeLimit * timeFraction) +} + +func (l processTimeLimit) set(job *JobObject) { + job.ExtendedLimits.BasicLimitInformation.PerProcessUserTimeLimit = l.processTime + l.basicLimit.set(job) +} + +func (l processTimeLimit) Value(job *JobObject) interface{} { + return l.LimitValue(job) +} + +type activeProcessLimit struct { + basicLimit + procs uint32 +} + +func (l activeProcessLimit) WithValue(x uint32) activeProcessLimit { + l.procs = x + return l +} + +func (l activeProcessLimit) LimitValue(job *JobObject) uint32 { + return job.ExtendedLimits.BasicLimitInformation.ActiveProcessLimit +} + +func (l activeProcessLimit) set(job *JobObject) { + job.ExtendedLimits.BasicLimitInformation.ActiveProcessLimit = uint32(l.procs) + l.basicLimit.set(job) +} + +func (l activeProcessLimit) Value(job *JobObject) interface{} { + return l.LimitValue(job) +} + +type workingSetLimit struct { + basicLimit + wsMin uintptr + wsMax uintptr +} + +func (l workingSetLimit) WithValue(min, max uintptr) workingSetLimit { + l.wsMin = min + l.wsMax = max + return l +} + +func (l workingSetLimit) MinWorkingSetSize(job *JobObject) uintptr { + return job.ExtendedLimits.BasicLimitInformation.MinimumWorkingSetSize +} + +func (l workingSetLimit) MaxWorkingSetSize(job *JobObject) uintptr { + return job.ExtendedLimits.BasicLimitInformation.MaximumWorkingSetSize +} + +func (l workingSetLimit) set(job *JobObject) { + job.ExtendedLimits.BasicLimitInformation.MinimumWorkingSetSize = l.wsMin + job.ExtendedLimits.BasicLimitInformation.MaximumWorkingSetSize = l.wsMax + l.basicLimit.set(job) +} + +type priorityClassLimit struct { + basicLimit + prio jobapi.PriorityClass +} + +func (l priorityClassLimit) WithValue(x jobapi.PriorityClass) priorityClassLimit { + l.prio = x + return l +} + +func (l priorityClassLimit) LimitValue(job *JobObject) jobapi.PriorityClass { + return jobapi.PriorityClass(job.ExtendedLimits.BasicLimitInformation.PriorityClass) +} + +func (l priorityClassLimit) set(job *JobObject) { + job.ExtendedLimits.BasicLimitInformation.PriorityClass = uint32(l.prio) + l.basicLimit.set(job) +} + +func (l priorityClassLimit) Value(job *JobObject) interface{} { + return l.LimitValue(job) +} + +type schedulingClassLimit struct { + basicLimit + schedClass uint32 +} + +func (l schedulingClassLimit) WithValue(x uint32) schedulingClassLimit { + l.schedClass = x + return l +} + +func (l schedulingClassLimit) LimitValue(job *JobObject) uint32 { + return job.ExtendedLimits.BasicLimitInformation.SchedulingClass +} + +func (l schedulingClassLimit) set(job *JobObject) { + job.ExtendedLimits.BasicLimitInformation.SchedulingClass = l.schedClass + l.basicLimit.set(job) +} + +func (l schedulingClassLimit) Value(job *JobObject) interface{} { + return l.LimitValue(job) +} diff --git a/vendor/github.com/kolesnikovae/go-winjob/limits_cpu.go b/vendor/github.com/kolesnikovae/go-winjob/limits_cpu.go new file mode 100644 index 00000000..2a933bd8 --- /dev/null +++ b/vendor/github.com/kolesnikovae/go-winjob/limits_cpu.go @@ -0,0 +1,110 @@ +//go:build windows +// +build windows + +package winjob + +import ( + "bytes" + "encoding/binary" + + "github.com/kolesnikovae/go-winjob/jobapi" +) + +// WithCPUHardCapLimit controls CPU rate with hard limit, the value specifies +// the portion of processor cycles that the threads in the job object can use +// during each scheduling interval, as the number of cycles per 10,000 cycles, +// e.g.: to limit a job object with 12.34% CPU rate, the value must be 1234. +// The value must be in range 1-10,000. +// +// The limit cannot be used with WithCPUWeightedLimit or WithCPUMinMaxLimit. +func WithCPUHardCapLimit(v uint32) Limit { + return LimitCPU.WithValue(CPURate{HardCap: v}) +} + +// WithCPUWeightedLimit specifies the scheduling weight of the job object, +// which determines the share of processor time given to the job relative to +// other workloads on the processor. This member can be a value from 1 through +// 9, where 1 is the smallest share and 9 is the largest share. The default is +// 5, which should be used for most workloads. +// +// The limit cannot be used with WithCPUHardCapLimit or WithCPUMinMaxLimit. +func WithCPUWeightedLimit(v uint32) Limit { + return LimitCPU.WithValue(CPURate{Weight: v}) +} + +// WithCPUMinMaxLimit specifies min and max portions of processor cycles that +// the job object can reserve and use during each scheduling interval. +// +// Specify this rate as a percentage times 100. For example, to set a minimum +// rate of 50%, specify 50 times 100, or 5,000. For the minimum rates to work +// correctly, the sum of the minimum rates for all of the job objects in the +// system cannot exceed 10,000, which is the equivalent of 100%. +// +// The limit cannot be used with WithCPUHardCapLimit or WithCPUWeightedLimit. +func WithCPUMinMaxLimit(min, max uint16) Limit { + return LimitCPU.WithValue(CPURate{Min: min, Max: max}) +} + +var LimitCPU cpuLimit + +type CPURate struct { + Min uint16 + Max uint16 + Weight uint32 + HardCap uint32 +} + +type cpuLimit CPURate + +func (l cpuLimit) reset(job *JobObject) { + job.CPURateControl.ControlFlags = 0 +} + +func (l cpuLimit) IsSet(job *JobObject) bool { + return job.CPURateControl.ControlFlags != 0 +} + +func (l cpuLimit) Value(job *JobObject) interface{} { + return l.LimitValue(job) +} + +func (l cpuLimit) WithValue(x CPURate) cpuLimit { + return cpuLimit(x) +} + +func (l cpuLimit) LimitValue(job *JobObject) CPURate { + var r CPURate + switch { + case job.CPURateControl.ControlFlags&jobapi.JOB_OBJECT_CPU_RATE_CONTROL_HARD_CAP > 0: + r.HardCap = job.CPURateControl.Value + case job.CPURateControl.ControlFlags&jobapi.JOB_OBJECT_CPU_RATE_CONTROL_WEIGHT_BASED > 0: + r.Weight = job.CPURateControl.Value + case job.CPURateControl.ControlFlags&jobapi.JOB_OBJECT_CPU_RATE_CONTROL_MIN_MAX_RATE > 0: + var b bytes.Buffer + _ = binary.Write(&b, binary.LittleEndian, job.CPURateControl.Value) + r.Min = binary.LittleEndian.Uint16(b.Bytes()[:2]) + r.Max = binary.LittleEndian.Uint16(b.Bytes()[2:]) + } + return r +} + +func (l cpuLimit) set(job *JobObject) { + var f jobapi.CPUControlFlag + switch { + case l.HardCap > 0: + job.CPURateControl.Value = l.HardCap + f = jobapi.JOB_OBJECT_CPU_RATE_CONTROL_HARD_CAP + case l.Weight > 0: + job.CPURateControl.Value = l.Weight + f = jobapi.JOB_OBJECT_CPU_RATE_CONTROL_WEIGHT_BASED + case l.Max > 0: + f = jobapi.JOB_OBJECT_CPU_RATE_CONTROL_MIN_MAX_RATE + var b bytes.Buffer + _ = binary.Write(&b, binary.LittleEndian, l.Min) + _ = binary.Write(&b, binary.LittleEndian, l.Max) + job.CPURateControl.Value = binary.LittleEndian.Uint32(b.Bytes()) + } + job.CPURateControl.ControlFlags = f | + jobapi.JOB_OBJECT_CPU_RATE_CONTROL_ENABLE | + jobapi.JOB_OBJECT_CPU_RATE_CONTROL_NOTIFY +} diff --git a/vendor/github.com/kolesnikovae/go-winjob/limits_net.go b/vendor/github.com/kolesnikovae/go-winjob/limits_net.go new file mode 100644 index 00000000..d24cb66e --- /dev/null +++ b/vendor/github.com/kolesnikovae/go-winjob/limits_net.go @@ -0,0 +1,94 @@ +//go:build windows +// +build windows + +package winjob + +import ( + "github.com/kolesnikovae/go-winjob/jobapi" +) + +// WithOutgoingBandwidthLimit sets the maximum bandwidth for outgoing +// network traffic for the job, in bytes. +func WithOutgoingBandwidthLimit(b uint64) Limit { + return LimitOutgoingBandwidth.WithValue(b) +} + +// WithDSCPTag sets the value to use for the Differentiated Service code +// point (DSCP) field to turn on network quality of service (QoS) for all +// outgoing network traffic generated by the processes of the job object. +// The valid range is from 0x00 through 0x3F. +func WithDSCPTag(t byte) Limit { + return LimitDSCPTag.WithValue(t) +} + +var LimitOutgoingBandwidth netBandwidthLimit + +var LimitDSCPTag netDSCPTagLimit + +type netBandwidthLimit struct { + maxBandwidth uint64 +} + +func (l netBandwidthLimit) WithValue(x uint64) netBandwidthLimit { + l.maxBandwidth = x + return l +} + +func (l netBandwidthLimit) LimitValue(job *JobObject) uint64 { + return job.NetRateControl.MaxBandwidth +} + +func (l netBandwidthLimit) set(job *JobObject) { + job.NetRateControl.MaxBandwidth = l.maxBandwidth + f := jobapi.JOB_OBJECT_NET_RATE_CONTROL_ENABLE | jobapi.JOB_OBJECT_NET_RATE_CONTROL_MAX_BANDWIDTH + job.NetRateControl.ControlFlags |= f +} + +func (l netBandwidthLimit) reset(job *JobObject) { + job.NetRateControl.ControlFlags &^= jobapi.JOB_OBJECT_NET_RATE_CONTROL_MAX_BANDWIDTH + if job.NetRateControl.ControlFlags == jobapi.JOB_OBJECT_NET_RATE_CONTROL_ENABLE { + job.NetRateControl.ControlFlags = 0 + } +} + +func (l netBandwidthLimit) IsSet(job *JobObject) bool { + return job.NetRateControl.ControlFlags&jobapi.JOB_OBJECT_NET_RATE_CONTROL_MAX_BANDWIDTH > 0 +} + +func (l netBandwidthLimit) Value(job *JobObject) interface{} { + return l.LimitValue(job) +} + +type netDSCPTagLimit struct { + dscpTag byte +} + +func (l netDSCPTagLimit) WithValue(t byte) netDSCPTagLimit { + l.dscpTag = t + return l +} + +func (l netDSCPTagLimit) LimitValue(job *JobObject) byte { + return job.NetRateControl.DscpTag +} + +func (l netDSCPTagLimit) set(job *JobObject) { + job.NetRateControl.DscpTag = l.dscpTag + f := jobapi.JOB_OBJECT_NET_RATE_CONTROL_ENABLE | jobapi.JOB_OBJECT_NET_RATE_CONTROL_DSCP_TAG + job.NetRateControl.ControlFlags |= f +} + +func (l netDSCPTagLimit) reset(job *JobObject) { + job.NetRateControl.ControlFlags &^= jobapi.JOB_OBJECT_NET_RATE_CONTROL_DSCP_TAG + if job.NetRateControl.ControlFlags == jobapi.JOB_OBJECT_NET_RATE_CONTROL_ENABLE { + job.NetRateControl.ControlFlags = 0 + } +} + +func (l netDSCPTagLimit) IsSet(job *JobObject) bool { + return job.NetRateControl.ControlFlags&jobapi.JOB_OBJECT_NET_RATE_CONTROL_DSCP_TAG > 0 +} + +func (l netDSCPTagLimit) Value(job *JobObject) interface{} { + return l.LimitValue(job) +} diff --git a/vendor/github.com/kolesnikovae/go-winjob/limits_ui.go b/vendor/github.com/kolesnikovae/go-winjob/limits_ui.go new file mode 100644 index 00000000..5b6fb483 --- /dev/null +++ b/vendor/github.com/kolesnikovae/go-winjob/limits_ui.go @@ -0,0 +1,85 @@ +//go:build windows +// +build windows + +package winjob + +import "github.com/kolesnikovae/go-winjob/jobapi" + +// WithDesktopLimit prevents processes associated with the job from creating +// desktops and switching desktops using the CreateDesktop and SwitchDesktop +// functions. +func WithDesktopLimit() Limit { + return LimitDesktop +} + +// WithDisplaySettingsLimit prevents processes associated with the job from +// calling the ChangeDisplaySettings function. +func WithDisplaySettingsLimit() Limit { + return LimitDisplaySettings +} + +// WithExitWindowsLimit prevents processes associated with the job from calling +// the ExitWindows or ExitWindowsEx function. +func WithExitWindowsLimit() Limit { + return LimitExitWindows +} + +// WithGlobalAtomsLimit prevents processes associated with the job from +// accessing global atoms. When this limit is used, each job has its own atom +// table. +func WithGlobalAtomsLimit() Limit { + return LimitGlobalAtoms +} + +// WithHandlesLimit prevents processes associated with the job from using USER +// handles owned by processes not associated with the same job. +func WithHandlesLimit() Limit { + return LimitHandles +} + +// WithReadClipboardLimit prevents processes associated with the job from +// reading data from the clipboard. +func WithReadClipboardLimit() Limit { + return LimitReadClipboard +} + +// WithSystemParametersLimit prevents processes associated with the job from +// changing system parameters by using the SystemParametersInfo function. +func WithSystemParametersLimit() Limit { + return LimitSystemParameters +} + +// WithWriteClipboardLimit prevents processes associated with the job from +// writing data to the clipboard. +func WithWriteClipboardLimit() Limit { + return LimitWriteClipboard +} + +var ( + LimitDesktop = uiRestriction(jobapi.JOB_OBJECT_UILIMIT_DESKTOP) + LimitDisplaySettings = uiRestriction(jobapi.JOB_OBJECT_UILIMIT_DISPLAYSETTINGS) + LimitExitWindows = uiRestriction(jobapi.JOB_OBJECT_UILIMIT_EXITWINDOWS) + LimitGlobalAtoms = uiRestriction(jobapi.JOB_OBJECT_UILIMIT_GLOBALATOMS) + LimitHandles = uiRestriction(jobapi.JOB_OBJECT_UILIMIT_HANDLES) + LimitSystemParameters = uiRestriction(jobapi.JOB_OBJECT_UILIMIT_SYSTEMPARAMETERS) + LimitWriteClipboard = uiRestriction(jobapi.JOB_OBJECT_UILIMIT_WRITECLIPBOARD) + LimitReadClipboard = uiRestriction(jobapi.JOB_OBJECT_UILIMIT_READCLIPBOARD) +) + +type uiRestriction jobapi.UIRestrictionsClass + +func (r uiRestriction) set(job *JobObject) { + job.UIRestrictions.UIRestrictionsClass |= jobapi.UIRestrictionsClass(r) +} + +func (r uiRestriction) reset(job *JobObject) { + job.UIRestrictions.UIRestrictionsClass &^= jobapi.UIRestrictionsClass(r) +} + +func (r uiRestriction) IsSet(job *JobObject) bool { + return job.UIRestrictions.UIRestrictionsClass&jobapi.UIRestrictionsClass(r) > 0 +} + +func (r uiRestriction) Value(job *JobObject) interface{} { + return r.IsSet(job) +} diff --git a/vendor/github.com/kolesnikovae/go-winjob/notifications.go b/vendor/github.com/kolesnikovae/go-winjob/notifications.go new file mode 100644 index 00000000..36e346af --- /dev/null +++ b/vendor/github.com/kolesnikovae/go-winjob/notifications.go @@ -0,0 +1,186 @@ +//go:build windows +// +build windows + +package winjob + +import ( + "errors" + "fmt" + "sync" + "syscall" + + "github.com/kolesnikovae/go-winjob/jobapi" +) + +// Port is a wrapper for a job object IoCompletionPort. +// +// The system sends messages to the I/O completion port associated with a job +// when certain events occur. If the job is nested, the message is sent to +// every I/O completion port associated with any job in the parent job chain of +// the job that triggered the message. All messages are sent directly from the +// job as if the job had called the PostQueuedCompletionStatus function. +// +// Note that, except for limits set with JobObjectNotificationLimitInformation +// information class, message delivery to a completion port is not guaranteed. +// Notifications for limits set with JobObjectNotificationLimitInformation are +// guaranteed to arrive at the completion port. +type Port syscall.Handle + +// Subscription is created when a new completion port is being associated +// with a job object. Refer to Notify function. +type Subscription struct { + Port + mu sync.Mutex + err error + closed bool +} + +// Notification is a CompletionPort message related to a job object. +type Notification struct { + Type NotificationType + // If a message does not concern a particular process, the PID will be 0. + PID int +} + +type NotificationType string + +const ( + NotificationEndOfJobTime = "EndOfJobTime" + NotificationEndOfProcessTime = "EndOfProcessTime" + NotificationActiveProcessLimit = "ActiveProcessLimit" + NotificationActiveProcessZero = "ActiveProcessZero" + NotificationNewProcess = "NewProcess" + NotificationExitProcess = "ExitProcess" + NotificationAbnormalExitProcess = "AbnormalExitProcess" + NotificationProcessMemoryExit = "ProcessMemoryExit" + NotificationJobMemoryLimit = "JobMemoryLimit" + NotificationNotificationLimit = "NotificationLimit" + NotificationJobCycleLimit = "JobCycleLimit" + NotificationSiloTerminated = "SiloTerminated" +) + +var notificationTypes = map[jobapi.CompletionPortMessage]NotificationType{ + jobapi.JOB_OBJECT_MSG_END_OF_JOB_TIME: NotificationEndOfJobTime, + jobapi.JOB_OBJECT_MSG_END_OF_PROCESS_TIME: NotificationEndOfProcessTime, + jobapi.JOB_OBJECT_MSG_ACTIVE_PROCESS_LIMIT: NotificationActiveProcessLimit, + jobapi.JOB_OBJECT_MSG_ACTIVE_PROCESS_ZERO: NotificationActiveProcessZero, + jobapi.JOB_OBJECT_MSG_NEW_PROCESS: NotificationNewProcess, + jobapi.JOB_OBJECT_MSG_EXIT_PROCESS: NotificationExitProcess, + jobapi.JOB_OBJECT_MSG_ABNORMAL_EXIT_PROCESS: NotificationAbnormalExitProcess, + jobapi.JOB_OBJECT_MSG_PROCESS_MEMORY_LIMIT: NotificationProcessMemoryExit, + jobapi.JOB_OBJECT_MSG_JOB_MEMORY_LIMIT: NotificationJobMemoryLimit, + jobapi.JOB_OBJECT_MSG_NOTIFICATION_LIMIT: NotificationNotificationLimit, + jobapi.JOB_OBJECT_MSG_JOB_CYCLE_TIME_LIMIT: NotificationJobCycleLimit, + jobapi.JOB_OBJECT_MSG_SILO_TERMINATED: NotificationSiloTerminated, +} + +func resolveNotificationType(mType jobapi.CompletionPortMessage) (NotificationType, bool) { + t, ok := notificationTypes[mType] + return t, ok +} + +// CreatePort creates a new job object completion port for notifications and +// associates it with the given job object. If an association can not be +// established, the port handle is closed, and returned Port handle represents +// the actual handle state. Created Port must be disposed with a Close call. +func CreatePort(job *JobObject) (p Port, err error) { + // https://docs.microsoft.com/en-us/windows/win32/fileio/createiocompletionport + handle, err := syscall.CreateIoCompletionPort( + syscall.InvalidHandle, // Ignore ExistingCompletionPort and CompletionKey. + 0, // ExistingCompletionPort + 0, // CompletionKey + 1, // NumberOfConcurrentThreads + ) + if err != nil { + return p, err + } + err = jobapi.AssociateCompletionPort(job.Handle, handle) + if err != nil { + _ = syscall.CloseHandle(handle) + } + return Port(handle), err +} + +// Close disposes completion port handle. +func (p Port) Close() error { + return syscall.CloseHandle(syscall.Handle(p)) +} + +// NextMessage blocks until the next completion port message is received, +// or a Close call, whichever occurs first. If a subscription is closed +// while the underlying GetQueuedCompletionStatus call was outstanding, +// a wrapped ErrAbandoned error will be returned. +func (p Port) NextMessage() (Notification, error) { + mType, pid, err := jobapi.GetQueuedCompletionStatus(syscall.Handle(p), syscall.INFINITE) + if err != nil { + return Notification{}, err + } + typ, ok := resolveNotificationType(jobapi.CompletionPortMessage(mType)) + if !ok { + typ = NotificationType(fmt.Sprintf("%v", mType)) + } + m := Notification{ + Type: typ, + PID: int(pid), + } + return m, nil +} + +// Notify causes job to relay notifications to the channel given. The channel +// is closed either on completion port polling error, or on subscription Close +// call. +func Notify(c chan<- Notification, job *JobObject) (*Subscription, error) { + p, err := CreatePort(job) + if err != nil { + return nil, err + } + s := Subscription{Port: p} + go s.notify(c) + return &s, nil +} + +// Close interrupts completion port polling, closes port handle and a channel +// provided to Notify call. The call is thread-safe and supposed to be +// performed concurrently with notification handling. +func (s *Subscription) Close() error { + s.mu.Lock() + defer s.mu.Unlock() + if s.closed { + return nil + } + if err := s.Port.Close(); err != nil { + return err + } + s.closed = true + return nil +} + +// Err reports an error encountered during completion polling, if any. +// The call should be done after Notify channel close. +func (s *Subscription) Err() error { + s.mu.Lock() + err := s.err + s.mu.Unlock() + return err +} + +func (s *Subscription) notify(c chan<- Notification) { + defer close(c) + for { + m, err := s.Port.NextMessage() + if err != nil { + s.handlePortErr(err) + return + } + c <- m + } +} + +func (s *Subscription) handlePortErr(err error) { + s.mu.Lock() + defer s.mu.Unlock() + if errors.Is(err, jobapi.ErrAbandoned) && s.closed { + return + } + s.err = err +} diff --git a/vendor/github.com/kolesnikovae/go-winjob/resume.go b/vendor/github.com/kolesnikovae/go-winjob/resume.go new file mode 100644 index 00000000..b17f5bb9 --- /dev/null +++ b/vendor/github.com/kolesnikovae/go-winjob/resume.go @@ -0,0 +1,107 @@ +//go:build windows +// +build windows + +package winjob + +import ( + "fmt" + "os/exec" + "unsafe" + + "golang.org/x/sys/windows" +) + +// Start creates a job object with the limits specified and starts the given +// command within the job. The process is created with suspended threads which +// are resumed when the process has been added to the job object. +func Start(cmd *exec.Cmd, limits ...Limit) (*JobObject, error) { + job, err := Create("", limits...) + if err != nil { + return nil, err + } + if err := StartInJobObject(cmd, job); err != nil { + _ = job.Close() + return nil, err + } + return job, nil +} + +// StartInJobObject starts the given command within the job objects specified. +// The process is created with suspended threads which are resumed when the +// process is added to the job. +func StartInJobObject(cmd *exec.Cmd, job *JobObject) error { + if cmd.SysProcAttr == nil { + cmd.SysProcAttr = new(windows.SysProcAttr) + } + cmd.SysProcAttr.CreationFlags |= windows.CREATE_SUSPENDED + if err := cmd.Start(); err != nil { + return err + } + if err := job.Assign(cmd.Process); err != nil { + return err + } + return Resume(cmd) +} + +// Resume resumes the process of the given command. The command should be +// created with CREATE_SUSPENDED flag: +// +// cmd.SysProcAttr = &windows.SysProcAttr{ +// CreationFlags: windows.CREATE_SUSPENDED, +// } +// +// CREATE_SUSPENDED specifies that the primary thread of the new process is +// created in a suspended state, and does not run until the ResumeThread +// windows function is called. +func Resume(cmd *exec.Cmd) error { + if cmd.Process == nil { + return fmt.Errorf("process is nil") + } + return ResumeProcess(cmd.Process.Pid) +} + +// ResumeProcess resumes the first found thread of the process. +func ResumeProcess(pid int) (err error) { + s, err := windows.CreateToolhelp32Snapshot(windows.TH32CS_SNAPTHREAD, uint32(pid)) + if err != nil { + return fmt.Errorf("CreateToolhelp32Snapshot: %w", err) + } + defer func() { + _ = windows.Close(s) + }() + + var e windows.ThreadEntry32 + e.Size = uint32(unsafe.Sizeof(e)) + if err := windows.Thread32First(s, &e); err != nil { + return fmt.Errorf("Thread32First: %w", err) + } + + for { + err := windows.Thread32Next(s, &e) + switch err { + default: + return fmt.Errorf("Thread32Next: %w", err) + case windows.ERROR_NO_MORE_FILES: + return fmt.Errorf("no threads found") + case nil: + if int(e.OwnerProcessID) == pid && e.ThreadID != 0 { + return ResumeThread(e.ThreadID) + } + } + } +} + +// ResumeThread resumes given thread. +func ResumeThread(tid uint32) (err error) { + hThread, err := windows.OpenThread(windows.THREAD_SUSPEND_RESUME, false, tid) + if err != nil { + return fmt.Errorf("OpenThread: %w", err) + } + defer func() { + _ = windows.Close(hThread) + }() + if _, err = windows.ResumeThread(hThread); err != nil { + return fmt.Errorf("ResumeThread: %w", err) + } + return nil +} diff --git a/vendor/golang.org/x/sys/unix/mkerrors.sh b/vendor/golang.org/x/sys/unix/mkerrors.sh index 6ab02b6c..d1c8b264 100644 --- a/vendor/golang.org/x/sys/unix/mkerrors.sh +++ b/vendor/golang.org/x/sys/unix/mkerrors.sh @@ -349,6 +349,9 @@ struct ltchars { #define _HIDIOCGRAWPHYS HIDIOCGRAWPHYS(_HIDIOCGRAWPHYS_LEN) #define _HIDIOCGRAWUNIQ HIDIOCGRAWUNIQ(_HIDIOCGRAWUNIQ_LEN) +// Renamed in v6.16, commit c6d732c38f93 ("net: ethtool: remove duplicate defines for family info") +#define ETHTOOL_FAMILY_NAME ETHTOOL_GENL_NAME +#define ETHTOOL_FAMILY_VERSION ETHTOOL_GENL_VERSION ' includes_NetBSD=' diff --git a/vendor/golang.org/x/sys/unix/syscall_darwin.go b/vendor/golang.org/x/sys/unix/syscall_darwin.go index 798f61ad..7838ca5d 100644 --- a/vendor/golang.org/x/sys/unix/syscall_darwin.go +++ b/vendor/golang.org/x/sys/unix/syscall_darwin.go @@ -602,14 +602,9 @@ func Connectx(fd int, srcIf uint32, srcAddr, dstAddr Sockaddr, associd SaeAssocI return } -// sys connectx(fd int, endpoints *SaEndpoints, associd SaeAssocID, flags uint32, iov []Iovec, n *uintptr, connid *SaeConnID) (err error) const minIovec = 8 func Readv(fd int, iovs [][]byte) (n int, err error) { - if !darwinKernelVersionMin(11, 0, 0) { - return 0, ENOSYS - } - iovecs := make([]Iovec, 0, minIovec) iovecs = appendBytes(iovecs, iovs) n, err = readv(fd, iovecs) @@ -618,9 +613,6 @@ func Readv(fd int, iovs [][]byte) (n int, err error) { } func Preadv(fd int, iovs [][]byte, offset int64) (n int, err error) { - if !darwinKernelVersionMin(11, 0, 0) { - return 0, ENOSYS - } iovecs := make([]Iovec, 0, minIovec) iovecs = appendBytes(iovecs, iovs) n, err = preadv(fd, iovecs, offset) @@ -629,10 +621,6 @@ func Preadv(fd int, iovs [][]byte, offset int64) (n int, err error) { } func Writev(fd int, iovs [][]byte) (n int, err error) { - if !darwinKernelVersionMin(11, 0, 0) { - return 0, ENOSYS - } - iovecs := make([]Iovec, 0, minIovec) iovecs = appendBytes(iovecs, iovs) if raceenabled { @@ -644,10 +632,6 @@ func Writev(fd int, iovs [][]byte) (n int, err error) { } func Pwritev(fd int, iovs [][]byte, offset int64) (n int, err error) { - if !darwinKernelVersionMin(11, 0, 0) { - return 0, ENOSYS - } - iovecs := make([]Iovec, 0, minIovec) iovecs = appendBytes(iovecs, iovs) if raceenabled { @@ -707,45 +691,7 @@ func readvRacedetect(iovecs []Iovec, n int, err error) { } } -func darwinMajorMinPatch() (maj, min, patch int, err error) { - var un Utsname - err = Uname(&un) - if err != nil { - return - } - - var mmp [3]int - c := 0 -Loop: - for _, b := range un.Release[:] { - switch { - case b >= '0' && b <= '9': - mmp[c] = 10*mmp[c] + int(b-'0') - case b == '.': - c++ - if c > 2 { - return 0, 0, 0, ENOTSUP - } - case b == 0: - break Loop - default: - return 0, 0, 0, ENOTSUP - } - } - if c != 2 { - return 0, 0, 0, ENOTSUP - } - return mmp[0], mmp[1], mmp[2], nil -} - -func darwinKernelVersionMin(maj, min, patch int) bool { - actualMaj, actualMin, actualPatch, err := darwinMajorMinPatch() - if err != nil { - return false - } - return actualMaj > maj || actualMaj == maj && (actualMin > min || actualMin == min && actualPatch >= patch) -} - +//sys connectx(fd int, endpoints *SaEndpoints, associd SaeAssocID, flags uint32, iov []Iovec, n *uintptr, connid *SaeConnID) (err error) //sys sendfile(infd int, outfd int, offset int64, len *int64, hdtr unsafe.Pointer, flags int) (err error) //sys shmat(id int, addr uintptr, flag int) (ret uintptr, err error) diff --git a/vendor/golang.org/x/sys/unix/zerrors_linux.go b/vendor/golang.org/x/sys/unix/zerrors_linux.go index 4f432bfe..b6db27d9 100644 --- a/vendor/golang.org/x/sys/unix/zerrors_linux.go +++ b/vendor/golang.org/x/sys/unix/zerrors_linux.go @@ -319,6 +319,7 @@ const ( AUDIT_INTEGRITY_POLICY_RULE = 0x70f AUDIT_INTEGRITY_RULE = 0x70d AUDIT_INTEGRITY_STATUS = 0x70a + AUDIT_INTEGRITY_USERSPACE = 0x710 AUDIT_IPC = 0x517 AUDIT_IPC_SET_PERM = 0x51f AUDIT_IPE_ACCESS = 0x58c @@ -327,6 +328,8 @@ const ( AUDIT_KERNEL = 0x7d0 AUDIT_KERNEL_OTHER = 0x524 AUDIT_KERN_MODULE = 0x532 + AUDIT_LANDLOCK_ACCESS = 0x58f + AUDIT_LANDLOCK_DOMAIN = 0x590 AUDIT_LAST_FEATURE = 0x1 AUDIT_LAST_KERN_ANOM_MSG = 0x707 AUDIT_LAST_USER_MSG = 0x4af @@ -491,6 +494,7 @@ const ( BPF_F_BEFORE = 0x8 BPF_F_ID = 0x20 BPF_F_NETFILTER_IP_DEFRAG = 0x1 + BPF_F_PREORDER = 0x40 BPF_F_QUERY_EFFECTIVE = 0x1 BPF_F_REDIRECT_FLAGS = 0x19 BPF_F_REPLACE = 0x4 @@ -527,6 +531,7 @@ const ( BPF_LDX = 0x1 BPF_LEN = 0x80 BPF_LL_OFF = -0x200000 + BPF_LOAD_ACQ = 0x100 BPF_LSH = 0x60 BPF_MAJOR_VERSION = 0x1 BPF_MAXINSNS = 0x1000 @@ -554,6 +559,7 @@ const ( BPF_RET = 0x6 BPF_RSH = 0x70 BPF_ST = 0x2 + BPF_STORE_REL = 0x110 BPF_STX = 0x3 BPF_SUB = 0x10 BPF_TAG_SIZE = 0x8 @@ -843,9 +849,9 @@ const ( DM_UUID_FLAG = 0x4000 DM_UUID_LEN = 0x81 DM_VERSION = 0xc138fd00 - DM_VERSION_EXTRA = "-ioctl (2023-03-01)" + DM_VERSION_EXTRA = "-ioctl (2025-04-28)" DM_VERSION_MAJOR = 0x4 - DM_VERSION_MINOR = 0x30 + DM_VERSION_MINOR = 0x32 DM_VERSION_PATCHLEVEL = 0x0 DT_BLK = 0x6 DT_CHR = 0x2 @@ -936,11 +942,10 @@ const ( EPOLL_CTL_MOD = 0x3 EPOLL_IOC_TYPE = 0x8a EROFS_SUPER_MAGIC_V1 = 0xe0f5e1e2 - ESP_V4_FLOW = 0xa - ESP_V6_FLOW = 0xc - ETHER_FLOW = 0x12 ETHTOOL_BUSINFO_LEN = 0x20 ETHTOOL_EROMVERS_LEN = 0x20 + ETHTOOL_FAMILY_NAME = "ethtool" + ETHTOOL_FAMILY_VERSION = 0x1 ETHTOOL_FEC_AUTO = 0x2 ETHTOOL_FEC_BASER = 0x10 ETHTOOL_FEC_LLRS = 0x20 @@ -1203,13 +1208,18 @@ const ( FAN_DENY = 0x2 FAN_ENABLE_AUDIT = 0x40 FAN_EPIDFD = -0x2 + FAN_ERRNO_BITS = 0x8 + FAN_ERRNO_MASK = 0xff + FAN_ERRNO_SHIFT = 0x18 FAN_EVENT_INFO_TYPE_DFID = 0x3 FAN_EVENT_INFO_TYPE_DFID_NAME = 0x2 FAN_EVENT_INFO_TYPE_ERROR = 0x5 FAN_EVENT_INFO_TYPE_FID = 0x1 + FAN_EVENT_INFO_TYPE_MNT = 0x7 FAN_EVENT_INFO_TYPE_NEW_DFID_NAME = 0xc FAN_EVENT_INFO_TYPE_OLD_DFID_NAME = 0xa FAN_EVENT_INFO_TYPE_PIDFD = 0x4 + FAN_EVENT_INFO_TYPE_RANGE = 0x6 FAN_EVENT_METADATA_LEN = 0x18 FAN_EVENT_ON_CHILD = 0x8000000 FAN_FS_ERROR = 0x8000 @@ -1224,9 +1234,12 @@ const ( FAN_MARK_IGNORED_SURV_MODIFY = 0x40 FAN_MARK_IGNORE_SURV = 0x440 FAN_MARK_INODE = 0x0 + FAN_MARK_MNTNS = 0x110 FAN_MARK_MOUNT = 0x10 FAN_MARK_ONLYDIR = 0x8 FAN_MARK_REMOVE = 0x2 + FAN_MNT_ATTACH = 0x1000000 + FAN_MNT_DETACH = 0x2000000 FAN_MODIFY = 0x2 FAN_MOVE = 0xc0 FAN_MOVED_FROM = 0x40 @@ -1240,6 +1253,7 @@ const ( FAN_OPEN_EXEC = 0x1000 FAN_OPEN_EXEC_PERM = 0x40000 FAN_OPEN_PERM = 0x10000 + FAN_PRE_ACCESS = 0x100000 FAN_Q_OVERFLOW = 0x4000 FAN_RENAME = 0x10000000 FAN_REPORT_DFID_NAME = 0xc00 @@ -1247,6 +1261,7 @@ const ( FAN_REPORT_DIR_FID = 0x400 FAN_REPORT_FD_ERROR = 0x2000 FAN_REPORT_FID = 0x200 + FAN_REPORT_MNT = 0x4000 FAN_REPORT_NAME = 0x800 FAN_REPORT_PIDFD = 0x80 FAN_REPORT_TARGET_FID = 0x1000 @@ -1266,6 +1281,7 @@ const ( FIB_RULE_PERMANENT = 0x1 FIB_RULE_UNRESOLVED = 0x4 FIDEDUPERANGE = 0xc0189436 + FSCRYPT_ADD_KEY_FLAG_HW_WRAPPED = 0x1 FSCRYPT_KEY_DESCRIPTOR_SIZE = 0x8 FSCRYPT_KEY_DESC_PREFIX = "fscrypt:" FSCRYPT_KEY_DESC_PREFIX_SIZE = 0x8 @@ -1574,7 +1590,6 @@ const ( IPV6_DONTFRAG = 0x3e IPV6_DROP_MEMBERSHIP = 0x15 IPV6_DSTOPTS = 0x3b - IPV6_FLOW = 0x11 IPV6_FREEBIND = 0x4e IPV6_HDRINCL = 0x24 IPV6_HOPLIMIT = 0x34 @@ -1625,7 +1640,6 @@ const ( IPV6_TRANSPARENT = 0x4b IPV6_UNICAST_HOPS = 0x10 IPV6_UNICAST_IF = 0x4c - IPV6_USER_FLOW = 0xe IPV6_V6ONLY = 0x1a IPV6_VERSION = 0x60 IPV6_VERSION_MASK = 0xf0 @@ -1687,7 +1701,6 @@ const ( IP_TTL = 0x2 IP_UNBLOCK_SOURCE = 0x25 IP_UNICAST_IF = 0x32 - IP_USER_FLOW = 0xd IP_XFRM_POLICY = 0x11 ISOFS_SUPER_MAGIC = 0x9660 ISTRIP = 0x20 @@ -1809,7 +1822,11 @@ const ( LANDLOCK_ACCESS_FS_WRITE_FILE = 0x2 LANDLOCK_ACCESS_NET_BIND_TCP = 0x1 LANDLOCK_ACCESS_NET_CONNECT_TCP = 0x2 + LANDLOCK_CREATE_RULESET_ERRATA = 0x2 LANDLOCK_CREATE_RULESET_VERSION = 0x1 + LANDLOCK_RESTRICT_SELF_LOG_NEW_EXEC_ON = 0x2 + LANDLOCK_RESTRICT_SELF_LOG_SAME_EXEC_OFF = 0x1 + LANDLOCK_RESTRICT_SELF_LOG_SUBDOMAINS_OFF = 0x4 LANDLOCK_SCOPE_ABSTRACT_UNIX_SOCKET = 0x1 LANDLOCK_SCOPE_SIGNAL = 0x2 LINUX_REBOOT_CMD_CAD_OFF = 0x0 @@ -2485,6 +2502,10 @@ const ( PR_FP_EXC_UND = 0x40000 PR_FP_MODE_FR = 0x1 PR_FP_MODE_FRE = 0x2 + PR_FUTEX_HASH = 0x4e + PR_FUTEX_HASH_GET_IMMUTABLE = 0x3 + PR_FUTEX_HASH_GET_SLOTS = 0x2 + PR_FUTEX_HASH_SET_SLOTS = 0x1 PR_GET_AUXV = 0x41555856 PR_GET_CHILD_SUBREAPER = 0x25 PR_GET_DUMPABLE = 0x3 @@ -2644,6 +2665,10 @@ const ( PR_TAGGED_ADDR_ENABLE = 0x1 PR_TASK_PERF_EVENTS_DISABLE = 0x1f PR_TASK_PERF_EVENTS_ENABLE = 0x20 + PR_TIMER_CREATE_RESTORE_IDS = 0x4d + PR_TIMER_CREATE_RESTORE_IDS_GET = 0x2 + PR_TIMER_CREATE_RESTORE_IDS_OFF = 0x0 + PR_TIMER_CREATE_RESTORE_IDS_ON = 0x1 PR_TIMING_STATISTICAL = 0x0 PR_TIMING_TIMESTAMP = 0x1 PR_TSC_ENABLE = 0x1 @@ -2724,6 +2749,7 @@ const ( PTRACE_SETREGSET = 0x4205 PTRACE_SETSIGINFO = 0x4203 PTRACE_SETSIGMASK = 0x420b + PTRACE_SET_SYSCALL_INFO = 0x4212 PTRACE_SET_SYSCALL_USER_DISPATCH_CONFIG = 0x4210 PTRACE_SINGLESTEP = 0x9 PTRACE_SYSCALL = 0x18 @@ -2787,7 +2813,7 @@ const ( RTAX_UNSPEC = 0x0 RTAX_WINDOW = 0x3 RTA_ALIGNTO = 0x4 - RTA_MAX = 0x1e + RTA_MAX = 0x1f RTCF_DIRECTSRC = 0x4000000 RTCF_DOREDIRECT = 0x1000000 RTCF_LOG = 0x2000000 @@ -2864,10 +2890,12 @@ const ( RTM_DELACTION = 0x31 RTM_DELADDR = 0x15 RTM_DELADDRLABEL = 0x49 + RTM_DELANYCAST = 0x3d RTM_DELCHAIN = 0x65 RTM_DELLINK = 0x11 RTM_DELLINKPROP = 0x6d RTM_DELMDB = 0x55 + RTM_DELMULTICAST = 0x39 RTM_DELNEIGH = 0x1d RTM_DELNETCONF = 0x51 RTM_DELNEXTHOP = 0x69 @@ -2917,11 +2945,13 @@ const ( RTM_NEWACTION = 0x30 RTM_NEWADDR = 0x14 RTM_NEWADDRLABEL = 0x48 + RTM_NEWANYCAST = 0x3c RTM_NEWCACHEREPORT = 0x60 RTM_NEWCHAIN = 0x64 RTM_NEWLINK = 0x10 RTM_NEWLINKPROP = 0x6c RTM_NEWMDB = 0x54 + RTM_NEWMULTICAST = 0x38 RTM_NEWNDUSEROPT = 0x44 RTM_NEWNEIGH = 0x1c RTM_NEWNEIGHTBL = 0x40 @@ -2970,6 +3000,7 @@ const ( RTPROT_NTK = 0xf RTPROT_OPENR = 0x63 RTPROT_OSPF = 0xbc + RTPROT_OVN = 0x54 RTPROT_RA = 0x9 RTPROT_REDIRECT = 0x1 RTPROT_RIP = 0xbd @@ -2987,11 +3018,12 @@ const ( RUSAGE_THREAD = 0x1 RWF_APPEND = 0x10 RWF_ATOMIC = 0x40 + RWF_DONTCACHE = 0x80 RWF_DSYNC = 0x2 RWF_HIPRI = 0x1 RWF_NOAPPEND = 0x20 RWF_NOWAIT = 0x8 - RWF_SUPPORTED = 0x7f + RWF_SUPPORTED = 0xff RWF_SYNC = 0x4 RWF_WRITE_LIFE_NOT_SET = 0x0 SCHED_BATCH = 0x3 @@ -3271,6 +3303,7 @@ const ( STATX_BTIME = 0x800 STATX_CTIME = 0x80 STATX_DIOALIGN = 0x2000 + STATX_DIO_READ_ALIGN = 0x20000 STATX_GID = 0x10 STATX_INO = 0x100 STATX_MNT_ID = 0x1000 @@ -3322,7 +3355,7 @@ const ( TASKSTATS_GENL_NAME = "TASKSTATS" TASKSTATS_GENL_VERSION = 0x1 TASKSTATS_TYPE_MAX = 0x6 - TASKSTATS_VERSION = 0xe + TASKSTATS_VERSION = 0x10 TCIFLUSH = 0x0 TCIOFF = 0x2 TCIOFLUSH = 0x2 @@ -3392,8 +3425,6 @@ const ( TCP_TX_DELAY = 0x25 TCP_ULP = 0x1f TCP_USER_TIMEOUT = 0x12 - TCP_V4_FLOW = 0x1 - TCP_V6_FLOW = 0x5 TCP_WINDOW_CLAMP = 0xa TCP_ZEROCOPY_RECEIVE = 0x23 TFD_TIMER_ABSTIME = 0x1 @@ -3503,6 +3534,7 @@ const ( TP_STATUS_WRONG_FORMAT = 0x4 TRACEFS_MAGIC = 0x74726163 TS_COMM_LEN = 0x20 + UBI_IOCECNFO = 0xc01c6f06 UDF_SUPER_MAGIC = 0x15013346 UDP_CORK = 0x1 UDP_ENCAP = 0x64 @@ -3515,8 +3547,6 @@ const ( UDP_NO_CHECK6_RX = 0x66 UDP_NO_CHECK6_TX = 0x65 UDP_SEGMENT = 0x67 - UDP_V4_FLOW = 0x2 - UDP_V6_FLOW = 0x6 UMOUNT_NOFOLLOW = 0x8 USBDEVICE_SUPER_MAGIC = 0x9fa2 UTIME_NOW = 0x3fffffff @@ -3559,7 +3589,7 @@ const ( WDIOS_TEMPPANIC = 0x4 WDIOS_UNKNOWN = -0x1 WEXITED = 0x4 - WGALLOWEDIP_A_MAX = 0x3 + WGALLOWEDIP_A_MAX = 0x4 WGDEVICE_A_MAX = 0x8 WGPEER_A_MAX = 0xa WG_CMD_MAX = 0x1 @@ -3673,6 +3703,7 @@ const ( XDP_SHARED_UMEM = 0x1 XDP_STATISTICS = 0x7 XDP_TXMD_FLAGS_CHECKSUM = 0x2 + XDP_TXMD_FLAGS_LAUNCH_TIME = 0x4 XDP_TXMD_FLAGS_TIMESTAMP = 0x1 XDP_TX_METADATA = 0x2 XDP_TX_RING = 0x3 diff --git a/vendor/golang.org/x/sys/unix/zerrors_linux_386.go b/vendor/golang.org/x/sys/unix/zerrors_linux_386.go index 75207613..1c37f9fb 100644 --- a/vendor/golang.org/x/sys/unix/zerrors_linux_386.go +++ b/vendor/golang.org/x/sys/unix/zerrors_linux_386.go @@ -68,6 +68,7 @@ const ( CS8 = 0x30 CSIZE = 0x30 CSTOPB = 0x40 + DM_MPATH_PROBE_PATHS = 0xfd12 ECCGETLAYOUT = 0x81484d11 ECCGETSTATS = 0x80104d12 ECHOCTL = 0x200 @@ -360,6 +361,7 @@ const ( SO_OOBINLINE = 0xa SO_PASSCRED = 0x10 SO_PASSPIDFD = 0x4c + SO_PASSRIGHTS = 0x53 SO_PASSSEC = 0x22 SO_PEEK_OFF = 0x2a SO_PEERCRED = 0x11 @@ -372,6 +374,7 @@ const ( SO_RCVBUFFORCE = 0x21 SO_RCVLOWAT = 0x12 SO_RCVMARK = 0x4b + SO_RCVPRIORITY = 0x52 SO_RCVTIMEO = 0x14 SO_RCVTIMEO_NEW = 0x42 SO_RCVTIMEO_OLD = 0x14 diff --git a/vendor/golang.org/x/sys/unix/zerrors_linux_amd64.go b/vendor/golang.org/x/sys/unix/zerrors_linux_amd64.go index c68acda5..6f54d34a 100644 --- a/vendor/golang.org/x/sys/unix/zerrors_linux_amd64.go +++ b/vendor/golang.org/x/sys/unix/zerrors_linux_amd64.go @@ -68,6 +68,7 @@ const ( CS8 = 0x30 CSIZE = 0x30 CSTOPB = 0x40 + DM_MPATH_PROBE_PATHS = 0xfd12 ECCGETLAYOUT = 0x81484d11 ECCGETSTATS = 0x80104d12 ECHOCTL = 0x200 @@ -361,6 +362,7 @@ const ( SO_OOBINLINE = 0xa SO_PASSCRED = 0x10 SO_PASSPIDFD = 0x4c + SO_PASSRIGHTS = 0x53 SO_PASSSEC = 0x22 SO_PEEK_OFF = 0x2a SO_PEERCRED = 0x11 @@ -373,6 +375,7 @@ const ( SO_RCVBUFFORCE = 0x21 SO_RCVLOWAT = 0x12 SO_RCVMARK = 0x4b + SO_RCVPRIORITY = 0x52 SO_RCVTIMEO = 0x14 SO_RCVTIMEO_NEW = 0x42 SO_RCVTIMEO_OLD = 0x14 diff --git a/vendor/golang.org/x/sys/unix/zerrors_linux_arm.go b/vendor/golang.org/x/sys/unix/zerrors_linux_arm.go index a8c607ab..783ec5c1 100644 --- a/vendor/golang.org/x/sys/unix/zerrors_linux_arm.go +++ b/vendor/golang.org/x/sys/unix/zerrors_linux_arm.go @@ -68,6 +68,7 @@ const ( CS8 = 0x30 CSIZE = 0x30 CSTOPB = 0x40 + DM_MPATH_PROBE_PATHS = 0xfd12 ECCGETLAYOUT = 0x81484d11 ECCGETSTATS = 0x80104d12 ECHOCTL = 0x200 @@ -366,6 +367,7 @@ const ( SO_OOBINLINE = 0xa SO_PASSCRED = 0x10 SO_PASSPIDFD = 0x4c + SO_PASSRIGHTS = 0x53 SO_PASSSEC = 0x22 SO_PEEK_OFF = 0x2a SO_PEERCRED = 0x11 @@ -378,6 +380,7 @@ const ( SO_RCVBUFFORCE = 0x21 SO_RCVLOWAT = 0x12 SO_RCVMARK = 0x4b + SO_RCVPRIORITY = 0x52 SO_RCVTIMEO = 0x14 SO_RCVTIMEO_NEW = 0x42 SO_RCVTIMEO_OLD = 0x14 diff --git a/vendor/golang.org/x/sys/unix/zerrors_linux_arm64.go b/vendor/golang.org/x/sys/unix/zerrors_linux_arm64.go index 18563dd8..ca83d3ba 100644 --- a/vendor/golang.org/x/sys/unix/zerrors_linux_arm64.go +++ b/vendor/golang.org/x/sys/unix/zerrors_linux_arm64.go @@ -68,6 +68,7 @@ const ( CS8 = 0x30 CSIZE = 0x30 CSTOPB = 0x40 + DM_MPATH_PROBE_PATHS = 0xfd12 ECCGETLAYOUT = 0x81484d11 ECCGETSTATS = 0x80104d12 ECHOCTL = 0x200 @@ -359,6 +360,7 @@ const ( SO_OOBINLINE = 0xa SO_PASSCRED = 0x10 SO_PASSPIDFD = 0x4c + SO_PASSRIGHTS = 0x53 SO_PASSSEC = 0x22 SO_PEEK_OFF = 0x2a SO_PEERCRED = 0x11 @@ -371,6 +373,7 @@ const ( SO_RCVBUFFORCE = 0x21 SO_RCVLOWAT = 0x12 SO_RCVMARK = 0x4b + SO_RCVPRIORITY = 0x52 SO_RCVTIMEO = 0x14 SO_RCVTIMEO_NEW = 0x42 SO_RCVTIMEO_OLD = 0x14 diff --git a/vendor/golang.org/x/sys/unix/zerrors_linux_loong64.go b/vendor/golang.org/x/sys/unix/zerrors_linux_loong64.go index 22912cda..607e611c 100644 --- a/vendor/golang.org/x/sys/unix/zerrors_linux_loong64.go +++ b/vendor/golang.org/x/sys/unix/zerrors_linux_loong64.go @@ -68,6 +68,7 @@ const ( CS8 = 0x30 CSIZE = 0x30 CSTOPB = 0x40 + DM_MPATH_PROBE_PATHS = 0xfd12 ECCGETLAYOUT = 0x81484d11 ECCGETSTATS = 0x80104d12 ECHOCTL = 0x200 @@ -353,6 +354,7 @@ const ( SO_OOBINLINE = 0xa SO_PASSCRED = 0x10 SO_PASSPIDFD = 0x4c + SO_PASSRIGHTS = 0x53 SO_PASSSEC = 0x22 SO_PEEK_OFF = 0x2a SO_PEERCRED = 0x11 @@ -365,6 +367,7 @@ const ( SO_RCVBUFFORCE = 0x21 SO_RCVLOWAT = 0x12 SO_RCVMARK = 0x4b + SO_RCVPRIORITY = 0x52 SO_RCVTIMEO = 0x14 SO_RCVTIMEO_NEW = 0x42 SO_RCVTIMEO_OLD = 0x14 diff --git a/vendor/golang.org/x/sys/unix/zerrors_linux_mips.go b/vendor/golang.org/x/sys/unix/zerrors_linux_mips.go index 29344eb3..b9cb5bd3 100644 --- a/vendor/golang.org/x/sys/unix/zerrors_linux_mips.go +++ b/vendor/golang.org/x/sys/unix/zerrors_linux_mips.go @@ -68,6 +68,7 @@ const ( CS8 = 0x30 CSIZE = 0x30 CSTOPB = 0x40 + DM_MPATH_PROBE_PATHS = 0x2000fd12 ECCGETLAYOUT = 0x41484d11 ECCGETSTATS = 0x40104d12 ECHOCTL = 0x200 @@ -359,6 +360,7 @@ const ( SO_OOBINLINE = 0x100 SO_PASSCRED = 0x11 SO_PASSPIDFD = 0x4c + SO_PASSRIGHTS = 0x53 SO_PASSSEC = 0x22 SO_PEEK_OFF = 0x2a SO_PEERCRED = 0x12 @@ -371,6 +373,7 @@ const ( SO_RCVBUFFORCE = 0x21 SO_RCVLOWAT = 0x1004 SO_RCVMARK = 0x4b + SO_RCVPRIORITY = 0x52 SO_RCVTIMEO = 0x1006 SO_RCVTIMEO_NEW = 0x42 SO_RCVTIMEO_OLD = 0x1006 diff --git a/vendor/golang.org/x/sys/unix/zerrors_linux_mips64.go b/vendor/golang.org/x/sys/unix/zerrors_linux_mips64.go index 20d51fb9..65b078a6 100644 --- a/vendor/golang.org/x/sys/unix/zerrors_linux_mips64.go +++ b/vendor/golang.org/x/sys/unix/zerrors_linux_mips64.go @@ -68,6 +68,7 @@ const ( CS8 = 0x30 CSIZE = 0x30 CSTOPB = 0x40 + DM_MPATH_PROBE_PATHS = 0x2000fd12 ECCGETLAYOUT = 0x41484d11 ECCGETSTATS = 0x40104d12 ECHOCTL = 0x200 @@ -359,6 +360,7 @@ const ( SO_OOBINLINE = 0x100 SO_PASSCRED = 0x11 SO_PASSPIDFD = 0x4c + SO_PASSRIGHTS = 0x53 SO_PASSSEC = 0x22 SO_PEEK_OFF = 0x2a SO_PEERCRED = 0x12 @@ -371,6 +373,7 @@ const ( SO_RCVBUFFORCE = 0x21 SO_RCVLOWAT = 0x1004 SO_RCVMARK = 0x4b + SO_RCVPRIORITY = 0x52 SO_RCVTIMEO = 0x1006 SO_RCVTIMEO_NEW = 0x42 SO_RCVTIMEO_OLD = 0x1006 diff --git a/vendor/golang.org/x/sys/unix/zerrors_linux_mips64le.go b/vendor/golang.org/x/sys/unix/zerrors_linux_mips64le.go index 321b6090..5298a303 100644 --- a/vendor/golang.org/x/sys/unix/zerrors_linux_mips64le.go +++ b/vendor/golang.org/x/sys/unix/zerrors_linux_mips64le.go @@ -68,6 +68,7 @@ const ( CS8 = 0x30 CSIZE = 0x30 CSTOPB = 0x40 + DM_MPATH_PROBE_PATHS = 0x2000fd12 ECCGETLAYOUT = 0x41484d11 ECCGETSTATS = 0x40104d12 ECHOCTL = 0x200 @@ -359,6 +360,7 @@ const ( SO_OOBINLINE = 0x100 SO_PASSCRED = 0x11 SO_PASSPIDFD = 0x4c + SO_PASSRIGHTS = 0x53 SO_PASSSEC = 0x22 SO_PEEK_OFF = 0x2a SO_PEERCRED = 0x12 @@ -371,6 +373,7 @@ const ( SO_RCVBUFFORCE = 0x21 SO_RCVLOWAT = 0x1004 SO_RCVMARK = 0x4b + SO_RCVPRIORITY = 0x52 SO_RCVTIMEO = 0x1006 SO_RCVTIMEO_NEW = 0x42 SO_RCVTIMEO_OLD = 0x1006 diff --git a/vendor/golang.org/x/sys/unix/zerrors_linux_mipsle.go b/vendor/golang.org/x/sys/unix/zerrors_linux_mipsle.go index 9bacdf1e..7bc557c8 100644 --- a/vendor/golang.org/x/sys/unix/zerrors_linux_mipsle.go +++ b/vendor/golang.org/x/sys/unix/zerrors_linux_mipsle.go @@ -68,6 +68,7 @@ const ( CS8 = 0x30 CSIZE = 0x30 CSTOPB = 0x40 + DM_MPATH_PROBE_PATHS = 0x2000fd12 ECCGETLAYOUT = 0x41484d11 ECCGETSTATS = 0x40104d12 ECHOCTL = 0x200 @@ -359,6 +360,7 @@ const ( SO_OOBINLINE = 0x100 SO_PASSCRED = 0x11 SO_PASSPIDFD = 0x4c + SO_PASSRIGHTS = 0x53 SO_PASSSEC = 0x22 SO_PEEK_OFF = 0x2a SO_PEERCRED = 0x12 @@ -371,6 +373,7 @@ const ( SO_RCVBUFFORCE = 0x21 SO_RCVLOWAT = 0x1004 SO_RCVMARK = 0x4b + SO_RCVPRIORITY = 0x52 SO_RCVTIMEO = 0x1006 SO_RCVTIMEO_NEW = 0x42 SO_RCVTIMEO_OLD = 0x1006 diff --git a/vendor/golang.org/x/sys/unix/zerrors_linux_ppc.go b/vendor/golang.org/x/sys/unix/zerrors_linux_ppc.go index c2242726..152399bb 100644 --- a/vendor/golang.org/x/sys/unix/zerrors_linux_ppc.go +++ b/vendor/golang.org/x/sys/unix/zerrors_linux_ppc.go @@ -68,6 +68,7 @@ const ( CS8 = 0x300 CSIZE = 0x300 CSTOPB = 0x400 + DM_MPATH_PROBE_PATHS = 0x2000fd12 ECCGETLAYOUT = 0x41484d11 ECCGETSTATS = 0x40104d12 ECHOCTL = 0x40 @@ -414,6 +415,7 @@ const ( SO_OOBINLINE = 0xa SO_PASSCRED = 0x14 SO_PASSPIDFD = 0x4c + SO_PASSRIGHTS = 0x53 SO_PASSSEC = 0x22 SO_PEEK_OFF = 0x2a SO_PEERCRED = 0x15 @@ -426,6 +428,7 @@ const ( SO_RCVBUFFORCE = 0x21 SO_RCVLOWAT = 0x10 SO_RCVMARK = 0x4b + SO_RCVPRIORITY = 0x52 SO_RCVTIMEO = 0x12 SO_RCVTIMEO_NEW = 0x42 SO_RCVTIMEO_OLD = 0x12 diff --git a/vendor/golang.org/x/sys/unix/zerrors_linux_ppc64.go b/vendor/golang.org/x/sys/unix/zerrors_linux_ppc64.go index 6270c8ee..1a1ce240 100644 --- a/vendor/golang.org/x/sys/unix/zerrors_linux_ppc64.go +++ b/vendor/golang.org/x/sys/unix/zerrors_linux_ppc64.go @@ -68,6 +68,7 @@ const ( CS8 = 0x300 CSIZE = 0x300 CSTOPB = 0x400 + DM_MPATH_PROBE_PATHS = 0x2000fd12 ECCGETLAYOUT = 0x41484d11 ECCGETSTATS = 0x40104d12 ECHOCTL = 0x40 @@ -418,6 +419,7 @@ const ( SO_OOBINLINE = 0xa SO_PASSCRED = 0x14 SO_PASSPIDFD = 0x4c + SO_PASSRIGHTS = 0x53 SO_PASSSEC = 0x22 SO_PEEK_OFF = 0x2a SO_PEERCRED = 0x15 @@ -430,6 +432,7 @@ const ( SO_RCVBUFFORCE = 0x21 SO_RCVLOWAT = 0x10 SO_RCVMARK = 0x4b + SO_RCVPRIORITY = 0x52 SO_RCVTIMEO = 0x12 SO_RCVTIMEO_NEW = 0x42 SO_RCVTIMEO_OLD = 0x12 diff --git a/vendor/golang.org/x/sys/unix/zerrors_linux_ppc64le.go b/vendor/golang.org/x/sys/unix/zerrors_linux_ppc64le.go index 9966c194..4231a1fb 100644 --- a/vendor/golang.org/x/sys/unix/zerrors_linux_ppc64le.go +++ b/vendor/golang.org/x/sys/unix/zerrors_linux_ppc64le.go @@ -68,6 +68,7 @@ const ( CS8 = 0x300 CSIZE = 0x300 CSTOPB = 0x400 + DM_MPATH_PROBE_PATHS = 0x2000fd12 ECCGETLAYOUT = 0x41484d11 ECCGETSTATS = 0x40104d12 ECHOCTL = 0x40 @@ -418,6 +419,7 @@ const ( SO_OOBINLINE = 0xa SO_PASSCRED = 0x14 SO_PASSPIDFD = 0x4c + SO_PASSRIGHTS = 0x53 SO_PASSSEC = 0x22 SO_PEEK_OFF = 0x2a SO_PEERCRED = 0x15 @@ -430,6 +432,7 @@ const ( SO_RCVBUFFORCE = 0x21 SO_RCVLOWAT = 0x10 SO_RCVMARK = 0x4b + SO_RCVPRIORITY = 0x52 SO_RCVTIMEO = 0x12 SO_RCVTIMEO_NEW = 0x42 SO_RCVTIMEO_OLD = 0x12 diff --git a/vendor/golang.org/x/sys/unix/zerrors_linux_riscv64.go b/vendor/golang.org/x/sys/unix/zerrors_linux_riscv64.go index 848e5fcc..21c0e952 100644 --- a/vendor/golang.org/x/sys/unix/zerrors_linux_riscv64.go +++ b/vendor/golang.org/x/sys/unix/zerrors_linux_riscv64.go @@ -68,6 +68,7 @@ const ( CS8 = 0x30 CSIZE = 0x30 CSTOPB = 0x40 + DM_MPATH_PROBE_PATHS = 0xfd12 ECCGETLAYOUT = 0x81484d11 ECCGETSTATS = 0x80104d12 ECHOCTL = 0x200 @@ -350,6 +351,7 @@ const ( SO_OOBINLINE = 0xa SO_PASSCRED = 0x10 SO_PASSPIDFD = 0x4c + SO_PASSRIGHTS = 0x53 SO_PASSSEC = 0x22 SO_PEEK_OFF = 0x2a SO_PEERCRED = 0x11 @@ -362,6 +364,7 @@ const ( SO_RCVBUFFORCE = 0x21 SO_RCVLOWAT = 0x12 SO_RCVMARK = 0x4b + SO_RCVPRIORITY = 0x52 SO_RCVTIMEO = 0x14 SO_RCVTIMEO_NEW = 0x42 SO_RCVTIMEO_OLD = 0x14 diff --git a/vendor/golang.org/x/sys/unix/zerrors_linux_s390x.go b/vendor/golang.org/x/sys/unix/zerrors_linux_s390x.go index 669b2adb..f00d1cd7 100644 --- a/vendor/golang.org/x/sys/unix/zerrors_linux_s390x.go +++ b/vendor/golang.org/x/sys/unix/zerrors_linux_s390x.go @@ -68,6 +68,7 @@ const ( CS8 = 0x30 CSIZE = 0x30 CSTOPB = 0x40 + DM_MPATH_PROBE_PATHS = 0xfd12 ECCGETLAYOUT = 0x81484d11 ECCGETSTATS = 0x80104d12 ECHOCTL = 0x200 @@ -422,6 +423,7 @@ const ( SO_OOBINLINE = 0xa SO_PASSCRED = 0x10 SO_PASSPIDFD = 0x4c + SO_PASSRIGHTS = 0x53 SO_PASSSEC = 0x22 SO_PEEK_OFF = 0x2a SO_PEERCRED = 0x11 @@ -434,6 +436,7 @@ const ( SO_RCVBUFFORCE = 0x21 SO_RCVLOWAT = 0x12 SO_RCVMARK = 0x4b + SO_RCVPRIORITY = 0x52 SO_RCVTIMEO = 0x14 SO_RCVTIMEO_NEW = 0x42 SO_RCVTIMEO_OLD = 0x14 diff --git a/vendor/golang.org/x/sys/unix/zerrors_linux_sparc64.go b/vendor/golang.org/x/sys/unix/zerrors_linux_sparc64.go index 4834e575..bc8d539e 100644 --- a/vendor/golang.org/x/sys/unix/zerrors_linux_sparc64.go +++ b/vendor/golang.org/x/sys/unix/zerrors_linux_sparc64.go @@ -71,6 +71,7 @@ const ( CS8 = 0x30 CSIZE = 0x30 CSTOPB = 0x40 + DM_MPATH_PROBE_PATHS = 0x2000fd12 ECCGETLAYOUT = 0x41484d11 ECCGETSTATS = 0x40104d12 ECHOCTL = 0x200 @@ -461,6 +462,7 @@ const ( SO_OOBINLINE = 0x100 SO_PASSCRED = 0x2 SO_PASSPIDFD = 0x55 + SO_PASSRIGHTS = 0x5c SO_PASSSEC = 0x1f SO_PEEK_OFF = 0x26 SO_PEERCRED = 0x40 @@ -473,6 +475,7 @@ const ( SO_RCVBUFFORCE = 0x100b SO_RCVLOWAT = 0x800 SO_RCVMARK = 0x54 + SO_RCVPRIORITY = 0x5b SO_RCVTIMEO = 0x2000 SO_RCVTIMEO_NEW = 0x44 SO_RCVTIMEO_OLD = 0x2000 diff --git a/vendor/golang.org/x/sys/unix/zsysnum_linux_386.go b/vendor/golang.org/x/sys/unix/zsysnum_linux_386.go index c79aaff3..aca56ee4 100644 --- a/vendor/golang.org/x/sys/unix/zsysnum_linux_386.go +++ b/vendor/golang.org/x/sys/unix/zsysnum_linux_386.go @@ -462,4 +462,5 @@ const ( SYS_GETXATTRAT = 464 SYS_LISTXATTRAT = 465 SYS_REMOVEXATTRAT = 466 + SYS_OPEN_TREE_ATTR = 467 ) diff --git a/vendor/golang.org/x/sys/unix/zsysnum_linux_amd64.go b/vendor/golang.org/x/sys/unix/zsysnum_linux_amd64.go index 5eb45069..2ea1ef58 100644 --- a/vendor/golang.org/x/sys/unix/zsysnum_linux_amd64.go +++ b/vendor/golang.org/x/sys/unix/zsysnum_linux_amd64.go @@ -385,4 +385,5 @@ const ( SYS_GETXATTRAT = 464 SYS_LISTXATTRAT = 465 SYS_REMOVEXATTRAT = 466 + SYS_OPEN_TREE_ATTR = 467 ) diff --git a/vendor/golang.org/x/sys/unix/zsysnum_linux_arm.go b/vendor/golang.org/x/sys/unix/zsysnum_linux_arm.go index 05e50297..d22c8af3 100644 --- a/vendor/golang.org/x/sys/unix/zsysnum_linux_arm.go +++ b/vendor/golang.org/x/sys/unix/zsysnum_linux_arm.go @@ -426,4 +426,5 @@ const ( SYS_GETXATTRAT = 464 SYS_LISTXATTRAT = 465 SYS_REMOVEXATTRAT = 466 + SYS_OPEN_TREE_ATTR = 467 ) diff --git a/vendor/golang.org/x/sys/unix/zsysnum_linux_arm64.go b/vendor/golang.org/x/sys/unix/zsysnum_linux_arm64.go index 38c53ec5..5ee264ae 100644 --- a/vendor/golang.org/x/sys/unix/zsysnum_linux_arm64.go +++ b/vendor/golang.org/x/sys/unix/zsysnum_linux_arm64.go @@ -329,4 +329,5 @@ const ( SYS_GETXATTRAT = 464 SYS_LISTXATTRAT = 465 SYS_REMOVEXATTRAT = 466 + SYS_OPEN_TREE_ATTR = 467 ) diff --git a/vendor/golang.org/x/sys/unix/zsysnum_linux_loong64.go b/vendor/golang.org/x/sys/unix/zsysnum_linux_loong64.go index 31d2e71a..f9f03ebf 100644 --- a/vendor/golang.org/x/sys/unix/zsysnum_linux_loong64.go +++ b/vendor/golang.org/x/sys/unix/zsysnum_linux_loong64.go @@ -325,4 +325,5 @@ const ( SYS_GETXATTRAT = 464 SYS_LISTXATTRAT = 465 SYS_REMOVEXATTRAT = 466 + SYS_OPEN_TREE_ATTR = 467 ) diff --git a/vendor/golang.org/x/sys/unix/zsysnum_linux_mips.go b/vendor/golang.org/x/sys/unix/zsysnum_linux_mips.go index f4184a33..87c2118e 100644 --- a/vendor/golang.org/x/sys/unix/zsysnum_linux_mips.go +++ b/vendor/golang.org/x/sys/unix/zsysnum_linux_mips.go @@ -446,4 +446,5 @@ const ( SYS_GETXATTRAT = 4464 SYS_LISTXATTRAT = 4465 SYS_REMOVEXATTRAT = 4466 + SYS_OPEN_TREE_ATTR = 4467 ) diff --git a/vendor/golang.org/x/sys/unix/zsysnum_linux_mips64.go b/vendor/golang.org/x/sys/unix/zsysnum_linux_mips64.go index 05b99622..391ad102 100644 --- a/vendor/golang.org/x/sys/unix/zsysnum_linux_mips64.go +++ b/vendor/golang.org/x/sys/unix/zsysnum_linux_mips64.go @@ -376,4 +376,5 @@ const ( SYS_GETXATTRAT = 5464 SYS_LISTXATTRAT = 5465 SYS_REMOVEXATTRAT = 5466 + SYS_OPEN_TREE_ATTR = 5467 ) diff --git a/vendor/golang.org/x/sys/unix/zsysnum_linux_mips64le.go b/vendor/golang.org/x/sys/unix/zsysnum_linux_mips64le.go index 43a256e9..56561577 100644 --- a/vendor/golang.org/x/sys/unix/zsysnum_linux_mips64le.go +++ b/vendor/golang.org/x/sys/unix/zsysnum_linux_mips64le.go @@ -376,4 +376,5 @@ const ( SYS_GETXATTRAT = 5464 SYS_LISTXATTRAT = 5465 SYS_REMOVEXATTRAT = 5466 + SYS_OPEN_TREE_ATTR = 5467 ) diff --git a/vendor/golang.org/x/sys/unix/zsysnum_linux_mipsle.go b/vendor/golang.org/x/sys/unix/zsysnum_linux_mipsle.go index eea5ddfc..0482b52e 100644 --- a/vendor/golang.org/x/sys/unix/zsysnum_linux_mipsle.go +++ b/vendor/golang.org/x/sys/unix/zsysnum_linux_mipsle.go @@ -446,4 +446,5 @@ const ( SYS_GETXATTRAT = 4464 SYS_LISTXATTRAT = 4465 SYS_REMOVEXATTRAT = 4466 + SYS_OPEN_TREE_ATTR = 4467 ) diff --git a/vendor/golang.org/x/sys/unix/zsysnum_linux_ppc.go b/vendor/golang.org/x/sys/unix/zsysnum_linux_ppc.go index 0d777bfb..71806f08 100644 --- a/vendor/golang.org/x/sys/unix/zsysnum_linux_ppc.go +++ b/vendor/golang.org/x/sys/unix/zsysnum_linux_ppc.go @@ -453,4 +453,5 @@ const ( SYS_GETXATTRAT = 464 SYS_LISTXATTRAT = 465 SYS_REMOVEXATTRAT = 466 + SYS_OPEN_TREE_ATTR = 467 ) diff --git a/vendor/golang.org/x/sys/unix/zsysnum_linux_ppc64.go b/vendor/golang.org/x/sys/unix/zsysnum_linux_ppc64.go index b4463650..e35a7105 100644 --- a/vendor/golang.org/x/sys/unix/zsysnum_linux_ppc64.go +++ b/vendor/golang.org/x/sys/unix/zsysnum_linux_ppc64.go @@ -425,4 +425,5 @@ const ( SYS_GETXATTRAT = 464 SYS_LISTXATTRAT = 465 SYS_REMOVEXATTRAT = 466 + SYS_OPEN_TREE_ATTR = 467 ) diff --git a/vendor/golang.org/x/sys/unix/zsysnum_linux_ppc64le.go b/vendor/golang.org/x/sys/unix/zsysnum_linux_ppc64le.go index 0c7d21c1..2aea4767 100644 --- a/vendor/golang.org/x/sys/unix/zsysnum_linux_ppc64le.go +++ b/vendor/golang.org/x/sys/unix/zsysnum_linux_ppc64le.go @@ -425,4 +425,5 @@ const ( SYS_GETXATTRAT = 464 SYS_LISTXATTRAT = 465 SYS_REMOVEXATTRAT = 466 + SYS_OPEN_TREE_ATTR = 467 ) diff --git a/vendor/golang.org/x/sys/unix/zsysnum_linux_riscv64.go b/vendor/golang.org/x/sys/unix/zsysnum_linux_riscv64.go index 84053916..6c9bb4e5 100644 --- a/vendor/golang.org/x/sys/unix/zsysnum_linux_riscv64.go +++ b/vendor/golang.org/x/sys/unix/zsysnum_linux_riscv64.go @@ -330,4 +330,5 @@ const ( SYS_GETXATTRAT = 464 SYS_LISTXATTRAT = 465 SYS_REMOVEXATTRAT = 466 + SYS_OPEN_TREE_ATTR = 467 ) diff --git a/vendor/golang.org/x/sys/unix/zsysnum_linux_s390x.go b/vendor/golang.org/x/sys/unix/zsysnum_linux_s390x.go index fcf1b790..680bc991 100644 --- a/vendor/golang.org/x/sys/unix/zsysnum_linux_s390x.go +++ b/vendor/golang.org/x/sys/unix/zsysnum_linux_s390x.go @@ -391,4 +391,5 @@ const ( SYS_GETXATTRAT = 464 SYS_LISTXATTRAT = 465 SYS_REMOVEXATTRAT = 466 + SYS_OPEN_TREE_ATTR = 467 ) diff --git a/vendor/golang.org/x/sys/unix/zsysnum_linux_sparc64.go b/vendor/golang.org/x/sys/unix/zsysnum_linux_sparc64.go index 52d15b5f..620f2710 100644 --- a/vendor/golang.org/x/sys/unix/zsysnum_linux_sparc64.go +++ b/vendor/golang.org/x/sys/unix/zsysnum_linux_sparc64.go @@ -404,4 +404,5 @@ const ( SYS_GETXATTRAT = 464 SYS_LISTXATTRAT = 465 SYS_REMOVEXATTRAT = 466 + SYS_OPEN_TREE_ATTR = 467 ) diff --git a/vendor/golang.org/x/sys/unix/ztypes_linux.go b/vendor/golang.org/x/sys/unix/ztypes_linux.go index a46abe64..cd236443 100644 --- a/vendor/golang.org/x/sys/unix/ztypes_linux.go +++ b/vendor/golang.org/x/sys/unix/ztypes_linux.go @@ -114,8 +114,10 @@ type Statx_t struct { Atomic_write_unit_min uint32 Atomic_write_unit_max uint32 Atomic_write_segments_max uint32 + Dio_read_offset_align uint32 + Atomic_write_unit_max_opt uint32 _ [1]uint32 - _ [9]uint64 + _ [8]uint64 } type Fsid struct { @@ -199,7 +201,8 @@ type FscryptAddKeyArg struct { Key_spec FscryptKeySpecifier Raw_size uint32 Key_id uint32 - _ [8]uint32 + Flags uint32 + _ [7]uint32 } type FscryptRemoveKeyArg struct { @@ -2226,8 +2229,11 @@ const ( NFT_PAYLOAD_LL_HEADER = 0x0 NFT_PAYLOAD_NETWORK_HEADER = 0x1 NFT_PAYLOAD_TRANSPORT_HEADER = 0x2 + NFT_PAYLOAD_INNER_HEADER = 0x3 + NFT_PAYLOAD_TUN_HEADER = 0x4 NFT_PAYLOAD_CSUM_NONE = 0x0 NFT_PAYLOAD_CSUM_INET = 0x1 + NFT_PAYLOAD_CSUM_SCTP = 0x2 NFT_PAYLOAD_L4CSUM_PSEUDOHDR = 0x1 NFTA_PAYLOAD_UNSPEC = 0x0 NFTA_PAYLOAD_DREG = 0x1 @@ -2314,6 +2320,11 @@ const ( NFT_CT_AVGPKT = 0x10 NFT_CT_ZONE = 0x11 NFT_CT_EVENTMASK = 0x12 + NFT_CT_SRC_IP = 0x13 + NFT_CT_DST_IP = 0x14 + NFT_CT_SRC_IP6 = 0x15 + NFT_CT_DST_IP6 = 0x16 + NFT_CT_ID = 0x17 NFTA_CT_UNSPEC = 0x0 NFTA_CT_DREG = 0x1 NFTA_CT_KEY = 0x2 @@ -2594,8 +2605,8 @@ const ( SOF_TIMESTAMPING_BIND_PHC = 0x8000 SOF_TIMESTAMPING_OPT_ID_TCP = 0x10000 - SOF_TIMESTAMPING_LAST = 0x20000 - SOF_TIMESTAMPING_MASK = 0x3ffff + SOF_TIMESTAMPING_LAST = 0x40000 + SOF_TIMESTAMPING_MASK = 0x7ffff SCM_TSTAMP_SND = 0x0 SCM_TSTAMP_SCHED = 0x1 @@ -3802,7 +3813,16 @@ const ( ETHTOOL_MSG_PSE_GET = 0x24 ETHTOOL_MSG_PSE_SET = 0x25 ETHTOOL_MSG_RSS_GET = 0x26 - ETHTOOL_MSG_USER_MAX = 0x2d + ETHTOOL_MSG_PLCA_GET_CFG = 0x27 + ETHTOOL_MSG_PLCA_SET_CFG = 0x28 + ETHTOOL_MSG_PLCA_GET_STATUS = 0x29 + ETHTOOL_MSG_MM_GET = 0x2a + ETHTOOL_MSG_MM_SET = 0x2b + ETHTOOL_MSG_MODULE_FW_FLASH_ACT = 0x2c + ETHTOOL_MSG_PHY_GET = 0x2d + ETHTOOL_MSG_TSCONFIG_GET = 0x2e + ETHTOOL_MSG_TSCONFIG_SET = 0x2f + ETHTOOL_MSG_USER_MAX = 0x2f ETHTOOL_MSG_KERNEL_NONE = 0x0 ETHTOOL_MSG_STRSET_GET_REPLY = 0x1 ETHTOOL_MSG_LINKINFO_GET_REPLY = 0x2 @@ -3842,7 +3862,17 @@ const ( ETHTOOL_MSG_MODULE_NTF = 0x24 ETHTOOL_MSG_PSE_GET_REPLY = 0x25 ETHTOOL_MSG_RSS_GET_REPLY = 0x26 - ETHTOOL_MSG_KERNEL_MAX = 0x2e + ETHTOOL_MSG_PLCA_GET_CFG_REPLY = 0x27 + ETHTOOL_MSG_PLCA_GET_STATUS_REPLY = 0x28 + ETHTOOL_MSG_PLCA_NTF = 0x29 + ETHTOOL_MSG_MM_GET_REPLY = 0x2a + ETHTOOL_MSG_MM_NTF = 0x2b + ETHTOOL_MSG_MODULE_FW_FLASH_NTF = 0x2c + ETHTOOL_MSG_PHY_GET_REPLY = 0x2d + ETHTOOL_MSG_PHY_NTF = 0x2e + ETHTOOL_MSG_TSCONFIG_GET_REPLY = 0x2f + ETHTOOL_MSG_TSCONFIG_SET_REPLY = 0x30 + ETHTOOL_MSG_KERNEL_MAX = 0x30 ETHTOOL_FLAG_COMPACT_BITSETS = 0x1 ETHTOOL_FLAG_OMIT_REPLY = 0x2 ETHTOOL_FLAG_STATS = 0x4 @@ -3949,7 +3979,12 @@ const ( ETHTOOL_A_RINGS_TCP_DATA_SPLIT = 0xb ETHTOOL_A_RINGS_CQE_SIZE = 0xc ETHTOOL_A_RINGS_TX_PUSH = 0xd - ETHTOOL_A_RINGS_MAX = 0x10 + ETHTOOL_A_RINGS_RX_PUSH = 0xe + ETHTOOL_A_RINGS_TX_PUSH_BUF_LEN = 0xf + ETHTOOL_A_RINGS_TX_PUSH_BUF_LEN_MAX = 0x10 + ETHTOOL_A_RINGS_HDS_THRESH = 0x11 + ETHTOOL_A_RINGS_HDS_THRESH_MAX = 0x12 + ETHTOOL_A_RINGS_MAX = 0x12 ETHTOOL_A_CHANNELS_UNSPEC = 0x0 ETHTOOL_A_CHANNELS_HEADER = 0x1 ETHTOOL_A_CHANNELS_RX_MAX = 0x2 @@ -4015,7 +4050,9 @@ const ( ETHTOOL_A_TSINFO_TX_TYPES = 0x3 ETHTOOL_A_TSINFO_RX_FILTERS = 0x4 ETHTOOL_A_TSINFO_PHC_INDEX = 0x5 - ETHTOOL_A_TSINFO_MAX = 0x6 + ETHTOOL_A_TSINFO_STATS = 0x6 + ETHTOOL_A_TSINFO_HWTSTAMP_PROVIDER = 0x7 + ETHTOOL_A_TSINFO_MAX = 0x9 ETHTOOL_A_CABLE_TEST_UNSPEC = 0x0 ETHTOOL_A_CABLE_TEST_HEADER = 0x1 ETHTOOL_A_CABLE_TEST_MAX = 0x1 @@ -4101,6 +4138,19 @@ const ( ETHTOOL_A_TUNNEL_INFO_MAX = 0x2 ) +const ( + TCP_V4_FLOW = 0x1 + UDP_V4_FLOW = 0x2 + TCP_V6_FLOW = 0x5 + UDP_V6_FLOW = 0x6 + ESP_V4_FLOW = 0xa + ESP_V6_FLOW = 0xc + IP_USER_FLOW = 0xd + IPV6_USER_FLOW = 0xe + IPV6_FLOW = 0x11 + ETHER_FLOW = 0x12 +) + const SPEED_UNKNOWN = -0x1 type EthtoolDrvinfo struct { @@ -4613,6 +4663,7 @@ const ( NL80211_ATTR_AKM_SUITES = 0x4c NL80211_ATTR_AP_ISOLATE = 0x60 NL80211_ATTR_AP_SETTINGS_FLAGS = 0x135 + NL80211_ATTR_ASSOC_SPP_AMSDU = 0x14a NL80211_ATTR_AUTH_DATA = 0x9c NL80211_ATTR_AUTH_TYPE = 0x35 NL80211_ATTR_BANDS = 0xef @@ -4623,6 +4674,7 @@ const ( NL80211_ATTR_BSS_BASIC_RATES = 0x24 NL80211_ATTR_BSS = 0x2f NL80211_ATTR_BSS_CTS_PROT = 0x1c + NL80211_ATTR_BSS_DUMP_INCLUDE_USE_DATA = 0x147 NL80211_ATTR_BSS_HT_OPMODE = 0x6d NL80211_ATTR_BSSID = 0xf5 NL80211_ATTR_BSS_SELECT = 0xe3 @@ -4682,6 +4734,7 @@ const ( NL80211_ATTR_DTIM_PERIOD = 0xd NL80211_ATTR_DURATION = 0x57 NL80211_ATTR_EHT_CAPABILITY = 0x136 + NL80211_ATTR_EMA_RNR_ELEMS = 0x145 NL80211_ATTR_EML_CAPABILITY = 0x13d NL80211_ATTR_EXT_CAPA = 0xa9 NL80211_ATTR_EXT_CAPA_MASK = 0xaa @@ -4717,6 +4770,7 @@ const ( NL80211_ATTR_HIDDEN_SSID = 0x7e NL80211_ATTR_HT_CAPABILITY = 0x1f NL80211_ATTR_HT_CAPABILITY_MASK = 0x94 + NL80211_ATTR_HW_TIMESTAMP_ENABLED = 0x144 NL80211_ATTR_IE_ASSOC_RESP = 0x80 NL80211_ATTR_IE = 0x2a NL80211_ATTR_IE_PROBE_RESP = 0x7f @@ -4747,9 +4801,10 @@ const ( NL80211_ATTR_MAC_HINT = 0xc8 NL80211_ATTR_MAC_MASK = 0xd7 NL80211_ATTR_MAX_AP_ASSOC_STA = 0xca - NL80211_ATTR_MAX = 0x14d + NL80211_ATTR_MAX = 0x151 NL80211_ATTR_MAX_CRIT_PROT_DURATION = 0xb4 NL80211_ATTR_MAX_CSA_COUNTERS = 0xce + NL80211_ATTR_MAX_HW_TIMESTAMP_PEERS = 0x143 NL80211_ATTR_MAX_MATCH_SETS = 0x85 NL80211_ATTR_MAX_NUM_AKM_SUITES = 0x13c NL80211_ATTR_MAX_NUM_PMKIDS = 0x56 @@ -4774,9 +4829,12 @@ const ( NL80211_ATTR_MGMT_SUBTYPE = 0x29 NL80211_ATTR_MLD_ADDR = 0x13a NL80211_ATTR_MLD_CAPA_AND_OPS = 0x13e + NL80211_ATTR_MLO_LINK_DISABLED = 0x146 NL80211_ATTR_MLO_LINK_ID = 0x139 NL80211_ATTR_MLO_LINKS = 0x138 NL80211_ATTR_MLO_SUPPORT = 0x13b + NL80211_ATTR_MLO_TTLM_DLINK = 0x148 + NL80211_ATTR_MLO_TTLM_ULINK = 0x149 NL80211_ATTR_MNTR_FLAGS = 0x17 NL80211_ATTR_MPATH_INFO = 0x1b NL80211_ATTR_MPATH_NEXT_HOP = 0x1a @@ -4809,12 +4867,14 @@ const ( NL80211_ATTR_PORT_AUTHORIZED = 0x103 NL80211_ATTR_POWER_RULE_MAX_ANT_GAIN = 0x5 NL80211_ATTR_POWER_RULE_MAX_EIRP = 0x6 + NL80211_ATTR_POWER_RULE_PSD = 0x8 NL80211_ATTR_PREV_BSSID = 0x4f NL80211_ATTR_PRIVACY = 0x46 NL80211_ATTR_PROBE_RESP = 0x91 NL80211_ATTR_PROBE_RESP_OFFLOAD = 0x90 NL80211_ATTR_PROTOCOL_FEATURES = 0xad NL80211_ATTR_PS_STATE = 0x5d + NL80211_ATTR_PUNCT_BITMAP = 0x142 NL80211_ATTR_QOS_MAP = 0xc7 NL80211_ATTR_RADAR_BACKGROUND = 0x134 NL80211_ATTR_RADAR_EVENT = 0xa8 @@ -4943,7 +5003,9 @@ const ( NL80211_ATTR_WIPHY_FREQ = 0x26 NL80211_ATTR_WIPHY_FREQ_HINT = 0xc9 NL80211_ATTR_WIPHY_FREQ_OFFSET = 0x122 + NL80211_ATTR_WIPHY_INTERFACE_COMBINATIONS = 0x14c NL80211_ATTR_WIPHY_NAME = 0x2 + NL80211_ATTR_WIPHY_RADIOS = 0x14b NL80211_ATTR_WIPHY_RETRY_LONG = 0x3e NL80211_ATTR_WIPHY_RETRY_SHORT = 0x3d NL80211_ATTR_WIPHY_RTS_THRESHOLD = 0x40 @@ -4978,6 +5040,8 @@ const ( NL80211_BAND_ATTR_IFTYPE_DATA = 0x9 NL80211_BAND_ATTR_MAX = 0xd NL80211_BAND_ATTR_RATES = 0x2 + NL80211_BAND_ATTR_S1G_CAPA = 0xd + NL80211_BAND_ATTR_S1G_MCS_NSS_SET = 0xc NL80211_BAND_ATTR_VHT_CAPA = 0x8 NL80211_BAND_ATTR_VHT_MCS_SET = 0x7 NL80211_BAND_IFTYPE_ATTR_EHT_CAP_MAC = 0x8 @@ -5001,6 +5065,10 @@ const ( NL80211_BSS_BEACON_INTERVAL = 0x4 NL80211_BSS_BEACON_TSF = 0xd NL80211_BSS_BSSID = 0x1 + NL80211_BSS_CANNOT_USE_6GHZ_PWR_MISMATCH = 0x2 + NL80211_BSS_CANNOT_USE_NSTR_NONPRIMARY = 0x1 + NL80211_BSS_CANNOT_USE_REASONS = 0x18 + NL80211_BSS_CANNOT_USE_UHB_PWR_MISMATCH = 0x2 NL80211_BSS_CAPABILITY = 0x5 NL80211_BSS_CHAIN_SIGNAL = 0x13 NL80211_BSS_CHAN_WIDTH_10 = 0x1 @@ -5032,6 +5100,9 @@ const ( NL80211_BSS_STATUS = 0x9 NL80211_BSS_STATUS_IBSS_JOINED = 0x2 NL80211_BSS_TSF = 0x3 + NL80211_BSS_USE_FOR = 0x17 + NL80211_BSS_USE_FOR_MLD_LINK = 0x2 + NL80211_BSS_USE_FOR_NORMAL = 0x1 NL80211_CHAN_HT20 = 0x1 NL80211_CHAN_HT40MINUS = 0x2 NL80211_CHAN_HT40PLUS = 0x3 @@ -5117,7 +5188,8 @@ const ( NL80211_CMD_LEAVE_IBSS = 0x2c NL80211_CMD_LEAVE_MESH = 0x45 NL80211_CMD_LEAVE_OCB = 0x6d - NL80211_CMD_MAX = 0x9b + NL80211_CMD_LINKS_REMOVED = 0x9a + NL80211_CMD_MAX = 0x9d NL80211_CMD_MICHAEL_MIC_FAILURE = 0x29 NL80211_CMD_MODIFY_LINK_STA = 0x97 NL80211_CMD_NAN_MATCH = 0x78 @@ -5161,6 +5233,7 @@ const ( NL80211_CMD_SET_COALESCE = 0x65 NL80211_CMD_SET_CQM = 0x3f NL80211_CMD_SET_FILS_AAD = 0x92 + NL80211_CMD_SET_HW_TIMESTAMP = 0x99 NL80211_CMD_SET_INTERFACE = 0x6 NL80211_CMD_SET_KEY = 0xa NL80211_CMD_SET_MAC_ACL = 0x5d @@ -5180,6 +5253,7 @@ const ( NL80211_CMD_SET_SAR_SPECS = 0x8c NL80211_CMD_SET_STATION = 0x12 NL80211_CMD_SET_TID_CONFIG = 0x89 + NL80211_CMD_SET_TID_TO_LINK_MAPPING = 0x9b NL80211_CMD_SET_TX_BITRATE_MASK = 0x39 NL80211_CMD_SET_WDS_PEER = 0x42 NL80211_CMD_SET_WIPHY = 0x2 @@ -5247,6 +5321,7 @@ const ( NL80211_EXT_FEATURE_AIRTIME_FAIRNESS = 0x21 NL80211_EXT_FEATURE_AP_PMKSA_CACHING = 0x22 NL80211_EXT_FEATURE_AQL = 0x28 + NL80211_EXT_FEATURE_AUTH_AND_DEAUTH_RANDOM_TA = 0x40 NL80211_EXT_FEATURE_BEACON_PROTECTION_CLIENT = 0x2e NL80211_EXT_FEATURE_BEACON_PROTECTION = 0x29 NL80211_EXT_FEATURE_BEACON_RATE_HE = 0x36 @@ -5262,6 +5337,7 @@ const ( NL80211_EXT_FEATURE_CQM_RSSI_LIST = 0xd NL80211_EXT_FEATURE_DATA_ACK_SIGNAL_SUPPORT = 0x1b NL80211_EXT_FEATURE_DEL_IBSS_STA = 0x2c + NL80211_EXT_FEATURE_DFS_CONCURRENT = 0x43 NL80211_EXT_FEATURE_DFS_OFFLOAD = 0x19 NL80211_EXT_FEATURE_ENABLE_FTM_RESPONDER = 0x20 NL80211_EXT_FEATURE_EXT_KEY_ID = 0x24 @@ -5281,9 +5357,12 @@ const ( NL80211_EXT_FEATURE_OCE_PROBE_REQ_DEFERRAL_SUPPRESSION = 0x14 NL80211_EXT_FEATURE_OCE_PROBE_REQ_HIGH_TX_RATE = 0x13 NL80211_EXT_FEATURE_OPERATING_CHANNEL_VALIDATION = 0x31 + NL80211_EXT_FEATURE_OWE_OFFLOAD_AP = 0x42 + NL80211_EXT_FEATURE_OWE_OFFLOAD = 0x41 NL80211_EXT_FEATURE_POWERED_ADDR_CHANGE = 0x3d NL80211_EXT_FEATURE_PROTECTED_TWT = 0x2b NL80211_EXT_FEATURE_PROT_RANGE_NEGO_AND_MEASURE = 0x39 + NL80211_EXT_FEATURE_PUNCT = 0x3e NL80211_EXT_FEATURE_RADAR_BACKGROUND = 0x3c NL80211_EXT_FEATURE_RRM = 0x1 NL80211_EXT_FEATURE_SAE_OFFLOAD_AP = 0x33 @@ -5295,8 +5374,10 @@ const ( NL80211_EXT_FEATURE_SCHED_SCAN_BAND_SPECIFIC_RSSI_THOLD = 0x23 NL80211_EXT_FEATURE_SCHED_SCAN_RELATIVE_RSSI = 0xc NL80211_EXT_FEATURE_SECURE_LTF = 0x37 + NL80211_EXT_FEATURE_SECURE_NAN = 0x3f NL80211_EXT_FEATURE_SECURE_RTT = 0x38 NL80211_EXT_FEATURE_SET_SCAN_DWELL = 0x5 + NL80211_EXT_FEATURE_SPP_AMSDU_SUPPORT = 0x44 NL80211_EXT_FEATURE_STA_TX_PWR = 0x25 NL80211_EXT_FEATURE_TXQS = 0x1c NL80211_EXT_FEATURE_UNSOL_BCAST_PROBE_RESP = 0x35 @@ -5343,7 +5424,10 @@ const ( NL80211_FREQUENCY_ATTR_2MHZ = 0x16 NL80211_FREQUENCY_ATTR_4MHZ = 0x17 NL80211_FREQUENCY_ATTR_8MHZ = 0x18 + NL80211_FREQUENCY_ATTR_ALLOW_6GHZ_VLP_AP = 0x21 + NL80211_FREQUENCY_ATTR_CAN_MONITOR = 0x20 NL80211_FREQUENCY_ATTR_DFS_CAC_TIME = 0xd + NL80211_FREQUENCY_ATTR_DFS_CONCURRENT = 0x1d NL80211_FREQUENCY_ATTR_DFS_STATE = 0x7 NL80211_FREQUENCY_ATTR_DFS_TIME = 0x8 NL80211_FREQUENCY_ATTR_DISABLED = 0x2 @@ -5351,12 +5435,14 @@ const ( NL80211_FREQUENCY_ATTR_GO_CONCURRENT = 0xf NL80211_FREQUENCY_ATTR_INDOOR_ONLY = 0xe NL80211_FREQUENCY_ATTR_IR_CONCURRENT = 0xf - NL80211_FREQUENCY_ATTR_MAX = 0x21 + NL80211_FREQUENCY_ATTR_MAX = 0x22 NL80211_FREQUENCY_ATTR_MAX_TX_POWER = 0x6 NL80211_FREQUENCY_ATTR_NO_10MHZ = 0x11 NL80211_FREQUENCY_ATTR_NO_160MHZ = 0xc NL80211_FREQUENCY_ATTR_NO_20MHZ = 0x10 NL80211_FREQUENCY_ATTR_NO_320MHZ = 0x1a + NL80211_FREQUENCY_ATTR_NO_6GHZ_AFC_CLIENT = 0x1f + NL80211_FREQUENCY_ATTR_NO_6GHZ_VLP_CLIENT = 0x1e NL80211_FREQUENCY_ATTR_NO_80MHZ = 0xb NL80211_FREQUENCY_ATTR_NO_EHT = 0x1b NL80211_FREQUENCY_ATTR_NO_HE = 0x13 @@ -5364,8 +5450,11 @@ const ( NL80211_FREQUENCY_ATTR_NO_HT40_PLUS = 0xa NL80211_FREQUENCY_ATTR_NO_IBSS = 0x3 NL80211_FREQUENCY_ATTR_NO_IR = 0x3 + NL80211_FREQUENCY_ATTR_NO_UHB_AFC_CLIENT = 0x1f + NL80211_FREQUENCY_ATTR_NO_UHB_VLP_CLIENT = 0x1e NL80211_FREQUENCY_ATTR_OFFSET = 0x14 NL80211_FREQUENCY_ATTR_PASSIVE_SCAN = 0x3 + NL80211_FREQUENCY_ATTR_PSD = 0x1c NL80211_FREQUENCY_ATTR_RADAR = 0x5 NL80211_FREQUENCY_ATTR_WMM = 0x12 NL80211_FTM_RESP_ATTR_CIVICLOC = 0x3 @@ -5430,6 +5519,7 @@ const ( NL80211_IFTYPE_STATION = 0x2 NL80211_IFTYPE_UNSPECIFIED = 0x0 NL80211_IFTYPE_WDS = 0x5 + NL80211_KCK_EXT_LEN_32 = 0x20 NL80211_KCK_EXT_LEN = 0x18 NL80211_KCK_LEN = 0x10 NL80211_KEK_EXT_LEN = 0x20 @@ -5458,9 +5548,10 @@ const ( NL80211_MAX_SUPP_HT_RATES = 0x4d NL80211_MAX_SUPP_RATES = 0x20 NL80211_MAX_SUPP_REG_RULES = 0x80 + NL80211_MAX_SUPP_SELECTORS = 0x80 NL80211_MBSSID_CONFIG_ATTR_EMA = 0x5 NL80211_MBSSID_CONFIG_ATTR_INDEX = 0x3 - NL80211_MBSSID_CONFIG_ATTR_MAX = 0x5 + NL80211_MBSSID_CONFIG_ATTR_MAX = 0x6 NL80211_MBSSID_CONFIG_ATTR_MAX_EMA_PROFILE_PERIODICITY = 0x2 NL80211_MBSSID_CONFIG_ATTR_MAX_INTERFACES = 0x1 NL80211_MBSSID_CONFIG_ATTR_TX_IFINDEX = 0x4 @@ -5703,11 +5794,16 @@ const ( NL80211_RADAR_PRE_CAC_EXPIRED = 0x4 NL80211_RATE_INFO_10_MHZ_WIDTH = 0xb NL80211_RATE_INFO_160_MHZ_WIDTH = 0xa + NL80211_RATE_INFO_16_MHZ_WIDTH = 0x1d + NL80211_RATE_INFO_1_MHZ_WIDTH = 0x19 + NL80211_RATE_INFO_2_MHZ_WIDTH = 0x1a NL80211_RATE_INFO_320_MHZ_WIDTH = 0x12 NL80211_RATE_INFO_40_MHZ_WIDTH = 0x3 + NL80211_RATE_INFO_4_MHZ_WIDTH = 0x1b NL80211_RATE_INFO_5_MHZ_WIDTH = 0xc NL80211_RATE_INFO_80_MHZ_WIDTH = 0x8 NL80211_RATE_INFO_80P80_MHZ_WIDTH = 0x9 + NL80211_RATE_INFO_8_MHZ_WIDTH = 0x1c NL80211_RATE_INFO_BITRATE32 = 0x5 NL80211_RATE_INFO_BITRATE = 0x1 NL80211_RATE_INFO_EHT_GI_0_8 = 0x0 @@ -5753,6 +5849,8 @@ const ( NL80211_RATE_INFO_HE_RU_ALLOC = 0x11 NL80211_RATE_INFO_MAX = 0x1d NL80211_RATE_INFO_MCS = 0x2 + NL80211_RATE_INFO_S1G_MCS = 0x17 + NL80211_RATE_INFO_S1G_NSS = 0x18 NL80211_RATE_INFO_SHORT_GI = 0x4 NL80211_RATE_INFO_VHT_MCS = 0x6 NL80211_RATE_INFO_VHT_NSS = 0x7 @@ -5770,14 +5868,19 @@ const ( NL80211_REKEY_DATA_KEK = 0x1 NL80211_REKEY_DATA_REPLAY_CTR = 0x3 NL80211_REPLAY_CTR_LEN = 0x8 + NL80211_RRF_ALLOW_6GHZ_VLP_AP = 0x1000000 NL80211_RRF_AUTO_BW = 0x800 NL80211_RRF_DFS = 0x10 + NL80211_RRF_DFS_CONCURRENT = 0x200000 NL80211_RRF_GO_CONCURRENT = 0x1000 NL80211_RRF_IR_CONCURRENT = 0x1000 NL80211_RRF_NO_160MHZ = 0x10000 NL80211_RRF_NO_320MHZ = 0x40000 + NL80211_RRF_NO_6GHZ_AFC_CLIENT = 0x800000 + NL80211_RRF_NO_6GHZ_VLP_CLIENT = 0x400000 NL80211_RRF_NO_80MHZ = 0x8000 NL80211_RRF_NO_CCK = 0x2 + NL80211_RRF_NO_EHT = 0x80000 NL80211_RRF_NO_HE = 0x20000 NL80211_RRF_NO_HT40 = 0x6000 NL80211_RRF_NO_HT40MINUS = 0x2000 @@ -5788,7 +5891,10 @@ const ( NL80211_RRF_NO_IR = 0x80 NL80211_RRF_NO_OFDM = 0x1 NL80211_RRF_NO_OUTDOOR = 0x8 + NL80211_RRF_NO_UHB_AFC_CLIENT = 0x800000 + NL80211_RRF_NO_UHB_VLP_CLIENT = 0x400000 NL80211_RRF_PASSIVE_SCAN = 0x80 + NL80211_RRF_PSD = 0x100000 NL80211_RRF_PTMP_ONLY = 0x40 NL80211_RRF_PTP_ONLY = 0x20 NL80211_RXMGMT_FLAG_ANSWERED = 0x1 @@ -5849,6 +5955,7 @@ const ( NL80211_STA_FLAG_MAX_OLD_API = 0x6 NL80211_STA_FLAG_MFP = 0x4 NL80211_STA_FLAG_SHORT_PREAMBLE = 0x2 + NL80211_STA_FLAG_SPP_AMSDU = 0x8 NL80211_STA_FLAG_TDLS_PEER = 0x6 NL80211_STA_FLAG_WME = 0x3 NL80211_STA_INFO_ACK_SIGNAL_AVG = 0x23 @@ -6007,6 +6114,13 @@ const ( NL80211_VHT_CAPABILITY_LEN = 0xc NL80211_VHT_NSS_MAX = 0x8 NL80211_WIPHY_NAME_MAXLEN = 0x40 + NL80211_WIPHY_RADIO_ATTR_FREQ_RANGE = 0x2 + NL80211_WIPHY_RADIO_ATTR_INDEX = 0x1 + NL80211_WIPHY_RADIO_ATTR_INTERFACE_COMBINATION = 0x3 + NL80211_WIPHY_RADIO_ATTR_MAX = 0x4 + NL80211_WIPHY_RADIO_FREQ_ATTR_END = 0x2 + NL80211_WIPHY_RADIO_FREQ_ATTR_MAX = 0x2 + NL80211_WIPHY_RADIO_FREQ_ATTR_START = 0x1 NL80211_WMMR_AIFSN = 0x3 NL80211_WMMR_CW_MAX = 0x2 NL80211_WMMR_CW_MIN = 0x1 @@ -6038,6 +6152,7 @@ const ( NL80211_WOWLAN_TRIG_PKT_PATTERN = 0x4 NL80211_WOWLAN_TRIG_RFKILL_RELEASE = 0x9 NL80211_WOWLAN_TRIG_TCP_CONNECTION = 0xe + NL80211_WOWLAN_TRIG_UNPROTECTED_DEAUTH_DISASSOC = 0x14 NL80211_WOWLAN_TRIG_WAKEUP_PKT_80211 = 0xa NL80211_WOWLAN_TRIG_WAKEUP_PKT_80211_LEN = 0xb NL80211_WOWLAN_TRIG_WAKEUP_PKT_8023 = 0xc diff --git a/vendor/golang.org/x/sys/unix/ztypes_linux_386.go b/vendor/golang.org/x/sys/unix/ztypes_linux_386.go index fd402da4..485f2d3a 100644 --- a/vendor/golang.org/x/sys/unix/ztypes_linux_386.go +++ b/vendor/golang.org/x/sys/unix/ztypes_linux_386.go @@ -282,7 +282,7 @@ type Taskstats struct { Ac_exitcode uint32 Ac_flag uint8 Ac_nice uint8 - _ [4]byte + _ [6]byte Cpu_count uint64 Cpu_delay_total uint64 Blkio_count uint64 @@ -338,6 +338,22 @@ type Taskstats struct { Wpcopy_delay_total uint64 Irq_count uint64 Irq_delay_total uint64 + Cpu_delay_max uint64 + Cpu_delay_min uint64 + Blkio_delay_max uint64 + Blkio_delay_min uint64 + Swapin_delay_max uint64 + Swapin_delay_min uint64 + Freepages_delay_max uint64 + Freepages_delay_min uint64 + Thrashing_delay_max uint64 + Thrashing_delay_min uint64 + Compact_delay_max uint64 + Compact_delay_min uint64 + Wpcopy_delay_max uint64 + Wpcopy_delay_min uint64 + Irq_delay_max uint64 + Irq_delay_min uint64 } type cpuMask uint32 diff --git a/vendor/golang.org/x/sys/unix/ztypes_linux_amd64.go b/vendor/golang.org/x/sys/unix/ztypes_linux_amd64.go index eb7a5e18..ecbd1ad8 100644 --- a/vendor/golang.org/x/sys/unix/ztypes_linux_amd64.go +++ b/vendor/golang.org/x/sys/unix/ztypes_linux_amd64.go @@ -351,6 +351,22 @@ type Taskstats struct { Wpcopy_delay_total uint64 Irq_count uint64 Irq_delay_total uint64 + Cpu_delay_max uint64 + Cpu_delay_min uint64 + Blkio_delay_max uint64 + Blkio_delay_min uint64 + Swapin_delay_max uint64 + Swapin_delay_min uint64 + Freepages_delay_max uint64 + Freepages_delay_min uint64 + Thrashing_delay_max uint64 + Thrashing_delay_min uint64 + Compact_delay_max uint64 + Compact_delay_min uint64 + Wpcopy_delay_max uint64 + Wpcopy_delay_min uint64 + Irq_delay_max uint64 + Irq_delay_min uint64 } type cpuMask uint64 diff --git a/vendor/golang.org/x/sys/unix/ztypes_linux_arm.go b/vendor/golang.org/x/sys/unix/ztypes_linux_arm.go index d78ac108..02f0463a 100644 --- a/vendor/golang.org/x/sys/unix/ztypes_linux_arm.go +++ b/vendor/golang.org/x/sys/unix/ztypes_linux_arm.go @@ -91,7 +91,7 @@ type Stat_t struct { Gid uint32 Rdev uint64 _ uint16 - _ [4]byte + _ [6]byte Size int64 Blksize int32 _ [4]byte @@ -273,7 +273,7 @@ type Taskstats struct { Ac_exitcode uint32 Ac_flag uint8 Ac_nice uint8 - _ [4]byte + _ [6]byte Cpu_count uint64 Cpu_delay_total uint64 Blkio_count uint64 @@ -329,6 +329,22 @@ type Taskstats struct { Wpcopy_delay_total uint64 Irq_count uint64 Irq_delay_total uint64 + Cpu_delay_max uint64 + Cpu_delay_min uint64 + Blkio_delay_max uint64 + Blkio_delay_min uint64 + Swapin_delay_max uint64 + Swapin_delay_min uint64 + Freepages_delay_max uint64 + Freepages_delay_min uint64 + Thrashing_delay_max uint64 + Thrashing_delay_min uint64 + Compact_delay_max uint64 + Compact_delay_min uint64 + Wpcopy_delay_max uint64 + Wpcopy_delay_min uint64 + Irq_delay_max uint64 + Irq_delay_min uint64 } type cpuMask uint32 diff --git a/vendor/golang.org/x/sys/unix/ztypes_linux_arm64.go b/vendor/golang.org/x/sys/unix/ztypes_linux_arm64.go index cd06d47f..6f4d400d 100644 --- a/vendor/golang.org/x/sys/unix/ztypes_linux_arm64.go +++ b/vendor/golang.org/x/sys/unix/ztypes_linux_arm64.go @@ -330,6 +330,22 @@ type Taskstats struct { Wpcopy_delay_total uint64 Irq_count uint64 Irq_delay_total uint64 + Cpu_delay_max uint64 + Cpu_delay_min uint64 + Blkio_delay_max uint64 + Blkio_delay_min uint64 + Swapin_delay_max uint64 + Swapin_delay_min uint64 + Freepages_delay_max uint64 + Freepages_delay_min uint64 + Thrashing_delay_max uint64 + Thrashing_delay_min uint64 + Compact_delay_max uint64 + Compact_delay_min uint64 + Wpcopy_delay_max uint64 + Wpcopy_delay_min uint64 + Irq_delay_max uint64 + Irq_delay_min uint64 } type cpuMask uint64 diff --git a/vendor/golang.org/x/sys/unix/ztypes_linux_loong64.go b/vendor/golang.org/x/sys/unix/ztypes_linux_loong64.go index 2f28fe26..cd532cfa 100644 --- a/vendor/golang.org/x/sys/unix/ztypes_linux_loong64.go +++ b/vendor/golang.org/x/sys/unix/ztypes_linux_loong64.go @@ -331,6 +331,22 @@ type Taskstats struct { Wpcopy_delay_total uint64 Irq_count uint64 Irq_delay_total uint64 + Cpu_delay_max uint64 + Cpu_delay_min uint64 + Blkio_delay_max uint64 + Blkio_delay_min uint64 + Swapin_delay_max uint64 + Swapin_delay_min uint64 + Freepages_delay_max uint64 + Freepages_delay_min uint64 + Thrashing_delay_max uint64 + Thrashing_delay_min uint64 + Compact_delay_max uint64 + Compact_delay_min uint64 + Wpcopy_delay_max uint64 + Wpcopy_delay_min uint64 + Irq_delay_max uint64 + Irq_delay_min uint64 } type cpuMask uint64 diff --git a/vendor/golang.org/x/sys/unix/ztypes_linux_mips.go b/vendor/golang.org/x/sys/unix/ztypes_linux_mips.go index 71d6cac2..41336208 100644 --- a/vendor/golang.org/x/sys/unix/ztypes_linux_mips.go +++ b/vendor/golang.org/x/sys/unix/ztypes_linux_mips.go @@ -278,7 +278,7 @@ type Taskstats struct { Ac_exitcode uint32 Ac_flag uint8 Ac_nice uint8 - _ [4]byte + _ [6]byte Cpu_count uint64 Cpu_delay_total uint64 Blkio_count uint64 @@ -334,6 +334,22 @@ type Taskstats struct { Wpcopy_delay_total uint64 Irq_count uint64 Irq_delay_total uint64 + Cpu_delay_max uint64 + Cpu_delay_min uint64 + Blkio_delay_max uint64 + Blkio_delay_min uint64 + Swapin_delay_max uint64 + Swapin_delay_min uint64 + Freepages_delay_max uint64 + Freepages_delay_min uint64 + Thrashing_delay_max uint64 + Thrashing_delay_min uint64 + Compact_delay_max uint64 + Compact_delay_min uint64 + Wpcopy_delay_max uint64 + Wpcopy_delay_min uint64 + Irq_delay_max uint64 + Irq_delay_min uint64 } type cpuMask uint32 diff --git a/vendor/golang.org/x/sys/unix/ztypes_linux_mips64.go b/vendor/golang.org/x/sys/unix/ztypes_linux_mips64.go index 8596d453..eaa37eb7 100644 --- a/vendor/golang.org/x/sys/unix/ztypes_linux_mips64.go +++ b/vendor/golang.org/x/sys/unix/ztypes_linux_mips64.go @@ -333,6 +333,22 @@ type Taskstats struct { Wpcopy_delay_total uint64 Irq_count uint64 Irq_delay_total uint64 + Cpu_delay_max uint64 + Cpu_delay_min uint64 + Blkio_delay_max uint64 + Blkio_delay_min uint64 + Swapin_delay_max uint64 + Swapin_delay_min uint64 + Freepages_delay_max uint64 + Freepages_delay_min uint64 + Thrashing_delay_max uint64 + Thrashing_delay_min uint64 + Compact_delay_max uint64 + Compact_delay_min uint64 + Wpcopy_delay_max uint64 + Wpcopy_delay_min uint64 + Irq_delay_max uint64 + Irq_delay_min uint64 } type cpuMask uint64 diff --git a/vendor/golang.org/x/sys/unix/ztypes_linux_mips64le.go b/vendor/golang.org/x/sys/unix/ztypes_linux_mips64le.go index cd60ea18..98ae6a1e 100644 --- a/vendor/golang.org/x/sys/unix/ztypes_linux_mips64le.go +++ b/vendor/golang.org/x/sys/unix/ztypes_linux_mips64le.go @@ -333,6 +333,22 @@ type Taskstats struct { Wpcopy_delay_total uint64 Irq_count uint64 Irq_delay_total uint64 + Cpu_delay_max uint64 + Cpu_delay_min uint64 + Blkio_delay_max uint64 + Blkio_delay_min uint64 + Swapin_delay_max uint64 + Swapin_delay_min uint64 + Freepages_delay_max uint64 + Freepages_delay_min uint64 + Thrashing_delay_max uint64 + Thrashing_delay_min uint64 + Compact_delay_max uint64 + Compact_delay_min uint64 + Wpcopy_delay_max uint64 + Wpcopy_delay_min uint64 + Irq_delay_max uint64 + Irq_delay_min uint64 } type cpuMask uint64 diff --git a/vendor/golang.org/x/sys/unix/ztypes_linux_mipsle.go b/vendor/golang.org/x/sys/unix/ztypes_linux_mipsle.go index b0ae420c..cae19615 100644 --- a/vendor/golang.org/x/sys/unix/ztypes_linux_mipsle.go +++ b/vendor/golang.org/x/sys/unix/ztypes_linux_mipsle.go @@ -278,7 +278,7 @@ type Taskstats struct { Ac_exitcode uint32 Ac_flag uint8 Ac_nice uint8 - _ [4]byte + _ [6]byte Cpu_count uint64 Cpu_delay_total uint64 Blkio_count uint64 @@ -334,6 +334,22 @@ type Taskstats struct { Wpcopy_delay_total uint64 Irq_count uint64 Irq_delay_total uint64 + Cpu_delay_max uint64 + Cpu_delay_min uint64 + Blkio_delay_max uint64 + Blkio_delay_min uint64 + Swapin_delay_max uint64 + Swapin_delay_min uint64 + Freepages_delay_max uint64 + Freepages_delay_min uint64 + Thrashing_delay_max uint64 + Thrashing_delay_min uint64 + Compact_delay_max uint64 + Compact_delay_min uint64 + Wpcopy_delay_max uint64 + Wpcopy_delay_min uint64 + Irq_delay_max uint64 + Irq_delay_min uint64 } type cpuMask uint32 diff --git a/vendor/golang.org/x/sys/unix/ztypes_linux_ppc.go b/vendor/golang.org/x/sys/unix/ztypes_linux_ppc.go index 83597287..6ce3b4e0 100644 --- a/vendor/golang.org/x/sys/unix/ztypes_linux_ppc.go +++ b/vendor/golang.org/x/sys/unix/ztypes_linux_ppc.go @@ -90,7 +90,7 @@ type Stat_t struct { Gid uint32 Rdev uint64 _ uint16 - _ [4]byte + _ [6]byte Size int64 Blksize int32 _ [4]byte @@ -285,7 +285,7 @@ type Taskstats struct { Ac_exitcode uint32 Ac_flag uint8 Ac_nice uint8 - _ [4]byte + _ [6]byte Cpu_count uint64 Cpu_delay_total uint64 Blkio_count uint64 @@ -341,6 +341,22 @@ type Taskstats struct { Wpcopy_delay_total uint64 Irq_count uint64 Irq_delay_total uint64 + Cpu_delay_max uint64 + Cpu_delay_min uint64 + Blkio_delay_max uint64 + Blkio_delay_min uint64 + Swapin_delay_max uint64 + Swapin_delay_min uint64 + Freepages_delay_max uint64 + Freepages_delay_min uint64 + Thrashing_delay_max uint64 + Thrashing_delay_min uint64 + Compact_delay_max uint64 + Compact_delay_min uint64 + Wpcopy_delay_max uint64 + Wpcopy_delay_min uint64 + Irq_delay_max uint64 + Irq_delay_min uint64 } type cpuMask uint32 diff --git a/vendor/golang.org/x/sys/unix/ztypes_linux_ppc64.go b/vendor/golang.org/x/sys/unix/ztypes_linux_ppc64.go index 69eb6a5c..c7429c6a 100644 --- a/vendor/golang.org/x/sys/unix/ztypes_linux_ppc64.go +++ b/vendor/golang.org/x/sys/unix/ztypes_linux_ppc64.go @@ -340,6 +340,22 @@ type Taskstats struct { Wpcopy_delay_total uint64 Irq_count uint64 Irq_delay_total uint64 + Cpu_delay_max uint64 + Cpu_delay_min uint64 + Blkio_delay_max uint64 + Blkio_delay_min uint64 + Swapin_delay_max uint64 + Swapin_delay_min uint64 + Freepages_delay_max uint64 + Freepages_delay_min uint64 + Thrashing_delay_max uint64 + Thrashing_delay_min uint64 + Compact_delay_max uint64 + Compact_delay_min uint64 + Wpcopy_delay_max uint64 + Wpcopy_delay_min uint64 + Irq_delay_max uint64 + Irq_delay_min uint64 } type cpuMask uint64 diff --git a/vendor/golang.org/x/sys/unix/ztypes_linux_ppc64le.go b/vendor/golang.org/x/sys/unix/ztypes_linux_ppc64le.go index 5f583cb6..4bf4baf4 100644 --- a/vendor/golang.org/x/sys/unix/ztypes_linux_ppc64le.go +++ b/vendor/golang.org/x/sys/unix/ztypes_linux_ppc64le.go @@ -340,6 +340,22 @@ type Taskstats struct { Wpcopy_delay_total uint64 Irq_count uint64 Irq_delay_total uint64 + Cpu_delay_max uint64 + Cpu_delay_min uint64 + Blkio_delay_max uint64 + Blkio_delay_min uint64 + Swapin_delay_max uint64 + Swapin_delay_min uint64 + Freepages_delay_max uint64 + Freepages_delay_min uint64 + Thrashing_delay_max uint64 + Thrashing_delay_min uint64 + Compact_delay_max uint64 + Compact_delay_min uint64 + Wpcopy_delay_max uint64 + Wpcopy_delay_min uint64 + Irq_delay_max uint64 + Irq_delay_min uint64 } type cpuMask uint64 diff --git a/vendor/golang.org/x/sys/unix/ztypes_linux_riscv64.go b/vendor/golang.org/x/sys/unix/ztypes_linux_riscv64.go index ad05b51a..e9709d70 100644 --- a/vendor/golang.org/x/sys/unix/ztypes_linux_riscv64.go +++ b/vendor/golang.org/x/sys/unix/ztypes_linux_riscv64.go @@ -358,6 +358,22 @@ type Taskstats struct { Wpcopy_delay_total uint64 Irq_count uint64 Irq_delay_total uint64 + Cpu_delay_max uint64 + Cpu_delay_min uint64 + Blkio_delay_max uint64 + Blkio_delay_min uint64 + Swapin_delay_max uint64 + Swapin_delay_min uint64 + Freepages_delay_max uint64 + Freepages_delay_min uint64 + Thrashing_delay_max uint64 + Thrashing_delay_min uint64 + Compact_delay_max uint64 + Compact_delay_min uint64 + Wpcopy_delay_max uint64 + Wpcopy_delay_min uint64 + Irq_delay_max uint64 + Irq_delay_min uint64 } type cpuMask uint64 diff --git a/vendor/golang.org/x/sys/unix/ztypes_linux_s390x.go b/vendor/golang.org/x/sys/unix/ztypes_linux_s390x.go index cf3ce900..fb44268c 100644 --- a/vendor/golang.org/x/sys/unix/ztypes_linux_s390x.go +++ b/vendor/golang.org/x/sys/unix/ztypes_linux_s390x.go @@ -353,6 +353,22 @@ type Taskstats struct { Wpcopy_delay_total uint64 Irq_count uint64 Irq_delay_total uint64 + Cpu_delay_max uint64 + Cpu_delay_min uint64 + Blkio_delay_max uint64 + Blkio_delay_min uint64 + Swapin_delay_max uint64 + Swapin_delay_min uint64 + Freepages_delay_max uint64 + Freepages_delay_min uint64 + Thrashing_delay_max uint64 + Thrashing_delay_min uint64 + Compact_delay_max uint64 + Compact_delay_min uint64 + Wpcopy_delay_max uint64 + Wpcopy_delay_min uint64 + Irq_delay_max uint64 + Irq_delay_min uint64 } type cpuMask uint64 diff --git a/vendor/golang.org/x/sys/unix/ztypes_linux_sparc64.go b/vendor/golang.org/x/sys/unix/ztypes_linux_sparc64.go index 590b5673..9c38265c 100644 --- a/vendor/golang.org/x/sys/unix/ztypes_linux_sparc64.go +++ b/vendor/golang.org/x/sys/unix/ztypes_linux_sparc64.go @@ -335,6 +335,22 @@ type Taskstats struct { Wpcopy_delay_total uint64 Irq_count uint64 Irq_delay_total uint64 + Cpu_delay_max uint64 + Cpu_delay_min uint64 + Blkio_delay_max uint64 + Blkio_delay_min uint64 + Swapin_delay_max uint64 + Swapin_delay_min uint64 + Freepages_delay_max uint64 + Freepages_delay_min uint64 + Thrashing_delay_max uint64 + Thrashing_delay_min uint64 + Compact_delay_max uint64 + Compact_delay_min uint64 + Wpcopy_delay_max uint64 + Wpcopy_delay_min uint64 + Irq_delay_max uint64 + Irq_delay_min uint64 } type cpuMask uint64 diff --git a/vendor/modules.txt b/vendor/modules.txt index ae89577c..f05f1c38 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -144,7 +144,7 @@ github.com/docker/go-connections/tlsconfig # github.com/docker/go-units v0.5.0 ## explicit github.com/docker/go-units -# github.com/docker/model-distribution v0.0.0-20250822172258-8fe9daa4a4da +# github.com/docker/model-distribution v0.0.0-20250905083217-3f098b3d8058 ## explicit; go 1.23.0 github.com/docker/model-distribution/builder github.com/docker/model-distribution/distribution @@ -157,7 +157,7 @@ github.com/docker/model-distribution/internal/store github.com/docker/model-distribution/registry github.com/docker/model-distribution/tarball github.com/docker/model-distribution/types -# github.com/docker/model-runner v0.0.0-20250822173738-5341c9fc2974 +# github.com/docker/model-runner v0.0.0-20250911130340-38bb0171c947 ## explicit; go 1.23.7 github.com/docker/model-runner/pkg/diskusage github.com/docker/model-runner/pkg/environment @@ -173,6 +173,8 @@ github.com/docker/model-runner/pkg/internal/dockerhub github.com/docker/model-runner/pkg/internal/jsonutil github.com/docker/model-runner/pkg/logging github.com/docker/model-runner/pkg/metrics +github.com/docker/model-runner/pkg/middleware +github.com/docker/model-runner/pkg/sandbox github.com/docker/model-runner/pkg/tailbuffer # github.com/elastic/go-sysinfo v1.15.3 ## explicit; go 1.21 @@ -309,6 +311,10 @@ github.com/klauspost/compress/internal/le github.com/klauspost/compress/internal/snapref github.com/klauspost/compress/zstd github.com/klauspost/compress/zstd/internal/xxhash +# github.com/kolesnikovae/go-winjob v1.0.0 => github.com/docker/go-winjob v0.0.0-20250829235554-57b487ebcbc5 +## explicit; go 1.23.0 +github.com/kolesnikovae/go-winjob +github.com/kolesnikovae/go-winjob/jobapi # github.com/mattn/go-colorable v0.1.13 ## explicit; go 1.15 github.com/mattn/go-colorable @@ -531,7 +537,7 @@ golang.org/x/net/trace golang.org/x/sync/errgroup golang.org/x/sync/semaphore golang.org/x/sync/singleflight -# golang.org/x/sys v0.33.0 +# golang.org/x/sys v0.35.0 ## explicit; go 1.23.0 golang.org/x/sys/cpu golang.org/x/sys/unix @@ -704,3 +710,4 @@ gopkg.in/yaml.v3 # howett.net/plist v1.0.1 ## explicit; go 1.12 howett.net/plist +# github.com/kolesnikovae/go-winjob => github.com/docker/go-winjob v0.0.0-20250829235554-57b487ebcbc5