示例#1
0
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;
}
示例#2
0
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;
}
示例#3
0
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;
}
示例#4
0
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;
   }
}