diff --git a/flock/flock.c b/flock/flock.c
index 3320cd28..28b6a0f1 100644
--- a/flock/flock.c
+++ b/flock/flock.c
@@ -99,16 +99,33 @@ main(int argc, char **argv, char **argh UNUSED)
 
   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)
   {
@@ -127,11 +144,9 @@ main(int argc, char **argv, char **argh UNUSED)
 #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();
@@ -173,8 +188,11 @@ main(int argc, char **argv, char **argh UNUSED)
    * 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);
@@ -190,6 +208,10 @@ main(int argc, char **argv, char **argh UNUSED)
   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)
diff --git a/flock/flock.h b/flock/flock.h
index 285339ae..988e4fa8 100644
--- a/flock/flock.h
+++ b/flock/flock.h
@@ -5,10 +5,12 @@
 #include "lib/birdlib.h"
 
 void hypervisor_exposed_fork(void);
+void hypervisor_control_socket(void);
 
 struct flock_config {
   const char *hypervisor_name;
   const char *exec_name;
+  const char *control_socket_path;
 };
 
 extern struct flock_config flock_config;
diff --git a/flock/hypervisor.c b/flock/hypervisor.c
index 8b2f955a..0f62c52b 100644
--- a/flock/hypervisor.c
+++ b/flock/hypervisor.c
@@ -2,10 +2,56 @@
 
 #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;