// ParseType parses s into a Type. func (p Process) ParseType(s string) Type { if s == "" { return Unknown } // See if it's a special value. if s[0] == '[' { switch s { case "[heap]": return Heap case "[stack]": return Stack case "[vsdo]": return VSDO case "[vsyscall]": return VSyscall case "[vvar]": return VVar } // Fish out stack with thread IDs like [stack:1234] if strings.HasPrefix(s, "[stack:") && s[len(s)-1] == ']' { return Stack } } // Probably is a path. // We can't use filepath.Ext here because if, for example, the path is: // /usr/share/lib/libc.so.6 // filepath.Ext will return ".6" which is a false negative for a .so file. if strings.HasSuffix(s, ".so") || strings.LastIndex(s, ".so.") > 0 { return Lib } var stat unix.Stat_t if err := unix.Stat(s, &stat); err != nil { return Unknown } ino := stat.Ino err := unix.Stat(p.exe, &stat) if err != nil { return Data } if stat.Ino == ino { return Exe } return Unknown }
func getStat(name string) (horcrux.Stat, error) { ustat := new(unix.Stat_t) err := unix.Stat(name, ustat) if err != nil { log.WithFields(log.Fields{"File": name, "Stat": ustat, "Error": err}).Error("Reducto: getStat - unix.Stat failed") return horcrux.Stat{}, err } mode := fileMode(ustat.Mode) stat := horcrux.Stat{Mode: mode, Uid: ustat.Uid, Gid: ustat.Gid, Size: ustat.Size} return stat, nil }
// LoadFileTime returns a FileTime associated with the file. func LoadFileTime(path string) (FileTime, error) { var ft = FileTime{} var st = unix.Stat_t{} err := unix.Stat(path, &st) if err != nil { return ft, err } ft.Changed = timeSpecToTime(st.Ctimespec) ft.Modified = timeSpecToTime(st.Mtimespec) ft.Accessed = timeSpecToTime(st.Atimespec) return ft, nil }
Describe("Execute", func() { var ( nsInode uint64 ns *namespace.Netns nsName string nsPath string ) BeforeEach(func() { nsName = fmt.Sprintf("ns-test-ns-%d", GinkgoParallelNode()) nsPath = fmt.Sprintf("/var/run/netns/%s", nsName) err := exec.Command("ip", "netns", "add", nsName).Run() Expect(err).NotTo(HaveOccurred()) var stat unix.Stat_t err = unix.Stat(nsPath, &stat) Expect(err).NotTo(HaveOccurred()) nsInode = stat.Ino nsFile, err := os.Open(nsPath) Expect(err).NotTo(HaveOccurred()) ns = &namespace.Netns{ File: nsFile, Logger: logger, ThreadLocker: threadLocker, } }) AfterEach(func() {
It("returns the error from open", func() { _, err := ns.Open() Expect(err).To(HaveOccurred()) }) }) }) Describe("Execute", func() { var nsInode uint64 BeforeEach(func() { err := exec.Command("ip", "netns", "add", "ns-test-ns").Run() Expect(err).NotTo(HaveOccurred()) var stat unix.Stat_t err = unix.Stat("/var/run/netns/ns-test-ns", &stat) Expect(err).NotTo(HaveOccurred()) nsInode = stat.Ino }) AfterEach(func() { err := exec.Command("ip", "netns", "delete", "ns-test-ns").Run() Expect(err).NotTo(HaveOccurred()) }) It("runs the closure in the namespace", func() { ns := namespace.NewNamespace("/var/run/netns/ns-test-ns") var namespaceInode string closure := func(f *os.File) error {
BeforeEach(func() { var err error repo, err = namespace.NewRepository(repoDir) Expect(err).NotTo(HaveOccurred()) }) It("creates a namespace in the repository", func() { ns, err := repo.Create("test-ns") Expect(err).NotTo(HaveOccurred()) Expect(ns.Name()).To(Equal("test-ns")) nsPath := filepath.Join(repoDir, "test-ns") defer unix.Unmount(nsPath, unix.MNT_DETACH) var repoStat unix.Stat_t err = unix.Stat(nsPath, &repoStat) Expect(err).NotTo(HaveOccurred()) var namespaceInode string callback := func(_ *os.File) error { // Stat of "/proc/self/ns/net" seemed to be flakey output, err := exec.Command("stat", "-L", "-c", "%i", "/proc/self/ns/net").CombinedOutput() namespaceInode = strings.TrimSpace(string(output)) return err } err = ns.Execute(callback) Expect(err).NotTo(HaveOccurred()) Expect(namespaceInode).To(Equal(fmt.Sprintf("%d", repoStat.Ino))) })
func getInode(path string) uint64 { stat := &unix.Stat_t{} err := unix.Stat(path, stat) Expect(err).NotTo(HaveOccurred()) return stat.Ino }