Skip to content

Commit

Permalink
Cherry-pick netns cleanup changes
Browse files Browse the repository at this point in the history
  • Loading branch information
alexhulbert committed Sep 28, 2022
1 parent 2206275 commit 0c9bcba
Show file tree
Hide file tree
Showing 3 changed files with 76 additions and 1 deletion.
1 change: 1 addition & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ require (
github.com/sirupsen/logrus v1.7.0
github.com/sparrc/go-ping v0.0.0-20190613174326-4e5b6552494c
github.com/stretchr/testify v1.6.1
github.com/vishvananda/netns v0.0.0-20210104183010-2eb08e3e575f
github.com/vishvananda/netlink v1.1.0
golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd
)
9 changes: 8 additions & 1 deletion machine.go
Original file line number Diff line number Diff line change
Expand Up @@ -235,6 +235,8 @@ type Machine struct {
// callbacks that should be run when the machine is being torn down
cleanupOnce sync.Once
cleanupFuncs []func() error
// cleanupCh is a channel that gets closed to notify cleanup cleanupFuncs has been called totally
cleanupCh chan struct{}
}

// Logger returns a logrus logger appropriate for logging hypervisor messages
Expand Down Expand Up @@ -313,7 +315,8 @@ func configureBuilder(builder VMCommandBuilder, cfg Config) VMCommandBuilder {
// provided Config.
func NewMachine(ctx context.Context, cfg Config, opts ...Opt) (*Machine, error) {
m := &Machine{
exitCh: make(chan struct{}),
exitCh: make(chan struct{}),
cleanupCh: make(chan struct{}),
}

if cfg.VMID == "" {
Expand Down Expand Up @@ -541,6 +544,8 @@ func (m *Machine) startVMM(ctx context.Context) error {
// When err is nil, two reads are performed (waitForSocket and close exitCh goroutine),
// second one never ends as it tries to read from empty channel.
close(errCh)
close(m.cleanupCh)

}()

m.setupSignals()
Expand Down Expand Up @@ -589,6 +594,8 @@ func (m *Machine) stopVMM() error {
if err != nil && !strings.Contains(err.Error(), "os: process already finished") {
return err
}
// Wait for the cleanup to finish.
<-m.cleanupCh
return nil
}
m.logger.Debug("stopVMM(): no firecracker process running, not sending a signal")
Expand Down
67 changes: 67 additions & 0 deletions machine_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ import (
"context"
"errors"
"flag"
"fmt"
"github.com/vishvananda/netns"
"io"
"io/ioutil"
"net"
Expand Down Expand Up @@ -719,6 +721,71 @@ func testStopVMM(ctx context.Context, t *testing.T, m *Machine) {
}
}

func TestStopVMMCleanup(t *testing.T) {
fctesting.RequiresKVM(t)
fctesting.RequiresRoot(t)

socketPath, cleanup := makeSocketPath(t)
defer cleanup()

dir, err := ioutil.TempDir("", t.Name())
require.NoError(t, err)
defer os.RemoveAll(dir)

cniConfDir := filepath.Join(dir, "cni.conf")
err = os.MkdirAll(cniConfDir, 0777)
require.NoError(t, err)

cniBinPath := []string{testDataBin}

const networkName = "fcnet"
const ifName = "veth0"

networkMask := "/24"
subnet := "10.168.0.0" + networkMask

cniConfPath := fmt.Sprintf("%s/%s.conflist", cniConfDir, networkName)
err = writeCNIConfWithHostLocalSubnet(cniConfPath, networkName, subnet)
require.NoError(t, err)
defer os.Remove(cniConfPath)

networkInterface := NetworkInterface{
CNIConfiguration: &CNIConfiguration{
NetworkName: networkName,
IfName: ifName,
ConfDir: cniConfDir,
BinPath: cniBinPath,
VMIfName: "eth0",
},
}

cfg := Config{
SocketPath: socketPath,
DisableValidation: true,
KernelImagePath: getVmlinuxPath(t),
NetworkInterfaces: []NetworkInterface{networkInterface},
MachineCfg: models.MachineConfiguration{
VcpuCount: Int64(1),
MemSizeMib: Int64(64),
CPUTemplate: models.CPUTemplate(models.CPUTemplateT2),
Smt: Bool(false),
},
}
ctx := context.Background()
cmd := VMCommandBuilder{}.
WithSocketPath(cfg.SocketPath).
WithBin(getFirecrackerBinaryPath()).
Build(ctx)
m, err := NewMachine(ctx, cfg, WithProcessRunner(cmd), WithLogger(fctesting.NewLogEntry(t)))
require.NoError(t, err)
err = m.Start(ctx)
require.NoError(t, err)
err = m.stopVMM()
require.NoError(t, err)
_, err = netns.GetFromName(m.Cfg.VMID)
require.Error(t, err)
}

func testShutdown(ctx context.Context, t *testing.T, m *Machine) {
err := m.Shutdown(ctx)
if err != nil {
Expand Down

0 comments on commit 0c9bcba

Please sign in to comment.