Thu Oct 28 14:37:29 2010 UTC ()
Run different clients (different sockets) in different processes
inside the rump kernel.  Now different host processes can no longer
step on each other inside the rump kernel.


(pooka)
diff -r1.1 -r1.2 src/lib/librumpuser/rumpuser_sp.c

cvs diff -r1.1 -r1.2 src/lib/librumpuser/rumpuser_sp.c (expand / switch to unified diff)

--- src/lib/librumpuser/rumpuser_sp.c 2010/10/27 20:44:50 1.1
+++ src/lib/librumpuser/rumpuser_sp.c 2010/10/28 14:37:29 1.2
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1/* $NetBSD: rumpuser_sp.c,v 1.1 2010/10/27 20:44:50 pooka Exp $ */ 1/* $NetBSD: rumpuser_sp.c,v 1.2 2010/10/28 14:37:29 pooka Exp $ */
2 2
3/* 3/*
4 * Copyright (c) 2010 Antti Kantee. All Rights Reserved. 4 * Copyright (c) 2010 Antti Kantee. All Rights Reserved.
5 * 5 *
6 * Redistribution and use in source and binary forms, with or without 6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions 7 * modification, are permitted provided that the following conditions
8 * are met: 8 * are met:
9 * 1. Redistributions of source code must retain the above copyright 9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer. 10 * notice, this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright 11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the 12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution. 13 * documentation and/or other materials provided with the distribution.
14 * 14 *
@@ -28,27 +28,27 @@ @@ -28,27 +28,27 @@
28/* 28/*
29 * Sysproxy routines. This provides system RPC support over host sockets. 29 * Sysproxy routines. This provides system RPC support over host sockets.
30 * The most notable limitation is that the client and server must share 30 * The most notable limitation is that the client and server must share
31 * the same ABI. This does not mean that they have to be the same 31 * the same ABI. This does not mean that they have to be the same
32 * machine or that they need to run the same version of the host OS, 32 * machine or that they need to run the same version of the host OS,
33 * just that they must agree on the data structures. This even *might* 33 * just that they must agree on the data structures. This even *might*
34 * work correctly from one hardware architecture to another. 34 * work correctly from one hardware architecture to another.
35 * 35 *
36 * Not finished yet, i.e. don't use in production. Lacks locking plus 36 * Not finished yet, i.e. don't use in production. Lacks locking plus
37 * handling of multiple clients and unexpected connection closes. 37 * handling of multiple clients and unexpected connection closes.
38 */ 38 */
39 39
40#include <sys/cdefs.h> 40#include <sys/cdefs.h>
41__RCSID("$NetBSD: rumpuser_sp.c,v 1.1 2010/10/27 20:44:50 pooka Exp $"); 41__RCSID("$NetBSD: rumpuser_sp.c,v 1.2 2010/10/28 14:37:29 pooka Exp $");
42 42
43#include <sys/types.h> 43#include <sys/types.h>
44#include <sys/mman.h> 44#include <sys/mman.h>
45#include <sys/socket.h> 45#include <sys/socket.h>
46 46
47#include <arpa/inet.h> 47#include <arpa/inet.h>
48#include <netinet/in.h> 48#include <netinet/in.h>
49#include <netinet/tcp.h> 49#include <netinet/tcp.h>
50 50
51#include <assert.h> 51#include <assert.h>
52#include <errno.h> 52#include <errno.h>
53#include <fcntl.h> 53#include <fcntl.h>
54#include <poll.h> 54#include <poll.h>
@@ -111,26 +111,27 @@ struct rsp_copydata { @@ -111,26 +111,27 @@ struct rsp_copydata {
111 void *rcp_addr; 111 void *rcp_addr;
112 uint8_t rcp_data[0]; 112 uint8_t rcp_data[0];
113}; 113};
114 114
115/* syscall response */ 115/* syscall response */
116struct rsp_sysresp { 116struct rsp_sysresp {
117 int rsys_error; 117 int rsys_error;
118 register_t rsys_retval[2]; 118 register_t rsys_retval[2];
119}; 119};
120 120
121 121
122struct spclient { 122struct spclient {
123 int spc_fd; 123 int spc_fd;
 124 struct lwp *spc_lwp;
124 125
125 /* incoming */ 126 /* incoming */
126 struct rsp_hdr spc_hdr; 127 struct rsp_hdr spc_hdr;
127 uint8_t *spc_buf; 128 uint8_t *spc_buf;
128 size_t spc_off; 129 size_t spc_off;
129 130
130#if 0 131#if 0
131 /* outgoing */ 132 /* outgoing */
132 int spc_obusy; 133 int spc_obusy;
133 pthread_mutex_t spc_omtx; 134 pthread_mutex_t spc_omtx;
134 pthread_cond_t spc_cv; 135 pthread_cond_t spc_cv;
135#endif 136#endif
136}; 137};
@@ -302,33 +303,36 @@ send_anonmmap_resp(struct spclient *spc, @@ -302,33 +303,36 @@ send_anonmmap_resp(struct spclient *spc,
302 303
303 rhdr.rsp_len = sizeof(rhdr) + sizeof(addr); 304 rhdr.rsp_len = sizeof(rhdr) + sizeof(addr);
304 rhdr.rsp_reqno = reqno; 305 rhdr.rsp_reqno = reqno;
305 rhdr.rsp_type = RUMPSP_ANONMMAP_RESP; 306 rhdr.rsp_type = RUMPSP_ANONMMAP_RESP;
306 rhdr.rsp_sysnum = 0; 307 rhdr.rsp_sysnum = 0;
307 308
308 dosend(spc, &rhdr, sizeof(rhdr)); 309 dosend(spc, &rhdr, sizeof(rhdr));
309 dosend(spc, &addr, sizeof(addr)); 310 dosend(spc, &addr, sizeof(addr));
310 311
311 return 0; 312 return 0;
312} 313}
313 314
314static void 315static void
315serv_handle_disco(unsigned int idx) 316serv_handledisco(unsigned int idx)
316{ 317{
317 struct spclient *spc = &spclist[idx]; 318 struct spclient *spc = &spclist[idx];
318 int fd = spc->spc_fd; 319 int fd = spc->spc_fd;
319 320
320 DPRINTF(("rump_sp: disconnecting [%u]\n", idx)); 321 DPRINTF(("rump_sp: disconnecting [%u]\n", idx));
321 322
 323 rump_pub_lwproc_switch(spc->spc_lwp);
 324 rump_pub_lwproc_releaselwp();
 325
322 free(spc->spc_buf); 326 free(spc->spc_buf);
323 memset(spc, 0, sizeof(*spc)); 327 memset(spc, 0, sizeof(*spc));
324 close(fd); 328 close(fd);
325 pfdlist[idx].fd = -1; 329 pfdlist[idx].fd = -1;
326 nfds--; 330 nfds--;
327 331
328 if (idx == maxidx) { 332 if (idx == maxidx) {
329 while (idx--) { 333 while (idx--) {
330 if (pfdlist[idx].fd != -1) { 334 if (pfdlist[idx].fd != -1) {
331 maxidx = idx; 335 maxidx = idx;
332 break; 336 break;
333 } 337 }
334 assert(idx != 0); 338 assert(idx != 0);
@@ -359,57 +363,68 @@ serv_handleconn(int fd, connecthook_fn c @@ -359,57 +363,68 @@ serv_handleconn(int fd, connecthook_fn c
359 363
360 flags = fcntl(newfd, F_GETFL, 0); 364 flags = fcntl(newfd, F_GETFL, 0);
361 if (fcntl(newfd, F_SETFL, flags | O_NONBLOCK) == -1) { 365 if (fcntl(newfd, F_SETFL, flags | O_NONBLOCK) == -1) {
362 close(newfd); 366 close(newfd);
363 return errno; 367 return errno;
364 } 368 }
365 flags = 1; 369 flags = 1;
366 370
367 if ((error = connhook(newfd)) != 0) { 371 if ((error = connhook(newfd)) != 0) {
368 close(newfd); 372 close(newfd);
369 return error; 373 return error;
370 } 374 }
371 375
 376 if ((error = rump_pub_lwproc_newproc()) != 0) {
 377 close(newfd);
 378 return error;
 379 }
 380
372 /* find empty slot the simple way */ 381 /* find empty slot the simple way */
373 for (i = 0; i < MAXCLI; i++) { 382 for (i = 0; i < MAXCLI; i++) {
374 if (pfdlist[i].fd == -1) 383 if (pfdlist[i].fd == -1)
375 break; 384 break;
376 } 385 }
377 386
378 assert(i < MAXCLI); 387 assert(i < MAXCLI);
379 nfds++; 388 nfds++;
380 389
381 pfdlist[i].fd = newfd; 390 pfdlist[i].fd = newfd;
382 spclist[i].spc_fd = newfd; 391 spclist[i].spc_fd = newfd;
 392 spclist[i].spc_lwp = rump_pub_lwproc_curlwp();
383 if (maxidx < i) 393 if (maxidx < i)
384 maxidx = i; 394 maxidx = i;
385 395
386 DPRINTF(("rump_sp: added new connection at idx %u\n", i)); 396 DPRINTF(("rump_sp: added new connection at idx %u, pid %d\n",
 397 i, rump_sys_getpid()));
 398
 399 rump_pub_lwproc_switch(NULL);
387 400
388 return 0; 401 return 0;
389} 402}
390 403
391static void 404static void
392serv_handlesyscall(struct spclient *spc, struct rsp_hdr *rhdr, uint8_t *data) 405serv_handlesyscall(struct spclient *spc, struct rsp_hdr *rhdr, uint8_t *data)
393{ 406{
394 register_t retval[2]; 407 register_t retval[2];
395 int rv, sysnum; 408 int rv, sysnum;
396 409
397 sysnum = (int)rhdr->rsp_sysnum; 410 sysnum = (int)rhdr->rsp_sysnum;
398 DPRINTF(("rump_sp: handling syscall %d from client %d\n", 411 DPRINTF(("rump_sp: handling syscall %d from client %d\n",
399 sysnum, 0)); 412 sysnum, 0));
400 413
401 pthread_setspecific(spclient_tls, spc); 414 pthread_setspecific(spclient_tls, spc);
 415 rump_pub_lwproc_switch(spc->spc_lwp);
402 rv = rump_pub_syscall(sysnum, data, retval); 416 rv = rump_pub_syscall(sysnum, data, retval);
 417 rump_pub_lwproc_switch(NULL);
403 pthread_setspecific(spclient_tls, NULL); 418 pthread_setspecific(spclient_tls, NULL);
404 419
405 send_syscall_resp(spc, rhdr->rsp_reqno, rv, retval); 420 send_syscall_resp(spc, rhdr->rsp_reqno, rv, retval);
406} 421}
407 422
408static int 423static int
409readframe(struct spclient *spc) 424readframe(struct spclient *spc)
410{ 425{
411 int fd = spc->spc_fd; 426 int fd = spc->spc_fd;
412 size_t left; 427 size_t left;
413 size_t framelen; 428 size_t framelen;
414 ssize_t n; 429 ssize_t n;
415 430
@@ -802,27 +817,27 @@ spserver(void *arg) @@ -802,27 +817,27 @@ spserver(void *arg)
802 continue; 817 continue;
803 818
804 seen++; 819 seen++;
805 DPRINTF(("rump_sp: activity at [%u] %d/%d\n", 820 DPRINTF(("rump_sp: activity at [%u] %d/%d\n",
806 idx, seen, rv)); 821 idx, seen, rv));
807 if (idx > 0) { 822 if (idx > 0) {
808 struct spclient *spc = &spclist[idx]; 823 struct spclient *spc = &spclist[idx];
809 824
810 DPRINTF(("rump_sp: mainloop read [%u]\n", idx)); 825 DPRINTF(("rump_sp: mainloop read [%u]\n", idx));
811 switch (readframe(spc)) { 826 switch (readframe(spc)) {
812 case 0: 827 case 0:
813 break; 828 break;
814 case -1: 829 case -1:
815 serv_handle_disco(idx); 830 serv_handledisco(idx);
816 break; 831 break;
817 default: 832 default:
818 spc->spc_off = 0; 833 spc->spc_off = 0;
819 serv_handlesyscall(spc, 834 serv_handlesyscall(spc,
820 &spc->spc_hdr, spc->spc_buf); 835 &spc->spc_hdr, spc->spc_buf);
821 spc->spc_buf = NULL; 836 spc->spc_buf = NULL;
822 break; 837 break;
823 } 838 }
824 } else { 839 } else {
825 DPRINTF(("rump_sp: mainloop new connection\n")); 840 DPRINTF(("rump_sp: mainloop new connection\n"));
826 serv_handleconn(pfdlist[0].fd, 841 serv_handleconn(pfdlist[0].fd,
827 sarg->sps_connhook); 842 sarg->sps_connhook);
828 } 843 }