Beispiel #1
0
func TestVolumes(t *testing.T) {
	zpoolTest(t, func() {
		v, err := zfs.CreateVolume("test/volume-test", uint64(pow2(23)), nil)
		ok(t, err)

		// volumes are sometimes "busy" if you try to manipulate them right away
		sleep(1)

		equals(t, zfs.DatasetVolume, v.Type)
		volumes, err := zfs.Volumes("")
		ok(t, err)

		for _, volume := range volumes {
			equals(t, zfs.DatasetVolume, volume.Type)
		}

		ok(t, v.Destroy(zfs.DestroyDefault))
	})
}
Beispiel #2
0
func (p *Provider) ImportFilesystem(fs *volume.Filesystem) (volume.Volume, error) {
	if fs.ID == "" {
		fs.ID = random.UUID()
	}
	info := fs.Info()
	info.CreatedAt = time.Now()
	v := &zfsVolume{
		info:       info,
		provider:   p,
		basemount:  p.mountPath(info),
		filesystem: fs,
	}

	// align size to blockSize
	size := (fs.Size/blockSize + 1) * blockSize

	opts := map[string]string{
		"volblocksize": strconv.Itoa(blockSize),
	}
	if _, ok := fs.Data.(sparse.FileIoProcessor); ok {
		opts["refreservation"] = "none"
	}

	var err error
	v.dataset, err = zfs.CreateVolume(p.datasetPath(info), uint64(size), opts)
	if err != nil {
		return nil, err
	}

	// open the zvol device, trying multiple times as the device node is
	// created asynchronously
	var dev *os.File
	err = zvolOpenAttempts.Run(func() (err error) {
		dev, err = os.OpenFile(p.zvolPath(info), os.O_WRONLY, 0666)
		return
	})
	if err != nil {
		p.destroy(v)
		return nil, err
	}
	defer dev.Close()

	if f, ok := fs.Data.(sparse.FileIoProcessor); ok {
		if err := p.copySparse(dev, f); err != nil {
			p.destroy(v)
			return nil, err
		}
	} else {
		n, err := io.Copy(dev, fs.Data)
		if err != nil {
			p.destroy(v)
			return nil, err
		} else if n != fs.Size {
			p.destroy(v)
			return nil, io.ErrShortWrite
		}
	}

	if err = os.MkdirAll(v.basemount, 0755); err != nil {
		p.destroy(v)
		return nil, err
	}

	if err := syscall.Mount(dev.Name(), v.basemount, string(fs.Type), fs.MountFlags, ""); err != nil {
		p.destroy(v)
		return nil, err
	}

	p.volumes[fs.ID] = v
	return v, nil
}