Example #1
0
// Equal determines if two network handles refer to the same network
// namespace. This is done by comparing the device and inode that the
// file descripors point to.
func (ns NsHandle) Equal(other NsHandle) bool {
	var s1, s2 syscall.Stat_t
	if err := syscall.Fstat(int(ns), &s1); err != nil {
		return false
	}
	if err := syscall.Fstat(int(other), &s2); err != nil {
		return false
	}
	return (s1.Dev == s2.Dev) && (s1.Ino == s2.Ino)
}
Example #2
0
func getHandle(fn string) (*handle, error) {
	f, err := os.OpenFile(fn, O_PATH, 0)
	if err != nil {
		return nil, errors.Wrapf(err, "failed to open %v with O_PATH", fn)
	}

	var stat syscall.Stat_t
	if err := syscall.Fstat(int(f.Fd()), &stat); err != nil {
		f.Close()
		return nil, errors.Wrapf(err, "failed to stat handle %v", f.Fd())
	}

	h := &handle{
		f:    f,
		name: fn,
		dev:  stat.Dev,
		ino:  stat.Ino,
	}

	// check /proc just in case
	if _, err := os.Stat(h.procPath()); err != nil {
		f.Close()
		return nil, errors.Wrapf(err, "couldn't stat %v", h.procPath())
	}

	return h, nil
}
Example #3
0
func NewNetNSProbe(g *graph.Graph, n *graph.Node, runPath ...string) (*NetNSProbe, error) {
	if uid := os.Geteuid(); uid != 0 {
		return nil, errors.New("NetNS probe has to be run as root")
	}

	path := "/var/run/netns"
	if len(runPath) > 0 && runPath[0] != "" {
		path = runPath[0]
	}

	rootNs, err := netns.Get()
	if err != nil {
		return nil, errors.New("Failed to get root namespace")
	}
	defer rootNs.Close()

	var stats syscall.Stat_t
	if err := syscall.Fstat(int(rootNs), &stats); err != nil {
		return nil, errors.New("Failed to stat root namespace")
	}

	return &NetNSProbe{
		Graph:       g,
		Root:        n,
		nsnlProbes:  make(map[string]*NetNsNetLinkTopoUpdater),
		pathToNetNS: make(map[string]*NetNs),
		runPath:     path,
		rootNsDev:   stats.Dev,
	}, nil
}
Example #4
0
func (h *Handle) getFileSize() (uint64, error) {
	var stat syscall.Stat_t
	if err := syscall.Fstat(int(h.file.Fd()), &stat); err != nil {
		return 0, osErrorToFuseError(err)
	}
	return uint64(stat.Size), nil
}
Example #5
0
func getBlkSize(f *os.File) (uint32, error) {
	var stat syscall.Stat_t
	if err := syscall.Fstat(int(f.Fd()), &stat); err != nil {
		return 0, osErrorToFuseError(err)
	}
	return uint32(stat.Blksize), nil
}
Example #6
0
// String shows the file descriptor number and its dev and inode.
func (ns NsHandle) String() string {
	var s syscall.Stat_t
	if err := syscall.Fstat(int(ns), &s); err != nil {
		return fmt.Sprintf("NS(%d: unknown)", ns)
	}
	return fmt.Sprintf("NS(%d: %d, %d)", ns, s.Dev, s.Ino)
}
Example #7
0
// fixStdioPermissions fixes the permissions of PID 1's STDIO within the container to the specified user.
// The ownership needs to match because it is created outside of the container and needs to be
// localized.
func fixStdioPermissions(u *user.ExecUser) error {
	var null syscall.Stat_t
	if err := syscall.Stat("/dev/null", &null); err != nil {
		return err
	}
	for _, fd := range []uintptr{
		os.Stdin.Fd(),
		os.Stderr.Fd(),
		os.Stdout.Fd(),
	} {
		var s syscall.Stat_t
		if err := syscall.Fstat(int(fd), &s); err != nil {
			return err
		}
		// skip chown of /dev/null if it was used as one of the STDIO fds.
		if s.Rdev == null.Rdev {
			continue
		}
		// Operation not permitted error on unprivileged container
		//if err := syscall.Fchown(int(fd), u.Uid, u.Gid); err != nil {
		//	return err
		//}
	}
	return nil
}
Example #8
0
File: file.go Project: matomesc/rkt
// NewLock opens a new lock on a file without acquisition
func NewLock(path string, lockType LockType) (*FileLock, error) {
	l := &FileLock{path: path, fd: -1}

	mode := syscall.O_RDONLY | syscall.O_CLOEXEC
	if lockType == Dir {
		mode |= syscall.O_DIRECTORY
	}
	lfd, err := syscall.Open(l.path, mode, 0)
	if err != nil {
		if err == syscall.ENOENT {
			err = ErrNotExist
		} else if err == syscall.EACCES {
			err = ErrPermission
		}
		return nil, err
	}
	l.fd = lfd

	var stat syscall.Stat_t
	err = syscall.Fstat(lfd, &stat)
	if err != nil {
		return nil, err
	}
	// Check if the file is a regular file
	if lockType == RegFile && !(stat.Mode&syscall.S_IFMT == syscall.S_IFREG) {
		return nil, ErrNotRegular
	}

	return l, nil
}
Example #9
0
// fixStdioPermissions fixes the permissions of PID 1's STDIO within the container to the specified user.
// The ownership needs to match because it is created outside of the container and needs to be
// localized.
func fixStdioPermissions(u *user.ExecUser) error {
	var null syscall.Stat_t
	if err := syscall.Stat("/dev/null", &null); err != nil {
		return err
	}
	for _, fd := range []uintptr{
		os.Stdin.Fd(),
		os.Stderr.Fd(),
		os.Stdout.Fd(),
	} {
		var s syscall.Stat_t
		if err := syscall.Fstat(int(fd), &s); err != nil {
			return err
		}
		// Skip chown of /dev/null if it was used as one of the STDIO fds.
		if s.Rdev == null.Rdev {
			continue
		}
		// We only change the uid owner (as it is possible for the mount to
		// prefer a different gid, and there's no reason for us to change it).
		// The reason why we don't just leave the default uid=X mount setup is
		// that users expect to be able to actually use their console. Without
		// this code, you couldn't effectively run as a non-root user inside a
		// container and also have a console set up.
		if err := syscall.Fchown(int(fd), u.Uid, int(s.Gid)); err != nil {
			return err
		}
	}
	return nil
}
Example #10
0
func touch(filename string, nacc, nmod int64) (errcnt int) {
	var st syscall.Stat_t
	var ut syscall.Utimbuf

	if e := syscall.Stat(filename, &st); e != 0 {
		if e == syscall.ENOENT {

			if *cflag {
				errcnt++
				return
			}

			var fd int
			defer syscall.Close(fd)

			if fd, e = syscall.Creat(filename, 0666); e != 0 {
				fmt.Fprintf(os.Stderr, "touch: can not create %s\n", filename)
				errcnt += 1
				return
			}

			if e = syscall.Fstat(fd, &st); e != 0 {
				fmt.Fprintf(os.Stderr, "touch: can't stat %s\n", filename)
				errcnt += 1
				return
			}
		} else {
			fmt.Fprintf(os.Stderr, "touch: can't stat %s\n", filename)
			errcnt += 1
			return
		}
	}

	if *aflag {
		ut.Actime = nacc
	} else {
		ut.Actime = st.Atim.Sec
	}

	if *mflag {
		ut.Modtime = nmod
	} else {
		ut.Modtime = st.Mtim.Sec
	}

	if nulltime {
		if e := syscall.Utime(filename, nil); e != 0 {
			fmt.Fprintf(os.Stderr, "touch: unable to touch %s", filename)
			errcnt += 1
		}
	} else {
		if e := syscall.Utime(filename, &ut); e != 0 {
			fmt.Fprintf(os.Stderr, "touch: unable to touch %s", filename)
			errcnt += 1
		}
	}

	return
}
Example #11
0
// Stat returns the Dir structure describing file.
// It returns the Dir and an error, if any.
func (file *File) Stat() (dir *Dir, err Error) {
	var stat syscall.Stat_t
	e := syscall.Fstat(file.fd, &stat)
	if e != 0 {
		return nil, &PathError{"stat", file.name, Errno(e)}
	}
	return dirFromStat(file.name, new(Dir), &stat, &stat), nil
}
Example #12
0
// isatty reports whether fd is a tty.
// Actually it reports whether fd is a character device, which is close enough.
func isatty(fd int) bool {
	var st syscall.Stat_t
	err := syscall.Fstat(fd, &st)
	if err != nil {
		return false
	}
	return st.Mode&syscall.S_IFMT == syscall.S_IFCHR
}
Example #13
0
// Stat returns the FileInfo structure describing file.
// If there is an error, it will be of type *PathError.
func (f *File) Stat() (fi FileInfo, err error) {
	var stat syscall.Stat_t
	err = syscall.Fstat(f.fd, &stat)
	if err != nil {
		return nil, &PathError{"stat", f.name, err}
	}
	return fileInfoFromStat(&stat, f.name), nil
}
Example #14
0
// Stat returns the FileInfo structure describing file.
// It returns the FileInfo and an error, if any.
func (file *File) Stat() (fi *FileInfo, err Error) {
	var stat syscall.Stat_t
	e := syscall.Fstat(file.fd, &stat)
	if e != 0 {
		return nil, &PathError{"stat", file.name, Errno(e)}
	}
	return fileInfoFromStat(file.name, new(FileInfo), &stat, &stat), nil
}
Example #15
0
func open(path string) (*os.File, error) {
	var f *os.File
	var err error

	for {
		f, err = os.OpenFile(path,
			syscall.O_RDWR|syscall.O_CREAT|syscall.O_EXCL, 0644)
		if err != nil {
			if !os.IsExist(err) {
				return nil, err
			}

			f, err = os.OpenFile(path, syscall.O_RDWR, 0644)
			if err != nil {
				if os.IsNotExist(err) {
					continue
				}
				return nil, err
			}
		}

		err = syscall.FcntlFlock(f.Fd(), syscall.F_SETLK, &syscall.Flock_t{
			Type: syscall.F_WRLCK,
		})
		if err != nil {
			f.Close()
			return nil, err
		}

		st1 := syscall.Stat_t{}
		err = syscall.Fstat(int(f.Fd()), &st1) // ffs
		if err != nil {
			f.Close()
			return nil, err
		}

		st2 := syscall.Stat_t{}
		err = syscall.Stat(path, &st2)
		if err != nil {
			f.Close()

			if os.IsNotExist(err) {
				continue
			}

			return nil, err
		}

		if st1.Ino != st2.Ino {
			f.Close()
			continue
		}

		break
	}

	return f, nil
}
Example #16
0
// Du returns the disk usage of the file "fd" points to, in bytes.
// Same as "du --block-size=1".
func Du(t *testing.T, fd int) (nBytes int64) {
	var st syscall.Stat_t
	err := syscall.Fstat(fd, &st)
	if err != nil {
		t.Fatal(err)
	}
	// st.Blocks = number of 512-byte blocks
	return st.Blocks * 512
}
Example #17
0
func (f *LoopbackFile) GetAttr(a *Attr) Status {
	st := syscall.Stat_t{}
	err := syscall.Fstat(int(f.File.Fd()), &st)
	if err != nil {
		return ToStatus(err)
	}
	a.FromStat(&st)
	return OK
}
Example #18
0
func ext۰syscall۰Fstat(fr *Frame, args []Value) Value {
	// func Fstat(fd int, stat *Stat_t) (err error)
	fd := args[0].(int)
	stat := (*args[1].(*Value)).(Structure)

	var st syscall.Stat_t
	err := syscall.Fstat(fd, &st)
	fillStat(&st, stat)
	return wrapError(err)
}
func ext۰syscall۰Fstat(fn *ssa.Function, args []value) value {
	// func Fstat(fd int, stat *Stat_t) (err error)
	fd := args[0].(int)
	stat := (*args[1].(*value)).(structure)

	var st syscall.Stat_t
	err := syscall.Fstat(fd, &st)
	fillStat(&st, stat)
	return wrapError(err)
}
Example #20
0
func (me *LoopbackFile) GetAttr() (*Attr, Status) {
	st := syscall.Stat_t{}
	err := syscall.Fstat(int(me.File.Fd()), &st)
	if err != nil {
		return nil, ToStatus(err)
	}
	a := &Attr{}
	a.FromStat(&st)
	return a, OK
}
Example #21
0
// UniqueId returns a string which uniquely identifies the namespace
// associated with the network handle.
func (ns NsHandle) UniqueId() string {
	var s syscall.Stat_t
	if ns == -1 {
		return "NS(none)"
	}
	if err := syscall.Fstat(int(ns), &s); err != nil {
		return "NS(unknown)"
	}
	return fmt.Sprintf("NS(%d:%d)", s.Dev, s.Ino)
}
Example #22
0
func (f *AzukiFile) GetAttr(a *fuse.Attr) fuse.Status {
	st := syscall.Stat_t{}
	f.lock.Lock()
	err := syscall.Fstat(int(f.File.Fd()), &st)
	f.lock.Unlock()
	if err != nil {
		return fuse.ToStatus(err)
	}
	a.FromStat(&st)
	return fuse.OK
}
Example #23
0
func fstat(u U, a []uint64) uint64 {
	fd, buf := int(a[0]), a[1]
	var stat syscall.Stat_t
	if err := syscall.Fstat(fd, &stat); err != nil {
		return errno(err)
	}
	if err := struc.Pack(u.Mem().StreamAt(buf), &stat); err != nil {
		panic(err)
	}
	return 0
}
Example #24
0
func (k *PosixKernel) Fstat(fd co.Fd, buf co.Obuf) uint64 {
	var stat syscall.Stat_t
	if err := syscall.Fstat(int(fd), &stat); err != nil {
		return Errno(err)
	}
	targetStat := NewTargetStat(&stat, k.U.OS(), k.U.Bits())
	if err := buf.Pack(targetStat); err != nil {
		panic(err)
	}
	return 0
}
Example #25
0
func NewFile(fd *os.File, writeOnly bool, cfs *cryptfs.CryptFS) nodefs.File {
	var st syscall.Stat_t
	syscall.Fstat(int(fd.Fd()), &st)

	return &file{
		fd:        fd,
		writeOnly: writeOnly,
		cfs:       cfs,
		ino:       st.Ino,
	}
}
Example #26
0
// Stat returns the FileInfo structure describing file.
// If there is an error, it will be of type *PathError.
func (f *File) Stat() (FileInfo, error) {
	if f == nil {
		return nil, ErrInvalid
	}
	var stat syscall.Stat_t
	err := syscall.Fstat(f.fd, &stat)
	if err != nil {
		return nil, &PathError{"stat", f.name, err}
	}
	return fileInfoFromStat(&stat, f.name), nil
}
Example #27
0
// Stat returns the FileInfo structure describing file.
// If there is an error, it will be of type *PathError.
func (f *File) Stat() (FileInfo, error) {
	if f == nil {
		return nil, ErrInvalid
	}
	var fs fileStat
	err := syscall.Fstat(f.fd, &fs.sys)
	if err != nil {
		return nil, &PathError{"stat", f.name, err}
	}
	fillFileStatFromSys(&fs, f.name)
	return &fs, nil
}
Example #28
0
func isCtty(fd int) bool {
	// One would hope there was a simple way to figure out what our controlling
	// tty is. Or at least check if stdin is coming from our controlling tty (as
	// opposed to just any old terminal). Alas, the infuriating morass that
	// passes for job control provides no such ability. Of no help:
	// stat(/dev/tty), readlink(/dev/fd/0), open(/dev/stdin), open(/dev/tty),
	// cat(/proc/self/fdinfo/0), stat(/proc/self/fd/0), ioctl, tty_ioctl, TIOC*,
	// anything to do with sid, pgrp, pgid, /dev/console, the tty command, $TTY,
	// $SSH_TTY. Since I am on a mission, I delved into the source for /bin/ps
	// to discover /proc/self/stat contains the major/minor numbers for the
	// controlling tty. And stat(stdin).Rdev provides the same info. If they
	// differ, I'm going to conclude -- oh so tentatively -- that stdin is NOT
	// our controlling tty. If they match, or anything goes wrong, we will
	// assume that stdin, if it is a terminal, is our ctty.
	if !terminal.IsTerminal(fd) {
		return false
	}
	var s syscall.Stat_t
	err := syscall.Fstat(fd, &s)
	if err != nil {
		fmt.Fprintf(noise, "[warning: fstat(%d) failed: %v]\n", fd, err)
		return true
	}
	name := "/proc/self/stat"
	f, err := os.Open(name)
	if err != nil {
		fmt.Fprintf(noise, "[warning: open(%q) failed: %v]\n", name, err)
		return true
	}
	b, err := ioutil.ReadAll(f)
	if err != nil {
		fmt.Fprintf(noise, "[warning: read(%q) failed: %v]\n", name, err)
		return true
	}
	a := strings.Split(string(b), " ")
	tty_nr := 6
	if len(a) <= tty_nr {
		fmt.Fprintf(noise, "[warning: read(%q) borked: only %d fields]\n", name, len(a))
		return true
	}
	ctty, err := strconv.Atoi(a[tty_nr])
	if err != nil {
		fmt.Fprintf(noise, "[warning: read(%q) borked: tty_nr = %v]\n", name, a[tty_nr])
		return true
	}
	if uint64(ctty) != s.Rdev {
		fmt.Fprintf(noise, "[warning: stdin is a tty, but not ctty]\n")
		return false
	}
	return true
}
Example #29
0
// If stdin, stdout, and/or stderr are pointing to `/dev/null` in the parent's rootfs
// this method will make them point to `/dev/null` in this container's rootfs.  This
// needs to be called after we chroot/pivot into the container's rootfs so that any
// symlinks are resolved locally.
func reOpenDevNull(rootfs string) error {
	var stat, devNullStat syscall.Stat_t
	file, err := os.Open("/dev/null")
	if err != nil {
		return fmt.Errorf("Failed to open /dev/null - %s", err)
	}
	defer file.Close()
	if err := syscall.Fstat(int(file.Fd()), &devNullStat); err != nil {
		return err
	}
	for fd := 0; fd < 3; fd++ {
		if err := syscall.Fstat(fd, &stat); err != nil {
			return err
		}
		if stat.Rdev == devNullStat.Rdev {
			// Close and re-open the fd.
			if err := syscall.Dup3(int(file.Fd()), fd, 0); err != nil {
				return err
			}
		}
	}
	return nil
}
Example #30
0
// Is stdin, stdout or stderr were to be pointing to '/dev/null',
// this method will make them point to '/dev/null' from within this namespace.
func reOpenDevNull(rootfs string) error {
	var stat, devNullStat syscall.Stat_t
	file, err := os.Open(filepath.Join(rootfs, "/dev/null"))
	if err != nil {
		return fmt.Errorf("Failed to open /dev/null - %s", err)
	}
	defer file.Close()
	if err = syscall.Fstat(int(file.Fd()), &devNullStat); err != nil {
		return fmt.Errorf("Failed to stat /dev/null - %s", err)
	}
	for fd := 0; fd < 3; fd++ {
		if err = syscall.Fstat(fd, &stat); err != nil {
			return fmt.Errorf("Failed to stat fd %d - %s", fd, err)
		}
		if stat.Rdev == devNullStat.Rdev {
			// Close and re-open the fd.
			if err = syscall.Dup2(int(file.Fd()), fd); err != nil {
				return fmt.Errorf("Failed to dup fd %d to fd %d - %s", file.Fd(), fd, err)
			}
		}
	}
	return nil
}