my initial attempt to send a response is not moving out of the queue...so here is a second attempt.
On 1/10/17, Alexander Bluhm <alexander.bl...@gmx.net> wrote: > Hi, > > When I force to unmount a filesystem where another mountpoint is > located, an unlinked mountpoint will remain. I have not found a > way to restore the kernel to a sane state. > > # mount /dev/vnd0a /mnt > # mkdir /mnt/mnt > # mount /dev/vnd1a /mnt/mnt > # mount > /dev/sd0a on / type ffs (local) > /dev/vnd0a on /mnt type ffs (local) > /dev/vnd1a on /mnt/mnt type ffs (local) > # umount /mnt > umount: /mnt: Device busy > # umount -f /mnt > # mount > /dev/sd0a on / type ffs (local) > /dev/vnd1a on /mnt/mnt type ffs (local) > # umount /mnt/mnt > umount: /mnt/mnt: No such file or directory does # umount /dev/vnd1a not do the trick? --patrick > # mkdir /mnt/mnt > # umount /mnt/mnt > umount: /mnt/mnt: Invalid argument > # vnconfig -u vnd1 > vnconfig: VNDIOCCLR: Device busy > > The fix could be to unmount recursively. > > ok? > > bluhm > > Index: kern/vfs_syscalls.c > =================================================================== > RCS file: /cvs/src/sys/kern/vfs_syscalls.c,v > retrieving revision 1.267 > diff -u -p -r1.267 vfs_syscalls.c > --- kern/vfs_syscalls.c 10 Jan 2017 20:13:17 -0000 1.267 > +++ kern/vfs_syscalls.c 10 Jan 2017 20:36:05 -0000 > @@ -88,6 +88,7 @@ int domkdirat(struct proc *, int, const > int doutimensat(struct proc *, int, const char *, struct timespec [2], > int); > int dovutimens(struct proc *, struct vnode *, struct timespec [2]); > int dofutimens(struct proc *, int, struct timespec [2]); > +int unmount_vnode(struct vnode *, void *); > > /* > * Virtual File System System Calls > @@ -368,15 +369,56 @@ sys_unmount(struct proc *p, void *v, reg > return (dounmount(mp, SCARG(uap, flags) & MNT_FORCE, p)); > } > > +struct unmount_args { > + struct proc *ua_proc; > + int ua_flags; > + int ua_error; > +}; > + > +int > +unmount_vnode(struct vnode *vp, void *args) > +{ > + struct unmount_args *ua = args; > + struct mount *mp; > + int error; > + > + if (vp->v_type != VDIR) > + return (0); > + if ((mp = vp->v_mountedhere) == NULL) > + return (0); > + if (!(ua->ua_flags & MNT_FORCE)) { > + ua->ua_error = EBUSY; > + return (EBUSY); > + } > + if (vfs_busy(mp, VB_WRITE|VB_WAIT)) { > + ua->ua_error = EBUSY; > + return (0); > + } > + error = dounmount(mp, ua->ua_flags, ua->ua_proc); > + if (error) > + ua->ua_error = error; > + return (0); > +} > + > /* > * Do the actual file system unmount. > */ > int > dounmount(struct mount *mp, int flags, struct proc *p) > { > + struct unmount_args ua; > struct vnode *coveredvp; > int error; > int hadsyncer = 0; > + > + ua.ua_proc = p; > + ua.ua_flags = flags; > + ua.ua_error = 0; > + vfs_mount_foreach_vnode(mp, unmount_vnode, &ua); > + if (ua.ua_error && !(flags & MNT_DOOMED)) { > + vfs_unbusy(mp); > + return (ua.ua_error); > + } > > mp->mnt_flag &=~ MNT_ASYNC; > cache_purgevfs(mp); /* remove cache entries for this file sys */ > >