Beispiel #1
0
func SetFileUser(filename, username string, run bool) (bool, error) {
	userData, err := user.Lookup(username)
	if err != nil {
		return false, err
	}
	uid, err := strconv.Atoi(userData.Uid)
	if err != nil {
		return false, err
	}
	var stat syscall.Stat_t
	err = syscall.Stat(filename, &stat)
	if err != nil {
		return false, err
	}
	if int(stat.Uid) == uid {
		return false, nil
	}
	if run {
		err = os.Chown(filename, uid, int(stat.Gid))
		if err != nil {
			return false, err
		}
	}
	return true, nil
}
Beispiel #2
0
func getDevnumForDevice(name string) (devnum uint64, err error) {
	var stat syscall.Stat_t
	if err = syscall.Stat(name, &stat); err != nil {
		return 0, err
	}
	return stat.Rdev, nil
}
Beispiel #3
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
}
Beispiel #4
0
func isDir(fullpath string) (bool, error) {
	var st syscall.Stat_t
	if err := syscall.Stat(fullpath, &st); err != nil {
		return false, osErrorToFuseError(err)
	}
	return st.Mode&syscall.S_IFMT == syscall.S_IFDIR, nil
}
Beispiel #5
0
// Stat takes a path to a file and returns
// a system.Stat_t type pertaining to that file.
//
// Throws an error if the file does not exist
func Stat(path string) (*Stat_t, error) {
	s := &syscall.Stat_t{}
	if err := syscall.Stat(path, s); err != nil {
		return nil, err
	}
	return fromStatT(s)
}
func readTree(base, root string) (map[string]node, error) {
	tree := make(map[string]node)

	dirInfos, err := ioutil.ReadDir(base)
	if err != nil {
		return nil, fmt.Errorf("Couldn't read directory entries for %q: %v", base, err)
	}

	for _, info := range dirInfos {
		s := &syscall.Stat_t{}
		if err := syscall.Stat(filepath.Join(base, info.Name()), s); err != nil {
			return nil, fmt.Errorf("Can't stat file %q: %v", filepath.Join(base, info.Name()), err)
		}
		tree[filepath.Join(root, info.Name())] = node{int(s.Uid), int(s.Gid)}
		if info.IsDir() {
			// read the subdirectory
			subtree, err := readTree(filepath.Join(base, info.Name()), filepath.Join(root, info.Name()))
			if err != nil {
				return nil, err
			}
			for path, nodeinfo := range subtree {
				tree[path] = nodeinfo
			}
		}
	}
	return tree, nil
}
Beispiel #7
0
func watchDaemon(mdbFileName string, mdbChannel chan<- *mdb.Mdb,
	logger *log.Logger) {
	var lastStat syscall.Stat_t
	var lastMdb *mdb.Mdb
	for ; ; time.Sleep(time.Second) {
		var stat syscall.Stat_t
		if err := syscall.Stat(mdbFileName, &stat); err != nil {
			logger.Printf("Error stating file: %s\t%s\n", mdbFileName, err)
			continue
		}
		stat.Atim = lastStat.Atim
		if stat != lastStat {
			mdb := loadFile(mdbFileName, logger)
			if mdb == nil {
				continue
			}
			compareStartTime := time.Now()
			if lastMdb == nil || !compare(lastMdb, mdb) {
				if lastMdb != nil {
					mdbCompareTimeDistribution.Add(time.Since(compareStartTime))
				}
				mdbChannel <- mdb
				lastMdb = mdb
			}
			lastStat = stat
		}
	}
}
Beispiel #8
0
// Setting nanoseconds should work for dates after 1970
func TestUtimesNano(t *testing.T) {
	tc := NewTestCase(t)
	defer tc.Cleanup()

	path := tc.mountFile
	err := ioutil.WriteFile(path, []byte("xyz"), 0600)
	if err != nil {
		t.Fatal(err)
	}
	ts := make([]syscall.Timespec, 2)
	// atime
	ts[0].Sec = 1
	ts[0].Nsec = 2
	// mtime
	ts[1].Sec = 3
	ts[1].Nsec = 4
	err = syscall.UtimesNano(path, ts)
	if err != nil {
		t.Fatal(err)
	}

	var st syscall.Stat_t
	err = syscall.Stat(path, &st)
	if err != nil {
		t.Fatal(err)
	}
	if st.Atim != ts[0] {
		t.Errorf("Wrong atime: %v, want: %v", st.Atim, ts[0])
	}
	if st.Mtim != ts[1] {
		t.Errorf("Wrong mtime: %v, want: %v", st.Mtim, ts[1])
	}
}
Beispiel #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
}
Beispiel #10
0
func watchDaemon(mdbFileName string, mdbChannel chan *Mdb, logger *log.Logger) {
	var lastStat syscall.Stat_t
	var lastMdb *Mdb
	for ; ; time.Sleep(time.Second) {
		var stat syscall.Stat_t
		err := syscall.Stat(mdbFileName, &stat)
		if err != nil {
			logger.Printf("Error stating file: %s\t%s\n", mdbFileName, err)
			continue
		}
		if stat != lastStat {
			file, err := os.Open(mdbFileName)
			if err != nil {
				logger.Printf("Error opening file\t%s\n", err)
				continue
			}
			decoder := json.NewDecoder(file)
			var mdb Mdb
			err = decoder.Decode(&mdb.Machines)
			if err != nil {
				logger.Printf("Error decoding\t%s\n", err)
				continue
			}
			sort.Sort(&mdb)
			if lastMdb == nil || !compare(lastMdb, &mdb) {
				mdbChannel <- &mdb
				lastMdb = &mdb
			}
			lastStat = stat
		}
	}
}
Beispiel #11
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
}
func GetFileSize(path string) int64 {
	var st syscall.Stat_t
	err := syscall.Stat(path, &st)
	if err != nil {
		return -1
	}
	return st.Size
}
Beispiel #13
0
func Stat(path string, statbuf *Stat_t) error {
	var rawStatbuf syscall.Stat_t
	if err := syscall.Stat(path, &rawStatbuf); err != nil {
		return err
	}
	convertStat(statbuf, &rawStatbuf)
	return nil
}
Beispiel #14
0
// Owner returns uid and gid of a file
func Owner(path string) (uid uint32, gid uint32, err error) {
	s := syscall.Stat_t{}
	err = syscall.Stat(path, &s)
	if err != nil {
		return 0, 0, err
	}
	return s.Uid, s.Gid, nil
}
Beispiel #15
0
func GetDevnumForFile(name string) (devnum uint64, err error) {
	var stat syscall.Stat_t
	err = syscall.Stat(name, &stat)
	if err != nil {
		return 0, err
	}
	return stat.Dev, nil
}
Beispiel #16
0
func ctimeFile(filename string) int64 {
	var st syscall.Stat_t
	if err := syscall.Stat(filename, &st); err != nil {
		log.Printf("[WARN] [%s] Can't stat file %s, error: ", module, filename, err)
		return -1
	}
	return st.Ctimespec.Sec
}
Beispiel #17
0
// Stat returns a FileInfo describing the named file.
// If there is an error, it will be of type *PathError.
func Stat(name string) (fi FileInfo, err error) {
	var stat syscall.Stat_t
	err = syscall.Stat(name, &stat)
	if err != nil {
		return nil, &PathError{"stat", name, err}
	}
	return fileInfoFromStat(&stat, name), nil
}
Beispiel #18
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
}
Beispiel #19
0
// Stat returns a FileInfo describing the named file.
// If there is an error, it will be of type *PathError.
func Stat(name string) (FileInfo, error) {
	var fs fileStat
	err := syscall.Stat(name, &fs.sys)
	if err != nil {
		return nil, &PathError{"stat", name, err}
	}
	fillFileStatFromSys(&fs, name)
	return &fs, nil
}
Beispiel #20
0
func readFileInode(fname string) uint64 {
	var stat syscall.Stat_t

	err := syscall.Stat(fname, &stat)
	if err != nil {
		return 0
	}
	return stat.Ino
}
Beispiel #21
0
// Less performs a memoized comparison between Atimes of files
func (f ByAtime) Less(i, j int) bool {
	st1 := memo[i]
	if st1.Atimespec.Sec == 0 {
		if err := syscall.Stat(f[i].AbsPath, &st1); err != nil {
			log.Fatal("Error on stat(" + f[i].AbsPath + "): " + err.Error())
		} else {
			memo[i] = st1
		}
	}
	st2 := memo[j]
	if st2.Atimespec.Sec == 0 {
		if err := syscall.Stat(f[j].AbsPath, &st2); err != nil {
			log.Fatal("Error on stat(" + f[j].AbsPath + "): " + err.Error())
		} else {
			memo[j] = st2
		}
	}
	return st1.Atimespec.Sec < st2.Atimespec.Sec
}
Beispiel #22
0
func ext۰syscall۰Stat(fr *Frame, args []Value) Value {
	// func Stat(name string, stat *Stat_t) (err error)
	name := args[0].(string)
	stat := (*args[1].(*Value)).(Structure)

	var st syscall.Stat_t
	err := syscall.Stat(name, &st)
	fillStat(&st, stat)
	return wrapError(err)
}
Beispiel #23
0
func getDev(path string) (int, int, error) {
	stat := syscall.Stat_t{}
	err := syscall.Stat(path, &stat)
	if err != nil {
		return 0, 0, err
	}
	major := int(stat.Rdev / 256)
	minor := int(stat.Rdev % 256)
	return major, minor, nil
}
Beispiel #24
0
func (h *handle) Path() (string, error) {
	var stat syscall.Stat_t
	if err := syscall.Stat(h.procPath(), &stat); err != nil {
		return "", errors.Wrapf(err, "path %v could not be statted", h.procPath())
	}
	if stat.Dev != h.dev || stat.Ino != h.ino {
		return "", errors.Errorf("failed to verify handle %v/%v %v/%v", stat.Dev, h.dev, stat.Ino, h.ino)
	}
	return h.procPath(), nil
}
func ext۰syscall۰Stat(fn *ssa.Function, args []value) value {
	// func Stat(name string, stat *Stat_t) (err error)
	name := args[0].(string)
	stat := (*args[1].(*value)).(structure)

	var st syscall.Stat_t
	err := syscall.Stat(name, &st)
	fillStat(&st, stat)
	return wrapError(err)
}
Beispiel #26
0
func (s *Server) reportDiskStats() error {
	for name, options := range s.conf.OSStats.Disk {
		if options.Usage != "" {
			statfsInfo := &syscall.Statfs_t{}
			if err := syscall.Statfs(options.Path, statfsInfo); err != nil {
				return err
			}
			usedBlocks := statfsInfo.Blocks - statfsInfo.Bavail // blocks used
			var used float64
			if options.Usage == "absolute" {
				used = float64(usedBlocks * uint64(statfsInfo.Bsize)) // number of bytes used
			} else {
				used = float64(usedBlocks) / float64(statfsInfo.Blocks) // fraction of space used
			}
			s.osGauge("disk."+name+".usage", used)
		}

		if options.IO {
			statInfo := &syscall.Stat_t{}
			if err := syscall.Stat(options.Path, statInfo); err != nil {
				return err
			}
			device := decomposeDevNumber(statInfo.Dev)
			diskStats, err := proc.DiskStats()
			if err != nil {
				return err
			}
			var stats *proc.IOStatEntry
			for _, entry := range diskStats {
				if entry.Major == device[0] && entry.Minor == device[1] {
					stats = entry
				}
			}
			if stats == nil {
				return fmt.Errorf("Cannot determine stats for device at %s", options.Path)
			}
			newStats := counterStats{
				stats.ReadsCompleted, stats.SectorsRead,
				stats.WritesCompleted, stats.SectorsWritten,
			}
			if oldStats, ok := s.osData.diskDeviceStats[device]; ok {
				diff := newStats.Sub(oldStats)
				s.osCounter("disk."+name+".io.reads", float64(diff[0]))
				s.osCounter("disk."+name+".io.writes", float64(diff[2]))
				// NOTE(caleb): As far as I can tell, a "sector" (in the context of /proc/diskstats and iostat) is 512
				// bytes. See, for example, `man iostat`.
				s.osCounter("disk."+name+".io.read_bytes", float64(diff[1])*512)
				s.osCounter("disk."+name+".io.write_bytes", float64(diff[3])*512)
			}
			s.osData.diskDeviceStats[device] = newStats
		}
	}

	return nil
}
Beispiel #27
0
func addBlockDev(dev string) ([]string, error) {
	stat := syscall.Stat_t{}
	err := syscall.Stat(dev, &stat)
	if err != nil {
		return []string{}, err
	}
	k := "lxc.cgroup.devices.allow"
	v := fmt.Sprintf("b %d:%d rwm", uint(stat.Rdev/256), uint(stat.Rdev%256))
	line := []string{k, v}
	return line, err
}
Beispiel #28
0
func reffile(filename string) (int64, int64) {
	var st syscall.Stat_t

	if e := syscall.Stat(filename, &st); e != 0 {
		fmt.Fprintf(os.Stderr, "stat: Error %s\n", syscall.Errstr(e))
		os.Exit(1)
	}

	//FIXME: bug in Go! Amd64 has following rest have Atimespec and Mtimespec
	return st.Atim.Sec, st.Mtim.Sec
}
Beispiel #29
0
func (constor *Constor) setdeleted(pathl string) error {
	stat := syscall.Stat_t{}
	err := syscall.Stat(pathl, &stat)
	if err != nil {
		fd, err := syscall.Creat(pathl, 0)
		if err != nil {
			return err
		}
		syscall.Close(fd)
	}
	return syscall.Setxattr(pathl, DELXATTR, []byte{49}, 0)
}
Beispiel #30
0
// FileSize checks the real file size. Helpful for detecting sparse files.
func FileSize(path string) (allocated int64, taken int64, err error) {
	s := syscall.Stat_t{}
	err = syscall.Stat(path, &s)
	if err != nil {
		return 0, 0, err
	}
	blockSize, err := FSBlockSize(path)
	if err != nil {
		return 0, 0, err
	}
	return s.Size, s.Blocks * int64(blockSize), nil
}