// parseMountInfo parses /proc/xxx/mountinfo.
175008
func parseMountInfo(filename string) ([]mountInfo, error) {
	content, err := utilio.ConsistentRead(filename, maxListTries)
	if err != nil {
		return []mountInfo{}, err
	}
	contentStr := string(content)
	infos := []mountInfo{}

	for _, line := range strings.Split(contentStr, "\n") {
		if line == "" {
			// the last split() item is empty string following the last \n
			continue
		}
		// See `man proc` for authoritative description of format of the file.
		fields := strings.Fields(line)
		if len(fields) < expectedAtLeastNumFieldsPerMountInfo {
			return nil, fmt.Errorf("wrong number of fields in (expected at least %d, got %d): %s", expectedAtLeastNumFieldsPerMountInfo, len(fields), line)
		}
		id, err := strconv.Atoi(fields[0])
		if err != nil {
			return nil, err
		}
		parentID, err := strconv.Atoi(fields[1])
		if err != nil {
			return nil, err
		}
		info := mountInfo{
			id:           id,
			parentID:     parentID,
			majorMinor:   fields[2],
			root:         fields[3],
			mountPoint:   fields[4],
			mountOptions: strings.Split(fields[5], ","),
		}
		// All fields until "-" are "optional fields".
		i := 6
		for ; i < len(fields) && fields[i] != "-"; i++ {
			info.optionalFields = append(info.optionalFields, fields[i])
		}
		// Parse the rest 3 fields.
		i += 1
		if len(fields)-i < 3 {
			return nil, fmt.Errorf("expect 3 fields in %s, got %d", line, len(fields)-i)
		}
		info.fsType = fields[i]
		info.source = fields[i+1]
		info.superOptions = strings.Split(fields[i+2], ",")
		infos = append(infos, info)
	}
	return infos, nil
}
153324
func pidMountInfo(pid int) ([]*types.MountInfo, error) {
	f, err := os.Open(fmt.Sprintf("/proc/%d/mountinfo", pid))
	if err != nil {
		return nil, err
	}
	defer f.Close()

	return parseInfoFile(f)
}
457408
func (p *criStatsProvider) getFsInfo(fsID *runtimeapi.FilesystemIdentifier) *cadvisorapiv2.FsInfo {
	if fsID == nil {
		klog.V(2).Infof("Failed to get filesystem info: fsID is nil.")
		return nil
	}
	mountpoint := fsID.GetMountpoint()
	fsInfo, err := p.cadvisor.GetDirFsInfo(mountpoint)
	if err != nil {
		msg := fmt.Sprintf("Failed to get the info of the filesystem with mountpoint %q: %v.", mountpoint, err)
		if err == cadvisorfs.ErrNoSuchDevice {
			klog.V(2).Info(msg)
		} else {
			klog.Error(msg)
		}
		return nil
	}
	return &fsInfo
}
1002113
func Lookup(dir string) (Info, error) {
	dir = filepath.Clean(dir)

	mounts, err := Self()
	if err != nil {
		return Info{}, err
	}

	// Sort descending order by Info.Mountpoint
	sort.SliceStable(mounts, func(i, j int) bool {
		return mounts[j].Mountpoint < mounts[i].Mountpoint
	})
	for _, m := range mounts {
		// Note that m.{Major, Minor} are generally unreliable for our purpose here
		// https://www.spinics.net/lists/linux-btrfs/msg58908.html
		// Note that device number is not checked here, because for overlayfs files
		// may have different device number with the mountpoint.
		if strings.HasPrefix(dir, m.Mountpoint) {
			return m, nil
		}
	}

	return Info{}, errors.Errorf("failed to find the mount info for %q", dir)
}
1078127
func (mount *MountInfo) Mount() error {
	ret := C.ceph_mount(mount.mount, nil)
	if ret != 0 {
		log.Errorf("Mount: Failed to mount")
		return cephError(ret)
	}
	return nil
}
1242588
func (s *Server) ImageFsInfo(ctx context.Context, req *pb.ImageFsInfoRequest) (resp *pb.ImageFsInfoResponse, err error) {
	const operation = "image_fs_info"
	defer func() {
		recordOperation(operation, time.Now())
		recordError(operation, err)
	}()

	store := s.StorageImageServer().GetStore()
	fsUsage, err := getStorageFsInfo(store)

	if err != nil {
		return nil, err
	}

	return &pb.ImageFsInfoResponse{
		ImageFilesystems: []*pb.FilesystemUsage{fsUsage},
	}, nil
}
1305333
func (v *Validator) CheckMounts() (errs error) {
	logrus.Debugf("check mounts")

	supportedTypes, err := supportedMountTypes(v.platform, v.HostSpecific)
	if err != nil {
		errs = multierror.Append(errs, err)
		return
	}

	for i, mountA := range v.spec.Mounts {
		if supportedTypes != nil && !supportedTypes[mountA.Type] {
			errs = multierror.Append(errs, fmt.Errorf("unsupported mount type %q", mountA.Type))
		}
		if !osFilepath.IsAbs(v.platform, mountA.Destination) {
			errs = multierror.Append(errs,
				specerror.NewError(
					specerror.MountsDestAbs,
					fmt.Errorf("mounts[%d].destination %q is not absolute",
						i,
						mountA.Destination),
					rspec.Version))
		}
		for j, mountB := range v.spec.Mounts {
			if i == j {
				continue
			}
			// whether B.Desination is nested within A.Destination
			nested, err := osFilepath.IsAncestor(v.platform, mountA.Destination, mountB.Destination, ".")
			if err != nil {
				errs = multierror.Append(errs, err)
				continue
			}
			if nested {
				if v.platform == "windows" && i < j {
					errs = multierror.Append(errs,
						specerror.NewError(
							specerror.MountsDestOnWindowsNotNested,
							fmt.Errorf("on Windows, %v nested within %v is forbidden",
								mountB.Destination, mountA.Destination),
							rspec.Version))
				}
				if i > j {
					logrus.Warnf("%v will be covered by %v", mountB.Destination, mountA.Destination)
				}
			}
		}
	}

	return
}
893309
func (mount *MountInfo) IsMounted() bool {
	ret := C.ceph_is_mounted(mount.mount)
	return ret == 1
}
1262463
func parseMountFlag(m string) (specs.Mount, error) {
	mount := specs.Mount{}
	r := csv.NewReader(strings.NewReader(m))

	fields, err := r.Read()
	if err != nil {
		return mount, err
	}

	for _, field := range fields {
		v := strings.Split(field, "=")
		if len(v) != 2 {
			return mount, fmt.Errorf("invalid mount specification: expected key=val")
		}

		key := v[0]
		val := v[1]
		switch key {
		case "type":
			mount.Type = val
		case "source", "src":
			mount.Source = val
		case "destination", "dst":
			mount.Destination = val
		case "options":
			mount.Options = strings.Split(val, ":")
		default:
			return mount, fmt.Errorf("mount option %q not supported", key)
		}
	}

	return mount, nil
}
671471
func AllProcs() (Procs, error) {
	fs, err := NewFS(DefaultMountPoint)
	if err != nil {
		return Procs{}, err
	}
	return fs.AllProcs()
}
199845
func parseMountTable(filter FilterFunc) ([]*Info, error) {
	var rawEntries *C.struct_statfs

	count := int(C.getmntinfo(&rawEntries, C.MNT_WAIT))
	if count == 0 {
		return nil, fmt.Errorf("Failed to call getmntinfo")
	}

	var entries []C.struct_statfs
	header := (*reflect.SliceHeader)(unsafe.Pointer(&entries))
	header.Cap = count
	header.Len = count
	header.Data = uintptr(unsafe.Pointer(rawEntries))

	var out []*Info
	for _, entry := range entries {
		var mountinfo Info
		var skip, stop bool
		mountinfo.Mountpoint = C.GoString(&entry.f_mntonname[0])

		if filter != nil {
			// filter out entries we're not interested in
			skip, stop = filter(p)
			if skip {
				continue
			}
		}

		mountinfo.Source = C.GoString(&entry.f_mntfromname[0])
		mountinfo.Fstype = C.GoString(&entry.f_fstypename[0])

		out = append(out, &mountinfo)
		if stop {
			break
		}
	}
	return out, nil
}
494883
func (self *Server) tryMounts(requestPath string, req *http.Request) (Mount, *MountResponse, error) {
	var body *bytes.Reader

	// buffer the request body because we need to repeatedly pass it to multiple mounts
	if data, err := ioutil.ReadAll(req.Body); err == nil {
		if len(data) > 0 {
			log.Debugf("  read %d bytes from request body\n", len(data))
		}

		body = bytes.NewReader(data)
	} else {
		return nil, nil, err
	}

	// find a mount that has this file
	for _, mount := range self.Mounts {
		// seek the body buffer back to the beginning
		if _, err := body.Seek(0, 0); err != nil {
			return nil, nil, err
		}

		if mount.WillRespondTo(requestPath, req, body) {
			// attempt to open the file entry
			if mountResponse, err := mount.OpenWithType(requestPath, req, body); err == nil {
				return mount, mountResponse, nil
			} else if IsHardStop(err) {
				return nil, nil, err
			} else {
				log.Warningf("%v", err)
			}
		}
	}

	return nil, nil, fmt.Errorf("%q not found", requestPath)
}
469248
func FindMount(volumePath string) (Volume, error) {
	rootDir, volumeName, err := SplitPath(volumePath)
	if err != nil {
		return nil, err
	} else if rootDir == volumePath {
		return nil, ErrPathIsDriver
	}
	return Mount(volumeName, rootDir)
}
453436
func GetMounts() ([]*MountEntry, error) {
	cmd := newCmd("mount")
	out, err := zExec(cmd)
	if err != nil {
		return nil, err
	}
	ret := []*MountEntry{}
	for _, l := range strings.Split(string(out), "\n") {
		d := strings.SplitN(l, "  ", 2)
		ret = append(ret, &MountEntry{
			Name:       strings.Trim(d[0], " "),
			Mountpoint: strings.Trim(d[1], " "),
		})
	}
	return ret, nil
}
1124143
func (fs *FSObjects) StorageInfo(ctx context.Context) StorageInfo {
	di, err := getDiskInfo(fs.fsPath)
	if err != nil {
		return StorageInfo{}
	}
	used := di.Total - di.Free
	if !fs.diskMount {
		used = atomic.LoadUint64(&fs.totalUsed)
	}
	storageInfo := StorageInfo{
		Used:      used,
		Total:     di.Total,
		Available: di.Free,
	}
	storageInfo.Backend.Type = BackendFS
	return storageInfo
}
1132869
func ParseSearchIndexInfo(reposName string) (*registrytypes.IndexInfo, error) {
	indexName, _ := splitReposSearchTerm(reposName)

	indexInfo, err := newIndexInfo(emptyServiceConfig, indexName)
	if err != nil {
		return nil, err
	}
	return indexInfo, nil
}
681034
func doMount(source string, target string, fstype string, options []string) error {
	glog.V(5).Infof("Mounting %s %s %s %v", source, target, fstype, options)
	mountArgs := makeMountArgs(source, target, fstype, options)
	command := exec.Command("mount", mountArgs...)
	output, err := command.CombinedOutput()
	if err != nil {
		return fmt.Errorf("Mount failed: %v\nMounting arguments: %s %s %s %v\nOutput: %s\n",
			err, source, target, fstype, options, string(output))
	}
	return err
}