docs: Convert unshare.txt to RST and add to the user-space API manual
authorJonathan Corbet <corbet@lwn.net>
Sun, 2 Apr 2017 21:18:32 +0000 (15:18 -0600)
committerJonathan Corbet <corbet@lwn.net>
Sun, 2 Apr 2017 21:18:32 +0000 (15:18 -0600)
This is a straightforward conversion, without any real textual changes.
Since this document has seen no substantive changes since its addition in
2006, some such changes are probably warranted.

Signed-off-by: Jonathan Corbet <corbet@lwn.net>
Documentation/unshare.txt [deleted file]
Documentation/userspace-api/index.rst
Documentation/userspace-api/unshare.rst [new file with mode: 0644]

diff --git a/Documentation/unshare.txt b/Documentation/unshare.txt
deleted file mode 100644 (file)
index a864351..0000000
+++ /dev/null
@@ -1,295 +0,0 @@
-
-unshare system call:
---------------------
-This document describes the new system call, unshare. The document
-provides an overview of the feature, why it is needed, how it can
-be used, its interface specification, design, implementation and
-how it can be tested.
-
-Change Log:
------------
-version 0.1  Initial document, Janak Desai (janak@us.ibm.com), Jan 11, 2006
-
-Contents:
----------
-       1) Overview
-       2) Benefits
-       3) Cost
-       4) Requirements
-       5) Functional Specification
-       6) High Level Design
-       7) Low Level Design
-       8) Test Specification
-       9) Future Work
-
-1) Overview
------------
-Most legacy operating system kernels support an abstraction of threads
-as multiple execution contexts within a process. These kernels provide
-special resources and mechanisms to maintain these "threads". The Linux
-kernel, in a clever and simple manner, does not make distinction
-between processes and "threads". The kernel allows processes to share
-resources and thus they can achieve legacy "threads" behavior without
-requiring additional data structures and mechanisms in the kernel. The
-power of implementing threads in this manner comes not only from
-its simplicity but also from allowing application programmers to work
-outside the confinement of all-or-nothing shared resources of legacy
-threads. On Linux, at the time of thread creation using the clone system
-call, applications can selectively choose which resources to share
-between threads.
-
-unshare system call adds a primitive to the Linux thread model that
-allows threads to selectively 'unshare' any resources that were being
-shared at the time of their creation. unshare was conceptualized by
-Al Viro in the August of 2000, on the Linux-Kernel mailing list, as part
-of the discussion on POSIX threads on Linux.  unshare augments the
-usefulness of Linux threads for applications that would like to control
-shared resources without creating a new process. unshare is a natural
-addition to the set of available primitives on Linux that implement
-the concept of process/thread as a virtual machine.
-
-2) Benefits
------------
-unshare would be useful to large application frameworks such as PAM
-where creating a new process to control sharing/unsharing of process
-resources is not possible. Since namespaces are shared by default
-when creating a new process using fork or clone, unshare can benefit
-even non-threaded applications if they have a need to disassociate
-from default shared namespace. The following lists two use-cases
-where unshare can be used.
-
-2.1 Per-security context namespaces
------------------------------------
-unshare can be used to implement polyinstantiated directories using
-the kernel's per-process namespace mechanism. Polyinstantiated directories,
-such as per-user and/or per-security context instance of /tmp, /var/tmp or
-per-security context instance of a user's home directory, isolate user
-processes when working with these directories. Using unshare, a PAM
-module can easily setup a private namespace for a user at login.
-Polyinstantiated directories are required for Common Criteria certification
-with Labeled System Protection Profile, however, with the availability
-of shared-tree feature in the Linux kernel, even regular Linux systems
-can benefit from setting up private namespaces at login and
-polyinstantiating /tmp, /var/tmp and other directories deemed
-appropriate by system administrators.
-
-2.2 unsharing of virtual memory and/or open files
--------------------------------------------------
-Consider a client/server application where the server is processing
-client requests by creating processes that share resources such as
-virtual memory and open files. Without unshare, the server has to
-decide what needs to be shared at the time of creating the process
-which services the request. unshare allows the server an ability to
-disassociate parts of the context during the servicing of the
-request. For large and complex middleware application frameworks, this
-ability to unshare after the process was created can be very
-useful.
-
-3) Cost
--------
-In order to not duplicate code and to handle the fact that unshare
-works on an active task (as opposed to clone/fork working on a newly
-allocated inactive task) unshare had to make minor reorganizational
-changes to copy_* functions utilized by clone/fork system call.
-There is a cost associated with altering existing, well tested and
-stable code to implement a new feature that may not get exercised
-extensively in the beginning. However, with proper design and code
-review of the changes and creation of an unshare test for the LTP
-the benefits of this new feature can exceed its cost.
-
-4) Requirements
----------------
-unshare reverses sharing that was done using clone(2) system call,
-so unshare should have a similar interface as clone(2). That is,
-since flags in clone(int flags, void *stack) specifies what should
-be shared, similar flags in unshare(int flags) should specify
-what should be unshared. Unfortunately, this may appear to invert
-the meaning of the flags from the way they are used in clone(2).
-However, there was no easy solution that was less confusing and that
-allowed incremental context unsharing in future without an ABI change.
-
-unshare interface should accommodate possible future addition of
-new context flags without requiring a rebuild of old applications.
-If and when new context flags are added, unshare design should allow
-incremental unsharing of those resources on an as needed basis.
-
-5) Functional Specification
----------------------------
-NAME
-       unshare - disassociate parts of the process execution context
-
-SYNOPSIS
-       #include <sched.h>
-
-       int unshare(int flags);
-
-DESCRIPTION
-       unshare allows a process to disassociate parts of its execution
-       context that are currently being shared with other processes. Part
-       of execution context, such as the namespace, is shared by default
-       when a new process is created using fork(2), while other parts,
-       such as the virtual memory, open file descriptors, etc, may be
-       shared by explicit request to share them when creating a process
-       using clone(2).
-
-       The main use of unshare is to allow a process to control its
-       shared execution context without creating a new process.
-
-       The flags argument specifies one or bitwise-or'ed of several of
-       the following constants.
-
-       CLONE_FS
-               If CLONE_FS is set, file system information of the caller
-               is disassociated from the shared file system information.
-
-       CLONE_FILES
-               If CLONE_FILES is set, the file descriptor table of the
-               caller is disassociated from the shared file descriptor
-               table.
-
-       CLONE_NEWNS
-               If CLONE_NEWNS is set, the namespace of the caller is
-               disassociated from the shared namespace.
-
-       CLONE_VM
-               If CLONE_VM is set, the virtual memory of the caller is
-               disassociated from the shared virtual memory.
-
-RETURN VALUE
-       On success, zero returned. On failure, -1 is returned and errno is
-
-ERRORS
-       EPERM   CLONE_NEWNS was specified by a non-root process (process
-               without CAP_SYS_ADMIN).
-
-       ENOMEM  Cannot allocate sufficient memory to copy parts of caller's
-               context that need to be unshared.
-
-       EINVAL  Invalid flag was specified as an argument.
-
-CONFORMING TO
-       The unshare() call is Linux-specific and  should  not be used
-       in programs intended to be portable.
-
-SEE ALSO
-       clone(2), fork(2)
-
-6) High Level Design
---------------------
-Depending on the flags argument, the unshare system call allocates
-appropriate process context structures, populates it with values from
-the current shared version, associates newly duplicated structures
-with the current task structure and releases corresponding shared
-versions. Helper functions of clone (copy_*) could not be used
-directly by unshare because of the following two reasons.
-  1) clone operates on a newly allocated not-yet-active task
-     structure, where as unshare operates on the current active
-     task. Therefore unshare has to take appropriate task_lock()
-     before associating newly duplicated context structures
-  2) unshare has to allocate and duplicate all context structures
-     that are being unshared, before associating them with the
-     current task and releasing older shared structures. Failure
-     do so will create race conditions and/or oops when trying
-     to backout due to an error. Consider the case of unsharing
-     both virtual memory and namespace. After successfully unsharing
-     vm, if the system call encounters an error while allocating
-     new namespace structure, the error return code will have to
-     reverse the unsharing of vm. As part of the reversal the
-     system call will have to go back to older, shared, vm
-     structure, which may not exist anymore.
-
-Therefore code from copy_* functions that allocated and duplicated
-current context structure was moved into new dup_* functions. Now,
-copy_* functions call dup_* functions to allocate and duplicate
-appropriate context structures and then associate them with the
-task structure that is being constructed. unshare system call on
-the other hand performs the following:
-  1) Check flags to force missing, but implied, flags
-  2) For each context structure, call the corresponding unshare
-     helper function to allocate and duplicate a new context
-     structure, if the appropriate bit is set in the flags argument.
-  3) If there is no error in allocation and duplication and there
-     are new context structures then lock the current task structure,
-     associate new context structures with the current task structure,
-     and release the lock on the current task structure.
-  4) Appropriately release older, shared, context structures.
-
-7) Low Level Design
--------------------
-Implementation of unshare can be grouped in the following 4 different
-items:
-  a) Reorganization of existing copy_* functions
-  b) unshare system call service function
-  c) unshare helper functions for each different process context
-  d) Registration of system call number for different architectures
-
-  7.1) Reorganization of copy_* functions
-       Each copy function such as copy_mm, copy_namespace, copy_files,
-       etc, had roughly two components. The first component allocated
-       and duplicated the appropriate structure and the second component
-       linked it to the task structure passed in as an argument to the copy
-       function. The first component was split into its own function.
-       These dup_* functions allocated and duplicated the appropriate
-       context structure. The reorganized copy_* functions invoked
-       their corresponding dup_* functions and then linked the newly
-       duplicated structures to the task structure with which the
-       copy function was called.
-
-  7.2) unshare system call service function
-       * Check flags
-        Force implied flags. If CLONE_THREAD is set force CLONE_VM.
-        If CLONE_VM is set, force CLONE_SIGHAND. If CLONE_SIGHAND is
-        set and signals are also being shared, force CLONE_THREAD. If
-        CLONE_NEWNS is set, force CLONE_FS.
-       * For each context flag, invoke the corresponding unshare_*
-        helper routine with flags passed into the system call and a
-        reference to pointer pointing the new unshared structure
-       * If any new structures are created by unshare_* helper
-        functions, take the task_lock() on the current task,
-        modify appropriate context pointers, and release the
-         task lock.
-       * For all newly unshared structures, release the corresponding
-         older, shared, structures.
-
-  7.3) unshare_* helper functions
-       For unshare_* helpers corresponding to CLONE_SYSVSEM, CLONE_SIGHAND,
-       and CLONE_THREAD, return -EINVAL since they are not implemented yet.
-       For others, check the flag value to see if the unsharing is
-       required for that structure. If it is, invoke the corresponding
-       dup_* function to allocate and duplicate the structure and return
-       a pointer to it.
-
-  7.4) Appropriately modify architecture specific code to register the
-       new system call.
-
-8) Test Specification
----------------------
-The test for unshare should test the following:
-  1) Valid flags: Test to check that clone flags for signal and
-       signal handlers, for which unsharing is not implemented
-       yet, return -EINVAL.
-  2) Missing/implied flags: Test to make sure that if unsharing
-       namespace without specifying unsharing of filesystem, correctly
-       unshares both namespace and filesystem information.
-  3) For each of the four (namespace, filesystem, files and vm)
-       supported unsharing, verify that the system call correctly
-       unshares the appropriate structure. Verify that unsharing
-       them individually as well as in combination with each
-       other works as expected.
-  4) Concurrent execution: Use shared memory segments and futex on
-       an address in the shm segment to synchronize execution of
-       about 10 threads. Have a couple of threads execute execve,
-       a couple _exit and the rest unshare with different combination
-       of flags. Verify that unsharing is performed as expected and
-       that there are no oops or hangs.
-
-9) Future Work
---------------
-The current implementation of unshare does not allow unsharing of
-signals and signal handlers. Signals are complex to begin with and
-to unshare signals and/or signal handlers of a currently running
-process is even more complex. If in the future there is a specific
-need to allow unsharing of signals and/or signal handlers, it can
-be incrementally added to unshare without affecting legacy
-applications using unshare.
-
index 6d98ea6c0d2d350d9a70c16efd4cbc105b2b53dc..a9d01b44a6594e37495ad6b5c1a6cd7be5c9c904 100644 (file)
@@ -16,6 +16,8 @@ place where this information is gathered.
 .. toctree::
    :maxdepth: 2
 
