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 */
>
>

Reply via email to