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)) }) }
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 }