From mboxrd@z Thu Jan 1 00:00:00 1970 From: rpeterso@sourceware.org Date: 15 Aug 2007 22:31:01 -0000 Subject: [Cluster-devel] cluster/gfs2 convert/gfs2_convert.c fsck/Makef ... Message-ID: <20070815223101.10617.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 Branch: RHEL5 Changes by: rpeterso at sourceware.org 2007-08-15 22:31:00 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&only_with_tag=RHEL5&r1=1.7.2.3&r2=1.7.2.4 http://sourceware.org/cgi-bin/cvsweb.cgi/cluster/gfs2/fsck/Makefile.diff?cvsroot=cluster&only_with_tag=RHEL5&r1=1.6.2.2&r2=1.6.2.3 http://sourceware.org/cgi-bin/cvsweb.cgi/cluster/gfs2/fsck/fsck.h.diff?cvsroot=cluster&only_with_tag=RHEL5&r1=1.3.2.2&r2=1.3.2.3 http://sourceware.org/cgi-bin/cvsweb.cgi/cluster/gfs2/fsck/main.c.diff?cvsroot=cluster&only_with_tag=RHEL5&r1=1.4.2.3&r2=1.4.2.4 http://sourceware.org/cgi-bin/cvsweb.cgi/cluster/gfs2/fsck/pass1.c.diff?cvsroot=cluster&only_with_tag=RHEL5&r1=1.4.2.5&r2=1.4.2.6 http://sourceware.org/cgi-bin/cvsweb.cgi/cluster/gfs2/libgfs2/gfs2_log.c.diff?cvsroot=cluster&only_with_tag=RHEL5&r1=1.2.2.1&r2=1.2.2.2 http://sourceware.org/cgi-bin/cvsweb.cgi/cluster/gfs2/libgfs2/libgfs2.h.diff?cvsroot=cluster&only_with_tag=RHEL5&r1=1.7.2.9&r2=1.7.2.10 --- cluster/gfs2/convert/gfs2_convert.c 2007/06/06 15:21:12 1.7.2.3 +++ cluster/gfs2/convert/gfs2_convert.c 2007/08/15 22:31:00 1.7.2.4 @@ -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/05/01 18:20:49 1.6.2.2 +++ cluster/gfs2/fsck/Makefile 2007/08/15 22:31:00 1.6.2.3 @@ -14,7 +14,8 @@ include ${top_srcdir}/make/defines.mk -TARGET= gfs2_fsck +TARGET1= fsck.gfs2 +TARGET2= gfs2_fsck INCLUDES= -I${top_srcdir}/include -I${top_srcdir}/config -I${top_srcdir}/libgfs2 -I${KERNEL_SRC}/fs/gfs2/ -I${KERNEL_SRC}/include/ LIBS=${top_srcdir}/libgfs2 @@ -27,38 +28,43 @@ CFLAGS+=-D_FILE_OFFSET_BITS=64 -DHELPER_PROGRAM -DGFS_RELEASE_NAME=\"${RELEASE}\" -Wall -O2 -all: ${TARGET} +all: depends ${TARGET1} ${TARGET2} -gfs2_fsck: $(sources:.c=.o) $(LIBS)/libgfs2.a +${TARGET1}: $(sources:.c=.o) $(CC) $(CFLAGS) -L$(LIBS) $^ -o $@ -lgfs2 +${TARGET2}: ${TARGET1} + ln -fs ${TARGET1} ${TARGET2} + %.o: %.c $(CC) -MMD -c $(INCLUDES) $(CFLAGS) $< -o $@ +depends: + $(MAKE) -C ../libgfs2 all test_block_list: log.o test_block_list.o $(CC) $(CFLAGS) $^ -o $@ test_bitmap: test_bitmap.o log.o $(CC) $(CFLAGS) $^ -o $@ + clean: - @rm -f gfs2_fsck *.o *~ *.d + rm -f ${TARGET1} ${TARGET2} *.o *~ *.d cscope.* test_inode_list *.orig *.rej test_block_list test_bitmap install: all if [ ! -d ${sbindir} ]; then \ install -d ${sbindir}; \ fi - strip ${TARGET} - install -m755 ${TARGET} ${sbindir} + install -m755 ${TARGET1} ${sbindir} + ln -sf ${sbindir}/${TARGET1} ${sbindir}/${TARGET2} distclean: clean - @rm -f cscope.* gfs2_fsck test_inode_list *.orig *.rej test_block_list test_bitmap + @rm -f cscope.* {TARGET1} test_inode_list *.orig *.rej test_block_list test_bitmap -gfs2_fsck.pot: $(sources) +{TARGET1}.pot: $(sources) @xgettext -C -F --keyword=print_log --keyword=log_debug --keyword=log_info --keyword=_ \ --keyword=log_notice --keyword=log_warn --keyword=log_err --keyword=log_crit \ - --keyword=log_debug --keyword=log_err --keyword=log_print -d - $(sources) > gfs2_fsck.pot - + --keyword=log_debug --keyword=log_err --keyword=log_print -d - $(sources) > ${TARGET1}.pot -include $(sources:.c=.d) --- cluster/gfs2/fsck/fsck.h 2007/05/01 18:20:49 1.3.2.2 +++ cluster/gfs2/fsck/fsck.h 2007/08/15 22:31:00 1.3.2.3 @@ -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 18:20:49 1.4.2.3 +++ cluster/gfs2/fsck/main.c 2007/08/15 22:31:00 1.4.2.4 @@ -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:42:45 1.4.2.5 +++ cluster/gfs2/fsck/pass1.c 2007/08/15 22:31:00 1.4.2.6 @@ -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:30:19 1.2.2.1 +++ cluster/gfs2/libgfs2/gfs2_log.c 2007/08/15 22:31:00 1.2.2.2 @@ -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:35 1.7.2.9 +++ cluster/gfs2/libgfs2/libgfs2.h 2007/08/15 22:31:00 1.7.2.10 @@ -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);