func (s *BlockVolume) RestoreSnapshot(name string) (err error) { if s.volume.Type != VolumeType { panic("Wrong type") } if err = s.mds.Lock(s.srv.Lease()); err != nil { return err } defer s.mds.Unlock() snaps, err := s.mds.GetSnapshots() if err != nil { return err } var found Snapshot for _, x := range snaps { if x.Name == name { found = x break } } if found.Name != name { return torus.ErrNotExist } ref := torus.INodeRefFromBytes(found.INodeRef) return s.mds.SyncINode(ref) }
func (b *blockEtcd) GetINode() (torus.INodeRef, error) { resp, err := b.Etcd.Client.Get(b.getContext(), etcd.MkKey("volumemeta", etcd.Uint64ToHex(uint64(b.vid)), "blockinode")) if err != nil { return torus.NewINodeRef(0, 0), err } if len(resp.Kvs) != 1 { return torus.NewINodeRef(0, 0), errors.New("unexpected metadata for volume") } return torus.INodeRefFromBytes(resp.Kvs[0].Value), nil }
func (b *blockvolGC) PrepVolume(vol *models.Volume) error { if vol.Type != VolumeType { return nil } mds, err := createBlockMetadata(b.srv.MDS, vol.Name, torus.VolumeID(vol.Id)) if err != nil { return err } curRef, err := mds.GetINode() if err != nil { return err } b.highwaters[curRef.Volume()] = 0 if curRef.INode <= 1 { return nil } snaps, err := mds.GetSnapshots() if err != nil { return err } curINodes := make([]torus.INodeRef, 0, len(snaps)+1) curINodes = append(curINodes, curRef) for _, x := range snaps { curINodes = append(curINodes, torus.INodeRefFromBytes(x.INodeRef)) } for _, x := range curINodes { inode, err := b.inodes.GetINode(b.getContext(), x) if err != nil { return err } set, err := blockset.UnmarshalFromProto(inode.Blocks, nil) if err != nil { return err } refs := set.GetAllBlockRefs() for _, ref := range refs { if ref.IsZero() { continue } if ref.INode > b.highwaters[ref.Volume()] { b.highwaters[ref.Volume()] = ref.INode } b.set[ref] = true } } b.curINodes = append(b.curINodes, curINodes...) return nil }
func (s *BlockVolume) OpenSnapshot(name string) (*BlockFile, error) { if s.volume.Type != VolumeType { panic("wrong type") } snaps, err := s.mds.GetSnapshots() if err != nil { return nil, err } var found Snapshot for _, x := range snaps { if x.Name == name { found = x break } } if found.Name != name { return nil, torus.ErrNotExist } ref := torus.INodeRefFromBytes(found.INodeRef) inode, err := s.getOrCreateBlockINode(ref) if err != nil { return nil, err } bs, err := blockset.UnmarshalFromProto(inode.GetBlocks(), s.srv.Blocks) if err != nil { return nil, err } f, err := s.srv.CreateFile(s.volume, inode, bs) if err != nil { return nil, err } f.ReadOnly = true return &BlockFile{ File: f, vol: s, }, nil }