mirror of
https://github.com/systemd/systemd
synced 2024-11-05 18:25:39 +00:00
Merge pull request #25266 from poettering/dissect-fsck-fix
dissect: fix fsck invocation
This commit is contained in:
commit
bcb639662e
5 changed files with 48 additions and 7 deletions
|
@ -174,12 +174,35 @@ int fd_cloexec(int fd, bool cloexec) {
|
|||
return RET_NERRNO(fcntl(fd, F_SETFD, nflags));
|
||||
}
|
||||
|
||||
int fd_cloexec_many(const int fds[], size_t n_fds, bool cloexec) {
|
||||
int ret = 0, r;
|
||||
|
||||
assert(n_fds == 0 || fds);
|
||||
|
||||
for (size_t i = 0; i < n_fds; i++) {
|
||||
if (fds[i] < 0) /* Skip gracefully over already invalidated fds */
|
||||
continue;
|
||||
|
||||
r = fd_cloexec(fds[i], cloexec);
|
||||
if (r < 0 && ret >= 0) /* Continue going, but return first error */
|
||||
ret = r;
|
||||
else
|
||||
ret = 1; /* report if we did anything */
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
_pure_ static bool fd_in_set(int fd, const int fdset[], size_t n_fdset) {
|
||||
assert(n_fdset == 0 || fdset);
|
||||
|
||||
for (size_t i = 0; i < n_fdset; i++)
|
||||
for (size_t i = 0; i < n_fdset; i++) {
|
||||
if (fdset[i] < 0)
|
||||
continue;
|
||||
|
||||
if (fdset[i] == fd)
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
@ -252,6 +275,10 @@ static int close_all_fds_special_case(const int except[], size_t n_except) {
|
|||
if (!have_close_range)
|
||||
return 0;
|
||||
|
||||
if (n_except == 1 && except[0] < 0) /* Minor optimization: if we only got one fd, and it's invalid,
|
||||
* we got none */
|
||||
n_except = 0;
|
||||
|
||||
switch (n_except) {
|
||||
|
||||
case 0:
|
||||
|
|
|
@ -56,6 +56,7 @@ DEFINE_TRIVIAL_CLEANUP_FUNC_FULL(DIR*, closedir, NULL);
|
|||
|
||||
int fd_nonblock(int fd, bool nonblock);
|
||||
int fd_cloexec(int fd, bool cloexec);
|
||||
int fd_cloexec_many(const int fds[], size_t n_fds, bool cloexec);
|
||||
|
||||
int get_max_fd(void);
|
||||
|
||||
|
|
|
@ -1372,6 +1372,14 @@ int safe_fork_full(
|
|||
}
|
||||
}
|
||||
|
||||
if (flags & FORK_CLOEXEC_OFF) {
|
||||
r = fd_cloexec_many(except_fds, n_except_fds, false);
|
||||
if (r < 0) {
|
||||
log_full_errno(prio, r, "Failed to turn off O_CLOEXEC on file descriptors: %m");
|
||||
_exit(EXIT_FAILURE);
|
||||
}
|
||||
}
|
||||
|
||||
/* When we were asked to reopen the logs, do so again now */
|
||||
if (flags & FORK_REOPEN_LOG) {
|
||||
log_open();
|
||||
|
|
|
@ -150,6 +150,7 @@ typedef enum ForkFlags {
|
|||
FORK_STDOUT_TO_STDERR = 1 << 11, /* Make stdout a copy of stderr */
|
||||
FORK_FLUSH_STDIO = 1 << 12, /* fflush() stdout (and stderr) before forking */
|
||||
FORK_NEW_USERNS = 1 << 13, /* Run child in its own user namespace */
|
||||
FORK_CLOEXEC_OFF = 1 << 14, /* In the child: turn off O_CLOEXEC on all fds in except_fds[] */
|
||||
} ForkFlags;
|
||||
|
||||
int safe_fork_full(const char *name, const int except_fds[], size_t n_except_fds, ForkFlags flags, pid_t *ret_pid);
|
||||
|
|
|
@ -1327,11 +1327,11 @@ static int is_loop_device(const char *path) {
|
|||
return true;
|
||||
}
|
||||
|
||||
static int run_fsck(const char *node, const char *fstype) {
|
||||
static int run_fsck(int node_fd, const char *fstype) {
|
||||
int r, exit_status;
|
||||
pid_t pid;
|
||||
|
||||
assert(node);
|
||||
assert(node_fd >= 0);
|
||||
assert(fstype);
|
||||
|
||||
r = fsck_exists_for_fstype(fstype);
|
||||
|
@ -1340,16 +1340,20 @@ static int run_fsck(const char *node, const char *fstype) {
|
|||
return 0;
|
||||
}
|
||||
if (r == 0) {
|
||||
log_debug("Not checking partition %s, as fsck for %s does not exist.", node, fstype);
|
||||
log_debug("Not checking partition %s, as fsck for %s does not exist.", FORMAT_PROC_FD_PATH(node_fd), fstype);
|
||||
return 0;
|
||||
}
|
||||
|
||||
r = safe_fork("(fsck)", FORK_RESET_SIGNALS|FORK_CLOSE_ALL_FDS|FORK_RLIMIT_NOFILE_SAFE|FORK_DEATHSIG|FORK_NULL_STDIO, &pid);
|
||||
r = safe_fork_full(
|
||||
"(fsck)",
|
||||
&node_fd, 1, /* Leave the node fd open */
|
||||
FORK_RESET_SIGNALS|FORK_CLOSE_ALL_FDS|FORK_RLIMIT_NOFILE_SAFE|FORK_DEATHSIG|FORK_NULL_STDIO|FORK_CLOEXEC_OFF,
|
||||
&pid);
|
||||
if (r < 0)
|
||||
return log_debug_errno(r, "Failed to fork off fsck: %m");
|
||||
if (r == 0) {
|
||||
/* Child */
|
||||
execl("/sbin/fsck", "/sbin/fsck", "-aT", node, NULL);
|
||||
execl("/sbin/fsck", "/sbin/fsck", "-aT", FORMAT_PROC_FD_PATH(node_fd), NULL);
|
||||
log_open();
|
||||
log_debug_errno(errno, "Failed to execl() fsck: %m");
|
||||
_exit(FSCK_OPERATIONAL_ERROR);
|
||||
|
@ -1439,7 +1443,7 @@ static int mount_partition(
|
|||
rw = m->rw && !(flags & DISSECT_IMAGE_MOUNT_READ_ONLY);
|
||||
|
||||
if (FLAGS_SET(flags, DISSECT_IMAGE_FSCK) && rw) {
|
||||
r = run_fsck(node, fstype);
|
||||
r = run_fsck(m->mount_node_fd, fstype);
|
||||
if (r < 0)
|
||||
return r;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue