Index: src/afs/afs_call.c
===================================================================
RCS file: /cvs/openafs/src/afs/afs_call.c,v
retrieving revision 1.48
diff -u -r1.48 afs_call.c
--- src/afs/afs_call.c	23 Mar 2003 19:43:47 -0000	1.48
+++ src/afs/afs_call.c	7 Apr 2003 18:34:37 -0000
@@ -733,10 +733,12 @@
     else if (parm == AFSOP_SHUTDOWN) {
 	afs_cold_shutdown = 0;
 	if (parm == 1) afs_cold_shutdown = 1;
+#ifndef AFS_DARWIN_ENV
 	if (afs_globalVFS != 0) {
 	    afs_warn("AFS isn't unmounted yet! Call aborted\n");
 	    code = EACCES;
 	} else
+#endif
 	    afs_shutdown();
     }
     else if (parm == AFSOP_AFS_VFSMOUNT) {
Index: src/afs/DARWIN/osi_vfsops.c
===================================================================
RCS file: /cvs/openafs/src/afs/DARWIN/osi_vfsops.c,v
retrieving revision 1.8
diff -u -r1.8 osi_vfsops.c
--- src/afs/DARWIN/osi_vfsops.c	16 Oct 2002 03:58:17 -0000	1.8
+++ src/afs/DARWIN/osi_vfsops.c	7 Apr 2003 18:34:37 -0000
@@ -67,7 +67,7 @@
     AFS_GLOCK();
     AFS_STATCNT(afs_mount);
 
-    if (afs_globalVFS) { /* Don't allow remounts. */
+    if (data == NULL && afs_globalVFS) { /* Don't allow remounts. */
 	AFS_GUNLOCK();
 	return (EBUSY);
     }
@@ -80,8 +80,51 @@
     (void) copyinstr(path, mp->mnt_stat.f_mntonname, MNAMELEN-1, &size);
     memset(mp->mnt_stat.f_mntonname + size, 0, MNAMELEN - size);
     memset(mp->mnt_stat.f_mntfromname, 0, MNAMELEN);
-    strcpy(mp->mnt_stat.f_mntfromname, "AFS");
-    /* null terminated string "AFS" will fit, just leave it be. */
+
+    if (data == NULL) {
+	strcpy(mp->mnt_stat.f_mntfromname, "AFS");
+	/* null terminated string "AFS" will fit, just leave it be. */
+	mp->mnt_data = (qaddr_t)NULL;
+    } else {
+	struct VenusFid *rootFid = NULL;
+	struct volume *tvp;
+	char volName[MNAMELEN];
+
+	(void) copyinstr((char *)data, volName, MNAMELEN-1, &size);
+	memset(volName + size, 0, MNAMELEN - size);
+
+	if (volName[0] == 0) {
+	    strcpy(mp->mnt_stat.f_mntfromname, "AFS");
+	    mp->mnt_data = (qaddr_t)&afs_rootFid;	    
+	} else {
+	    struct cell *localcell = afs_GetPrimaryCell(READ_LOCK);
+	    if (localcell == NULL) {
+		AFS_GUNLOCK();
+		return ENODEV;
+	    }
+
+	    /* Set the volume identifier to "AFS:volume.name" */
+	    snprintf(mp->mnt_stat.f_mntfromname, MNAMELEN-1, "AFS:%s",
+		     volName);
+	    tvp = afs_GetVolumeByName(volName, localcell->cellNum, 1,
+				      (struct vrequest *)0, READ_LOCK);
+	    
+	    if (tvp) {
+		int volid = (tvp->roVol ? tvp->roVol : tvp->volume);
+		MALLOC(rootFid, struct VenusFid *, sizeof(*rootFid), 
+		       M_UFSMNT, M_WAITOK);
+		rootFid->Cell = localcell->cellNum;
+		rootFid->Fid.Volume = volid;
+		rootFid->Fid.Vnode = 1;
+		rootFid->Fid.Unique = 1;
+	    } else {
+		AFS_GUNLOCK();
+		return ENODEV;
+	    }
+	
+	    mp->mnt_data = (qaddr_t)rootFid;
+	}
+    }
     strcpy(mp->mnt_stat.f_fstypename, "afs");
     AFS_GUNLOCK();
     (void) afs_statfs(mp, &mp->mnt_stat, p);
@@ -97,8 +140,23 @@
     
     AFS_GLOCK();
     AFS_STATCNT(afs_unmount);
-    afs_globalVFS = 0;
-    afs_shutdown();
+
+    if (mp->mnt_data != (qaddr_t)-1) {
+	if (mp->mnt_data != NULL) {
+	    FREE(mp->mnt_data, M_UFSMNT);
+	    mp->mnt_data = (qaddr_t)-1;
+	} else {
+	    if (flags & MNT_FORCE) {
+		afs_globalVFS = 0;
+		afs_shutdown();
+	    } else {
+		AFS_GUNLOCK();
+		return EBUSY;
+	    }
+	}
+	mp->mnt_flag &= ~MNT_LOCAL;
+    }
+
     AFS_GUNLOCK();
 
     return 0;
@@ -119,10 +177,16 @@
     pcred_unlock(p);
     AFS_GLOCK();
     AFS_STATCNT(afs_root);
-    if (afs_globalVp && (afs_globalVp->states & CStatd)) {
+    if (mp->mnt_data == NULL
+	&& afs_globalVp && (afs_globalVp->states & CStatd)) {
 	tvp = afs_globalVp;
         error=0;
+    } else if (mp->mnt_data == (qaddr_t)-1) {
+	error = ENOENT;
     } else {
+	struct VenusFid *rootFid = (mp->mnt_data == NULL)
+	    ? &afs_rootFid : (struct VenusFid *)mp->mnt_data;
+
 	if (afs_globalVp) {
 	    afs_PutVCache(afs_globalVp);
 	    afs_globalVp = NULL;
@@ -130,10 +194,11 @@
 
 	if (!(error = afs_InitReq(&treq, &cr)) &&
 	    !(error = afs_CheckInit())) {
-	    tvp = afs_GetVCache(&afs_rootFid, &treq, NULL, NULL);
+	    tvp = afs_GetVCache(rootFid, &treq, NULL, NULL);
 	    /* we really want this to stay around */
 	    if (tvp) {
-	        afs_globalVp = tvp;
+		if (mp->mnt_data == NULL)
+		    afs_globalVp = tvp;
 	    } else
 	        error = ENOENT;
 	}
@@ -143,9 +208,12 @@
     AFS_GUNLOCK();
         vn_lock(AFSTOV(tvp), LK_EXCLUSIVE | LK_RETRY, p);
     AFS_GLOCK();
-	afs_globalVFS = mp;
+        if (mp->mnt_data == NULL) {
+	    afs_globalVFS = mp;
+	}	
 	*vpp = AFSTOV(tvp);
         AFSTOV(tvp)->v_flag |= VROOT;
+	AFSTOV(tvp)->v_vfsp = mp;
     }
 
     afs_Trace2(afs_iclSetp, CM_TRACE_VFSROOT, ICL_TYPE_POINTER, *vpp,
@@ -168,7 +236,7 @@
     }
     error = vget(vp, lfl, current_proc());
     if (!error)
-	insmntque(vp, afs_globalVFS);   /* take off free list */
+	insmntque(vp, mp);   /* take off free list */
     return error;
 }
 
Index: src/afs/DARWIN/osi_vnodeops.c
===================================================================
RCS file: /cvs/openafs/src/afs/DARWIN/osi_vnodeops.c,v
retrieving revision 1.11
diff -u -r1.11 osi_vnodeops.c
--- src/afs/DARWIN/osi_vnodeops.c	7 Jan 2003 23:03:35 -0000	1.11
+++ src/afs/DARWIN/osi_vnodeops.c	7 Apr 2003 18:34:38 -0000
@@ -173,6 +173,7 @@
 	return (error);
     }
     vp = AFSTOV(vcp);  /* always get a node if no error */
+    vp->v_vfsp = dvp->v_vfsp;
 
     /* The parent directory comes in locked.  We unlock it on return
        unless the caller wants it left locked.
@@ -237,6 +238,7 @@
 
     if (vcp) {
 	*ap->a_vpp = AFSTOV(vcp);
+	(*ap->a_vpp)->v_vfsp = dvp->v_vfsp;
 	vn_lock(*ap->a_vpp, LK_EXCLUSIVE| LK_RETRY, p);
         if (UBCINFOMISSING(*ap->a_vpp) ||
             UBCINFORECLAIMED(*ap->a_vpp))
@@ -810,11 +812,6 @@
 
     GETNAME();
     p=cnp->cn_proc;
-    if (dvp->v_mount != vp->v_mount) {
-	VOP_ABORTOP(vp, cnp);
-	error = EXDEV;
-	goto out;
-    }
     if (vp->v_type == VDIR) {
 	VOP_ABORTOP(vp, cnp);
 	error = EISDIR;
@@ -859,25 +856,6 @@
     struct proc *p=fcnp->cn_proc;
 
     /*
-     * Check for cross-device rename.
-     */
-    if ((fvp->v_mount != tdvp->v_mount) ||
-	(tvp && (fvp->v_mount != tvp->v_mount))) {
-	error = EXDEV;
-abortit:
-	VOP_ABORTOP(tdvp, tcnp); /* XXX, why not in NFS? */
-	if (tdvp == tvp)
-	    vrele(tdvp);
-	else
-	    vput(tdvp);
-	if (tvp)
-	    vput(tvp);
-	VOP_ABORTOP(fdvp, fcnp); /* XXX, why not in NFS? */
-	vrele(fdvp);
-	vrele(fvp);
-	return (error);
-    }
-    /*
      * if fvp == tvp, we're just removing one name of a pair of
      * directory entries for the same element.  convert call into rename.
      ( (pinched from NetBSD 1.0's ufs_rename())
@@ -885,7 +863,18 @@
     if (fvp == tvp) {
 	if (fvp->v_type == VDIR) {
 	    error = EINVAL;
-	    goto abortit;
+	abortit:
+	    VOP_ABORTOP(tdvp, tcnp); /* XXX, why not in NFS? */
+	    if (tdvp == tvp)
+		vrele(tdvp);
+	    else
+		vput(tdvp);
+	    if (tvp)
+		vput(tvp);
+	    VOP_ABORTOP(fdvp, fcnp); /* XXX, why not in NFS? */
+	    vrele(fdvp);
+	    vrele(fvp);
+	    return (error);
 	}
 
 	/* Release destination completely. */
@@ -968,6 +957,7 @@
     }
     if (vcp) {
 	*ap->a_vpp = AFSTOV(vcp);
+	(*ap->a_vpp)->v_vfsp = dvp->v_vfsp;
 	vn_lock(*ap->a_vpp, LK_EXCLUSIVE|LK_RETRY, p);
     } else
 	*ap->a_vpp = 0;
