RFS woes... with fix

Todd Brunhoff toddb at tekcrl.UUCP
Thu Aug 7 09:13:31 AEST 1986


In article <230 at dcdwest.UUCP> phb at 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()



More information about the Comp.unix.wizards mailing list