func (n *Netns) execute(callback func(*os.File) error) error { logger := n.Logger.Session("execute", lager.Data{"namespace": n}) n.ThreadLocker.LockOSThread() defer n.ThreadLocker.UnlockOSThread() originalNamespace, err := os.Open(taskNamespacePath()) if err != nil { logger.Error("open", err) return fmt.Errorf("open failed: %s", err) } defer originalNamespace.Close() if err := ns.SetNS(n.File, syscall.CLONE_NEWNET); err != nil { logger.Error("set ns", err) return fmt.Errorf("set ns failed: %s", err) } defer func() { if err := ns.SetNS(originalNamespace, syscall.CLONE_NEWNET); err != nil { panic(err) } }() logger.Info("invoking-callback") if err := callback(originalNamespace); err != nil { logger.Error("callback-failed", err) return err } logger.Info("callback-complete") return nil }
// execute f() in tgtNS func withNetNS(curNS, tgtNS *os.File, f func() error) error { if err := ns.SetNS(tgtNS, syscall.CLONE_NEWNET); err != nil { return err } if err := f(); err != nil { // Attempt to revert the net ns in a known state if err := ns.SetNS(curNS, syscall.CLONE_NEWNET); err != nil { stderr.PrintE("cannot revert the net namespace", err) } return err } return ns.SetNS(curNS, syscall.CLONE_NEWNET) }
func newNetNS() (hostNS, childNS *os.File, err error) { defer func() { if err != nil { if hostNS != nil { hostNS.Close() } if childNS != nil { childNS.Close() } } }() hostNS, err = os.Open(selfNetNS) if err != nil { return } if err = syscall.Unshare(syscall.CLONE_NEWNET); err != nil { return } childNS, err = os.Open(selfNetNS) if err != nil { ns.SetNS(hostNS, syscall.CLONE_NEWNET) return } return }
// enterHostNS moves into the host's network namespace. func (n *Networking) enterHostNS() error { return ns.SetNS(n.hostNS, syscall.CLONE_NEWNET) }