Skip to content

Commit

Permalink
src/*: implement features
Browse files Browse the repository at this point in the history
Fixes: #1177
Signed-off-by: Sohan Kunkerkar <sohank2602@gmail.com>
  • Loading branch information
sohankunkerkar committed Jun 26, 2023
1 parent 7da99fb commit b0e39d3
Show file tree
Hide file tree
Showing 8 changed files with 633 additions and 2 deletions.
4 changes: 2 additions & 2 deletions Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -130,7 +130,7 @@ dist-luarock: $(LUACRUN_ROCK)
endif

crun_CFLAGS = -I $(abs_top_builddir)/libocispec/src -I $(abs_top_srcdir)/libocispec/src -D CRUN_LIBDIR="\"$(CRUN_LIBDIR)\""
crun_SOURCES = src/crun.c src/run.c src/delete.c src/kill.c src/pause.c src/unpause.c src/spec.c \
crun_SOURCES = src/crun.c src/run.c src/delete.c src/kill.c src/pause.c src/unpause.c src/oci_features.c src/spec.c \
src/exec.c src/list.c src/create.c src/start.c src/state.c src/update.c src/ps.c \
src/checkpoint.c src/restore.c src/libcrun/cloned_binary.c

Expand All @@ -143,7 +143,7 @@ endif

EXTRA_DIST = COPYING COPYING.libcrun README.md NEWS SECURITY.md rpm/crun.spec.in autogen.sh \
src/crun.h src/list.h src/run.h src/delete.h src/kill.h src/pause.h src/unpause.h \
src/create.h src/start.h src/state.h src/exec.h src/spec.h src/update.h src/ps.h \
src/create.h src/start.h src/state.h src/exec.h src/oci_features.h src/spec.h src/update.h src/ps.h \
src/checkpoint.h src/restore.h src/libcrun/seccomp_notify.h src/libcrun/seccomp_notify_plugin.h \
src/libcrun/container.h src/libcrun/seccomp.h src/libcrun/ebpf.h \
src/libcrun/cgroup.h src/libcrun/cgroup-cgroupfs.h \
Expand Down
4 changes: 4 additions & 0 deletions src/crun.c
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@
#include "spec.h"
#include "pause.h"
#include "unpause.h"
#include "oci_features.h"
#include "ps.h"
#include "checkpoint.h"
#include "restore.h"
Expand Down Expand Up @@ -137,6 +138,7 @@ enum
COMMAND_UPDATE,
COMMAND_PAUSE,
COMMAND_UNPAUSE,
COMMAND_FEATURES,
COMMAND_PS,
COMMAND_CHECKPOINT,
COMMAND_RESTORE,
Expand All @@ -155,6 +157,7 @@ struct commands_s commands[] = { { COMMAND_CREATE, "create", crun_command_create
{ COMMAND_UPDATE, "update", crun_command_update },
{ COMMAND_PAUSE, "pause", crun_command_pause },
{ COMMAND_UNPAUSE, "resume", crun_command_unpause },
{ COMMAND_FEATURES, "features", crun_command_features },
#if HAVE_CRIU && HAVE_DLOPEN
{ COMMAND_CHECKPOINT, "checkpoint", crun_command_checkpoint },
{ COMMAND_RESTORE, "restore", crun_command_restore },
Expand All @@ -170,6 +173,7 @@ static char doc[] = "\nCOMMANDS:\n"
"\tcreate - create a container\n"
"\tdelete - remove definition for a container\n"
"\texec - exec a command in a running container\n"
"\tfeatures - show the enabled features\n"
"\tlist - list known containers\n"
"\tkill - send a signal to the container init process\n"
"\tps - show the processes in the container\n"
Expand Down
219 changes: 219 additions & 0 deletions src/libcrun/container.c
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
#include "container.h"
#include "utils.h"
#include "seccomp.h"
#include <seccomp.h>
#include "scheduler.h"
#include "seccomp_notify.h"
#include "custom-handler.h"
Expand All @@ -36,6 +37,7 @@
#include <string.h>
#include <fcntl.h>
#include "status.h"
#include "mount_flags.h"
#include "linux.h"
#include "terminal.h"
#include "io_priority.h"
Expand All @@ -45,7 +47,9 @@
#include <sys/signalfd.h>
#include <sys/epoll.h>
#include <sys/socket.h>
#include <sys/capability.h>
#include <grp.h>
#include <git-version.h>

#ifdef HAVE_SYSTEMD
# include <systemd/sd-daemon.h>
Expand Down Expand Up @@ -92,6 +96,69 @@ struct sync_socket_message_s

typedef runtime_spec_schema_defs_hook hook;

// linux hooks
const char *hooks[] = {
"prestart",
"createRuntime",
"createContainer",
"startContainer",
"poststart",
"poststop"
};

// linux namespaces
static const char *namespaces[] = {
"cgroup",
"ipc",
"mount",
"network",
"pid",
"user",
"uts"
};

static const char *actions[] = {
"SCMP_ACT_ALLOW",
"SCMP_ACT_ERRNO",
"SCMP_ACT_KILL",
"SCMP_ACT_KILL_PROCESS",
"SCMP_ACT_KILL_THREAD",
"SCMP_ACT_LOG",
"SCMP_ACT_NOTIFY",
"SCMP_ACT_TRACE",
"SCMP_ACT_TRAP"
};

const char *operators[] = {
"SCMP_CMP_NE",
"SCMP_CMP_LT",
"SCMP_CMP_LE",
"SCMP_CMP_EQ",
"SCMP_CMP_GE",
"SCMP_CMP_GT",
"SCMP_CMP_MASKED_EQ",
};

static const char *archs[] = {
"SCMP_ARCH_AARCH64",
"SCMP_ARCH_ARM",
"SCMP_ARCH_MIPS",
"SCMP_ARCH_MIPS64",
"SCMP_ARCH_MIPS64N32",
"SCMP_ARCH_MIPSEL",
"SCMP_ARCH_MIPSEL64",
"SCMP_ARCH_MIPSEL64N32",
"SCMP_ARCH_PPC",
"SCMP_ARCH_PPC64",
"SCMP_ARCH_PPC64LE",
"SCMP_ARCH_RISCV64",
"SCMP_ARCH_S390",
"SCMP_ARCH_S390X",
"SCMP_ARCH_X32",
"SCMP_ARCH_X86",
"SCMP_ARCH_X86_64"
};

static const char spec_file[] = "\
{\n\
\"ociVersion\": \"1.0.0\",\n\
Expand Down Expand Up @@ -3706,6 +3773,158 @@ libcrun_container_update_from_values (libcrun_context_t *context, const char *id
return ret;
}

void
populate_array_field (const char ***field, const char *array[], size_t num_elements)
{
*field = xmalloc0 ((num_elements + 1) * sizeof (char *));
size_t i;
for (i = 0; i < num_elements; i++)
(*field)[i] = xstrdup (array[i]);

(*field)[i] = NULL; // Terminate the array with NULL
}

void
populate_capabilities (struct features_info_s *info, const char ***capabilities, size_t *num_capabilities)
{
cap_value_t i;
*num_capabilities = 0;
char *endptr;
for (i = 0;; i++)
{
char *v = cap_to_name (i);
if (v == NULL)
break;
strtol (v, &endptr, 10);
if (endptr != v)
{
// Non-numeric or non-zero value encountered, break the loop
break;
}
(*num_capabilities)++;
}

*capabilities = xmalloc0 ((*num_capabilities + 1) * sizeof (const char *));
size_t index = 0;
int j;
for (i = 0;; i++)
{
char *v = cap_to_name (i);
if (v == NULL)
break;
strtol (v, &endptr, 10);
if (endptr != v)
{
// Non-numeric or non-zero value encountered, break the loop
break;
}

// Convert capability name to uppercase
for (j = 0; v[j] != '\0'; j++)
{
v[j] = toupper (v[j]);
}

(*capabilities)[index] = v;
index++;
}

(*capabilities)[index] = NULL; // Terminate the array with NULL
populate_array_field (&(info->linux.capabilities), *capabilities, *num_capabilities);
}

void
retrieve_mount_options (struct features_info_s **info)
{
// Retrieve mount options from wordlist
const struct propagation_flags_s *mount_options_list = get_mount_flags_from_wordlist ();

// Calculate the number of mount options
size_t num_mount_options = 0;
while (mount_options_list[num_mount_options].name != NULL)
num_mount_options++;

// Allocate memory for mount options in info struct
(*info)->mount_options = xmalloc0 ((num_mount_options + 1) * sizeof (char *));

// Copy mount options to info struct
for (size_t i = 0; i < num_mount_options; i++)
(*info)->mount_options[i] = xstrdup (mount_options_list[i].name);
}

int
libcrun_container_get_features (struct features_info_s **info)
{
// Allocate memory for the features_info_s structure
*info = xmalloc0 (sizeof (struct features_info_s));
size_t num_hooks = sizeof (hooks) / sizeof (hooks[0]);
size_t num_namspaces = sizeof (namespaces) / sizeof (namespaces[0]);
size_t num_capabilities = 0;
const char **capabilities = NULL;
size_t num_actions = sizeof (actions) / sizeof (actions[0]);
size_t num_operators = sizeof (operators) / sizeof (operators[0]);
size_t num_archs = sizeof (archs) / sizeof (archs[0]);

// Hardcoded feature information
(*info)->oci_version_min = xstrdup ("1.0.0");
(*info)->oci_version_max = xstrdup ("1.1.0-rc.3");

// Populate hooks
populate_array_field (&((*info)->hooks), hooks, num_hooks);

// Populate mount_options
retrieve_mount_options (info);

// Populate namespaces
populate_array_field (&((*info)->linux.namespaces), namespaces, num_namspaces);

// Populate capabilities
populate_capabilities (*info, &capabilities, &num_capabilities);

// Hardcode the values for cgroup
(*info)->linux.cgroup.v1 = true;
(*info)->linux.cgroup.v2 = true;
#ifdef HAVE_SYSTEMD
(*info)->linux.cgroup.systemd = true;
(*info)->linux.cgroup.systemd_user = true;
#endif

// Put seccomp values
#ifdef HAVE_SECCOMP
(*info)->linux.seccomp.enabled = true;
// Populate actions
populate_array_field (&((*info)->linux.seccomp.actions), actions, num_actions);
// Populate operators
populate_array_field (&((*info)->linux.seccomp.operators), operators, num_operators);
// Populate archs
populate_array_field (&((*info)->linux.seccomp.archs), archs, num_archs);
#else
(*info)->linux.seccomp.enabled = false;
#endif

// Put values for apparmor and selinux
(*info)->linux.apparmor.enabled = true;
(*info)->linux.selinux.enabled = true;

// Populate the values for annotations
#ifdef HAVE_SECCOMP
{
const struct scmp_version *version = seccomp_version ();

int size = snprintf (NULL, 0, "%u.%u.%u", version->major, version->minor, version->micro) + 1;
char *version_string = xmalloc0 (size);
snprintf (version_string, size, "%u.%u.%u", version->major, version->minor, version->micro);
(*info)->annotations.io_github_seccomp_libseccomp_version = xstrdup (version_string);
}
#endif
(*info)->annotations.org_opencontainers_runc_checkpoint_enabled = true;
(*info)->annotations.run_oci_crun_checkpoint_enabled = true;
(*info)->annotations.io_github_containers_crun_commit = GIT_VERSION;
(*info)->annotations.io_github_containers_crun_version = PACKAGE_VERSION;

return 0;
}

int
libcrun_container_spec (bool root, FILE *out, libcrun_error_t *err arg_unused)
{
Expand Down
Loading

0 comments on commit b0e39d3

Please sign in to comment.