summaryrefslogtreecommitdiffstats
path: root/disk-utils/fsck.c
diff options
context:
space:
mode:
authorStanislav Brabec2015-04-27 17:20:55 +0200
committerKarel Zak2015-04-28 13:16:41 +0200
commit07c09a29eaf359f75a8adf8bb0320f3f2d97c5cc (patch)
tree408b022e123f7e6daafd46cea6a0bba40cd8b062 /disk-utils/fsck.c
parenthwclock: fix spelling, punctuation and formatting mistakes in the man page (diff)
downloadkernel-qcow2-util-linux-07c09a29eaf359f75a8adf8bb0320f3f2d97c5cc.tar.gz
kernel-qcow2-util-linux-07c09a29eaf359f75a8adf8bb0320f3f2d97c5cc.tar.xz
kernel-qcow2-util-linux-07c09a29eaf359f75a8adf8bb0320f3f2d97c5cc.zip
fsck: implement fsck -r {fd}
Make possible sending of statistics to a dedicated file descriptor. Rationale: When UI is calling fsck from a remote terminal, fsck progress needs to be sent to stdout. It is mixed there with output of statistics, and it is impossible to parse the output to get the statistics. Now it will be possible e. g. with "fsck -C -r 3 /dev/sda1" Note: Code in if and else is intentionally partially duplicated. Current human readable output of floats does not conform to locale conventions, and may be changed in future. But we want to keep machine readable output exactly same as it is now. [kzak@redhat.com: - don't use report_stats_fd globally] Signed-off-by: Stanislav Brabec <sbrabec@suse.cz> Signed-off-by: Karel Zak <kzak@redhat.com>
Diffstat (limited to 'disk-utils/fsck.c')
-rw-r--r--disk-utils/fsck.c64
1 files changed, 52 insertions, 12 deletions
diff --git a/disk-utils/fsck.c b/disk-utils/fsck.c
index 299a77525..6ef8ad198 100644
--- a/disk-utils/fsck.c
+++ b/disk-utils/fsck.c
@@ -141,6 +141,7 @@ static int progress;
static int progress_fd;
static int force_all_parallel;
static int report_stats;
+static FILE *report_stats_file;
static int num_running;
static int max_running;
@@ -586,16 +587,28 @@ static void print_stats(struct fsck_instance *inst)
timersub(&inst->end_time, &inst->start_time, &delta);
- fprintf(stdout, "%s: status %d, rss %ld, "
- "real %ld.%06ld, user %d.%06d, sys %d.%06d\n",
- fs_get_device(inst->fs),
- inst->exit_status,
- inst->rusage.ru_maxrss,
- delta.tv_sec, delta.tv_usec,
- (int)inst->rusage.ru_utime.tv_sec,
- (int)inst->rusage.ru_utime.tv_usec,
- (int)inst->rusage.ru_stime.tv_sec,
- (int)inst->rusage.ru_stime.tv_usec);
+ if (report_stats_file)
+ fprintf(report_stats_file, "%s %d %ld "
+ "%ld.%06ld %d.%06d %d.%06d\n",
+ fs_get_device(inst->fs),
+ inst->exit_status,
+ inst->rusage.ru_maxrss,
+ delta.tv_sec, delta.tv_usec,
+ (int)inst->rusage.ru_utime.tv_sec,
+ (int)inst->rusage.ru_utime.tv_usec,
+ (int)inst->rusage.ru_stime.tv_sec,
+ (int)inst->rusage.ru_stime.tv_usec);
+ else
+ fprintf(stdout, "%s: status %d, rss %ld, "
+ "real %ld.%06ld, user %d.%06d, sys %d.%06d\n",
+ fs_get_device(inst->fs),
+ inst->exit_status,
+ inst->rusage.ru_maxrss,
+ delta.tv_sec, delta.tv_usec,
+ (int)inst->rusage.ru_utime.tv_sec,
+ (int)inst->rusage.ru_utime.tv_usec,
+ (int)inst->rusage.ru_stime.tv_sec,
+ (int)inst->rusage.ru_stime.tv_usec);
}
/*
@@ -1371,11 +1384,12 @@ static void __attribute__((__noreturn__)) usage(FILE *out)
fputs(_(" -N do not execute, just show what would be done\n"), out);
fputs(_(" -P check filesystems in parallel, including root\n"), out);
fputs(_(" -R skip root filesystem; useful only with '-A'\n"), out);
- fputs(_(" -r report statistics for each device checked\n"), out);
+ fputs(_(" -r [<fd>] report statistics for each device checked;\n"
+ " file descriptor is for GUIs\n"), out);
fputs(_(" -s serialize the checking operations\n"), out);
fputs(_(" -T do not show the title on startup\n"), out);
fputs(_(" -t <type> specify filesystem types to be checked;\n"
- " <type> is allowed to be a comma-separated list\n"), out);
+ " <type> is allowed to be a comma-separated list\n"), out);
fputs(_(" -V explain what is being done\n"), out);
fputs(_(" -? display this help and exit\n"), out);
@@ -1399,6 +1413,7 @@ static void parse_argv(int argc, char *argv[])
int opt = 0;
int opts_for_fsck = 0;
struct sigaction sa;
+ int report_stats_fd = 0;
/*
* Set up signal action
@@ -1504,6 +1519,21 @@ static void parse_argv(int argc, char *argv[])
break;
case 'r':
report_stats = 1;
+ if (arg[j+1]) { /* -r<fd> */
+ report_stats_fd = string_to_int(arg+j+1);
+ if (report_stats_fd < 0)
+ report_stats_fd = 0;
+ else
+ goto next_arg;
+ } else if (i+1 < argc && *argv[i+1] != '-') { /* -r <fd> */
+ report_stats_fd = string_to_int(argv[i+1]);
+ if (report_stats_fd < 0)
+ report_stats_fd = 0;
+ else {
+ ++i;
+ goto next_arg;
+ }
+ }
break;
case 's':
serialize = 1;
@@ -1542,6 +1572,16 @@ static void parse_argv(int argc, char *argv[])
opt = 0;
}
}
+
+ /* Validate the report stats file descriptor to avoid disasters */
+ if (report_stats_fd) {
+ report_stats_file = fdopen(report_stats_fd, "w");
+ if (!report_stats_file)
+ err(FSCK_EX_ERROR,
+ _("invalid argument -r %d"),
+ report_stats_fd);
+ }
+
if (getenv("FSCK_FORCE_ALL_PARALLEL"))
force_all_parallel++;
if ((tmp = getenv("FSCK_MAX_INST")))