From mboxrd@z Thu Jan 1 00:00:00 1970 From: rpeterso@sourceware.org Date: 15 Aug 2007 22:28:20 -0000 Subject: [Cluster-devel] cluster/gfs2 convert/gfs2_convert.c fsck/Makef ... Message-ID: <20070815222820.15397.qmail@sourceware.org> List-Id: To: cluster-devel.redhat.com MIME-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit CVSROOT: /cvs/cluster Module name: cluster Changes by: rpeterso at sourceware.org 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 #include #include - #include +#include +#include +#include #include #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);