Exemplo n.º 1
0
// Lock a segment, or block until a segment can be locked
// Returns a Segment struct
// Implicit unchecked assumption: you cannot lock more than one segment
// for a given uuid (without unlocking them in between). It will break
// segcache
func (sp *CephStorageProvider) LockSegment(uuid []byte) bprovider.Segment {
	rv := new(CephSegment)
	rv.sp = sp
	h, err := C.handle_create()
	if err != nil {
		log.Panic("CGO ERROR: %v", err)
	}
	rv.h = h
	rv.ptr = <-sp.alloc
	rv.uid = UUIDSliceToArr(uuid)
	rv.wcache = make([]byte, 0, WCACHE_SIZE)
	sp.segcachelock.Lock()
	cached_ptr, ok := sp.segaddrcache[rv.uid]
	if ok {
		delete(sp.segaddrcache, rv.uid)
	}
	sp.segcachelock.Unlock()
	//ok = false
	if ok {
		rv.base = cached_ptr
		rv.naddr = rv.base
	} else {
		rv.base = rv.ptr
		rv.naddr = rv.base
	}
	rv.wcache_base = rv.naddr
	//Although I don't know this for sure, I am concerned that when we pass the write array pointer to C
	//the Go GC may free it before C is done. I prevent this by pinning all the written arrays, which get
	//deref'd after the segment is unlocked
	rv.warrs = make([][]byte, 0, 64)
	return rv
}
Exemplo n.º 2
0
func (sp *CephStorageProvider) obtainBaseAddress() uint64 {
	h, err := C.handle_create()
	if err != nil {
		log.Panic("CGO ERROR: %v", err)
	}
	addr, err := C.handle_obtainrange(h)
	if err != nil {
		log.Panic("CGO ERROR: %v", err)
	}
	return uint64(addr)
}
Exemplo n.º 3
0
//Called at startup of a normal run
func (sp *CephStorageProvider) Initialize(opts map[string]string) {
	//Allocate caches
	sp.rcache = &CephCache{}
	cachesz, _ := strconv.Atoi(opts["cephrcache"])
	if cachesz < 40 {
		cachesz = 40 //one per read handle: 40MB
	}
	sp.rcache.initCache(uint64(cachesz))

	cephconf := C.CString(opts["cephconf"])
	cephpool := C.CString(opts["cephpool"])
	_, err := C.initialize_provider(cephconf, cephpool)
	if err != nil {
		log.Panic("CGO ERROR: %v", err)
	}
	C.free(unsafe.Pointer(cephconf))
	C.free(unsafe.Pointer(cephpool))

	sp.rh = make([]C.phandle_t, NUM_RHANDLES)
	sp.rh_avail = make([]bool, NUM_RHANDLES)
	sp.rhidx = make(chan int, NUM_RHANDLES+1)
	sp.rhidx_ret = make(chan int, NUM_RHANDLES+1)
	sp.alloc = make(chan uint64, 128)
	sp.segaddrcache = make(map[[16]byte]uint64, SEGCACHE_SIZE)
	sp.chunkgate = make(map[chunkreqindex][]chan []byte)

	for i := 0; i < NUM_RHANDLES; i++ {
		sp.rh_avail[i] = true
		h, err := C.handle_create()
		if err != nil {
			log.Panic("CGO ERROR: %v", err)
		}
		sp.rh[i] = h
	}

	//Obtain base address
	sp.ptr = sp.obtainBaseAddress()
	if sp.ptr == 0 {
		log.Panic("Could not read allocator! DB not created properly?")
	}
	log.Info("Base address obtained as 0x%016x", sp.ptr)

	//Start serving read handles
	go sp.provideReadHandles()

	//Start providing address allocations
	go sp.provideAllocs()

}
Exemplo n.º 4
0
//Called to create the database for the first time
func (sp *CephStorageProvider) CreateDatabase(opts map[string]string) error {
	cephconf := C.CString(opts["cephconf"])
	cephpool := C.CString(opts["cephpool"])
	_, err := C.initialize_provider(cephconf, cephpool)
	if err != nil {
		log.Panic("CGO ERROR: %v", err)
	}
	C.free(unsafe.Pointer(cephconf))
	C.free(unsafe.Pointer(cephpool))
	h, err := C.handle_create()
	if err != nil {
		log.Panic("CGO ERROR: %v", err)
	}
	C.handle_init_allocator(h)
	_, err = C.handle_close(h)
	if err != nil {
		log.Panic("CGO ERROR: %v", err)
	}
	return nil
}