#include <errno.h>
#include <fcntl.h>
#include <stdbool.h>
-#include <stdio.h>
#include <sys/file.h>
#include <sys/prctl.h>
#include <sys/stat.h>
#include "device-util.h"
#include "fd-util.h"
#include "fs-util.h"
+#include "fsck-util.h"
+#include "main-func.h"
#include "parse-util.h"
#include "path-util.h"
#include "proc-cmdline.h"
#include "process-util.h"
+#include "rlimit-util.h"
#include "signal-util.h"
#include "socket-util.h"
#include "special.h"
#include "stdio-util.h"
#include "util.h"
-/* exit codes as defined in fsck(8) */
-enum {
- FSCK_SUCCESS = 0,
- FSCK_ERROR_CORRECTED = 1 << 0,
- FSCK_SYSTEM_SHOULD_REBOOT = 1 << 1,
- FSCK_ERRORS_LEFT_UNCORRECTED = 1 << 2,
- FSCK_OPERATIONAL_ERROR = 1 << 3,
- FSCK_USAGE_OR_SYNTAX_ERROR = 1 << 4,
- FSCK_USER_CANCELLED = 1 << 5,
- FSCK_SHARED_LIB_ERROR = 1 << 7,
-};
-
static bool arg_skip = false;
static bool arg_force = false;
static bool arg_show_progress = false;
(double) cur / (double) max;
}
-static int process_progress(int fd) {
- _cleanup_fclose_ FILE *console = NULL, *f = NULL;
+static int process_progress(int fd, FILE* console) {
+ _cleanup_fclose_ FILE *f = NULL;
usec_t last = 0;
bool locked = false;
int clear = 0, r;
if (fd < 0)
return 0;
- f = fdopen(fd, "re");
+ f = fdopen(fd, "r");
if (!f) {
safe_close(fd);
- return -errno;
+ return log_debug_errno(errno, "Failed to use pipe: %m");
}
- console = fopen("/dev/console", "we");
- if (!console)
- return -ENOMEM;
-
for (;;) {
int pass, m;
unsigned long cur, max;
r = log_warning_errno(errno, "Failed to read from progress pipe: %m");
else if (feof(f))
r = 0;
- else {
- log_warning("Failed to parse progress pipe data");
- r = -EBADMSG;
- }
+ else
+ r = log_warning_errno(SYNTHETIC_ERRNO(errno), "Failed to parse progress pipe data");
+
break;
}
static int run(int argc, char *argv[]) {
_cleanup_close_pair_ int progress_pipe[2] = { -1, -1 };
_cleanup_(sd_device_unrefp) sd_device *dev = NULL;
+ _cleanup_free_ char *dpath = NULL;
+ _cleanup_fclose_ FILE *console = NULL;
const char *device, *type;
bool root_directory;
struct stat st;
int r, exit_status;
pid_t pid;
- log_set_target(LOG_TARGET_AUTO);
- log_parse_environment();
- log_open();
+ log_setup_service();
if (argc > 2) {
log_error("This program expects one or no arguments.");
return 0;
if (argc > 1) {
- device = argv[1];
+ dpath = strdup(argv[1]);
+ if (!dpath)
+ return log_oom();
+
+ device = dpath;
if (stat(device, &st) < 0)
return log_error_errno(errno, "Failed to stat %s: %m", device);
}
}
- if (arg_show_progress &&
+ console = fopen("/dev/console", "we");
+ if (console &&
+ arg_show_progress &&
pipe(progress_pipe) < 0)
return log_error_errno(errno, "pipe(): %m");
cmdline[i++] = device;
cmdline[i++] = NULL;
+ (void) rlimit_nofile_safe();
+
execv(cmdline[0], (char**) cmdline);
_exit(FSCK_OPERATIONAL_ERROR);
}
- progress_pipe[1] = safe_close(progress_pipe[1]);
- (void) process_progress(TAKE_FD(progress_pipe[0]));
+ if (console) {
+ progress_pipe[1] = safe_close(progress_pipe[1]);
+ (void) process_progress(TAKE_FD(progress_pipe[0]), console);
+ }
exit_status = wait_for_terminate_and_check("fsck", pid, WAIT_LOG_ABNORMAL);
if (exit_status < 0)
return exit_status;
- if (exit_status & ~1) {
+ if ((exit_status & ~FSCK_ERROR_CORRECTED) != FSCK_SUCCESS) {
log_error("fsck failed with exit status %i.", exit_status);
if ((exit_status & FSCK_SYSTEM_SHOULD_REBOOT) && root_directory) {
if (exit_status & FSCK_ERROR_CORRECTED)
(void) touch("/run/systemd/quotacheck");
- return exit_status & (FSCK_SYSTEM_SHOULD_REBOOT | FSCK_ERRORS_LEFT_UNCORRECTED);
+ return !!(exit_status & (FSCK_SYSTEM_SHOULD_REBOOT | FSCK_ERRORS_LEFT_UNCORRECTED));
}
DEFINE_MAIN_FUNCTION_WITH_POSITIVE_FAILURE(run);