示例#1
0
文件: ioctx.go 项目: kallax/go-ceph-1
// List clients that have locked the named object lock and information about the lock.
// The number of bytes required in each buffer is put in the corresponding size out parameter.
// If any of the provided buffers are too short, -ERANGE is returned after these sizes are filled in.
func (ioctx *IOContext) ListLockers(oid, name string) (*LockInfo, error) {
	c_oid := C.CString(oid)
	c_name := C.CString(name)

	c_tag := (*C.char)(C.malloc(C.size_t(1024)))
	c_clients := (*C.char)(C.malloc(C.size_t(1024)))
	c_cookies := (*C.char)(C.malloc(C.size_t(1024)))
	c_addrs := (*C.char)(C.malloc(C.size_t(1024)))

	var c_exclusive C.int
	c_tag_len := C.size_t(1024)
	c_clients_len := C.size_t(1024)
	c_cookies_len := C.size_t(1024)
	c_addrs_len := C.size_t(1024)

	defer C.free(unsafe.Pointer(c_oid))
	defer C.free(unsafe.Pointer(c_name))
	defer C.free(unsafe.Pointer(c_tag))
	defer C.free(unsafe.Pointer(c_clients))
	defer C.free(unsafe.Pointer(c_cookies))
	defer C.free(unsafe.Pointer(c_addrs))

	ret := C.rados_list_lockers(
		ioctx.ioctx,
		c_oid,
		c_name,
		&c_exclusive,
		c_tag,
		&c_tag_len,
		c_clients,
		&c_clients_len,
		c_cookies,
		&c_cookies_len,
		c_addrs,
		&c_addrs_len)

	splitCString := func(items *C.char, itemsLen C.size_t) []string {
		currLen := 0
		clients := []string{}
		for currLen < int(itemsLen) {
			client := C.GoString(C.nextChunk(&items))
			clients = append(clients, client)
			currLen += len(client) + 1
		}
		return clients
	}

	if ret < 0 {
		return nil, RadosError(int(ret))
	} else {
		return &LockInfo{int(ret), c_exclusive == 1, C.GoString(c_tag), splitCString(c_clients, c_clients_len), splitCString(c_cookies, c_cookies_len), splitCString(c_addrs, c_addrs_len)}, nil
	}
}
示例#2
0
// ListLockers show all the clients that has locks on the object. This also returns the lock tag if any.
func (o *Object) ListLockers(name string) ([]*Locker, string, error) {
	oid := C.CString(o.name)
	defer freeString(oid)

	n := C.CString(name)
	defer freeString(n)

	var exclusive C.int

	bufLen := 2048
	var tagLen C.size_t
	var clientsLen C.size_t
	var cookiesLen C.size_t
	var addrsLen C.size_t

	for {
		cTag := bufferAddress(bufLen)
		cClients := bufferAddress(bufLen)
		cCookies := bufferAddress(bufLen)
		cAddrs := bufferAddress(bufLen)

		ret := C.rados_list_lockers(o.ioContext, oid, n, &exclusive, cTag, &tagLen, cClients, &clientsLen, cCookies, &cookiesLen, cAddrs, &addrsLen)
		if int(ret) == -int(syscall.ERANGE) {
			bufLen *= 2
			continue
		}
		if err := toRadosError(C.int(ret)); err != nil {
			err.Message = fmt.Sprintf("Unable to get lockers for object %s.", o.name)
			return nil, "", err
		}

		tag := C.GoStringN(cTag, C.int(tagLen))

		clients := bufToStringSlice(cClients, C.int(clientsLen))
		cookies := bufToStringSlice(cCookies, C.int(cookiesLen))
		addrs := bufToStringSlice(cAddrs, C.int(addrsLen))

		lockers := make([]*Locker, ret)
		for i := 0; i < int(ret); i++ {
			lockers[i] = &Locker{
				Client:  clients[i],
				Cookies: cookies[i],
				Address: addrs[i],
			}
		}

		return lockers, tag, nil
	}

}