18c2ecf20Sopenharmony_ciunshare system call 28c2ecf20Sopenharmony_ci=================== 38c2ecf20Sopenharmony_ci 48c2ecf20Sopenharmony_ciThis document describes the new system call, unshare(). The document 58c2ecf20Sopenharmony_ciprovides an overview of the feature, why it is needed, how it can 68c2ecf20Sopenharmony_cibe used, its interface specification, design, implementation and 78c2ecf20Sopenharmony_cihow it can be tested. 88c2ecf20Sopenharmony_ci 98c2ecf20Sopenharmony_ciChange Log 108c2ecf20Sopenharmony_ci---------- 118c2ecf20Sopenharmony_civersion 0.1 Initial document, Janak Desai (janak@us.ibm.com), Jan 11, 2006 128c2ecf20Sopenharmony_ci 138c2ecf20Sopenharmony_ciContents 148c2ecf20Sopenharmony_ci-------- 158c2ecf20Sopenharmony_ci 1) Overview 168c2ecf20Sopenharmony_ci 2) Benefits 178c2ecf20Sopenharmony_ci 3) Cost 188c2ecf20Sopenharmony_ci 4) Requirements 198c2ecf20Sopenharmony_ci 5) Functional Specification 208c2ecf20Sopenharmony_ci 6) High Level Design 218c2ecf20Sopenharmony_ci 7) Low Level Design 228c2ecf20Sopenharmony_ci 8) Test Specification 238c2ecf20Sopenharmony_ci 9) Future Work 248c2ecf20Sopenharmony_ci 258c2ecf20Sopenharmony_ci1) Overview 268c2ecf20Sopenharmony_ci----------- 278c2ecf20Sopenharmony_ci 288c2ecf20Sopenharmony_ciMost legacy operating system kernels support an abstraction of threads 298c2ecf20Sopenharmony_cias multiple execution contexts within a process. These kernels provide 308c2ecf20Sopenharmony_cispecial resources and mechanisms to maintain these "threads". The Linux 318c2ecf20Sopenharmony_cikernel, in a clever and simple manner, does not make distinction 328c2ecf20Sopenharmony_cibetween processes and "threads". The kernel allows processes to share 338c2ecf20Sopenharmony_ciresources and thus they can achieve legacy "threads" behavior without 348c2ecf20Sopenharmony_cirequiring additional data structures and mechanisms in the kernel. The 358c2ecf20Sopenharmony_cipower of implementing threads in this manner comes not only from 368c2ecf20Sopenharmony_ciits simplicity but also from allowing application programmers to work 378c2ecf20Sopenharmony_cioutside the confinement of all-or-nothing shared resources of legacy 388c2ecf20Sopenharmony_cithreads. On Linux, at the time of thread creation using the clone system 398c2ecf20Sopenharmony_cicall, applications can selectively choose which resources to share 408c2ecf20Sopenharmony_cibetween threads. 418c2ecf20Sopenharmony_ci 428c2ecf20Sopenharmony_ciunshare() system call adds a primitive to the Linux thread model that 438c2ecf20Sopenharmony_ciallows threads to selectively 'unshare' any resources that were being 448c2ecf20Sopenharmony_cishared at the time of their creation. unshare() was conceptualized by 458c2ecf20Sopenharmony_ciAl Viro in the August of 2000, on the Linux-Kernel mailing list, as part 468c2ecf20Sopenharmony_ciof the discussion on POSIX threads on Linux. unshare() augments the 478c2ecf20Sopenharmony_ciusefulness of Linux threads for applications that would like to control 488c2ecf20Sopenharmony_cishared resources without creating a new process. unshare() is a natural 498c2ecf20Sopenharmony_ciaddition to the set of available primitives on Linux that implement 508c2ecf20Sopenharmony_cithe concept of process/thread as a virtual machine. 518c2ecf20Sopenharmony_ci 528c2ecf20Sopenharmony_ci2) Benefits 538c2ecf20Sopenharmony_ci----------- 548c2ecf20Sopenharmony_ci 558c2ecf20Sopenharmony_ciunshare() would be useful to large application frameworks such as PAM 568c2ecf20Sopenharmony_ciwhere creating a new process to control sharing/unsharing of process 578c2ecf20Sopenharmony_ciresources is not possible. Since namespaces are shared by default 588c2ecf20Sopenharmony_ciwhen creating a new process using fork or clone, unshare() can benefit 598c2ecf20Sopenharmony_cieven non-threaded applications if they have a need to disassociate 608c2ecf20Sopenharmony_cifrom default shared namespace. The following lists two use-cases 618c2ecf20Sopenharmony_ciwhere unshare() can be used. 628c2ecf20Sopenharmony_ci 638c2ecf20Sopenharmony_ci2.1 Per-security context namespaces 648c2ecf20Sopenharmony_ci~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 658c2ecf20Sopenharmony_ci 668c2ecf20Sopenharmony_ciunshare() can be used to implement polyinstantiated directories using 678c2ecf20Sopenharmony_cithe kernel's per-process namespace mechanism. Polyinstantiated directories, 688c2ecf20Sopenharmony_cisuch as per-user and/or per-security context instance of /tmp, /var/tmp or 698c2ecf20Sopenharmony_ciper-security context instance of a user's home directory, isolate user 708c2ecf20Sopenharmony_ciprocesses when working with these directories. Using unshare(), a PAM 718c2ecf20Sopenharmony_cimodule can easily setup a private namespace for a user at login. 728c2ecf20Sopenharmony_ciPolyinstantiated directories are required for Common Criteria certification 738c2ecf20Sopenharmony_ciwith Labeled System Protection Profile, however, with the availability 748c2ecf20Sopenharmony_ciof shared-tree feature in the Linux kernel, even regular Linux systems 758c2ecf20Sopenharmony_cican benefit from setting up private namespaces at login and 768c2ecf20Sopenharmony_cipolyinstantiating /tmp, /var/tmp and other directories deemed 778c2ecf20Sopenharmony_ciappropriate by system administrators. 788c2ecf20Sopenharmony_ci 798c2ecf20Sopenharmony_ci2.2 unsharing of virtual memory and/or open files 808c2ecf20Sopenharmony_ci~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 818c2ecf20Sopenharmony_ci 828c2ecf20Sopenharmony_ciConsider a client/server application where the server is processing 838c2ecf20Sopenharmony_ciclient requests by creating processes that share resources such as 848c2ecf20Sopenharmony_civirtual memory and open files. Without unshare(), the server has to 858c2ecf20Sopenharmony_cidecide what needs to be shared at the time of creating the process 868c2ecf20Sopenharmony_ciwhich services the request. unshare() allows the server an ability to 878c2ecf20Sopenharmony_cidisassociate parts of the context during the servicing of the 888c2ecf20Sopenharmony_cirequest. For large and complex middleware application frameworks, this 898c2ecf20Sopenharmony_ciability to unshare() after the process was created can be very 908c2ecf20Sopenharmony_ciuseful. 918c2ecf20Sopenharmony_ci 928c2ecf20Sopenharmony_ci3) Cost 938c2ecf20Sopenharmony_ci------- 948c2ecf20Sopenharmony_ci 958c2ecf20Sopenharmony_ciIn order to not duplicate code and to handle the fact that unshare() 968c2ecf20Sopenharmony_ciworks on an active task (as opposed to clone/fork working on a newly 978c2ecf20Sopenharmony_ciallocated inactive task) unshare() had to make minor reorganizational 988c2ecf20Sopenharmony_cichanges to copy_* functions utilized by clone/fork system call. 998c2ecf20Sopenharmony_ciThere is a cost associated with altering existing, well tested and 1008c2ecf20Sopenharmony_cistable code to implement a new feature that may not get exercised 1018c2ecf20Sopenharmony_ciextensively in the beginning. However, with proper design and code 1028c2ecf20Sopenharmony_cireview of the changes and creation of an unshare() test for the LTP 1038c2ecf20Sopenharmony_cithe benefits of this new feature can exceed its cost. 1048c2ecf20Sopenharmony_ci 1058c2ecf20Sopenharmony_ci4) Requirements 1068c2ecf20Sopenharmony_ci--------------- 1078c2ecf20Sopenharmony_ci 1088c2ecf20Sopenharmony_ciunshare() reverses sharing that was done using clone(2) system call, 1098c2ecf20Sopenharmony_ciso unshare() should have a similar interface as clone(2). That is, 1108c2ecf20Sopenharmony_cisince flags in clone(int flags, void \*stack) specifies what should 1118c2ecf20Sopenharmony_cibe shared, similar flags in unshare(int flags) should specify 1128c2ecf20Sopenharmony_ciwhat should be unshared. Unfortunately, this may appear to invert 1138c2ecf20Sopenharmony_cithe meaning of the flags from the way they are used in clone(2). 1148c2ecf20Sopenharmony_ciHowever, there was no easy solution that was less confusing and that 1158c2ecf20Sopenharmony_ciallowed incremental context unsharing in future without an ABI change. 1168c2ecf20Sopenharmony_ci 1178c2ecf20Sopenharmony_ciunshare() interface should accommodate possible future addition of 1188c2ecf20Sopenharmony_cinew context flags without requiring a rebuild of old applications. 1198c2ecf20Sopenharmony_ciIf and when new context flags are added, unshare() design should allow 1208c2ecf20Sopenharmony_ciincremental unsharing of those resources on an as needed basis. 1218c2ecf20Sopenharmony_ci 1228c2ecf20Sopenharmony_ci5) Functional Specification 1238c2ecf20Sopenharmony_ci--------------------------- 1248c2ecf20Sopenharmony_ci 1258c2ecf20Sopenharmony_ciNAME 1268c2ecf20Sopenharmony_ci unshare - disassociate parts of the process execution context 1278c2ecf20Sopenharmony_ci 1288c2ecf20Sopenharmony_ciSYNOPSIS 1298c2ecf20Sopenharmony_ci #include <sched.h> 1308c2ecf20Sopenharmony_ci 1318c2ecf20Sopenharmony_ci int unshare(int flags); 1328c2ecf20Sopenharmony_ci 1338c2ecf20Sopenharmony_ciDESCRIPTION 1348c2ecf20Sopenharmony_ci unshare() allows a process to disassociate parts of its execution 1358c2ecf20Sopenharmony_ci context that are currently being shared with other processes. Part 1368c2ecf20Sopenharmony_ci of execution context, such as the namespace, is shared by default 1378c2ecf20Sopenharmony_ci when a new process is created using fork(2), while other parts, 1388c2ecf20Sopenharmony_ci such as the virtual memory, open file descriptors, etc, may be 1398c2ecf20Sopenharmony_ci shared by explicit request to share them when creating a process 1408c2ecf20Sopenharmony_ci using clone(2). 1418c2ecf20Sopenharmony_ci 1428c2ecf20Sopenharmony_ci The main use of unshare() is to allow a process to control its 1438c2ecf20Sopenharmony_ci shared execution context without creating a new process. 1448c2ecf20Sopenharmony_ci 1458c2ecf20Sopenharmony_ci The flags argument specifies one or bitwise-or'ed of several of 1468c2ecf20Sopenharmony_ci the following constants. 1478c2ecf20Sopenharmony_ci 1488c2ecf20Sopenharmony_ci CLONE_FS 1498c2ecf20Sopenharmony_ci If CLONE_FS is set, file system information of the caller 1508c2ecf20Sopenharmony_ci is disassociated from the shared file system information. 1518c2ecf20Sopenharmony_ci 1528c2ecf20Sopenharmony_ci CLONE_FILES 1538c2ecf20Sopenharmony_ci If CLONE_FILES is set, the file descriptor table of the 1548c2ecf20Sopenharmony_ci caller is disassociated from the shared file descriptor 1558c2ecf20Sopenharmony_ci table. 1568c2ecf20Sopenharmony_ci 1578c2ecf20Sopenharmony_ci CLONE_NEWNS 1588c2ecf20Sopenharmony_ci If CLONE_NEWNS is set, the namespace of the caller is 1598c2ecf20Sopenharmony_ci disassociated from the shared namespace. 1608c2ecf20Sopenharmony_ci 1618c2ecf20Sopenharmony_ci CLONE_VM 1628c2ecf20Sopenharmony_ci If CLONE_VM is set, the virtual memory of the caller is 1638c2ecf20Sopenharmony_ci disassociated from the shared virtual memory. 1648c2ecf20Sopenharmony_ci 1658c2ecf20Sopenharmony_ciRETURN VALUE 1668c2ecf20Sopenharmony_ci On success, zero returned. On failure, -1 is returned and errno is 1678c2ecf20Sopenharmony_ci 1688c2ecf20Sopenharmony_ciERRORS 1698c2ecf20Sopenharmony_ci EPERM CLONE_NEWNS was specified by a non-root process (process 1708c2ecf20Sopenharmony_ci without CAP_SYS_ADMIN). 1718c2ecf20Sopenharmony_ci 1728c2ecf20Sopenharmony_ci ENOMEM Cannot allocate sufficient memory to copy parts of caller's 1738c2ecf20Sopenharmony_ci context that need to be unshared. 1748c2ecf20Sopenharmony_ci 1758c2ecf20Sopenharmony_ci EINVAL Invalid flag was specified as an argument. 1768c2ecf20Sopenharmony_ci 1778c2ecf20Sopenharmony_ciCONFORMING TO 1788c2ecf20Sopenharmony_ci The unshare() call is Linux-specific and should not be used 1798c2ecf20Sopenharmony_ci in programs intended to be portable. 1808c2ecf20Sopenharmony_ci 1818c2ecf20Sopenharmony_ciSEE ALSO 1828c2ecf20Sopenharmony_ci clone(2), fork(2) 1838c2ecf20Sopenharmony_ci 1848c2ecf20Sopenharmony_ci6) High Level Design 1858c2ecf20Sopenharmony_ci-------------------- 1868c2ecf20Sopenharmony_ci 1878c2ecf20Sopenharmony_ciDepending on the flags argument, the unshare() system call allocates 1888c2ecf20Sopenharmony_ciappropriate process context structures, populates it with values from 1898c2ecf20Sopenharmony_cithe current shared version, associates newly duplicated structures 1908c2ecf20Sopenharmony_ciwith the current task structure and releases corresponding shared 1918c2ecf20Sopenharmony_civersions. Helper functions of clone (copy_*) could not be used 1928c2ecf20Sopenharmony_cidirectly by unshare() because of the following two reasons. 1938c2ecf20Sopenharmony_ci 1948c2ecf20Sopenharmony_ci 1) clone operates on a newly allocated not-yet-active task 1958c2ecf20Sopenharmony_ci structure, where as unshare() operates on the current active 1968c2ecf20Sopenharmony_ci task. Therefore unshare() has to take appropriate task_lock() 1978c2ecf20Sopenharmony_ci before associating newly duplicated context structures 1988c2ecf20Sopenharmony_ci 1998c2ecf20Sopenharmony_ci 2) unshare() has to allocate and duplicate all context structures 2008c2ecf20Sopenharmony_ci that are being unshared, before associating them with the 2018c2ecf20Sopenharmony_ci current task and releasing older shared structures. Failure 2028c2ecf20Sopenharmony_ci do so will create race conditions and/or oops when trying 2038c2ecf20Sopenharmony_ci to backout due to an error. Consider the case of unsharing 2048c2ecf20Sopenharmony_ci both virtual memory and namespace. After successfully unsharing 2058c2ecf20Sopenharmony_ci vm, if the system call encounters an error while allocating 2068c2ecf20Sopenharmony_ci new namespace structure, the error return code will have to 2078c2ecf20Sopenharmony_ci reverse the unsharing of vm. As part of the reversal the 2088c2ecf20Sopenharmony_ci system call will have to go back to older, shared, vm 2098c2ecf20Sopenharmony_ci structure, which may not exist anymore. 2108c2ecf20Sopenharmony_ci 2118c2ecf20Sopenharmony_ciTherefore code from copy_* functions that allocated and duplicated 2128c2ecf20Sopenharmony_cicurrent context structure was moved into new dup_* functions. Now, 2138c2ecf20Sopenharmony_cicopy_* functions call dup_* functions to allocate and duplicate 2148c2ecf20Sopenharmony_ciappropriate context structures and then associate them with the 2158c2ecf20Sopenharmony_citask structure that is being constructed. unshare() system call on 2168c2ecf20Sopenharmony_cithe other hand performs the following: 2178c2ecf20Sopenharmony_ci 2188c2ecf20Sopenharmony_ci 1) Check flags to force missing, but implied, flags 2198c2ecf20Sopenharmony_ci 2208c2ecf20Sopenharmony_ci 2) For each context structure, call the corresponding unshare() 2218c2ecf20Sopenharmony_ci helper function to allocate and duplicate a new context 2228c2ecf20Sopenharmony_ci structure, if the appropriate bit is set in the flags argument. 2238c2ecf20Sopenharmony_ci 2248c2ecf20Sopenharmony_ci 3) If there is no error in allocation and duplication and there 2258c2ecf20Sopenharmony_ci are new context structures then lock the current task structure, 2268c2ecf20Sopenharmony_ci associate new context structures with the current task structure, 2278c2ecf20Sopenharmony_ci and release the lock on the current task structure. 2288c2ecf20Sopenharmony_ci 2298c2ecf20Sopenharmony_ci 4) Appropriately release older, shared, context structures. 2308c2ecf20Sopenharmony_ci 2318c2ecf20Sopenharmony_ci7) Low Level Design 2328c2ecf20Sopenharmony_ci------------------- 2338c2ecf20Sopenharmony_ci 2348c2ecf20Sopenharmony_ciImplementation of unshare() can be grouped in the following 4 different 2358c2ecf20Sopenharmony_ciitems: 2368c2ecf20Sopenharmony_ci 2378c2ecf20Sopenharmony_ci a) Reorganization of existing copy_* functions 2388c2ecf20Sopenharmony_ci 2398c2ecf20Sopenharmony_ci b) unshare() system call service function 2408c2ecf20Sopenharmony_ci 2418c2ecf20Sopenharmony_ci c) unshare() helper functions for each different process context 2428c2ecf20Sopenharmony_ci 2438c2ecf20Sopenharmony_ci d) Registration of system call number for different architectures 2448c2ecf20Sopenharmony_ci 2458c2ecf20Sopenharmony_ci7.1) Reorganization of copy_* functions 2468c2ecf20Sopenharmony_ci~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 2478c2ecf20Sopenharmony_ci 2488c2ecf20Sopenharmony_ciEach copy function such as copy_mm, copy_namespace, copy_files, 2498c2ecf20Sopenharmony_cietc, had roughly two components. The first component allocated 2508c2ecf20Sopenharmony_ciand duplicated the appropriate structure and the second component 2518c2ecf20Sopenharmony_cilinked it to the task structure passed in as an argument to the copy 2528c2ecf20Sopenharmony_cifunction. The first component was split into its own function. 2538c2ecf20Sopenharmony_ciThese dup_* functions allocated and duplicated the appropriate 2548c2ecf20Sopenharmony_cicontext structure. The reorganized copy_* functions invoked 2558c2ecf20Sopenharmony_citheir corresponding dup_* functions and then linked the newly 2568c2ecf20Sopenharmony_ciduplicated structures to the task structure with which the 2578c2ecf20Sopenharmony_cicopy function was called. 2588c2ecf20Sopenharmony_ci 2598c2ecf20Sopenharmony_ci7.2) unshare() system call service function 2608c2ecf20Sopenharmony_ci~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 2618c2ecf20Sopenharmony_ci 2628c2ecf20Sopenharmony_ci * Check flags 2638c2ecf20Sopenharmony_ci Force implied flags. If CLONE_THREAD is set force CLONE_VM. 2648c2ecf20Sopenharmony_ci If CLONE_VM is set, force CLONE_SIGHAND. If CLONE_SIGHAND is 2658c2ecf20Sopenharmony_ci set and signals are also being shared, force CLONE_THREAD. If 2668c2ecf20Sopenharmony_ci CLONE_NEWNS is set, force CLONE_FS. 2678c2ecf20Sopenharmony_ci 2688c2ecf20Sopenharmony_ci * For each context flag, invoke the corresponding unshare_* 2698c2ecf20Sopenharmony_ci helper routine with flags passed into the system call and a 2708c2ecf20Sopenharmony_ci reference to pointer pointing the new unshared structure 2718c2ecf20Sopenharmony_ci 2728c2ecf20Sopenharmony_ci * If any new structures are created by unshare_* helper 2738c2ecf20Sopenharmony_ci functions, take the task_lock() on the current task, 2748c2ecf20Sopenharmony_ci modify appropriate context pointers, and release the 2758c2ecf20Sopenharmony_ci task lock. 2768c2ecf20Sopenharmony_ci 2778c2ecf20Sopenharmony_ci * For all newly unshared structures, release the corresponding 2788c2ecf20Sopenharmony_ci older, shared, structures. 2798c2ecf20Sopenharmony_ci 2808c2ecf20Sopenharmony_ci7.3) unshare_* helper functions 2818c2ecf20Sopenharmony_ci~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 2828c2ecf20Sopenharmony_ci 2838c2ecf20Sopenharmony_ciFor unshare_* helpers corresponding to CLONE_SYSVSEM, CLONE_SIGHAND, 2848c2ecf20Sopenharmony_ciand CLONE_THREAD, return -EINVAL since they are not implemented yet. 2858c2ecf20Sopenharmony_ciFor others, check the flag value to see if the unsharing is 2868c2ecf20Sopenharmony_cirequired for that structure. If it is, invoke the corresponding 2878c2ecf20Sopenharmony_cidup_* function to allocate and duplicate the structure and return 2888c2ecf20Sopenharmony_cia pointer to it. 2898c2ecf20Sopenharmony_ci 2908c2ecf20Sopenharmony_ci7.4) Finally 2918c2ecf20Sopenharmony_ci~~~~~~~~~~~~ 2928c2ecf20Sopenharmony_ci 2938c2ecf20Sopenharmony_ciAppropriately modify architecture specific code to register the 2948c2ecf20Sopenharmony_cinew system call. 2958c2ecf20Sopenharmony_ci 2968c2ecf20Sopenharmony_ci8) Test Specification 2978c2ecf20Sopenharmony_ci--------------------- 2988c2ecf20Sopenharmony_ci 2998c2ecf20Sopenharmony_ciThe test for unshare() should test the following: 3008c2ecf20Sopenharmony_ci 3018c2ecf20Sopenharmony_ci 1) Valid flags: Test to check that clone flags for signal and 3028c2ecf20Sopenharmony_ci signal handlers, for which unsharing is not implemented 3038c2ecf20Sopenharmony_ci yet, return -EINVAL. 3048c2ecf20Sopenharmony_ci 3058c2ecf20Sopenharmony_ci 2) Missing/implied flags: Test to make sure that if unsharing 3068c2ecf20Sopenharmony_ci namespace without specifying unsharing of filesystem, correctly 3078c2ecf20Sopenharmony_ci unshares both namespace and filesystem information. 3088c2ecf20Sopenharmony_ci 3098c2ecf20Sopenharmony_ci 3) For each of the four (namespace, filesystem, files and vm) 3108c2ecf20Sopenharmony_ci supported unsharing, verify that the system call correctly 3118c2ecf20Sopenharmony_ci unshares the appropriate structure. Verify that unsharing 3128c2ecf20Sopenharmony_ci them individually as well as in combination with each 3138c2ecf20Sopenharmony_ci other works as expected. 3148c2ecf20Sopenharmony_ci 3158c2ecf20Sopenharmony_ci 4) Concurrent execution: Use shared memory segments and futex on 3168c2ecf20Sopenharmony_ci an address in the shm segment to synchronize execution of 3178c2ecf20Sopenharmony_ci about 10 threads. Have a couple of threads execute execve, 3188c2ecf20Sopenharmony_ci a couple _exit and the rest unshare with different combination 3198c2ecf20Sopenharmony_ci of flags. Verify that unsharing is performed as expected and 3208c2ecf20Sopenharmony_ci that there are no oops or hangs. 3218c2ecf20Sopenharmony_ci 3228c2ecf20Sopenharmony_ci9) Future Work 3238c2ecf20Sopenharmony_ci-------------- 3248c2ecf20Sopenharmony_ci 3258c2ecf20Sopenharmony_ciThe current implementation of unshare() does not allow unsharing of 3268c2ecf20Sopenharmony_cisignals and signal handlers. Signals are complex to begin with and 3278c2ecf20Sopenharmony_cito unshare signals and/or signal handlers of a currently running 3288c2ecf20Sopenharmony_ciprocess is even more complex. If in the future there is a specific 3298c2ecf20Sopenharmony_cineed to allow unsharing of signals and/or signal handlers, it can 3308c2ecf20Sopenharmony_cibe incrementally added to unshare() without affecting legacy 3318c2ecf20Sopenharmony_ciapplications using unshare(). 3328c2ecf20Sopenharmony_ci 333