// Snap specified volume. IO to the underlying volume should be quiesced before
// calling this function.
// Errors ErrEnoEnt may be returned
341751
func (v *volumeClient) Snapshot(volumeID string,
	readonly bool,
	locator *api.VolumeLocator,
	noRetry bool,
) (string, error) {
	response := &api.SnapCreateResponse{}
	request := &api.SnapCreateRequest{
		Id:       volumeID,
		Readonly: readonly,
		Locator:  locator,
		NoRetry:  noRetry,
	}
	if err := v.c.Post().Resource(snapPath).Body(request).Do().Unmarshal(response); err != nil {
		return "", err
	}

	// TODO(pedge): this probably should not be embedded in this way
	if response.VolumeCreateResponse != nil &&
		response.VolumeCreateResponse.VolumeResponse != nil &&
		response.VolumeCreateResponse.VolumeResponse.Error != "" {
		return "", errors.New(
			response.VolumeCreateResponse.VolumeResponse.Error)
	}
	if response.VolumeCreateResponse != nil {
		return response.VolumeCreateResponse.Id, nil
	}
	return "", nil
}
640763
func (os *OpenStack) ExpandVolume(volumeID string, oldSize resource.Quantity, newSize resource.Quantity) (resource.Quantity, error) {
	volume, err := os.getVolume(volumeID)
	if err != nil {
		return oldSize, err
	}
	if volume.Status != volumeAvailableStatus {
		// cinder volume can not be expanded if its status is not available
		return oldSize, fmt.Errorf("volume status is not available")
	}

	// Cinder works with gigabytes, convert to GiB with rounding up
	volSizeGiB, err := volumehelpers.RoundUpToGiBInt(newSize)
	if err != nil {
		return oldSize, err
	}
	newSizeQuant := resource.MustParse(fmt.Sprintf("%dGi", volSizeGiB))

	// if volume size equals to or greater than the newSize, return nil
	if volume.Size >= volSizeGiB {
		return newSizeQuant, nil
	}

	volumes, err := os.volumeService("")
	if err != nil {
		return oldSize, err
	}

	err = volumes.expandVolume(volumeID, volSizeGiB)
	if err != nil {
		return oldSize, err
	}
	return newSizeQuant, nil
}
127849
func (v *RsyncVolume) Snapshot(label, message string, tags []string) (err error) {
	v.Lock()
	defer v.Unlock()
	// does the snapshot already exist
	label = v.rawSnapshotLabel(label)
	dest := v.snapshotPath(label)
	if exists, err := volume.IsDir(dest); exists || err != nil {
		if exists {
			glog.Errorf("Snapshot exists: %s", v.rawSnapshotLabel(label))
			return volume.ErrSnapshotExists
		}
		return err
	}
	// check the tags for duplicates
	for _, tagName := range tags {
		if tagInfo, err := v.getSnapshotWithTag(tagName, false); err != volume.ErrSnapshotDoesNotExist {
			if err != nil {
				glog.Errorf("Could not look up snapshot for tag %s: %s", tagName, err)
				return err
			} else {
				glog.Errorf("Tag '%s' is already in use by snapshot %s", tagName, tagInfo.Name)
				return volume.ErrTagAlreadyExists
			}
		}
	}
	// write snapshot info
	info := volume.SnapshotInfo{
		Name:     v.rawSnapshotLabel(label),
		TenantID: v.Tenant(),
		Label:    v.prettySnapshotLabel(label),
		Tags:     tags,
		Message:  message,
		Created:  time.Now(),
	}
	if err := v.writeSnapshotInfo(label, &info); err != nil {
		return err
	}
	exe, err := exec.LookPath("rsync")
	if err != nil {
		return err
	}
	argv := []string{"-a", v.Path() + "/", dest + "/"}
	glog.Infof("Performing snapshot rsync command: %s %s", exe, argv)
	if err := os.MkdirAll(filepath.Join(v.driver.MetadataDir(), label), 0755); err != nil && !os.IsExist(err) {
		return err
	}
	var output []byte
	for i := 0; i < 3; i++ {
		rsync := exec.Command(exe, argv...)
		done := make(chan interface{})
		go func() {
			defer close(done)
			output, err = rsync.CombinedOutput()
		}()

		select {
		case <-time.After(v.timeout):
			glog.V(2).Infof("Received signal to kill rsync")
			rsync.Process.Kill()
			<-done
		case <-done:
		}
		if err == nil {
			return nil
		}
		if exitStatus, ok := utils.GetExitStatus(err); !ok || exitStatus != 24 {
			glog.Errorf("Could not perform rsync: %s", string(output))
			return err
		}
		glog.Infof("trying snapshot again: %s", label)
	}
	if exitStatus, _ := utils.GetExitStatus(err); exitStatus == 24 {
		glog.Warningf("snapshot completed with errors: Partial transfer due to vanished source files")
		return nil
	}
	glog.Errorf("Could not perform rsync: %s", string(output))
	return err
}
628582
func (c *Host) DestroyVolume(volumeID string) error {
	return c.c.Delete(fmt.Sprintf("/storage/volumes/%s", volumeID))
}
1273101
func (s *VolumeServer) SnapshotRestore(
	ctx context.Context,
	req *api.SdkVolumeSnapshotRestoreRequest,
) (*api.SdkVolumeSnapshotRestoreResponse, error) {
	if s.cluster() == nil || s.driver(ctx) == nil {
		return nil, status.Error(codes.Unavailable, "Resource has not been initialized")
	}

	if len(req.GetVolumeId()) == 0 {
		return nil, status.Error(codes.InvalidArgument, "Must supply volume id")
	} else if len(req.GetSnapshotId()) == 0 {
		return nil, status.Error(codes.InvalidArgument, "Must supply snapshot id")
	}

	// Get access rights
	if err := s.checkAccessForVolumeId(ctx, req.GetVolumeId(), api.Ownership_Write); err != nil {
		return nil, err
	}

	err := s.driver(ctx).Restore(req.GetVolumeId(), req.GetSnapshotId())
	if err != nil {
		if err == kvdb.ErrNotFound {
			return nil, status.Errorf(
				codes.NotFound,
				"Id %s or %s not found",
				req.GetVolumeId(), req.GetSnapshotId())
		}
		return nil, status.Errorf(
			codes.Internal,
			"Failed to restore volume %s to snapshot %s: %v",
			req.GetVolumeId(),
			req.GetSnapshotId(),
			err.Error())
	}

	return &api.SdkVolumeSnapshotRestoreResponse{}, nil
}
670821
func (ec2i *FakeEC2Impl) DetachVolume(request *ec2.DetachVolumeInput) (resp *ec2.VolumeAttachment, err error) {
	panic("Not implemented")
}
67240
func (ec2i *FakeEC2Impl) AttachVolume(request *ec2.AttachVolumeInput) (resp *ec2.VolumeAttachment, err error) {
	panic("Not implemented")
}
1141108
func (dfs *DistributedFilesystem) Snapshot(data SnapshotInfo, spaceFactor int) (string, error) {
	label := generateSnapshotLabel()
	vol, err := dfs.disk.Get(data.TenantID)

	if volume.DriverTypeDeviceMapper == dfs.disk.DriverType() {
		freeSpace, err := ensureFreeSpace(vol, dfs, spaceFactor)
		if err != nil {
			glog.Errorf("Could not determine freespace on devicemapper device %s", err)
			return "", err
		}
		if !freeSpace {
			return "", errors.New("There is not enough diskspace to complete your request. You should enlarge your thin pool using LVM tools and/or delete some snapshots")
		}
	}
	if err != nil {
		glog.Errorf("Could not get volume for tenant %s: %s", data.TenantID, err)
		return "", err
	}
	// relabel all registry tags for this snapshot
	images := make([]string, len(data.Images))
	for i, image := range data.Images {
		rImage, err := dfs.index.FindImage(image)
		if err != nil {
			glog.Errorf("Could not find image %s for snapshot: %s", image, err)
			return "", err
		}

		// make sure we actually have the image locally before changing the tag and triggering a push
		if _, err := dfs.reg.FindImage(rImage); err != nil {
			glog.Errorf("Could not find image %s locally for snapshot:  %s", rImage.String(), err)
			return "", err
		}

		rImage.Tag = label
		if err := dfs.index.PushImage(rImage.String(), rImage.UUID, rImage.Hash); err != nil {
			glog.Errorf("Could not retag image %s for snapshot: %s", image, err)
			return "", err
		}
		fullImagePath, err := dfs.reg.ImagePath(rImage.String())
		if err != nil {
			glog.Errorf("Could not get the full image path for image %s: %s", image, err)
			return "", err
		}
		images[i] = fullImagePath
	}
	// write snapshot metadata
	w, err := vol.WriteMetadata(label, ImagesMetadataFile)
	if err != nil {
		glog.Errorf("Could not create image metadata file for tenant %s: %s", data.TenantID, err)
		return "", err
	}
	if err := exportJSON(w, images); err != nil {
		glog.Errorf("Could not write service metadata file for tenant %s: %s", data.TenantID, err)
		return "", err
	}
	w, err = vol.WriteMetadata(label, ServicesMetadataFile)
	if err != nil {
		glog.Errorf("Could not create service metadata file for tenant %s: %s", data.TenantID, err)
		return "", err
	}
	if err := exportJSON(w, data.Services); err != nil {
		glog.Errorf("Could not write service metadata file for tenant %s: %s", data.TenantID, err)
		return "", err
	}
	// snapshot the volume
	if err := vol.Snapshot(label, data.Message, data.Tags); err != nil {
		glog.Errorf("Could not snapshot volume for tenant %s: %s", data.TenantID, err)
		return "", err
	}
	info, err := vol.SnapshotInfo(label)
	if err != nil {
		glog.Errorf("Could not get info for snapshot %s of tenant %s: %s", label, data.TenantID, err)
		return "", err
	}
	return info.Name, nil
}
79252
func (d *driver) VolumeCreateFromSnapshot(
	ctx types.Context,
	snapshotID, volumeName string,
	opts *types.VolumeCreateOpts) (*types.Volume, error) {
	return nil, types.ErrNotImplemented
}
1238718
func (s *VolumeService) AttachVolume(p *AttachVolumeParams) (*AttachVolumeResponse, error) {
	resp, err := s.cs.newRequest("attachVolume", p.toURLValues())
	if err != nil {
		return nil, err
	}

	var r AttachVolumeResponse
	if err := json.Unmarshal(resp, &r); err != nil {
		return nil, err
	}

	// If we have a async client, we need to wait for the async result
	if s.cs.async {
		b, err := s.cs.GetAsyncJobResult(r.JobID, s.cs.timeout)
		if err != nil {
			if err == AsyncTimeoutErr {
				return &r, err
			}
			return nil, err
		}

		b, err = getRawValue(b)
		if err != nil {
			return nil, err
		}

		if err := json.Unmarshal(b, &r); err != nil {
			return nil, err
		}
	}

	return &r, nil
}
698073
func (p *Player) SetVolume(volume float64) {
	// The condition must be true when volume is NaN.
	if volume < 0 || volume > 1 {
		log.Println("Volume can only be set between zero and one. Volume was not set.")
		return
	}

	p.sync(func() {
		p.volume = volume * masterVolume
	})
}
582402
func (os *OpenStack) CreateVolume(name string, size int, vtype, availability, snapshotID string, tags *map[string]string) (string, string, error) {
	volumes, err := os.volumeService("")
	if err != nil || volumes == nil {
		glog.Errorf("Unable to initialize cinder client for region: %s", os.region)
		return "", "", err
	}

	opts := VolumeCreateOpts{
		Name:             name,
		Size:             size,
		VolumeType:       vtype,
		Availability:     availability,
		SourceSnapshotID: snapshotID,
	}
	if tags != nil {
		opts.Metadata = *tags
	}

	volumeID, volumeAZ, err := volumes.createVolume(opts)

	if err != nil {
		glog.Errorf("Failed to create a %d GB volume: %v", size, err)
		return "", "", err
	}

	glog.Infof("Created volume %v in Availability Zone: %v", volumeID, volumeAZ)
	return volumeID, volumeAZ, nil
}
1232211
func (v *DeviceMapperVolume) rawSnapshotLabel(label string) string {
	return volume.DefaultSnapshotLabel(v.Tenant(), label)
}
448961
func (c *Server) AddVolume(volumePath string) error {
	c.Lock()
	defer c.Unlock()
	fsid := atomic.AddInt32(&fsidIdx, 1)
	c.volumes[volumePath] = fsid
	return nil
}
632255
func (ga *openstackStorageAdapter) DetachVolume(serverId, attachmentId string) error {
	if err := ga.novaClient.DetachVolume(serverId, attachmentId); err != nil {
		if gooseerrors.IsNotFound(err) {
			return errors.NewNotFound(nil,
				fmt.Sprintf("volume %q is not attached to server %q",
					attachmentId, serverId,
				),
			)
		}
		return err
	}
	return nil
}
449677
func (s *VolumeService) GetVolumeByName(name string, opts ...OptionFunc) (*Volume, int, error) {
	id, count, err := s.GetVolumeID(name, opts...)
	if err != nil {
		return nil, count, err
	}

	r, count, err := s.GetVolumeByID(id, opts...)
	if err != nil {
		return nil, count, err
	}
	return r, count, nil
}
1313254
func (d *RsyncDriver) Remove(volumeName string) error {
	v, err := d.Get(volumeName)
	if err != nil {
		return err
	}
	// Delete all of the snapshots
	snapshots, err := v.Snapshots()
	if err != nil {
		return err
	}

	for _, snapshot := range snapshots {
		if err := v.RemoveSnapshot(snapshot); err != nil {
			return err
		}
	}
	// Delete the volume
	v.(*RsyncVolume).Lock()
	defer v.(*RsyncVolume).Unlock()
	if err := os.RemoveAll(filepath.Join(d.MetadataDir(), volumeName)); err != nil {
		return err
	} else if err := os.RemoveAll(v.Path()); err != nil {
		glog.Errorf("Could not delete volume %s: %s", volumeName, err)
		return ErrDeletingVolume
	}
	return nil
}