// Load mount table func (m *DeviceMounter) Load(devPrefix string) error { info, err := mount.GetMounts() if err != nil { return err } DeviceLoop: for _, v := range info { if !strings.HasPrefix(v.Source, devPrefix) { continue } mount, ok := m.mounts[v.Source] if !ok { mount = &Info{ Device: v.Source, Fs: v.Fstype, Minor: v.Minor, Mountpoint: make([]PathInfo, 0), } m.mounts[v.Source] = mount } // Allow Load to be called multiple times. for _, p := range mount.Mountpoint { if p.Path == v.Mountpoint { continue DeviceLoop } } // XXX Reconstruct refs. mount.Mountpoint = append(mount.Mountpoint, PathInfo{Path: v.Mountpoint, ref: 1}) m.paths[v.Mountpoint] = v.Source } return nil }
func (clnt *client) setExited(containerID string) error { clnt.lock(containerID) defer clnt.unlock(containerID) var exitCode uint32 if event, ok := clnt.remote.pastEvents[containerID]; ok { exitCode = event.Status delete(clnt.remote.pastEvents, containerID) } err := clnt.backend.StateChanged(containerID, StateInfo{ State: StateExit, ExitCode: exitCode, }) // Unmount and delete the bundle folder if mts, err := mount.GetMounts(); err == nil { for _, mts := range mts { if strings.HasSuffix(mts.Mountpoint, containerID+"/rootfs") { if err := syscall.Unmount(mts.Mountpoint, syscall.MNT_DETACH); err == nil { os.RemoveAll(strings.TrimSuffix(mts.Mountpoint, "/rootfs")) } break } } } return err }
// getSelinuxMountPoint returns the path to the mountpoint of an selinuxfs // filesystem or an empty string if no mountpoint is found. Selinuxfs is // a proc-like pseudo-filesystem that exposes the selinux policy API to // processes. The existence of an selinuxfs mount is used to determine // whether selinux is currently enabled or not. func getSelinuxMountPoint() string { if selinuxfs != "unknown" { return selinuxfs } selinuxfs = "" mounts, err := mount.GetMounts() if err != nil { return selinuxfs } for _, mount := range mounts { if mount.Fstype == "selinuxfs" { selinuxfs = mount.Mountpoint break } } if selinuxfs != "" { var buf syscall.Statfs_t syscall.Statfs(selinuxfs, &buf) if (buf.Flags & stRdOnly) == 1 { selinuxfs = "" } } return selinuxfs }
func GetCgroupMounts() ([]Mount, error) { mounts, err := mount.GetMounts() if err != nil { return nil, err } all, err := GetAllSubsystems() if err != nil { return nil, err } allMap := make(map[string]bool) for _, s := range all { allMap[s] = true } res := []Mount{} for _, mount := range mounts { if mount.Fstype == "cgroup" { m := Mount{Mountpoint: mount.Mountpoint} for _, opt := range strings.Split(mount.VfsOpts, ",") { if strings.HasPrefix(opt, cgroupNamePrefix) { m.Subsystems = append(m.Subsystems, opt[len(cgroupNamePrefix):]) } if allMap[opt] { m.Subsystems = append(m.Subsystems, opt) } } res = append(res, m) } } return res, nil }
// Get the source mount point of directory passed in as argument. Also return // optional fields. func getSourceMount(source string) (string, string, error) { // Ensure any symlinks are resolved. sourcePath, err := filepath.EvalSymlinks(source) if err != nil { return "", "", err } mountinfos, err := mount.GetMounts() if err != nil { return "", "", err } mountinfo := getMountInfo(mountinfos, sourcePath) if mountinfo != nil { return sourcePath, mountinfo.Optional, nil } path := sourcePath for { path = filepath.Dir(path) mountinfo = getMountInfo(mountinfos, path) if mountinfo != nil { return path, mountinfo.Optional, nil } if path == "/" { break } } // If we are here, we did not find parent mount. Something is wrong. return "", "", fmt.Errorf("Could not find source mount of %s", source) }
// storageHealthCheck returns a channel that will close when the distributed // storage is no longer accessible (i.e., stale NFS mount) func (c *Controller) storageHealthCheck() (chan struct{}, error) { gone := make(chan struct{}) mounts, err := mount.GetMounts() if err != nil { return nil, err } nfsMountPoints := []string{} for _, minfo := range mounts { if strings.HasPrefix(minfo.Fstype, "nfs") { nfsMountPoints = append(nfsMountPoints, minfo.Mountpoint) } } if len(nfsMountPoints) > 0 { // Start polling go func() { for { for _, mp := range nfsMountPoints { if isNFSMountStale(mp) { close(gone) return } } <-time.After(5 * time.Second) } }() } return gone, nil }
// Get the parent mount point of directory passed in as argument. Also return // optional fields. func getParentMount(rootfs string) (string, string, error) { var path string mountinfos, err := mount.GetMounts() if err != nil { return "", "", err } mountinfo := getMountInfo(mountinfos, rootfs) if mountinfo != nil { return rootfs, mountinfo.Optional, nil } path = rootfs for { path = filepath.Dir(path) mountinfo = getMountInfo(mountinfos, path) if mountinfo != nil { return path, mountinfo.Optional, nil } if path == "/" { break } } // If we are here, we did not find parent mount. Something is wrong. return "", "", fmt.Errorf("Could not find parent mount of %s", rootfs) }
func NewFsInfo(context Context) (FsInfo, error) { mounts, err := mount.GetMounts() if err != nil { return nil, err } partitions := make(map[string]partition, 0) fsInfo := &RealFsInfo{} fsInfo.labels = make(map[string]string, 0) supportedFsType := map[string]bool{ // all ext systems are checked through prefix. "btrfs": true, "xfs": true, } for _, mount := range mounts { if !strings.HasPrefix(mount.Fstype, "ext") && !supportedFsType[mount.Fstype] { continue } // Avoid bind mounts. if _, ok := partitions[mount.Source]; ok { continue } partitions[mount.Source] = partition{mount.Mountpoint, uint(mount.Major), uint(mount.Minor)} } glog.Infof("Filesystem partitions: %+v", partitions) fsInfo.partitions = partitions fsInfo.addLabels(context) return fsInfo, nil }
// New instantiates a new Root instance with the provided scope. Scope // is the base path that the Root instance uses to store its // volumes. The base path is created here if it does not exist. func New(scope string, rootUID, rootGID int) (*Root, error) { rootDirectory := filepath.Join(scope, volumesPathName) if err := idtools.MkdirAllAs(rootDirectory, 0700, rootUID, rootGID); err != nil { return nil, err } r := &Root{ scope: scope, path: rootDirectory, volumes: make(map[string]*localVolume), rootUID: rootUID, rootGID: rootGID, } dirs, err := ioutil.ReadDir(rootDirectory) if err != nil { return nil, err } mountInfos, err := mount.GetMounts() if err != nil { logrus.Debugf("error looking up mounts for local volume cleanup: %v", err) } for _, d := range dirs { if !d.IsDir() { continue } name := filepath.Base(d.Name()) v := &localVolume{ driverName: r.Name(), name: name, path: r.DataPath(name), } r.volumes[name] = v optsFilePath := filepath.Join(rootDirectory, name, "opts.json") if b, err := ioutil.ReadFile(optsFilePath); err == nil { opts := optsConfig{} if err := json.Unmarshal(b, &opts); err != nil { return nil, err } if !reflect.DeepEqual(opts, optsConfig{}) { v.opts = &opts } // unmount anything that may still be mounted (for example, from an unclean shutdown) for _, info := range mountInfos { if info.Mountpoint == v.path { mount.Unmount(v.path) break } } } } return r, nil }
func existsMountpointWithPrefix(mountpointPrefix string) (bool, error) { mounts, err := mount.GetMounts() if err != nil { return false, err } for _, mnt := range mounts { if strings.HasPrefix(mnt.Mountpoint, mountpointPrefix) { return true, nil } } return false, nil }
func TestFactoryNewTmpfs(t *testing.T) { root, rerr := newTestRoot() if rerr != nil { t.Fatal(rerr) } defer os.RemoveAll(root) factory, err := New(root, Cgroupfs, TmpfsRoot) if err != nil { t.Fatal(err) } if factory == nil { t.Fatal("factory should not be nil") } lfactory, ok := factory.(*LinuxFactory) if !ok { t.Fatal("expected linux factory returned on linux based systems") } if lfactory.Root != root { t.Fatalf("expected factory root to be %q but received %q", root, lfactory.Root) } if factory.Type() != "libcontainer" { t.Fatalf("unexpected factory type: %q, expected %q", factory.Type(), "libcontainer") } mounted, err := mount.Mounted(lfactory.Root) if err != nil { t.Fatal(err) } if !mounted { t.Fatalf("Factory Root is not mounted") } mounts, err := mount.GetMounts() if err != nil { t.Fatal(err) } var found bool for _, m := range mounts { if m.Mountpoint == lfactory.Root { if m.Fstype != "tmpfs" { t.Fatalf("Fstype of root: %s, expected %s", m.Fstype, "tmpfs") } if m.Source != "tmpfs" { t.Fatalf("Source of root: %s, expected %s", m.Source, "tmpfs") } found = true } } if !found { t.Fatalf("Factory Root is not listed in mounts list") } defer syscall.Unmount(root, syscall.MNT_DETACH) }
func NewFsInfo(context Context) (FsInfo, error) { mounts, err := mount.GetMounts() if err != nil { return nil, err } partitions := make(map[string]partition, 0) fsInfo := &RealFsInfo{} fsInfo.labels = make(map[string]string, 0) supportedFsType := map[string]bool{ // all ext systems are checked through prefix. "btrfs": true, "xfs": true, "zfs": true, } for _, mount := range mounts { var Fstype string if !strings.HasPrefix(mount.Fstype, "ext") && !supportedFsType[mount.Fstype] { continue } // Avoid bind mounts. if _, ok := partitions[mount.Source]; ok { continue } if mount.Fstype == "zfs" { Fstype = mount.Fstype } partitions[mount.Source] = partition{ fsType: Fstype, mountpoint: mount.Mountpoint, major: uint(mount.Major), minor: uint(mount.Minor), } } if storageDriver, ok := context.DockerInfo["Driver"]; ok && storageDriver == "devicemapper" { dev, major, minor, blockSize, err := dockerDMDevice(context.DockerInfo["DriverStatus"]) if err != nil { glog.Warningf("Could not get Docker devicemapper device: %v", err) } else { partitions[dev] = partition{ fsType: "devicemapper", major: major, minor: minor, blockSize: blockSize, } fsInfo.labels[LabelDockerImages] = dev } } glog.Infof("Filesystem partitions: %+v", partitions) fsInfo.partitions = partitions fsInfo.addLabels(context) return fsInfo, nil }
// Take care of the old 1.11.0 behavior in case the version upgrade // happened without a clean daemon shutdown func (clnt *client) cleanupOldRootfs(containerID string) { // Unmount and delete the bundle folder if mts, err := mount.GetMounts(); err == nil { for _, mts := range mts { if strings.HasSuffix(mts.Mountpoint, containerID+"/rootfs") { if err := syscall.Unmount(mts.Mountpoint, syscall.MNT_DETACH); err == nil { os.RemoveAll(strings.TrimSuffix(mts.Mountpoint, "/rootfs")) } break } } } }
func getMount(mountpoint string) (*mount.Info, error) { entries, err := mount.GetMounts() if err != nil { return nil, err } // Search the table for the mountpoint for _, e := range entries { if e.Mountpoint == mountpoint { return e, nil } } return nil, fmt.Errorf("Mountpoint not found") }
func FindCgroupMountpointDir() (string, error) { mounts, err := mount.GetMounts() if err != nil { return "", err } for _, mount := range mounts { if mount.Fstype == "cgroup" { return filepath.Dir(mount.Mountpoint), nil } } return "", NewNotFoundError("cgroup") }
func (m *Mounter) GetMountsRoot() ([]*mount.Info, error) { mounts, err := mount.GetMounts() if err != nil { return nil, err } targets := make([]*mount.Info, 0) for _, mo := range mounts { if strings.HasPrefix(mo.Mountpoint, m.rootDir) { targets = append(targets, mo) } } return targets, nil }
func NewFsInfo(context Context) (FsInfo, error) { mounts, err := mount.GetMounts() if err != nil { return nil, err } fsInfo := &RealFsInfo{ partitions: make(map[string]partition, 0), labels: make(map[string]string, 0), dmsetup: devicemapper.NewDmsetupClient(), } supportedFsType := map[string]bool{ // all ext systems are checked through prefix. "btrfs": true, "xfs": true, "zfs": true, } for _, mount := range mounts { var Fstype string if !strings.HasPrefix(mount.Fstype, "ext") && !supportedFsType[mount.Fstype] { continue } // Avoid bind mounts. if _, ok := fsInfo.partitions[mount.Source]; ok { continue } if mount.Fstype == "zfs" { Fstype = mount.Fstype } fsInfo.partitions[mount.Source] = partition{ fsType: Fstype, mountpoint: mount.Mountpoint, major: uint(mount.Major), minor: uint(mount.Minor), } } fsInfo.addRktImagesLabel(context, mounts) // need to call this before the log line below printing out the partitions, as this function may // add a "partition" for devicemapper to fsInfo.partitions fsInfo.addDockerImagesLabel(context, mounts) //add hyper images label fsInfo.addHyperImagesLabel(context, mounts) glog.Infof("Filesystem partitions: %+v", fsInfo.partitions) fsInfo.addSystemRootLabel(mounts) return fsInfo, nil }
// https://www.kernel.org/doc/Documentation/cgroups/cgroups.txt func FindCgroupMountpoint(subsystem string) (string, error) { mounts, err := mount.GetMounts() if err != nil { return "", err } for _, mount := range mounts { if mount.Fstype == "cgroup" { for _, opt := range strings.Split(mount.VfsOpts, ",") { if opt == subsystem { return mount.Mountpoint, nil } } } } return "", ErrNotFound }
func NewFsInfo() (FsInfo, error) { mounts, err := mount.GetMounts() if err != nil { return nil, err } partitions := make(map[string]partition, 0) for _, mount := range mounts { if !strings.HasPrefix(mount.Fstype, "ext") { continue } // Avoid bind mounts. if _, ok := partitions[mount.Source]; ok { continue } partitions[mount.Source] = partition{mount.Mountpoint, uint(mount.Major), uint(mount.Minor)} } return &RealFsInfo{partitions}, nil }
func NewFsInfo(context Context) (FsInfo, error) { mounts, err := mount.GetMounts() if err != nil { return nil, err } fsInfo := &RealFsInfo{ partitions: make(map[string]partition, 0), labels: make(map[string]string, 0), dmsetup: &defaultDmsetupClient{}, } fsInfo.addSystemRootLabel(mounts) fsInfo.addDockerImagesLabel(context, mounts) fsInfo.addRktImagesLabel(context, mounts) supportedFsType := map[string]bool{ // all ext systems are checked through prefix. "btrfs": true, "xfs": true, "zfs": true, } for _, mount := range mounts { var Fstype string if !strings.HasPrefix(mount.Fstype, "ext") && !supportedFsType[mount.Fstype] { continue } // Avoid bind mounts. if _, ok := fsInfo.partitions[mount.Source]; ok { continue } if mount.Fstype == "zfs" { Fstype = mount.Fstype } fsInfo.partitions[mount.Source] = partition{ fsType: Fstype, mountpoint: mount.Mountpoint, major: uint(mount.Major), minor: uint(mount.Minor), } } glog.Infof("Filesystem partitions: %+v", fsInfo.partitions) return fsInfo, nil }
// Load mount table func (m *NFSMounter) Load(source string) error { info, err := mount.GetMounts() if err != nil { return err } re := regexp.MustCompile(`,addr=(.*)`) MountLoop: for _, v := range info { if m.server != "" { if v.Fstype != "nfs" { continue } matches := re.FindStringSubmatch(v.VfsOpts) if len(matches) != 2 { continue } if matches[1] != m.server { continue } } mount, ok := m.mounts[v.Source] if !ok { mount = &Info{ Device: v.Source, Fs: v.Fstype, Minor: v.Minor, Mountpoint: make([]*PathInfo, 0), } m.mounts[v.Source] = mount } // Allow Load to be called multiple times. for _, p := range mount.Mountpoint { if p.Path == v.Mountpoint { continue MountLoop } } // XXX Reconstruct refs. mount.Mountpoint = append(mount.Mountpoint, &PathInfo{Path: v.Mountpoint, ref: 1}) } return nil }
func (driver *Driver) GetMounts(deviceName, mountPoint string) ([]*mount.Info, error) { mounts, err := mount.GetMounts() if err != nil { return nil, err } if mountPoint == "" && deviceName == "" { return mounts, nil } else if mountPoint != "" && deviceName != "" { return nil, errors.New("Cannot specify mountPoint and deviceName") } var matchedMounts []*mount.Info for _, mount := range mounts { if mount.Mountpoint == mountPoint || mount.Source == deviceName { matchedMounts = append(matchedMounts, mount) } } return matchedMounts, nil }
func newFsInfo(storageDriver string) (FsInfo, error) { mounts, err := mount.GetMounts() if err != nil { return nil, err } fsInfo := &RealFsInfo{ partitions: make(map[string]partition, 0), labels: make(map[string]string, 0), } fsInfo.addSystemRootLabel(mounts) supportedFsType := map[string]bool{ // all ext systems are checked through prefix. "btrfs": true, "xfs": true, "zfs": true, } for _, mount := range mounts { var Fstype string if !strings.HasPrefix(mount.Fstype, "ext") && !supportedFsType[mount.Fstype] { continue } // Avoid bind mounts. if _, ok := fsInfo.partitions[mount.Source]; ok { continue } if mount.Fstype == "zfs" { Fstype = mount.Fstype } fsInfo.partitions[mount.Source] = partition{ fsType: Fstype, mountpoint: mount.Mountpoint, major: uint(mount.Major), minor: uint(mount.Minor), } } return fsInfo, nil }
func NewFsInfo(context Context) (FsInfo, error) { mounts, err := mount.GetMounts() if err != nil { return nil, err } // Avoid devicemapper container mounts - these are tracked by the ThinPoolWatcher excluded := []string{fmt.Sprintf("%s/devicemapper/mnt", context.Docker.Root)} fsInfo := &RealFsInfo{ partitions: processMounts(mounts, excluded), labels: make(map[string]string, 0), dmsetup: devicemapper.NewDmsetupClient(), } fsInfo.addRktImagesLabel(context, mounts) // need to call this before the log line below printing out the partitions, as this function may // add a "partition" for devicemapper to fsInfo.partitions fsInfo.addDockerImagesLabel(context, mounts) glog.Infof("Filesystem partitions: %+v", fsInfo.partitions) fsInfo.addSystemRootLabel(mounts) return fsInfo, nil }
func NewFsInfo(context Context) (FsInfo, error) { mounts, err := mount.GetMounts() if err != nil { return nil, err } partitions := make(map[string]partition, 0) fsInfo := &RealFsInfo{} fsInfo.labels = make(map[string]string, 0) for _, mount := range mounts { if !strings.HasPrefix(mount.Fstype, "ext") && mount.Fstype != "btrfs" { continue } // Avoid bind mounts. if _, ok := partitions[mount.Source]; ok { continue } partitions[mount.Source] = partition{mount.Mountpoint, uint(mount.Major), uint(mount.Minor)} } glog.Infof("Filesystem partitions: %+v", partitions) fsInfo.partitions = partitions fsInfo.addLabels(context) return fsInfo, nil }
func lookupZfsDataset(rootdir string) (string, error) { var stat syscall.Stat_t if err := syscall.Stat(rootdir, &stat); err != nil { return "", fmt.Errorf("Failed to access '%s': %s", rootdir, err) } wantedDev := stat.Dev mounts, err := mount.GetMounts() if err != nil { return "", err } for _, m := range mounts { if err := syscall.Stat(m.Mountpoint, &stat); err != nil { logrus.Debugf("[zfs] failed to stat '%s' while scanning for zfs mount: %v", m.Mountpoint, err) continue // may fail on fuse file systems } if stat.Dev == wantedDev && m.Fstype == "zfs" { return m.Source, nil } } return "", fmt.Errorf("Failed to find zfs dataset mounted on '%s' in /proc/mounts", rootdir) }
func TestCreateWithOpts(t *testing.T) { if runtime.GOOS == "windows" { t.Skip() } rootDir, err := ioutil.TempDir("", "local-volume-test") if err != nil { t.Fatal(err) } defer os.RemoveAll(rootDir) r, err := New(rootDir, 0, 0) if err != nil { t.Fatal(err) } if _, err := r.Create("test", map[string]string{"invalidopt": "notsupported"}); err == nil { t.Fatal("expected invalid opt to cause error") } vol, err := r.Create("test", map[string]string{"device": "tmpfs", "type": "tmpfs", "o": "size=1m,uid=1000"}) if err != nil { t.Fatal(err) } v := vol.(*localVolume) dir, err := v.Mount("1234") if err != nil { t.Fatal(err) } defer func() { if err := v.Unmount("1234"); err != nil { t.Fatal(err) } }() mountInfos, err := mount.GetMounts() if err != nil { t.Fatal(err) } var found bool for _, info := range mountInfos { if info.Mountpoint == dir { found = true if info.Fstype != "tmpfs" { t.Fatalf("expected tmpfs mount, got %q", info.Fstype) } if info.Source != "tmpfs" { t.Fatalf("expected tmpfs mount, got %q", info.Source) } if !strings.Contains(info.VfsOpts, "uid=1000") { t.Fatalf("expected mount info to have uid=1000: %q", info.VfsOpts) } if !strings.Contains(info.VfsOpts, "size=1024k") { t.Fatalf("expected mount info to have size=1024k: %q", info.VfsOpts) } break } } if !found { t.Fatal("mount not found") } if v.active.count != 1 { t.Fatalf("Expected active mount count to be 1, got %d", v.active.count) } // test double mount if _, err := v.Mount("1234"); err != nil { t.Fatal(err) } if v.active.count != 2 { t.Fatalf("Expected active mount count to be 2, got %d", v.active.count) } if err := v.Unmount("1234"); err != nil { t.Fatal(err) } if v.active.count != 1 { t.Fatalf("Expected active mount count to be 1, got %d", v.active.count) } mounted, err := mount.Mounted(v.path) if err != nil { t.Fatal(err) } if !mounted { t.Fatal("expected mount to still be active") } r, err = New(rootDir, 0, 0) if err != nil { t.Fatal(err) } v2, exists := r.volumes["test"] if !exists { t.Fatal("missing volume on restart") } if !reflect.DeepEqual(v.opts, v2.opts) { t.Fatal("missing volume options on restart") } }