[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]

[Cluster-devel] cluster/gfs2 convert/gfs2_convert.c fsck/Makef ...



CVSROOT:	/cvs/cluster
Module name:	cluster
Branch: 	RHEL5
Changes by:	rpeterso 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 <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: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);


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]