fsck: shrink (we were passing around some params which were unused)
No binary (build failed)
—
(log yok)
| @@ -39,6 +39,11 @@ | |
| #include "libbb.h" | |
| + | /* "progress indicator" code is somewhat buggy and ext[23] specific. |
| + | * We should be filesystem agnostic. IOW: there should be a well-defined |
| + | * API for fsck.something, NOT ad-hoc hacks in generic fsck. */ |
| + | #define DO_PROGRESS_INDICATOR 0 |
| + | |
| #define EXIT_OK 0 | |
| #define EXIT_NONDESTRUCT 1 | |
| #define EXIT_DESTRUCT 2 | |
| @@ -57,7 +62,6 @@ struct fs_info { | |
| char *mountpt; | |
| char *type; | |
| char *opts; | |
| - | int freq; |
| int passno; | |
| int flags; | |
| }; | |
| @@ -71,10 +75,10 @@ struct fsck_instance { | |
| struct fsck_instance *next; | |
| int pid; | |
| int flags; | |
| - | int exit_status; |
| + | #if DO_PROGRESS_INDICATOR |
| time_t start_time; | |
| + | #endif |
| char *prog; | |
| - | char *type; |
| char *device; | |
| char *base_device; /* /dev/hda for /dev/hdaN etc */ | |
| }; | |
| @@ -125,10 +129,6 @@ static smallint notitle; | |
| static smallint parallel_root; | |
| static smallint force_all_parallel; | |
| - | /* "progress indicator" code is somewhat buggy and ext[23] specific. |
| - | * We should be filesystem agnostic. IOW: there should be a well-defined |
| - | * API for fsck.something, NOT ad-hoc hacks in generic fsck. */ |
| - | #define DO_PROGRESS_INDICATOR 0 |
| #if DO_PROGRESS_INDICATOR | |
| static smallint progress; | |
| static int progress_fd; | |
| @@ -273,7 +273,7 @@ static void free_instance(struct fsck_instance *p) | |
| static struct fs_info *create_fs_device(const char *device, const char *mntpnt, | |
| const char *type, const char *opts, | |
| - | int freq, int passno) |
| + | int passno) |
| { | |
| struct fs_info *fs; | |
| @@ -282,7 +282,6 @@ static struct fs_info *create_fs_device(const char *device, const char *mntpnt, | |
| fs->mountpt = xstrdup(mntpnt); | |
| fs->type = xstrdup(type); | |
| fs->opts = xstrdup(opts ? opts : ""); | |
| - | fs->freq = freq; |
| fs->passno = passno; | |
| /*fs->flags = 0; */ | |
| /*fs->next = NULL; */ | |
| @@ -344,10 +343,10 @@ static void parse_escape(char *word) | |
| static int parse_fstab_line(char *line, struct fs_info **ret_fs) | |
| { | |
| - | char *device, *mntpnt, *type, *opts, *freq, *passno, *cp; |
| + | char *device, *mntpnt, *type, *opts, *passno, *cp; |
| struct fs_info *fs; | |
| - | *ret_fs = 0; |
| + | *ret_fs = NULL; |
| strip_line(line); | |
| *strchrnul(line, '#') = '\0'; /* Ignore everything after comment */ | |
| cp = line; | |
| @@ -357,7 +356,7 @@ static int parse_fstab_line(char *line, struct fs_info **ret_fs) | |
| mntpnt = parse_word(&cp); | |
| type = parse_word(&cp); | |
| opts = parse_word(&cp); | |
| - | freq = parse_word(&cp); |
| + | /*freq =*/ parse_word(&cp); |
| passno = parse_word(&cp); | |
| if (!mntpnt || !type) | |
| @@ -367,15 +366,13 @@ static int parse_fstab_line(char *line, struct fs_info **ret_fs) | |
| parse_escape(mntpnt); | |
| parse_escape(type); | |
| parse_escape(opts); | |
| - | parse_escape(freq); |
| parse_escape(passno); | |
| if (strchr(type, ',')) | |
| type = NULL; | |
| fs = create_fs_device(device, mntpnt, type ? type : "auto", opts, | |
| - | freq ? atoi(freq) : -1, |
| - | passno ? atoi(passno) : -1); |
| + | (passno ? atoi(passno) : -1)); |
| *ret_fs = fs; | |
| return 0; | |
| } | |
| @@ -477,9 +474,10 @@ static void kill_all_if_cancel_requested(void) | |
| /* | |
| * Wait for one child process to exit; when it does, unlink it from | |
| - | * the list of executing child processes, and return it. |
| + | * the list of executing child processes, free, and return its exit status. |
| + | * If there is no exited child, return -1. |
| */ | |
| - | static struct fsck_instance *wait_one(int flags) |
| + | static int wait_one(int flags) |
| { | |
| int status; | |
| int sig; | |
| @@ -487,46 +485,34 @@ static struct fsck_instance *wait_one(int flags) | |
| pid_t pid; | |
| if (!instance_list) | |
| - | return NULL; |
| - | |
| - | if (noexecute) { |
| - | inst = instance_list; |
| - | prev = NULL; |
| - | #ifdef RANDOM_DEBUG |
| - | while (inst->next && (random() & 1)) { |
| - | prev = inst; |
| - | inst = inst->next; |
| - | } |
| - | #endif |
| - | inst->exit_status = 0; |
| - | goto ret_inst; |
| - | } |
| + | return -1; |
| + | /* if (noexecute) { already returned -1; } */ |
| - | inst = prev = NULL; /* for gcc */ |
| - | do { |
| + | while (1) { |
| pid = waitpid(-1, &status, flags); | |
| kill_all_if_cancel_requested(); | |
| - | if (pid == 0 && (flags & WNOHANG)) |
| - | return NULL; |
| + | if (pid == 0) /* flags == WNOHANG and no children exited */ |
| + | return -1; |
| if (pid < 0) { | |
| - | if (errno == EINTR || errno == EAGAIN) |
| + | if (errno == EINTR) |
| continue; | |
| - | if (errno == ECHILD) { |
| - | bb_error_msg("wait: no more child process?!?"); |
| - | return NULL; |
| + | if (errno == ECHILD) { /* paranoia */ |
| + | bb_error_msg("wait: no more children"); |
| + | return -1; |
| } | |
| bb_perror_msg("wait"); | |
| continue; | |
| } | |
| prev = NULL; | |
| inst = instance_list; | |
| - | while (inst) { |
| + | do { |
| if (inst->pid == pid) | |
| - | break; |
| + | goto child_died; |
| prev = inst; | |
| inst = inst->next; | |
| - | } |
| - | } while (!inst); |
| + | } while (inst); |
| + | } |
| + | child_died: |
| if (WIFEXITED(status)) | |
| status = WEXITSTATUS(status); | |
| @@ -534,8 +520,8 @@ static struct fsck_instance *wait_one(int flags) | |
| sig = WTERMSIG(status); | |
| status = EXIT_UNCORRECTED; | |
| if (sig != SIGINT) { | |
| - | printf("Warning... %s %s exited " |
| - | "with signal %d\n", |
| + | printf("Warning: %s %s terminated " |
| + | "by signal %d\n", |
| inst->prog, inst->device, sig); | |
| status = EXIT_ERROR; | |
| } | |
| @@ -544,7 +530,6 @@ static struct fsck_instance *wait_one(int flags) | |
| inst->prog, inst->device, status); | |
| status = EXIT_ERROR; | |
| } | |
| - | inst->exit_status = status; |
| #if DO_PROGRESS_INDICATOR | |
| if (progress && (inst->flags & FLAG_PROGRESS) && !progress_active()) { | |
| @@ -573,39 +558,34 @@ static struct fsck_instance *wait_one(int flags) | |
| } | |
| #endif | |
| - | ret_inst: |
| if (prev) | |
| prev->next = inst->next; | |
| else | |
| instance_list = inst->next; | |
| if (verbose > 1) | |
| printf("Finished with %s (exit status %d)\n", | |
| - | inst->device, inst->exit_status); |
| + | inst->device, status); |
| num_running--; | |
| - | return inst; |
| + | free_instance(inst); |
| + | |
| + | return status; |
| } | |
| - | #define FLAG_WAIT_ALL 0 |
| - | #define FLAG_WAIT_ATLEAST_ONE 1 |
| /* | |
| * Wait until all executing child processes have exited; return the | |
| * logical OR of all of their exit code values. | |
| */ | |
| + | #define FLAG_WAIT_ALL 0 |
| + | #define FLAG_WAIT_ATLEAST_ONE WNOHANG |
| static int wait_many(int flags) | |
| { | |
| - | struct fsck_instance *inst; |
| + | int exit_status; |
| int global_status = 0; | |
| int wait_flags = 0; | |
| - | while ((inst = wait_one(wait_flags))) { |
| - | global_status |= inst->exit_status; |
| - | free_instance(inst); |
| - | #ifdef RANDOM_DEBUG |
| - | if (noexecute && (flags & WNOHANG) && !(random() % 3)) |
| - | break; |
| - | #endif |
| - | if (flags & FLAG_WAIT_ATLEAST_ONE) |
| - | wait_flags = WNOHANG; |
| + | while ((exit_status = wait_one(wait_flags)) != -1) { |
| + | global_status |= exit_status; |
| + | wait_flags |= flags; |
| } | |
| return global_status; | |
| } | |
| @@ -614,8 +594,8 @@ static int wait_many(int flags) | |
| * Execute a particular fsck program, and link it into the list of | |
| * child processes we are waiting for. | |
| */ | |
| - | static void execute(const char *type, const char *device, const char *mntpt, |
| - | int interactive) |
| + | static void execute(const char *type, const char *device, |
| + | const char *mntpt /*, int interactive */) |
| { | |
| char *argv[num_args + 4]; /* see count below: */ | |
| int argc; | |
| @@ -623,8 +603,6 @@ static void execute(const char *type, const char *device, const char *mntpt, | |
| struct fsck_instance *inst; | |
| pid_t pid; | |
| - | inst = xzalloc(sizeof(*inst)); |
| - | |
| argv[0] = xasprintf("fsck.%s", type); /* 1 */ | |
| for (i = 0; i < num_args; i++) | |
| argv[i+1] = args[i]; /* num_args */ | |
| @@ -641,7 +619,7 @@ static void execute(const char *type, const char *device, const char *mntpt, | |
| } | |
| #endif | |
| - | argv[argc++] = xstrdup(device); /* 1 */ |
| + | argv[argc++] = (char*)device; /* 1 */ |
| argv[argc] = NULL; /* 1 */ | |
| if (verbose || noexecute) { | |
| @@ -660,21 +638,24 @@ static void execute(const char *type, const char *device, const char *mntpt, | |
| bb_simple_perror_msg(argv[0]); | |
| } | |
| - | for (i = num_args+1; i < argc; i++) |
| - | free(argv[i]); |
| + | #if DO_PROGRESS_INDICATOR |
| + | free(argv[num_args + 1]); |
| + | #endif |
| - | /* No pid, so don't record an instance */ |
| - | if (pid < 0) { |
| - | free(inst); |
| + | /* No child, so don't record an instance */ |
| + | if (pid <= 0) { |
| + | free(argv[0]); |
| return; | |
| } | |
| + | inst = xzalloc(sizeof(*inst)); |
| inst->pid = pid; | |
| inst->prog = argv[0]; | |
| - | inst->type = xstrdup(type); |
| inst->device = xstrdup(device); | |
| inst->base_device = base_device(device); | |
| + | #if DO_PROGRESS_INDICATOR |
| inst->start_time = time(NULL); | |
| + | #endif |
| /* Add to the list of running fsck's. | |
| * (was adding to the end, but adding to the front is simpler...) */ | |
| @@ -692,7 +673,7 @@ static void execute(const char *type, const char *device, const char *mntpt, | |
| * If the type isn't specified by the user, then use either the type | |
| * specified in /etc/fstab, or "auto". | |
| */ | |
| - | static void fsck_device(struct fs_info *fs, int interactive) |
| + | static void fsck_device(struct fs_info *fs /*, int interactive */) |
| { | |
| const char *type; | |
| @@ -719,7 +700,7 @@ static void fsck_device(struct fs_info *fs, int interactive) | |
| } | |
| num_running++; | |
| - | execute(type, fs->device, fs->mountpt, interactive); |
| + | execute(type, fs->device, fs->mountpt /*, interactive */); |
| } | |
| /* | |
| @@ -871,32 +852,31 @@ static int check_all(void) | |
| * which should be ignored as done, and resolve any "auto" | |
| * filesystem types (done as a side-effect of calling ignore()). | |
| */ | |
| - | for (fs = filesys_info; fs; fs = fs->next) { |
| + | for (fs = filesys_info; fs; fs = fs->next) |
| if (ignore(fs)) | |
| fs->flags |= FLAG_DONE; | |
| - | } |
| /* | |
| * Find and check the root filesystem. | |
| */ | |
| if (!parallel_root) { | |
| for (fs = filesys_info; fs; fs = fs->next) { | |
| - | if (LONE_CHAR(fs->mountpt, '/')) |
| + | if (LONE_CHAR(fs->mountpt, '/')) { |
| + | if (!skip_root && !ignore(fs)) { |
| + | fsck_device(fs /*, 1*/); |
| + | status |= wait_many(FLAG_WAIT_ALL); |
| + | if (status > EXIT_NONDESTRUCT) |
| + | return status; |
| + | } |
| + | fs->flags |= FLAG_DONE; |
| break; | |
| - | } |
| - | if (fs) { |
| - | if (!skip_root && !ignore(fs)) { |
| - | fsck_device(fs, 1); |
| - | status |= wait_many(FLAG_WAIT_ALL); |
| - | if (status > EXIT_NONDESTRUCT) |
| - | return status; |
| } | |
| - | fs->flags |= FLAG_DONE; |
| } | |
| } | |
| /* | |
| - | * This is for the bone-headed user who enters the root |
| - | * filesystem twice. Skip root will skip all root entries. |
| + | * This is for the bone-headed user who has root |
| + | * filesystem listed twice. |
| + | * "Skip root" will skip _all_ root entries. |
| */ | |
| if (skip_root) | |
| for (fs = filesys_info; fs; fs = fs->next) | |
| @@ -916,7 +896,7 @@ static int check_all(void) | |
| continue; | |
| /* | |
| * If the filesystem's pass number is higher | |
| - | * than the current pass number, then we don't |
| + | * than the current pass number, then we didn't |
| * do it yet. | |
| */ | |
| if (fs->passno > passno) { | |
| @@ -935,7 +915,7 @@ static int check_all(void) | |
| /* | |
| * Spawn off the fsck process | |
| */ | |
| - | fsck_device(fs, serialize); |
| + | fsck_device(fs /*, serialize*/); |
| fs->flags |= FLAG_DONE; | |
| /* | |
| @@ -979,21 +959,16 @@ static void compile_fs_type(char *fs_type) | |
| int num = 2; | |
| smallint negate; | |
| - | if (fs_type) { |
| - | s = fs_type; |
| - | while ((s = strchr(s, ','))) { |
| - | num++; |
| - | s++; |
| - | } |
| + | s = fs_type; |
| + | while ((s = strchr(s, ','))) { |
| + | num++; |
| + | s++; |
| } | |
| fs_type_list = xzalloc(num * sizeof(fs_type_list[0])); | |
| fs_type_flag = xzalloc(num * sizeof(fs_type_flag[0])); | |
| fs_type_negated = -1; /* not yet known is it negated or not */ | |
| - | if (!fs_type) |
| - | return; |
| - | |
| num = 0; | |
| s = fs_type; | |
| while (1) { | |
| @@ -1031,12 +1006,12 @@ static void compile_fs_type(char *fs_type) | |
| } | |
| } | |
| - | static void parse_args(int argc, char **argv) |
| + | static void parse_args(char **argv) |
| { | |
| int i, j; | |
| char *arg, *tmp; | |
| - | char *options = NULL; |
| - | int optpos = 0; |
| + | char *options; |
| + | int optpos; |
| int opts_for_fsck = 0; | |
| /* in bss, so already zeroed | |
| @@ -1045,8 +1020,7 @@ static void parse_args(int argc, char **argv) | |
| instance_list = NULL; | |
| */ | |
| - | /* TODO: getopt32 */ |
| - | for (i = 1; i < argc; i++) { |
| + | for (i = 1; argv[i]; i++) { |
| arg = argv[i]; | |
| /* "/dev/blk" or "/path" or "UUID=xxx" or "LABEL=xxx" */ | |
| @@ -1065,14 +1039,14 @@ static void parse_args(int argc, char **argv) | |
| continue; | |
| } | |
| + | if (LONE_CHAR(arg + 1, '-')) { /* "--" ? */ |
| + | opts_for_fsck = 1; |
| + | continue; |
| + | } |
| + | |
| + | optpos = 0; |
| + | options = NULL; |
| for (j = 1; arg[j]; j++) { | |
| - | if (opts_for_fsck) { |
| - | optpos++; |
| - | /* one extra for '\0' */ |
| - | options = xrealloc(options, optpos + 2); |
| - | options[optpos] = arg[j]; |
| - | continue; |
| - | } |
| switch (arg[j]) { | |
| case 'A': | |
| doall = 1; | |
| @@ -1085,7 +1059,8 @@ static void parse_args(int argc, char **argv) | |
| goto next_arg; | |
| } | |
| /* -C n */ | |
| - | progress_fd = xatoi_u(argv[++i]); |
| + | if (!argv[++i]) bb_show_usage(); |
| + | progress_fd = xatoi_u(argv[i]); |
| goto next_arg; | |
| #endif | |
| case 'V': | |
| @@ -1114,16 +1089,13 @@ static void parse_args(int argc, char **argv) | |
| bb_show_usage(); | |
| if (arg[++j]) | |
| tmp = &arg[j]; | |
| - | else if (++i < argc) |
| + | else if (argv[++i]) |
| tmp = argv[i]; | |
| else | |
| bb_show_usage(); | |
| fstype = xstrdup(tmp); | |
| compile_fs_type(fstype); | |
| goto next_arg; | |
| - | case '-': |
| - | opts_for_fsck++; |
| - | break; |
| case '?': | |
| bb_show_usage(); | |
| break; | |
| @@ -1141,8 +1113,6 @@ static void parse_args(int argc, char **argv) | |
| options[optpos + 1] = '\0'; | |
| args = xrealloc(args, (num_args+1) * sizeof(args[0])); | |
| args[num_args++] = options; | |
| - | optpos = 0; |
| - | options = NULL; |
| } | |
| } | |
| if (getenv("FSCK_FORCE_ALL_PARALLEL")) | |
| @@ -1160,17 +1130,18 @@ static void signal_cancel(int sig ATTRIBUTE_UNUSED) | |
| int fsck_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; | |
| int fsck_main(int argc, char **argv) | |
| { | |
| - | int i, status = 0; |
| - | int interactive; |
| + | int i, status; |
| + | /*int interactive;*/ |
| const char *fstab; | |
| struct fs_info *fs; | |
| + | /* we want wait() to be interruptible */ |
| signal_no_SA_RESTART_empty_mask(SIGINT, signal_cancel); | |
| signal_no_SA_RESTART_empty_mask(SIGTERM, signal_cancel); | |
| setbuf(stdout, NULL); | |
| - | parse_args(argc, argv); |
| + | parse_args(argv); |
| if (!notitle) | |
| puts("fsck (busybox "BB_VER", "BB_BT")"); | |
| @@ -1182,18 +1153,14 @@ int fsck_main(int argc, char **argv) | |
| fstab = "/etc/fstab"; | |
| load_fs_info(fstab); | |
| - | interactive = (num_devices == 1) | serialize; |
| + | /*interactive = (num_devices == 1) | serialize;*/ |
| - | /* If -A was specified ("check all"), do that! */ |
| + | if (num_devices == 0) |
| + | /*interactive =*/ serialize = doall = 1; |
| if (doall) | |
| return check_all(); | |
| - | if (num_devices == 0) { |
| - | serialize = 1; |
| - | interactive = 1; |
| - | return check_all(); |
| - | } |
| - | |
| + | status = 0; |
| for (i = 0; i < num_devices; i++) { | |
| if (cancel_requested) { | |
| kill_all_if_cancel_requested(); | |
| @@ -1202,19 +1169,15 @@ int fsck_main(int argc, char **argv) | |
| fs = lookup(devices[i]); | |
| if (!fs) | |
| - | fs = create_fs_device(devices[i], 0, "auto", 0, -1, -1); |
| - | fsck_device(fs, interactive); |
| + | fs = create_fs_device(devices[i], "", "auto", NULL, -1); |
| + | fsck_device(fs /*, interactive */); |
| if (serialize | |
| || (max_running && (num_running >= max_running)) | |
| ) { | |
| - | struct fsck_instance *inst; |
| - | |
| - | inst = wait_one(0); |
| - | if (inst) { |
| - | status |= inst->exit_status; |
| - | free_instance(inst); |
| - | } |
| + | int exit_status = wait_one(0); |
| + | if (exit_status >= 0) |
| + | status |= exit_status; |
| if (verbose > 1) | |
| puts("----------------------------------"); | |
| } | |