post.c 1.9 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980
  1. /*
  2. * This file is part of the UCB release of Plan 9. It is subject to the license
  3. * terms in the LICENSE file found in the top-level directory of this
  4. * distribution and at http://akaros.cs.berkeley.edu/files/Plan9License. No
  5. * part of the UCB release of Plan 9, including this file, may be copied,
  6. * modified, propagated, or distributed except according to the terms contained
  7. * in the LICENSE file.
  8. */
  9. #include <u.h>
  10. #include <libc.h>
  11. #include <fcall.h>
  12. #include <thread.h>
  13. #include <9p.h>
  14. #include <auth.h>
  15. static void postproc(void*);
  16. void
  17. _postmountsrv(Srv *s, char *name, char *mtpt, int flag)
  18. {
  19. int fd[2];
  20. if(!s->nopipe){
  21. if(pipe(fd) < 0)
  22. sysfatal("pipe: %r");
  23. s->infd = s->outfd = fd[1];
  24. s->srvfd = fd[0];
  25. }
  26. if(name)
  27. if(postfd(name, s->srvfd) < 0)
  28. sysfatal("postfd %s: %r", name);
  29. if(_forker == nil)
  30. sysfatal("no forker");
  31. _forker(postproc, s, RFNAMEG);
  32. /*
  33. * Normally the server is posting as the last thing it does
  34. * before exiting, so the correct thing to do is drop into
  35. * a different fd space and close the 9P server half of the
  36. * pipe before trying to mount the kernel half. This way,
  37. * if the file server dies, we don't have a ref to the 9P server
  38. * half of the pipe. Then killing the other procs will drop
  39. * all the refs on the 9P server half, and the mount will fail.
  40. * Otherwise the mount hangs forever.
  41. *
  42. * Libthread in general and acme win in particular make
  43. * it hard to make this fd bookkeeping work out properly,
  44. * so leaveinfdopen is a flag that win sets to opt out of this
  45. * safety net.
  46. */
  47. if(!s->leavefdsopen){
  48. rfork(RFFDG);
  49. rendezvous(0, 0);
  50. close(s->infd);
  51. if(s->infd != s->outfd)
  52. close(s->outfd);
  53. }
  54. if(mtpt){
  55. if(amount(s->srvfd, mtpt, flag, "") == -1)
  56. sysfatal("mount %s: %r", mtpt);
  57. }else
  58. close(s->srvfd);
  59. }
  60. static void
  61. postproc(void *v)
  62. {
  63. Srv *s;
  64. s = v;
  65. if(!s->leavefdsopen){
  66. rfork(RFNOTEG);
  67. rendezvous(0, 0);
  68. close(s->srvfd);
  69. }
  70. srv(s);
  71. }