Skip to content

Commit

Permalink
Merge pull request #257 from giuseppe/add-support-time
Browse files Browse the repository at this point in the history
linux: add support for TIME namespace
  • Loading branch information
rhatdan committed Feb 13, 2020
2 parents 69b3c5f + 2f1ca79 commit a669dc6
Show file tree
Hide file tree
Showing 3 changed files with 53 additions and 11 deletions.
5 changes: 5 additions & 0 deletions crun.1.md
Expand Up @@ -300,6 +300,11 @@ will skip the `setgroups` syscall that is used to either set the
additional groups specified in the OCI configuration, or to reset the
list of additional groups if none is specified.

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

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

## tmpcopyup mount options

If the `tmpcopyup` option is specified for a tmpfs, then the path that
Expand Down
17 changes: 9 additions & 8 deletions src/libcrun/cgroup.c
Expand Up @@ -126,6 +126,7 @@ enable_controllers (runtime_spec_schema_config_linux_resources *resources, const
{
cleanup_free char *controllers = NULL;
cleanup_free char *tmp_path = NULL;
size_t controllers_len = 0;
bool has_hugetlb = false;
bool has_memory = false;
bool has_cpuset = false;
Expand All @@ -149,13 +150,13 @@ enable_controllers (runtime_spec_schema_config_linux_resources *resources, const
has_hugetlb = resources->hugepage_limits_len;
}

xasprintf (&controllers, "%s %s %s %s %s %s",
has_cpu ? "+cpu" : "",
has_io ? "+io" : "",
has_memory ? "+memory" : "",
has_pids ? "+pids" : "",
has_cpuset ? "+cpuset" : "",
has_hugetlb ? "+hugetlb" : "");
controllers_len = xasprintf (&controllers, "%s %s %s %s %s %s",
has_cpu ? "+cpu" : "",
has_io ? "+io" : "",
has_memory ? "+memory" : "",
has_pids ? "+pids" : "",
has_cpuset ? "+cpuset" : "",
has_hugetlb ? "+hugetlb" : "");

xasprintf (&tmp_path, "%s/", path);

Expand All @@ -176,7 +177,7 @@ enable_controllers (runtime_spec_schema_config_linux_resources *resources, const
if (next_slash)
{
xasprintf (&subtree_control, "%s/cgroup.subtree_control", cgroup_path);
ret = write_file (subtree_control, controllers, strlen (controllers), err);
ret = write_file (subtree_control, controllers, controllers_len, err);
if (ret < 0)
{
int e = crun_error_get_errno (err);
Expand Down
42 changes: 39 additions & 3 deletions src/libcrun/linux.c
Expand Up @@ -115,6 +115,9 @@ static struct linux_namespace_s namespaces[] =
{"user", CLONE_NEWUSER},
#ifdef CLONE_NEWCGROUP
{"cgroup", CLONE_NEWCGROUP},
#endif
#ifdef CLONE_NEWTIME
{"time", CLONE_NEWTIME},
#endif
{NULL, 0}
};
Expand Down Expand Up @@ -2394,6 +2397,7 @@ libcrun_run_linux_container (libcrun_container_t *container,
int namespaces_to_join_index[MAX_NAMESPACES];
size_t n_namespaces_to_join = 0;
int userns_join_index = -1;
bool must_fork = false;

for (i = 0; i < def->linux->namespaces_len; i++)
{
Expand Down Expand Up @@ -2470,6 +2474,13 @@ libcrun_run_linux_container (libcrun_container_t *container,
if (UNLIKELY (ret < 0))
goto out;

if (flags & CLONE_NEWPID)
must_fork = true;
#ifdef CLONE_NEWTIME
if (flags & CLONE_NEWTIME)
must_fork = true;
#endif

/* If we create a new user namespace, create it as part of the clone. */
pid = syscall_clone ((flags & ((userns_join_index >= 0) ? 0 : CLONE_NEWUSER)) | (detach ? 0 : SIGCHLD), NULL);
if (UNLIKELY (pid < 0))
Expand All @@ -2495,7 +2506,7 @@ libcrun_run_linux_container (libcrun_container_t *container,
return crun_make_error (err, errno, "write to sync socket");
}

if (flags & CLONE_NEWPID)
if (must_fork)
{
ret = TEMP_FAILURE_RETRY (read (sync_socket_host, &grandchild, sizeof (grandchild)));
if (UNLIKELY (ret < 0))
Expand Down Expand Up @@ -2602,9 +2613,34 @@ libcrun_run_linux_container (libcrun_container_t *container,
goto out;
}

if (flags & CLONE_NEWPID)
#ifdef CLONE_NEWTIME
if (flags & CLONE_NEWTIME)
{
cleanup_close int fd = open ("/proc/self/timens_offsets", O_WRONLY | O_CLOEXEC);
if (container->container_def->annotations)
{
size_t i;

for (i = 0; i < container->container_def->annotations->len; i++)
{
if (strcmp (container->container_def->annotations->keys[i], "run.oci.timens_offset") == 0)
{
const char *v;

v = container->container_def->annotations->values[i];

ret = write (fd, v, strlen (v));
if (UNLIKELY (ret < 0))
goto out;
}
}
}
}
#endif

if (must_fork)
{
/* A PID namespace is joined when a new process is created. */
/* A PID and a time namespace is joined when a new process is created. */
pid_container = fork ();
if (UNLIKELY (ret < 0))
{
Expand Down

0 comments on commit a669dc6

Please sign in to comment.