log_switch(1, NULL, NULL);
+ /* Find the original UID/GIDs */
+ uid_t euid = geteuid(), egid = getegid();
+
/* Parse args */
flock_config.exec_name = argv[0] ?: "flock-sim";
int opt;
- while ((opt = getopt(argc, argv, "")) != -1)
+ while ((opt = getopt(argc, argv, "ls:")) != -1)
{
- /* TODO: add some options */
- usage(stderr);
- return 2;
+ switch (opt)
+ {
+ case 'l':
+ flock_config.control_socket_path = "flock-sim.ctl";
+ break;
+
+ case 's':
+ flock_config.control_socket_path = mb_strdup(&root_pool, optarg);
+ break;
+
+ default:
+ usage(stderr);
+ return 2;
+ }
}
+ /* FIXME: have a default */
+ ASSERT_DIE(flock_config.control_socket_path);
+
/* Get hypervisor name */
if (optind != argc - 1)
{
#undef FROB
sigprocmask(SIG_BLOCK, &newmask, &oldmask);
- /* Keep the original UID/GIDs */
- uid_t euid = geteuid(), egid = getegid();
-
- /* First we need to create the PID + mount + user namespace to acquire capabilities */
- SYSCALL(unshare, CLONE_NEWPID | CLONE_NEWNS | CLONE_NEWUSER);
+ /* First we need to create the PID + mount + user namespace to acquire capabilities,
+ * and also time namespace for good measure */
+ SYSCALL(unshare, CLONE_NEWPID | CLONE_NEWNS | CLONE_NEWUSER | CLONE_NEWTIME);
/* Then we have to fork() to become PID 1 of the new PID namespace */
pid_t init_pid = fork();
* let's spawn a child to do external communication before unsharing */
hypervisor_exposed_fork();
- /* And now finally we can go for unsharing the rest -- networks and time */
- SYSCALL(unshare, CLONE_NEWTIME | CLONE_NEWNET);
+ /* We also need to prepare all the hypervisor-init stuff */
+ hypervisor_control_socket();
+
+ /* And now finally we can go for unsharing the networks */
+ SYSCALL(unshare, CLONE_NEWNET);
/* Set signal handlers as this process is init in its PID namespace */
signal(SIGTERM, hypervisor_poweroff_sighandler);
getrlimit(RLIMIT_CORE, &corelimit);
log(L_INFO "Core limit %u %u", corelimit.rlim_cur, corelimit.rlim_max);
+ /* Run worker threads */
+ struct thread_config tc = {};
+ bird_thread_commit(&tc);
+
/* Wait for Godot */
log(L_INFO "Hypervisor running");
while (1)
#include "lib/resource.h"
#include "lib/io-loop.h"
+#include "lib/socket.h"
+
+#include "flock/flock.h"
#include <sys/socket.h>
-/* Local communication structure */
+/**
+ * Main control socket
+ **/
+
+pool *hypervisor_control_socket_pool;
+
+static int
+hcs_connect(sock *s, uint size UNUSED)
+{
+ log(L_INFO "CLI connected: %p", s);
+ sk_close(s);
+ return 1;
+}
+
+static void
+hcs_connect_err(sock *s UNUSED, int err)
+{
+ ASSERT_DIE(err);
+ log(L_INFO "Failed to accept CLI connection: %s", strerror(err));
+}
+
+void
+hypervisor_control_socket(void)
+{
+ struct birdloop *loop = birdloop_new(&root_pool, DOMAIN_ORDER(control), 0, "Control socket");
+ birdloop_enter(loop);
+
+ pool *p = hypervisor_control_socket_pool = rp_new(birdloop_pool(loop), birdloop_domain(loop), "Control socket pool");
+ sock *s = sk_new(p);
+ s->type = SK_UNIX_PASSIVE;
+ s->rx_hook = hcs_connect;
+ s->err_hook = hcs_connect_err;
+ s->rbsize = 1024;
+
+ unlink(flock_config.control_socket_path);
+ if (sk_open_unix(s, loop, flock_config.control_socket_path) < 0)
+ die("Can't create control socket %s: %m", flock_config.control_socket_path);
+
+ birdloop_leave(loop);
+}
+
+/**
+ * Exposed process' communication structure
+ **/
static struct hypervisor_exposed {
pool *p;
sock *s;