Magellan Linux

Diff of /trunk/mkinitrd-magellan/busybox/e2fsprogs/fsck.c

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 983 by niro, Fri Apr 24 18:33:46 2009 UTC revision 984 by niro, Sun May 30 11:32:42 2010 UTC
# Line 20  Line 20 
20   * Copyright (C) 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000,   * Copyright (C) 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
21   *      2001, 2002, 2003, 2004, 2005 by  Theodore Ts'o.   *      2001, 2002, 2003, 2004, 2005 by  Theodore Ts'o.
22   *   *
23   * %Begin-Header%   * Licensed under GPLv2, see file LICENSE in this tarball for details.
  * This file may be redistributed under the terms of the GNU Public  
  * License.  
  * %End-Header%  
24   */   */
25    
26  /* All filesystem specific hooks have been removed.  /* All filesystem specific hooks have been removed.
# Line 44  Line 41 
41   * API for fsck.something, NOT ad-hoc hacks in generic fsck. */   * API for fsck.something, NOT ad-hoc hacks in generic fsck. */
42  #define DO_PROGRESS_INDICATOR 0  #define DO_PROGRESS_INDICATOR 0
43    
44    /* fsck 1.41.4 (27-Jan-2009) manpage says:
45     * 0   - No errors
46     * 1   - File system errors corrected
47     * 2   - System should be rebooted
48     * 4   - File system errors left uncorrected
49     * 8   - Operational error
50     * 16  - Usage or syntax error
51     * 32  - Fsck canceled by user request
52     * 128 - Shared library error
53     */
54  #define EXIT_OK          0  #define EXIT_OK          0
55  #define EXIT_NONDESTRUCT 1  #define EXIT_NONDESTRUCT 1
56  #define EXIT_DESTRUCT    2  #define EXIT_DESTRUCT    2
# Line 55  Line 62 
62  /*  /*
63   * Internal structure for mount table entries.   * Internal structure for mount table entries.
64   */   */
   
