github.com/inspektor-gadget/inspektor-gadget@v0.28.1/pkg/utils/host/namespaces.go (about) 1 //go:build linux 2 // +build linux 3 4 // Copyright 2023 The Inspektor Gadget authors 5 // 6 // Licensed under the Apache License, Version 2.0 (the "License"); 7 // you may not use this file except in compliance with the License. 8 // You may obtain a copy of the License at 9 // 10 // http://www.apache.org/licenses/LICENSE-2.0 11 // 12 // Unless required by applicable law or agreed to in writing, software 13 // distributed under the License is distributed on an "AS IS" BASIS, 14 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 // See the License for the specific language governing permissions and 16 // limitations under the License. 17 18 // Package host provides ways to access the host filesystem. 19 // 20 // Inspektor Gadget can run either in the host or in a container. When running 21 // in a container, the host filesystem must be available in a specific 22 // directory. 23 package host 24 25 import ( 26 "fmt" 27 "os" 28 "sync" 29 "syscall" 30 ) 31 32 var ( 33 onceHostPidNs sync.Once 34 isHostPidNs bool 35 errHostPidNs error 36 37 onceHostNetNs sync.Once 38 isHostNetNs bool 39 errHostNetNs error 40 ) 41 42 // IsHostPidNs returns true if the current process is running in the host PID namespace 43 func IsHostPidNs() (bool, error) { 44 onceHostPidNs.Do(func() { 45 isHostPidNs, errHostPidNs = isHostNamespace("pid") 46 }) 47 return isHostPidNs, errHostPidNs 48 } 49 50 // IsHostNetNs returns true if the current process is running in the host network namespace 51 func IsHostNetNs() (bool, error) { 52 onceHostNetNs.Do(func() { 53 isHostNetNs, errHostNetNs = isHostNamespace("net") 54 }) 55 return isHostNetNs, errHostNetNs 56 } 57 58 // isHostNamespace checks if the current process is running in the specified host namespace 59 func isHostNamespace(nsKind string) (bool, error) { 60 if !initDone { 61 // HostProcFs can be overwritten by workarounds, so Init() must be called first. 62 return false, fmt.Errorf("host.Init() must be called before calling isHostNamespace()") 63 } 64 65 selfFileInfo, err := os.Stat("/proc/self/ns/" + nsKind) 66 if err != nil { 67 return false, err 68 } 69 selfStat, ok := selfFileInfo.Sys().(*syscall.Stat_t) 70 if !ok { 71 return false, fmt.Errorf("reading inode of /proc/self/ns/%s", nsKind) 72 } 73 74 systemdFileInfo, err := os.Stat(fmt.Sprintf("%s/1/ns/%s", HostProcFs, nsKind)) 75 if err != nil { 76 return false, err 77 } 78 systemdStat, ok := systemdFileInfo.Sys().(*syscall.Stat_t) 79 if !ok { 80 return false, fmt.Errorf("reading inode of %s/1/ns/%s", HostProcFs, nsKind) 81 } 82 83 return selfStat.Ino == systemdStat.Ino, nil 84 }