// Detach device from the host.
// Errors ErrEnoEnt, ErrVolDetached may be returned.
511895
func (v *volumeClient) Detach(volumeID string, options map[string]string) error {
	return v.doVolumeSet(
		volumeID,
		&api.VolumeSetRequest{
			Action: &api.VolumeStateAction{
				Attach: api.VolumeActionParam_VOLUME_ACTION_PARAM_OFF,
			},
			Options: options,
		},
	)
}
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
}
268030
func Detach(xu *xgbutil.XUtil, win xproto.Window) {
	detach(xu, xevent.KeyPress, win)
	detach(xu, xevent.KeyRelease, win)
}
31917
func (md *RootMetadataV2) RevokeRemovedDevices(
	updatedWriterKeys, updatedReaderKeys UserDevicePublicKeys,
	_ ExtraMetadata) (ServerHalfRemovalInfo, error) {
	if md.TlfID().Type() != tlf.Private {
		return nil, InvalidNonPrivateTLFOperation{
			md.TlfID(), "RevokeRemovedDevices", md.Version()}
	}

	var wRemovalInfo ServerHalfRemovalInfo
	for _, wkb := range md.WKeys {
		removalInfo := wkb.WKeys.RemoveDevicesNotIn(updatedWriterKeys)
		if wRemovalInfo == nil {
			wRemovalInfo = removalInfo
		} else {
			err := wRemovalInfo.AddGeneration(removalInfo)
			if err != nil {
				return nil, err
			}
		}
	}

	var rRemovalInfo ServerHalfRemovalInfo
	for _, rkb := range md.RKeys {
		removalInfo := rkb.RKeys.RemoveDevicesNotIn(updatedReaderKeys)
		if rRemovalInfo == nil {
			rRemovalInfo = removalInfo
		} else {
			err := rRemovalInfo.AddGeneration(removalInfo)
			if err != nil {
				return nil, err
			}
		}
	}

	return wRemovalInfo.MergeUsers(rRemovalInfo)
}
749630
func (s *cinderVolumeSource) DetachVolumes(ctx context.ProviderCallContext, args []storage.VolumeAttachmentParams) ([]error, error) {
	return detachVolumes(ctx, s.storageAdapter, args), nil
}
733152
func (g *Cloud) DetachDisk(devicePath string, nodeName types.NodeName) error {
	instanceName := mapNodeNameToInstanceName(nodeName)
	inst, err := g.getInstanceByName(instanceName)
	if err != nil {
		if err == cloudprovider.InstanceNotFound {
			// If instance no longer exists, safe to assume volume is not attached.
			klog.Warningf(
				"Instance %q does not exist. DetachDisk will assume PD %q is not attached to it.",
				instanceName,
				devicePath)
			return nil
		}

		return fmt.Errorf("error getting instance %q", instanceName)
	}

	mc := newDiskMetricContextZonal("detach", g.region, inst.Zone)
	return mc.Observe(g.manager.DetachDiskOnCloudProvider(inst.Zone, inst.Name, devicePath))
}
225644
func (d *flexVolumeDetacher) Detach(volumeName string, hostName types.NodeName) error {

	call := d.plugin.NewDriverCall(detachCmd)
	call.Append(volumeName)
	call.Append(string(hostName))

	_, err := call.Run()
	if isCmdNotSupportedErr(err) {
		return (*detacherDefaults)(d).Detach(volumeName, hostName)
	}
	return err
}
1289526
func (c *Cloud) endAttaching(i *awsInstance, volumeID awsVolumeID, mountDevice mountDevice) bool {
	c.attachingMutex.Lock()
	defer c.attachingMutex.Unlock()

	existingVolumeID, found := c.attaching[i.nodeName][mountDevice]
	if !found {
		return false
	}
	if volumeID != existingVolumeID {
		// This actually can happen, because getMountDevice combines the attaching map with the volumes
		// attached to the instance (as reported by the EC2 API).  So if endAttaching comes after
		// a 10 second poll delay, we might well have had a concurrent request to allocate a mountpoint,
		// which because we allocate sequentially is _very_ likely to get the immediately freed volume
		glog.Infof("endAttaching on device %q assigned to different volume: %q vs %q", mountDevice, volumeID, existingVolumeID)
		return false
	}
	glog.V(2).Infof("Releasing in-process attachment entry: %s -> volume %s", mountDevice, volumeID)
	delete(c.attaching[i.nodeName], mountDevice)
	return true
}
1013740
func (s *awsService) Detach(ctx context.Context, groupID string, instanceIDs []string) error {
	input := &aws.DetachGroupInput{
		GroupID:                       fi.String(groupID),
		InstanceIDs:                   instanceIDs,
		ShouldDecrementTargetCapacity: fi.Bool(false),
		ShouldTerminateInstances:      fi.Bool(true),
	}

	_, err := s.svc.Detach(ctx, input)
	return err
}
837085
func (m *loopDeviceManager) DetachLoopDevices(rootfs, prefix string) error {
	logger.Debugf("detaching loop devices inside %q", rootfs)
	loopDevices, err := loopDevices(m.run)
	if err != nil {
		return errors.Annotate(err, "listing loop devices")
	}

	for _, info := range loopDevices {
		logger.Debugf("checking loop device: %v", info)
		if !strings.HasPrefix(info.backingFile, prefix) {
			continue
		}
		if info.backingInode == 0 {
			continue
		}
		rootedBackingFile := path.Join(rootfs, info.backingFile)
		st, err := m.stat(rootedBackingFile)
		if os.IsNotExist(err) {
			continue
		} else if err != nil {
			return errors.Annotate(err, "querying backing file")
		}
		if m.inode(st) != info.backingInode {
			continue
		}
		logger.Debugf("detaching loop device %q", info.name)
		if err := detachLoopDevice(m.run, info.name); err != nil {
			return errors.Trace(err)
		}
	}
	return nil
}
1256413
func (os *OpenStack) DetachDisk(instanceID, volumeID string) error {
	volume, err := os.getVolume(volumeID)
	if err != nil {
		return err
	}
	if volume.Status == volumeAvailableStatus {
		// "available" is fine since that means the volume is detached from instance already.
		klog.V(2).Infof("volume: %s has been detached from compute: %s ", volume.ID, instanceID)
		return nil
	}

	if volume.Status != volumeInUseStatus {
		return fmt.Errorf("can not detach volume %s, its status is %s", volume.Name, volume.Status)
	}
	cClient, err := os.NewComputeV2()
	if err != nil {
		return err
	}
	if volume.AttachedServerID != instanceID {
		return fmt.Errorf("disk: %s has no attachments or is not attached to compute: %s", volume.Name, instanceID)
	}

	startTime := time.Now()
	// This is a blocking call and effects kubelet's performance directly.
	// We should consider kicking it out into a separate routine, if it is bad.
	err = volumeattach.Delete(cClient, instanceID, volume.ID).ExtractErr()
	timeTaken := time.Since(startTime).Seconds()
	recordOpenstackOperationMetric("detach_disk", timeTaken, err)
	if err != nil {
		return fmt.Errorf("failed to delete volume %s from compute %s attached %v", volume.ID, instanceID, err)
	}
	klog.V(2).Infof("Successfully detached volume: %s from compute: %s", volume.ID, instanceID)

	return nil
}
335039
func (n *NodeDevice) ReAttach() error {
	var err C.virError
	result := C.virNodeDeviceReAttachWrapper(n.ptr, &err)
	if result == -1 {
		return makeError(&err)
	}
	return nil
}
720491
func (util *portworxVolumeUtil) DetachVolume(u *portworxVolumeUnmounter) 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.Detach(u.volName, false /*doNotForceDetach*/)
	if err != nil {
		klog.Errorf("Error detaching Portworx Volume (%v): %v", u.volName, err)
		return err
	}
	return nil
}
1094450
func (vs *VSphere) DetachDisk(volPath string, nodeName k8stypes.NodeName) error {
	detachDiskInternal := func(volPath string, nodeName k8stypes.NodeName) error {
		if nodeName == "" {
			nodeName = convertToK8sType(vs.hostName)
		}
		// Create context
		ctx, cancel := context.WithCancel(context.Background())
		defer cancel()
		vsi, err := vs.getVSphereInstance(nodeName)
		if err != nil {
			// If node doesn't exist, disk is already detached from node.
			if err == vclib.ErrNoVMFound {
				klog.Infof("Node %q does not exist, disk %s is already detached from node.", convertToString(nodeName), volPath)
				return nil
			}
			return err
		}
		// Ensure client is logged in and session is valid
		err = vs.nodeManager.vcConnect(ctx, vsi)
		if err != nil {
			return err
		}
		vm, err := vs.getVMFromNodeName(ctx, nodeName)
		if err != nil {
			// If node doesn't exist, disk is already detached from node.
			if err == vclib.ErrNoVMFound {
				klog.Infof("Node %q does not exist, disk %s is already detached from node.", convertToString(nodeName), volPath)
				return nil
			}

			klog.Errorf("Failed to get VM object for node: %q. err: +%v", convertToString(nodeName), err)
			return err
		}
		err = vm.DetachDisk(ctx, volPath)
		if err != nil {
			klog.Errorf("Failed to detach disk: %s for node: %s. err: +%v", volPath, convertToString(nodeName), err)
			return err
		}
		return nil
	}
	requestTime := time.Now()
	err := detachDiskInternal(volPath, nodeName)
	if err != nil {
		if vclib.IsManagedObjectNotFoundError(err) {
			err = vs.nodeManager.RediscoverNode(nodeName)
			if err == nil {
				err = detachDiskInternal(volPath, nodeName)
			}
		}
	}
	vclib.RecordvSphereMetric(vclib.OperationDetachVolume, requestTime, err)
	return err
}
605976
func detachVolumes(ctx *context, ops map[params.MachineStorageId]*detachVolumeOp) error {
	volumeAttachmentParams := make([]storage.VolumeAttachmentParams, 0, len(ops))
	for _, op := range ops {
		volumeAttachmentParams = append(volumeAttachmentParams, op.args)
	}
	paramsBySource, volumeSources, err := volumeAttachmentParamsBySource(
		ctx.config.StorageDir, volumeAttachmentParams, ctx.config.Registry,
	)
	if err != nil {
		return errors.Trace(err)
	}
	var reschedule []scheduleOp
	var statuses []params.EntityStatusArgs
	var remove []params.MachineStorageId
	for sourceName, volumeAttachmentParams := range paramsBySource {
		logger.Debugf("detaching volumes: %+v", volumeAttachmentParams)
		volumeSource := volumeSources[sourceName]
		if volumeSource == nil {
			// The storage provider does not support dynamic
			// storage, there's nothing for the provisioner
			// to do here.
			continue
		}
		errs, err := volumeSource.DetachVolumes(ctx.config.CloudCallContext, volumeAttachmentParams)
		if err != nil {
			return errors.Annotatef(err, "detaching volumes from source %q", sourceName)
		}
		for i, err := range errs {
			p := volumeAttachmentParams[i]
			statuses = append(statuses, params.EntityStatusArgs{
				Tag: p.Volume.String(),
				// TODO(axw) when we support multiple
				// attachment, we'll have to check if
				// there are any other attachments
				// before saying the status "detached".
				Status: status.Detached.String(),
			})
			id := params.MachineStorageId{
				MachineTag:    p.Machine.String(),
				AttachmentTag: p.Volume.String(),
			}
			entityStatus := &statuses[len(statuses)-1]
			if err != nil {
				reschedule = append(reschedule, ops[id])
				entityStatus.Status = status.Detaching.String()
				entityStatus.Info = err.Error()
				logger.Debugf(
					"failed to detach %s from %s: %v",
					names.ReadableString(p.Volume),
					names.ReadableString(p.Machine),
					err,
				)
				continue
			}
			remove = append(remove, id)
		}
	}
	scheduleOperations(ctx, reschedule...)
	setStatus(ctx, statuses)
	if err := removeAttachments(ctx, remove); err != nil {
		return errors.Annotate(err, "removing attachments from state")
	}
	for _, id := range remove {
		delete(ctx.volumeAttachments, id)
	}
	return nil
}
897471
func (c *Client) Detach(storageIds []string, force *bool, maxWait *time.Duration) ([]params.ErrorResult, error) {
	results := params.ErrorResults{}
	ids := make([]params.StorageAttachmentId, len(storageIds))
	for i, id := range storageIds {
		if !names.IsValidStorage(id) {
			return nil, errors.NotValidf("storage ID %q", id)
		}
		ids[i] = params.StorageAttachmentId{
			StorageTag: names.NewStorageTag(id).String(),
		}
	}
	var args interface{}
	var method string
	if c.BestAPIVersion() < 6 {
		method = "Detach"
		args = params.StorageAttachmentIds{ids}
	} else {
		method = "DetachStorage"
		args = params.StorageDetachmentParams{
			StorageIds: params.StorageAttachmentIds{ids},
			Force:      force,
			MaxWait:    maxWait,
		}
	}
	if err := c.facade.FacadeCall(method, args, &results); err != nil {
		return nil, errors.Trace(err)
	}
	if len(results.Results) != len(storageIds) {
		return nil, errors.Errorf(
			"expected %d result(s), got %d",
			len(storageIds), len(results.Results),
		)
	}
	return results.Results, nil
}
992309
func (p *PoliciesClient) Detach(ctx context.Context, attachmentID *identity.ID) error {
	return p.client.RoundTrip(ctx, "DELETE", "/policy-attachments/"+attachmentID.String(), nil, nil, nil)
}