CVSROOT:        /cvs/cluster
Module name:    cluster
Changes by:     [EMAIL PROTECTED]       2007-08-15 22:28:18

Modified files:
        gfs2/convert   : gfs2_convert.c 
        gfs2/fsck      : Makefile fsck.h main.c pass1.c 
        gfs2/libgfs2   : gfs2_log.c libgfs2.h 

Log message:
        Resolves: bz #240545: gfs2_fsck should behave more like the other fscks.

Patches:
http://sourceware.org/cgi-bin/cvsweb.cgi/cluster/gfs2/convert/gfs2_convert.c.diff?cvsroot=cluster&r1=1.10&r2=1.11
http://sourceware.org/cgi-bin/cvsweb.cgi/cluster/gfs2/fsck/Makefile.diff?cvsroot=cluster&r1=1.12&r2=1.13
http://sourceware.org/cgi-bin/cvsweb.cgi/cluster/gfs2/fsck/fsck.h.diff?cvsroot=cluster&r1=1.5&r2=1.6
http://sourceware.org/cgi-bin/cvsweb.cgi/cluster/gfs2/fsck/main.c.diff?cvsroot=cluster&r1=1.7&r2=1.8
http://sourceware.org/cgi-bin/cvsweb.cgi/cluster/gfs2/fsck/pass1.c.diff?cvsroot=cluster&r1=1.9&r2=1.10
http://sourceware.org/cgi-bin/cvsweb.cgi/cluster/gfs2/libgfs2/gfs2_log.c.diff?cvsroot=cluster&r1=1.3&r2=1.4
http://sourceware.org/cgi-bin/cvsweb.cgi/cluster/gfs2/libgfs2/libgfs2.h.diff?cvsroot=cluster&r1=1.16&r2=1.17

