A patch for /sys/src/cmd/cpu.c This patch is designed to be upper compatible to current cpu.c 1. execution local binary cpu -c localcommand exits. now perm bit of /dev/cpunote is 664 writing some message to /dev/cpunote will terminate exportfs (we should restrict the message such as "finished", but I am lazy) 2. grid capable now "user" is taken from /dev/user and the user's home and profile is assigned as follows: (using rc notation) if (! test -e /usr/$user) home=/usr/none if (! test -e $home/lib/profile) bind /usr/none $home thus grid user will execute /usr/none/lib/profile 3. added some log information 4. tiny bug fix for usage message -p to -P Notes: Sat Jul 9 07:47:06 EDT 2005 rsc I applied a different set of changes. I fixed -P. I changed the notefs process to postnote once the remote side closes /dev/cpunote, so the server need not write the "finished" note. This seemed cleaner and it only requires running a new cpu client. I'm not convinced that the so-called grid home directory logic is correct or that it belongs in cpu. I don't know what the right answer is yet. I log into machines hwere I don't have a home directory and I'm pretty happy with the current behavior. I don't want none's home directory bound on top of mine just because I don't have a profile. What if I'm logging in to run /sys/lib/newuser?! Instead of testing if(dirstat(home)==nil) you could just do if(access(home, AEXIST) >= 0), which doesn't leak. Instead of explicitly opening the notepg file, you can use postnote(PNGROUP, exportfspid, "kill"). Reference: /n/sources/patch/applied/cpu-update Date: Sat Jul 9 12:06:49 CES 2005 Signed-off-by: arisawa@ar.aichi-u.ac.jp Reviewed-by: rsc --- /sys/src/cmd/cpu.c Sat Jul 9 12:08:28 2005 +++ /sys/src/cmd/cpu.c Sat Jul 9 12:06:38 2005 @@ -38,6 +38,9 @@ char *exportfs = "/bin/exportfs"; char *ealgs = "rc4_256 sha1"; + +int exportfspid; + /* message size for exportfs; may be larger so we can do big graphics in CPU window */ int msgsize = Maxfdata+IOHDRSZ; @@ -70,7 +73,7 @@ void usage(void) { - fprint(2, "usage: cpu [-h system] [-a authmethod] [-e 'crypt hash'] [-k keypattern] [-p patternfile] [-c cmd args ...]\n"); + fprint(2, "usage: cpu [-h system] [-a authmethod] [-e 'crypt hash'] [-k keypattern] [-P patternfile] [-c cmd args ...]\n"); exits("usage"); } int fdd; @@ -266,6 +269,7 @@ remoteside(int old) { char user[MaxStr], home[MaxStr], buf[MaxStr], xdir[MaxStr], cmd[MaxStr]; + char profile[MaxStr]; int i, n, fd, badchdir, gotcmd; rfork(RFENVG); @@ -287,9 +291,11 @@ fatal(1, "srvauth"); /* Set environment values for the user */ + snprint(user,sizeof(user), "%s", getuser()); putenv("user", user); - sprint(home, "/usr/%s", user); + snprint(home, sizeof(home),"/usr/%s", user); putenv("home", home); + syslog(0,"cpu", "%s login", user); /* Now collect invoking cpu's current directory or possibly a command */ gotcmd = 0; @@ -312,6 +318,8 @@ chdir(home); } + putenv("xdir",xdir); + /* Start the gnot serving its namespace */ writestr(fd, "FS", "FS", 0); writestr(fd, "/", "exportfs dir", 0); @@ -347,6 +355,18 @@ if(badchdir) print("cpu: failed to chdir to '%s'\n", xdir); + /* don't mind memory leak here */ + if(dirstat(home) == nil){ + snprint(home,sizeof(home),"/usr/none"); + putenv("home", home); + } + + snprint(profile,sizeof(profile),"%s/lib/profile",home); + fd = open(profile,OREAD); + if(fd < 0) + bind("/usr/none/", home, MREPL); + close(fd); + if(gotcmd) execl("/bin/rc", "rc", "-lc", cmd, 0); else @@ -687,12 +707,22 @@ } /* original proc waits for shell proc to die and kills note proc */ + + fprint(2, "waiting rc to finish\n"); for(;;){ n = waitpid(); if(n < 0 || n == pid) break; } + + fd = open("/mnt/term/dev/cpunote",OWRITE); + if(fd < 0) + fprint(2, "/mnt/term/dev/cpunote not open: %r\n"); + else + write(fd,"finished",8); + postnote(PNPROC, notepid, "kill"); + _exits(0); } @@ -711,7 +741,7 @@ } fstab[] = { [Qdir] { ".", {Qdir, 0, QTDIR}, DMDIR|0555 }, - [Qcpunote] { "cpunote", {Qcpunote, 0}, 0444 }, + [Qcpunote] { "cpunote", {Qcpunote, 0}, 0664 }, }; typedef struct Note Note; @@ -995,10 +1025,6 @@ f.nwqid = i; break; case Topen: - if(f.mode != OREAD){ - f.type = Rerror; - f.ename = Eperm; - } f.qid = fstab[fid->file].qid; break; case Tcreate: @@ -1011,6 +1037,8 @@ doreply = 0; break; case Twrite: + if(fid->file == Qcpunote) + goto err; f.type = Rerror; f.ename = Eperm; break; @@ -1039,6 +1067,14 @@ if(dbg) fprint(2, "notefs exiting: %r\n"); close(fd); + + snprint((char*)buf,sizeof buf,"/proc/%d/notepg", exportfspid); + fd = open((char*)buf,OWRITE); + /* fd < 0 in regular case */ + if(fd > 0){ + write(fd,"kill", 4); + close(fd); + } } char notebuf[ERRMAX]; @@ -1062,7 +1098,6 @@ void lclnoteproc(int netfd) { - int exportfspid; Waitmsg *w; Note *np; int pfd[2];