A synchronous, single-threaded interface for starting processes on Linux

Related tags

Miscellaneoussfork
Overview

Summary

sfork is a prototype for a new system call on Linux which provides a synchronous, single-threaded interface for starting processes.

sfork can be viewed as a variation on vfork which does the minimal amount of work required to make vfork actually useful and usable. In particular, sfork removes all the traditional restrictions vfork has on what you can do in the child process.

Interface

The raw interface is identical to the usual prototypes on Linux for vfork, exit, and execveat:

int sfork();
int sfork_exit(int status);
int sfork_execveat(int dirfd, const char* pathname, char *const argv[],
                   char *const envp[], int flags);

However, unlike traditional fork and vfork, sfork only ever returns once. sfork always returns 0 on success, or a negative value if forking failed for any of the usual reasons, like a cap on the number of processes.

The pid, then, is obtained from the return value of exit or execveat. Of course, those system calls don’t usually return, hence the need to wrap them with sfork-supporting equivalents.

In other words, the control flow for sfork is different from the control flow for fork and vfork.

Control flow for fork and vfork proceeds as below. Each line is numbered according to the order in which it is reached. (Error checking is omitted for simplicity)

int ret; // 1
printf("I'm in the parent"); // 2
ret = vfork();  // 3 and 7
if (ret == 0) { // 4 and 8
  printf("I'm in the child"); // 5
  exec(); // 6
} else {
  printf("I'm in the parent once again"); // 9
  printf("Pid of child is %d", ret); // 10
}

Control flow for sfork proceeds like this (again, with error checking omitted):

int ret; // 1
printf("I'm in the parent"); // 2
sfork();  // 3
printf("I'm in the child"); // 4
ret = exec(); // 5
printf("I'm in the parent once again"); // 6
printf("Pid of child is %d", ret); // 7

Control flow works like that naturally in any language that calls sfork, like any other normal function call.

For example, with the Python wrapper, exceptions thrown in the child automatically propagate up. The subprocess() contextmanager in the Python wrapper catches exceptions, automatically calls exit(1) to exit the child process context and re-enter the parent process context, and rethrows the exception. So if a user application encounters an error while setting up the child, the error is naturally and easily propagated up.

A clean way to understand sfork, is to view it as moving a single existing thread of control from an existing process context, the parent, to a new, fresh process context, the child, which starts off sharing its address space with the parent.

In this view, after a call to sfork, exec is an overloaded operation which does three things: Creates a new address space inside the current process context and loads the executable into it, creates a new thread starting at the executable entry point in the current process context and the new address space, and returns the current thread to the parent process context.

And exit, after a call to sfork, just destroys the current process context (setting the exit code), and returns the current thread to the parent process context.

In this view, sfork actually is much more like unshare than fork or vfork. Like unshare, sfork creates a new execution context and moves the current thread into that execution context. Unfortunately, sfork cannot currently be implemented with unshare; see the discussion in appropriate section below.

Userspace implementation

Recall that vfork shares the memory space between the parent process and child process, and blocks the thread in the parent process that executes vfork. The thread in the parent process is unblocked when the child process calls either exec or exit.

The kernel, when implementing vfork, saves the parent process’s registers and restores them after the parent is resumed. To achieve the behavior of sfork, we would rather the kernel just not save and restore the registers at all, but rather, just continue control flow from the point of the child process’s exec.

If you view vfork as just moving a single thread of control between processes, then the fact that the kernel saves the registers of this thread at the point of calling vfork, and then restores them when calling exec or exit, becomes obviously unnecessary: Merely not doing that save and restore gives us sfork. Without that save and restore, we get a single continuous control flow without any jumps.

So all that the sfork wrapper does is perform the exact opposite jump of the kernel: It saves the child process’s registers at the point of exec or exit, and restore those child registers immediately after the parent process is resumed with the parent’s saved registers. This register save/restore exactly counteracts the kernel’s register save/restore.

Possible implementation using unshare

Instead of calling vfork to create a new process context, sfork could call unshare(CLONE_SIGHAND|CLONE_FILES|CLONE_FS) to create a new process context and move the current thread into it.

Then, instead of calling exec, we would call clone(new_stack, CLONE_VM) while inside the new process context, with an appropriately set up new_stack to immediately call exec.

Then to return to the parent process context, we would call setns(procfd, CLONE_SIGHAND|CLONE_FILES|CLONE_FS), where procfd is a file descriptor pointing to the parent process context.

The main missing piece here is that there’s no way to get a file descriptor representing the parent process context, and setns does not support passing any of CLONE_SIGHAND|CLONE_FILES|CLONE_FS, so there’s no way for the thread to return to the parent process.

Also, unshare doesn’t allow calling CLONE_SIGHAND in multi-threaded applications, for good reason. Properly dealing with signals will be tricky.

Also, unshare doesn’t allow calling CLONE_VM in multi-threaded applications, for reasons which are unclear to me. I think that could be changed to be allowed.

