예제 #1
0
파일: kvchunks.go 프로젝트: jgluck/bazil
func makeKey(key cas.Key, typ string, level uint8) []byte {
	k := make([]byte, 0, cas.KeySize+len(typ)+1)
	k = append(k, key.Bytes()...)
	k = append(k, typ...)
	k = append(k, level)
	return k
}
예제 #2
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
}