Eric Biggers <ebiggers@xxxxxxxxxx> wrote: > Also, since the case of a fd with an internal mount was overlooked, probably > the man page needs to be updated clarify that move_mount(2) fails with > EINVAL in this case. Where is the man page? See below. I'm in the middle of updating the manpages I need to push. David --- '\" t .\" Copyright (c) 2018 David Howells <dhowells@xxxxxxxxxx> .\" .\" %%%LICENSE_START(VERBATIM) .\" Permission is granted to make and distribute verbatim copies of this .\" manual provided the copyright notice and this permission notice are .\" preserved on all copies. .\" .\" Permission is granted to copy and distribute modified versions of this .\" manual under the conditions for verbatim copying, provided that the .\" entire resulting derived work is distributed under the terms of a .\" permission notice identical to this one. .\" .\" Since the Linux kernel and libraries are constantly changing, this .\" manual page may be incorrect or out-of-date. The author(s) assume no .\" responsibility for errors or omissions, or for damages resulting from .\" the use of the information contained herein. The author(s) may not .\" have taken the same level of care in the production of this manual, .\" which is licensed free of charge, as they might when working .\" professionally. .\" .\" Formatted or processed versions of this manual, if unaccompanied by .\" the source, must acknowledge the copyright and authors of this work. .\" %%%LICENSE_END .\" .TH MOVE_MOUNT 2 2018-06-08 "Linux" "Linux Programmer's Manual" .SH NAME move_mount \- Move mount objects around the filesystem topology .SH SYNOPSIS .nf .B #include <sys/types.h> .br .B #include <sys/mount.h> .br .B #include <unistd.h> .br .BR "#include <fcntl.h> " "/* Definition of AT_* constants */" .PP .BI "int move_mount(int " from_dirfd ", const char *" from_pathname "," .BI " int " to_dirfd ", const char *" to_pathname "," .BI " unsigned int " flags ); .fi .PP .IR Note : There are no glibc wrappers for these system calls. .SH DESCRIPTION The .BR move_mount () call moves a mount from one place to another; it can also be used to attach an unattached mount created by .BR fsmount "() or " open_tree "() with " OPEN_TREE_CLONE . .PP If .BR move_mount () is called repeatedly with a file descriptor that refers to a mount object, then the object will be attached/moved the first time and then moved again and again and again, detaching it from the previous mountpoint each time. .PP To access the source mount object or the destination mountpoint, no permissions are required on the object itself, but if either pathname is supplied, execute (search) permission is required on all of the directories specified in .IR from_pathname " or " to_pathname . .PP The caller does, however, require the appropriate capabilities or permission to effect a mount. .PP .BR move_mount () uses .IR from_pathname ", " from_dirfd " and some " flags to locate the mount object to be moved and .IR to_pathname ", " to_dirfd " and some other " flags to locate the destination mountpoint. Each lookup can be done in one of a variety of ways: .TP [*] By absolute path. The pathname points to an absolute path and the dirfd is ignored. The file is looked up by name, starting from the root of the filesystem as seen by the calling process. .TP [*] By cwd-relative path. The pathname points to a relative path and the dirfd is .IR AT_FDCWD . The file is looked up by name, starting from the current working directory. .TP [*] By dir-relative path. The pathname points to relative path and the dirfd indicates a file descriptor pointing to a directory. The file is looked up by name, starting from the directory specified by .IR dirfd . .TP [*] By file descriptor. The pathname points to "", the dirfd points directly to the mount object to move or the destination mount point and the appropriate .B *_EMPTY_PATH flag is set. .PP .I flags can be used to influence a path-based lookup. A value for .I flags is constructed by OR'ing together zero or more of the following constants: .TP .BR MOVE_MOUNT_F_EMPTY_PATH .\" commit 65cfc6722361570bfe255698d9cd4dccaf47570d If .I from_pathname is an empty string, operate on the file referred to by .IR from_dirfd (which may have been obtained using the .BR open (2) .B O_PATH flag or .BR open_tree ()) If .I from_dirfd is .BR AT_FDCWD , the call operates on the current working directory. In this case, .I from_dirfd can refer to any type of file, not just a directory. This flag is Linux-specific; define .B _GNU_SOURCE .\" Before glibc 2.16, defining _ATFILE_SOURCE sufficed to obtain its definition. .TP .B MOVE_MOUNT_T_EMPTY_PATH As above, but operating on .IR to_pathname " and " to_dirfd . .TP .B MOVE_MOUNT_F_NO_AUTOMOUNT Don't automount the terminal ("basename") component of .I from_pathname if it is a directory that is an automount point. This allows a mount object that has an automount point at its root to be moved and prevents unintended triggering of an automount point. The .B MOVE_MOUNT_F_NO_AUTOMOUNT flag has no effect if the automount point has already been mounted over. This flag is Linux-specific; define .B _GNU_SOURCE .\" Before glibc 2.16, defining _ATFILE_SOURCE sufficed to obtain its definition. .TP .B MOVE_MOUNT_T_NO_AUTOMOUNT As above, but operating on .IR to_pathname " and " to_dirfd . This allows an automount point to be manually mounted over. .TP .B MOVE_MOUNT_F_SYMLINKS If .I from_pathname is a symbolic link, then dereference it. The default for .BR move_mount () is to not follow symlinks. .TP .B MOVE_MOUNT_T_SYMLINKS As above, but operating on .IR to_pathname " and " to_dirfd . .SH EXAMPLES The .BR move_mount () function can be used like the following: .PP .RS .nf move_mount(AT_FDCWD, "/a", AT_FDCWD, "/b", 0); .fi .RE .PP This would move the object mounted on "/a" to "/b". It can also be used in conjunction with .BR open_tree "(2) or " open "(2) with " O_PATH : .PP .RS .nf fd = open_tree(AT_FDCWD, "/mnt", 0); move_mount(fd, "", AT_FDCWD, "/mnt2", MOVE_MOUNT_F_EMPTY_PATH); move_mount(fd, "", AT_FDCWD, "/mnt3", MOVE_MOUNT_F_EMPTY_PATH); move_mount(fd, "", AT_FDCWD, "/mnt4", MOVE_MOUNT_F_EMPTY_PATH); .fi .RE .PP This would attach the path point for "/mnt" to fd, then it would move the mount to "/mnt2", then move it to "/mnt3" and finally to "/mnt4". .PP It can also be used to attach new mounts: .PP .RS .nf sfd = fsopen("ext4", FSOPEN_CLOEXEC); write(sfd, "s /dev/sda1"); write(sfd, "o user_xattr"); mfd = fsmount(sfd, FSMOUNT_CLOEXEC, MS_NODEV); move_mount(mfd, "", AT_FDCWD, "/home", MOVE_MOUNT_F_EMPTY_PATH); .fi .RE .PP Which would open the Ext4 filesystem mounted on "/dev/sda1", turn on user extended attribute support and create a mount object for it. Finally, the new mount object would be attached with .BR move_mount () to "/home". .\""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" .\""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" .\""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" .SH RETURN VALUE On success, 0 is returned. On error, \-1 is returned, and .I errno is set appropriately. .SH ERRORS .TP .B EACCES Search permission is denied for one of the directories in the path prefix of .IR pathname . (See also .BR path_resolution (7).) .TP .B EBADF .IR from_dirfd " or " to_dirfd is not a valid open file descriptor. .TP .B EFAULT .IR from_pathname " or " to_pathname is NULL or either one point to a location outside the process's accessible address space. .TP .B EINVAL Reserved flag specified in .IR flags . .TP .B ELOOP Too many symbolic links encountered while traversing the pathname. .TP .B ENAMETOOLONG .IR from_pathname " or " to_pathname is too long. .TP .B ENOENT A component of .IR from_pathname " or " to_pathname does not exist, or one is an empty string and the appropriate .B *_EMPTY_PATH was not specified in .IR flags . .TP .B ENOMEM Out of memory (i.e., kernel memory). .TP .B ENOTDIR A component of the path prefix of .IR from_pathname " or " to_pathname is not a directory or one or the other is relative and the appropriate .I *_dirfd is a file descriptor referring to a file other than a directory. .SH VERSIONS .BR move_mount () was added to Linux in kernel 4.18. .SH CONFORMING TO .BR move_mount () is Linux-specific. .SH NOTES Glibc does not (yet) provide a wrapper for the .BR move_mount () system call; call it using .BR syscall (2). .SH SEE ALSO .BR fsmount (2), .BR fsopen (2), .BR open_tree (2)