toddb@tekcrl.UUCP (Todd Brunhoff) (08/07/86)
In article <230@dcdwest.UUCP> phb@dcdwest.UUCP (Peter H. Berens) writes: >We are running Todd Brunhoff's remote file system (RFS) code on our >4.2 BSD VAXen. I should also mention that we are also running >CHAOS net on our system as well. It seems that certain operations >cause the system to permanently allocate an mbuf for data and never >give it up. This can be made to happen under the two following >circumstances: > % cd /REMOTESYS/a/b/c; tar x > or > % ls > /REMOTESYS/a/b/c >In the case of the tar extraction, it is very easy to completely >run out of mbufs in short order causing the system to eventually crash. >The other cases (shell output redirection) lose mbufs so slowly that >you can go for many weeks before running out. > >Has anyone else had this experience? Are any fixes known other >than the ones distributed by Todd? Has anyone else sucessfully >run CHOAS net and this software at the same time? > >Thanks in advance for any information. > Pete Berens > ITT DCDWEST > San Diego, CA > 619-578-3080 x240 Hats off to Bill Sommerfeld at MIT for pointing this out to me. The problem is quite clear: for the system calls ioctl() and utimes(), the message to be sent to the server is composed in an mbuf, but never sent, because the former has never been implemented and because the latter erroneously called rmt_noop(). The program "ls" uses ioctl() and the program "tar" uses utimes(). The fix is just as simple, and diffs are included here. The idea is that rmt_noop() is really a bad choice in the remote_syscall[] table. For each entry there is a "general" and a "specific" processing routine; the general routine will call the specific routine, unless it knows it is not necessary. Well, any general routine that never calls the specific routine should probably have rmt_error() listed as the specific routine. At any rate, the spirit of the fix is to completely remove any reference to rmt_noop(), and make sure that rmt_ioctl() and rmt_error() always free the mbufs passed to them. Incidentally, the fix below also fixes a problem with utimes(), so that commands like tar xp never worked right; the modification and access times were never set. ============ remote/rmt_data_template ================================== RCS file: RCS/rmt_data_template,v retrieving revision 2.0 diff -c -r2.0 rmt_data_template *** /tmp/,RCSt1008552 Wed Aug 6 16:05:56 1986 --- rmt_data_template Wed Aug 6 15:37:46 1986 *************** *** 41,47 rmt_ioctl(), rmt_lseek(), rmt_mknod(), - rmt_noop(), rmt_onearg(), rmt_open(), rmt_readlink(), --- 41,46 ----- rmt_ioctl(), rmt_lseek(), rmt_mknod(), rmt_onearg(), rmt_open(), rmt_readlink(), *************** *** 71,77 * general specific flags to follow call before * rmt_fin() symlinks real syscall */ ! { remote_fork, rmt_noop, RFLG_INFO, FALSE, TRUE }, /* RSYS_fork */ { remote_fd, rmt_datafin, RFLG_RD, FALSE, TRUE }, /* RSYS_read */ { remote_fd, rmt_datafin, RFLG_WR, FALSE, TRUE }, /* RSYS_write */ { remote_path1, rmt_open, 0, TRUE, FALSE }, /* RSYS_open */ --- 70,76 ----- * general specific flags to follow call before * rmt_fin() symlinks real syscall */ ! { remote_fork, rmt_error, RFLG_INFO, FALSE, TRUE }, /* RSYS_fork */ { remote_fd, rmt_datafin, RFLG_RD, FALSE, TRUE }, /* RSYS_read */ { remote_fd, rmt_datafin, RFLG_WR, FALSE, TRUE }, /* RSYS_write */ { remote_path1, rmt_open, 0, TRUE, FALSE }, /* RSYS_open */ *************** *** 77,83 { remote_path1, rmt_open, 0, TRUE, FALSE }, /* RSYS_open */ { remote_fd, rmt_onearg, RFLG_INFO, FALSE, TRUE }, /* RSYS_close */ { remote_path1, rmt_open, 0, TRUE, FALSE }, /* RSYS_creat */ ! { remote_path2, rmt_noop, 0, FALSE, FALSE }, /* RSYS_link */ { remote_path1, rmt_onearg, 0, FALSE, FALSE }, /* RSYS_unlink */ { remote_path1, rmt_chdir, 0, TRUE, FALSE }, /* RSYS_chdir */ { remote_path1, rmt_mknod, 0, FALSE, FALSE }, /* RSYS_mknod */ --- 76,82 ----- { remote_path1, rmt_open, 0, TRUE, FALSE }, /* RSYS_open */ { remote_fd, rmt_onearg, RFLG_INFO, FALSE, TRUE }, /* RSYS_close */ { remote_path1, rmt_open, 0, TRUE, FALSE }, /* RSYS_creat */ ! { remote_path2, rmt_error, 0, FALSE, FALSE }, /* RSYS_link */ { remote_path1, rmt_onearg, 0, FALSE, FALSE }, /* RSYS_unlink */ { remote_path1, rmt_chdir, 0, TRUE, FALSE }, /* RSYS_chdir */ { remote_path1, rmt_mknod, 0, FALSE, FALSE }, /* RSYS_mknod */ *************** *** 89,95 { remote_path1, rmt_stat, 0, TRUE, FALSE }, /* RSYS_access */ { remote_fd, rmt_dup, 0, FALSE, TRUE }, /* RSYS_dup */ { remote_fd, rmt_ioctl, 0, FALSE, TRUE }, /* RSYS_ioctl */ ! { remote_path2, rmt_noop, 0, TRUE, FALSE }, /* RSYS_symlink */ { remote_path1, rmt_readlink, RFLG_RD, FALSE, FALSE }, /* RSYS_readlink */ { remote_fd, rmt_stat, 0, FALSE, TRUE }, /* RSYS_fstat */ { remote_fd, rmt_dup2, 0, FALSE, TRUE }, /* RSYS_dup2 */ --- 88,94 ----- { remote_path1, rmt_stat, 0, TRUE, FALSE }, /* RSYS_access */ { remote_fd, rmt_dup, 0, FALSE, TRUE }, /* RSYS_dup */ { remote_fd, rmt_ioctl, 0, FALSE, TRUE }, /* RSYS_ioctl */ ! { remote_path2, rmt_error, 0, TRUE, FALSE }, /* RSYS_symlink */ { remote_path1, rmt_readlink, RFLG_RD, FALSE, FALSE }, /* RSYS_readlink */ { remote_fd, rmt_stat, 0, FALSE, TRUE }, /* RSYS_fstat */ { remote_fd, rmt_dup2, 0, FALSE, TRUE }, /* RSYS_dup2 */ *************** *** 101,107 FALSE, TRUE },/* RSYS_writev */ { remote_fd, rmt_chown, 0, FALSE, TRUE }, /* RSYS_fchown */ { remote_fd, rmt_chmod, 0, FALSE, TRUE }, /* RSYS_fchmod */ ! { remote_path2, rmt_noop, 0, TRUE, FALSE }, /* RSYS_rename */ { remote_path1, rmt_truncate, 0, TRUE, FALSE }, /* RSYS_truncate */ { remote_fd, rmt_truncate, 0, FALSE, TRUE }, /* RSYS_ftruncate */ { remote_fd, rmt_flock, 0, FALSE, TRUE }, /* RSYS_flock */ --- 100,106 ----- FALSE, TRUE },/* RSYS_writev */ { remote_fd, rmt_chown, 0, FALSE, TRUE }, /* RSYS_fchown */ { remote_fd, rmt_chmod, 0, FALSE, TRUE }, /* RSYS_fchmod */ ! { remote_path2, rmt_error, 0, TRUE, FALSE }, /* RSYS_rename */ { remote_path1, rmt_truncate, 0, TRUE, FALSE }, /* RSYS_truncate */ { remote_fd, rmt_truncate, 0, FALSE, TRUE }, /* RSYS_ftruncate */ { remote_fd, rmt_flock, 0, FALSE, TRUE }, /* RSYS_flock */ *************** *** 107,115 { remote_fd, rmt_flock, 0, FALSE, TRUE }, /* RSYS_flock */ { remote_path1, rmt_mknod, 0, FALSE, FALSE }, /* RSYS_mkdir */ { remote_path1, rmt_onearg, 0, FALSE, FALSE }, /* RSYS_rmdir */ ! { remote_path1, rmt_noop, 0, TRUE, FALSE }, /* RSYS_utimes */ ! { remote_exit, rmt_noop, RFLG_INFO,FALSE, TRUE }, /* RSYS_exit */ ! { remote_fork, rmt_noop, RFLG_INFO, FALSE, TRUE }, /* RSYS_vfork */ { remote_path1, rmt_execinfo, 0, TRUE, FALSE }, /* RSYS_execinfo */ { rmt_error, rmt_noop, 0, FALSE, FALSE }, /* RSYS_execread */ { remote_path1, rmt_error, 0, TRUE, FALSE }, /* RSYS_execve */ --- 106,114 ----- { remote_fd, rmt_flock, 0, FALSE, TRUE }, /* RSYS_flock */ { remote_path1, rmt_mknod, 0, FALSE, FALSE }, /* RSYS_mkdir */ { remote_path1, rmt_onearg, 0, FALSE, FALSE }, /* RSYS_rmdir */ ! { remote_path1, rmt_utimes, 0, TRUE, FALSE }, /* RSYS_utimes */ ! { remote_exit, rmt_error, RFLG_INFO, FALSE, TRUE }, /* RSYS_exit */ ! { remote_fork, rmt_error, RFLG_INFO, FALSE, TRUE }, /* RSYS_vfork */ { remote_path1, rmt_execinfo, 0, TRUE, FALSE }, /* RSYS_execinfo */ { rmt_error, rmt_error, 0, FALSE, FALSE }, /* RSYS_execread */ { remote_path1, rmt_error, 0, TRUE, FALSE }, /* RSYS_execve */ *************** *** 111,117 { remote_exit, rmt_noop, RFLG_INFO,FALSE, TRUE }, /* RSYS_exit */ { remote_fork, rmt_noop, RFLG_INFO, FALSE, TRUE }, /* RSYS_vfork */ { remote_path1, rmt_execinfo, 0, TRUE, FALSE }, /* RSYS_execinfo */ ! { rmt_error, rmt_noop, 0, FALSE, FALSE }, /* RSYS_execread */ { remote_path1, rmt_error, 0, TRUE, FALSE }, /* RSYS_execve */ { rmt_error, rmt_noop, 0, FALSE, FALSE }, /* RSYS_nosys */ { rmt_error, rmt_noop, 0, FALSE, FALSE }, /* RSYS_qlseek */ --- 110,116 ----- { remote_exit, rmt_error, RFLG_INFO, FALSE, TRUE }, /* RSYS_exit */ { remote_fork, rmt_error, RFLG_INFO, FALSE, TRUE }, /* RSYS_vfork */ { remote_path1, rmt_execinfo, 0, TRUE, FALSE }, /* RSYS_execinfo */ ! { rmt_error, rmt_error, 0, FALSE, FALSE }, /* RSYS_execread */ { remote_path1, rmt_error, 0, TRUE, FALSE }, /* RSYS_execve */ { rmt_error, rmt_error, 0, FALSE, FALSE }, /* RSYS_nosys */ { rmt_error, rmt_error, 0, FALSE, FALSE }, /* RSYS_qlseek */ *************** *** 113,120 { remote_path1, rmt_execinfo, 0, TRUE, FALSE }, /* RSYS_execinfo */ { rmt_error, rmt_noop, 0, FALSE, FALSE }, /* RSYS_execread */ { remote_path1, rmt_error, 0, TRUE, FALSE }, /* RSYS_execve */ ! { rmt_error, rmt_noop, 0, FALSE, FALSE }, /* RSYS_nosys */ ! { rmt_error, rmt_noop, 0, FALSE, FALSE }, /* RSYS_qlseek */ }; struct remoteinfo remote_info[ R_MAXSYS ]; --- 112,119 ----- { remote_path1, rmt_execinfo, 0, TRUE, FALSE }, /* RSYS_execinfo */ { rmt_error, rmt_error, 0, FALSE, FALSE }, /* RSYS_execread */ { remote_path1, rmt_error, 0, TRUE, FALSE }, /* RSYS_execve */ ! { rmt_error, rmt_error, 0, FALSE, FALSE }, /* RSYS_nosys */ ! { rmt_error, rmt_error, 0, FALSE, FALSE }, /* RSYS_qlseek */ }; struct remoteinfo remote_info[ R_MAXSYS ]; ====================== remote/rmt_syscall1.c ======================= RCS file: RCS/rmt_syscall1.c,v retrieving revision 2.0 diff -c -r2.0 rmt_syscall1.c *** /tmp/,RCSt1008677 Wed Aug 6 16:07:29 1986 --- rmt_syscall1.c Wed Aug 6 15:36:57 1986 *************** *** 227,234 * routine for handling an error. We should never get here... but if we * do..... */ ! rmt_error(sysnum) ! int sysnum; { debug1("error reached\n"); return(EINVAL); --- 227,235 ----- * routine for handling an error. We should never get here... but if we * do..... */ ! rmt_error(sysindex, m) ! long sysindex; ! struct mbuf *m; { m_freem(m); printf("rmt_error() reached\n"); *************** *** 230,235 rmt_error(sysnum) int sysnum; { ! debug1("error reached\n"); return(EINVAL); } --- 231,237 ----- long sysindex; struct mbuf *m; { ! m_freem(m); ! printf("rmt_error() reached\n"); return(EINVAL); } ======================= remote/rmt_syscall2.c ========================== RCS file: RCS/rmt_syscall2.c,v retrieving revision 2.0 diff -c -r2.0 rmt_syscall2.c *** /tmp/,RCSt1008789 Wed Aug 6 16:08:42 1986 --- rmt_syscall2.c Wed Aug 6 15:37:21 1986 *************** *** 114,119 struct mbuf *m; char *argp; { /* * for now always fail. --- 114,120 ----- struct mbuf *m; char *argp; { + m_freem(m); /* * for now always fail. *************** *** 208,215 */ return( rmt_msgfin(sysindex, m, 0) ); } - - rmt_noop() { return; } /* * Remote mkdir() and rmdir() and unlink() and fsync() and close() --- 209,214 ----- */ return( rmt_msgfin(sysindex, m, 0) ); } /* * Remote mkdir() and rmdir() and unlink() and fsync() and close()