Subject: another patch for compat/ultrix/ultrix_misc.c
To: None <port-pmax@sun-lamp.cs.berkeley.edu>
From: Jonathan Stone <jonathan@DSG.Stanford.EDU>
List: port-pmax
Date: 08/23/1994 18:27:56
This change to compat/ultrix/ultrix_misc.c removes lots of the cruft
I'd put in for debugging, and recognises when Ultrix mount(8) is
trying to do a mount on path "/", and if so, ors MNT_UPDATE into the
flags passed to native mount. This lets me mount a root partition
read-write with Ultrix's mount.

If someone wants to scan the flags Ultrix passes to mount,
and translate them to NetBSD mount flags, that'd be great...


*** ultrix_misc.c.DIST	Mon Aug  1 13:22:03 1994
--- ultrix_misc.c	Tue Aug 23 18:17:57 1994
***************
*** 260,274 ****
  	return (unmount(p, uap, retval));
  }
  
- #define	SUNM_RDONLY	0x01	/* mount fs read-only */
- #define	SUNM_NOSUID	0x02	/* mount fs with setuid disallowed */
- #define	SUNM_NEWTYPE	0x04	/* type is string (char *), not int */
- #define	SUNM_GRPID	0x08	/* (bsd semantics; ignored) */
- #define	SUNM_REMOUNT	0x10	/* update existing mount */
- #define	SUNM_NOSUB	0x20	/* prevent submounts (rejected) */
- #define	SUNM_MULTI	0x40	/* (ignored) */
- #define	SUNM_SYS5	0x80	/* Sys 5-specific semantics (rejected) */
  
  struct	sun_nfs_args {
  	struct	sockaddr_in *addr;	/* file server address */
  	caddr_t	fh;			/* file handle to be mounted */
--- 260,281 ----
  	return (unmount(p, uap, retval));
  }
  
  
+ #define ULT_NM_RONLY    0x0001  /* mount read-only */
+ #define ULT_NM_SOFT     0x0002  /* soft mount (hard is default) */
+ #define ULT_NM_WSIZE    0x0004  /* set write size */
+ #define ULT_NM_RSIZE    0x0008  /* set read size */
+ #define ULT_NM_TIMEO    0x0010  /* set initial timeout */
+ #define ULT_NM_RETRANS  0x0020  /* set number of request retrys */
+ #define ULT_NM_HOSTNAME 0x0040  /* set hostname for error printf */
+ #define ULT_NM_PGTHRESH 0x0080  /* set page threshold for exec */
+ #define ULT_NM_INT      0x0100  /* allow hard mount keyboard interrupts */
+ #define ULT_NM_NOAC     0x0200  /* don't cache attributes */
+ 									
+ 
+ #define ULT_FSTYPE_UFS 1
+ #define ULT_FSTYPE_NFS 5
+ 
  struct	sun_nfs_args {
  	struct	sockaddr_in *addr;	/* file server address */
  	caddr_t	fh;			/* file handle to be mounted */
***************
*** 286,358 ****
  	struct	pathcnf *pathconf;	/* static pathconf kludge */
  };
  
! struct sun_mount_args {
  	char	*type;
! 	char	*dir;
  	int	flags;
  	caddr_t	data;
  };
! sun_mount(p, uap, retval)
  	struct proc *p;
