podman
73 строки · 1.7 Кб
1package netns
2
3import (
4"fmt"
5
6"golang.org/x/sys/unix"
7)
8
9// NsHandle is a handle to a network namespace. It can be cast directly
10// to an int and used as a file descriptor.
11type NsHandle int
12
13// Equal determines if two network handles refer to the same network
14// namespace. This is done by comparing the device and inode that the
15// file descriptors point to.
16func (ns NsHandle) Equal(other NsHandle) bool {
17if ns == other {
18return true
19}
20var s1, s2 unix.Stat_t
21if err := unix.Fstat(int(ns), &s1); err != nil {
22return false
23}
24if err := unix.Fstat(int(other), &s2); err != nil {
25return false
26}
27return (s1.Dev == s2.Dev) && (s1.Ino == s2.Ino)
28}
29
30// String shows the file descriptor number and its dev and inode.
31func (ns NsHandle) String() string {
32if ns == -1 {
33return "NS(none)"
34}
35var s unix.Stat_t
36if err := unix.Fstat(int(ns), &s); err != nil {
37return fmt.Sprintf("NS(%d: unknown)", ns)
38}
39return fmt.Sprintf("NS(%d: %d, %d)", ns, s.Dev, s.Ino)
40}
41
42// UniqueId returns a string which uniquely identifies the namespace
43// associated with the network handle.
44func (ns NsHandle) UniqueId() string {
45if ns == -1 {
46return "NS(none)"
47}
48var s unix.Stat_t
49if err := unix.Fstat(int(ns), &s); err != nil {
50return "NS(unknown)"
51}
52return fmt.Sprintf("NS(%d:%d)", s.Dev, s.Ino)
53}
54
55// IsOpen returns true if Close() has not been called.
56func (ns NsHandle) IsOpen() bool {
57return ns != -1
58}
59
60// Close closes the NsHandle and resets its file descriptor to -1.
61// It is not safe to use an NsHandle after Close() is called.
62func (ns *NsHandle) Close() error {
63if err := unix.Close(int(*ns)); err != nil {
64return err
65}
66*ns = -1
67return nil
68}
69
70// None gets an empty (closed) NsHandle.
71func None() NsHandle {
72return NsHandle(-1)
73}
74