func Init(params volume.DriverParams) (volume.VolumeDriver, error) { inst := &driver{ IoNotSupported: &volume.IoNotSupported{}, DefaultEnumerator: volume.NewDefaultEnumerator(Name, kvdb.Instance()), } inst.buseDevices = make(map[string]*buseDev) if err := os.MkdirAll(BuseMountPath, 0744); err != nil { return nil, err } volumeInfo, err := inst.DefaultEnumerator.Enumerate( &api.VolumeLocator{}, nil, ) if err == nil { for _, info := range volumeInfo { if info.Status == api.VolumeStatus_VOLUME_STATUS_NONE { info.Status = api.VolumeStatus_VOLUME_STATUS_UP inst.UpdateVol(info) } } } else { dlog.Println("Could not enumerate Volumes, ", err) } c, err := cluster.Inst() if err != nil { dlog.Println("BUSE initializing in single node mode") } else { dlog.Println("BUSE initializing in clustered mode") c.AddEventListener(inst) } dlog.Println("BUSE initialized and driver mounted at: ", BuseMountPath) return inst, nil }
func (d *driver) Delete(volumeID string) error { v, err := d.GetVol(volumeID) if err != nil { dlog.Println(err) return err } bd, ok := d.buseDevices[v.DevicePath] if !ok { err = fmt.Errorf("Cannot locate a BUSE device for %s", v.DevicePath) dlog.Println(err) return err } // Clean up buse block file and close the NBD connection. os.Remove(bd.file) bd.f.Close() bd.nbd.Disconnect() dlog.Infof("BUSE deleted volume %v at NBD device %s", volumeID, v.DevicePath) if err := d.DeleteVol(volumeID); err != nil { dlog.Println(err) return err } return nil }
func (d *driver) Create( locator *api.VolumeLocator, source *api.Source, spec *api.VolumeSpec) (string, error) { volumeID := uuid.New() volumeID = strings.TrimSuffix(volumeID, "\n") // Create a directory on the NFS server with this UUID. volPath := path.Join(nfsMountPath, volumeID) err := os.MkdirAll(volPath, 0744) if err != nil { dlog.Println(err) return "", err } if source != nil { if len(source.Seed) != 0 { seed, err := seed.New(source.Seed, spec.VolumeLabels) if err != nil { dlog.Warnf("Failed to initailize seed from %q : %v", source.Seed, err) return "", err } err = seed.Load(path.Join(volPath, config.DataDir)) if err != nil { dlog.Warnf("Failed to seed from %q to %q: %v", source.Seed, nfsMountPath, err) return "", err } } } f, err := os.Create(path.Join(nfsMountPath, volumeID+nfsBlockFile)) if err != nil { dlog.Println(err) return "", err } defer f.Close() if err := f.Truncate(int64(spec.Size)); err != nil { dlog.Println(err) return "", err } v := common.NewVolume( volumeID, api.FSType_FS_TYPE_NFS, locator, source, spec, ) v.DevicePath = path.Join(nfsMountPath, volumeID+nfsBlockFile) if err := d.CreateVol(v); err != nil { return "", err } return v.Id, err }
func (d *driver) Delete(volumeID string) error { v, err := d.GetVol(volumeID) if err != nil { dlog.Println(err) return err } // Delete the simulated block volume os.Remove(v.DevicePath) // Delete the directory on the nfs server. os.RemoveAll(path.Join(nfsMountPath, volumeID)) err = d.DeleteVol(volumeID) if err != nil { dlog.Println(err) return err } return nil }
func (d *driver) Delete(volumeID string) error { // Check if volume exists _, err := d.GetVol(volumeID) if err != nil { dlog.Println("Volume not found ", err) return err } // Delete the directory os.RemoveAll(filepath.Join(config.VolumeBase, string(volumeID))) err = d.DeleteVol(volumeID) if err != nil { dlog.Println(err) return err } return nil }
// Mount volume at specified path // Errors ErrEnoEnt, ErrVolDetached may be returned. func (d *driver) Mount(volumeID string, mountpath string) error { v, err := d.GetVol(volumeID) if err != nil { dlog.Println(err) return err } syscall.Unmount(mountpath, 0) if err := syscall.Mount(filepath.Join(config.VolumeBase, string(volumeID)), mountpath, string(v.Spec.Format), syscall.MS_BIND, ""); err != nil { dlog.Printf("Cannot mount %s at %s because %+v", filepath.Join(config.VolumeBase, string(volumeID)), mountpath, err) return err } v.AttachPath = mountpath // TODO(pedge): why ignoring error? err = d.UpdateVol(v) return nil }
func (d *driver) Mount(volumeID string, mountpath string) error { v, err := d.GetVol(volumeID) if err != nil { dlog.Println(err) return err } srcPath := path.Join(":", d.nfsPath, volumeID) mountExists, err := d.mounter.Exists(srcPath, mountpath) if !mountExists { d.mounter.Unmount(path.Join(nfsMountPath, volumeID), mountpath) if err := d.mounter.Mount(0, path.Join(nfsMountPath, volumeID), mountpath, string(v.Spec.Format), syscall.MS_BIND, ""); err != nil { dlog.Printf("Cannot mount %s at %s because %+v", path.Join(nfsMountPath, volumeID), mountpath, err) return err } } v.AttachPath = mountpath return d.UpdateVol(v) }
func (d *driver) Create(locator *api.VolumeLocator, source *api.Source, spec *api.VolumeSpec) (string, error) { volumeID := uuid.New() volumeID = strings.TrimSuffix(volumeID, "\n") // Create a directory on the Local machine with this UUID. if err := os.MkdirAll(filepath.Join(config.VolumeBase, string(volumeID)), 0744); err != nil { dlog.Println(err) return "", err } v := common.NewVolume( volumeID, api.FSType_FS_TYPE_VFS, locator, source, spec, ) v.DevicePath = filepath.Join(config.VolumeBase, volumeID) if err := d.CreateVol(v); err != nil { return "", err } return v.Id, d.UpdateVol(v) }
func (d *driver) Create(locator *api.VolumeLocator, source *api.Source, spec *api.VolumeSpec) (string, error) { volumeID := uuid.New() volumeID = strings.TrimSuffix(volumeID, "\n") if spec.Size == 0 { return "", fmt.Errorf("Volume size cannot be zero", "buse") } if spec.Format == api.FSType_FS_TYPE_NONE { return "", fmt.Errorf("Missing volume format", "buse") } // Create a file on the local buse path with this UUID. buseFile := path.Join(BuseMountPath, volumeID) f, err := os.Create(buseFile) if err != nil { dlog.Println(err) return "", err } if err := f.Truncate(int64(spec.Size)); err != nil { dlog.Println(err) return "", err } bd := &buseDev{ file: buseFile, f: f, } nbd := Create(bd, int64(spec.Size)) bd.nbd = nbd dlog.Infof("Connecting to NBD...") dev, err := bd.nbd.Connect() if err != nil { dlog.Println(err) return "", err } dlog.Infof("Formatting %s with %v", dev, spec.Format) cmd := "/sbin/mkfs." + spec.Format.SimpleString() o, err := exec.Command(cmd, dev).Output() if err != nil { dlog.Warnf("Failed to run command %v %v: %v", cmd, dev, o) return "", err } dlog.Infof("BUSE mapped NBD device %s (size=%v) to block file %s", dev, spec.Size, buseFile) v := common.NewVolume( volumeID, spec.Format, locator, source, spec, ) v.DevicePath = dev d.buseDevices[dev] = bd err = d.CreateVol(v) if err != nil { return "", err } return v.Id, err }
func Init(params volume.DriverParams) (volume.VolumeDriver, error) { path, ok := params["path"] if !ok { return nil, errors.New("No NFS path provided") } server, ok := params["server"] if !ok { dlog.Printf("No NFS server provided, will attempt to bind mount %s", path) } else { dlog.Printf("NFS driver initializing with %s:%s ", server, path) } // Create a mount manager for this NFS server. Blank sever is OK. mounter, err := mount.New(mount.NFSMount, server) if err != nil { dlog.Warnf("Failed to create mount manager for server: %v (%v)", server, err) return nil, err } inst := &driver{ IoNotSupported: &volume.IoNotSupported{}, DefaultEnumerator: volume.NewDefaultEnumerator(Name, kvdb.Instance()), nfsServer: server, nfsPath: path, mounter: mounter, } if err := os.MkdirAll(nfsMountPath, 0744); err != nil { return nil, err } src := inst.nfsPath if server != "" { src = ":" + inst.nfsPath } // If src is already mounted at dest, leave it be. mountExists, err := mounter.Exists(src, nfsMountPath) if !mountExists { // Mount the nfs server locally on a unique path. syscall.Unmount(nfsMountPath, 0) if server != "" { err = syscall.Mount(src, nfsMountPath, "nfs", 0, "nolock,addr="+inst.nfsServer) } else { err = syscall.Mount(src, nfsMountPath, "", syscall.MS_BIND, "") } if err != nil { dlog.Printf("Unable to mount %s:%s at %s (%+v)", inst.nfsServer, inst.nfsPath, nfsMountPath, err) return nil, err } } volumeInfo, err := inst.DefaultEnumerator.Enumerate(&api.VolumeLocator{}, nil) if err == nil { for _, info := range volumeInfo { if info.Status == api.VolumeStatus_VOLUME_STATUS_NONE { info.Status = api.VolumeStatus_VOLUME_STATUS_UP inst.UpdateVol(info) } } } else { dlog.Println("Could not enumerate Volumes, ", err) } dlog.Println("NFS initialized and driver mounted at: ", nfsMountPath) return inst, nil }