Skip to content

Instantly share code, notes, and snippets.

@ibmibmibm
Created June 16, 2021 14:44
Show Gist options
  • Save ibmibmibm/69ee66e99e765727be29bf7c45d566b6 to your computer and use it in GitHub Desktop.
Save ibmibmibm/69ee66e99e765727be29bf7c45d566b6 to your computer and use it in GitHub Desktop.
diff --git a/configure.ac b/configure.ac
index c003d51..dcee18d 100644
--- a/configure.ac
+++ b/configure.ac
@@ -47,6 +47,9 @@ AS_IF([test "x$enable_dl" != "xno"], [
dnl include support for libkrun (EXPERIMENTAL)
AC_ARG_WITH([libkrun], AS_HELP_STRING([--with-libkrun], [build with libkrun support]))
AS_IF([test "x$with_libkrun" = "xyes"], AC_CHECK_HEADERS([libkrun.h], AC_DEFINE([HAVE_LIBKRUN], 1, [Define if libkrun is available]), [AC_MSG_ERROR([*** Missing libkrun headers])]))
+dnl include support for libssvm (EXPERIMENTAL)
+AC_ARG_WITH([libssvm], AS_HELP_STRING([--with-libssvm], [build with libssvm support]))
+AS_IF([test "x$with_libssvm" = "xyes"], AC_CHECK_HEADERS([ssvm.h], AC_DEFINE([HAVE_LIBSSVM], 1, [Define if libssvm is available]), [AC_MSG_ERROR([*** Missing libssvm headers])]))
dnl libseccomp
AC_ARG_ENABLE([seccomp],
AS_HELP_STRING([--disable-seccomp], [Ignore libseccomp and disable support]))
diff --git a/src/libcrun/container.c b/src/libcrun/container.c
index d3fb017..9c72302 100644
--- a/src/libcrun/container.c
+++ b/src/libcrun/container.c
@@ -51,6 +51,10 @@
# include <libkrun.h>
#endif
+#ifdef HAVE_LIBSSVM
+# include <libssvm.h>
+#endif
+
#ifdef HAVE_SYSTEMD
# include <systemd/sd-daemon.h>
#endif
@@ -726,6 +730,98 @@ libcrun_configure_libkrun (struct container_entrypoint_s *args, libcrun_error_t
#endif
}
+#if HAVE_DLOPEN && HAVE_LIBSSVM
+static int
+libssvm_do_exec (void *container, void *arg, const char *pathname, char *const argv[])
+{
+ runtime_spec_schema_config_schema *def = ((libcrun_container_t *) container)->container_def;
+ int32_t (*ssvm_create_ctx) ();
+ int (*ssvm_start_enter) (uint32_t ctx_id);
+ int32_t (*ssvm_set_vm_config) (uint32_t ctx_id, uint8_t num_vcpus, uint32_t ram_mib);
+ int32_t (*ssvm_set_root) (uint32_t ctx_id, const char *root_path);
+ int32_t (*ssvm_set_workdir) (uint32_t ctx_id, const char *workdir_path);
+ int32_t (*ssvm_set_exec) (uint32_t ctx_id, const char *exec_path, char *const argv[], char *const envp[]);
+ void *handle = arg;
+ uint32_t num_vcpus, ram_mib;
+ int32_t ctx_id, ret;
+ cpu_set_t set;
+
+ ssvm_create_ctx = dlsym (handle, "ssvm_create_ctx");
+ ssvm_start_enter = dlsym (handle, "ssvm_start_enter");
+ ssvm_set_vm_config = dlsym (handle, "ssvm_set_vm_config");
+ ssvm_set_root = dlsym (handle, "ssvm_set_root");
+ ssvm_set_workdir = dlsym (handle, "ssvm_set_workdir");
+ ssvm_set_exec = dlsym (handle, "ssvm_set_exec");
+ if (ssvm_create_ctx == NULL || ssvm_start_enter == NULL || ssvm_set_vm_config == NULL || ssvm_set_root == NULL
+ || ssvm_set_exec == NULL)
+ {
+ fprintf (stderr, "could not find symbol in `libssvm.so`");
+ dlclose (handle);
+ return -1;
+ }
+
+ /* If sched_getaffinity fails, default to 1 vcpu. */
+ num_vcpus = 1;
+ /* If no memory limit is specified, default to 2G. */
+ ram_mib = 2 * 1024;
+
+ if (def && def->linux && def->linux->resources && def->linux->resources->memory
+ && def->linux->resources->memory->limit_present)
+ ram_mib = def->linux->resources->memory->limit / (1024 * 1024);
+
+ CPU_ZERO (&set);
+ if (sched_getaffinity (getpid (), sizeof (set), &set) == 0)
+ num_vcpus = CPU_COUNT (&set);
+
+ ctx_id = ssvm_create_ctx ();
+ if (UNLIKELY (ctx_id < 0))
+ error (EXIT_FAILURE, -ret, "could not create ssvm context");
+
+ ret = ssvm_set_vm_config (ctx_id, num_vcpus, ram_mib);
+ if (UNLIKELY (ret < 0))
+ error (EXIT_FAILURE, -ret, "could not set ssvm vm configuration");
+
+ ret = ssvm_set_root (ctx_id, "/");
+ if (UNLIKELY (ret < 0))
+ error (EXIT_FAILURE, -ret, "could not set ssvm root");
+
+ if (ssvm_set_workdir && def && def->process && def->process->cwd)
+ {
+ ret = ssvm_set_workdir (ctx_id, def->process->cwd);
+ if (UNLIKELY (ret < 0))
+ error (EXIT_FAILURE, -ret, "could not set ssvm working directory");
+ }
+
+ ret = ssvm_set_exec (ctx_id, pathname, &argv[1], NULL);
+ if (UNLIKELY (ret < 0))
+ error (EXIT_FAILURE, -ret, "could not set ssvm executable");
+
+ return ssvm_start_enter (ctx_id);
+}
+#endif
+
+static int
+libcrun_configure_libssvm (struct container_entrypoint_s *args, libcrun_error_t *err)
+{
+#if HAVE_DLOPEN && HAVE_LIBSSVM
+ void *handle;
+#endif
+
+#if HAVE_DLOPEN && HAVE_LIBSSVM
+ handle = dlopen ("libssvm.so", RTLD_NOW);
+ if (handle == NULL)
+ return crun_make_error (err, 0, "could not load `libssvm.so`: %s", dlerror ());
+
+ args->exec_func = libssvm_do_exec;
+ args->exec_func_arg = handle;
+
+ return 0;
+#else
+ (void) args;
+ return crun_make_error (err, ENOTSUP, "libssvm or dlopen not present");
+#endif
+}
+
static int
libcrun_configure_handler (struct container_entrypoint_s *args, libcrun_error_t *err)
{
@@ -739,6 +835,9 @@ libcrun_configure_handler (struct container_entrypoint_s *args, libcrun_error_t
if (strcmp (annotation, "krun") == 0)
return libcrun_configure_libkrun (args, err);
+ if (strcmp (annotation, "ssvm") == 0)
+ return libcrun_configure_libssvm (args, err);
+
return crun_make_error (err, EINVAL, "invalid handler specified `%s`", annotation);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment