| @@ -1,14 +1,14 @@ | | | @@ -1,14 +1,14 @@ |
1 | /* $NetBSD: rumpclient.c,v 1.25 2011/02/07 14:49:53 pooka Exp $ */ | | 1 | /* $NetBSD: rumpclient.c,v 1.26 2011/02/07 15:25:41 pooka Exp $ */ |
2 | | | 2 | |
3 | /* | | 3 | /* |
4 | * Copyright (c) 2010, 2011 Antti Kantee. All Rights Reserved. | | 4 | * Copyright (c) 2010, 2011 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 | * |
| @@ -257,56 +257,53 @@ cliwaitresp(struct spclient *spc, struct | | | @@ -257,56 +257,53 @@ cliwaitresp(struct spclient *spc, struct |
257 | } | | 257 | } |
258 | } | | 258 | } |
259 | TAILQ_REMOVE(&spc->spc_respwait, rw, rw_entries); | | 259 | TAILQ_REMOVE(&spc->spc_respwait, rw, rw_entries); |
260 | pthread_mutex_unlock(&spc->spc_mtx); | | 260 | pthread_mutex_unlock(&spc->spc_mtx); |
261 | pthread_cond_destroy(&rw->rw_cv); | | 261 | pthread_cond_destroy(&rw->rw_cv); |
262 | | | 262 | |
263 | if (spc->spc_generation != mygen || !imalive) { | | 263 | if (spc->spc_generation != mygen || !imalive) { |
264 | return ENOTCONN; | | 264 | return ENOTCONN; |
265 | } | | 265 | } |
266 | return rw->rw_error; | | 266 | return rw->rw_error; |
267 | } | | 267 | } |
268 | | | 268 | |
269 | static int | | 269 | static int |
270 | syscall_req(struct spclient *spc, int sysnum, | | 270 | syscall_req(struct spclient *spc, sigset_t *omask, int sysnum, |
271 | const void *data, size_t dlen, void **resp) | | 271 | const void *data, size_t dlen, void **resp) |
272 | { | | 272 | { |
273 | struct rsp_hdr rhdr; | | 273 | struct rsp_hdr rhdr; |
274 | struct respwait rw; | | 274 | struct respwait rw; |
275 | sigset_t omask; | | | |
276 | int rv; | | 275 | int rv; |
277 | | | 276 | |
278 | rhdr.rsp_len = sizeof(rhdr) + dlen; | | 277 | rhdr.rsp_len = sizeof(rhdr) + dlen; |
279 | rhdr.rsp_class = RUMPSP_REQ; | | 278 | rhdr.rsp_class = RUMPSP_REQ; |
280 | rhdr.rsp_type = RUMPSP_SYSCALL; | | 279 | rhdr.rsp_type = RUMPSP_SYSCALL; |
281 | rhdr.rsp_sysnum = sysnum; | | 280 | rhdr.rsp_sysnum = sysnum; |
282 | | | 281 | |
283 | pthread_sigmask(SIG_SETMASK, &fullset, &omask); | | | |
284 | do { | | 282 | do { |
285 | putwait(spc, &rw, &rhdr); | | 283 | putwait(spc, &rw, &rhdr); |
286 | if ((rv = send_with_recon(spc, &rhdr, sizeof(rhdr))) != 0) { | | 284 | if ((rv = send_with_recon(spc, &rhdr, sizeof(rhdr))) != 0) { |
287 | unputwait(spc, &rw); | | 285 | unputwait(spc, &rw); |
288 | continue; | | 286 | continue; |
289 | } | | 287 | } |
290 | if ((rv = send_with_recon(spc, data, dlen)) != 0) { | | 288 | if ((rv = send_with_recon(spc, data, dlen)) != 0) { |
291 | unputwait(spc, &rw); | | 289 | unputwait(spc, &rw); |
292 | continue; | | 290 | continue; |
293 | } | | 291 | } |
294 | | | 292 | |
295 | rv = cliwaitresp(spc, &rw, &omask, false); | | 293 | rv = cliwaitresp(spc, &rw, omask, false); |
296 | if (rv == ENOTCONN) | | 294 | if (rv == ENOTCONN) |
297 | rv = EAGAIN; | | 295 | rv = EAGAIN; |
298 | } while (rv == EAGAIN); | | 296 | } while (rv == EAGAIN); |
299 | pthread_sigmask(SIG_SETMASK, &omask, NULL); | | | |
300 | | | 297 | |
301 | *resp = rw.rw_data; | | 298 | *resp = rw.rw_data; |
302 | return rv; | | 299 | return rv; |
303 | } | | 300 | } |
304 | | | 301 | |
305 | static int | | 302 | static int |
306 | handshake_req(struct spclient *spc, uint32_t *auth, int cancel, bool haslock) | | 303 | handshake_req(struct spclient *spc, uint32_t *auth, int cancel, bool haslock) |
307 | { | | 304 | { |
308 | struct handshake_fork rf; | | 305 | struct handshake_fork rf; |
309 | struct rsp_hdr rhdr; | | 306 | struct rsp_hdr rhdr; |
310 | struct respwait rw; | | 307 | struct respwait rw; |
311 | sigset_t omask; | | 308 | sigset_t omask; |
312 | size_t bonus; | | 309 | size_t bonus; |
| @@ -336,69 +333,66 @@ handshake_req(struct spclient *spc, uint | | | @@ -336,69 +333,66 @@ handshake_req(struct spclient *spc, uint |
336 | if (auth) { | | 333 | if (auth) { |
337 | memcpy(rf.rf_auth, auth, AUTHLEN*sizeof(*auth)); | | 334 | memcpy(rf.rf_auth, auth, AUTHLEN*sizeof(*auth)); |
338 | rf.rf_cancel = cancel; | | 335 | rf.rf_cancel = cancel; |
339 | rv = send_with_recon(spc, &rf, sizeof(rf)); | | 336 | rv = send_with_recon(spc, &rf, sizeof(rf)); |
340 | } else { | | 337 | } else { |
341 | rv = dosend(spc, getprogname(), strlen(getprogname())+1); | | 338 | rv = dosend(spc, getprogname(), strlen(getprogname())+1); |
342 | } | | 339 | } |
343 | if (rv || cancel) { | | 340 | if (rv || cancel) { |
344 | if (haslock) | | 341 | if (haslock) |
345 | unputwait_locked(spc, &rw); | | 342 | unputwait_locked(spc, &rw); |
346 | else | | 343 | else |
347 | unputwait(spc, &rw); | | 344 | unputwait(spc, &rw); |
348 | if (cancel) { | | 345 | if (cancel) { |
349 | pthread_sigmask(SIG_SETMASK, &omask, NULL); | | 346 | goto out; |
350 | return rv; | | | |
351 | } | | 347 | } |
352 | } else { | | 348 | } else { |
353 | rv = cliwaitresp(spc, &rw, &omask, haslock); | | 349 | rv = cliwaitresp(spc, &rw, &omask, haslock); |
354 | } | | 350 | } |
355 | pthread_sigmask(SIG_SETMASK, &omask, NULL); | | | |
356 | if (rv) | | 351 | if (rv) |
357 | return rv; | | 352 | goto out; |
358 | | | 353 | |
359 | rv = *(int *)rw.rw_data; | | 354 | rv = *(int *)rw.rw_data; |
360 | free(rw.rw_data); | | 355 | free(rw.rw_data); |
361 | | | 356 | |
| | | 357 | out: |
| | | 358 | pthread_sigmask(SIG_SETMASK, &omask, NULL); |
362 | return rv; | | 359 | return rv; |
363 | } | | 360 | } |
364 | | | 361 | |
365 | static int | | 362 | static int |
366 | prefork_req(struct spclient *spc, void **resp) | | 363 | prefork_req(struct spclient *spc, sigset_t *omask, void **resp) |
367 | { | | 364 | { |
368 | struct rsp_hdr rhdr; | | 365 | struct rsp_hdr rhdr; |
369 | struct respwait rw; | | 366 | struct respwait rw; |
370 | sigset_t omask; | | | |
371 | int rv; | | 367 | int rv; |
372 | | | 368 | |
373 | rhdr.rsp_len = sizeof(rhdr); | | 369 | rhdr.rsp_len = sizeof(rhdr); |
374 | rhdr.rsp_class = RUMPSP_REQ; | | 370 | rhdr.rsp_class = RUMPSP_REQ; |
375 | rhdr.rsp_type = RUMPSP_PREFORK; | | 371 | rhdr.rsp_type = RUMPSP_PREFORK; |
376 | rhdr.rsp_error = 0; | | 372 | rhdr.rsp_error = 0; |
377 | | | 373 | |
378 | pthread_sigmask(SIG_SETMASK, &fullset, &omask); | | | |
379 | do { | | 374 | do { |
380 | putwait(spc, &rw, &rhdr); | | 375 | putwait(spc, &rw, &rhdr); |
381 | rv = send_with_recon(spc, &rhdr, sizeof(rhdr)); | | 376 | rv = send_with_recon(spc, &rhdr, sizeof(rhdr)); |
382 | if (rv != 0) { | | 377 | if (rv != 0) { |
383 | unputwait(spc, &rw); | | 378 | unputwait(spc, &rw); |
384 | continue; | | 379 | continue; |
385 | } | | 380 | } |
386 | | | 381 | |
387 | rv = cliwaitresp(spc, &rw, &omask, false); | | 382 | rv = cliwaitresp(spc, &rw, omask, false); |
388 | if (rv == ENOTCONN) | | 383 | if (rv == ENOTCONN) |
389 | rv = EAGAIN; | | 384 | rv = EAGAIN; |
390 | } while (rv == EAGAIN); | | 385 | } while (rv == EAGAIN); |
391 | pthread_sigmask(SIG_SETMASK, &omask, NULL); | | | |
392 | | | 386 | |
393 | *resp = rw.rw_data; | | 387 | *resp = rw.rw_data; |
394 | return rv; | | 388 | return rv; |
395 | } | | 389 | } |
396 | | | 390 | |
397 | /* | | 391 | /* |
398 | * prevent response code from deadlocking with reconnect code | | 392 | * prevent response code from deadlocking with reconnect code |
399 | */ | | 393 | */ |
400 | static int | | 394 | static int |
401 | resp_sendlock(struct spclient *spc) | | 395 | resp_sendlock(struct spclient *spc) |
402 | { | | 396 | { |
403 | int rv = 0; | | 397 | int rv = 0; |
404 | | | 398 | |
| @@ -453,44 +447,49 @@ send_anonmmap_resp(struct spclient *spc, | | | @@ -453,44 +447,49 @@ send_anonmmap_resp(struct spclient *spc, |
453 | | | 447 | |
454 | if (resp_sendlock(spc) != 0) | | 448 | if (resp_sendlock(spc) != 0) |
455 | return; | | 449 | return; |
456 | (void)dosend(spc, &rhdr, sizeof(rhdr)); | | 450 | (void)dosend(spc, &rhdr, sizeof(rhdr)); |
457 | (void)dosend(spc, &addr, sizeof(addr)); | | 451 | (void)dosend(spc, &addr, sizeof(addr)); |
458 | sendunlock(spc); | | 452 | sendunlock(spc); |
459 | } | | 453 | } |
460 | | | 454 | |
461 | int | | 455 | int |
462 | rumpclient_syscall(int sysnum, const void *data, size_t dlen, | | 456 | rumpclient_syscall(int sysnum, const void *data, size_t dlen, |
463 | register_t *retval) | | 457 | register_t *retval) |
464 | { | | 458 | { |
465 | struct rsp_sysresp *resp; | | 459 | struct rsp_sysresp *resp; |
| | | 460 | sigset_t omask; |
466 | void *rdata; | | 461 | void *rdata; |
467 | int rv; | | 462 | int rv; |
468 | | | 463 | |
| | | 464 | pthread_sigmask(SIG_SETMASK, &fullset, &omask); |
| | | 465 | |
469 | DPRINTF(("rumpsp syscall_req: syscall %d with %p/%zu\n", | | 466 | DPRINTF(("rumpsp syscall_req: syscall %d with %p/%zu\n", |
470 | sysnum, data, dlen)); | | 467 | sysnum, data, dlen)); |
471 | | | 468 | |
472 | rv = syscall_req(&clispc, sysnum, data, dlen, &rdata); | | 469 | rv = syscall_req(&clispc, &omask, sysnum, data, dlen, &rdata); |
473 | if (rv) | | 470 | if (rv) |
474 | return rv; | | 471 | goto out; |
475 | | | 472 | |
476 | resp = rdata; | | 473 | resp = rdata; |
477 | DPRINTF(("rumpsp syscall_resp: syscall %d error %d, rv: %d/%d\n", | | 474 | DPRINTF(("rumpsp syscall_resp: syscall %d error %d, rv: %d/%d\n", |
478 | sysnum, rv, resp->rsys_retval[0], resp->rsys_retval[1])); | | 475 | sysnum, rv, resp->rsys_retval[0], resp->rsys_retval[1])); |
479 | | | 476 | |
480 | memcpy(retval, &resp->rsys_retval, sizeof(resp->rsys_retval)); | | 477 | memcpy(retval, &resp->rsys_retval, sizeof(resp->rsys_retval)); |
481 | rv = resp->rsys_error; | | 478 | rv = resp->rsys_error; |
482 | free(rdata); | | 479 | free(rdata); |
483 | | | 480 | |
| | | 481 | out: |
| | | 482 | pthread_sigmask(SIG_SETMASK, &omask, NULL); |
484 | return rv; | | 483 | return rv; |
485 | } | | 484 | } |
486 | | | 485 | |
487 | static void | | 486 | static void |
488 | handlereq(struct spclient *spc) | | 487 | handlereq(struct spclient *spc) |
489 | { | | 488 | { |
490 | struct rsp_copydata *copydata; | | 489 | struct rsp_copydata *copydata; |
491 | struct rsp_hdr *rhdr = &spc->spc_hdr; | | 490 | struct rsp_hdr *rhdr = &spc->spc_hdr; |
492 | void *mapaddr; | | 491 | void *mapaddr; |
493 | size_t maplen; | | 492 | size_t maplen; |
494 | int reqtype = spc->spc_hdr.rsp_type; | | 493 | int reqtype = spc->spc_hdr.rsp_type; |
495 | | | 494 | |
496 | switch (reqtype) { | | 495 | switch (reqtype) { |
| @@ -747,42 +746,47 @@ rumpclient_init() | | | @@ -747,42 +746,47 @@ rumpclient_init() |
747 | } | | 746 | } |
748 | | | 747 | |
749 | return 0; | | 748 | return 0; |
750 | } | | 749 | } |
751 | | | 750 | |
752 | struct rumpclient_fork { | | 751 | struct rumpclient_fork { |
753 | uint32_t fork_auth[AUTHLEN]; | | 752 | uint32_t fork_auth[AUTHLEN]; |
754 | }; | | 753 | }; |
755 | | | 754 | |
756 | struct rumpclient_fork * | | 755 | struct rumpclient_fork * |
757 | rumpclient_prefork(void) | | 756 | rumpclient_prefork(void) |
758 | { | | 757 | { |
759 | struct rumpclient_fork *rpf; | | 758 | struct rumpclient_fork *rpf; |
| | | 759 | sigset_t omask; |
760 | void *resp; | | 760 | void *resp; |
761 | int rv; | | 761 | int rv; |
762 | | | 762 | |
| | | 763 | pthread_sigmask(SIG_SETMASK, &fullset, &omask); |
763 | rpf = malloc(sizeof(*rpf)); | | 764 | rpf = malloc(sizeof(*rpf)); |
764 | if (rpf == NULL) | | 765 | if (rpf == NULL) |
765 | return NULL; | | 766 | return NULL; |
766 | | | 767 | |
767 | if ((rv = prefork_req(&clispc, &resp)) != 0) { | | 768 | if ((rv = prefork_req(&clispc, &omask, &resp)) != 0) { |
768 | free(rpf); | | 769 | free(rpf); |
769 | errno = rv; | | 770 | errno = rv; |
770 | return NULL; | | 771 | rpf = NULL; |
| | | 772 | goto out; |
771 | } | | 773 | } |
772 | | | 774 | |
773 | memcpy(rpf->fork_auth, resp, sizeof(rpf->fork_auth)); | | 775 | memcpy(rpf->fork_auth, resp, sizeof(rpf->fork_auth)); |
774 | free(resp); | | 776 | free(resp); |
775 | | | 777 | |
| | | 778 | out: |
| | | 779 | pthread_sigmask(SIG_SETMASK, &omask, NULL); |
776 | return rpf; | | 780 | return rpf; |
777 | } | | 781 | } |
778 | | | 782 | |
779 | int | | 783 | int |
780 | rumpclient_fork_init(struct rumpclient_fork *rpf) | | 784 | rumpclient_fork_init(struct rumpclient_fork *rpf) |
781 | { | | 785 | { |
782 | int error; | | 786 | int error; |
783 | int osock; | | 787 | int osock; |
784 | | | 788 | |
785 | osock = clispc.spc_fd; | | 789 | osock = clispc.spc_fd; |
786 | memset(&clispc, 0, sizeof(clispc)); | | 790 | memset(&clispc, 0, sizeof(clispc)); |
787 | clispc.spc_fd = osock; | | 791 | clispc.spc_fd = osock; |
788 | | | 792 | |