Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

lib/posix-process: Add vfork & execve #1386

Open
wants to merge 9 commits into
base: staging
Choose a base branch
from

Conversation

michpappas
Copy link
Member

@michpappas michpappas commented Apr 16, 2024

Prerequisite checklist

  • Read the contribution guidelines regarding submitting new changes to the project;
  • Tested your changes against relevant architectures and platforms;
  • Ran the checkpatch.uk on your commit series before opening this PR;
  • Updated relevant documentation.

Base target

  • Architecture(s): [N/A]
  • Platform(s): [N/A]
  • Application(s): [N/A]

Additional configuration

  • CONFIG_LIBPOSIX_PROCESS_EXECVE: Enables the execve() syscall
  • CONFIG_LIBPOSIX_PROCESS_VFORK: Enables the vfork() syscall
  • CONFIG_LIBUKBINFMT: Enables the ukbinfmt library

Description of changes

This PR adds support for vfork() / execve() to libposix-process. This provides the foundation for running multiprocess applications on Unikraft.

vfork() creates a child process that shares the same memory with the calling thread, including the stack. Upon vfork() the parent is suspended until the child calls execve() or _exit() to prevent the parent's state from being corrupted. Due to above, the only permissible actions taken by the child are:

  • Update a variable of type pid_t to store its return value.
  • Calling any function other than one of the functions of the exec(2) family, or _exit(2).

Any action besides the above results into undefined behavior.

For a more elaborate description on vfork() see vfork(2).

execve() implements the standard behavior described in execve(2). To provide flexibility on the supported binary formats the implementation relies on libukbinfmt, which is also introducedin this series. Similarly to linux, this provides a minimal framework for registering loaders that handle different binary formats, introducing the ability of loading interpreted scripts. The implementation may be extended with support for linux's binfmt_misc fs, should such a use-case arise. The implementation of the ELF ukbinfmt loader is introduced in app-elfloader.

GitHub-Depends-On: #1316
GitHub-Depends-On: #1322
GitHub-Depends-On: #1346
GitHub-Depends-On: unikraft/app-elfloader#79

@michpappas michpappas requested review from a team as code owners April 16, 2024 16:08
@github-actions github-actions bot added arch/arm arch/arm64 arch/x86_64 area/arch Unikraft Architecture area/include Part of include/uk area/lib Internal Unikraft Microlibrary area/plat Unikraft Patform lang/c Issues or PRs to do with C/C++ lib/nolibc Only neccessary subset of libc functionality lib/posix-process Information about system parameters lib/syscall_shim lib/ukboot lib/uksched lib/ukschedcoop lib/vfscore VFS Core Interface plat/common Common to all platforms plat/kvm Unikraft for KVM labels Apr 16, 2024
@nderjung nderjung added the release-note Denotes a PR that will be considered when it comes time to generate release notes. label Apr 16, 2024
@razvand razvand added this to the v0.17.0 (Calypso) milestone Apr 28, 2024
Copy link
Member

@mogasergiu mogasergiu left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi there 👋 👨‍⚕️ . Had a brief go at this. I will have a deeper look once we get the dependency PRs in.

lib/Makefile.uk Show resolved Hide resolved
lib/ukbinfmt/include/uk/binfmt.h Outdated Show resolved Hide resolved
lib/posix-process/process.h Show resolved Hide resolved
lib/posix-process/arch/arm64/execve.c Outdated Show resolved Hide resolved
lib/posix-process/arch/x86_64/execve.c Outdated Show resolved Hide resolved
lib/posix-process/arch/arm64/execve.c Show resolved Hide resolved
lib/posix-process/arch/x86_64/execve.c Outdated Show resolved Hide resolved
lib/posix-process/clone.c Show resolved Hide resolved
lib/posix-process/clone.c Outdated Show resolved Hide resolved
lib/posix-process/clone.c Outdated Show resolved Hide resolved
@michpappas michpappas force-pushed the michpappas/feature/vfork_execve branch 5 times, most recently from b36691a to b251f78 Compare July 25, 2024 12:42
arch/arm/arm64/include/uk/asm/lcpu.h Show resolved Hide resolved
lib/ukbinfmt/binfmt.c Outdated Show resolved Hide resolved
lib/ukbinfmt/binfmt.c Show resolved Hide resolved
lib/ukbinfmt/binfmt.c Show resolved Hide resolved
lib/ukbinfmt/binfmt.c Outdated Show resolved Hide resolved
lib/posix-process/clone.c Outdated Show resolved Hide resolved
lib/posix-process/clone.c Show resolved Hide resolved
lib/posix-process/clone.c Show resolved Hide resolved
lib/posix-process/vfork.c Outdated Show resolved Hide resolved
lib/posix-process/vfork.c Outdated Show resolved Hide resolved
@michpappas michpappas force-pushed the michpappas/feature/vfork_execve branch from b251f78 to 3f47c41 Compare July 30, 2024 03:52
Add an architecture specific getter for the stack pointer of a
`struct __regs`.

Signed-off-by: Sergiu Moga <sergiu@unikraft.io>
Signed-off-by: Michalis Pappas <michalis@unikraft.io>
Co-authored-by: Michalis Pappas <michalis@unikraft.io>
libukbinfmt provides a minimal framework to register handlers of
executable files. Typical examples include binary executables like
ELF objects, or interpreted files like *nix scripts that use the
sha-bang sequence to specify an interpreter.

