Documentation
¶
Overview ¶
Package vmutils provides shared utility functions for working with Utility VMs.
This package contains stateless utility functions that can be used by both the legacy UVM management code (internal/uvm) and the new controller-based architecture (internal/controller). Functions in this package are designed to be decoupled from specific UVM implementations.
This allows different shims (containerd-shim-runhcs-v1, containerd-shim-lcow-v2) to share common logic while maintaining their own orchestration patterns.
Index ¶
- Constants
- Variables
- func DefaultLCOWOSBootFilesPath() string
- func DefaultProcessorCountForUVM() int32
- func LookupVMMEM(ctx context.Context, vmID guid.GUID, win iwin.API) (windows.Handle, error)
- func NormalizeMemorySize(ctx context.Context, uvmID string, requested uint64) uint64
- func NormalizeProcessorCount(ctx context.Context, uvmID string, requested int32, ...) int32
- func ParseUVMReferenceInfo(ctx context.Context, referenceRoot, referenceName string) (string, error)
- func PrepareVNumaTopology(ctx context.Context, opts *NumaConfig) (*hcsschema.Numa, *hcsschema.NumaProcessors, error)
- func UnmarshalRuntimeOptions(ctx context.Context, options *anypb.Any) (*runhcsoptions.Options, error)
- func ValidateNumaForVM(numa *hcsschema.Numa, procCount uint32, memInMb uint64) error
- type GCSLogEntry
- type GCSLogEntryStandard
- type NumaConfig
- type OutputHandler
- type OutputHandlerCreator
Constants ¶
const ( // MaxVPMEMCount is the maximum number of VPMem devices that may be added to an LCOW // utility VM. MaxVPMEMCount = 128 // DefaultVPMEMCount is the default number of VPMem devices that may be added to an LCOW // utility VM if the create request doesn't specify how many. DefaultVPMEMCount = 64 // DefaultVPMemSizeBytes is the default size of a VPMem device if the create request // doesn't specify. DefaultVPMemSizeBytes = 4 * memory.GiB // 4GB // DefaultDmVerityRootfsVhd is the default file name for a dm-verity rootfs VHD, // mounted by the GuestStateFile during boot and used as the root file system when // booting in the SNP case. Similar to layer VHDs, the Merkle tree is appended after // the ext4 filesystem ends. DefaultDmVerityRootfsVhd = "rootfs.vhd" // DefaultGuestStateFile is the default file name for a VMGS (VM Guest State) file, // which contains the kernel and kernel command that mounts DmVerityVhdFile when // booting in the SNP case. DefaultGuestStateFile = "kernel.vmgs" // DefaultUVMReferenceInfoFile is the default file name for a COSE_Sign1 reference // UVM info file, which can be made available to workload containers and used for // validation purposes. DefaultUVMReferenceInfoFile = "reference_info.cose" // InitrdFile is the default file name for an initrd.img used to boot LCOW. InitrdFile = "initrd.img" // VhdFile is the default file name for a rootfs.vhd used to boot LCOW. VhdFile = "rootfs.vhd" // KernelFile is the default file name for a kernel used to boot LCOW. KernelFile = "kernel" // UncompressedKernelFile is the default file name for an uncompressed // kernel used to boot LCOW with KernelDirect. UncompressedKernelFile = "vmlinux" // LinuxEntropyVsockPort is the vsock port used to inject initial entropy // into the LCOW guest VM during boot. LinuxEntropyVsockPort = 1 // LinuxLogVsockPort is the vsock port used by the GCS (Guest Compute Service) // to forward stdout/stderr log data from the guest to the host. LinuxLogVsockPort = 109 // LinuxEntropyBytes is the number of bytes of random data to send to a Linux UVM // during boot to seed the CRNG. There is not much point in making this too // large since the random data collected from the host is likely computed from a // relatively small key (256 bits?), so additional bytes would not actually // increase the entropy of the guest's pool. However, send enough to convince // containers that there is a large amount of entropy since this idea is // generally misunderstood. LinuxEntropyBytes = 512 // Plan9Port is the default port number for the 9p service in LCOW. Plan9Port = 564 )
Variables ¶
var ( // ErrCPUGroupCreateNotSupported is returned when a create request specifies a CPU group but the host build doesn't support it. ErrCPUGroupCreateNotSupported = fmt.Errorf("cpu group assignment on create requires a build of %d or higher", osversion.V21H1) )
Functions ¶
func DefaultLCOWOSBootFilesPath ¶
func DefaultLCOWOSBootFilesPath() string
DefaultLCOWOSBootFilesPath returns the default path used to locate the LCOW OS kernel and root FS files. This default is the subdirectory `LinuxBootFiles` in the directory of the executable that started the current process; or, if it does not exist, `%ProgramFiles%\Linux Containers`.
func DefaultProcessorCountForUVM ¶
func DefaultProcessorCountForUVM() int32
DefaultProcessorCountForUVM returns the default processor count to use for a utility VM. If the system has only 1 logical processor, it returns 1. Otherwise, it returns 2.
func LookupVMMEM ¶
LookupVMMEM locates the vmmem process for a VM given the VM ID. It enumerates processes using Toolhelp32 to filter by name, then validates the token using LookupAccount to match the "NT VIRTUAL MACHINE\<VM ID>" identity.
func NormalizeMemorySize ¶
NormalizeMemorySize aligns the requested memory size to an even number (2MB alignment).
func NormalizeProcessorCount ¶
func NormalizeProcessorCount(ctx context.Context, uvmID string, requested int32, processorTopology *hcsschema.ProcessorTopology) int32
NormalizeProcessorCount ensures that the requested processor count does not exceed the host's logical processor count as reported by HCS.
func ParseUVMReferenceInfo ¶
func ParseUVMReferenceInfo(ctx context.Context, referenceRoot, referenceName string) (string, error)
ParseUVMReferenceInfo reads the UVM reference info file, and base64 encodes the content if it exists.
func PrepareVNumaTopology ¶
func PrepareVNumaTopology(ctx context.Context, opts *NumaConfig) (*hcsschema.Numa, *hcsschema.NumaProcessors, error)
PrepareVNumaTopology creates vNUMA settings for implicit (platform) or explicit (user-defined) topology.
For implicit topology we look for `MaxProcessorsPerNumaNode`, `MaxMemorySizePerNumaNode` and `PreferredPhysicalNumaNodes` create options. Setting them in HCS doc will trigger platform to create vNUMA topology based on the given values. Based on experiments, the platform will create an evenly distributed topology based on requested memory and processor count for the HCS VM.
For explicit topology we look for `NumaMappedPhysicalNodes`, `NumaProcessorCounts` and `NumaMemoryBlocksCounts` create options. The above options are number slices, where a value at index `i` in each slice represents the corresponding value for the `i`th vNUMA node.
Limitations:
- only `hcsschema.MemoryBackingType_PHYSICAL` is supported
- `PhysicalNumaNodes` values at index `i` will be mapped to virtual node number `i`
- client is responsible for setting wildcard physical node numbers
func UnmarshalRuntimeOptions ¶
func UnmarshalRuntimeOptions(ctx context.Context, options *anypb.Any) (*runhcsoptions.Options, error)
UnmarshalRuntimeOptions decodes the runtime options into runhcsoptions.Options. When no options are provided (options == nil) it returns a non-nil, zero-value Options struct.
Types ¶
type GCSLogEntry ¶
type GCSLogEntry struct {
GCSLogEntryStandard
Fields map[string]interface{}
}
GCSLogEntry represents a complete GCS log entry including standard fields and any additional custom fields that may be present in the log output.
func (*GCSLogEntry) UnmarshalJSON ¶
func (e *GCSLogEntry) UnmarshalJSON(b []byte) error
UnmarshalJSON implements json.Unmarshaler for GCSLogEntry. It performs custom unmarshaling with the following behaviors:
- Sets default log level to Info if not specified
- Clamps log levels to Error or above (prevents Fatal/Panic propagation)
- Handles ETW (Event Tracing for Windows) log entries with alternate message field names
- Removes standard fields (time, level, msg) from the Fields map to avoid duplication
- Normalizes floating-point numbers that are whole numbers to int64
This method is optimized to minimize allocations and redundant map operations.
type GCSLogEntryStandard ¶
type GCSLogEntryStandard struct {
Time time.Time `json:"time"`
Level logrus.Level `json:"level"`
Message string `json:"msg"`
}
GCSLogEntryStandard represents the standard fields of a GCS log entry. These fields are common across all log entries and map directly to JSON fields.
type NumaConfig ¶
type NumaConfig struct {
// MaxProcessorsPerNumaNode is the maximum number of processors per vNUMA node.
MaxProcessorsPerNumaNode uint32
// MaxMemorySizePerNumaNode is the maximum size of memory (in MiB) per vNUMA node.
MaxMemorySizePerNumaNode uint64
// PreferredPhysicalNumaNodes are the preferred physical NUMA nodes to map to vNUMA nodes.
PreferredPhysicalNumaNodes []uint32
// NumaMappedPhysicalNodes are the physical NUMA nodes mapped to vNUMA nodes.
// The value at index i represents the physical node for virtual node i.
NumaMappedPhysicalNodes []uint32
// NumaProcessorCounts are the number of processors per vNUMA node.
// The value at index i represents the processor count for virtual node i.
NumaProcessorCounts []uint32
// NumaMemoryBlocksCounts are the number of memory blocks (in MiB) per vNUMA node.
// The value at index i represents the memory blocks for virtual node i.
NumaMemoryBlocksCounts []uint64
}
NumaConfig holds vNUMA topology configuration. This is a decoupled representation that can be constructed from various sources (uvm.Options, specs.SandboxSpec, etc.)
type OutputHandler ¶
OutputHandler processes the output stream from a program running in a UVM (Utility VM). It is responsible for reading, parsing, and handling the output data.
func ParseGCSLogrus ¶
func ParseGCSLogrus(vmID string) OutputHandler
ParseGCSLogrus creates an OutputHandler that parses and logs GCS (Guest Compute Service) output. It processes JSON-formatted log entries from the GCS and forwards them to the host's logging system.
The handler performs the following operations:
- Decodes JSON log entries from the GCS output stream
- Enriches each log entry with VM-specific metadata (VM ID and timestamp)
- Handles error conditions including disconnections and malformed input
- Captures and logs panic stacks or other non-JSON output from GCS termination
Parameters:
- vmID: The unique identifier of the VM whose logs are being processed
Returns:
- OutputHandler: A configured handler function for processing the VM's log stream
type OutputHandlerCreator ¶
type OutputHandlerCreator func(string) OutputHandler
OutputHandlerCreator is a factory function that creates an OutputHandler for a specific VM. It takes a VM ID and returns a configured OutputHandler for that VM's output.