Also, calling clone(new_stack, CLONE_VM) will copy the address space, negating one of the main advantages of a vfork style approach. We may need some other specialized system call that runs an executable in a new address space on a new thread, inheriting all the parts of the execution context.

Owner
Spencer Baugh
Spencer Baugh
Superset custom path for python

It is a common requirement to have superset running under a base url, (https://mydomain.at/analytics/ instead of https://mydomain.at/). I created the

9 Dec 14, 2022
System Information Utility With Python

System-Information-Utility This is a simple utility, for the terminal, which allows you to find out information about your PC. It's very easy to run t

2 Apr 15, 2022
A telegram bot which programed to countdown.

countdown-vi this is a telegram bot which programed to countdown. usage well, first you should specify a exact interval. there is 5 column, very first

Arya Shabane 3 Feb 15, 2022
py-js: python3 objects for max

Simple (and extensible) python3 externals for MaxMSP

Shakeeb Alireza 39 Nov 20, 2022
Clackety Keyboards Powered by Python

KMK: Clackety Keyboards Powered by Python KMK is a feature-rich and beginner-friendly firmware for computer keyboards written and configured in Circui

KMK Firmware 780 Jan 03, 2023
Find functions without canary check (or similar)

Ghidra Check Protector Which non-trivial functions don't reference the stack canary checker (or other, user-defined function)? Place your cursor to th

buherator 3 Jan 17, 2022
Extract continuous and discrete relaxation spectra from G(t)

pyReSpect-time Extract continuous and discrete relaxation spectra from stress relaxation modulus G(t). The papers which describe the method and test c

3 Nov 03, 2022
Capture screen and download off Roku based devices

rokuview Capture screen and download off Roku based devices Tested on Hisense TV with Roku OS built-in No guarantee this will work with all Roku model

3 May 27, 2021
GNU/Linux'u yeni kurulumu bitirmiş olarak açtığınızda sizi karşılayacak bir uygulama.

Hoş Geldiniz GNU/Linux'u yeni kurulumu bitirmiş olarak açtığınızda sizi karşılayacak bir uygulama.

Alperen İsa 96 Oct 30, 2022
Generate your personal 8-bit avatars using Cellular Automata, a mathematical model that simulates life, survival, and extinction

Try the interactive demo here ✨ ✨ Sprites-as-a-Service is an open-source web application that allows you to generate custom 8-bit sprites using Cellul

Lj Miranda 265 Dec 26, 2022
A Web app to Cross-Seed torrents in Deluge/qBittorrent/Transmission

SeedCross A Web app to Cross-Seed torrents in Deluge/qBittorrent/Transmission based on CrossSeedAutoDL Require Jackett Deluge/qBittorrent/Transmission

ccf2012 76 Dec 19, 2022
Vector tile server for the Wildfire Predictive Services Unit

wps-tileserver Vector tile server for the Wildfire Predictive Services Unit Overview The intention of this project is to: provide tools to easily spin

Province of British Columbia 6 Dec 20, 2022
A collection of modern themes for Tkinter TTK

ttkbootstrap A collection of modern flat themes inspired by Bootstrap. Also includes TTK Creator which allows you to easily create and use your own th

Israel Dryer 827 Jan 04, 2023
This is the key combo trainer for League of Legends and Dota 2 players.

This is the key combo trainer for League of Legends and Dota 2 players. Place the mouse cursor on the blue point and press the key combo from the upper-left side of the screen.

Ilya Shpigor 1 Jan 31, 2022
GCP Scripts and API Client Toolss

GCP Scripts and API Client Toolss Script Authentication The scripts and CLI assume GCP Application Default Credentials are set. Credentials can be set

3 Feb 21, 2022
Collapse a set of redundant kmers to use IUPAC degenerate bases

kmer-collapse Collapse a set of redundant kmers to use IUPAC degenerate bases Overview Given an input set of kmers, find the smallest set of kmers tha

Alex Reynolds 3 Jan 06, 2022
Automatização completa do site https://blaze.com

PyBlaze Pyblaze possibilita o acesso a api do site blaze utilizando python, retornando os últimos resultados de crashs e doubles. Agora também é possí

Cleiton Leonel 24 Dec 30, 2022
Ant Colony Optimization for Traveling Salesman Problem

tsp-aco Ant Colony Optimization for Traveling Salesman Problem Dependencies Python 3.8 tqdm numpy matplotlib To run the solver run main.py from the p

Baha Eren YALDIZ 4 Feb 03, 2022
String Spy is a project aimed at improving MacOS defenses.

String Spy is a project aimed at improving MacOS defenses. It allows users to constantly monitor all running processes for user-defined strings, and if it detects a process with such a string it will

10 Dec 13, 2022
Goddard A collection of small, simple strategies for Freqtrade

Goddard A collection of small, simple strategies for Freqtrade. Simply add the strategy you choose in your strategies folder and run. ⚠️ General Crypt

Shane Jones 118 Dec 14, 2022