/* SPDX-License-Identifier: LGPL-2.1+ */
-#ifndef _GNU_SOURCE
-#define _GNU_SOURCE 1
-#endif
+#include "config.h"
+
#include <dirent.h>
#include <errno.h>
#include <fcntl.h>
#include "commands_utils.h"
#include "compiler.h"
#include "conf.h"
-#include "config.h"
#include "confile_utils.h"
#include "error.h"
#include "file_utils.h"
#include <sys/capability.h>
#endif
-#ifndef HAVE_STRLCPY
+#if !HAVE_STRLCPY
#include "strlcpy.h"
#endif
TRACE("Mainloop is ready");
ret = lxc_mainloop(&descr, -1);
- close_prot_errno_disarm(descr.epfd);
+ if (descr.type == LXC_MAINLOOP_EPOLL)
+ close_prot_errno_disarm(descr.epfd);
if (ret < 0 || !handler->init_died)
goto out_mainloop_console;
return 0;
}
+static int core_scheduling(struct lxc_handler *handler)
+{
+ struct lxc_conf *conf = handler->conf;
+ int ret;
+
+ if (!conf->sched_core)
+ return log_trace(0, "No new core scheduling domain requested");
+
+ if (!(handler->ns_clone_flags & CLONE_NEWPID))
+ return syserror_set(-EINVAL, "Core scheduling currently requires a separate pid namespace");
+
+ ret = core_scheduling_cookie_create_threadgroup(handler->pid);
+ if (ret < 0) {
+ if (ret == -ENODEV) {
+ INFO("The kernel doesn't support or doesn't use simultaneous multithreading (SMT)");
+ conf->sched_core = false;
+ return 0;
+ }
+ if (ret == -EINVAL)
+ return syserror("The kernel does not support core scheduling");
+
+ return syserror("Failed to create new core scheduling domain");
+ }
+
+ ret = core_scheduling_cookie_get(handler->pid, &conf->sched_core_cookie);
+ if (ret || !core_scheduling_cookie_valid(conf->sched_core_cookie))
+ return syserror("Failed to retrieve core scheduling domain cookie");
+
+ TRACE("Created new core scheduling domain with cookie %llu",
+ (llu)conf->sched_core_cookie);
+
+ return 0;
+}
+
/* lxc_spawn() performs crucial setup tasks and clone()s the new process which
* exec()s the requested container binary.
* Note that lxc_spawn() runs in the parent namespaces. Any operations performed
handler->clone_flags &= ~CLONE_PIDFD;
TRACE("Cloned child process %d", handler->pid);
+ ret = core_scheduling(handler);
+ if (ret < 0)
+ goto out_delete_net;
+
/* Verify that we can actually make use of pidfds. */
if (!lxc_can_use_pidfd(handler->pidfd))
close_prot_errno_disarm(handler->pidfd);