Beispiel #1
0
// Mount makes the contents of the volume visible at the given
// mountpoint. If Mount returns with a nil error, the mount has
// occurred.
func (app *App) Mount(volumeName string, mountpoint string) (*MountInfo, error) {
	// TODO obey `bazil -debug server run`

	var vol *fs.Volume
	var volumeID *fs.VolumeID
	var ready = make(chan error, 1)
	app.mounts.Lock()
	err := app.DB.View(func(tx *bolt.Tx) error {
		bucket := tx.Bucket([]byte(tokens.BucketVolName))
		val := bucket.Get([]byte(volumeName))
		if val == nil {
			return errors.New("volume not found")
		}
		var volConf wire.VolumeConfig
		if err := proto.Unmarshal(val, &volConf); err != nil {
			return err
		}
		var err error
		volumeID, err = fs.NewVolumeID(volConf.VolumeID)
		if err != nil {
			return err
		}
		if _, ok := app.mounts.open[*volumeID]; ok {
			return errors.New("volume already mounted")
		}

		kvstore, err := app.openKV(&volConf.Storage)
		if err != nil {
			return err
		}

		chunkStore := kvchunks.New(kvstore)
		vol, err = fs.Open(app.DB, chunkStore, volumeID)
		if err != nil {
			return err
		}
		mnt := &mountState{
			unmounted: make(chan struct{}),
		}
		go func() {
			defer close(mnt.unmounted)
			ready <- app.serveMount(vol, volumeID, mountpoint)
		}()
		app.mounts.open[*volumeID] = mnt
		return nil
	})
	app.mounts.Unlock()
	if err != nil {
		return nil, err
	}
	err = <-ready
	if err != nil {
		return nil, err
	}
	info := &MountInfo{
		VolumeID: *volumeID,
	}
	return info, nil
}
Beispiel #2
0
// caller must hold App.volumes.Mutex
func (app *App) openVolume(tx *db.Tx, id *db.VolumeID) (*fs.Volume, error) {
	v, err := tx.Volumes().GetByVolumeID(id)
	if err != nil {
		return nil, err
	}
	kvstore, err := app.OpenKV(tx, v.Storage())
	if err != nil {
		return nil, err
	}

	chunkStore := kvchunks.New(kvstore)
	vol, err := fs.Open(app.DB, chunkStore, id, (*peer.PublicKey)(app.Keys.Sign.Pub))
	if err != nil {
		return nil, err
	}
	return vol, nil
}