--- cluster/gfs2/convert/gfs2_convert.c 2007/06/06 15:19:55     1.10
+++ cluster/gfs2/convert/gfs2_convert.c 2007/08/15 22:28:18     1.11
@@ -1088,8 +1088,12 @@
        /* Make them seal their fate.                     */
        /* ---------------------------------------------- */
        if (!error) {
+               int abort;
+
                give_warning();
-               if (!query(&opts, "Convert %s from GFS1 to GFS2? (y/n)", 
device)) {
+               if (!gfs2_query(&abort, &opts,
+                               "Convert %s from GFS1 to GFS2? (y/n)",
+                               device)) {
                        log_crit("%s not converted.\n", device);
                        close(sb2.device_fd);
                        exit(0);
--- cluster/gfs2/fsck/Makefile  2007/06/01 09:45:34     1.12
+++ cluster/gfs2/fsck/Makefile  2007/08/15 22:28:18     1.13
@@ -12,8 +12,8 @@
 
 include ../../make/defines.mk
 
-TARGET1= gfs2_fsck
-TARGET2= fsck.gfs2
+TARGET1= fsck.gfs2
+TARGET2= gfs2_fsck
 
 OBJS=  eattr.o \
        fs_recovery.o \
--- cluster/gfs2/fsck/fsck.h    2007/05/01 16:43:38     1.5
+++ cluster/gfs2/fsck/fsck.h    2007/08/15 22:28:18     1.6
@@ -19,6 +19,8 @@
 #define FSCK_HASH_SIZE          (1 << FSCK_HASH_SHIFT)
 #define FSCK_HASH_MASK          (FSCK_HASH_SIZE - 1)
 
+#define query(opts, fmt, args...) gfs2_query(&fsck_abort, opts, fmt, ##args)
+
 struct inode_info
 {
         osi_list_t list;
--- cluster/gfs2/fsck/main.c    2007/05/01 16:43:38     1.7
+++ cluster/gfs2/fsck/main.c    2007/08/15 22:28:18     1.8
@@ -139,56 +139,26 @@
 
 void interrupt(int sig)
 {
-       fd_set rfds;
-       struct timeval tv;
        char response;
-       int err;
+       char progress[PATH_MAX];
 
-       if (opts.query) /* if we're asking them a question */
-               return;     /* ignore the interrupt signal */
-       FD_ZERO(&rfds);
-       FD_SET(STDIN_FILENO, &rfds);
-
-       tv.tv_sec = 0;
-       tv.tv_usec = 0;
-       /* Make sure there isn't extraneous input before asking the
-        * user the question */
-       while((err = select(STDIN_FILENO + 1, &rfds, NULL, NULL, &tv))) {
-               if(err < 0) {
-                       log_debug("Error in select() on stdin\n");
-                       break;
-               }
-               read(STDIN_FILENO, &response, sizeof(char));
-       }
-       while (TRUE) {
-               printf("\ngfs_fsck interrupted in %s:  ", pass);
-               if (!last_reported_block || last_reported_block == 
last_fs_block)
-                       printf("progress unknown.\n");
-               else
-                       printf("processing block %" PRIu64 " out of %" PRIu64 
"\n",
-                                  last_reported_block, last_fs_block);
-               printf("Do you want to abort gfs_fsck, skip the rest of %s or 
continue (a/s/c)?", pass);
-
-               /* Make sure query is printed out */
-               fflush(stdout);
-               read(STDIN_FILENO, &response, sizeof(char));
-
-               if(tolower(response) == 's') {
-                       skip_this_pass = TRUE;
-                       return;
-               }
-               else if (tolower(response) == 'a') {
-                       fsck_abort = TRUE;
-                       return;
-               }
-               else if (tolower(response) == 'c')
-                       return;
-        else {
-                       while(response != '\n')
-                               read(STDIN_FILENO, &response, sizeof(char));
-                       printf("Bad response, please type 'c', 'a' or 's'.\n");
-                       continue;
-        }
+       if (!last_reported_block || last_reported_block == last_fs_block)
+               sprintf(progress, "progress unknown.\n");
+       else
+               sprintf(progress, "processing block %" PRIu64 " out of %"
+                       PRIu64 "\n", last_reported_block, last_fs_block);
+       
+       response = generic_interrupt("gfs2_fsck", pass, progress,
+                                    "Do you want to abort gfs_fsck, skip " \
+                                    "the rest of this pass or continue " \
+                                    "(a/s/c)?", "asc");
+       if(tolower(response) == 's') {
+               skip_this_pass = TRUE;
+               return;
+       }
+       else if (tolower(response) == 'a') {
+               fsck_abort = TRUE;
+               return;
        }
 }
 
--- cluster/gfs2/fsck/pass1.c   2007/06/28 23:41:37     1.9
+++ cluster/gfs2/fsck/pass1.c   2007/08/15 22:28:18     1.10
@@ -766,8 +766,10 @@
                        if (gfs2_next_rg_meta(rgd, &block, first))
                                break;
                        warm_fuzzy_stuff(block);
-                       if (fsck_abort) /* if asked to abort */
+                       if (fsck_abort) { /* if asked to abort */
+                               gfs2_rgrp_relse(rgd, not_updated);
                                return 0;
+                       }
                        if (skip_this_pass) {
                                printf("Skipping pass 1 is not a good idea.\n");
                                skip_this_pass = FALSE;
--- cluster/gfs2/libgfs2/gfs2_log.c     2007/01/23 19:23:06     1.3
+++ cluster/gfs2/libgfs2/gfs2_log.c     2007/08/15 22:28:18     1.4
@@ -14,8 +14,10 @@
 #include <stdarg.h>
 #include <ctype.h>
 #include <libintl.h>
-
 #include <sys/select.h>
+#include <signal.h>
+#include <string.h>
+#include <termios.h>
 #include <unistd.h>
 
 #include "libgfs2.h"
@@ -45,13 +47,13 @@
        case MSG_DEBUG:
                printf("(%s:%d)\t", file, line);
                vprintf(format, args);
-               fflush(stdout);
+               fflush(NULL);
                break;
        case MSG_INFO:
        case MSG_NOTICE:
        case MSG_WARN:
                vprintf(format, args);
-               fflush(stdout);
+               fflush(NULL);
                break;
        case MSG_ERROR:
        case MSG_CRITICAL:
@@ -81,30 +83,43 @@
        va_end(args);
 }
 
+char gfs2_getch(void)
+{
+       struct termios termattr, savetermattr;
+       char ch;
+       ssize_t size;
+
+       tcgetattr (STDIN_FILENO, &termattr);
+       savetermattr = termattr;
+       termattr.c_lflag &= ~(ICANON | IEXTEN | ISIG);
+       termattr.c_iflag &= ~(BRKINT | ICRNL | INPCK | ISTRIP | IXON);
+       termattr.c_cflag &= ~(CSIZE | PARENB);
+       termattr.c_cflag |= CS8;
+       termattr.c_oflag &= ~(OPOST);
+       termattr.c_cc[VMIN] = 0;
+       termattr.c_cc[VTIME] = 0;
+
+       tcsetattr (STDIN_FILENO, TCSANOW, &termattr);
+       do {
+               size = read(STDIN_FILENO, &ch, 1);
+               if (size)
+                       break;
+               usleep(50000);
+       } while (!size);
 
+       tcsetattr (STDIN_FILENO, TCSANOW, &savetermattr);
+       return ch;
+}
 
-int query(struct gfs2_options *opts, const char *format, ...)
+char generic_interrupt(const char *caller, const char *where,
+                      const char *progress, const char *question,
+                      const char *answers)
 {
-
-       va_list args;
-       const char *transform;
-       char response;
        fd_set rfds;
        struct timeval tv;
-       int err = 0;
-       int ret = 0;
-
-       va_start(args, format);
-
-       transform = _(format);
-
-       if(opts->yes)
-               return 1;
-       if(opts->no)
-               return 0;
+       char response;
+       int err, i;
 
-       opts->query = TRUE;
-       /* Watch stdin (fd 0) to see when it has input. */
        FD_ZERO(&rfds);
        FD_SET(STDIN_FILENO, &rfds);
 
@@ -118,37 +133,79 @@
                        break;
                }
                read(STDIN_FILENO, &response, sizeof(char));
-
        }
- query:
-       vprintf(transform, args);
+       while (TRUE) {
+               printf("\n%s interrupted during %s:  ", caller, where);
+               if (progress)
+                       printf("%s.\n", progress);
+               printf("%s", question);
+
+               /* Make sure query is printed out */
+               fflush(NULL);
+               response = gfs2_getch();
+               printf("\n");
+               fflush(NULL);
+               if (strchr(answers, response))
+                       break;
+               printf("Bad response, please type ");
+               for (i = 0; i < strlen(answers) - 1; i++)
+                       printf("'%c', ", answers[i]);
+               printf(" or '%c'.\n", answers[i]);
+       }
+       return response;
+}
 
-       /* Make sure query is printed out */
-       fflush(NULL);
+int gfs2_query(int *setonabort, struct gfs2_options *opts,
+              const char *format, ...)
+{
 
- rescan:
-       read(STDIN_FILENO, &response, sizeof(char));
+       va_list args;
+       const char *transform;
+       char response;
+       int ret = 0;
 
-       if(tolower(response) == 'y') {
-               ret = 1;
-       } else if (tolower(response) == 'n') {
-               ret = 0;
-       } else if ((response == ' ') || (response == '\t')) {
-               goto rescan;
-       } else {
-               while(response != '\n')
-                       read(STDIN_FILENO, &response, sizeof(char));
-               printf("Bad response, please type 'y' or 'n'.\n");
-               goto query;
-       }
+       *setonabort = 0;
+       va_start(args, format);
 
-       /* Clip the input */
-       while((err = select(STDIN_FILENO + 1, &rfds, NULL, NULL, &tv))) {
-               if(err < 0) {
-                       log_debug("Error in select() on stdin\n");
+       transform = _(format);
+
+       if(opts->yes)
+               return 1;
+       if(opts->no)
+               return 0;
+
+       opts->query = TRUE;
+       while (1) {
+               vprintf(transform, args);
+
+               /* Make sure query is printed out */
+               fflush(NULL);
+               response = gfs2_getch();
+
+               printf("\n");
+               fflush(NULL);
+               if (response == 0x3) { /* if interrupted, by ctrl-c */
+                       response = generic_interrupt("Question", "response",
+                                                    NULL,
+                                                    "Do you want to abort " \
+                                                    "or continue (a/c)?",
+                                                    "ac");
+                       if (response == 'a') {
+                               ret = 0;
+                               *setonabort = 1;
+                               break;
+                       }
+                       printf("Continuing.\n");
+               } else if(tolower(response) == 'y') {
+                        ret = 1;
+                        break;
+               } else if (tolower(response) == 'n') {
+                       ret = 0;
                        break;
+               } else {
+                       printf("Bad response %d, please type 'y' or 'n'.\n",
+                              response);
                }
-               read(STDIN_FILENO, &response, sizeof(char));
        }
 
        opts->query = FALSE;
--- cluster/gfs2/libgfs2/libgfs2.h      2007/07/10 18:21:07     1.16
+++ cluster/gfs2/libgfs2/libgfs2.h      2007/08/15 22:28:18     1.17
@@ -496,7 +496,13 @@
 void decrease_verbosity(void);
 void print_fsck_log(int iif, int priority, char *file, int line,
                                        const char *format, ...);
-int query(struct gfs2_options *opts, const char *format, ...);
+char gfs2_getch(void);
+
+char generic_interrupt(const char *caller, const char *where,
+                      const char *progress, const char *question,
+                      const char *answers);
+int gfs2_query(int *setonabort, struct gfs2_options *opts,
+              const char *format, ...);
 
 /* misc.c */
 void compute_constants(struct gfs2_sbd *sdp);

Reply via email to