65  struct fs_info {  struct fs_info {
66   struct fs_info *next;   struct fs_info *next;
67   char *device;   char *device;
# Line 106  static const char really_wanted[] ALIGN1 Line 112  static const char really_wanted[] ALIGN1
112    
113  #define BASE_MD "/dev/md"  #define BASE_MD "/dev/md"
114    
 static char **devices;  
115  static char **args;  static char **args;
 static int num_devices;  
116  static int num_args;  static int num_args;
117  static int verbose;  static int verbose;
118    
# Line 119  static char **fs_type_list; Line 123  static char **fs_type_list;
123  static uint8_t *fs_type_flag;  static uint8_t *fs_type_flag;
124  static smallint fs_type_negated;  static smallint fs_type_negated;
125    
 static volatile smallint cancel_requested;  
 static smallint doall;  
126  static smallint noexecute;  static smallint noexecute;
127  static smallint serialize;  static smallint serialize;
128  static smallint skip_root;  static smallint skip_root;
129  /* static smallint like_mount; */  /* static smallint like_mount; */
 static smallint notitle;  
130  static smallint parallel_root;  static smallint parallel_root;
131  static smallint force_all_parallel;  static smallint force_all_parallel;
132    
# Line 306  static void load_fs_info(const char *fil Line 307  static void load_fs_info(const char *fil
307    
308   fstab = setmntent(filename, "r");   fstab = setmntent(filename, "r");
309   if (!fstab) {   if (!fstab) {
310   bb_perror_msg("cannot read %s", filename);   bb_perror_msg("can't read %s", filename);
311   return;   return;
312   }   }
313    
# Line 356  static int progress_active(void) Line 357  static int progress_active(void)
357  /*  /*
358   * Send a signal to all outstanding fsck child processes   * Send a signal to all outstanding fsck child processes
359   */   */
360  static void kill_all_if_cancel_requested(void)  static void kill_all_if_got_signal(void)
361  {  {
362   static smallint kill_sent;   static smallint kill_sent;
363    
364   struct fsck_instance *inst;   struct fsck_instance *inst;
365    
366   if (!cancel_requested || kill_sent)   if (!bb_got_signal || kill_sent)
367   return;   return;
368    
369   for (inst = instance_list; inst; inst = inst->next) {   for (inst = instance_list; inst; inst = inst->next) {
# Line 391  static int wait_one(int flags) Line 392  static int wait_one(int flags)
392    
393   while (1) {   while (1) {
394   pid = waitpid(-1, &status, flags);   pid = waitpid(-1, &status, flags);
395   kill_all_if_cancel_requested();   kill_all_if_got_signal();
396   if (pid == 0) /* flags == WNOHANG and no children exited */   if (pid == 0) /* flags == WNOHANG and no children exited */
397   return -1;   return -1;
398   if (pid < 0) {   if (pid < 0) {
# Line 498  static int wait_many(int flags) Line 499  static int wait_many(int flags)
499  static void execute(const char *type, const char *device,  static void execute(const char *type, const char *device,
500   const char *mntpt /*, int interactive */)   const char *mntpt /*, int interactive */)
501  {  {
  char *argv[num_args + 4]; /* see count below: */  
  int argc;  
502   int i;   int i;
503   struct fsck_instance *inst;   struct fsck_instance *inst;
504   pid_t pid;   pid_t pid;
505    
506   argv[0] = xasprintf("fsck.%s", type); /* 1 */   args[0] = xasprintf("fsck.%s", type);
  for (i = 0; i < num_args; i++)  
  argv[i+1] = args[i]; /* num_args */  
  argc = num_args + 1;  
507    
508  #if DO_PROGRESS_INDICATOR  #if DO_PROGRESS_INDICATOR
509   if (progress && !progress_active()) {   if (progress && !progress_active()) {
510   if (strcmp(type, "ext2") == 0   if (strcmp(type, "ext2") == 0
511   || strcmp(type, "ext3") == 0   || strcmp(type, "ext3") == 0
512   ) {   ) {
513   argv[argc++] = xasprintf("-C%d", progress_fd); /* 1 */   args[XXX] = xasprintf("-C%d", progress_fd); /* 1 */
514   inst->flags |= FLAG_PROGRESS;   inst->flags |= FLAG_PROGRESS;
515   }   }
516   }   }
517  #endif  #endif
518    
519   argv[argc++] = (char*)device; /* 1 */   args[num_args - 2] = (char*)device;
520   argv[argc] = NULL; /* 1 */   /* args[num_args - 1] = NULL; - already is */
521    
522   if (verbose || noexecute) {   if (verbose || noexecute) {
523   printf("[%s (%d) -- %s]", argv[0], num_running,   printf("[%s (%d) -- %s]", args[0], num_running,
524   mntpt ? mntpt : device);   mntpt ? mntpt : device);
525   for (i = 0; i < argc; i++)   for (i = 0; args[i]; i++)
526   printf(" %s", argv[i]);   printf(" %s", args[i]);
527   bb_putchar('\n');   bb_putchar('\n');
528   }   }
529    
530   /* Fork and execute the correct program. */   /* Fork and execute the correct program. */
531   pid = -1;   pid = -1;
532   if (!noexecute) {   if (!noexecute) {
533   pid = spawn(argv);   pid = spawn(args);
534   if (pid < 0)   if (pid < 0)
535   bb_simple_perror_msg(argv[0]);   bb_simple_perror_msg(args[0]);
536   }   }
537    
538  #if DO_PROGRESS_INDICATOR  #if DO_PROGRESS_INDICATOR
539   free(argv[num_args + 1]);   free(args[XXX]);
540  #endif  #endif
541    
542   /* No child, so don't record an instance */   /* No child, so don't record an instance */
543   if (pid <= 0) {   if (pid <= 0) {
544   free(argv[0]);   free(args[0]);
545   return;   return;
546   }   }
547    
548   inst = xzalloc(sizeof(*inst));   inst = xzalloc(sizeof(*inst));
549   inst->pid = pid;   inst->pid = pid;
550   inst->prog = argv[0];   inst->prog = args[0];
551   inst->device = xstrdup(device);   inst->device = xstrdup(device);
552   inst->base_device = base_device(device);   inst->base_device = base_device(device);
553  #if DO_PROGRESS_INDICATOR  #if DO_PROGRESS_INDICATOR
# Line 791  static int check_all(void) Line 787  static int check_all(void)
787   pass_done = 1;   pass_done = 1;
788    
789   for (fs = filesys_info; fs; fs = fs->next) {   for (fs = filesys_info; fs; fs = fs->next) {
790   if (cancel_requested)   if (bb_got_signal)
791   break;   break;
792   if (fs->flags & FLAG_DONE)   if (fs->flags & FLAG_DONE)
793   continue;   continue;
# Line 831  static int check_all(void) Line 827  static int check_all(void)
827   break;   break;
828   }   }
829   }   }
830   if (cancel_requested)   if (bb_got_signal)
831   break;   break;
832   if (verbose > 1)   if (verbose > 1)
833   printf("--waiting-- (pass %d)\n", passno);   printf("--waiting-- (pass %d)\n", passno);
# Line 844  static int check_all(void) Line 840  static int check_all(void)
840   } else   } else
841   not_done_yet = 1;   not_done_yet = 1;
842   }   }
843   kill_all_if_cancel_requested();   kill_all_if_got_signal();
844   status |= wait_many(FLAG_WAIT_ATLEAST_ONE);   status |= wait_many(FLAG_WAIT_ATLEAST_ONE);
845   return status;   return status;
846  }  }
# Line 907  static void compile_fs_type(char *fs_typ Line 903  static void compile_fs_type(char *fs_typ
903   }   }
904  }  }
905    
906  static void parse_args(char **argv)  static char **new_args(void)
907  {  {
908   int i, j;   args = xrealloc_vector(args, 2, num_args);
909   char *arg, *tmp;   return &args[num_args++];
910   char *options;  }
  int optpos;  
  int opts_for_fsck = 0;  
911    
912   /* in bss, so already zeroed  int fsck_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
913    int fsck_main(int argc UNUSED_PARAM, char **argv)
914    {
915     int i, status;
916     /*int interactive;*/
917     struct fs_info *fs;
918     const char *fstab;
919     char *tmp;
920     char **devices;
921     int num_devices;
922     smallint opts_for_fsck;
923     smallint doall;
924     smallint notitle;
925    
926     /* we want wait() to be interruptible */
927     signal_no_SA_RESTART_empty_mask(SIGINT, record_signo);
928     signal_no_SA_RESTART_empty_mask(SIGTERM, record_signo);
929    
930     setbuf(stdout, NULL);
931    
932     opts_for_fsck = doall = notitle = 0;
933     devices = NULL;
934   num_devices = 0;   num_devices = 0;
935   num_args = 0;   new_args(); /* args[0] = NULL, will be replaced by fsck.<type> */
936   instance_list = NULL;   /* instance_list = NULL; - in bss, so already zeroed */
  */  
937    
938   for (i = 1; argv[i]; i++) {   while (*++argv) {
939   arg = argv[i];   int j;
940     int optpos;
941     char *options;
942     char *arg = *argv;
943    
944   /* "/dev/blk" or "/path" or "UUID=xxx" or "LABEL=xxx" */   /* "/dev/blk" or "/path" or "UUID=xxx" or "LABEL=xxx" */
945   if ((arg[0] == '/' && !opts_for_fsck) || strchr(arg, '=')) {   if ((arg[0] == '/' && !opts_for_fsck) || strchr(arg, '=')) {
# Line 930  static void parse_args(char **argv) Line 947  static void parse_args(char **argv)
947  // "/path", "UUID=xxx" or "LABEL=xxx" into block device name  // "/path", "UUID=xxx" or "LABEL=xxx" into block device name
948  // ("UUID=xxx"/"LABEL=xxx" can probably shifted to fsck.auto duties)  // ("UUID=xxx"/"LABEL=xxx" can probably shifted to fsck.auto duties)
949   devices = xrealloc_vector(devices, 2, num_devices);   devices = xrealloc_vector(devices, 2, num_devices);
950   devices[num_devices++] = xstrdup(arg);   devices[num_devices++] = arg;
951   continue;   continue;
952   }   }
953    
954   if (arg[0] != '-' || opts_for_fsck) {   if (arg[0] != '-' || opts_for_fsck) {
955   args = xrealloc_vector(args, 2, num_args);   *new_args() = arg;
  args[num_args++] = xstrdup(arg);  
956   continue;   continue;
957   }   }
958    
# Line 960  static void parse_args(char **argv) Line 976  static void parse_args(char **argv)
976   goto next_arg;   goto next_arg;
977   }   }
978   /* -C n */   /* -C n */
979   if (!argv[++i]) bb_show_usage();   if (!*++argv)
980   progress_fd = xatoi_u(argv[i]);   bb_show_usage();
981     progress_fd = xatoi_u(*argv);
982   goto next_arg;   goto next_arg;
983  #endif  #endif
984   case 'V':   case 'V':
# Line 990  static void parse_args(char **argv) Line 1007  static void parse_args(char **argv)
1007   bb_show_usage();   bb_show_usage();
1008   if (arg[++j])   if (arg[++j])
1009   tmp = &arg[j];   tmp = &arg[j];
1010   else if (argv[++i])   else if (*++argv)
1011   tmp = argv[i];   tmp = *argv;
1012   else   else
1013   bb_show_usage();   bb_show_usage();
1014   fstype = xstrdup(tmp);   fstype = xstrdup(tmp);
# Line 1012  static void parse_args(char **argv) Line 1029  static void parse_args(char **argv)
1029   if (optpos) {   if (optpos) {
1030   options[0] = '-';   options[0] = '-';
1031   options[optpos + 1] = '\0';   options[optpos + 1] = '\0';
1032   args = xrealloc_vector(args, 2, num_args);   *new_args() = options;
  args[num_args++] = options;  
1033   }   }
1034   }   }
1035   if (getenv("FSCK_FORCE_ALL_PARALLEL"))   if (getenv("FSCK_FORCE_ALL_PARALLEL"))
# Line 1021  static void parse_args(char **argv) Line 1037  static void parse_args(char **argv)
1037   tmp = getenv("FSCK_MAX_INST");   tmp = getenv("FSCK_MAX_INST");
1038   if (tmp)   if (tmp)
1039   max_running = xatoi(tmp);   max_running = xatoi(tmp);
1040  }   new_args(); /* args[num_args - 2] will be replaced by <device> */
1041     new_args(); /* args[num_args - 1] is the last, NULL element */
 static void signal_cancel(int sig UNUSED_PARAM)  
 {  
  cancel_requested = 1;  
 }  
   
 int fsck_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;  
 int fsck_main(int argc UNUSED_PARAM, char **argv)  
 {  
  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(argv);  
1042    
1043   if (!notitle)   if (!notitle)
1044   puts("fsck (busybox "BB_VER", "BB_BT")");   puts("fsck (busybox "BB_VER", "BB_BT")");
# Line 1063  int fsck_main(int argc UNUSED_PARAM, cha Line 1059  int fsck_main(int argc UNUSED_PARAM, cha
1059    
1060   status = 0;   status = 0;
1061   for (i = 0; i < num_devices; i++) {   for (i = 0; i < num_devices; i++) {
1062   if (cancel_requested) {   if (bb_got_signal) {
1063   kill_all_if_cancel_requested();   kill_all_if_got_signal();
1064   break;   break;
1065   }   }
1066    

Legend:
Removed from v.983  
changed lines
  Added in v.984