This commit only implements the functionality required to register
and execute loaders within the kernel's scope. Additional
functionality incl. application support via Linux's `binfmt_misc`
API shall be added as a future extension.

Checkpatch-Ignore: COMPLEX_MACRO
Checkpatch-Ignore: MACRO_ARG_REUSE

Signed-off-by: Michalis Pappas <michalis@unikraft.io>
Add definition of ARG_MAX to limits.h. POSIX defines ARG_MAX as the
number of bytes available for the combined arguments and env vars
of a new process. Whether that additionally includes NULL terminator,
pointers, or alignment bytes is IMPLEMENTATION DEFINED.

Signed-off-by: Michalis Pappas <michalis@unikraft.io>
Migrate the definitions of tid2pthread() and tid2pprocess() to
the private process.h to make them available to the rest of the
library. This requires to additionally migrate the definitions of
struct posix_process() and struct posix_thread().

Signed-off-by: Michalis Pappas <michalis@unikraft.io>
@michpappas michpappas force-pushed the michpappas/feature/vfork_execve branch 2 times, most recently from cbd0e09 to 428de80 Compare July 30, 2024 08:54
lib/posix-process/process.h Outdated Show resolved Hide resolved
lib/posix-process/Makefile.uk Show resolved Hide resolved
lib/posix-process/arch/x86_64/execve.c Outdated Show resolved Hide resolved
lib/posix-process/arch/x86_64/execve.c Show resolved Hide resolved
lib/posix-process/execve.c Show resolved Hide resolved
lib/posix-process/arch/x86_64/execve.c Show resolved Hide resolved
lib/posix-process/execve.c Outdated Show resolved Hide resolved
lib/posix-process/clone.c Outdated Show resolved Hide resolved
The state provides information on whether a posix_thread is
running, blocked, or exited.

Notice that posix_thread_state is only updated by operations
at the posix_process / posix_thread level and may not
always be in sync with the state of the underlying uk_thread.
This specifically applies to the POSIX_THREAD_RUNNING state,
which may not be accurate e.g. if the underlying uk_thread
blocks at the scheduler due to a lock.

On the other hand, the variants of POSIX_STATE_BLOCKED always
reflect the state of a posix_thread, as it is certain that the
underlying uk_thread will also be blocked from the scheduler.

Given the above, a check against POSIX_STATE_RUNNING should only be
used to check if the state of a posix-thread is not terminated or
blocked.

Signed-off-by: Michalis Pappas <michalis@unikraft.io>
Add a field to posix_thread to keep track of its parent. This is
populated during the creation of a posix_thread, and it is used
for deriving the parent's state in execve() / exit().

Signed-off-by: Michalis Pappas <michalis@unikraft.io>
Add implementation for execve(). For more info see execve(2).

Requires a binfmt ELF loader. The default loader is provided by
app-bincompat.

Checkpatch-Ignore: AVOID_EXTERNS

Signed-off-by: Michalis Pappas <michalis@unikraft.io>
vfork() sets the CLONE_VM and CLONE_VFORK flags. This triggers an
error in the clone handlers of vfscore as CLONE_FS is not set. Update
the handlers to additionally check against CLONE_VM, as that also
implies that the parent and child share filesystem state.

Signed-off-by: Michalis Pappas <michalis@unikraft.io>
@michpappas michpappas force-pushed the michpappas/feature/vfork_execve branch from 428de80 to 924c4aa Compare July 31, 2024 03:23
The vfork() syscall is equivalent to calling clone() with the flags
parameter set to CLONE_VM | CLONE_VFORK | SIGCHLD. Update clone() to
support CLONE_VFORK and CLONE_VM. Implement vfork() as a wrapper of
clone().

For more info see vfork(2).

Signed-off-by: Michalis Pappas <michalis@unikraft.io>
@michpappas michpappas force-pushed the michpappas/feature/vfork_execve branch from 924c4aa to 27304a9 Compare July 31, 2024 07:57
Copy link
Member

@mogasergiu mogasergiu left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reviewed-by: Sergiu Moga sergiu@unikraft.io

@michpappas
Copy link
Member Author

@mogasergiu

ok but this still feels awkward and I am thinking of the case where someone may pass something to clone and wake up to clonetab having a different value somehow. Maybe at least there should be a warning/note comment somewhere?

I pushed an update where I shadow elements of cl_args into locals.

@razvand razvand removed this from the v0.18.0 (Helene) milestone Aug 19, 2024
@razvand razvand removed the request for review from RaduNichita October 2, 2024 06:02
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
arch/arm arch/arm64 arch/x86_64 area/arch Unikraft Architecture area/include Part of include/uk area/lib Internal Unikraft Microlibrary area/plat Unikraft Patform area/support Support scripts, tools, services. lang/c Issues or PRs to do with C/C++ lib/nolibc Only neccessary subset of libc functionality lib/posix-process Information about system parameters lib/syscall_shim lib/ukboot lib/uksched lib/ukschedcoop lib/vfscore VFS Core Interface plat/common Common to all platforms plat/kvm Unikraft for KVM release-note Denotes a PR that will be considered when it comes time to generate release notes.
Projects
Status: No status
Status: 🧊 Icebox
Development

Successfully merging this pull request may close these issues.

5 participants