vc: fix netns leak

when kata container start fails, netns will leak, add a defer func
to fix it

Fixes: #1640

Signed-off-by: Ace-Tang <aceapril@126.com>
This commit is contained in:
Ace-Tang 2019-05-08 22:24:36 +08:00
parent 7327f8a77b
commit a5bc98c150
2 changed files with 34 additions and 1 deletions

View File

@ -173,7 +173,7 @@ func SetEphemeralStorageType(ociSpec oci.CompatOCISpec) oci.CompatOCISpec {
// CreateSandbox create a sandbox container
func CreateSandbox(ctx context.Context, vci vc.VC, ociSpec oci.CompatOCISpec, runtimeConfig oci.RuntimeConfig, rootFs vc.RootFs,
containerID, bundlePath, console string, disableOutput, systemdCgroup, builtIn bool) (vc.VCSandbox, vc.Process, error) {
containerID, bundlePath, console string, disableOutput, systemdCgroup, builtIn bool) (_ vc.VCSandbox, _ vc.Process, err error) {
span, ctx := Trace(ctx, "createSandbox")
defer span.Finish()
@ -204,6 +204,16 @@ func CreateSandbox(ctx context.Context, vci vc.VC, ociSpec oci.CompatOCISpec, ru
return nil, vc.Process{}, err
}
defer func() {
// cleanup netns if kata creates it
ns := sandboxConfig.NetworkConfig
if err != nil && ns.NetNsCreated {
if ex := cleanupNetNS(ns.NetNSPath); ex != nil {
kataUtilsLogger.WithField("path", ns.NetNSPath).WithError(ex).Warn("failed to cleanup netns")
}
}
}()
// Run pre-start OCI hooks.
err = EnterNetNS(sandboxConfig.NetworkConfig.NetNSPath, func() error {
return PreStartHooks(ctx, ociSpec, containerID, bundlePath)

View File

@ -66,6 +66,7 @@ func SetupNetworkNamespace(config *vc.NetworkConfig) error {
config.NetNSPath = n.Path()
config.NetNsCreated = true
kataUtilsLogger.WithField("netns", n.Path()).Info("create netns")
return nil
}
@ -179,3 +180,25 @@ func hostNetworkingRequested(configNetNs string) (bool, error) {
return false, nil
}
// cleanupNetNS cleanup netns created by kata, trigger only create sandbox fails
func cleanupNetNS(netNSPath string) error {
n, err := ns.GetNS(netNSPath)
if err != nil {
return fmt.Errorf("failed to get netns %s: %v", netNSPath, err)
}
err = n.Close()
if err != nil {
return fmt.Errorf("failed to close netns %s: %v", netNSPath, err)
}
if err = unix.Unmount(netNSPath, unix.MNT_DETACH); err != nil {
return fmt.Errorf("failed to unmount namespace %s: %v", netNSPath, err)
}
if err := os.RemoveAll(netNSPath); err != nil {
return fmt.Errorf("failed to clean up namespace %s: %v", netNSPath, err)
}
return nil
}