/* SPDX-License-Identifier: LGPL-2.1+ */
-/***
- This file is part of systemd.
-
- Copyright 2011 Lennart Poettering
-***/
#include <errno.h>
#include <string.h>
#include "bus-label.h"
#include "bus-util.h"
#include "copy.h"
+#include "env-file.h"
#include "env-util.h"
#include "fd-util.h"
-#include "fileio.h"
#include "format-util.h"
#include "fs-util.h"
#include "in-addr-util.h"
+#include "io-util.h"
#include "local-addresses.h"
#include "machine-dbus.h"
#include "machine.h"
+#include "missing_capability.h"
#include "mkdir.h"
+#include "namespace-util.h"
+#include "os-util.h"
#include "path-util.h"
#include "process-util.h"
#include "signal-util.h"
#include "strv.h"
#include "terminal-util.h"
+#include "tmpfile-util.h"
#include "user-util.h"
static BUS_DEFINE_PROPERTY_GET_ENUM(property_get_class, machine_class, MachineClass);
if (socketpair(AF_UNIX, SOCK_SEQPACKET, 0, pair) < 0)
return -errno;
- r = safe_fork("(sd-addr)", FORK_RESET_SIGNALS|FORK_DEATHSIG, &child);
+ r = namespace_fork("(sd-addrns)", "(sd-addr)", NULL, 0, FORK_RESET_SIGNALS|FORK_DEATHSIG,
+ -1, -1, netns_fd, -1, -1, &child);
if (r < 0)
return sd_bus_error_set_errnof(error, r, "Failed to fork(): %m");
if (r == 0) {
pair[0] = safe_close(pair[0]);
- r = namespace_enter(-1, -1, netns_fd, -1, -1);
- if (r < 0)
- _exit(EXIT_FAILURE);
-
n = local_addresses(NULL, 0, AF_UNSPEC, &addresses);
if (n < 0)
_exit(EXIT_FAILURE);
.msg_iovlen = 2,
};
- iov[0] = (struct iovec) { .iov_base = &family, .iov_len = sizeof(family) };
- iov[1] = (struct iovec) { .iov_base = &in_addr, .iov_len = sizeof(in_addr) };
+ iov[0] = IOVEC_MAKE(&family, sizeof(family));
+ iov[1] = IOVEC_MAKE(&in_addr, sizeof(in_addr));
n = recvmsg(pair[0], &mh, 0);
if (n < 0)
return r;
}
- r = wait_for_terminate_and_check("(sd-addr)", child, 0);
+ r = wait_for_terminate_and_check("(sd-addrns)", child, 0);
if (r < 0)
return sd_bus_error_set_errnof(error, r, "Failed to wait for child: %m");
if (r != EXIT_SUCCESS)
switch (m->class) {
case MACHINE_HOST:
- r = load_env_file_pairs(NULL, "/etc/os-release", NULL, &l);
+ r = load_os_release_pairs(NULL, &l);
if (r < 0)
return r;
break;
case MACHINE_CONTAINER: {
- _cleanup_close_ int mntns_fd = -1, root_fd = -1;
+ _cleanup_close_ int mntns_fd = -1, root_fd = -1, pidns_fd = -1;
_cleanup_close_pair_ int pair[2] = { -1, -1 };
_cleanup_fclose_ FILE *f = NULL;
pid_t child;
- r = namespace_open(m->leader, NULL, &mntns_fd, NULL, NULL, &root_fd);
+ r = namespace_open(m->leader, &pidns_fd, &mntns_fd, NULL, NULL, &root_fd);
if (r < 0)
return r;
if (socketpair(AF_UNIX, SOCK_SEQPACKET, 0, pair) < 0)
return -errno;
- r = safe_fork("(sd-osrel)", FORK_RESET_SIGNALS|FORK_DEATHSIG, &child);
+ r = namespace_fork("(sd-osrelns)", "(sd-osrel)", NULL, 0, FORK_RESET_SIGNALS|FORK_DEATHSIG,
+ pidns_fd, mntns_fd, -1, -1, root_fd,
+ &child);
if (r < 0)
return sd_bus_error_set_errnof(error, r, "Failed to fork(): %m");
if (r == 0) {
pair[0] = safe_close(pair[0]);
- r = namespace_enter(-1, mntns_fd, -1, -1, root_fd);
+ r = open_os_release(NULL, NULL, &fd);
+ if (r == -ENOENT)
+ _exit(EXIT_NOT_FOUND);
if (r < 0)
_exit(EXIT_FAILURE);
- fd = open("/etc/os-release", O_RDONLY|O_CLOEXEC|O_NOCTTY);
- if (fd < 0 && errno == ENOENT) {
- fd = open("/usr/lib/os-release", O_RDONLY|O_CLOEXEC|O_NOCTTY);
- if (fd < 0 && errno == ENOENT)
- _exit(EXIT_NOT_FOUND);
- }
- if (fd < 0)
- _exit(EXIT_FAILURE);
-
r = copy_bytes(fd, pair[1], (uint64_t) -1, 0);
if (r < 0)
_exit(EXIT_FAILURE);
pair[1] = safe_close(pair[1]);
- f = fdopen(pair[0], "re");
+ f = fdopen(pair[0], "r");
if (!f)
return -errno;
pair[0] = -1;
- r = load_env_file_pairs(f, "/etc/os-release", NULL, &l);
+ r = load_env_file_pairs(f, "/etc/os-release", &l);
if (r < 0)
return r;
- r = wait_for_terminate_and_check("(sd-osrel)", child, 0);
+ r = wait_for_terminate_and_check("(sd-osrelns)", child, 0);
if (r < 0)
return sd_bus_error_set_errnof(error, r, "Failed to wait for child: %m");
if (r == EXIT_NOT_FOUND)
if (r == 0)
return 1; /* Will call us back */
- master = machine_openpt(m, O_RDWR|O_NOCTTY|O_CLOEXEC);
+ master = machine_openpt(m, O_RDWR|O_NOCTTY|O_CLOEXEC, &pty_name);
if (master < 0)
return master;
- r = ptsname_namespace(master, &pty_name);
- if (r < 0)
- return r;
-
r = sd_bus_message_new_method_return(message, &reply);
if (r < 0)
return r;
break;
case MACHINE_CONTAINER: {
- _cleanup_(sd_bus_unrefp) sd_bus *bus = NULL;
+ _cleanup_(sd_bus_close_unrefp) sd_bus *bus = NULL;
char *address;
r = sd_bus_new(&bus);
if (r == 0)
return 1; /* Will call us back */
- master = machine_openpt(m, O_RDWR|O_NOCTTY|O_CLOEXEC);
+ master = machine_openpt(m, O_RDWR|O_NOCTTY|O_CLOEXEC, &pty_name);
if (master < 0)
return master;
- r = ptsname_namespace(master, &pty_name);
- if (r < 0)
- return r;
-
p = path_startswith(pty_name, "/dev/pts/");
- if (!p)
- return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "PTS name %s is invalid", pty_name);
+ assert(p);
r = container_bus_new(m, error, &allocated_bus);
if (r < 0)
if (strv_isempty(args)) {
args = strv_free(args);
- args = strv_new(path, NULL);
+ args = strv_new(path);
if (!args)
return -ENOMEM;
}
if (r == 0)
return 1; /* Will call us back */
- master = machine_openpt(m, O_RDWR|O_NOCTTY|O_CLOEXEC);
+ master = machine_openpt(m, O_RDWR|O_NOCTTY|O_CLOEXEC, &pty_name);
if (master < 0)
return master;
- r = ptsname_namespace(master, &pty_name);
- if (r < 0)
- return r;
-
p = path_startswith(pty_name, "/dev/pts/");
assert(p);
}
int bus_machine_method_copy(sd_bus_message *message, void *userdata, sd_bus_error *error) {
- const char *src, *dest, *host_path, *container_path, *host_basename, *host_dirname, *container_basename, *container_dirname;
+ const char *src, *dest, *host_path, *container_path, *host_basename, *container_basename, *container_dirname;
_cleanup_close_pair_ int errno_pipe_fd[2] = { -1, -1 };
CopyFlags copy_flags = COPY_REFLINK|COPY_MERGE;
_cleanup_close_ int hostfd = -1;
}
host_basename = basename(host_path);
- t = strdupa(host_path);
- host_dirname = dirname(t);
container_basename = basename(container_path);
t = strdupa(container_path);
container_dirname = dirname(t);
- hostfd = open(host_dirname, O_CLOEXEC|O_RDONLY|O_NOCTTY|O_DIRECTORY);
+ hostfd = open_parent(host_path, O_CLOEXEC, 0);
if (hostfd < 0)
- return sd_bus_error_set_errnof(error, errno, "Failed to open host directory %s: %m", host_dirname);
+ return sd_bus_error_set_errnof(error, hostfd, "Failed to open host directory %s: %m", host_path);
if (pipe2(errno_pipe_fd, O_CLOEXEC|O_NONBLOCK) < 0)
return sd_bus_error_set_errnof(error, errno, "Failed to create pipe: %m");
if (socketpair(AF_UNIX, SOCK_DGRAM, 0, pair) < 0)
return -errno;
- r = safe_fork("(sd-openroot)", FORK_RESET_SIGNALS|FORK_DEATHSIG, &child);
+ r = namespace_fork("(sd-openrootns)", "(sd-openroot)", NULL, 0, FORK_RESET_SIGNALS|FORK_DEATHSIG,
+ -1, mntns_fd, -1, -1, root_fd, &child);
if (r < 0)
return sd_bus_error_set_errnof(error, r, "Failed to fork(): %m");
if (r == 0) {
pair[0] = safe_close(pair[0]);
- r = namespace_enter(-1, mntns_fd, -1, -1, root_fd);
- if (r < 0)
- _exit(EXIT_FAILURE);
-
dfd = open("/", O_RDONLY|O_CLOEXEC|O_DIRECTORY);
if (dfd < 0)
_exit(EXIT_FAILURE);
pair[1] = safe_close(pair[1]);
- r = wait_for_terminate_and_check("(sd-openroot)", child, 0);
+ r = wait_for_terminate_and_check("(sd-openrootns)", child, 0);
if (r < 0)
return sd_bus_error_set_errnof(error, r, "Failed to wait for child: %m");
if (r != EXIT_SUCCESS)