void put_handle (struct shim_handle * hdl) { int ref_count = REF_DEC(hdl->ref_count); #ifdef DEBUG_REF debug("put handle %p(%s) (ref_count = %d)\n", hdl, __handle_name(hdl), ref_count); #endif if (!ref_count) { if (hdl->fs && hdl->fs->fs_ops && hdl->fs->fs_ops->hput) hdl->fs->fs_ops->hput(hdl); qstrfree(&hdl->path); qstrfree(&hdl->uri); if (hdl->pal_handle) DkObjectClose(hdl->pal_handle); if (hdl->dentry) put_dentry(hdl->dentry); if (hdl->fs) put_mount(hdl->fs); destroy_handle(hdl); } }
int main (int argc, char ** argv, char ** envp) { pal_printf("Enter Main Thread\n"); PAL_HANDLE out = DkStreamOpen(file_uri, PAL_ACCESS_RDWR, PAL_SHARE_OWNER_W, PAL_CREAT_TRY, 0); if (out == NULL) { pal_printf("DkStreamOpen failed\n"); return -1; } str[0] = 'H'; str[1] = 'e'; str[2] = 'l'; str[3] = 'l'; str[4] = 'o'; str[5] = ' '; str[6] = 'W'; str[7] = 'o'; str[8] = 'r'; str[9] = 'l'; str[10] = 'd'; str[11] = 0; int bytes = DkStreamWrite(out, 0, 11, str, NULL); if (!bytes) { pal_printf("DkStreamWrite failed\n"); return -1; } DkObjectClose(out); PAL_HANDLE in = DkStreamOpen(file_uri, PAL_ACCESS_RDONLY, 0, 0, 0); bytes = DkStreamRead(in, 0, 20, str, NULL, 0); if (!bytes) { pal_printf("DkStreamRead failed\n"); return -1; } pal_printf("%s\n", str); DkStreamDelete(in, 0); PAL_HANDLE del = DkStreamOpen(file_uri, PAL_ACCESS_RDWR, 0, 0, 0); if (del) { pal_printf("DkStreamDelete failed\n"); return -1; } pal_printf("Leave Main Thread\n"); return 0; }
int create_pipes (IDTYPE * pipeid, PAL_HANDLE * srv, PAL_HANDLE * cli, struct shim_qstr * qstr, int flags) { PAL_HANDLE hdl0 = NULL, hdl1 = NULL, hdl2 = NULL; int ret = 0; char * uri = __alloca(PIPE_URI_SIZE); if ((ret = create_pipe(pipeid, uri, PIPE_URI_SIZE, &hdl0, qstr)) < 0) { debug("pipe creation failure\n"); return ret; } if (!(hdl2 = DkStreamOpen(uri, 0, 0, 0, flags & O_NONBLOCK))) { ret = -PAL_ERRNO; debug("pipe connection failure\n"); goto err; } if (!(hdl1 = DkStreamWaitForClient(hdl0))) { ret = -PAL_ERRNO; debug("pipe acception failure\n"); goto err; } DkStreamDelete(hdl0, 0); DkObjectClose(hdl0); *srv = hdl1; *cli = hdl2; return 0; err: if (hdl1) DkObjectClose(hdl1); if (hdl2) DkObjectClose(hdl2); DkStreamDelete(hdl0, 0); DkObjectClose(hdl0); return ret; }
static void __put_ipc_port (struct shim_ipc_port * pobj) { int ref_count = REF_DEC(pobj->ref_count); #ifdef DEBUG_REF debug("put ipc port %p (handle %p, ref_count = %d)\n", pobj, pobj->pal_handle, ref_count); #endif if (!ref_count) { if (pobj->pal_handle) { DkObjectClose(pobj->pal_handle); pobj->pal_handle = NULL; } free_mem_obj_to_mgr(port_mgr, pobj); } }
int main (int argc, char ** argv) { int nsend = 5 , i; PAL_HANDLE handles[nsend]; if (argc == 1) /* parent */ { pal_printf("Parent: Executing the program\n"); const char *args[3] = { "HandleSend", "child", NULL }; char * data = "Hello World"; char content[20]; char uri[80]; PAL_HANDLE child; int bytes; pal_printf("Parent: Creating handles\n"); // Sending pipe handle handles[0] = DkStreamOpen("pipe.srv:012", PAL_ACCESS_RDWR, 0, PAL_CREATE_TRY, 0); if (!handles[0]) { pal_printf("Parent: DkStreamOpen for pipe failed\n"); goto out; } // Sending pipe handle handles[1] = DkStreamOpen("udp:127.0.0.1:8000", PAL_ACCESS_RDWR, 0, PAL_CREATE_TRY, 0); if (!handles[1]) { pal_printf("Parent: DkStreamOpen for socket failed\n"); goto out; } for (i = 2 ; i < nsend; i++) { snprintf(uri, 80, "file:test_file_%d", i - 2); handles[i] = DkStreamOpen(uri, PAL_ACCESS_RDWR, 0600, PAL_CREATE_TRY, 0); if (!handles[i]) { pal_printf("Parent: DkStreamOpen failed\n"); goto out; } DkStreamSetLength(handles[i], 0); } for (i = 0 ; i < nsend ; i++) { /* do some write */ snprintf(content, sizeof(content), "%s%d", data, i); bytes = DkStreamWrite(handles[i], 0, sizeof(content), content, NULL); if (!bytes) { pal_printf("Parent: DKStreamWrite failed\n"); goto out; } DkStreamFlush(handles[i]); } pal_printf("Parent: Forking child\n"); child = DkProcessCreate ("file:HandleSend", args); if (!child) { pal_printf("Parent: Failed creating process\n"); DkProcessExit(1); } for (i = 0 ; i < nsend ; i++) { pal_printf("Parent: Sending Handle %d\n", i); if (!DkSendHandle(child, handles[i])) { pal_printf("Send handle failed\n"); goto out; } DkObjectClose(handles[i]); } pal_printf("Parent: Finished execution\n"); DkObjectClose(child); } else /* child */ { PAL_HANDLE parent = pal_control.parent_process; for (i = 0 ; i < nsend ; i++) { pal_printf("Child: Receiving Handle %d\n", i); handles[i] = DkReceiveHandle(parent); if (!handles[i]) { pal_printf("Child: Failed receiving handle\n"); DkProcessExit(1); } } pal_printf("Child: Reading the handles\n"); for (i = 0 ; i < nsend ; i++) { /* do some read */ pal_printf("Child: Handle %d Type ", i); char data[20]; switch(PAL_GET_TYPE(handles[i])) { case pal_type_file: if ((DkStreamRead(handles[i], 0, 20, data, NULL, 0))) pal_printf("File Data: %s\n", data); else pal_printf("Couldn't read\n"); break; case pal_type_pipesrv: pal_printf("Pipe\n"); break; case pal_type_udp: pal_printf("Udp\n"); break; default: pal_printf("Unknown\n"); } DkObjectClose(handles[i]); } pal_printf("Child: Finished execution\n\n"); DkObjectClose(parent); } out: for (i = 0 ; i < nsend ; i++) DkObjectClose(handles[i]); return 0; }
int main (int argc, char ** argv) { if (argc < 2) { pal_printf("specify the port to open\n"); return 0; } char uri[60]; snprintf(uri, 60, "tcp.srv:127.0.0.1:%s", argv[1]); PAL_HANDLE srv = DkStreamOpen(uri, PAL_ACCESS_RDWR, 0, PAL_CREAT_TRY, 0); if (srv == NULL) { pal_printf("DkStreamOpen failed\n"); return -1; } void * buffer = (void *) DkVirtualMemoryAlloc(NULL, 4096, 0, PAL_PROT_READ|PAL_PROT_WRITE); if (!buffer) { pal_printf("DkVirtualMemoryAlloc failed\n"); return -1; } PAL_HANDLE hdls[8]; int nhdls = 1, i; hdls[0] = srv; while(1) { PAL_HANDLE hdl = DkObjectsWaitAny(nhdls, hdls, NO_TIMEOUT); if (!hdl) continue; if (hdl == srv) { hdl = DkStreamWaitForClient(srv); if (!hdl) continue; if (nhdls >= 8) { pal_printf("[ ] connection rejected\n"); DkObjectClose(hdl); continue; } pal_printf("[%d] receive new connection\n", nhdls); hdls[nhdls++] = hdl; continue; } int cnt = 0; for (i = 0 ; i < nhdls ; i++) if (hdls[i] == hdl) cnt = i; int bytes = DkStreamRead(hdl, 0, 4096, buffer, NULL, 0); if (bytes == 0) { DkObjectClose(hdls[cnt]); if (cnt != nhdls - 1) hdls[cnt] = hdls[nhdls - 1]; nhdls--; continue; } ((char *) buffer)[bytes] = 0; pal_printf("[%d] %s", cnt, (char *) buffer); } return 0; }
int main(int argc, char ** argv) { char * name = "parent"; if (argc == 1) { const char * args[3]; char uri[20], uri2[20]; snprintf(uri2, 20, "file:%s", argv[0]); args[0] = "Ipc"; args[1] = uri; args[2] = NULL; void * mem = (void *) DkVirtualMemoryAlloc(NULL, pal_control.alloc_align, 0, PAL_PROT_READ|PAL_PROT_WRITE); pal_printf("mem = %p\n", mem); snprintf((char *) mem, 4096, "Hello World"); PAL_NUM key = 0; PAL_HANDLE chdl = DkCreatePhysicalMemoryChannel(&key); if (chdl == NULL) { pal_printf ("(parent) DkCreatePhysicalMemoryChannel Failed," " Make sure gipc module is loaded\n"); return 0; } snprintf(uri, 20, "gipc:%lld", key); PAL_HANDLE phdl = DkProcessCreate(uri2, 0, args); if (phdl == NULL) pal_printf ("ProcessCreate Failed\n"); PAL_PTR addr = (PAL_PTR) mem; PAL_NUM size = pal_control.alloc_align; DkPhysicalMemoryCommit(chdl, 1, &addr, &size, 0); DkObjectClose(chdl); char x; int rv = DkStreamRead(phdl, 0, 1, &x, NULL, 0); if (rv != 1) { pal_printf("Failed to get exit signal from child, %d\n", rv); return -1; } } else { name = argv[1]; PAL_HANDLE chdl = DkStreamOpen(name, 0, 0, 0, 0); if (chdl == NULL) { pal_printf("(child) StreamOpen Failed\n"); return 0; } PAL_PTR addr = NULL; PAL_NUM size = pal_control.alloc_align; PAL_FLG prot = PAL_PROT_READ|PAL_PROT_WRITE; int len = DkPhysicalMemoryMap (chdl, 1, &addr, &size, &prot); if (!len) { pal_printf("PhysicalMemoryMap Failed\n"); return 0; } pal_printf("(child) mem = %p\n", addr); pal_printf("(child) receive string: %s\n", (char *) addr); DkStreamDelete(chdl, 0); DkObjectClose(chdl); // Write a byte to the parent int rv = DkStreamWrite(pal_control.parent_process, 0, 1, "z", NULL); if (rv < 0) { pal_printf("Failed to write an exit byte\n"); return -1; } } pal_printf("Enter Main Thread (%s)\n", name); DkThreadDelayExecution (3000); pal_printf("Leave Main Thread\n"); return 0; }
static int __load_msg_persist (struct shim_msg_handle * msgq, bool readmsg) { int ret = 0; char fileuri[20]; snprintf(fileuri, 20, "file:msgq.%08x", msgq->msqid); PAL_HANDLE file = DkStreamOpen(fileuri, PAL_ACCESS_RDONLY, 0, 0, 0); if (!file) return -EIDRM; struct msg_handle_backup mback; int bytes = DkStreamRead(file, 0, sizeof(struct msg_handle_backup), &mback, NULL, 0); if (bytes < sizeof(struct msg_handle_backup)) { ret = bytes ? -EFAULT : -PAL_ERRNO; goto out; } msgq->perm = mback.perm; if (!readmsg || !mback.nmsgs) goto done; int expected_size = sizeof(struct msg_handle_backup) + sizeof(struct msg_backup) * mback.nmsgs + mback.currentsize; void * mem = (void *) DkStreamMap(file, NULL, PAL_PROT_READ, 0, ALIGN_UP(expected_size)); if (!mem) { ret = -PAL_ERRNO; goto out; } mem += sizeof(struct msg_handle_backup); struct msg_type * mtype = NULL; for (int i = 0 ; i < mback.nmsgs ; i++) { struct msg_backup * m = mem; mem += sizeof(struct msg_backup) + m->size; debug("load msg: type=%d, size=%d\n", m->type, m->size); if (!mtype || mtype->type != m->type) mtype = __add_msg_type(m->type, &msgq->types, &msgq->ntypes, &msgq->maxtypes); if ((ret = __store_msg_qobjs(msgq, mtype, m->size, m->data)) < 0) goto out; }; DkStreamUnmap(mem, ALIGN_UP(expected_size)); done: DkStreamDelete(file, 0); ret = 0; goto out; out: DkObjectClose(file); return ret; }
static int __store_msg_persist (struct shim_msg_handle * msgq) { int ret = 0; if (msgq->deleted) goto out; debug("store msgq %d to persistent store\n", msgq->msqid); char fileuri[20]; snprintf(fileuri, 20, "file:msgq.%08x", msgq->msqid); PAL_HANDLE file = DkStreamOpen(fileuri, PAL_ACCESS_RDWR, 0600, PAL_CREAT_TRY, 0); if (!file) { ret = -PAL_ERRNO; goto out; } int expected_size = sizeof(struct msg_handle_backup) + sizeof(struct msg_backup) * msgq->nmsgs + msgq->currentsize; if (DkStreamSetLength(file, expected_size) != expected_size) goto err_file; void * mem = (void *) DkStreamMap(file, NULL, PAL_PROT_READ|PAL_PROT_WRITE, 0, ALIGN_UP(expected_size)); if (!mem) { ret = -EFAULT; goto err_file; } struct msg_handle_backup * mback = mem; mem += sizeof(struct msg_handle_backup); mback->perm = msgq->perm; mback->nmsgs = msgq->nmsgs; mback->currentsize = msgq->currentsize; struct msg_type * mtype; for (mtype = msgq->types ; mtype < &msgq->types[msgq->ntypes] ; mtype++) { while (mtype->msgs) { struct msg_backup * msg = mem; mem += sizeof(struct msg_backup) + mtype->msgs->size; msg->type = mtype->type; msg->size = mtype->msgs->size; __load_msg_qobjs(msgq, mtype, mtype->msgs, msg->data); } mtype->msgs = mtype->msg_tail = NULL; } DkStreamUnmap(mem, ALIGN_UP(expected_size)); if (msgq->owned) for (mtype = msgq->types ; mtype < &msgq->types[msgq->ntypes] ; mtype++) { struct msg_req * req = mtype->reqs; mtype->reqs = mtype->req_tail = NULL; while (req) { struct sysv_client * c = &req->dest; struct msg_req * next = req->next; __response_ipc_message(c->port, c->vmid, -EIDRM, c->seq); put_ipc_port(c->port); __free_msg_qobj(msgq, req); req = next; } } msgq->owned = false; ret = 0; goto out; err_file: DkStreamDelete(file, 0); DkObjectClose(file); out: // To wake up any receiver waiting on local message which must // now be requested from new owner. DkEventSet(msgq->event); return ret; }
int main (int argc, char ** argv, char ** envp) { char gipc_uri[20]; int ret; DkSetExceptionHandler(handler, PAL_EVENT_MEMFAULT); if (argc > 1 && !memcmp(argv[1], "Child", 6)) { /* private memory */ ret = DkStreamRead(pal_control.parent_process, 0, 20, gipc_uri, NULL, 0); if (ret > 0) { PAL_HANDLE ipc1 = DkStreamOpen(gipc_uri, 0, 0, 0, 0); if (ipc1) { pal_printf("Join Physical Memory Store OK\n"); PAL_PTR mem_addr = 0; PAL_NUM mem_size = UNIT; PAL_FLG mem_prot = PAL_PROT_READ|PAL_PROT_WRITE; ret = DkPhysicalMemoryMap(ipc1, 1, &mem_addr, &mem_size, &mem_prot); if (ret > 0) { pal_printf("[Test 1] Physical Memory Map : %s\n", (char *) mem_addr); memcpy((void *) mem_addr, "Hello World, Bob", 20); pal_printf("[Test 1] Receiver After Map : %s\n", (char *) mem_addr); } ret = 0; DkStreamWrite(pal_control.parent_process, 0, sizeof(int), &ret, NULL); DkObjectClose(ipc1); } } /* private untouched memory */ ret = DkStreamRead(pal_control.parent_process, 0, 20, gipc_uri, NULL, 0); if (ret > 0) { PAL_HANDLE ipc2 = DkStreamOpen(gipc_uri, 0, 0, 0, 0); if (ipc2) { pal_printf("Join Physical Memory Store OK\n"); PAL_PTR mem_addr = 0; PAL_NUM mem_size = UNIT; PAL_FLG mem_prot = PAL_PROT_READ|PAL_PROT_WRITE; ret = DkPhysicalMemoryMap(ipc2, 1, &mem_addr, &mem_size, &mem_prot); if (ret > 0) { pal_printf("[Test 2] Physical Memory Map : %s\n", (char *) mem_addr); memcpy((void *) mem_addr, "Hello World, Bob", 20); pal_printf("[Test 2] Receiver After Map : %s\n", (char *) mem_addr); } ret = 0; DkStreamWrite(pal_control.parent_process, 0, sizeof(int), &ret, NULL); DkStreamDelete(ipc2, 0); DkObjectClose(ipc2); } } /* file-backed memory */ ret = DkStreamRead(pal_control.parent_process, 0, 20, gipc_uri, NULL, 0); if (ret > 0) { PAL_HANDLE ipc3 = DkStreamOpen(gipc_uri, 0, 0, 0, 0); if (ipc3) { pal_printf("Join Physical Memory Store OK\n"); PAL_PTR mem_addr = 0; PAL_NUM mem_size = UNIT; PAL_FLG mem_prot = PAL_PROT_READ|PAL_PROT_WRITE; ret = DkPhysicalMemoryMap(ipc3, 1, &mem_addr, &mem_size, &mem_prot); if (ret > 0) { pal_printf("[Test 3] Physical Memory Map : %s\n", (char *) mem_addr); memcpy((void *) mem_addr, "Hello World, Bob", 20); pal_printf("[Test 3] Receiver After Map : %s\n", (char *) mem_addr); } ret = 0; DkStreamWrite(pal_control.parent_process, 0, sizeof(int), &ret, NULL); DkObjectClose(ipc3); } } /* file-backed memory beyond file size */ ret = DkStreamRead(pal_control.parent_process, 0, 20, gipc_uri, NULL, 0); if (ret > 0) { PAL_HANDLE ipc4 = DkStreamOpen(gipc_uri, 0, 0, 0, 0); if (ipc4) { pal_printf("Join Physical Memory Store OK\n"); PAL_PTR mem_addr = 0; PAL_NUM mem_size = UNIT; PAL_FLG mem_prot = PAL_PROT_READ|PAL_PROT_WRITE; ret = DkPhysicalMemoryMap(ipc4, 1, &mem_addr, &mem_size, &mem_prot); if (ret > 0) { message = "[Test 4] Physical Memory Map : Memory Fault\n"; *(volatile int *) mem_addr; __asm__ volatile("nop"); message = NULL; } ret = 0; DkStreamWrite(pal_control.parent_process, 0, sizeof(int), &ret, NULL); DkObjectClose(ipc4); }
long shim_do_sandbox_create (int flags, const char * fs_sb, struct net_sb * net_sb) { unsigned int sbid; char uri[24]; PAL_HANDLE handle = NULL; int ret = create_handle("file:sandbox-", uri, 24, &handle, &sbid); if (ret < 0) return ret; debug("create manifest: %s\n", uri); struct config_store * newcfg = __alloca(sizeof(struct config_store)); memset(newcfg, 0, sizeof(struct config_store)); newcfg->malloc = __malloc; newcfg->free = __free; if ((ret = copy_config(root_config, newcfg)) < 0) { newcfg = NULL; goto err; } if (flags & SANDBOX_FS) if ((ret = isolate_fs(newcfg, fs_sb)) < 0) goto err; if (flags & SANDBOX_NET) if ((ret = isolate_net(newcfg, net_sb)) < 0) goto err; struct cfg_arg arg; arg.handle = handle; arg.offset = 0; if ((ret = write_config(&arg, __write, newcfg)) < 0) goto err; DkObjectClose(handle); PAL_BOL success = DkProcessSandboxCreate(uri, flags & SANDBOX_RPC ? PAL_SANDBOX_PIPE : 0); if (!success) { ret = -PAL_ERRNO; goto err; } if (sandbox_info.sbid) { if (!sandbox_info.parent_sbid || sandbox_info.parent_vmid != cur_process.vmid) { sandbox_info.parent_sbid = sandbox_info.sbid; sandbox_info.parent_vmid = cur_process.vmid; } } if (flags & SANDBOX_RPC) del_all_ipc_ports(0); if ((ret = free_config(root_config)) < 0) goto err; handle = DkStreamOpen(uri, PAL_ACCESS_RDONLY, 0, 0, 0); if (!handle) return -PAL_ERRNO; root_config = newcfg; sandbox_info.sbid = sbid; return sbid; err: free_config(newcfg); DkStreamDelete(handle, 0); DkObjectClose(handle); return ret; }
int main (int argc, char ** argv) { PAL_HANDLE handles[3]; if (argc == 2 && !memcmp(argv[1], "Child", 6)) { for (int i = 0 ; i < 3 ; i++) { handles[i] = DkReceiveHandle(pal_control.parent_process); if (handles[i]) pal_printf("Receive Handle OK\n"); } char buffer[20]; for (int i = 0 ; i < 3 ; i++) { if (!handles[i]) continue; memset(buffer, 0, 20); switch(PAL_GET_TYPE(handles[i])) { case pal_type_pipesrv: { PAL_HANDLE pipe = DkStreamWaitForClient(handles[i]); if (pipe) { if (DkStreamRead(pipe, 0, 20, buffer, NULL, 0)) pal_printf("Receive Pipe Handle: %s\n", buffer); DkObjectClose(pipe); } break; } case pal_type_udpsrv: { char uri[20]; if ((DkStreamRead(handles[i], 0, 20, buffer, &uri, 20))) pal_printf("Receive Socket Handle: %s\n", buffer); break; } case pal_type_file: if (DkStreamRead(handles[i], 0, 20, buffer, NULL, 0)) pal_printf("Receive File Handle: %s\n", buffer); break; default: break; } DkObjectClose(handles[i]); } } else { const char *args[3] = { "SendHandle", "Child", NULL }; PAL_HANDLE child = DkProcessCreate("file:SendHandle", 0, args); if (child) { // Sending pipe handle handles[0] = DkStreamOpen("pipe.srv:1", PAL_ACCESS_RDWR, 0, PAL_CREAT_TRY, 0); if (handles[0]) { pal_printf("Send Handle OK\n"); if (DkSendHandle(child, handles[0])) { DkObjectClose(handles[0]); PAL_HANDLE pipe = DkStreamOpen("pipe:1", PAL_ACCESS_RDWR, 0, 0, 0); if (pipe) { DkStreamWrite(pipe, 0, 20, "Hello World", NULL); DkObjectClose(pipe); } } else { DkObjectClose(handles[0]); } } // Sending udp handle handles[1] = DkStreamOpen("udp.srv:127.0.0.1:8000", PAL_ACCESS_RDWR, 0, PAL_CREAT_TRY, 0); if (handles[1]) { pal_printf("Send Handle OK\n"); if (DkSendHandle(child, handles[1])) { DkObjectClose(handles[1]); PAL_HANDLE socket = DkStreamOpen("udp:127.0.0.1:8000", PAL_ACCESS_RDWR, 0, 0, 0); if (socket) { DkStreamWrite(socket, 0, 20, "Hello World", NULL); DkObjectClose(socket); } } else { DkObjectClose(handles[1]); } } handles[2] = DkStreamOpen("file:to_send.tmp", PAL_ACCESS_RDWR, 0600, PAL_CREAT_TRY, 0); if (handles[2]) { pal_printf("Send Handle OK\n"); DkStreamWrite(handles[2], 0, 20, "Hello World", NULL); DkStreamSetLength(handles[2], 4096); DkSendHandle(child, handles[2]); DkObjectClose(handles[2]); } } DkObjectClose(child); } return 0; }