Sophie

Sophie

distrib > Scientific%20Linux > 5x > x86_64 > by-pkgid > e92145e04b77d6f57a758422ce479a60 > files > 5

gfs-kmod-0.1.34-12.el5.src.rpm

commit 57f87843c7f54149d688e716fded0f08c3d7f619
Author: Bob Peterson <rpeterso@redhat.com>
Date:   Fri Oct 9 14:26:55 2009 -0500

    GFS: New mount option: -o errors=withdraw|panic
    
    This patch adds "-o errors=panic" and "-o errors=withdraw" to the
    gfs mount options.  The "errors=withdraw" option is today's
    current behaviour, meaning to withdraw from the file system if a
    non-serious gfs error occurs.  The new "errors=panic" option
    tells gfs to force a kernel panic if a non-serious gfs file
    system error occurs.  This may be useful, for example, where
    fabric-level fencing is used that has no way to reboot (such as
    fence_scsi).
    
    rhbz#517145

diff --git a/gfs-kernel/src/gfs/incore.h b/gfs-kernel/src/gfs/incore.h
index fa6f539..841b852 100644
--- a/gfs-kernel/src/gfs/incore.h
+++ b/gfs-kernel/src/gfs/incore.h
@@ -830,6 +830,10 @@ struct gfs_trans {
 #define GFS_DATA_WRITEBACK     1
 #define GFS_DATA_ORDERED       2
 
+#define GFS_ERRORS_WITHDRAW    0
+#define GFS_ERRORS_CONTINUE    1 /* place holder for future feature */
+#define GFS_ERRORS_RO          2 /* place holder for future feature */
+#define GFS_ERRORS_PANIC       3
 
 struct gfs_args {
 	char ar_lockproto[GFS_LOCKNAME_LEN]; /* The name of the Lock Protocol */
@@ -852,6 +856,7 @@ struct gfs_args {
 	int ar_oopses_ok; /* Allow oopses */
 
 	int ar_debug; /* Oops on errors instead of trying to be graceful */
+	int ar_errors; /* errors=default | panic */
 	int ar_upgrade; /* Upgrade ondisk/multihost format */
 
 	unsigned int ar_num_glockd; /* # of glock cleanup daemons to run
diff --git a/gfs-kernel/src/gfs/lm.c b/gfs-kernel/src/gfs/lm.c
index e16216e..acfd598 100644
--- a/gfs-kernel/src/gfs/lm.c
+++ b/gfs-kernel/src/gfs/lm.c
@@ -97,26 +97,30 @@ int gfs_lm_withdraw(struct gfs_sbd *sdp, char *fmt, ...)
 {
 	va_list args;
 
-	if (test_and_set_bit(SDF_SHUTDOWN, &sdp->sd_flags))
+	if (sdp->sd_args.ar_errors == GFS_ERRORS_WITHDRAW &&
+	    test_and_set_bit(SDF_SHUTDOWN, &sdp->sd_flags))
 		return 0;
 
 	va_start(args, fmt);
 	vprintk(fmt, args);
 	va_end(args);
 
-	printk("GFS: fsid=%s: about to withdraw from the cluster\n",
-	       sdp->sd_fsname);
+	if (sdp->sd_args.ar_errors == GFS_ERRORS_WITHDRAW) {
+		printk("GFS: fsid=%s: about to withdraw from the cluster\n",
+		       sdp->sd_fsname);
 
-	BUG_ON(sdp->sd_args.ar_debug);
+		BUG_ON(sdp->sd_args.ar_debug);
 
-	printk("GFS: fsid=%s: telling LM to withdraw\n",
-	       sdp->sd_fsname);
+		printk("GFS: fsid=%s: telling LM to withdraw\n",
+		       sdp->sd_fsname);
 
-	gfs_withdraw_lockproto(&sdp->sd_lockstruct);
+		gfs_withdraw_lockproto(&sdp->sd_lockstruct);
 
-	printk("GFS: fsid=%s: withdrawn\n",
-	       sdp->sd_fsname);
+		printk("GFS: fsid=%s: withdrawn\n", sdp->sd_fsname);
+	}
 	dump_stack();
+	if (sdp->sd_args.ar_errors == GFS_ERRORS_PANIC)
+		panic("GFS: fsid=%s: panic requested.\n", sdp->sd_fsname);
 
 	return -1;
 }
diff --git a/gfs-kernel/src/gfs/mount.c b/gfs-kernel/src/gfs/mount.c
index 8dd58e8..741667a 100644
--- a/gfs-kernel/src/gfs/mount.c
+++ b/gfs-kernel/src/gfs/mount.c
@@ -52,6 +52,7 @@ gfs_make_args(char *data_arg, struct gfs_args *args, int remount)
 
 	memset(args, 0, sizeof(struct gfs_args));
 	args->ar_num_glockd = GFS_GLOCKD_DEFAULT;
+	args->ar_errors = GFS_ERRORS_WITHDRAW;
 
 	if (!remount) {
 		/*  If someone preloaded options, use those instead  */
@@ -119,10 +120,21 @@ gfs_make_args(char *data_arg, struct gfs_args *args, int remount)
 		else if (!strcmp(x, "localcaching"))
 			args->ar_localcaching = TRUE;
 
-		else if (!strcmp(x, "oopses_ok"))
+		else if (!strcmp(x, "oopses_ok")) {
+			if (args->ar_errors == GFS_ERRORS_PANIC) {
+				printk("GFS: -o oopses_ok and -o errors=panic "
+				       "are mutually exclusive.\n");
+				error = -EINVAL;
+				break;
+			}
 			args->ar_oopses_ok = TRUE;
-
-		else if (!strcmp(x, "debug")) {
+		} else if (!strcmp(x, "debug")) {
+			if (args->ar_errors == GFS_ERRORS_PANIC) {
+				printk("GFS: -o debug and -o errors=panic "
+				       "are mutually exclusive.\n");
+				error = -EINVAL;
+				break;
+			}
 			args->ar_oopses_ok = TRUE;
 			args->ar_debug = TRUE;
 
@@ -159,6 +171,37 @@ gfs_make_args(char *data_arg, struct gfs_args *args, int remount)
 		else if (!strcmp(x, "gfs_noatime"))
 			args->ar_noatime = TRUE;
 
+		else if (!strcmp(x, "errors")) {
+			if (!y) {
+				printk("GFS: need argument to errors\n");
+				error = -EINVAL;
+				break;
+			}
+			if (!strcmp(y, "withdraw"))
+				args->ar_errors = GFS_ERRORS_WITHDRAW;
+			else if (!strcmp(y, "panic")) {
+				if (args->ar_debug) {
+					printk("GFS: -o debug and -o errors="
+					       "panic are mutually "
+					       "exclusive.\n");
+					error = -EINVAL;
+					break;
+				} else if (args->ar_oopses_ok) {
+					printk("GFS: -o oopses_ok and -o "
+					       "errors=panic are mutually "
+					       "exclusive.\n");
+					error = -EINVAL;
+					break;
+				}
+				args->ar_errors = GFS_ERRORS_PANIC;
+			} else {
+				printk("GFS: errors= must be either withdraw "
+				       "or panic.\n");
+				error = -EINVAL;
+				break;
+			}
+		}
+
 		/*  Unknown  */
 
 		else {
diff --git a/gfs-kernel/src/gfs/ops_super.c b/gfs-kernel/src/gfs/ops_super.c
index 7f92691..7f29771 100644
--- a/gfs-kernel/src/gfs/ops_super.c
+++ b/gfs-kernel/src/gfs/ops_super.c
@@ -449,7 +449,11 @@ gfs_show_options(struct seq_file *s, struct vfsmount *mnt)
 		seq_printf(s, ",noquota");
 	if (args->ar_suiddir)
 		seq_printf(s, ",suiddir");
-
+	if (args->ar_errors) {
+		seq_printf(s, ",errors=");
+		if (args->ar_errors == GFS_ERRORS_PANIC)
+			seq_printf(s, "panic");
+	}
 	return 0;
 }
 
diff --git a/gfs-kernel/src/gfs/util.c b/gfs-kernel/src/gfs/util.c
index 3e093aa..828d427 100644
--- a/gfs-kernel/src/gfs/util.c
+++ b/gfs-kernel/src/gfs/util.c
@@ -23,6 +23,7 @@
 #include "gfs.h"
 #include "glock.h"
 #include "lm.h"
+#include "super.h"
 
 uint32_t gfs_random_number;
 
@@ -208,7 +209,8 @@ gfs_assert_i(struct gfs_sbd *sdp,
 		       sdp->sd_fsname, function,
 		       sdp->sd_fsname, file, line,
 		       sdp->sd_fsname, get_seconds());
-		BUG();
+		if (sdp->sd_args.ar_errors == GFS_ERRORS_WITHDRAW)
+			BUG();
 	}
 	dump_stack();
 	panic("GFS: fsid=%s: assertion \"%s\" failed\n"
@@ -275,19 +277,30 @@ gfs_assert_warn_i(struct gfs_sbd *sdp,
 			gfs_tune_get(sdp, gt_complain_secs) * HZ))
 		return -2;
 
-	printk("GFS: fsid=%s: warning: assertion \"%s\" failed\n"
-	       "GFS: fsid=%s:   function = %s\n"
-	       "GFS: fsid=%s:   file = %s, line = %u\n"
-	       "GFS: fsid=%s:   time = %lu\n",
-	       sdp->sd_fsname, assertion,
-	       sdp->sd_fsname, function,
-	       sdp->sd_fsname, file, line,
-	       sdp->sd_fsname, get_seconds());
+	if (sdp->sd_args.ar_errors == GFS_ERRORS_WITHDRAW)
+		printk("GFS: fsid=%s: warning: assertion \"%s\" failed\n"
+		       "GFS: fsid=%s:   function = %s\n"
+		       "GFS: fsid=%s:   file = %s, line = %u\n"
+		       "GFS: fsid=%s:   time = %lu\n",
+		       sdp->sd_fsname, assertion,
+		       sdp->sd_fsname, function,
+		       sdp->sd_fsname, file, line,
+		       sdp->sd_fsname, get_seconds());
 
+	if (sdp->sd_args.ar_errors != GFS_ERRORS_WITHDRAW)
+		dump_stack();
 	sdp->sd_last_warning = jiffies;
 	if (sdp->sd_args.ar_debug)
 		BUG();
-
+	if (sdp->sd_args.ar_errors == GFS_ERRORS_PANIC)
+		panic("GFS: fsid=%s: assertion \"%s\" failed\n"
+		      "GFS: fsid=%s:   function = %s\n"
+		      "GFS: fsid=%s:   file = %s, line = %u\n"
+		      "GFS: fsid=%s:   time = %lu\n",
+		      sdp->sd_fsname, assertion,
+		      sdp->sd_fsname, function,
+		      sdp->sd_fsname, file, line,
+		      sdp->sd_fsname, get_seconds());
 
 	return -1;
 }