cluster: STABLE3 - GFS: New mount option: -o errors=withdraw|panic
Bob Peterson
rpeterso at fedoraproject.org
Fri Oct 9 19:23:09 UTC 2009
Gitweb: http://git.fedorahosted.org/git/cluster.git?p=cluster.git;a=commitdiff;h=a81abbe637251f46a9730ca5f4a2b1db6194edab
Commit: a81abbe637251f46a9730ca5f4a2b1db6194edab
Parent: 830d6fdf94593513d8c569afbb3f097ef73a1d98
Author: Bob Peterson <rpeterso at redhat.com>
AuthorDate: Fri Oct 9 14:22:49 2009 -0500
Committer: Bob Peterson <rpeterso at redhat.com>
CommitterDate: Fri Oct 9 14:25:08 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
---
gfs-kernel/src/gfs/incore.h | 5 ++++
gfs-kernel/src/gfs/lm.c | 22 ++++++++++-------
gfs-kernel/src/gfs/mount.c | 49 +++++++++++++++++++++++++++++++++++++--
gfs-kernel/src/gfs/ops_super.c | 6 ++++-
gfs-kernel/src/gfs/util.c | 33 ++++++++++++++++++--------
5 files changed, 92 insertions(+), 23 deletions(-)
diff --git a/gfs-kernel/src/gfs/incore.h b/gfs-kernel/src/gfs/incore.h
index a0a3b8f..1e00fc2 100644
--- a/gfs-kernel/src/gfs/incore.h
+++ b/gfs-kernel/src/gfs/incore.h
@@ -817,6 +817,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 */
@@ -839,6 +843,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 f27d581..bff0806 100644
--- a/gfs-kernel/src/gfs/lm.c
+++ b/gfs-kernel/src/gfs/lm.c
@@ -87,26 +87,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 534b911..51e40c8 100644
--- a/gfs-kernel/src/gfs/mount.c
+++ b/gfs-kernel/src/gfs/mount.c
@@ -39,6 +39,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 */
@@ -106,10 +107,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;
@@ -146,6 +158,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 0a27b14..621973e 100644
--- a/gfs-kernel/src/gfs/ops_super.c
+++ b/gfs-kernel/src/gfs/ops_super.c
@@ -441,7 +441,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 0367424..869e479 100644
--- a/gfs-kernel/src/gfs/util.c
+++ b/gfs-kernel/src/gfs/util.c
@@ -10,6 +10,7 @@
#include "gfs.h"
#include "glock.h"
#include "lm.h"
+#include "super.h"
uint32_t gfs_random_number;
@@ -195,7 +196,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"
@@ -262,19 +264,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;
}
More information about the cluster-commits
mailing list