f904d33a11
Single-fork daemonize: the child calls setsid() itself rather than
re-enabling bwrap's own --new-session, which was previously removed
(and stays that way) because it only detaches the deeply-nested
sandboxed command, leaving bwrap/nsenter/slocker-lite itself still
attached to the original session -- not real daemonization. Calling
setsid() in slocker-lite's own forked child, before it execs into
nsenter/bwrap, detaches the whole chain at once, since exec() never
changes session membership -- confirmed via ps -o sid,pgid,tty against
a running daemonized session.
The child also ignores SIGHUP (confirmed to survive exec() into bwrap,
unlike a real handler, which exec() resets) and redirects stdin to
/dev/null and stdout/stderr to a log file under
$XDG_STATE_HOME/slocker-lite/logs/ (session_log_file_path(), new
sibling to the existing session_pid_file_path() in pid_file.{h,cpp}).
The original process blocks briefly on a pipe until the child reports
the real bwrap pid (or exits without doing so), then prints it and
exits -- keeping "pid" meaning the same thing everywhere in this
codebase (the same one --list-processes/-e/--exec already use), rather
than introducing a separate daemon-supervisor pid. run_bwrap() gained
an on_bwrap_pid_known callback (bwrap.{h,cpp}) for this, invoked
alongside the existing session-lock creation at the same instant.
The daemonized child is what runs run_container()'s entire existing
body afterward, including the unmount/cleanup that already ran once
bwrap exits -- no separate watcher/reaper process.
Testing caught a real bug before this was correct: the log file gets
renamed from its initial (daemon-pid-named) filename to the final
<container_name>-<bwrap-pid>.log once the real pid is known, but the
parent had already been told the pre-rename path and was never updated
-- fixed by re-reporting the path over the same pipe after the rename.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Gv3s5jckJKzh6JkMoi2Akz
40 lines
1.7 KiB
Meson
40 lines
1.7 KiB
Meson
project('slocker-lite', 'cpp',
|
|
version : '0.0.1',
|
|
default_options : ['warning_level=3', 'cpp_std=c++20'])
|
|
|
|
fmt_dep = dependency('fmt')
|
|
catch2_dep = dependency('catch2', required : get_option('enable_tests'))
|
|
yaml_dep = dependency('yaml-0.1')
|
|
archive_dep = dependency('libarchive')
|
|
json_dep = dependency('nlohmann_json')
|
|
spdlog_dep = dependency('spdlog')
|
|
|
|
conf_data = configuration_data()
|
|
conf_data.set_quoted('PACKAGE', meson.project_name())
|
|
conf_data.set_quoted('VERSION', meson.project_version())
|
|
conf_data.set10('ENABLE_TESTS', get_option('enable_tests'))
|
|
|
|
configure_file(output : 'config.h', configuration : conf_data)
|
|
|
|
slocker_lite = executable('slocker-lite',
|
|
['src/main.cpp', 'src/process.cpp', 'src/oci_image.cpp', 'src/containers_storage.cpp',
|
|
'src/bwrap.cpp', 'src/user_spec.cpp', 'src/config_file.cpp', 'src/volume_mount.cpp',
|
|
'src/pid_file.cpp', 'src/exec_session.cpp', 'src/env_spec.cpp', 'src/daemonize.cpp'],
|
|
include_directories : include_directories('.'),
|
|
dependencies : [fmt_dep, catch2_dep, yaml_dep, archive_dep, json_dep, spdlog_dep],
|
|
install : true)
|
|
|
|
# Bind-mounted into the sandbox by -r/--run's --user/--group handling (src/bwrap.cpp),
|
|
# so it must be dependency-free and statically linked to run regardless of what
|
|
# libc/libraries the container image itself has.
|
|
priv_drop_helper = executable('slocker-lite-priv-drop',
|
|
['src/priv_drop_helper.cpp'],
|
|
link_args : ['-static'],
|
|
install : true)
|
|
|
|
fixture_tar = custom_target('oci-fixture',
|
|
output : 'fixture.tar',
|
|
command : [find_program('python3'), files('tests/gen_fixture.py'), '@OUTPUT@'])
|
|
|
|
test('test', find_program('python3'), args : [files('tests/run_test.py'), slocker_lite, fixture_tar])
|