Skip to content

Commit f1ff1b7

Browse files
committed
fix2
1 parent 49e2169 commit f1ff1b7

1 file changed

Lines changed: 14 additions & 19 deletions

File tree

hypervisor/cloudhypervisor/start.go

Lines changed: 14 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -20,8 +20,6 @@ import (
2020

2121
const socketWaitTimeout = 5 * time.Second
2222

23-
var savedNetns netns.NsHandle //nolint:gochecknoglobals
24-
2523
// Start launches the Cloud Hypervisor process for each VM ref.
2624
// Returns the IDs that were successfully started.
2725
func (ch *CloudHypervisor) Start(ctx context.Context, refs []string) ([]string, error) {
@@ -133,11 +131,11 @@ func (ch *CloudHypervisor) launchProcess(ctx context.Context, vmID, socketPath s
133131
// If the VM has network, CH must be launched inside the VM's netns
134132
// so it can access the tap device. We setns before fork and restore after.
135133
if withNetwork {
136-
if enterErr := enterNetns(ch.conf.CNINetnsPath(vmID)); enterErr != nil {
134+
restore, enterErr := enterNetns(ch.conf.CNINetnsPath(vmID))
135+
if enterErr != nil {
137136
return 0, fmt.Errorf("enter netns: %w", enterErr)
138137
}
139-
// Deferred restore happens after cmd.Start() forks the child.
140-
defer exitNetns()
138+
defer restore()
141139
}
142140

143141
if startErr := cmd.Start(); startErr != nil {
@@ -179,37 +177,34 @@ func waitForSocket(ctx context.Context, socketPath string, pid int) error {
179177

180178
// enterNetns locks the OS thread, saves the current netns, and switches
181179
// to the target netns. The forked child process inherits the new netns.
182-
// Call exitNetns (via defer) after cmd.Start() to restore.
183-
func enterNetns(nsPath string) error {
180+
// Returns a restore function that must be deferred by the caller.
181+
// No global state — safe for concurrent use.
182+
func enterNetns(nsPath string) (restore func(), err error) {
184183
runtime.LockOSThread()
185184

186185
orig, err := netns.Get()
187186
if err != nil {
188187
runtime.UnlockOSThread()
189-
return fmt.Errorf("get current netns: %w", err)
188+
return nil, fmt.Errorf("get current netns: %w", err)
190189
}
191-
savedNetns = orig
192190

193191
target, err := netns.GetFromPath(nsPath)
194192
if err != nil {
195193
_ = orig.Close()
196194
runtime.UnlockOSThread()
197-
return fmt.Errorf("open netns %s: %w", nsPath, err)
195+
return nil, fmt.Errorf("open netns %s: %w", nsPath, err)
198196
}
199197
defer target.Close() //nolint:errcheck
200198

201199
if err := netns.Set(target); err != nil {
202200
_ = orig.Close()
203201
runtime.UnlockOSThread()
204-
return fmt.Errorf("setns %s: %w", nsPath, err)
202+
return nil, fmt.Errorf("setns %s: %w", nsPath, err)
205203
}
206-
return nil
207-
}
208204

209-
// exitNetns restores the original netns and unlocks the OS thread.
210-
func exitNetns() {
211-
_ = netns.Set(savedNetns)
212-
_ = savedNetns.Close()
213-
savedNetns = -1
214-
runtime.UnlockOSThread()
205+
return func() {
206+
_ = netns.Set(orig)
207+
_ = orig.Close()
208+
runtime.UnlockOSThread()
209+
}, nil
215210
}

0 commit comments

Comments
 (0)