func main() { var err error flag.Parse() if *replicationEnd == 0 { *replicationEnd = *replication } nPeers := *nodes + *delta if *delta <= 0 { nPeers = *nodes } peers = make([]*models.PeerInfo, nPeers) for i := 0; i < nPeers; i++ { u, _ := metadata.MakeOrGetUUID("") peers[i] = &models.PeerInfo{ UUID: u, TotalBlocks: 100 * 1024 * 1024 * 1024, // 100giga-blocks for testing } } blockSize, err = humanize.ParseBytes(*blockSizeStr) if err != nil { fmt.Fprintf(os.Stderr, "error parsing block-size: %s\n", err) os.Exit(1) } totalData, err = humanize.ParseBytes(*totalDataStr) if err != nil { fmt.Fprintf(os.Stderr, "error parsing total-data: %s\n", err) os.Exit(1) } nblocks := totalData / blockSize var blocks []torus.BlockRef inode := torus.INodeID(1) part := float64(*partition) / 100.0 for len(blocks) < int(nblocks) { perFile := rand.Intn(1000) + 1 f := rand.NormFloat64() var out []torus.BlockRef if f < part { out, inode = generateRewrittenFile(torus.VolumeID(1), inode, perFile) } else { out, inode = generateLinearFile(torus.VolumeID(1), inode, perFile) } blocks = append(blocks, out...) } r1, r2 := createRings() fmt.Printf("Unique blocks: %d\n", len(blocks)) cluster := assignData(blocks, r1) fmt.Println("@START *****") cluster.printBalance() newc, rebalance := cluster.Rebalance(r1, r2) fmt.Println("@END *****") newc.printBalance() fmt.Println("Changes:") rebalance.printStats() }
func (b *blockEtcd) CreateBlockVolume(volume *models.Volume) error { new, err := b.AtomicModifyKey([]byte(etcd.MkKey("meta", "volumeminter")), etcd.BytesAddOne) volume.Id = new.(uint64) if err != nil { return err } vbytes, err := volume.Marshal() if err != nil { return err } inodeBytes := torus.NewINodeRef(torus.VolumeID(volume.Id), 1).ToBytes() do := b.Etcd.Client.Txn(b.getContext()).If( etcdv3.Compare(etcdv3.Version(etcd.MkKey("volumes", volume.Name)), "=", 0), ).Then( etcdv3.OpPut(etcd.MkKey("volumes", volume.Name), string(etcd.Uint64ToBytes(volume.Id))), etcdv3.OpPut(etcd.MkKey("volumeid", etcd.Uint64ToHex(volume.Id)), string(vbytes)), etcdv3.OpPut(etcd.MkKey("volumemeta", etcd.Uint64ToHex(volume.Id), "inode"), string(etcd.Uint64ToBytes(1))), etcdv3.OpPut(etcd.MkKey("volumemeta", etcd.Uint64ToHex(volume.Id), "blockinode"), string(inodeBytes)), ) resp, err := do.Commit() if err != nil { return err } if !resp.Succeeded { return torus.ErrExists } return nil }
func (s *BlockVolume) getOrCreateBlockINode(ref torus.INodeRef) (*models.INode, error) { if ref.Volume() != torus.VolumeID(s.volume.Id) { panic("ids managed by metadata didn't match, how is that possible?") } if ref.INode != 1 { return s.srv.INodes.GetINode(s.getContext(), ref) } globals, err := s.mds.GlobalMetadata() if err != nil { } bs, err := blockset.CreateBlocksetFromSpec(globals.DefaultBlockSpec, nil) if err != nil { return nil, err } nBlocks := (s.volume.MaxBytes / globals.BlockSize) if s.volume.MaxBytes%globals.BlockSize != 0 { nBlocks++ } err = bs.Truncate(int(nBlocks), globals.BlockSize) if err != nil { return nil, err } inode := models.NewEmptyINode() inode.INode = 1 inode.Volume = s.volume.Id inode.Filesize = s.volume.MaxBytes inode.Blocks, err = torus.MarshalBlocksetToProto(bs) return inode, err }
func (c *etcdCtx) NewVolumeID() (torus.VolumeID, error) { c.etcd.mut.Lock() defer c.etcd.mut.Unlock() k := []byte(MkKey("meta", "volumeminter")) newID, err := c.AtomicModifyKey(k, BytesAddOne) if err != nil { return 0, err } return torus.VolumeID(newID.(uint64)), nil }
func DeleteBlockVolume(mds torus.MetadataService, volume string) error { vol, err := mds.GetVolume(volume) if err != nil { return err } bmds, err := createBlockMetadata(mds, vol.Name, torus.VolumeID(vol.Id)) if err != nil { return err } return bmds.DeleteVolume() }
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 (b *blockTempMetadata) CreateBlockVolume(volume *models.Volume) error { b.LockData() defer b.UnlockData() _, ok := b.GetData(fmt.Sprint(volume.Id)) if ok { return torus.ErrExists } b.CreateVolume(volume) b.SetData(fmt.Sprint(volume.Id), &blockTempVolumeData{ locked: "", id: torus.NewINodeRef(torus.VolumeID(volume.Id), 1), }) return nil }
func OpenBlockVolume(s *torus.Server, volume string) (*BlockVolume, error) { vol, err := s.MDS.GetVolume(volume) if err != nil { return nil, err } mds, err := createBlockMetadata(s.MDS, vol.Name, torus.VolumeID(vol.Id)) if err != nil { return nil, err } return &BlockVolume{ srv: s, mds: mds, volume: vol, }, nil }
func (c *etcdCtx) GetVolumes() ([]*models.Volume, torus.VolumeID, error) { promOps.WithLabelValues("get-volumes").Inc() txn := c.etcd.Client.Txn(c.getContext()).Then( etcdv3.OpGet(MkKey("meta", "volumeminter")), etcdv3.OpGet(MkKey("volumeid"), etcdv3.WithPrefix()), ) resp, err := txn.Commit() if err != nil { return nil, 0, err } highwater := BytesToUint64(resp.Responses[0].GetResponseRange().Kvs[0].Value) list := resp.Responses[1].GetResponseRange().Kvs var out []*models.Volume for _, x := range list { v := &models.Volume{} err := v.Unmarshal(x.Value) if err != nil { return nil, 0, err } out = append(out, v) } return out, torus.VolumeID(highwater), nil }
func (t *Client) CreateVolume(volume *models.Volume) error { t.srv.volIndex[volume.Name] = volume t.srv.inode[torus.VolumeID(volume.Id)] = 1 return nil }