Index: src/afsd/Makefile.in
===================================================================
RCS file: /cvs/openafs/src/afsd/Makefile.in,v
retrieving revision 1.14
diff -u -r1.14 Makefile.in
--- src/afsd/Makefile.in	13 Feb 2003 23:44:29 -0000	1.14
+++ src/afsd/Makefile.in	7 Apr 2003 18:34:38 -0000
@@ -23,7 +23,7 @@
 AFSLIBS=${TOP_LIBDIR}/libauth.a ${TOP_LIBDIR}/libcmd.a ${TOP_LIBDIR}/libsys.a ${TOP_LIBDIR}/util.a ${TOP_LIBDIR}/librx.a ${TOP_LIBDIR}/liblwp.a ${TOP_LIBDIR}/util.a
 
 afsd: afsd.o $(AFSLIBS) $(AFSD_LIBS)
-	${CC} ${CFLAGS} -o afsd afsd.o $(NON_SHARED) $(LDFLAGS) $(AFSLIBS) ${XLIBS} ${AFSD_LIBS}
+	${CC} ${CFLAGS} -o afsd afsd.o $(NON_SHARED) $(LDFLAGS) $(AFSD_LDFLAGS) $(AFSLIBS) ${XLIBS} ${AFSD_LIBS}
 
 vsys: vsys.o
 	${CC} ${CFLAGS} -o vsys vsys.o ${TOP_LIBDIR}/libsys.a $(LDFLAGS) ${XLIBS}
