sshnet: fix fork race conditions
sshreadproc() needs to be started after opening the sshfd file descriptor. fsnetproc() needs to run in the same filedescriptor group as the fileserver.
This commit is contained in:
parent
2c53dd32b5
commit
59fdb3a12c
1 changed files with 30 additions and 24 deletions
|
@ -33,7 +33,7 @@ enum
|
|||
#define TYPE(path) ((int)(path) & 0xFF)
|
||||
#define NUM(path) ((uint)(path)>>8)
|
||||
|
||||
Channel *ssherrchan; /* chan(char*) */
|
||||
int sessionopen = 0;
|
||||
Channel *sshmsgchan; /* chan(Msg*) */
|
||||
Channel *fsreqchan; /* chan(Req*) */
|
||||
Channel *fsreqwaitchan; /* chan(nil) */
|
||||
|
@ -125,7 +125,7 @@ struct Msg
|
|||
|
||||
int nclient;
|
||||
Client **client;
|
||||
char *mtpt;
|
||||
char *mtpt, *service;
|
||||
int sshfd;
|
||||
|
||||
int
|
||||
|
@ -1148,7 +1148,7 @@ handlemsg(Msg *m)
|
|||
if(unpack(m, "_uuuu", &chan, &n, &win, &pkt) < 0)
|
||||
break;
|
||||
if(chan == SESSIONCHAN){
|
||||
sendp(ssherrchan, nil);
|
||||
sessionopen++;
|
||||
break;
|
||||
}
|
||||
c = getclient(chan);
|
||||
|
@ -1173,7 +1173,7 @@ handlemsg(Msg *m)
|
|||
break;
|
||||
s = smprint("%.*s", utfnlen(s, n), s);
|
||||
if(chan == SESSIONCHAN){
|
||||
sendp(ssherrchan, s);
|
||||
sysfatal("ssh failed: %s", s);
|
||||
break;
|
||||
}
|
||||
c = getclient(chan);
|
||||
|
@ -1313,6 +1313,12 @@ fsdestroyfid(Fid *fid)
|
|||
recvp(fsclunkwaitchan);
|
||||
}
|
||||
|
||||
static void
|
||||
startup(Srv*)
|
||||
{
|
||||
proccreate(fsnetproc, nil, 8*1024);
|
||||
}
|
||||
|
||||
void
|
||||
takedown(Srv*)
|
||||
{
|
||||
|
@ -1321,7 +1327,7 @@ takedown(Srv*)
|
|||
|
||||
Srv fs =
|
||||
{
|
||||
.attach= fssend,
|
||||
.attach= fssend,
|
||||
.destroyfid= fsdestroyfid,
|
||||
.walk1= fswalk1,
|
||||
.open= fssend,
|
||||
|
@ -1329,6 +1335,7 @@ Srv fs =
|
|||
.write= fssend,
|
||||
.stat= fssend,
|
||||
.flush= fssend,
|
||||
.start= startup,
|
||||
.end= takedown,
|
||||
};
|
||||
|
||||
|
@ -1356,9 +1363,9 @@ startssh(void *)
|
|||
void
|
||||
ssh(int argc, char *argv[])
|
||||
{
|
||||
Alt a[3];
|
||||
Alt a[4];
|
||||
Waitmsg *w;
|
||||
char *e;
|
||||
Msg *m;
|
||||
|
||||
sshargc = argc + 2;
|
||||
sshargv = emalloc9p(sizeof(char *) * (sshargc + 1));
|
||||
|
@ -1366,11 +1373,14 @@ ssh(int argc, char *argv[])
|
|||
sshargv[1] = "-X";
|
||||
memcpy(sshargv + 2, argv, argc * sizeof(char *));
|
||||
|
||||
pipe(pfd);
|
||||
if(pipe(pfd) < 0)
|
||||
sysfatal("pipe: %r");
|
||||
sshfd = pfd[0];
|
||||
procrfork(startssh, nil, 8*1024, RFFDG|RFNOTEG|RFNAMEG);
|
||||
procrfork(startssh, nil, 8*1024, RFFDG|RFNOTEG);
|
||||
close(pfd[1]);
|
||||
|
||||
procrfork(sshreadproc, nil, 8*1024, RFFDG|RFNOTEG);
|
||||
|
||||
sendmsg(pack(nil, "bsuuu", MSG_CHANNEL_OPEN,
|
||||
"session", 7,
|
||||
SESSIONCHAN,
|
||||
|
@ -1381,18 +1391,18 @@ ssh(int argc, char *argv[])
|
|||
a[0].c = threadwaitchan();
|
||||
a[0].v = &w;
|
||||
a[1].op = CHANRCV;
|
||||
a[1].c = ssherrchan;
|
||||
a[1].v = &e;
|
||||
a[1].c = sshmsgchan;
|
||||
a[1].v = &m;
|
||||
a[2].op = CHANEND;
|
||||
|
||||
switch(alt(a)){
|
||||
case 0:
|
||||
sysfatal("ssh failed: %s", w->msg);
|
||||
case 1:
|
||||
if(e != nil)
|
||||
sysfatal("ssh failed: %s", e);
|
||||
while(!sessionopen){
|
||||
switch(alt(a)){
|
||||
case 0:
|
||||
sysfatal("ssh failed: %s", w->msg);
|
||||
case 1:
|
||||
handlemsg(m);
|
||||
}
|
||||
}
|
||||
chanclose(ssherrchan);
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -1405,8 +1415,6 @@ usage(void)
|
|||
void
|
||||
threadmain(int argc, char **argv)
|
||||
{
|
||||
char *service;
|
||||
|
||||
fmtinstall('H', encodefmt);
|
||||
|
||||
mtpt = "/net";
|
||||
|
@ -1429,17 +1437,15 @@ threadmain(int argc, char **argv)
|
|||
usage();
|
||||
|
||||
time0 = time(0);
|
||||
ssherrchan = chancreate(sizeof(char*), 0);
|
||||
sshmsgchan = chancreate(sizeof(Msg*), 16);
|
||||
fsreqchan = chancreate(sizeof(Req*), 0);
|
||||
fsreqwaitchan = chancreate(sizeof(void*), 0);
|
||||
fsclunkchan = chancreate(sizeof(Fid*), 0);
|
||||
fsclunkwaitchan = chancreate(sizeof(void*), 0);
|
||||
procrfork(fsnetproc, nil, 8*1024, RFNAMEG|RFNOTEG);
|
||||
procrfork(sshreadproc, nil, 8*1024, RFNAMEG|RFNOTEG);
|
||||
|
||||
ssh(argc, argv);
|
||||
|
||||
threadpostmountsrv(&fs, service, mtpt, MREPL);
|
||||
exits(0);
|
||||
|
||||
threadexits(nil);
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue