pkg/ns: don't allow operations after Close()

This commit is contained in:
Stefan Junker
2016-05-24 20:27:18 +02:00
parent 984ef8117a
commit b23895a7c7

View File

@ -58,6 +58,7 @@ type NetNS interface {
type netNS struct { type netNS struct {
file *os.File file *os.File
mounted bool mounted bool
closed bool
} }
func getCurrentThreadNetNSPath() string { func getCurrentThreadNetNSPath() string {
@ -165,8 +166,22 @@ func (ns *netNS) Fd() uintptr {
return ns.file.Fd() return ns.file.Fd()
} }
func (ns *netNS) errorIfClosed() error {
if ns.closed {
return fmt.Errorf("%q has already been closed", ns.file.Name())
}
return nil
}
func (ns *netNS) Close() error { func (ns *netNS) Close() error {
ns.file.Close() if err := ns.errorIfClosed(); err != nil {
return err
}
if err := ns.file.Close(); err != nil {
return fmt.Errorf("Failed to close %q: %v", ns.file.Name(), err)
}
ns.closed = true
if ns.mounted { if ns.mounted {
if err := unix.Unmount(ns.file.Name(), unix.MNT_DETACH); err != nil { if err := unix.Unmount(ns.file.Name(), unix.MNT_DETACH); err != nil {
@ -175,11 +190,17 @@ func (ns *netNS) Close() error {
if err := os.RemoveAll(ns.file.Name()); err != nil { if err := os.RemoveAll(ns.file.Name()); err != nil {
return fmt.Errorf("Failed to clean up namespace %s: %v", ns.file.Name(), err) return fmt.Errorf("Failed to clean up namespace %s: %v", ns.file.Name(), err)
} }
ns.mounted = false
} }
return nil return nil
} }
func (ns *netNS) Do(toRun func(NetNS) error) error { func (ns *netNS) Do(toRun func(NetNS) error) error {
if err := ns.errorIfClosed(); err != nil {
return err
}
containedCall := func(hostNS NetNS) error { containedCall := func(hostNS NetNS) error {
threadNS, err := GetNS(getCurrentThreadNetNSPath()) threadNS, err := GetNS(getCurrentThreadNetNSPath())
if err != nil { if err != nil {
@ -218,6 +239,10 @@ func (ns *netNS) Do(toRun func(NetNS) error) error {
} }
func (ns *netNS) Set() error { func (ns *netNS) Set() error {
if err := ns.errorIfClosed(); err != nil {
return err
}
if _, _, err := unix.Syscall(unix.SYS_SETNS, ns.Fd(), uintptr(unix.CLONE_NEWNET), 0); err != 0 { if _, _, err := unix.Syscall(unix.SYS_SETNS, ns.Fd(), uintptr(unix.CLONE_NEWNET), 0); err != 0 {
return fmt.Errorf("Error switching to ns %v: %v", ns.file.Name(), err) return fmt.Errorf("Error switching to ns %v: %v", ns.file.Name(), err)
} }