! 	struct sun_mount_args *uap;
  	int *retval;
  {
! 	int oflags = uap->flags, nflags, error;
  	extern char sigcode[], esigcode[];
  	char fsname[MFSNAMELEN];
  
  #define	szsigcode	(esigcode - sigcode)
  
! 	if (oflags & (SUNM_NOSUB | SUNM_SYS5))
  		return (EINVAL);
! 	if ((oflags & SUNM_NEWTYPE) == 0)
! 		return (EINVAL);
! 	nflags = 0;
! 	if (oflags & SUNM_RDONLY)
! 		nflags |= MNT_RDONLY;
! 	if (oflags & SUNM_NOSUID)
! 		nflags |= MNT_NOSUID;
! 	if (oflags & SUNM_REMOUNT)
! 		nflags |= MNT_UPDATE;
! 	uap->flags = nflags;
  
! 	if (error = copyinstr((caddr_t)uap->type, fsname, sizeof fsname, (u_int *)0))
  		return (error);
  
! 	if (strcmp(fsname, "4.2") == 0) {
! 		uap->type = (caddr_t)ALIGN(PS_STRINGS - szsigcode - STACKGAPLEN);
! 		if (error = copyout("ufs", uap->type, sizeof("ufs")))
! 			return (error);
! 	} else if (strcmp(fsname, "nfs") == 0) {
! 		struct sun_nfs_args sna;
! 		struct sockaddr_in sain;
  		struct nfs_args na;
! 		struct sockaddr sa;
  
! 		if (error = copyin(uap->data, &sna, sizeof sna))
  			return (error);
! 		if (error = copyin(sna.addr, &sain, sizeof sain))
  			return (error);
! 		bcopy(&sain, &sa, sizeof sa);
! 		sa.sa_len = sizeof(sain);
! 		uap->data = (caddr_t)ALIGN(PS_STRINGS - szsigcode - STACKGAPLEN);
! 		na.addr = (struct sockaddr *)((int)uap->data + sizeof na);
  		na.sotype = SOCK_DGRAM;
  		na.proto = IPPROTO_UDP;
! 		na.fh = (nfsv2fh_t *)sna.fh;
! 		na.flags = sna.flags;
! 		na.wsize = sna.wsize;
! 		na.rsize = sna.rsize;
! 		na.timeo = sna.timeo;
! 		na.retrans = sna.retrans;
! 		na.hostname = sna.hostname;
! 
! 		if (error = copyout(&sa, na.addr, sizeof sa))
  			return (error);
! 		if (error = copyout(&na, uap->data, sizeof na))
  			return (error);
  	}
! 	return (mount(p, uap, retval));
  }
  
  #if defined(NFSCLIENT)
--- 293,456 ----
  	struct	pathcnf *pathconf;	/* static pathconf kludge */
  };
  
! /*
!  * Arguments to native mount syscall. See kern/vfs_syscalls.c
!  */
! struct mount_args {
  	char	*type;
! 	char	*path;
  	int	flags;
  	caddr_t	data;
  };
! 
! 
! /* Arguments to Ultrix mount(2) */
! 
! struct ult_mount_args {
! 	char	*special;
! 	char	*dir;
! 	int	rdonly, type;
! 	caddr_t data;
! };
! 
! /* Old-style inet sockaddr (no len field) as passed to Ultrix mount(2) */
! struct osockaddr_in {
! 	short   sin_family;
! 	u_short sin_port;
! 	struct  in_addr sin_addr;
! 	char    sin_zero[8];
! };
! 
! struct	ult_nfs_args {
! 	struct	osockaddr_in *addr;	/* file server address */
! 	nfsv2fh_t *fh;			/* file handle to be mounted */
! 	int	flags;			/* flags */
! 	int	wsize;			/* write size in bytes */
! 	int	rsize;			/* read size in bytes */
! 	int	timeo;			/* initial timeout in .1 secs */
! 	int	retrans;		/* times to retry send */
! 	char	*hostname;		/* server's hostname */
! 	char	*optstr;		/* string of nfs mount options*/
! 	int	gfs_flags;		/* gnode flags (ugh) */
! 	int	pg_thresh;		/* paging threshold ? */
! };
! 
! struct ult_ufs_args {
! 	u_long ufs_flags;		/* mount flags?*/
! 	u_long ufs_pgthresh;		/* minimum file size to page */
! };
! 
! int
! ultrix_mount(p, uap, retval)
  	struct proc *p;