Index: afsd.c
===================================================================
RCS file: /cvs/openafs/src/afsd/afsd.c,v
retrieving revision 1.32
diff -u -r1.32 afsd.c
--- afsd.c	23 Mar 2003 19:43:49 -0000	1.32
+++ afsd.c	10 Apr 2003 18:39:56 -0000
@@ -146,6 +146,14 @@
 #ifdef AFS_LINUX20_ENV
 #include <sys/resource.h>
 #endif
+#ifdef AFS_DARWIN_ENV
+#include <mach/mach.h>
+/* Symbols from the DiskArbitration framework */
+kern_return_t DiskArbStart(mach_port_t *);
+kern_return_t DiskArbDiskAppearedWithMountpointPing_auto(char *, unsigned int,
+							 char *);
+#define DISK_ARB_NETWORK_DISK_FLAG 8
+#endif /* AFS_DARWIN_ENV */
 
 #ifndef MOUNT_AFS
 #define	MOUNT_AFS AFS_MOUNT_AFS
@@ -250,6 +258,7 @@
 #endif
 static int enable_dynroot = 0;		/* enable dynroot support */
 static int enable_fakestat = 0;		/* enable fakestat support */
+static int enable_nomount = 0;		/* do not mount */
 #ifdef notdef
 static int inodes = 60;		        /* VERY conservative, but has to be */
 #endif
@@ -1347,6 +1356,10 @@
 	/* -fakestat-all */
 	enable_fakestat = 1;
     }
