ref: 59fdb3a12cd1e6ec9f65ca014c23fd27bea45245
parent: 2c53dd32b5cf88daad2bad02a058af414275322d
author: cinap_lenrek <[email protected]>
date: Sat Mar 7 23:54:37 EST 2020
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.
--- a/sys/src/cmd/sshnet.c
+++ b/sys/src/cmd/sshnet.c
@@ -33,7 +33,7 @@
#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 @@
int nclient;
Client **client;
-char *mtpt;
+char *mtpt, *service;
int sshfd;
int
@@ -1148,7 +1148,7 @@
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 @@
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 @@
recvp(fsclunkwaitchan);
}
+static void
+startup(Srv*)
+{
+ proccreate(fsnetproc, nil, 8*1024);
+}
+
void
takedown(Srv*)
{
@@ -1321,7 +1327,7 @@
Srv fs =
{
-.attach= fssend,
+.attach= fssend,
.destroyfid= fsdestroyfid,
.walk1= fswalk1,
.open= fssend,
@@ -1329,6 +1335,7 @@
.write= fssend,
.stat= fssend,
.flush= fssend,
+.start= startup,
.end= takedown,
};
@@ -1356,9 +1363,9 @@
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 @@
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 @@
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 @@
void
threadmain(int argc, char **argv)
{
- char *service;
-
fmtinstall('H', encodefmt);
mtpt = "/net";
@@ -1429,17 +1437,15 @@
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);
}