Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -179,7 +179,8 @@ PYTHON_TESTS = tests/test_capabilities.py \
tests/test_resources.py \
tests/test_start.py \
tests/test_exec.py \
tests/test_seccomp.py
tests/test_seccomp.py \
tests/test_time.py

TESTS = $(PYTHON_TESTS) $(UNIT_TESTS)

Expand Down
5 changes: 0 additions & 5 deletions crun.1
Original file line number Diff line number Diff line change
Expand Up @@ -583,11 +583,6 @@ chown -R the_user.the_user /sys/fs/cgroup/systemd
.fi
.RE

.SH \fB\fCrun.oci.timens_offset=ID SEC NSEC\fR
.PP
Specify the offset to be written to /proc/self/timens_offsets when creating
a time namespace.

.SH \fB\fCrun.oci.systemd.subgroup=SUBGROUP\fR
.PP
Override the name for the systemd sub cgroup created under the systemd
Expand Down
5 changes: 0 additions & 5 deletions crun.1.md
Original file line number Diff line number Diff line change
Expand Up @@ -466,11 +466,6 @@ mount cgroup -t cgroup /sys/fs/cgroup/systemd -o none,name=systemd,xattr
chown -R the_user.the_user /sys/fs/cgroup/systemd
```

## `run.oci.timens_offset=ID SEC NSEC`

Specify the offset to be written to /proc/self/timens_offsets when creating
a time namespace.

## `run.oci.systemd.subgroup=SUBGROUP`

Override the name for the systemd sub cgroup created under the systemd
Expand Down
2 changes: 1 addition & 1 deletion libocispec
41 changes: 30 additions & 11 deletions src/libcrun/linux.c
Original file line number Diff line number Diff line change
Expand Up @@ -4326,14 +4326,27 @@ init_container (libcrun_container_t *container, int sync_socket_container, struc
return crun_make_error (err, errno, "unshare");
}

if (init_status->all_namespaces & CLONE_NEWTIME)
if (def->linux->time_offsets)
{
const char *v = find_annotation (container, "run.oci.timens_offset");
if (v)
char fmt_buffer[128];
cleanup_close int fd = -1;

fd = open ("/proc/self/timens_offsets", O_WRONLY | O_CLOEXEC);
if (UNLIKELY (fd < 0))
return crun_make_error (err, errno, "open /proc/self/timens_offsets");
if (def->linux->time_offsets->boottime)
{
ret = write_file ("/proc/self/timens_offsets", v, strlen (v), err);
sprintf (fmt_buffer, "boottime %" PRIi64 " %" PRIu32, def->linux->time_offsets->boottime->secs, def->linux->time_offsets->boottime->nanosecs);
ret = write (fd, fmt_buffer, strlen (fmt_buffer));
if (UNLIKELY (ret < 0))
return ret;
return crun_make_error (err, errno, "write /proc/self/timens_offsets");
}
if (def->linux->time_offsets->monotonic)
{
sprintf (fmt_buffer, "monotonic %" PRIi64 " %" PRIu32, def->linux->time_offsets->monotonic->secs, def->linux->time_offsets->monotonic->nanosecs);
ret = write (fd, fmt_buffer, strlen (fmt_buffer));
if (UNLIKELY (ret < 0))
return crun_make_error (err, errno, "write /proc/self/timens_offsets");
}
}

Expand Down Expand Up @@ -4516,6 +4529,18 @@ libcrun_run_linux_container (libcrun_container_t *container, container_entrypoin
first_clone_args = init_status.namespaces_to_unshare & ~(CLONE_NEWTIME | CLONE_NEWCGROUP);
}

init_status.namespaces_to_unshare &= ~first_clone_args;

/* Check if there are still namespaces that require a fork(). */
if (init_status.namespaces_to_unshare & (CLONE_NEWPID | CLONE_NEWTIME))
{
/* If we need to make another fork(), make sure the NEWPID is always
created as part of that. */
first_clone_args &= ~CLONE_NEWPID;
init_status.namespaces_to_unshare |= CLONE_NEWPID;
init_status.must_fork = true;
}

pid = -1;
if (cgroup_dirfd && *cgroup_dirfd->dirfd >= 0)
{
Expand All @@ -4541,12 +4566,6 @@ libcrun_run_linux_container (libcrun_container_t *container, container_entrypoin
return crun_make_error (err, errno, "clone");
}

init_status.namespaces_to_unshare &= ~first_clone_args;

/* Check if there are still namespaces that require a fork(). */
if (init_status.namespaces_to_unshare & (CLONE_NEWPID | CLONE_NEWTIME))
init_status.must_fork = true;

if (pid)
{
__attribute__ ((unused)) cleanup_pid pid_t pid_to_clean = pid;
Expand Down
77 changes: 77 additions & 0 deletions tests/test_time.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
#!/bin/env python3
# crun - OCI runtime written in C
#
# Copyright (C) 2017, 2018, 2019 Giuseppe Scrivano <[email protected]>
# crun is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# crun is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with crun. If not, see <http://www.gnu.org/licenses/>.

import time
import subprocess
import os
import os.path
import threading
import socket
import json
from tests_utils import *

def test_time_namespace():
timens_offsets = "/proc/self/timens_offsets"

if not os.path.exists(timens_offsets):
return 77
if is_rootless():
return 77

time_offsets = {
"monotonic": {
"secs": 1,
"nanosecs": 2
},
"boottime": {
"secs": 3,
"nanosecs": 4
}
}

conf = base_config()
conf['process']['args'] = ['/init', 'cat', timens_offsets]
conf['linux']['timeOffsets'] = time_offsets
add_all_namespaces(conf,time=True)
try:
out, cid = run_and_get_output(conf, command='run')

for line in out.split("\n"):
parts = line.split()
if len(parts) != 3:
continue
if parts[0] == "monotonic":
if parts[1] != "1":
return -1
if parts[2] != "2":
return -1
if parts[0] == "boottime":
if parts[1] != "3":
return -1
if parts[2] != "4":
return -1
return 0
except:
return -1
return 0

all_tests = {
"time-namespace": test_time_namespace,
}

if __name__ == "__main__":
tests_main(all_tests)
4 changes: 3 additions & 1 deletion tests/tests_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -143,7 +143,7 @@ def parse_proc_status(content):
r[k] = v.strip()
return r

def add_all_namespaces(conf, cgroupns=False, userns=False, netns=True, ipcns=True, utsns=True, pidns=True):
def add_all_namespaces(conf, cgroupns=False, userns=False, netns=True, ipcns=True, utsns=True, pidns=True,time=False):
has = {}
for i in conf['linux']['namespaces']:
has[i['type']] = i['type']
Expand All @@ -160,6 +160,8 @@ def add_all_namespaces(conf, cgroupns=False, userns=False, netns=True, ipcns=Tru
namespaces = namespaces + ["user"]
if netns:
namespaces = namespaces + ["network"]
if time:
namespaces = namespaces + ["time"]
for i in namespaces:
if i not in has:
conf['linux']['namespaces'].append({"type" : i})
Expand Down