#include "blockdev-util.h"
#include "chase-symlinks.h"
#include "device-util.h"
+#include "devnum-util.h"
#include "dirent-util.h"
#include "env-util.h"
#include "fd-util.h"
size_t *ret_size) {
_cleanup_free_ char *buffer = NULL, *suffixed_url = NULL;
- _cleanup_(close_pairp) int pfd[2] = { -1, -1 };
+ _cleanup_(close_pairp) int pfd[2] = PIPE_EBADF;
_cleanup_fclose_ FILE *manifest = NULL;
size_t size = 0;
pid_t pid;
log_info("%s Acquiring manifest file %s%s", special_glyph(SPECIAL_GLYPH_DOWNLOAD),
suffixed_url, special_glyph(SPECIAL_GLYPH_ELLIPSIS));
- r = safe_fork("(sd-pull)", FORK_RESET_SIGNALS|FORK_DEATHSIG|FORK_LOG, &pid);
+ r = safe_fork_full("(sd-pull)",
+ (int[]) { -EBADF, pfd[1], STDERR_FILENO },
+ NULL, 0,
+ FORK_RESET_SIGNALS|FORK_CLOSE_ALL_FDS|FORK_DEATHSIG|FORK_REARRANGE_STDIO|FORK_LOG,
+ &pid);
if (r < 0)
return r;
if (r == 0) {
NULL
};
- pfd[0] = safe_close(pfd[0]);
-
- r = rearrange_stdio(-1, pfd[1], STDERR_FILENO);
- if (r < 0) {
- log_error_errno(r, "Failed to rearrange stdin/stdout: %m");
- _exit(EXIT_FAILURE);
- }
-
(void) unsetenv("NOTIFY_SOCKET");
execv(pull_binary_path(), (char *const*) cmdline);
log_error_errno(errno, "Failed to execute %s tool: %m", pull_binary_path());
assert(rr);
if (rr->path_auto) {
+ struct stat orig_root_stats;
- /* NB: we don't actually check the backing device of the root fs "/", but of "/usr", in order
- * to support environments where the root fs is a tmpfs, and the OS itself placed exclusively
- * in /usr/. */
+ /* NB: If the root mount has been replaced by some form of volatile file system (overlayfs),
+ * the original root block device node is symlinked in /run/systemd/volatile-root. Let's
+ * follow that link here. If that doesn't exist, we check the backing device of "/usr". We
+ * don't actually check the backing device of the root fs "/", in order to support
+ * environments where the root fs is a tmpfs, and the OS itself placed exclusively in
+ * /usr/. */
if (rr->type != RESOURCE_PARTITION)
return log_error_errno(SYNTHETIC_ERRNO(EOPNOTSUPP),
return log_error_errno(SYNTHETIC_ERRNO(EPERM),
"Block device is not allowed when using --root= mode.");
- r = get_block_device_harder("/usr/", &d);
+ r = stat("/run/systemd/volatile-root", &orig_root_stats);
+ if (r < 0) {
+ if (errno == ENOENT) /* volatile-root not found */
+ r = get_block_device_harder("/usr/", &d);
+ else
+ return log_error_errno(r, "Failed to stat /run/systemd/volatile-root: %m");
+ } else if (!S_ISBLK(orig_root_stats.st_mode)) /* symlink was present but not block device */
+ return log_error_errno(SYNTHETIC_ERRNO(ENOTBLK), "/run/systemd/volatile-root is not linked to a block device.");
+ else /* symlink was present and a block device */
+ d = orig_root_stats.st_rdev;
} else if (rr->type == RESOURCE_PARTITION) {
- _cleanup_close_ int fd = -1, real_fd = -1;
+ _cleanup_close_ int fd = -EBADF, real_fd = -EBADF;
_cleanup_free_ char *resolved = NULL;
struct stat st;