#include <sys/signalfd.h>
#include <grp.h>
#include <linux/fs.h>
-#include <linux/netlink.h>
#include <sys/un.h>
#include <sys/socket.h>
+#include <linux/netlink.h>
#include <systemd/sd-daemon.h>
#include <systemd/sd-bus.h>
#include "fdset.h"
#include "build.h"
#include "fileio.h"
-#include "bus-internal.h"
-#include "bus-message.h"
+#include "bus-util.h"
#ifndef TTY_GID
#define TTY_GID 5
assert(argc >= 0);
assert(argv);
- while ((c = getopt_long(argc, argv, "+hD:u:C:bM:jS:", options, NULL)) >= 0) {
+ while ((c = getopt_long(argc, argv, "+hD:u:bM:jS:", options, NULL)) >= 0) {
switch (c) {
STRV_FOREACH_PAIR(x, y, l) {
_cleanup_free_ char *where = NULL;
+ struct stat source_st, dest_st;
+
+ if (stat(*x, &source_st) < 0) {
+ log_error("failed to stat %s: %m", *x);
+ return -errno;
+ }
where = strjoin(dest, "/", *y, NULL);
if (!where)
return log_oom();
- mkdir_p_label(where, 0755);
+ if (stat(where, &dest_st) == 0) {
+ if ((source_st.st_mode & S_IFMT) != (dest_st.st_mode & S_IFMT)) {
+ log_error("The file types of %s and %s do not match. Refusing bind mount",
+ *x, where);
+ return -EINVAL;
+ }
+ } else {
+ /* Create the mount point, but be conservative -- refuse to create block
+ * and char devices. */
+ if (S_ISDIR(source_st.st_mode))
+ mkdir_p_label(where, 0755);
+ else if (S_ISFIFO(source_st.st_mode))
+ mkfifo(where, 0644);
+ else if (S_ISSOCK(source_st.st_mode))
+ mknod(where, 0644 | S_IFSOCK, 0);
+ else if (S_ISREG(source_st.st_mode))
+ touch(where);
+ else {
+ log_error("Refusing to create mountpoint for file: %s", *x);
+ return -ENOTSUP;
+ }
+ }
if (mount(*x, where, "bind", MS_BIND, NULL) < 0) {
log_error("mount(%s) failed: %m", where);
static int setup_resolv_conf(const char *dest) {
char _cleanup_free_ *where = NULL;
- _cleanup_close_ int fd = -1;
assert(dest);
if (!where)
return log_oom();
- fd = open(where, O_WRONLY|O_CREAT|O_EXCL|O_CLOEXEC|O_NOCTTY|O_NOFOLLOW, 0644);
-
/* We don't really care for the results of this really. If it
* fails, it fails, but meh... */
- if (mount("/etc/resolv.conf", where, "bind", MS_BIND, NULL) < 0)
- log_warning("Failed to bind mount /etc/resolv.conf: %m");
- else
- if (mount("/etc/resolv.conf", where, "bind",
- MS_BIND|MS_REMOUNT|MS_RDONLY, NULL) < 0) {
- log_error("Failed to remount /etc/resolv.conf readonly: %m");
- return -errno;
- }
+ copy_file("/etc/resolv.conf", where, O_TRUNC|O_NOFOLLOW);
return 0;
}
r = sd_bus_call_method(
bus,
- "org.freedesktop.login1",
- "/org/freedesktop/login1",
- "org.freedesktop.login1.Manager",
+ "org.freedesktop.machine1",
+ "/org/freedesktop/machine1",
+ "org.freedesktop.machine1.Manager",
"CreateMachine",
&error,
NULL,
- "sayssuss",
+ "sayssusa(sv)",
arg_machine,
- SD_BUS_APPEND_ID128(arg_uuid),
+ SD_BUS_MESSAGE_APPEND_ID128(arg_uuid),
"nspawn",
"container",
(uint32_t) 0,
- strempty(arg_slice),
- strempty(arg_directory));
+ strempty(arg_directory),
+ 1, "Slice", "s", strempty(arg_slice));
if (r < 0) {
- log_error("Failed to register machine: %s", error.message);
+ log_error("Failed to register machine: %s", error.message ? error.message : strerror(-r));
return r;
}
bool saved_attr_valid = false;
struct winsize ws;
int kmsg_socket_pair[2] = { -1, -1 };
- FDSet *fds = NULL;
+ _cleanup_fdset_free_ FDSet *fds = NULL;
log_parse_environment();
log_open();
}
if ((asprintf((char **)(envp + n_env++), "LISTEN_FDS=%u", n_fd_passed) < 0) ||
- (asprintf((char **)(envp + n_env++), "LISTEN_PID=%lu", (unsigned long) 1) < 0)) {
+ (asprintf((char **)(envp + n_env++), "LISTEN_PID=1") < 0)) {
log_oom();
goto child_fail;
}
free(arg_directory);
free(arg_machine);
- fdset_free(fds);
-
return r;
}