+   unshare
+
 .. only::  subproject and html
 
    Indices
diff --git a/Documentation/userspace-api/unshare.rst b/Documentation/userspace-api/unshare.rst
new file mode 100644 (file)
index 0000000..737c192
--- /dev/null
@@ -0,0 +1,332 @@
+unshare system call
+===================
+
+This document describes the new system call, unshare(). The document
+provides an overview of the feature, why it is needed, how it can
+be used, its interface specification, design, implementation and
+how it can be tested.
+
+Change Log
+----------
+version 0.1  Initial document, Janak Desai (janak@us.ibm.com), Jan 11, 2006
+
+Contents
+--------
+       1) Overview
+       2) Benefits
+       3) Cost
+       4) Requirements
+       5) Functional Specification
+       6) High Level Design
+       7) Low Level Design
+       8) Test Specification
+       9) Future Work
+
+1) Overview
+-----------
+
+Most legacy operating system kernels support an abstraction of threads
+as multiple execution contexts within a process. These kernels provide
+special resources and mechanisms to maintain these "threads". The Linux
+kernel, in a clever and simple manner, does not make distinction
+between processes and "threads". The kernel allows processes to share
+resources and thus they can achieve legacy "threads" behavior without
+requiring additional data structures and mechanisms in the kernel. The
+power of implementing threads in this manner comes not only from
+its simplicity but also from allowing application programmers to work
+outside the confinement of all-or-nothing shared resources of legacy
+threads. On Linux, at the time of thread creation using the clone system
+call, applications can selectively choose which resources to share
+between threads.
+
+unshare() system call adds a primitive to the Linux thread model that
+allows threads to selectively 'unshare' any resources that were being
+shared at the time of their creation. unshare() was conceptualized by
+Al Viro in the August of 2000, on the Linux-Kernel mailing list, as part
+of the discussion on POSIX threads on Linux.  unshare() augments the
+usefulness of Linux threads for applications that would like to control
+shared resources without creating a new process. unshare() is a natural
+addition to the set of available primitives on Linux that implement
+the concept of process/thread as a virtual machine.
+
+2) Benefits
+-----------
+
+unshare() would be useful to large application frameworks such as PAM
+where creating a new process to control sharing/unsharing of process
+resources is not possible. Since namespaces are shared by default
+when creating a new process using fork or clone, unshare() can benefit
+even non-threaded applications if they have a need to disassociate
+from default shared namespace. The following lists two use-cases
+where unshare() can be used.
+
+2.1 Per-security context namespaces
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+unshare() can be used to implement polyinstantiated directories using
+the kernel's per-process namespace mechanism. Polyinstantiated directories,
+such as per-user and/or per-security context instance of /tmp, /var/tmp or
+per-security context instance of a user's home directory, isolate user
+processes when working with these directories. Using unshare(), a PAM
+module can easily setup a private namespace for a user at login.
+Polyinstantiated directories are required for Common Criteria certification
+with Labeled System Protection Profile, however, with the availability
+of shared-tree feature in the Linux kernel, even regular Linux systems
+can benefit from setting up private namespaces at login and
+polyinstantiating /tmp, /var/tmp and other directories deemed
+appropriate by system administrators.
+
+2.2 unsharing of virtual memory and/or open files
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Consider a client/server application where the server is processing
+client requests by creating processes that share resources such as
+virtual memory and open files. Without unshare(), the server has to
+decide what needs to be shared at the time of creating the process
+which services the request. unshare() allows the server an ability to
+disassociate parts of the context during the servicing of the
+request. For large and complex middleware application frameworks, this
+ability to unshare() after the process was created can be very
+useful.
+
+3) Cost
+-------
+
+In order to not duplicate code and to handle the fact that unshare()
+works on an active task (as opposed to clone/fork working on a newly
+allocated inactive task) unshare() had to make minor reorganizational
+changes to copy_* functions utilized by clone/fork system call.
+There is a cost associated with altering existing, well tested and
+stable code to implement a new feature that may not get exercised
+extensively in the beginning. However, with proper design and code
+review of the changes and creation of an unshare() test for the LTP
+the benefits of this new feature can exceed its cost.
+
+4) Requirements
+---------------
+
+unshare() reverses sharing that was done using clone(2) system call,
+so unshare() should have a similar interface as clone(2). That is,
+since flags in clone(int flags, void *stack) specifies what should
+be shared, similar flags in unshare(int flags) should specify
+what should be unshared. Unfortunately, this may appear to invert
+the meaning of the flags from the way they are used in clone(2).
+However, there was no easy solution that was less confusing and that
+allowed incremental context unsharing in future without an ABI change.
+
+unshare() interface should accommodate possible future addition of
+new context flags without requiring a rebuild of old applications.
+If and when new context flags are added, unshare() design should allow
+incremental unsharing of those resources on an as needed basis.
+
+5) Functional Specification
+---------------------------
+
+NAME
+       unshare - disassociate parts of the process execution context
+
+SYNOPSIS
+       #include <sched.h>
+
+       int unshare(int flags);
+
+DESCRIPTION
+       unshare() allows a process to disassociate parts of its execution
+       context that are currently being shared with other processes. Part
+       of execution context, such as the namespace, is shared by default
+       when a new process is created using fork(2), while other parts,
+       such as the virtual memory, open file descriptors, etc, may be
+       shared by explicit request to share them when creating a process
+       using clone(2).
+
+       The main use of unshare() is to allow a process to control its
+       shared execution context without creating a new process.
+
+       The flags argument specifies one or bitwise-or'ed of several of
+       the following constants.
+
+       CLONE_FS
+               If CLONE_FS is set, file system information of the caller
+               is disassociated from the shared file system information.
+
+       CLONE_FILES
+               If CLONE_FILES is set, the file descriptor table of the
+               caller is disassociated from the shared file descriptor
+               table.
+
+       CLONE_NEWNS
+               If CLONE_NEWNS is set, the namespace of the caller is
+               disassociated from the shared namespace.
+
+       CLONE_VM
+               If CLONE_VM is set, the virtual memory of the caller is
+               disassociated from the shared virtual memory.
+
+RETURN VALUE
+       On success, zero returned. On failure, -1 is returned and errno is
+
+ERRORS
+       EPERM   CLONE_NEWNS was specified by a non-root process (process
+               without CAP_SYS_ADMIN).
+
+       ENOMEM  Cannot allocate sufficient memory to copy parts of caller's
+               context that need to be unshared.
+
+       EINVAL  Invalid flag was specified as an argument.
+
+CONFORMING TO
+       The unshare() call is Linux-specific and  should  not be used
+       in programs intended to be portable.
+
+SEE ALSO
+       clone(2), fork(2)
+
+6) High Level Design
+--------------------
+
+Depending on the flags argument, the unshare() system call allocates
+appropriate process context structures, populates it with values from
+the current shared version, associates newly duplicated structures
+with the current task structure and releases corresponding shared
+versions. Helper functions of clone (copy_*) could not be used
+directly by unshare() because of the following two reasons.
+
+  1) clone operates on a newly allocated not-yet-active task
+     structure, where as unshare() operates on the current active
+     task. Therefore unshare() has to take appropriate task_lock()
+     before associating newly duplicated context structures
+
+  2) unshare() has to allocate and duplicate all context structures
+     that are being unshared, before associating them with the
+     current task and releasing older shared structures. Failure
+     do so will create race conditions and/or oops when trying
+     to backout due to an error. Consider the case of unsharing
+     both virtual memory and namespace. After successfully unsharing
+     vm, if the system call encounters an error while allocating
+     new namespace structure, the error return code will have to
+     reverse the unsharing of vm. As part of the reversal the
+     system call will have to go back to older, shared, vm
+     structure, which may not exist anymore.
+
+Therefore code from copy_* functions that allocated and duplicated
+current context structure was moved into new dup_* functions. Now,
+copy_* functions call dup_* functions to allocate and duplicate
+appropriate context structures and then associate them with the
+task structure that is being constructed. unshare() system call on
+the other hand performs the following:
+
+  1) Check flags to force missing, but implied, flags
+
+  2) For each context structure, call the corresponding unshare()
+     helper function to allocate and duplicate a new context
+     structure, if the appropriate bit is set in the flags argument.
+
+  3) If there is no error in allocation and duplication and there
+     are new context structures then lock the current task structure,
+     associate new context structures with the current task structure,
+     and release the lock on the current task structure.
+
+  4) Appropriately release older, shared, context structures.
+
+7) Low Level Design
+-------------------
+
+Implementation of unshare() can be grouped in the following 4 different
+items:
+
+  a) Reorganization of existing copy_* functions
+
+  b) unshare() system call service function
+
+  c) unshare() helper functions for each different process context
+
+  d) Registration of system call number for different architectures
+
+7.1) Reorganization of copy_* functions
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Each copy function such as copy_mm, copy_namespace, copy_files,
+etc, had roughly two components. The first component allocated
+and duplicated the appropriate structure and the second component
+linked it to the task structure passed in as an argument to the copy
+function. The first component was split into its own function.
+These dup_* functions allocated and duplicated the appropriate
+context structure. The reorganized copy_* functions invoked
+their corresponding dup_* functions and then linked the newly
+duplicated structures to the task structure with which the
+copy function was called.
+
+7.2) unshare() system call service function
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+       * Check flags
+        Force implied flags. If CLONE_THREAD is set force CLONE_VM.
+        If CLONE_VM is set, force CLONE_SIGHAND. If CLONE_SIGHAND is
+        set and signals are also being shared, force CLONE_THREAD. If
+        CLONE_NEWNS is set, force CLONE_FS.
+
+       * For each context flag, invoke the corresponding unshare_*
+        helper routine with flags passed into the system call and a
+        reference to pointer pointing the new unshared structure
+
+       * If any new structures are created by unshare_* helper
+        functions, take the task_lock() on the current task,
+        modify appropriate context pointers, and release the
+         task lock.
+
+       * For all newly unshared structures, release the corresponding
+         older, shared, structures.
+
+7.3) unshare_* helper functions
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+For unshare_* helpers corresponding to CLONE_SYSVSEM, CLONE_SIGHAND,
+and CLONE_THREAD, return -EINVAL since they are not implemented yet.
+For others, check the flag value to see if the unsharing is
+required for that structure. If it is, invoke the corresponding
+dup_* function to allocate and duplicate the structure and return
+a pointer to it.
+
+7.4) Finally
+~~~~~~~~~~~~
+
+Appropriately modify architecture specific code to register the
+new system call.
+
+8) Test Specification
+---------------------
+
+The test for unshare() should test the following:
+
+  1) Valid flags: Test to check that clone flags for signal and
+     signal handlers, for which unsharing is not implemented
+     yet, return -EINVAL.
+
+  2) Missing/implied flags: Test to make sure that if unsharing
+     namespace without specifying unsharing of filesystem, correctly
+     unshares both namespace and filesystem information.
+
+  3) For each of the four (namespace, filesystem, files and vm)
+     supported unsharing, verify that the system call correctly
+     unshares the appropriate structure. Verify that unsharing
+     them individually as well as in combination with each
+     other works as expected.
+
+  4) Concurrent execution: Use shared memory segments and futex on
+     an address in the shm segment to synchronize execution of
+     about 10 threads. Have a couple of threads execute execve,
+     a couple _exit and the rest unshare with different combination
+     of flags. Verify that unsharing is performed as expected and
+     that there are no oops or hangs.
+
+9) Future Work
+--------------
+
+The current implementation of unshare() does not allow unsharing of
+signals and signal handlers. Signals are complex to begin with and
+to unshare signals and/or signal handlers of a currently running
+process is even more complex. If in the future there is a specific
+need to allow unsharing of signals and/or signal handlers, it can
+be incrementally added to unshare() without affecting legacy
+applications using unshare().
+