Bool VMCIDs_Init(void) { static VMCIResourcePrivilegeType priv[] = { VMCI_PRIV_DG_SEND }; int result; /* Initialize internal datastructure */ if (!DsListInit(&dsAPI.registry, 10)) { VMCILOG((LGPFX"registry initialization failed.\n")); return FALSE; } /* Setup server handle */ if (VMCIDatagramCreateHndPriv(VMCI_DS_RESOURCE_ID, VMCI_FLAG_WELLKNOWN_DG_HND, VMCI_PRIVILEGE_FLAG_TRUSTED, DsRequestCb, NULL, &dsAPI.handle) < VMCI_SUCCESS) { VMCILOG((LGPFX"make handle failed.\n")); return FALSE; } if (!VMCI_HANDLE_EQUAL(dsAPI.handle, VMCI_DS_HANDLE)) { VMCILOG((LGPFX"handle inconsistency.\n")); return FALSE; } /* * Create a vmcids group.By adding this group as a client to the * datagramAPIResource with the VMCI_PRIV_DG_CREATE we can give contexts access * to the vmcids by making them members of this group. */ dsAPI.groupHandle = VMCIGroup_Create(); if (VMCI_HANDLE_EQUAL(dsAPI.groupHandle, VMCI_INVALID_HANDLE)) { VMCILOG((LGPFX"Failed creating Datagram API group.\n")); VMCIDatagramDestroyHndInt(dsAPI.handle); return FALSE; } /* Add group as client of vmcids API with the right privilege. */ result = VMCIResource_AddClientPrivileges(dsAPI.handle, dsAPI.groupHandle, 1, priv, 0, NULL); if (result != VMCI_SUCCESS) { VMCILOG((LGPFX"Failed to setup privileges: %d.\n", result)); VMCIGroup_Destroy(dsAPI.groupHandle); VMCIDatagramDestroyHndInt(dsAPI.handle); return FALSE; } VMCI_InitLock(&lock, "VMCIDsLock", VMCI_LOCK_RANK_MIDDLE); dsAPI.isInitialized = TRUE; return TRUE; }
static int DsListRemoveResource(DsList *list, // IN: VMCIResource *resource) // IN: { VMCIHandle handle; int i, registrationCount; int count = 0; if (!list || !resource) { return VMCI_ERROR_INVALID_ARGS; } handle = resource->handle; if (VMCI_HANDLE_EQUAL(handle, VMCI_INVALID_HANDLE)) { return VMCI_ERROR_NO_HANDLE; } registrationCount = resource->registrationCount; if (!registrationCount) { VMCILOG((LGPFX"%s called with registrationCount = 0.\n", __FUNCTION__)); } for (i = 0; i < list->size;) { if (VMCI_HANDLE_EQUAL(list->elements[i].handle, handle)) { int removeElement = DsListRemoveElement(list, i); if (removeElement != VMCI_SUCCESS) { VMCILOG((LGPFX"Error: %s returned %d.\n", __FUNCTION__, removeElement)); break; } count++; VMCIResource_DecDsRegCount(resource); } else { /* Move to the next element. */ i++; } } if (count != registrationCount) { VMCILOG((LGPFX"Error: %s: no. of removed registrations " "= %d, should be %d.\n", __FUNCTION__, count, registrationCount)); } return count; }
static int DsListInsert(DsList *list, // IN: const char *name, // IN: VMCIHandle handle, // IN: VMCIId contextID) // IN: { int nameLen; char *nameMem; if (!list || !name || VMCI_HANDLE_EQUAL(handle, VMCI_INVALID_HANDLE) || contextID == VMCI_INVALID_ID) { return VMCI_ERROR_INVALID_ARGS; } /* Check for duplicates */ if (DsListLookupIndex(list, name) >= 0) { return VMCI_ERROR_ALREADY_EXISTS; } if (list->capacity == list->size) { /* We need to expand the list */ int newCapacity = list->capacity * 2; DsListElement *elms = VMCI_AllocKernelMem(sizeof(DsListElement) * newCapacity, VMCI_MEMORY_NONPAGED | VMCI_MEMORY_ATOMIC); if (elms == NULL) { return VMCI_ERROR_NO_MEM; } memcpy(elms, list->elements, sizeof(DsListElement) * list->capacity); VMCI_FreeKernelMem(list->elements, sizeof *list->elements * list->capacity); list->elements = elms; list->capacity = newCapacity; } ASSERT(list->capacity > list->size); nameLen = strlen(name) + 1; nameMem = VMCI_AllocKernelMem(nameLen, VMCI_MEMORY_NONPAGED | VMCI_MEMORY_ATOMIC); if (nameMem == NULL) { return VMCI_ERROR_NO_MEM; } memcpy(nameMem, name, nameLen); list->elements[list->size].name = nameMem; list->elements[list->size].handle = handle; list->elements[list->size].contextID = contextID; list->size = list->size + 1; return VMCI_SUCCESS; }
int VMCIDs_Unregister(const char *name, // IN: VMCIId contextID) // IN: { int errcode; VMCILockFlags flags; VMCIHandle handle = VMCI_INVALID_HANDLE; VMCI_GrabLock(&lock, &flags); errcode = DsListRemove(dsAPI.registry, name, &handle, contextID); VMCI_ReleaseLock(&lock, flags); if (errcode == VMCI_SUCCESS) { VMCIResource *resource; ASSERT(!VMCI_HANDLE_EQUAL(handle, VMCI_INVALID_HANDLE)); resource = VMCIResource_Get(handle, VMCI_RESOURCE_TYPE_ANY); if (resource) { VMCIResource_DecDsRegCount(resource); VMCIResource_Release(resource); } } return errcode; }
static void VPageChannelPeerDetachCB(VMCIId subId, // IN VMCI_EventData *eData, // IN void *clientData) // IN { VPageChannel *channel; VMCIEventPayload_QP *ePayload; ASSERT(eData); ASSERT(clientData); channel = (VPageChannel *)clientData; ePayload = VMCIEventDataPayload(eData); if (VMCI_HANDLE_EQUAL(channel->qpHandle, ePayload->handle)) { VMCI_DEBUG_LOG(10, (LGPFX"Peer detached (channel=%p) " "(qp handle=0x%x:0x%x).\n", channel, ePayload->handle.context, ePayload->handle.resource)); channel->state = VPCState_Disconnected; } }