// BindMount, well, bind mounts a source in to a destination. This will
// do some bookkeeping:
// * evaluate all symlinks
// * ensure the source exists
// * recursively create the destination
490967
func BindMount(mnt fs.MountUnmounter, source, destination string, readOnly bool) error {
	absSource, err := filepath.EvalSymlinks(source)
	if err != nil {
		return errwrap.Wrap(fmt.Errorf("Could not resolve symlink for source %v", source), err)
	}

	if err := EnsureTargetExists(absSource, destination); err != nil {
		return errwrap.Wrap(fmt.Errorf("Could not create destination mount point: %v", destination), err)
	} else if err := mnt.Mount(absSource, destination, "bind", syscall.MS_BIND, ""); err != nil {
		return errwrap.Wrap(fmt.Errorf("Could not bind mount %v to %v", absSource, destination), err)
	}
	if readOnly {
		err := mnt.Mount(source, destination, "bind", syscall.MS_REMOUNT|syscall.MS_RDONLY|syscall.MS_BIND, "")

		// If we failed to remount ro, unmount
		if err != nil {
			mnt.Unmount(destination, 0) // if this fails, oh well
			return errwrap.Wrap(fmt.Errorf("Could not remount %v read-only", destination), err)
		}
	}
	return nil
}
1239159
func (rl *referencedRWLayer) Unmount() error {
	return rl.layerStore.driver.Put(rl.mountedLayer.mountID)
}
248172
func Mounted(mountpoint string) (bool, error) {
	var mntpointSt unix.Stat_t
	if err := unix.Stat(mountpoint, &mntpointSt); err != nil {
		if os.IsNotExist(err) {
			return false, nil
		}
		return false, err
	}
	var parentSt unix.Stat_t
	if err := unix.Stat(filepath.Join(mountpoint, ".."), &parentSt); err != nil {
		return false, err
	}
	return mntpointSt.Dev != parentSt.Dev, nil
}
651631
func (b *snapshotter) Mounts(ctx context.Context, key string) ([]mount.Mount, error) {
	ctx, t, err := b.ms.TransactionContext(ctx, false)
	if err != nil {
		return nil, err
	}
	s, err := storage.GetSnapshot(ctx, key)
	t.Rollback()
	if err != nil {
		return nil, errors.Wrap(err, "failed to get active snapshot")
	}

	dir := filepath.Join(b.root, strings.ToLower(s.Kind.String()), s.ID)
	return b.mounts(dir, s)
}
720759
func (m *MountPoint) Setup(mountLabel string, rootIDs idtools.Identity, checkFun func(m *MountPoint) error) (path string, err error) {
	if m.SkipMountpointCreation {
		return m.Source, nil
	}

	defer func() {
		if err != nil || !label.RelabelNeeded(m.Mode) {
			return
		}

		var sourcePath string
		sourcePath, err = filepath.EvalSymlinks(m.Source)
		if err != nil {
			path = ""
			err = errors.Wrapf(err, "error evaluating symlinks from mount source %q", m.Source)
			return
		}
		err = label.Relabel(sourcePath, mountLabel, label.IsShared(m.Mode))
		if err == syscall.ENOTSUP {
			err = nil
		}
		if err != nil {
			path = ""
			err = errors.Wrapf(err, "error setting label on mount source '%s'", sourcePath)
		}
	}()

	if m.Volume != nil {
		id := m.ID
		if id == "" {
			id = stringid.GenerateNonCryptoID()
		}
		path, err := m.Volume.Mount(id)
		if err != nil {
			return "", errors.Wrapf(err, "error while mounting volume '%s'", m.Source)
		}

		m.ID = id
		m.active++
		return path, nil
	}

	if len(m.Source) == 0 {
		return "", fmt.Errorf("Unable to setup mount point, neither source nor volume defined")
	}

	if m.Type == mounttypes.TypeBind {
		// Before creating the source directory on the host, invoke checkFun if it's not nil. One of
		// the use case is to forbid creating the daemon socket as a directory if the daemon is in
		// the process of shutting down.
		if checkFun != nil {
			if err := checkFun(m); err != nil {
				return "", err
			}
		}

		// idtools.MkdirAllNewAs() produces an error if m.Source exists and is a file (not a directory)
		// also, makes sure that if the directory is created, the correct remapped rootUID/rootGID will own it
		if err := idtools.MkdirAllAndChownNew(m.Source, 0755, rootIDs); err != nil {
			if perr, ok := err.(*os.PathError); ok {
				if perr.Err != syscall.ENOTDIR {
					return "", errors.Wrapf(err, "error while creating mount source path '%s'", m.Source)
				}
			}
		}
	}
	return m.Source, nil
}
946841
func (u *unionFS) bind(mountPoint string, fs http.FileSystem) {
	u.ns[mountPoint] = fs
	u.root.entries = append(u.root.entries, &dirInfo{
		name: mountPoint[1:],
	})
}
80676
func Mount(cfg *MountCfg) error {
	err := syscall.Mount("overlay", cfg.Dest, "overlay", 0, cfg.Opts())
	if err != nil {
		const text = "error mounting overlay with options '%s' and dest '%s'"
		return errwrap.Wrap(fmt.Errorf(text, cfg.Opts(), cfg.Dest), err)
	}

	return nil
}
450434
func (m *Mounter) Mounts(sourcePath string) []string {
	m.Lock()
	defer m.Unlock()

	v, ok := m.mounts[sourcePath]
	if !ok {
		return nil
	}

	mounts := make([]string, len(v.Mountpoint))
	for i, v := range v.Mountpoint {
		mounts[i] = v.Path
	}

	return mounts
}
59815
func CreateMount() (*MountInfo, error) {
	mount := &MountInfo{}
	ret := C.ceph_create(&mount.mount, nil)
	if ret != 0 {
		log.Errorf("CreateMount: Failed to create mount")
		return nil, cephError(ret)
	}
	return mount, nil
}
260187
func (c *Core) remount(ctx context.Context, src, dst string) error {
	ns, err := namespace.FromContext(ctx)
	if err != nil {
		return err
	}

	// Ensure we end the path in a slash
	if !strings.HasSuffix(src, "/") {
		src += "/"
	}
	if !strings.HasSuffix(dst, "/") {
		dst += "/"
	}

	// Prevent protected paths from being remounted
	for _, p := range protectedMounts {
		if strings.HasPrefix(src, p) {
			return fmt.Errorf("cannot remount %q", src)
		}
	}

	// Verify exact match of the route
	srcMatch := c.router.MatchingMountEntry(ctx, src)
	if srcMatch == nil {
		return fmt.Errorf("no matching mount at %q", src)
	}
	if srcMatch.NamespaceID != ns.ID {
		return fmt.Errorf("source mount in a different namespace than request")
	}

	if err := verifyNamespace(c, ns, &MountEntry{Path: dst}); err != nil {
		return err
	}

	if match := c.router.MatchingMount(ctx, dst); match != "" {
		return fmt.Errorf("existing mount at %q", match)
	}

	// Mark the entry as tainted
	if err := c.taintMountEntry(ctx, src, true); err != nil {
		return err
	}

	// Taint the router path to prevent routing
	if err := c.router.Taint(ctx, src); err != nil {
		return err
	}

	if !c.IsDRSecondary() {
		// Invoke the rollback manager a final time
		rCtx := namespace.ContextWithNamespace(c.activeContext, ns)
		if err := c.rollback.Rollback(rCtx, src); err != nil {
			return err
		}

		entry := c.router.MatchingMountEntry(ctx, src)
		if entry == nil {
			return fmt.Errorf("no matching mount at %q", src)
		}

		// Revoke all the dynamic keys
		if err := c.expiration.RevokePrefix(rCtx, src, true); err != nil {
			return err
		}
	}

	c.mountsLock.Lock()
	var entry *MountEntry
	for _, mountEntry := range c.mounts.Entries {
		if mountEntry.Path == src && mountEntry.NamespaceID == ns.ID {
			entry = mountEntry
			entry.Path = dst
			entry.Tainted = false
			break
		}
	}

	if entry == nil {
		c.mountsLock.Unlock()
		c.logger.Error("failed to find entry in mounts table")
		return logical.CodedError(500, "failed to find entry in mounts table")
	}

	// Update the mount table
	if err := c.persistMounts(ctx, c.mounts, &entry.Local); err != nil {
		entry.Path = src
		entry.Tainted = true
		c.mountsLock.Unlock()
		if err == logical.ErrReadOnly && c.perfStandby {
			return err
		}

		c.logger.Error("failed to update mounts table", "error", err)
		return logical.CodedError(500, "failed to update mounts table")
	}
	c.mountsLock.Unlock()

	// Remount the backend
	if err := c.router.Remount(ctx, src, dst); err != nil {
		return err
	}

	// Un-taint the path
	if err := c.router.Untaint(ctx, dst); err != nil {
		return err
	}

	if c.logger.IsInfo() {
		c.logger.Info("successful remount", "old_path", src, "new_path", dst)
	}
	return nil
}
482758
func (m *execMounter) doExecMount(source, target, fstype string, options []string) error {
	klog.V(5).Infof("Exec Mounting %s %s %s %v", source, target, fstype, options)
	mountArgs := mount.MakeMountArgs(source, target, fstype, options)
	output, err := m.exec.Run("mount", mountArgs...)
	klog.V(5).Infof("Exec mounted %v: %v: %s", mountArgs, err, string(output))
	if err != nil {
		return fmt.Errorf("mount failed: %v\nMounting command: %s\nMounting arguments: %s %s %s %v\nOutput: %s",
			err, "mount", source, target, fstype, options, string(output))
	}

	return err
}
1167665
func (c *Core) loadMounts(ctx context.Context) error {
	// Load the existing mount table
	raw, err := c.barrier.Get(ctx, coreMountConfigPath)
	if err != nil {
		c.logger.Error("failed to read mount table", "error", err)
		return errLoadMountsFailed
	}
	rawLocal, err := c.barrier.Get(ctx, coreLocalMountConfigPath)
	if err != nil {
		c.logger.Error("failed to read local mount table", "error", err)
		return errLoadMountsFailed
	}

	c.mountsLock.Lock()
	defer c.mountsLock.Unlock()

	if raw != nil {
		// Check if the persisted value has canary in the beginning. If
		// yes, decompress the table and then JSON decode it. If not,
		// simply JSON decode it.
		mountTable, err := c.decodeMountTable(ctx, raw.Value)
		if err != nil {
			c.logger.Error("failed to decompress and/or decode the mount table", "error", err)
			return err
		}
		c.mounts = mountTable
	}

	var needPersist bool
	if c.mounts == nil {
		c.logger.Info("no mounts; adding default mount table")
		c.mounts = c.defaultMountTable()
		needPersist = true
	}

	if rawLocal != nil {
		localMountTable, err := c.decodeMountTable(ctx, rawLocal.Value)
		if err != nil {
			c.logger.Error("failed to decompress and/or decode the local mount table", "error", err)
			return err
		}
		if localMountTable != nil && len(localMountTable.Entries) > 0 {
			c.mounts.Entries = append(c.mounts.Entries, localMountTable.Entries...)
		}
	}

	// Note that this is only designed to work with singletons, as it checks by
	// type only.

	// Upgrade to typed mount table
	if c.mounts.Type == "" {
		c.mounts.Type = mountTableType
		needPersist = true
	}

	for _, requiredMount := range c.requiredMountTable().Entries {
		foundRequired := false
		for _, coreMount := range c.mounts.Entries {
			if coreMount.Type == requiredMount.Type {
				foundRequired = true
				coreMount.Config = requiredMount.Config
				break
			}
		}

		// In a replication scenario we will let sync invalidation take
		// care of creating a new required mount that doesn't exist yet.
		// This should only happen in the upgrade case where a new one is
		// introduced on the primary; otherwise initial bootstrapping will
		// ensure this comes over. If we upgrade first, we simply don't
		// create the mount, so we won't conflict when we sync. If this is
		// local (e.g. cubbyhole) we do still add it.
		if !foundRequired && (!c.ReplicationState().HasState(consts.ReplicationPerformanceSecondary) || requiredMount.Local) {
			c.mounts.Entries = append(c.mounts.Entries, requiredMount)
			needPersist = true
		}
	}

	// Upgrade to table-scoped entries
	for _, entry := range c.mounts.Entries {
		if entry.Type == cubbyholeMountType && !entry.Local {
			entry.Local = true
			needPersist = true
		}
		if entry.Table == "" {
			entry.Table = c.mounts.Type
			needPersist = true
		}
		if entry.Accessor == "" {
			accessor, err := c.generateMountAccessor(entry.Type)
			if err != nil {
				return err
			}
			entry.Accessor = accessor
			needPersist = true
		}
		if entry.BackendAwareUUID == "" {
			bUUID, err := uuid.GenerateUUID()
			if err != nil {
				return err
			}
			entry.BackendAwareUUID = bUUID
			needPersist = true
		}

		if entry.NamespaceID == "" {
			entry.NamespaceID = namespace.RootNamespaceID
			needPersist = true
		}
		ns, err := NamespaceByID(ctx, entry.NamespaceID, c)
		if err != nil {
			return err
		}
		if ns == nil {
			return namespace.ErrNoNamespace
		}
		entry.namespace = ns

		// Sync values to the cache
		entry.SyncCache()
	}

	// Done if we have restored the mount table and we don't need
	// to persist
	if !needPersist {
		return nil
	}

	// Persist both mount tables
	if err := c.persistMounts(ctx, c.mounts, nil); err != nil {
		c.logger.Error("failed to persist mount table", "error", err)
		return errLoadMountsFailed
	}
	return nil
}
266815
func getSourceMount(source string) (string, string, error) {
	// Ensure any symlinks are resolved.
	sourcePath, err := filepath.EvalSymlinks(source)
	if err != nil {
		return "", "", err
	}

	mi, err := mount.GetMounts(mount.ParentsFilter(sourcePath))
	if err != nil {
		return "", "", err
	}
	if len(mi) < 1 {
		return "", "", fmt.Errorf("Can't find mount point of %s", source)
	}

	// find the longest mount point
	var idx, maxlen int
	for i := range mi {
		if len(mi[i].Mountpoint) > maxlen {
			maxlen = len(mi[i].Mountpoint)
			idx = i
		}
	}
	return mi[idx].Mountpoint, mi[idx].Optional, nil
}
1369741
func (m *execMounter) Mount(source string, target string, fstype string, options []string) error {
	bind, bindOpts, bindRemountOpts := mount.IsBind(options)

	if bind {
		err := m.doExecMount(source, target, fstype, bindOpts)
		if err != nil {
			return err
		}
		return m.doExecMount(source, target, fstype, bindRemountOpts)
	}

	return m.doExecMount(source, target, fstype, options)
}
935187
func (f *Folder) addMount(path []string, dest string) error {
	if len(path) < 1 {
		return errors.Errorf("Path must not be empty")
	}
	name := path[0]
	if len(path) == 1 {
		f.Folders[name] = newMount(name, dest)
		return nil
	}
	next := f.getFolder(name)
	return next.addMount(path[1:], dest)
}
409280
func (c *client) MountBlob(ctx context.Context, sourceRef reference.Canonical, targetRef reference.Named) error {
	repoEndpoint, err := newDefaultRepositoryEndpoint(targetRef, c.insecureRegistry)
	if err != nil {
		return err
	}
	repo, err := c.getRepositoryForReference(ctx, targetRef, repoEndpoint)
	if err != nil {
		return err
	}
	lu, err := repo.Blobs(ctx).Create(ctx, distributionclient.WithMountFrom(sourceRef))
	switch err.(type) {
	case distribution.ErrBlobMounted:
		logrus.Debugf("mount of blob %s succeeded", sourceRef)
		return nil
	case nil:
	default:
		return errors.Wrapf(err, "failed to mount blob %s to %s", sourceRef, targetRef)
	}
	lu.Cancel(ctx)
	logrus.Debugf("mount of blob %s created", sourceRef)
	return ErrBlobCreated{From: sourceRef, Target: targetRef}
}
782915
func (m *execMounter) Unmount(target string) error {
	outputBytes, err := m.exec.Run("umount", target)
	if err == nil {
		klog.V(5).Infof("Exec unmounted %s: %s", target, string(outputBytes))
	} else {
		klog.V(5).Infof("Failed to exec unmount %s: err: %q, umount output: %s", target, err, string(outputBytes))
	}

	return err
}