+    if (as->parms[29].items) {
+	/* -nomount */
+	enable_nomount = 1;
+    }
 
     /*
      * Pull out all the configuration info for the workstation's AFS cache and
@@ -1846,6 +1859,8 @@
 	exit(1);
     }
 
+    if (!enable_nomount) {
+
     mountFlags = 0;	/* Read/write file system, can do setuid() */
 #if	defined(AFS_SUN_ENV) || defined(AFS_SUN5_ENV)
 #ifdef	AFS_SUN5_ENV
@@ -1928,6 +1943,8 @@
 
     HandleMTab();
 
+    }
+
     if (afsd_rmtsys) {
 	if (afsd_verbose)
 	    printf("%s: Forking 'rmtsys' daemon.\n", rn);
@@ -1991,6 +2008,7 @@
     cmd_AddParm(ts, "-dynroot", CMD_FLAG, CMD_OPTIONAL, "Enable dynroot support");
     cmd_AddParm(ts, "-fakestat", CMD_FLAG, CMD_OPTIONAL, "Enable fakestat support for cross-cell mounts");
     cmd_AddParm(ts, "-fakestat-all", CMD_FLAG, CMD_OPTIONAL, "Enable fakestat support for all mounts");
+    cmd_AddParm(ts, "-nomount", CMD_FLAG, CMD_OPTIONAL, "Do not mount AFS");
     return (cmd_Dispatch(argc, argv));
 }
 
@@ -2064,6 +2082,18 @@
 #endif	/* AFS_SGI_ENV */
 #endif	/* AFS_SUN5_ENV */
 #endif	/* unreasonable systems */
+#ifdef AFS_DARWIN_ENV
+    mach_port_t diskarb_port;
+    kern_return_t status;
+
+    status = DiskArbStart(&diskarb_port);
+    if (status == KERN_SUCCESS) {
+	status = DiskArbDiskAppearedWithMountpointPing_auto("AFS",
+	             DISK_ARB_NETWORK_DISK_FLAG, cacheMountDir);
+    }
+
+    return status;
+#endif /* AFS_DARWIN_ENV */
     return 0;
 }
 
Index: src/cf/osconf.m4
===================================================================
RCS file: /cvs/openafs/src/cf/osconf.m4,v
retrieving revision 1.34
diff -u -r1.34 osconf.m4
--- src/cf/osconf.m4	10 Mar 2003 20:02:38 -0000	1.34
+++ src/cf/osconf.m4	7 Apr 2003 18:34:43 -0000
@@ -304,12 +304,14 @@
 		;;
 
 	ppc_darwin_12)
+		AFSD_LDFLAGS="-F/System/Library/PrivateFrameworks -framework DiskArbitration"
 		LEX="lex -l"
 		REGEX_OBJ="regex.o"
 		XCFLAGS="-traditional-cpp"
 		;;
 
 	ppc_darwin_13)
+		AFSD_LDFLAGS="-F/System/Library/PrivateFrameworks -framework DiskArbitration"
 		LEX="lex -l"
 		LWP_OPTMZ="-O2"
 		REGEX_OBJ="regex.o"
@@ -317,6 +319,7 @@
 		;;
 
 	ppc_darwin_14)
+		AFSD_LDFLAGS="-F/System/Library/PrivateFrameworks -framework DiskArbitration"
 		LEX="lex -l"
 		LWP_OPTMZ="-O2"
 		REGEX_OBJ="regex.o"
@@ -324,6 +327,7 @@
 		;;
 
 	ppc_darwin_60)
+		AFSD_LDFLAGS="-F/System/Library/PrivateFrameworks -framework DiskArbitration"
 		LEX="lex -l"
 		LWP_OPTMZ="-O2"
 		REGEX_OBJ="regex.o"
@@ -732,6 +736,7 @@
 
 AC_SUBST(CCXPG2)
 AC_SUBST(AFSD_LIBS)
+AC_SUBST(AFSD_LDFLAGS)
 AC_SUBST(AR)
 AC_SUBST(AS)
 AC_SUBST(CP)
Index: src/config/Makefile.config.in
===================================================================
RCS file: /cvs/openafs/src/config/Makefile.config.in,v
retrieving revision 1.7
diff -u -r1.7 Makefile.config.in
--- src/config/Makefile.config.in	11 Jan 2003 07:34:04 -0000	1.7
+++ src/config/Makefile.config.in	7 Apr 2003 18:34:43 -0000
@@ -30,6 +30,7 @@
 AR = @AR@
 AS = @AS@
 AFSD_LIBS = @AFSD_LIBS@
+AFSD_LDFLAGS = @AFSD_LDFLAGS@
 CC = @CC@
 CCXPG2 = @CCXPG2@
 CFLAGS = @CFLAGS@
