Exemplo n.º 1
0
func newFS(chunkStore chunks.Store, dir *wire.Dir) (*FS, error) {
	root, err := snap.Open(chunkStore, dir)
	if err != nil {
		return nil, err
	}
	return &FS{root: root}, nil
}
Exemplo n.º 2
0
// Mkdir takes a snapshot of this volume and records it under the
// given name.
func (d *listSnaps) Mkdir(req *fuse.MkdirRequest, intr fs.Intr) (fs.Node, fuse.Error) {
	// TODO this lock is too much
	d.fs.mu.Lock()
	defer d.fs.mu.Unlock()

	var snapshot = wiresnap.Snapshot{
		Name: req.Name,
	}
	err := d.fs.db.View(func(tx *bolt.Tx) error {
		return d.rootDir.snapshot(tx, &snapshot.Contents, intr)
	})
	if err != nil {
		return nil, fmt.Errorf("cannot record snapshot: %v", err)
	}

	var key cas.Key
	{
		buf, err := proto.Marshal(&snapshot)
		if err != nil {
			return nil, fmt.Errorf("cannot marshal snapshot: %v", err)
		}
		if len(buf) == 0 {
			return nil, errors.New("marshaled snapshot become empty; this is a bug!")
		}

		// store the snapshot as a chunk, for disaster recovery
		key, err = d.fs.chunkStore.Add(&chunks.Chunk{
			Type:  "snap",
			Level: 0,
			Buf:   buf,
		})
		if err != nil {
			return nil, fmt.Errorf("cannot store snapshot: %v", err)
		}
	}

	var ref = wire.SnapshotRef{
		Key: key,
	}
	buf, err := proto.Marshal(&ref)
	if err != nil {
		return nil, fmt.Errorf("cannot marshal snapshot pointer: %v", err)
	}

	err = d.fs.db.Update(func(tx *bolt.Tx) error {
		b := d.fs.bucket(tx).Bucket(bucketSnap)
		if b == nil {
			return errors.New("snapshot bucket missing")
		}
		return b.Put([]byte(req.Name), buf)
	})

	n, err := snap.Open(d.fs.chunkStore, &snapshot.Contents)
	if err != nil {
		return nil, fmt.Errorf("cannot serve snapshot: %v", err)
	}
	return n, nil
}
Exemplo n.º 3
0
func (d *listSnaps) Lookup(ctx context.Context, name string) (fs.Node, error) {
	var ref wire.SnapshotRef
	lookup := func(tx *db.Tx) error {
		bucket := d.fs.bucket(tx).SnapBucket()
		if bucket == nil {
			return errors.New("snapshot bucket missing")
		}
		buf := bucket.Get([]byte(name))
		if buf == nil {
			return fuse.ENOENT
		}
		if err := proto.Unmarshal(buf, &ref); err != nil {
			return fmt.Errorf("corrupt snapshot reference: %q: %v", name, err)
		}
		return nil
	}
	if err := d.fs.db.View(lookup); err != nil {
		return nil, err
	}

	var k cas.Key
	if err := k.UnmarshalBinary(ref.Key); err != nil {
		return nil, fmt.Errorf("corrupt snapshot reference: %q: %v", name, err)
	}

	chunk, err := d.fs.chunkStore.Get(k, "snap", 0)
	if err != nil {
		return nil, fmt.Errorf("cannot fetch snapshot: %v", err)
	}

	var snapshot wiresnap.Snapshot
	err = proto.Unmarshal(chunk.Buf, &snapshot)
	if err != nil {
		return nil, fmt.Errorf("corrupt snapshot: %v: %v", ref.Key, err)
	}

	n, err := snap.Open(d.fs.chunkStore, snapshot.Contents)
	if err != nil {
		return nil, fmt.Errorf("cannot serve snapshot: %v", err)
	}
	return n, nil
}
Exemplo n.º 4
0
func (d *listSnaps) Lookup(name string, intr fs.Intr) (fs.Node, fuse.Error) {
	var buf []byte
	err := d.fs.db.View(func(tx *bolt.Tx) error {
		bucket := d.fs.bucket(tx).Bucket(bucketSnap)
		if bucket == nil {
			return errors.New("snapshot bucket missing")
		}
		buf := bucket.Get([]byte(name))
		if buf == nil {
			return fuse.ENOENT
		}
		return nil
	})
	if err != nil {
		return nil, err
	}
	var ref wire.SnapshotRef
	err = proto.Unmarshal(buf, &ref)
	if err != nil {
		return nil, fmt.Errorf("corrupt snapshot reference: %q: %v", name, err)
	}

	chunk, err := d.fs.chunkStore.Get(ref.Key, "snap", 0)
	if err != nil {
		return nil, fmt.Errorf("cannot fetch snapshot: %v", err)
	}

	var snapshot wiresnap.Snapshot
	err = proto.Unmarshal(chunk.Buf, &snapshot)
	if err != nil {
		return nil, fmt.Errorf("corrupt snapshot: %v: %v", ref.Key, err)
	}

	n, err := snap.Open(d.fs.chunkStore, &snapshot.Contents)
	if err != nil {
		return nil, fmt.Errorf("cannot serve snapshot: %v", err)
	}
	return n, nil
}
Exemplo n.º 5
0
// Mkdir takes a snapshot of this volume and records it under the
// given name.
func (d *listSnaps) Mkdir(ctx context.Context, req *fuse.MkdirRequest) (fs.Node, error) {
	var snapshot *wiresnap.Snapshot
	record := func(tx *db.Tx) error {
		s, err := d.fs.Snapshot(ctx, tx)
		if err != nil {
			return err
		}
		snapshot = s
		return nil
	}
	if err := d.fs.db.View(record); err != nil {
		return nil, fmt.Errorf("cannot record snapshot: %v", err)
	}

	snapshot.Name = req.Name

	var key cas.Key
	{
		buf, err := proto.Marshal(snapshot)
		if err != nil {
			return nil, fmt.Errorf("cannot marshal snapshot: %v", err)
		}
		if len(buf) == 0 {
			return nil, errors.New("marshaled snapshot become empty; this is a bug")
		}

		// store the snapshot as a chunk, for disaster recovery
		key, err = d.fs.chunkStore.Add(&chunks.Chunk{
			Type:  "snap",
			Level: 0,
			Buf:   buf,
		})
		if err != nil {
			return nil, fmt.Errorf("cannot store snapshot: %v", err)
		}
	}

	var ref = wire.SnapshotRef{
		Key: key.Bytes(),
	}
	buf, err := proto.Marshal(&ref)
	if err != nil {
		return nil, fmt.Errorf("cannot marshal snapshot pointer: %v", err)
	}

	add := func(tx *db.Tx) error {
		b := d.fs.bucket(tx).SnapBucket()
		if b == nil {
			return errors.New("snapshot bucket missing")
		}
		return b.Put([]byte(req.Name), buf)
	}
	if err := d.fs.db.Update(add); err != nil {
		return nil, fmt.Errorf("cannot save snapshot pointer: %v", err)
	}

	n, err := snap.Open(d.fs.chunkStore, snapshot.Contents)
	if err != nil {
		return nil, fmt.Errorf("cannot serve snapshot: %v", err)
	}
	return n, nil
}