static bool arg_read_only = false;
static bool arg_boot = false;
static LinkJournal arg_link_journal = LINK_AUTO;
+static bool arg_link_journal_try = false;
static uint64_t arg_retain =
(1ULL << CAP_CHOWN) |
(1ULL << CAP_DAC_OVERRIDE) |
" --capability=CAP In addition to the default, retain specified\n"
" capability\n"
" --drop-capability=CAP Drop the specified capability from the default set\n"
- " --link-journal=MODE Link up guest journal, one of no, auto, guest, host\n"
- " -j Equivalent to --link-journal=host\n"
+ " --link-journal=MODE Link up guest journal, one of no, auto, guest, host,\n"
+ " try-guest, try-host\n"
+ " -j Equivalent to --link-journal=try-guest\n"
" --read-only Mount the root directory read-only\n"
" --bind=PATH[:PATH] Bind mount a file or directory from the host into\n"
" the container\n"
case 'j':
arg_link_journal = LINK_GUEST;
+ arg_link_journal_try = true;
break;
case ARG_LINK_JOURNAL:
arg_link_journal = LINK_GUEST;
else if (streq(optarg, "host"))
arg_link_journal = LINK_HOST;
- else {
+ else if (streq(optarg, "try-guest")) {
+ arg_link_journal = LINK_GUEST;
+ arg_link_journal_try = true;
+ } else if (streq(optarg, "try-host")) {
+ arg_link_journal = LINK_HOST;
+ arg_link_journal_try = true;
+ } else {
log_error("Failed to parse link journal mode %s", optarg);
return -EINVAL;
}
return log_oom();
r = mkdir_label(where, 0755);
- if (r < 0) {
+ if (r < 0 && errno != EEXIST) {
log_error("creating mount point for tmpfs %s failed: %s", where, strerror(-r));
return r;
if (arg_link_journal == LINK_GUEST) {
if (symlink(q, p) < 0) {
- log_error("Failed to symlink %s to %s: %m", q, p);
- return -errno;
+ if (arg_link_journal_try) {
+ log_debug("Failed to symlink %s to %s, skipping journal setup: %m", q, p);
+ return 0;
+ } else {
+ log_error("Failed to symlink %s to %s: %m", q, p);
+ return -errno;
+ }
}
r = mkdir_p(q, 0755);
}
if (arg_link_journal == LINK_HOST) {
- r = mkdir_p(p, 0755);
+ /* don't create parents here -- if the host doesn't have
+ * permanent journal set up, don't force it here */
+ r = mkdir(p, 0755);
if (r < 0) {
- log_error("Failed to create %s: %m", p);
- return r;
+ if (arg_link_journal_try) {
+ log_debug("Failed to create %s, skipping journal setup: %m", p);
+ return 0;
+ } else {
+ log_error("Failed to create %s: %m", p);
+ return r;
+ }
}
} else if (access(p, F_OK) < 0)
return 0;
}
-static int setup_kdbus(const char *dest, const char *path) {
- const char *p;
-
- if (!path)
- return 0;
-
- p = strappenda(dest, "/dev/kdbus");
- if (mkdir(p, 0755) < 0) {
- log_error("Failed to create kdbus path: %m");
- return -errno;
- }
-
- if (mount(path, p, "bind", MS_BIND, NULL) < 0) {
- log_error("Failed to mount kdbus domain path: %m");
- return -errno;
- }
-
- return 0;
-}
-
static int drop_capabilities(void) {
return capability_bounding_set_drop(~arg_retain, false);
}
return r;
}
- r = sd_bus_message_append(m, "(sv)", "DeviceAllow", "a(ss)", 11,
+ r = sd_bus_message_append(m, "(sv)", "DeviceAllow", "a(ss)", 9,
/* Allow the container to
* access and create the API
* device nodes, so that
* container to ever create
* these device nodes. */
"/dev/pts/ptmx", "rw",
- "char-pts", "rw",
- /* Allow the container
- * access to all kdbus
- * devices. Again, the
- * container cannot create
- * these nodes, only use
- * them. We use a pretty
- * open match here, so that
- * the kernel API can still
- * change. */
- "char-kdbus", "rw",
- "char-kdbus/*", "rw");
+ "char-pts", "rw");
if (r < 0) {
log_error("Failed to add device whitelist: %s", strerror(-r));
return r;
int main(int argc, char *argv[]) {
- _cleanup_free_ char *kdbus_domain = NULL, *device_path = NULL, *root_device = NULL, *home_device = NULL, *srv_device = NULL;
+ _cleanup_free_ char *device_path = NULL, *root_device = NULL, *home_device = NULL, *srv_device = NULL;
bool root_device_rw = true, home_device_rw = true, srv_device_rw = true;
- _cleanup_close_ int master = -1, kdbus_fd = -1, image_fd = -1;
+ _cleanup_close_ int master = -1, image_fd = -1;
_cleanup_close_pair_ int kmsg_socket_pair[2] = { -1, -1 };
_cleanup_fdset_free_ FDSet *fds = NULL;
int r = EXIT_FAILURE, k, n_fd_passed, loop_nr = -1;
goto finish;
}
- if (access("/dev/kdbus/control", F_OK) >= 0) {
-
- if (arg_share_system) {
- kdbus_domain = strdup("/dev/kdbus");
- if (!kdbus_domain) {
- log_oom();
- goto finish;
- }
- } else {
- const char *ns;
-
- ns = strappenda("machine-", arg_machine);
- kdbus_fd = bus_kernel_create_domain(ns, &kdbus_domain);
- if (r < 0)
- log_debug("Failed to create kdbus domain: %s", strerror(-r));
- else
- log_debug("Successfully created kdbus domain as %s", kdbus_domain);
- }
- }
-
if (socketpair(AF_UNIX, SOCK_DGRAM|SOCK_NONBLOCK|SOCK_CLOEXEC, 0, kmsg_socket_pair) < 0) {
log_error("Failed to create kmsg socket pair: %m");
goto finish;
if (mount_tmpfs(arg_directory) < 0)
_exit(EXIT_FAILURE);
- if (setup_kdbus(arg_directory, kdbus_domain) < 0)
- _exit(EXIT_FAILURE);
-
/* Tell the parent that we are ready, and that
* it can cgroupify us to that we lack access
* to certain devices and resources. */