Skip to content

Commit f660bd8

Browse files
committed
review 2
Signed-off-by: Harsh Rawat <harshrawat@microsoft.com>
1 parent c874986 commit f660bd8

8 files changed

Lines changed: 66 additions & 164 deletions

File tree

internal/controller/vm/doc.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
//go:build windows
1+
//go:build windows && (lcow || wcow)
22

33
// Package vm provides a controller for managing the lifecycle of a Utility VM (UVM).
44
//

internal/controller/vm/state.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
//go:build windows
1+
//go:build windows && (lcow || wcow)
22

33
package vm
44

internal/controller/vm/types.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
//go:build windows
1+
//go:build windows && (lcow || wcow)
22

33
package vm
44

internal/controller/vm/vm.go

Lines changed: 62 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
//go:build windows
1+
//go:build windows && (lcow || wcow)
22

33
package vm
44

@@ -24,8 +24,6 @@ import (
2424
"github.com/Microsoft/hcsshim/internal/vm/vmmanager"
2525
"github.com/Microsoft/hcsshim/internal/vm/vmutils"
2626
iwin "github.com/Microsoft/hcsshim/internal/windows"
27-
"github.com/Microsoft/hcsshim/pkg/annotations"
28-
"github.com/Microsoft/hcsshim/pkg/ctrdtaskapi"
2927

3028
"github.com/Microsoft/go-winio/pkg/process"
3129
"github.com/containerd/errdefs"
@@ -236,41 +234,78 @@ func (c *Controller) StartVM(ctx context.Context, opts *StartOptions) (err error
236234
return nil
237235
}
238236

239-
// Update is used to update the VM configuration on-the-fly.
240-
// It supports modifying resources like CPU and memory while the VM is running.
241-
// It also supports injecting policy fragments or updating the CPU group id for the VM.
242-
func (c *Controller) Update(ctx context.Context, resources interface{}, annots map[string]string) error {
243-
ctx, _ = log.WithContext(ctx, logrus.WithField(logfields.Operation, "Update"))
237+
// UpdatePolicyFragment injects a security policy fragment into the running VM's guest.
238+
func (c *Controller) UpdatePolicyFragment(ctx context.Context, fragment guestresource.SecurityPolicyFragment) error {
239+
ctx, _ = log.WithContext(ctx, logrus.WithField(logfields.Operation, "UpdatePolicyFragment"))
244240

245241
c.mu.Lock()
246242
defer c.mu.Unlock()
247243

248244
if c.vmState != StateRunning {
249-
return fmt.Errorf("cannot update VM: VM is in state %s", c.vmState)
245+
return fmt.Errorf("cannot update policy fragment: VM is in state %s", c.vmState)
250246
}
251247

252-
// If the resource is a policy fragment, inject it directly into the guest and return.
253-
if policyFragment, ok := resources.(*ctrdtaskapi.PolicyFragment); ok {
254-
return c.guest.InjectPolicyFragment(ctx,
255-
guestresource.SecurityPolicyFragment{
256-
Fragment: policyFragment.Fragment,
257-
},
258-
)
248+
return c.guest.InjectPolicyFragment(ctx, fragment)
249+
}
250+
251+
// UpdateCPUGroup assigns the VM to the specified CPU group.
252+
func (c *Controller) UpdateCPUGroup(ctx context.Context, cpuGroupID string) error {
253+
ctx, _ = log.WithContext(ctx, logrus.WithField(logfields.Operation, "UpdateCPUGroup"))
254+
255+
c.mu.Lock()
256+
defer c.mu.Unlock()
257+
258+
if c.vmState != StateRunning {
259+
return fmt.Errorf("cannot update cpu group: VM is in state %s", c.vmState)
259260
}
260261

261-
// Apply generic VM resource updates (e.g., CPU count, memory).
262-
if err := c.updateVMResources(ctx, resources); err != nil {
263-
return fmt.Errorf("failed to update VM resources: %w", err)
262+
if cpuGroupID == "" {
263+
return errors.New("must specify an ID to use when configuring a VM's cpu group")
264264
}
265265

266-
// Update CPU group membership if the corresponding annotation is present.
267-
if cpuGroupID, ok := annots[annotations.CPUGroupID]; ok {
268-
if cpuGroupID == "" {
269-
return errors.New("must specify an ID to use when configuring a VM's cpugroup")
270-
}
271-
if err := c.uvm.SetCPUGroup(ctx, &hcsschema.CpuGroup{Id: cpuGroupID}); err != nil {
272-
return fmt.Errorf("failed to set CPU group: %w", err)
273-
}
266+
if err := c.uvm.SetCPUGroup(ctx, &hcsschema.CpuGroup{Id: cpuGroupID}); err != nil {
267+
return fmt.Errorf("failed to set CPU group: %w", err)
268+
}
269+
270+
return nil
271+
}
272+
273+
// UpdateCPU updates the CPU limits for the running VM.
274+
func (c *Controller) UpdateCPU(ctx context.Context, limits *hcsschema.ProcessorLimits) error {
275+
ctx, _ = log.WithContext(ctx, logrus.WithField(logfields.Operation, "UpdateCPU"))
276+
277+
c.mu.Lock()
278+
defer c.mu.Unlock()
279+
280+
if c.vmState != StateRunning {
281+
return fmt.Errorf("cannot update cpu limits: VM is in state %s", c.vmState)
282+
}
283+
284+
if err := c.uvm.UpdateCPULimits(ctx, limits); err != nil {
285+
return fmt.Errorf("failed to update vm cpu limits: %w", err)
286+
}
287+
288+
return nil
289+
}
290+
291+
// UpdateMemory updates the memory size for the running VM.
292+
// The requestedSizeInMB is normalized before being applied.
293+
func (c *Controller) UpdateMemory(ctx context.Context, requestedSizeInMB uint64) error {
294+
ctx, _ = log.WithContext(ctx, logrus.WithField(logfields.Operation, "UpdateMemory"))
295+
296+
c.mu.Lock()
297+
defer c.mu.Unlock()
298+
299+
if c.vmState != StateRunning {
300+
return fmt.Errorf("cannot update memory: VM is in state %s", c.vmState)
301+
}
302+
303+
// Normalize the requested memory size and apply it.
304+
// Internally, HCS will get the number of pages this corresponds to
305+
// and attempt to assign pages to numa nodes evenly.
306+
actual := vmutils.NormalizeMemorySize(ctx, c.vmID, requestedSizeInMB)
307+
if err := c.uvm.UpdateMemory(ctx, actual); err != nil {
308+
return fmt.Errorf("failed to update vm memory: %w", err)
274309
}
275310

276311
return nil

internal/controller/vm/vm_devices.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
//go:build windows
1+
//go:build windows && (lcow || wcow)
22

33
package vm
44

internal/controller/vm/vm_lcow.go

Lines changed: 0 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -9,15 +9,10 @@ import (
99
"io"
1010

1111
"github.com/Microsoft/hcsshim/internal/controller/device/plan9"
12-
hcsschema "github.com/Microsoft/hcsshim/internal/hcs/schema2"
13-
"github.com/Microsoft/hcsshim/internal/memory"
1412
"github.com/Microsoft/hcsshim/internal/vm/vmmanager"
1513
"github.com/Microsoft/hcsshim/internal/vm/vmutils"
16-
"github.com/Microsoft/hcsshim/osversion"
1714

1815
"github.com/Microsoft/go-winio"
19-
"github.com/containerd/errdefs"
20-
"github.com/opencontainers/runtime-spec/specs-go"
2116
"golang.org/x/sync/errgroup"
2217
)
2318

@@ -122,50 +117,3 @@ func (c *Controller) setupLoggingListener(ctx context.Context, group *errgroup.G
122117
func (c *Controller) finalizeGCSConnection(_ context.Context) error {
123118
return nil
124119
}
125-
126-
// updateVMResources applies Linux VM memory and CPU limits from OCI resources.
127-
func (c *Controller) updateVMResources(ctx context.Context, data interface{}) error {
128-
resources, ok := data.(*specs.LinuxResources)
129-
if !ok {
130-
return fmt.Errorf("invalid resource type %T, expected *specs.LinuxResources", data)
131-
}
132-
133-
if resources.Memory != nil {
134-
if resources.Memory.Limit == nil {
135-
return fmt.Errorf("invalid linux memory limit")
136-
}
137-
138-
sizeInBytes := uint64(*resources.Memory.Limit)
139-
// Make a call to the VM's orchestrator to update the VM's size in MB
140-
// Internally, HCS will get the number of pages this corresponds to and attempt to assign
141-
// pages to numa nodes evenly
142-
requestedSizeInMB := sizeInBytes / memory.MiB
143-
actual := vmutils.NormalizeMemorySize(ctx, c.vmID, requestedSizeInMB)
144-
145-
if err := c.uvm.UpdateMemory(ctx, actual); err != nil {
146-
return fmt.Errorf("update vm memory: %w", err)
147-
}
148-
}
149-
150-
// Translate OCI CPU knobs to HCS processor limits.
151-
if resources.CPU != nil {
152-
processorLimits := &hcsschema.ProcessorLimits{}
153-
if resources.CPU.Quota != nil {
154-
processorLimits.Limit = uint64(*resources.CPU.Quota)
155-
}
156-
if resources.CPU.Shares != nil {
157-
processorLimits.Weight = uint64(*resources.CPU.Shares)
158-
}
159-
160-
// Support for updating CPU limits was not added until 20H2 build
161-
if osversion.Get().Build < osversion.V20H2 {
162-
return errdefs.ErrNotImplemented
163-
}
164-
165-
if err := c.uvm.UpdateCPULimits(ctx, processorLimits); err != nil {
166-
return fmt.Errorf("update vm cpu limits: %w", err)
167-
}
168-
}
169-
170-
return nil
171-
}

internal/controller/vm/vm_unsupported.go

Lines changed: 0 additions & 30 deletions
This file was deleted.

internal/controller/vm/vm_wcow.go

Lines changed: 0 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -10,13 +10,9 @@ import (
1010
"github.com/Microsoft/go-winio"
1111
"github.com/Microsoft/hcsshim/internal/gcs/prot"
1212
hcsschema "github.com/Microsoft/hcsshim/internal/hcs/schema2"
13-
"github.com/Microsoft/hcsshim/internal/memory"
1413
"github.com/Microsoft/hcsshim/internal/vm/vmmanager"
1514
"github.com/Microsoft/hcsshim/internal/vm/vmutils"
16-
"github.com/Microsoft/hcsshim/osversion"
1715

18-
"github.com/containerd/errdefs"
19-
"github.com/opencontainers/runtime-spec/specs-go"
2016
"github.com/sirupsen/logrus"
2117
"golang.org/x/net/netutil"
2218
"golang.org/x/sync/errgroup"
@@ -122,50 +118,3 @@ func (c *Controller) finalizeGCSConnection(ctx context.Context) error {
122118

123119
return nil
124120
}
125-
126-
// updateVMResources applies Windows VM memory and CPU limits from OCI resources.
127-
func (c *Controller) updateVMResources(ctx context.Context, data interface{}) error {
128-
resources, ok := data.(*specs.WindowsResources)
129-
if !ok {
130-
return fmt.Errorf("invalid resource type %T, expected *specs.WindowsResources", data)
131-
}
132-
133-
if resources.Memory != nil {
134-
if resources.Memory.Limit == nil {
135-
return fmt.Errorf("invalid windows memory limit: nil")
136-
}
137-
138-
sizeInBytes := *resources.Memory.Limit
139-
// Make a call to the VM's orchestrator to update the VM's size in MB
140-
// Internally, HCS will get the number of pages this corresponds to and attempt to assign
141-
// pages to numa nodes evenly
142-
requestedSizeInMB := sizeInBytes / memory.MiB
143-
actual := vmutils.NormalizeMemorySize(ctx, c.vmID, requestedSizeInMB)
144-
145-
if err := c.uvm.UpdateMemory(ctx, actual); err != nil {
146-
return fmt.Errorf("update vm memory: %w", err)
147-
}
148-
}
149-
150-
// Translate OCI CPU knobs to HCS processor limits.
151-
if resources.CPU != nil {
152-
processorLimits := &hcsschema.ProcessorLimits{}
153-
if resources.CPU.Maximum != nil {
154-
processorLimits.Limit = uint64(*resources.CPU.Maximum)
155-
}
156-
if resources.CPU.Shares != nil {
157-
processorLimits.Weight = uint64(*resources.CPU.Shares)
158-
}
159-
160-
// Support for updating CPU limits was not added until 20H2 build
161-
if osversion.Get().Build < osversion.V20H2 {
162-
return errdefs.ErrNotImplemented
163-
}
164-
165-
if err := c.uvm.UpdateCPULimits(ctx, processorLimits); err != nil {
166-
return fmt.Errorf("update vm cpu limits: %w", err)
167-
}
168-
}
169-
170-
return nil
171-
}

0 commit comments

Comments
 (0)