! 	struct ult_mount_args *uap;
  	int *retval;
  {
! 	int error;
! 	int otype = uap->type;
  	extern char sigcode[], esigcode[];
  	char fsname[MFSNAMELEN];
+ 	char * fstype;
+ 	struct mount_args fixed;
  
  #define	szsigcode	(esigcode - sigcode)
+ 	caddr_t usp = (caddr_t)ALIGN(PS_STRINGS - szsigcode - STACKGAPLEN);
  
! 	fixed.flags = 0;
! 	/*
! 	 * fix up Ultrix mount codes for UFS and NFS.
! 	 * Other filesystem types (msdos, DEC ods-2) not yet done */
! 	if (otype == ULT_FSTYPE_UFS)
! 		fstype = "ufs";
! 	else if (otype == ULT_FSTYPE_NFS)
! 		fstype = "nfs";
! 	else
  		return (EINVAL);
! 
! 	if (uap->rdonly)
! 		fixed.flags |= MNT_RDONLY;
  
! 	/* copy string-ified version of mount type in user space */
! 	fixed.type = (char *)usp;
! 	if (error = copyout(fstype, fixed.type, strlen(fstype)+1)) {
  		return (error);
+ 	}
+ 	usp += strlen(fstype)+1;
  
! #ifdef later
! 	parse ultrix mount option string and set NetBSD flags
! #endif
! 	fixed.path = uap->dir;
! 
! 	if (otype == ULT_FSTYPE_UFS) {
! 		struct ufs_args ua;
! 		struct nameidata nd;
! 
! 		ua.fspec = uap->special;
! 		bzero(&ua.export, sizeof(ua.export));
! 		fixed.data = usp;
! 	
! 		if (error = copyout(&ua, fixed.data, sizeof ua)) {
! 			return(error);
! 		}
! 		/*
! 		 * Ultrix mount has no MNT_UPDATE flag.
! 		 * Attempt to see if this is the root we're mounting,
! 		 * and if so, set MNT_UPDATE so we can mount / read-write.
! 		 */
! 		fsname[0] = 0;
! 		if (error = copyinstr((caddr_t)fixed.path, fsname,
! 				      sizeof fsname, (u_int*)0))
! 			return(error);
! 		if (strcmp(fsname, "/") == 0) {
! 			fixed.flags |= MNT_UPDATE;
! 			printf("COMPAT_ULTRIX: mount with MNT_UPDATE on %s\n",
! 			       fsname);
! 		}
! 	} else if (otype == ULT_FSTYPE_NFS) {
! 		struct ult_nfs_args una;
  		struct nfs_args na;
! 		struct osockaddr_in osa;
! 		struct sockaddr_in *sap = (struct sockaddr_in *)& osa;
  
! 		bzero(&osa, sizeof(osa));
! 		bzero(&una, sizeof(una));
! 		if (error = copyin(uap->data, &una, sizeof una)) {
  			return (error);
! 		}
! 		/*
! 		 * this is the only syscall boundary the
! 		 * address of the server passes, so do backwards
! 		 * compatibility on 4.3style sockaddrs here.
! 		 */
! 		if (error = copyin(una.addr, &osa, sizeof osa)) {
! 			printf("ult_mount: nfs copyin osa\n");
  			return (error);
! 		}
! 		sap->sin_family = (u_char)osa.sin_family;
! 		sap->sin_len = sizeof(*sap);
! 		/* allocate space above caller's stack for nfs_args */
! 		fixed.data = usp;
! 		usp +=  sizeof (na);
! 		/* allocate space above caller's stack for server sockaddr */
! 		na.addr = (struct sockaddr *)usp;
! 		usp += sizeof(*sap);
! 		na.addrlen = sap->sin_len;
  		na.sotype = SOCK_DGRAM;
  		na.proto = IPPROTO_UDP;
! 		na.fh = una.fh;
! 		na.flags = /*una.flags;*/ NFSMNT_NOCONN | NFSMNT_RESVPORT;
! 		na.wsize = una.wsize;
! 		na.rsize = una.rsize;
! 		na.timeo = una.timeo;
! 		na.retrans = una.retrans;
! 		na.hostname = una.hostname;
! 		if (error = copyout(sap, na.addr, sizeof (*sap) ))
  			return (error);
! 		if (error = copyout(&na, fixed.data, sizeof na))
  			return (error);
  	}
! 	return (mount(p, &fixed, retval));
  }
  
  #if defined(NFSCLIENT)

------------------------------------------------------------------------------