€•BÖŒsphinx.addnodes”Œdocument”“”)”}”(Œ rawsource”Œ”Œchildren”]”(Œ translations”Œ LanguagesNode”“”)”}”(hhh]”(hŒ pending_xref”“”)”}”(hhh]”Œdocutils.nodes”ŒText”“”ŒChinese (Simplified)”…””}”Œparent”hsbaŒ attributes”}”(Œids”]”Œclasses”]”Œnames”]”Œdupnames”]”Œbackrefs”]”Œ refdomain”Œstd”Œreftype”Œdoc”Œ reftarget”Œ)/translations/zh_CN/userspace-api/unshare”Œmodname”NŒ classname”NŒ refexplicit”ˆuŒtagname”hhh ubh)”}”(hhh]”hŒChinese (Traditional)”…””}”hh2sbah}”(h]”h ]”h"]”h$]”h&]”Œ refdomain”h)Œreftype”h+Œ reftarget”Œ)/translations/zh_TW/userspace-api/unshare”Œmodname”NŒ classname”NŒ refexplicit”ˆuh1hhh ubh)”}”(hhh]”hŒItalian”…””}”hhFsbah}”(h]”h ]”h"]”h$]”h&]”Œ refdomain”h)Œreftype”h+Œ reftarget”Œ)/translations/it_IT/userspace-api/unshare”Œmodname”NŒ classname”NŒ refexplicit”ˆuh1hhh ubh)”}”(hhh]”hŒJapanese”…””}”hhZsbah}”(h]”h ]”h"]”h$]”h&]”Œ refdomain”h)Œreftype”h+Œ reftarget”Œ)/translations/ja_JP/userspace-api/unshare”Œmodname”NŒ classname”NŒ refexplicit”ˆuh1hhh ubh)”}”(hhh]”hŒKorean”…””}”hhnsbah}”(h]”h ]”h"]”h$]”h&]”Œ refdomain”h)Œreftype”h+Œ reftarget”Œ)/translations/ko_KR/userspace-api/unshare”Œmodname”NŒ classname”NŒ refexplicit”ˆuh1hhh ubh)”}”(hhh]”hŒPortuguese (Brazilian)”…””}”hh‚sbah}”(h]”h ]”h"]”h$]”h&]”Œ refdomain”h)Œreftype”h+Œ reftarget”Œ)/translations/pt_BR/userspace-api/unshare”Œmodname”NŒ classname”NŒ refexplicit”ˆuh1hhh ubh)”}”(hhh]”hŒSpanish”…””}”hh–sbah}”(h]”h ]”h"]”h$]”h&]”Œ refdomain”h)Œreftype”h+Œ reftarget”Œ)/translations/sp_SP/userspace-api/unshare”Œmodname”NŒ classname”NŒ refexplicit”ˆuh1hhh ubeh}”(h]”h ]”h"]”h$]”h&]”Œcurrent_language”ŒEnglish”uh1h hhŒ _document”hŒsource”NŒline”NubhŒsection”“”)”}”(hhh]”(hŒtitle”“”)”}”(hŒunshare system call”h]”hŒunshare system call”…””}”(hh¼h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hºhh·h²hh³ŒC/var/lib/git/docbuild/linux/Documentation/userspace-api/unshare.rst”h´KubhŒ paragraph”“”)”}”(hŒÝ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.”h]”hŒÝ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.”…””}”(hhÍh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hËh³hÊh´Khh·h²hubh¶)”}”(hhh]”(h»)”}”(hŒ Change Log”h]”hŒ Change Log”…””}”(hhÞh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hºhhÛh²hh³hÊh´K ubhÌ)”}”(hŒKversion 0.1 Initial document, Janak Desai (janak@us.ibm.com), Jan 11, 2006”h]”(hŒ,version 0.1 Initial document, Janak Desai (”…””}”(hhìh²hh³Nh´NubhŒ reference”“”)”}”(hŒjanak@us.ibm.com”h]”hŒjanak@us.ibm.com”…””}”(hhöh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”Œrefuri”Œmailto:janak@us.ibm.com”uh1hôhhìubhŒ), Jan 11, 2006”…””}”(hhìh²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1hËh³hÊh´K hhÛh²hubeh}”(h]”Œ change-log”ah ]”h"]”Œ change log”ah$]”h&]”uh1hµhh·h²hh³hÊh´K ubh¶)”}”(hhh]”(h»)”}”(hŒContents”h]”hŒContents”…””}”(hjh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hºhjh²hh³hÊh´KubhŒ block_quote”“”)”}”(hŒš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 ”h]”hŒenumerated_list”“”)”}”(hhh]”(hŒ list_item”“”)”}”(hŒOverview”h]”hÌ)”}”(hj8h]”hŒOverview”…””}”(hj:h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hËh³hÊh´Khj6ubah}”(h]”h ]”h"]”h$]”h&]”uh1j4hj1ubj5)”}”(hŒBenefits”h]”hÌ)”}”(hjOh]”hŒBenefits”…””}”(hjQh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hËh³hÊh´KhjMubah}”(h]”h ]”h"]”h$]”h&]”uh1j4hj1ubj5)”}”(hŒCost”h]”hÌ)”}”(hjfh]”hŒCost”…””}”(hjhh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hËh³hÊh´Khjdubah}”(h]”h ]”h"]”h$]”h&]”uh1j4hj1ubj5)”}”(hŒ Requirements”h]”hÌ)”}”(hj}h]”hŒ Requirements”…””}”(hjh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hËh³hÊh´Khj{ubah}”(h]”h ]”h"]”h$]”h&]”uh1j4hj1ubj5)”}”(hŒFunctional Specification”h]”hÌ)”}”(hj”h]”hŒFunctional Specification”…””}”(hj–h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hËh³hÊh´Khj’ubah}”(h]”h ]”h"]”h$]”h&]”uh1j4hj1ubj5)”}”(hŒHigh Level Design”h]”hÌ)”}”(hj«h]”hŒHigh Level Design”…””}”(hj­h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hËh³hÊh´Khj©ubah}”(h]”h ]”h"]”h$]”h&]”uh1j4hj1ubj5)”}”(hŒLow Level Design”h]”hÌ)”}”(hjÂh]”hŒLow Level Design”…””}”(hjÄh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hËh³hÊh´KhjÀubah}”(h]”h ]”h"]”h$]”h&]”uh1j4hj1ubj5)”}”(hŒTest Specification”h]”hÌ)”}”(hjÙh]”hŒTest Specification”…””}”(hjÛh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hËh³hÊh´Khj×ubah}”(h]”h ]”h"]”h$]”h&]”uh1j4hj1ubj5)”}”(hŒ Future Work ”h]”hÌ)”}”(hŒ Future Work”h]”hŒ Future Work”…””}”(hjòh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hËh³hÊh´Khjîubah}”(h]”h ]”h"]”h$]”h&]”uh1j4hj1ubeh}”(h]”h ]”h"]”h$]”h&]”Œenumtype”Œarabic”Œprefix”hŒsuffix”Œ)”uh1j/hj+ubah}”(h]”h ]”h"]”h$]”h&]”uh1j)h³hÊh´Khjh²hubeh}”(h]”Œcontents”ah ]”h"]”Œcontents”ah$]”h&]”uh1hµhh·h²hh³hÊh´Kubh¶)”}”(hhh]”(h»)”}”(hŒ 1) Overview”h]”hŒ 1) Overview”…””}”(hj"h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hºhjh²hh³hÊh´KubhÌ)”}”(hXRMost 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.”h]”hX^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.”…””}”(hj0h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hËh³hÊh´Khjh²hubhÌ)”}”(hXgunshare() 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.”h]”hXkunshare() 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.”…””}”(hj>h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hËh³hÊh´K*hjh²hubeh}”(h]”Œoverview”ah ]”h"]”Œ 1) overview”ah$]”h&]”uh1hµhh·h²hh³hÊh´Kubh¶)”}”(hhh]”(h»)”}”(hŒ 2) Benefits”h]”hŒ 2) Benefits”…””}”(hjWh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hºhjTh²hh³hÊh´K5ubhÌ)”}”(hX´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.”h]”hX´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.”…””}”(hjeh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hËh³hÊh´K7hjTh²hubh¶)”}”(hhh]”(h»)”}”(hŒ#2.1 Per-security context namespaces”h]”hŒ#2.1 Per-security context namespaces”…””}”(hjvh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hºhjsh²hh³hÊh´K@ubhÌ)”}”(hX$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.”h]”hX(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.”…””}”(hj„h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hËh³hÊh´KBhjsh²hubeh}”(h]”Œper-security-context-namespaces”ah ]”h"]”Œ#2.1 per-security context namespaces”ah$]”h&]”uh1hµhjTh²hh³hÊh´K@ubh¶)”}”(hhh]”(h»)”}”(hŒ12.2 unsharing of virtual memory and/or open files”h]”hŒ12.2 unsharing of virtual memory and/or open files”…””}”(hjh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hºhjšh²hh³hÊh´KPubhÌ)”}”(hXConsider 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.”h]”hXConsider 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.”…””}”(hj«h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hËh³hÊh´KRhjšh²hubeh}”(h]”Œ-unsharing-of-virtual-memory-and-or-open-files”ah ]”h"]”Œ12.2 unsharing of virtual memory and/or open files”ah$]”h&]”uh1hµhjTh²hh³hÊh´KPubeh}”(h]”Œbenefits”ah ]”h"]”Œ 2) benefits”ah$]”h&]”uh1hµhh·h²hh³hÊh´K5ubh¶)”}”(hhh]”(h»)”}”(hŒ3) Cost”h]”hŒ3) Cost”…””}”(hjÌh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hºhjÉh²hh³hÊh´K]ubhÌ)”}”(hXQIn 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.”h]”hXQIn 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.”…””}”(hjÚh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hËh³hÊh´K_hjÉh²hubeh}”(h]”Œcost”ah ]”h"]”Œ3) cost”ah$]”h&]”uh1hµhh·h²hh³hÊh´K]ubh¶)”}”(hhh]”(h»)”}”(hŒ4) Requirements”h]”hŒ4) Requirements”…””}”(hjóh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hºhjðh²hh³hÊh´KjubhÌ)”}”(hXunshare() 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.”h]”hXunshare() 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.”…””}”(hjh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hËh³hÊh´Klhjðh²hubhÌ)”}”(hX 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.”h]”hX 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.”…””}”(hjh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hËh³hÊh´Kuhjðh²hubeh}”(h]”Œ requirements”ah ]”h"]”Œ4) requirements”ah$]”h&]”uh1hµhh·h²hh³hÊh´Kjubh¶)”}”(hhh]”(h»)”}”(hŒ5) Functional Specification”h]”hŒ5) Functional Specification”…””}”(hj(h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hºhj%h²hh³hÊh´K{ubhŒdefinition_list”“”)”}”(hhh]”(hŒdefinition_list_item”“”)”}”(hŒCNAME unshare - disassociate parts of the process execution context ”h]”(hŒterm”“”)”}”(hŒNAME”h]”hŒNAME”…””}”(hjCh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jAh³hÊh´K~hj=ubhŒ definition”“”)”}”(hhh]”hÌ)”}”(hŒ=unshare - disassociate parts of the process execution context”h]”hŒ=unshare - disassociate parts of the process execution context”…””}”(hjVh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hËh³hÊh´K~hjSubah}”(h]”h ]”h"]”h$]”h&]”uh1jQhj=ubeh}”(h]”h ]”h"]”h$]”h&]”uh1j;h³hÊh´K~hj8ubj<)”}”(hŒ5SYNOPSIS #include int unshare(int flags); ”h]”(jB)”}”(hŒSYNOPSIS”h]”hŒSYNOPSIS”…””}”(hjth²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jAh³hÊh´KƒhjpubjR)”}”(hhh]”(hÌ)”}”(hŒ#include ”h]”hŒ#include ”…””}”(hj…h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hËh³hÊh´Khj‚ubhÌ)”}”(hŒint unshare(int flags);”h]”hŒint unshare(int flags);”…””}”(hj“h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hËh³hÊh´Kƒhj‚ubeh}”(h]”h ]”h"]”h$]”h&]”uh1jQhjpubeh}”(h]”h ]”h"]”h$]”h&]”uh1j;h³hÊh´Kƒhj8h²hubj<)”}”(hXœ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. ”h]”(jB)”}”(hŒ DESCRIPTION”h]”hŒ DESCRIPTION”…””}”(hj±h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jAh³hÊh´K£hj­ubjR)”}”(hhh]”(hÌ)”}”(hX–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).”h]”hX–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).”…””}”(hjÂh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hËh³hÊh´K†hj¿ubhÌ)”}”(hŒwThe main use of unshare() is to allow a process to control its shared execution context without creating a new process.”h]”hŒwThe main use of unshare() is to allow a process to control its shared execution context without creating a new process.”…””}”(hjÐh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hËh³hÊh´KŽhj¿ubhÌ)”}”(hŒXThe flags argument specifies one or bitwise-or'ed of several of the following constants.”h]”hŒZThe flags argument specifies one or bitwise-or’ed of several of the following constants.”…””}”(hjÞh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hËh³hÊh´K‘hj¿ubj7)”}”(hhh]”(j<)”}”(hŒ}CLONE_FS If CLONE_FS is set, file system information of the caller is disassociated from the shared file system information. ”h]”(jB)”}”(hŒCLONE_FS”h]”hŒCLONE_FS”…””}”(hjóh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jAh³hÊh´K–hjïubjR)”}”(hhh]”hÌ)”}”(hŒsIf CLONE_FS is set, file system information of the caller is disassociated from the shared file system information.”h]”hŒsIf CLONE_FS is set, file system information of the caller is disassociated from the shared file system information.”…””}”(hjh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hËh³hÊh´K•hjubah}”(h]”h ]”h"]”h$]”h&]”uh1jQhjïubeh}”(h]”h ]”h"]”h$]”h&]”uh1j;h³hÊh´K–hjìubj<)”}”(hŒƒCLONE_FILES If CLONE_FILES is set, the file descriptor table of the caller is disassociated from the shared file descriptor table. ”h]”(jB)”}”(hŒ CLONE_FILES”h]”hŒ CLONE_FILES”…””}”(hj"h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jAh³hÊh´K›hjubjR)”}”(hhh]”hÌ)”}”(hŒvIf CLONE_FILES is set, the file descriptor table of the caller is disassociated from the shared file descriptor table.”h]”hŒvIf CLONE_FILES is set, the file descriptor table of the caller is disassociated from the shared file descriptor table.”…””}”(hj3h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hËh³hÊh´K™hj0ubah}”(h]”h ]”h"]”h$]”h&]”uh1jQhjubeh}”(h]”h ]”h"]”h$]”h&]”uh1j;h³hÊh´K›hjìubj<)”}”(hŒkCLONE_NEWNS If CLONE_NEWNS is set, the namespace of the caller is disassociated from the shared namespace. ”h]”(jB)”}”(hŒ CLONE_NEWNS”h]”hŒ CLONE_NEWNS”…””}”(hjQh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jAh³hÊh´KŸhjMubjR)”}”(hhh]”hÌ)”}”(hŒ^If CLONE_NEWNS is set, the namespace of the caller is disassociated from the shared namespace.”h]”hŒ^If CLONE_NEWNS is set, the namespace of the caller is disassociated from the shared namespace.”…””}”(hjbh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hËh³hÊh´Kžhj_ubah}”(h]”h ]”h"]”h$]”h&]”uh1jQhjMubeh}”(h]”h ]”h"]”h$]”h&]”uh1j;h³hÊh´KŸhjìubj<)”}”(hŒoCLONE_VM If CLONE_VM is set, the virtual memory of the caller is disassociated from the shared virtual memory. ”h]”(jB)”}”(hŒCLONE_VM”h]”hŒCLONE_VM”…””}”(hj€h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jAh³hÊh´K£hj|ubjR)”}”(hhh]”hÌ)”}”(hŒeIf CLONE_VM is set, the virtual memory of the caller is disassociated from the shared virtual memory.”h]”hŒeIf CLONE_VM is set, the virtual memory of the caller is disassociated from the shared virtual memory.”…””}”(hj‘h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hËh³hÊh´K¢hjŽubah}”(h]”h ]”h"]”h$]”h&]”uh1jQhj|ubeh}”(h]”h ]”h"]”h$]”h&]”uh1j;h³hÊh´K£hjìubeh}”(h]”h ]”h"]”h$]”h&]”uh1j6hj¿ubeh}”(h]”h ]”h"]”h$]”h&]”uh1jQhj­ubeh}”(h]”h ]”h"]”h$]”h&]”uh1j;h³hÊh´K£hj8h²hubj<)”}”(hŒPRETURN VALUE On success, zero returned. On failure, -1 is returned and errno is ”h]”(jB)”}”(hŒ RETURN VALUE”h]”hŒ RETURN VALUE”…””}”(hjÁh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jAh³hÊh´K¦hj½ubjR)”}”(hhh]”hÌ)”}”(hŒBOn success, zero returned. On failure, -1 is returned and errno is”h]”hŒBOn success, zero returned. On failure, -1 is returned and errno is”…””}”(hjÒh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hËh³hÊh´K¦hjÏubah}”(h]”h ]”h"]”h$]”h&]”uh1jQhj½ubeh}”(h]”h ]”h"]”h$]”h&]”uh1j;h³hÊh´K¦hj8h²hubj<)”}”(hX 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. ”h]”(jB)”}”(hŒERRORS”h]”hŒERRORS”…””}”(hjðh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jAh³hÊh´K¯hjìubjR)”}”(hhh]”(j7)”}”(hhh]”(j<)”}”(hŒYEPERM CLONE_NEWNS was specified by a non-root process (process without CAP_SYS_ADMIN). ”h]”(jB)”}”(hŒ@EPERM CLONE_NEWNS was specified by a non-root process (process”h]”hŒ@EPERM CLONE_NEWNS was specified by a non-root process (process”…””}”(hjh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jAh³hÊh´KªhjubjR)”}”(hhh]”hÌ)”}”(hŒwithout CAP_SYS_ADMIN).”h]”hŒwithout CAP_SYS_ADMIN).”…””}”(hjh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hËh³hÊh´Kªhjubah}”(h]”h ]”h"]”h$]”h&]”uh1jQhjubeh}”(h]”h ]”h"]”h$]”h&]”uh1j;h³hÊh´Kªhjubj<)”}”(hŒfENOMEM Cannot allocate sufficient memory to copy parts of caller's context that need to be unshared. ”h]”(jB)”}”(hŒCENOMEM Cannot allocate sufficient memory to copy parts of caller's”h]”hŒEENOMEM Cannot allocate sufficient memory to copy parts of caller’s”…””}”(hj7h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jAh³hÊh´K­hj3ubjR)”}”(hhh]”hÌ)”}”(hŒ!context that need to be unshared.”h]”hŒ!context that need to be unshared.”…””}”(hjHh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hËh³hÊh´K­hjEubah}”(h]”h ]”h"]”h$]”h&]”uh1jQhj3ubeh}”(h]”h ]”h"]”h$]”h&]”uh1j;h³hÊh´K­hjubeh}”(h]”h ]”h"]”h$]”h&]”uh1j6hjþubhÌ)”}”(hŒ2EINVAL Invalid flag was specified as an argument.”h]”hŒ2EINVAL Invalid flag was specified as an argument.”…””}”(hjhh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hËh³hÊh´K¯hjþubeh}”(h]”h ]”h"]”h$]”h&]”uh1jQhjìubeh}”(h]”h ]”h"]”h$]”h&]”uh1j;h³hÊh´K¯hj8h²hubj<)”}”(hŒqCONFORMING TO The unshare() call is Linux-specific and should not be used in programs intended to be portable. ”h]”(jB)”}”(hŒ CONFORMING TO”h]”hŒ CONFORMING TO”…””}”(hj†h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jAh³hÊh´K³hj‚ubjR)”}”(hhh]”hÌ)”}”(hŒbThe unshare() call is Linux-specific and should not be used in programs intended to be portable.”h]”hŒbThe unshare() call is Linux-specific and should not be used in programs intended to be portable.”…””}”(hj—h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hËh³hÊh´K²hj”ubah}”(h]”h ]”h"]”h$]”h&]”uh1jQhj‚ubeh}”(h]”h ]”h"]”h$]”h&]”uh1j;h³hÊh´K³hj8h²hubj<)”}”(hŒSEE ALSO clone(2), fork(2) ”h]”(jB)”}”(hŒSEE ALSO”h]”hŒSEE ALSO”…””}”(hjµh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jAh³hÊh´K¶hj±ubjR)”}”(hhh]”hÌ)”}”(hŒclone(2), fork(2)”h]”hŒclone(2), fork(2)”…””}”(hjÆh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hËh³hÊh´K¶hjÃubah}”(h]”h ]”h"]”h$]”h&]”uh1jQhj±ubeh}”(h]”h ]”h"]”h$]”h&]”uh1j;h³hÊh´K¶hj8h²hubeh}”(h]”h ]”h"]”h$]”h&]”uh1j6hj%h²hh³hÊh´Nubeh}”(h]”Œfunctional-specification”ah ]”h"]”Œ5) functional specification”ah$]”h&]”uh1hµhh·h²hh³hÊh´K{ubh¶)”}”(hhh]”(h»)”}”(hŒ6) High Level Design”h]”hŒ6) High Level Design”…””}”(hjñh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hºhjîh²hh³hÊh´K¹ubhÌ)”}”(hXŠ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.”h]”hXŠ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.”…””}”(hjÿh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hËh³hÊh´K»hjîh²hubj*)”}”(hX‘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. ”h]”j0)”}”(hhh]”(j5)”}”(hŒê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 ”h]”hÌ)”}”(hŒé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”h]”hŒé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”…””}”(hjh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hËh³hÊh´KÂhjubah}”(h]”h ]”h"]”h$]”h&]”uh1j4hjubj5)”}”(hXyunshare() 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. ”h]”hÌ)”}”(hXxunshare() 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.”h]”hXxunshare() 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.”…””}”(hj0h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hËh³hÊh´KÇhj,ubah}”(h]”h ]”h"]”h$]”h&]”uh1j4hjubeh}”(h]”h ]”h"]”h$]”h&]”j j jhjjuh1j/hj ubah}”(h]”h ]”h"]”h$]”h&]”uh1j)h³hÊh´KÂhjîh²hubhÌ)”}”(hXoTherefore 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:”h]”hXoTherefore 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:”…””}”(hjPh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hËh³hÊh´KÓhjîh²hubj*)”}”(hX11) 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. ”h]”j0)”}”(hhh]”(j5)”}”(hŒ1Check flags to force missing, but implied, flags ”h]”hÌ)”}”(hŒ0Check flags to force missing, but implied, flags”h]”hŒ0Check flags to force missing, but implied, flags”…””}”(hjih²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hËh³hÊh´KÚhjeubah}”(h]”h ]”h"]”h$]”h&]”uh1j4hjbubj5)”}”(hŒµ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. ”h]”hÌ)”}”(hŒ´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.”h]”hŒ´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.”…””}”(hjh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hËh³hÊh´KÜhj}ubah}”(h]”h ]”h"]”h$]”h&]”uh1j4hjbubj5)”}”(hŒô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. ”h]”hÌ)”}”(hŒó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.”h]”hŒó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.”…””}”(hj™h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hËh³hÊh´Kàhj•ubah}”(h]”h ]”h"]”h$]”h&]”uh1j4hjbubj5)”}”(hŒ9Appropriately release older, shared, context structures. ”h]”hÌ)”}”(hŒ8Appropriately release older, shared, context structures.”h]”hŒ8Appropriately release older, shared, context structures.”…””}”(hj±h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hËh³hÊh´Kåhj­ubah}”(h]”h ]”h"]”h$]”h&]”uh1j4hjbubeh}”(h]”h ]”h"]”h$]”h&]”j j jhjjuh1j/hj^ubah}”(h]”h ]”h"]”h$]”h&]”uh1j)h³hÊh´KÚhjîh²hubeh}”(h]”Œhigh-level-design”ah ]”h"]”Œ6) high level design”ah$]”h&]”uh1hµhh·h²hh³hÊh´K¹ubh¶)”}”(hhh]”(h»)”}”(hŒ7) Low Level Design”h]”hŒ7) Low Level Design”…””}”(hjÜh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hºhjÙh²hh³hÊh´KèubhÌ)”}”(hŒNImplementation of unshare() can be grouped in the following 4 different items:”h]”hŒNImplementation of unshare() can be grouped in the following 4 different items:”…””}”(hjêh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hËh³hÊh´KêhjÙh²hubj*)”}”(hŒß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 ”h]”j0)”}”(hhh]”(j5)”}”(hŒ,Reorganization of existing copy_* functions ”h]”hÌ)”}”(hŒ+Reorganization of existing copy_* functions”h]”hŒ+Reorganization of existing copy_* functions”…””}”(hjh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hËh³hÊh´Kíhjÿubah}”(h]”h ]”h"]”h$]”h&]”uh1j4hjüubj5)”}”(hŒ'unshare() system call service function ”h]”hÌ)”}”(hŒ&unshare() system call service function”h]”hŒ&unshare() system call service function”…””}”(hjh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hËh³hÊh´Kïhjubah}”(h]”h ]”h"]”h$]”h&]”uh1j4hjüubj5)”}”(hŒ>unshare() helper functions for each different process context ”h]”hÌ)”}”(hŒ=unshare() helper functions for each different process context”h]”hŒ=unshare() helper functions for each different process context”…””}”(hj3h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hËh³hÊh´Kñhj/ubah}”(h]”h ]”h"]”h$]”h&]”uh1j4hjüubj5)”}”(hŒ?Registration of system call number for different architectures ”h]”hÌ)”}”(hŒ>Registration of system call number for different architectures”h]”hŒ>Registration of system call number for different architectures”…””}”(hjKh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hËh³hÊh´KóhjGubah}”(h]”h ]”h"]”h$]”h&]”uh1j4hjüubeh}”(h]”h ]”h"]”h$]”h&]”j Œ loweralpha”jhjjuh1j/hjøubah}”(h]”h ]”h"]”h$]”h&]”uh1j)h³hÊh´KíhjÙh²hubh¶)”}”(hhh]”(h»)”}”(hŒ'7.1) Reorganization of copy_* functions”h]”hŒ'7.1) Reorganization of copy_* functions”…””}”(hjoh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hºhjlh²hh³hÊh´KöubhÌ)”}”(hXREach 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.”h]”hXREach 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.”…””}”(hj}h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hËh³hÊh´Køhjlh²hubeh}”(h]”Œ reorganization-of-copy-functions”ah ]”h"]”Œ'7.1) reorganization of copy_* functions”ah$]”h&]”uh1hµhjÙh²hh³hÊh´Köubh¶)”}”(hhh]”(h»)”}”(hŒ+7.2) unshare() system call service function”h]”hŒ+7.2) unshare() system call service function”…””}”(hj–h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hºhj“h²hh³hÊh´Mubj*)”}”(hX¸* 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. ”h]”hŒ bullet_list”“”)”}”(hhh]”(j5)”}”(hŒç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. ”h]”hÌ)”}”(hŒæ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.”h]”hŒæ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.”…””}”(hj±h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hËh³hÊh´Mhj­ubah}”(h]”h ]”h"]”h$]”h&]”uh1j4hjªubj5)”}”(hŒ¯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 ”h]”hÌ)”}”(hŒ®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”h]”hŒ®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”…””}”(hjÉh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hËh³hÊh´M hjÅubah}”(h]”h ]”h"]”h$]”h&]”uh1j4hjªubj5)”}”(hŒ«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. ”h]”hÌ)”}”(hŒª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.”h]”hŒª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.”…””}”(hjáh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hËh³hÊh´MhjÝubah}”(h]”h ]”h"]”h$]”h&]”uh1j4hjªubj5)”}”(hŒXFor all newly unshared structures, release the corresponding older, shared, structures. ”h]”hÌ)”}”(hŒWFor all newly unshared structures, release the corresponding older, shared, structures.”h]”hŒWFor all newly unshared structures, release the corresponding older, shared, structures.”…””}”(hjùh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hËh³hÊh´Mhjõubah}”(h]”h ]”h"]”h$]”h&]”uh1j4hjªubeh}”(h]”h ]”h"]”h$]”h&]”Œbullet”Œ*”uh1j¨h³hÊh´Mhj¤ubah}”(h]”h ]”h"]”h$]”h&]”uh1j)h³hÊh´Mhj“h²hubeh}”(h]”Œ$unshare-system-call-service-function”ah ]”h"]”Œ+7.2) unshare() system call service function”ah$]”h&]”uh1hµhjÙh²hh³hÊh´Mubh¶)”}”(hhh]”(h»)”}”(hŒ7.3) unshare_* helper functions”h]”hŒ7.3) unshare_* helper functions”…””}”(hj&h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hºhj#h²hh³hÊh´MubhÌ)”}”(hXXFor 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.”h]”hXXFor 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.”…””}”(hj4h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hËh³hÊh´Mhj#h²hubeh}”(h]”Œunshare-helper-functions”ah ]”h"]”Œ7.3) unshare_* helper functions”ah$]”h&]”uh1hµhjÙh²hh³hÊh´Mubh¶)”}”(hhh]”(h»)”}”(hŒ 7.4) Finally”h]”hŒ 7.4) Finally”…””}”(hjMh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hºhjJh²hh³hÊh´M#ubhÌ)”}”(hŒPAppropriately modify architecture specific code to register the new system call.”h]”hŒPAppropriately modify architecture specific code to register the new system call.”…””}”(hj[h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hËh³hÊh´M%hjJh²hubeh}”(h]”Œfinally”ah ]”h"]”Œ 7.4) finally”ah$]”h&]”uh1hµhjÙh²hh³hÊh´M#ubeh}”(h]”Œlow-level-design”ah ]”h"]”Œ7) low level design”ah$]”h&]”uh1hµhh·h²hh³hÊh´Kèubh¶)”}”(hhh]”(h»)”}”(hŒ8) Test Specification”h]”hŒ8) Test Specification”…””}”(hj|h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hºhjyh²hh³hÊh´M)ubhÌ)”}”(hŒ1The test for unshare() should test the following:”h]”hŒ1The test for unshare() should test the following:”…””}”(hjŠh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hËh³hÊh´M+hjyh²hubj*)”}”(hX¼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. ”h]”j0)”}”(hhh]”(j5)”}”(hŒˆValid flags: Test to check that clone flags for signal and signal handlers, for which unsharing is not implemented yet, return -EINVAL. ”h]”hÌ)”}”(hŒ‡Valid flags: Test to check that clone flags for signal and signal handlers, for which unsharing is not implemented yet, return -EINVAL.”h]”hŒ‡Valid flags: Test to check that clone flags for signal and signal handlers, for which unsharing is not implemented yet, return -EINVAL.”…””}”(hj£h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hËh³hÊh´M-hjŸubah}”(h]”h ]”h"]”h$]”h&]”uh1j4hjœubj5)”}”(hŒ¯Missing/implied flags: Test to make sure that if unsharing namespace without specifying unsharing of filesystem, correctly unshares both namespace and filesystem information. ”h]”hÌ)”}”(hŒ®Missing/implied flags: Test to make sure that if unsharing namespace without specifying unsharing of filesystem, correctly unshares both namespace and filesystem information.”h]”hŒ®Missing/implied flags: Test to make sure that if unsharing namespace without specifying unsharing of filesystem, correctly unshares both namespace and filesystem information.”…””}”(hj»h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hËh³hÊh´M1hj·ubah}”(h]”h ]”h"]”h$]”h&]”uh1j4hjœubj5)”}”(hŒÿ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. ”h]”hÌ)”}”(hŒþ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.”h]”hŒþ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.”…””}”(hjÓh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hËh³hÊh´M5hjÏubah}”(h]”h ]”h"]”h$]”h&]”uh1j4hjœubj5)”}”(hXPConcurrent 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. ”h]”hÌ)”}”(hXOConcurrent 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.”h]”hXOConcurrent 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.”…””}”(hjëh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hËh³hÊh´M;hjçubah}”(h]”h ]”h"]”h$]”h&]”uh1j4hjœubeh}”(h]”h ]”h"]”h$]”h&]”j j jhjjuh1j/hj˜ubah}”(h]”h ]”h"]”h$]”h&]”uh1j)h³hÊh´M-hjyh²hubeh}”(h]”Œtest-specification”ah ]”h"]”Œ8) test specification”ah$]”h&]”uh1hµhh·h²hh³hÊh´M)ubh¶)”}”(hhh]”(h»)”}”(hŒ9) Future Work”h]”hŒ9) Future Work”…””}”(hj h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hºhj h²hh³hÊh´MCubhÌ)”}”(hX§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().”h]”hX§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().”…””}”(hj$ h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hËh³hÊh´MEhj h²hubeh}”(h]”Œ future-work”ah ]”h"]”Œ9) future work”ah$]”h&]”uh1hµhh·h²hh³hÊh´MCubeh}”(h]”Œunshare-system-call”ah ]”h"]”Œunshare system call”ah$]”h&]”uh1hµhhh²hh³hÊh´Kubeh}”(h]”h ]”h"]”h$]”h&]”Œsource”hÊuh1hŒcurrent_source”NŒ current_line”NŒsettings”Œdocutils.frontend”ŒValues”“”)”}”(hºNŒ generator”NŒ datestamp”NŒ source_link”NŒ source_url”NŒ toc_backlinks”Œentry”Œfootnote_backlinks”KŒ sectnum_xform”KŒstrip_comments”NŒstrip_elements_with_classes”NŒ strip_classes”NŒ report_level”KŒ halt_level”KŒexit_status_level”KŒdebug”NŒwarning_stream”NŒ traceback”ˆŒinput_encoding”Œ utf-8-sig”Œinput_encoding_error_handler”Œstrict”Œoutput_encoding”Œutf-8”Œoutput_encoding_error_handler”je Œerror_encoding”Œutf-8”Œerror_encoding_error_handler”Œbackslashreplace”Œ language_code”Œen”Œrecord_dependencies”NŒconfig”NŒ id_prefix”hŒauto_id_prefix”Œid”Œ dump_settings”NŒdump_internals”NŒdump_transforms”NŒdump_pseudo_xml”NŒexpose_internals”NŒstrict_visitor”NŒ_disable_config”NŒ_source”hÊŒ _destination”NŒ _config_files”]”Œ7/var/lib/git/docbuild/linux/Documentation/docutils.conf”aŒfile_insertion_enabled”ˆŒ raw_enabled”KŒline_length_limit”M'Œpep_references”NŒ pep_base_url”Œhttps://peps.python.org/”Œpep_file_url_template”Œpep-%04d”Œrfc_references”NŒ rfc_base_url”Œ&https://datatracker.ietf.org/doc/html/”Œ tab_width”KŒtrim_footnote_reference_space”‰Œsyntax_highlight”Œlong”Œ smart_quotes”ˆŒsmartquotes_locales”]”Œcharacter_level_inline_markup”‰Œdoctitle_xform”‰Œ docinfo_xform”KŒsectsubtitle_xform”‰Œ image_loading”Œlink”Œembed_stylesheet”‰Œcloak_email_addresses”ˆŒsection_self_link”‰Œenv”NubŒreporter”NŒindirect_targets”]”Œsubstitution_defs”}”Œsubstitution_names”}”Œrefnames”}”Œrefids”}”Œnameids”}”(j? j< jjjjjQjNjÆjÃj—j”j¾j»jíjêj"jjëjèjÖjÓjvjsjjj jjGjDjnjkj j j7 j4 uŒ nametypes”}”(j? ‰j‰j‰jQ‰jƉj—‰j¾‰jí‰j"‰jë‰jÖ‰jv‰j‰j ‰jG‰jn‰j ‰j7 ‰uh}”(j< h·jhÛjjjNjjÃjTj”jsj»jšjêjÉjjðjèj%jÓjîjsjÙjjljj“jDj#jkjJj jyj4 j uŒ footnote_refs”}”Œ citation_refs”}”Œ autofootnotes”]”Œautofootnote_refs”]”Œsymbol_footnotes”]”Œsymbol_footnote_refs”]”Œ footnotes”]”Œ citations”]”Œautofootnote_start”KŒsymbol_footnote_start”KŒ id_counter”Œ collections”ŒCounter”“”}”…”R”Œparse_messages”]”Œtransform_messages”]”Œ transformer”NŒ include_log”]”Œ decoration”Nh²hub.