Files
Aishu KamalandHanzo Dev 4cbdcc589b tools/tpucheckpoint: standalone host-side client for tpu_control protocol
Add a CLI tool and Go library that speak the libtpu checkpoint/restore
control protocol (pkg/sentry/control/tpu_control.proto) against
unsandboxed processes.

gVisor coordinates libtpu C/R during sandbox save/restore
(pkg/sentry/control/tpu_control.go), but there is no way to exercise
or debug that protocol path without a full runsc save cycle. This tool
fills the gap: it discovers libtpu control threads by scanning
/proc/<pid>/task/*/comm, opens the encoded pipe FDs via /proc/<pid>/fd/,
and sends ControlRequest messages.

Accepts a comma-separated PID list and runs actions concurrently
across PIDs with per-PID results, for multi-process jobs that need all
processes checkpointed together.

Co-authored-by: Hanzo Dev <[email protected]>
2026-09-08 16:19:05 -07:00

89 lines
2.6 KiB
Go

// Copyright 2026 The gVisor Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package tpucontrol
import (
"fmt"
"strings"
tpupb "gvisor.dev/gvisor/pkg/sentry/control/tpu_control_proto_go_proto"
)
// actionName returns a short lower-case name for a control action, e.g.
// "checkpoint" for ACTION_CHECKPOINT.
func actionName(a tpupb.ControlAction) string {
return strings.ToLower(strings.TrimPrefix(a.String(), "ACTION_"))
}
// DiscoveryError indicates failure to find libtpu control threads.
type DiscoveryError struct {
PID int
Err error
}
// Error implements error.Error.
func (e *DiscoveryError) Error() string {
return fmt.Sprintf("discovery for PID %d: %v", e.PID, e.Err)
}
// Unwrap supports errors.Is/As.
func (e *DiscoveryError) Unwrap() error { return e.Err }
// TimeoutError indicates the operation timed out waiting for a response.
type TimeoutError struct {
Action tpupb.ControlAction
TID int
Err error
}
// Error implements error.Error.
func (e *TimeoutError) Error() string {
return fmt.Sprintf("%s timed out on thread %d: %v", actionName(e.Action), e.TID, e.Err)
}
// Unwrap supports errors.Is/As.
func (e *TimeoutError) Unwrap() error { return e.Err }
// ProtocolError indicates a wire-format or response parsing failure.
type ProtocolError struct {
Action tpupb.ControlAction
TID int
Err error
}
// Error implements error.Error.
func (e *ProtocolError) Error() string {
return fmt.Sprintf("%s protocol error on thread %d: %v", actionName(e.Action), e.TID, e.Err)
}
// Unwrap supports errors.Is/As.
func (e *ProtocolError) Unwrap() error { return e.Err }
// ControlFailedError indicates libtpu returned success=false.
type ControlFailedError struct {
Action tpupb.ControlAction
TID int
CurrentState tpupb.RuntimeState
ErrorMessage string
}
// Error implements error.Error.
func (e *ControlFailedError) Error() string {
if e.ErrorMessage != "" {
return fmt.Sprintf("%s failed on thread %d: %s", actionName(e.Action), e.TID, e.ErrorMessage)
}
return fmt.Sprintf("%s failed on thread %d: state=%s", actionName(e.Action), e.TID, e.CurrentState)
}