// NewUnmounter creates a representation of the volume to unmount
333628
func (p *sioPlugin) NewUnmounter(specName string, podUID types.UID) (volume.Unmounter, error) {
	klog.V(4).Info(log("Unmounter for %s", specName))

	return &sioVolume{
		podUID:      podUID,
		volSpecName: specName,
		plugin:      p,
	}, nil
}
638472
func NewVolumeDriver(name string, baseDirPath string, provider Provider) volume.VolumeDriver {
	return newVolumeDriver(name, baseDirPath, provider)
}
1021422
func NewVolumeService(root string, pg plugingetter.PluginGetter, rootIDs idtools.Identity, logger volumeEventLogger) (*VolumesService, error) {
	ds := drivers.NewStore(pg)
	if err := setupDefaultDriver(ds, root, rootIDs); err != nil {
		return nil, err
	}

	vs, err := NewStore(root, ds)
	if err != nil {
		return nil, err
	}
	return &VolumesService{vs: vs, ds: ds, eventLogger: logger}, nil
}
817315
func UnmountViaEmptyDir(dir string, host volume.VolumeHost, volName string, volSpec volume.Spec, podUID utypes.UID) error {
	klog.V(3).Infof("Tearing down volume %v for pod %v at %v", volName, podUID, dir)

	// Wrap EmptyDir, let it do the teardown.
	wrapped, err := host.NewWrapperUnmounter(volName, volSpec, podUID)
	if err != nil {
		return err
	}
	return wrapped.TearDownAt(dir)
}
24395
func (d *flexVolumeDetacher) UnmountDevice(deviceMountPath string) error {

	pathExists, pathErr := mount.PathExists(deviceMountPath)
	if !pathExists {
		klog.Warningf("Warning: Unmount skipped because path does not exist: %v", deviceMountPath)
		return nil
	}
	if pathErr != nil && !mount.IsCorruptedMnt(pathErr) {
		return fmt.Errorf("Error checking path: %v", pathErr)
	}

	notmnt, err := isNotMounted(d.plugin.host.GetMounter(d.plugin.GetPluginName()), deviceMountPath)
	if err != nil {
		if mount.IsCorruptedMnt(err) {
			notmnt = false // Corrupted error is assumed to be mounted.
		} else {
			return err
		}
	}

	if notmnt {
		klog.Warningf("Warning: Path: %v already unmounted", deviceMountPath)
	} else {
		call := d.plugin.NewDriverCall(unmountDeviceCmd)
		call.Append(deviceMountPath)

		_, err := call.Run()
		if isCmdNotSupportedErr(err) {
			err = (*detacherDefaults)(d).UnmountDevice(deviceMountPath)
		}
		if err != nil {
			return err
		}
	}

	// Flexvolume driver may remove the directory. Ignore if it does.
	if pathExists, pathErr := mount.PathExists(deviceMountPath); pathErr != nil {
		return fmt.Errorf("Error checking if path exists: %v", pathErr)
	} else if !pathExists {
		return nil
	}
	return os.Remove(deviceMountPath)
}
622983
func (v *localVolume) Unmount(id string) error {
	v.m.Lock()
	defer v.m.Unlock()

	// Always decrement the count, even if the unmount fails
	// Essentially docker doesn't care if this fails, it will send an error, but
	// ultimately there's nothing that can be done. If we don't decrement the count
	// this volume can never be removed until a daemon restart occurs.
	if v.opts != nil {
		v.active.count--
	}

	if v.active.count > 0 {
		return nil
	}

	return v.unmount()
}
88529
func (daemon *Daemon) conditionalUnmountOnCleanup(container *container.Container) error {

	// Bail out now for Linux containers
	if system.LCOWSupported() && container.OS != "windows" {
		return nil
	}

	// We do not unmount if a Hyper-V container
	if !daemon.runAsHyperVContainer(container.HostConfig) {
		return daemon.Unmount(container)
	}
	return nil
}
735150
func NewUpgrader(toSeries string, manager service.SystemdServiceManager, logger Logger) (Upgrader, error) {
	fromSeries, err := hostSeries()
	if err != nil {
		return nil, errors.Trace(err)
	}
	fromInit, err := service.VersionInitSystem(fromSeries)
	if err != nil {
		return nil, errors.Trace(err)
	}

	toInit, err := service.VersionInitSystem(toSeries)
	if err != nil {
		return nil, errors.Trace(err)
	}

	return &upgrader{
		logger:     logger,
		fromSeries: fromSeries,
		fromInit:   fromInit,
		toSeries:   toSeries,
		toInit:     toInit,
		manager:    manager,
	}, nil
}
498589
func (detacher *azureDiskDetacher) UnmountDevice(deviceMountPath string) error {
	err := mount.CleanupMountPoint(deviceMountPath, detacher.plugin.host.GetMounter(detacher.plugin.GetPluginName()), false)
	if err == nil {
		klog.V(2).Infof("azureDisk - Device %s was unmounted", deviceMountPath)
	} else {
		klog.Warningf("azureDisk - Device %s failed to unmount with error: %s", deviceMountPath, err.Error())
	}
	return err
}
911570
func NewVolumeMount(name, path string, readOnly bool) v1.VolumeMount {
	return v1.VolumeMount{
		Name:      name,
		MountPath: path,
		ReadOnly:  readOnly,
	}
}
621508
func (d *driver) Unmount(
	ctx types.Context,
	volumeID, volumeName string,
	opts types.Store) (*types.Volume, error) {

	ctx.WithFields(log.Fields{
		"volumeName": volumeName,
		"volumeID":   volumeID,
		"opts":       opts}).Info("unmounting volume")

	if volumeName == "" && volumeID == "" {
		return nil, goof.New("missing volume name or ID")
	}

	vol, err := d.volumeInspectByIDOrName(
		ctx, volumeID, volumeName,
		types.VolAttReqWithDevMapOnlyVolsAttachedToInstance, opts)
	if err != nil {
		return nil, err
	}

	if len(vol.Attachments) == 0 {
		return nil, nil
	}

	client := context.MustClient(ctx)

	inst, err := client.Storage().InstanceInspect(ctx, utils.NewStore())
	if err != nil {
		return nil, goof.New("problem getting instance ID")
	}
	var ma *types.VolumeAttachment
	for _, att := range vol.Attachments {
		if att.InstanceID.ID == inst.InstanceID.ID {
			ma = att
			break
		}
	}

	if ma == nil {
		return nil, goof.New("no attachment found for instance")
	}

	if ma.DeviceName == "" {
		return nil, goof.New("no device name found for attachment")
	}

	mounts, err := client.OS().Mounts(
		ctx, ma.DeviceName, "", opts)
	if err != nil {
		return nil, err
	}

	for _, mount := range mounts {
		ctx.WithField("mount", mount).Debug("retrieved mount")
	}

	if len(mounts) > 0 {
		for _, mount := range mounts {
			ctx.WithField("mount", mount).Debug("unmounting mount point")
			err = client.OS().Unmount(ctx, mount.MountPoint, opts)
			if err != nil {
				return nil, err
			}
		}
	}

	vol, err = client.Storage().VolumeDetach(ctx, vol.ID,
		&types.VolumeDetachOpts{
			Force: opts.GetBool("force"),
			Opts:  utils.NewStore(),
		})
	if err != nil {
		return nil, err
	}

	ctx.WithFields(log.Fields{
		"vol": vol}).Info("unmounted and detached volume")

	return vol, nil
}
336904
func (v *DeviceMapperVolume) unmount() error {
	glog.V(2).Infof("unmount() (%s) START", v.name)
	defer glog.V(2).Infof("unmount() (%s) END", v.name)
	v.driver.DeviceSet.Lock()
	defer v.driver.DeviceSet.Unlock()

	mountPath := v.Path()
	glog.V(2).Infof("Unmounting from path %s START", mountPath)
	if err := unmount(mountPath); err != nil {
		glog.Errorf("Got an error unmounting %s (%s)", mountPath, err)
		return err
	}
	glog.V(2).Infof("Unmounting from path %s END", mountPath)
	// pessimistically clean up the DeviceInfo object in memory. If it isn't
	// there the next time the device is requested, it'll be recreated from
	// disk.
	delete(v.driver.DeviceSet.Devices, v.Metadata.CurrentDevice())
	return nil
}
526062
func (d *detacherDefaults) UnmountDevice(deviceMountPath string) error {
	klog.Warning(logPrefix(d.plugin.flexVolumePlugin), "using default UnmountDevice for device mount path ", deviceMountPath)
	return mount.CleanupMountPoint(deviceMountPath, d.plugin.host.GetMounter(d.plugin.GetPluginName()), false)
}
140530
func (plugin *flexVolumePlugin) newMounterInternal(spec *volume.Spec, pod *api.Pod, mounter mount.Interface, runner exec.Interface) (volume.Mounter, error) {
	sourceDriver, err := getDriver(spec)
	if err != nil {
		return nil, err
	}

	readOnly, err := getReadOnly(spec)
	if err != nil {
		return nil, err
	}

	var metricsProvider volume.MetricsProvider
	if plugin.capabilities.SupportsMetrics {
		metricsProvider = volume.NewMetricsStatFS(plugin.host.GetPodVolumeDir(
			pod.UID, utilstrings.EscapeQualifiedName(sourceDriver), spec.Name()))
	} else {
		metricsProvider = &volume.MetricsNil{}
	}

	return &flexVolumeMounter{
		flexVolume: &flexVolume{
			driverName:            sourceDriver,
			execPath:              plugin.getExecutable(),
			mounter:               mounter,
			plugin:                plugin,
			podName:               pod.Name,
			podUID:                pod.UID,
			podNamespace:          pod.Namespace,
			podServiceAccountName: pod.Spec.ServiceAccountName,
			volName:               spec.Name(),
			MetricsProvider:       metricsProvider,
		},
		runner:   runner,
		spec:     spec,
		readOnly: readOnly,
	}, nil
}
1370299
func NewDeviceMounter(
	devPrefixes []string,
	mountImpl MountImpl,
	allowedDirs []string,
	trashLocation string,
) (*deviceMounter, error) {

	m := &deviceMounter{
		Mounter: Mounter{
			mountImpl:     mountImpl,
			mounts:        make(DeviceMap),
			paths:         make(PathMap),
			allowedDirs:   allowedDirs,
			kl:            keylock.New(),
			trashLocation: trashLocation,
		},
	}
	err := m.Load(devPrefixes)
	if err != nil {
		return nil, err
	}

	if len(m.trashLocation) > 0 {
		if err := os.MkdirAll(m.trashLocation, 0755); err != nil {
			return nil, err
		}
	}

	return m, nil
}
381058
func (util *portworxVolumeUtil) UnmountVolume(u *portworxVolumeUnmounter, mountPath string) error {
	driver, err := util.getLocalPortworxDriver(u.plugin.host)
	if err != nil || driver == nil {
		klog.Errorf("Failed to get portworx driver. Err: %v", err)
		return err
	}

	err = driver.Unmount(u.volName, mountPath)
	if err != nil {
		klog.Errorf("Error unmounting Portworx Volume (%v) on Path (%v): %v", u.volName, mountPath, err)
		return err
	}
	return nil
}
808177
func filterUnmountedVolumes(mountedVolumes sets.String, expectedVolumes []string) []string {
	unmountedVolumes := []string{}
	for _, expectedVolume := range expectedVolumes {
		if !mountedVolumes.Has(expectedVolume) {
			unmountedVolumes = append(unmountedVolumes, expectedVolume)
		}
	}
	return unmountedVolumes
}