/* Free a given structure. Ptr must be NOT NULL *only* if type is not THR, TSK or SMO. */ void sfree(void *ptr, int id, int type) { if(type == SALLOC_TSK || type == SALLOC_THR || type == SALLOC_SMO) { switch(type) { case SALLOC_TSK: if(!TST_PTR(id,tsk)) return; // not allocated csfree(GET_PTR(id,tsk), SALLOC2CONT_TYPE(type)); break; case SALLOC_THR: if(!TST_PTR(id,thr)) return; csfree(GET_PTR(id,thr), SALLOC2CONT_TYPE(type)); break; case SALLOC_SMO: if(!TST_PTR(id,smo)) return; csfree(GET_PTR(id,smo), SALLOC2CONT_TYPE(type)); break; default: break; } index_free(id, ALLOC2IDX(type)); } else { csfree(ptr, SALLOC2CONT_TYPE(type)); } ammount[type]--; }
struct srv_client* srv_ctable_connect_direct_handler(srv_common_t *srv, srv_msg_t *m, seL4_CPtr liveness, int* _errno) { assert(srv && srv->magic == SRV_MAGIC && m); /* Check that the liveness cap passed in correctly. */ if(!srv_check_dispatch_caps(m, 0x00000000, 1)) { SET_ERRNO_PTR(_errno, EINVALIDPARAM); return NULL; } int error = ENOMEM; /* Copyout the liveness cap, create session cap cslot. Do not printf before the copyout. */ seL4_CPtr livenessCP = rpc_copyout_cptr(liveness); if (!liveness || !livenessCP) { goto error0; } /* Allocate the client structure. */ struct srv_client *c = client_alloc(&srv->clientTable, livenessCP); if (!c) { goto error1; } dprintf("Adding new %s client cID = %d. Hi! (:D)\n", srv->config.serverName, c->cID); assert(c->session); /* Authenticate the client to the process server, using its liveness cap. */ error = proc_watch_client(c->liveness, srv->notifyClientFaultDeathAsyncEP, &c->deathID); if (error != ESUCCESS) { goto error2; } SET_ERRNO_PTR(_errno, ESUCCESS); return c; /* Exit stack. */ error2: client_queue_delete(&srv->clientTable, c->cID); client_table_postaction(&srv->clientTable); error1: seL4_CNode_Delete(REFOS_CSPACE, livenessCP, REFOS_CDEPTH); csfree(livenessCP); error0: SET_ERRNO_PTR(_errno, error); return NULL; }
seL4_CPtr srv_mint(int badge, seL4_CPtr ep) { assert(ep); seL4_CPtr mintEP = csalloc(); if (!mintEP) { ROS_ERROR("Could not allocate cslot to mint badge."); return 0; } int error = seL4_CNode_Mint ( REFOS_CSPACE, mintEP, REFOS_CDEPTH, REFOS_CSPACE, ep, REFOS_CDEPTH, seL4_NoRead, seL4_CapData_Badge_new(badge) ); if (error != seL4_NoError) { ROS_ERROR("Could not mint badge."); csfree(mintEP); return 0; } return mintEP; }
static int test_file_server_connect() { test_start("fs connection"); /* Find the file server. */ nsv_mountpoint_t mp = nsv_resolve("fileserv/*"); test_assert(mp.success == true); test_assert(mp.serverAnon != 0); seL4_CPtr fileservAnon = mp.serverAnon; const int fs_test_repeat = 5; /* Attempt to ping the file server. */ for (int i = 0; i < fs_test_repeat; i++) { int error = serv_ping(fileservAnon); test_assert(error == ESUCCESS); } /* Repeatedly connect to and disconnect from the file server. */ for (int i = 0; i < fs_test_repeat; i++) { int error; seL4_CPtr fileservSession = serv_connect_direct(fileservAnon, REFOS_LIVENESS, &error); test_assert(fileservSession && error == ESUCCESS); if (fileservSession) { serv_disconnect_direct(fileservSession); seL4_CNode_Delete(REFOS_CSPACE, fileservSession, REFOS_CDEPTH); csfree(fileservSession); } } /* Release the resources stored in the valid mountpoint. */ nsv_mountpoint_release(&mp); test_assert(mp.success == false); test_assert(mp.serverAnon == 0); return test_success(); }
refos_err_t srv_ctable_set_param_buffer_handler(srv_common_t *srv, struct srv_client *c, srv_msg_t *m, seL4_CPtr parambufferDataspace, uint32_t parambufferSize) { assert(srv && srv->magic == SRV_MAGIC); assert(c && m); /* Special case: unset the parameter buffer. */ if (!parambufferDataspace && parambufferSize == 0) { seL4_CNode_Revoke(REFOS_CSPACE, c->paramBuffer, REFOS_CDEPTH); seL4_CNode_Delete(REFOS_CSPACE, c->paramBuffer, REFOS_CDEPTH); csfree(c->paramBuffer); c->paramBuffer = 0; c->paramBufferSize = 0; return ESUCCESS; } /* Sanity check parameters. */ if (!srv_check_dispatch_caps(m, 0x00000000, 1)) { return EINVALIDPARAM; } if (parambufferSize == 0) { return EINVALIDPARAM; } /* Set the parameter buffer by copying out the given dspace cap. Do not printf before copyout. */ c->paramBuffer = rpc_copyout_cptr(parambufferDataspace); if (!c->paramBuffer) { ROS_ERROR("Failed to copyout the cap."); return ENOMEM; } c->paramBufferSize = parambufferSize; dprintf("Set param buffer for client cID = %d...\n", c->cID); return ESUCCESS; }
static serv_connection_t serv_connect_internal(char *serverPath, bool paramBuffer) { _svprintf("Connecting to server [%s]...\n", serverPath); serv_connection_t sc; memset(&sc, 0, sizeof(serv_connection_t)); sc.error = EINVALID; /* Resolve server path to find the server's anon cap. */ _svprintf(" Querying nameserv to find anon cap for [%s]....\n", serverPath); printf(" Querying nameserv to find anon cap for [%s]....\n", serverPath); sc.serverMountPoint = nsv_resolve(serverPath); if (!sc.serverMountPoint.success || ROS_ERRNO() != ESUCCESS) { _svprintf(" WARNING: Server not found.\n"); printf(" WARNING: Server not found.\n"); sc.error = ESERVERNOTFOUND; goto exit1; } _svprintf(" Result path prefix [%s] anon 0x%x dspace [%s]....\n", sc.serverMountPoint.nameservPathPrefix, sc.serverMountPoint.serverAnon, sc.serverMountPoint.dspaceName); printf(" Result path prefix [%s] anon 0x%x dspace [%s]....\n", sc.serverMountPoint.nameservPathPrefix, sc.serverMountPoint.serverAnon, sc.serverMountPoint.dspaceName); if (serv_special_connectless_server(sc.serverMountPoint.serverAnon)) { /* Connectionless server. */ _svprintf(" Known connectionless server detected.\n"); printf(" Known connectionless server detected.\n"); sc.connectionLess = true; sc.serverSession = sc.serverMountPoint.serverAnon; sc.error = ESUCCESS; return sc; } else { /* Make connection request to server using the anon cap. */ _svprintf(" Make connection request to server [%s] using the anon cap 0x%x...\n", serverPath, sc.serverMountPoint.serverAnon); printf(" Make connection request to server [%s] using the anon cap 0x%x...\n", serverPath, sc.serverMountPoint.serverAnon); sc.serverSession = serv_connect_direct(sc.serverMountPoint.serverAnon, REFOS_LIVENESS, &sc.error); } if (!sc.serverSession || sc.error != ESUCCESS) { _svprintf(" WARNING: Failed to anonymously connect to server.\n"); printf(" WARNING: Failed to anonymously connect to server.\n"); goto exit2; } /* Try pinging the server. */ int error = serv_ping(sc.serverSession); if (error) { _svprintf(" WARNING: Failed to ping file server.\n"); printf(" WARNING: Failed to ping file server.\n"); sc.error = error; goto exit3; } /* Set up the parameter buffer between client (ie. us) and server. */ if (paramBuffer) { sc.paramBuffer = data_open_map(REFOS_PROCSERV_EP, "anon", 0, 0, PROCESS_PARAM_DEFAULTSIZE, -1); if (sc.paramBuffer.err != ESUCCESS) { _svprintf(" WARNING: Failed to create param buffer dspace.\n"); printf(" WARNING: Failed to create param buffer dspace.\n"); sc.error = sc.paramBuffer.err; goto exit3; } assert(sc.paramBuffer.window && sc.paramBuffer.dataspace); assert(sc.paramBuffer.vaddr != NULL); /* Set this parameter buffer on server. */ error = serv_set_param_buffer(sc.serverSession, sc.paramBuffer.dataspace, PROCESS_PARAM_DEFAULTSIZE); if (error) { _svprintf(" Failed to set remote server parameter buffer."); printf(" Failed to set remote server parameter buffer."); sc.error = error; goto exit4; } } else { sc.paramBuffer.err = -1; } _svprintf("Successfully connected to server [%s]!\n", serverPath); printf("Successfully connected to server [%s]!\n", serverPath); sc.error = ESUCCESS; return sc; /* Exit stack. */ exit4: assert(sc.paramBuffer.err == ESUCCESS); data_mapping_release(sc.paramBuffer); exit3: assert(sc.serverSession); if (!sc.connectionLess) { serv_disconnect_direct(sc.serverSession); seL4_CNode_Delete(REFOS_CSPACE, sc.serverSession, REFOS_CDEPTH); csfree(sc.serverSession); } exit2: nsv_mountpoint_release(&sc.serverMountPoint); exit1: assert(sc.error != ESUCCESS); return sc; }
static int test_file_server_dataspace() { /* ---------- datamap test ------------ */ test_start("fs cpio dspace datamap"); int error; /* Find the file server. */ nsv_mountpoint_t mp = nsv_resolve("fileserv/*"); test_assert(mp.success == true); test_assert(mp.serverAnon != 0); seL4_CPtr fileservAnon = mp.serverAnon; seL4_CPtr fileservSession = serv_connect_direct(fileservAnon, REFOS_LIVENESS, &error); test_assert(fileservSession && error == ESUCCESS); /* Allocate a temporary window. */ seL4_CPtr tempWindow = 0; seL4_Word tempWindowVaddr = walloc(2, &tempWindow); test_assert(tempWindowVaddr && tempWindow); /* Open a new dataspace on the fileserver to test with. */ seL4_CPtr dspace = data_open(fileservSession, "hello.txt", 0, O_RDWR, 0, &error); test_assert(dspace && error == ESUCCESS); /* Test datamap. */ error = data_datamap(fileservSession, dspace, tempWindow, 3); test_assert(error == ESUCCESS); int scmp = strncmp((char*) tempWindowVaddr, "lo world!", 9); test_assert(scmp == 0); test_success(); /* ---------- init_data test ------------ */ test_start("fs cpio dspace init_data"); /* Open a new anon dataspace to init data on */ seL4_CPtr anonDS = data_open(REFOS_PROCSERV_EP, "anon", 0, O_RDWR, 0x1000, &error); test_assert(anonDS && error == ESUCCESS); /* Inititialise content of this anon dataspace with our fileserv CPIO dataspace. */ error = data_init_data(fileservSession, anonDS, dspace , 3); test_assert(error == ESUCCESS); /* Allocate another temporary window. */ seL4_CPtr tempWindowAnon = 0; seL4_Word tempWindowVaddrAnon = walloc(2, &tempWindowAnon); test_assert(tempWindowVaddrAnon && tempWindowAnon); /* Datamap initialised anon dataspace. */ error = data_datamap(REFOS_PROCSERV_EP, anonDS, tempWindowAnon, 0); test_assert(error == ESUCCESS); scmp = strncmp((char*) tempWindowVaddrAnon, "lo world!", 9); test_assert(scmp == 0); /* Clean up. */ data_dataunmap(fileservSession, tempWindow); data_dataunmap(REFOS_PROCSERV_EP, tempWindowAnon); if (tempWindow) { walloc_free(tempWindowVaddr, 2); } if (tempWindowAnon) { walloc_free(tempWindowVaddrAnon, 2); } if (fileservSession) { serv_disconnect_direct(fileservSession); seL4_CNode_Delete(REFOS_CSPACE, fileservSession, REFOS_CDEPTH); csfree(fileservSession); } /* Release the resources stored in the valid mountpoint. */ nsv_mountpoint_release(&mp); test_assert(mp.success == false); test_assert(mp.serverAnon == 0); return test_success(); }