Skip to content

Commit 5146da5

Browse files
committed
Add wait for cleanup when stopVMM
Signed-off-by: Mathis Joffre <[email protected]>
1 parent 570d5fe commit 5146da5

File tree

3 files changed

+75
-1
lines changed

3 files changed

+75
-1
lines changed

go.mod

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ require (
1818
github.com/sirupsen/logrus v1.8.1
1919
github.com/stretchr/testify v1.8.0
2020
github.com/vishvananda/netlink v1.1.1-0.20210330154013-f5de75959ad5
21+
github.com/vishvananda/netns v0.0.0-20210104183010-2eb08e3e575f
2122
golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d
2223
golang.org/x/sys v0.0.0-20220204135822-1c1b9b1eba6a
2324
)

machine.go

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -232,6 +232,8 @@ type Machine struct {
232232
// callbacks that should be run when the machine is being torn down
233233
cleanupOnce sync.Once
234234
cleanupFuncs []func() error
235+
// cleanupCh is a channel that gets closed to notify cleanup cleanupFuncs has been called totally
236+
cleanupCh chan struct{}
235237
}
236238

237239
// Logger returns a logrus logger appropriate for logging hypervisor messages
@@ -316,7 +318,8 @@ func configureBuilder(builder VMCommandBuilder, cfg Config) VMCommandBuilder {
316318
// provided Config.
317319
func NewMachine(ctx context.Context, cfg Config, opts ...Opt) (*Machine, error) {
318320
m := &Machine{
319-
exitCh: make(chan struct{}),
321+
exitCh: make(chan struct{}),
322+
cleanupCh: make(chan struct{}),
320323
}
321324

322325
if cfg.VMID == "" {
@@ -560,6 +563,8 @@ func (m *Machine) startVMM(ctx context.Context) error {
560563
// When err is nil, two reads are performed (waitForSocket and close exitCh goroutine),
561564
// second one never ends as it tries to read from empty channel.
562565
close(errCh)
566+
close(m.cleanupCh)
567+
563568
}()
564569

565570
m.setupSignals()
@@ -608,6 +613,8 @@ func (m *Machine) stopVMM() error {
608613
if err != nil && !strings.Contains(err.Error(), "os: process already finished") {
609614
return err
610615
}
616+
// Wait for the cleanup to finish.
617+
<-m.cleanupCh
611618
return nil
612619
}
613620
m.logger.Debug("stopVMM(): no firecracker process running, not sending a signal")

machine_test.go

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ import (
1919
"errors"
2020
"flag"
2121
"fmt"
22+
"github.com/vishvananda/netns"
2223
"io"
2324
"io/ioutil"
2425
"net"
@@ -799,6 +800,71 @@ func testStopVMM(ctx context.Context, t *testing.T, m *Machine) {
799800
}
800801
}
801802

803+
func TestStopVMMCleanup(t *testing.T) {
804+
fctesting.RequiresKVM(t)
805+
fctesting.RequiresRoot(t)
806+
807+
socketPath, cleanup := makeSocketPath(t)
808+
defer cleanup()
809+
810+
dir, err := ioutil.TempDir("", t.Name())
811+
require.NoError(t, err)
812+
defer os.RemoveAll(dir)
813+
814+
cniConfDir := filepath.Join(dir, "cni.conf")
815+
err = os.MkdirAll(cniConfDir, 0777)
816+
require.NoError(t, err)
817+
818+
cniBinPath := []string{testDataBin}
819+
820+
const networkName = "fcnet"
821+
const ifName = "veth0"
822+
823+
networkMask := "/24"
824+
subnet := "10.168.0.0" + networkMask
825+
826+
cniConfPath := fmt.Sprintf("%s/%s.conflist", cniConfDir, networkName)
827+
err = writeCNIConfWithHostLocalSubnet(cniConfPath, networkName, subnet)
828+
require.NoError(t, err)
829+
defer os.Remove(cniConfPath)
830+
831+
networkInterface := NetworkInterface{
832+
CNIConfiguration: &CNIConfiguration{
833+
NetworkName: networkName,
834+
IfName: ifName,
835+
ConfDir: cniConfDir,
836+
BinPath: cniBinPath,
837+
VMIfName: "eth0",
838+
},
839+
}
840+
841+
cfg := Config{
842+
SocketPath: socketPath,
843+
DisableValidation: true,
844+
KernelImagePath: getVmlinuxPath(t),
845+
NetworkInterfaces: []NetworkInterface{networkInterface},
846+
MachineCfg: models.MachineConfiguration{
847+
VcpuCount: Int64(1),
848+
MemSizeMib: Int64(64),
849+
CPUTemplate: models.CPUTemplate(models.CPUTemplateT2),
850+
Smt: Bool(false),
851+
},
852+
}
853+
ctx := context.Background()
854+
cmd := VMCommandBuilder{}.
855+
WithSocketPath(cfg.SocketPath).
856+
WithBin(getFirecrackerBinaryPath()).
857+
Build(ctx)
858+
m, err := NewMachine(ctx, cfg, WithProcessRunner(cmd), WithLogger(fctesting.NewLogEntry(t)))
859+
require.NoError(t, err)
860+
err = m.Start(ctx)
861+
require.NoError(t, err)
862+
err = m.stopVMM()
863+
require.NoError(t, err)
864+
_, err = netns.GetFromName(m.Cfg.VMID)
865+
require.Error(t, err)
866+
}
867+
802868
func testShutdown(ctx context.Context, t *testing.T, m *Machine) {
803869
err := m.Shutdown(ctx)
804870
if err != nil {

0 commit comments

Comments
 (0)