cluster: RHEL55 - GFS: New mount option: -o errors=withdraw|panic
Bob Peterson
rpeterso at fedoraproject.org
Fri Oct 9 19:26:36 UTC 2009
Gitweb: http://git.fedorahosted.org/git/cluster.git?p=cluster.git;a=commitdiff;h=57f87843c7f54149d688e716fded0f08c3d7f619
Commit: 57f87843c7f54149d688e716fded0f08c3d7f619
Parent: 417822ca757ede38d6a7ce98029c4ec30fef9d46
Author: Bob Peterson <rpeterso at redhat.com>
AuthorDate: Fri Oct 9 14:26:55 2009 -0500
Committer: Bob Peterson <rpeterso at redhat.com>
CommitterDate: Fri Oct 9 14:27:54 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 ++++++++++++++++++--------
gfs/man/gfs_mount.8 | 22 +++++++++++++++++-
6 files changed, 113 insertions(+), 24 deletions(-)
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;
}
diff --git a/gfs/man/gfs_mount.8 b/gfs/man/gfs_mount.8
index 13418fd..1c456f9 100644
--- a/gfs/man/gfs_mount.8
+++ b/gfs/man/gfs_mount.8
@@ -140,6 +140,8 @@ with care.
This is turned on automatically by the lock_nolock module,
but can be overridden by using the \fBignore_local_fs\fP option.
+
+This may not be specified with -o errors=panic.
.TP
\fBignore_local_fs\fP
By default, using the nolock lock module automatically turns on the
@@ -179,7 +181,25 @@ Sets S_ISUID in any new directory, if its parent directory's S_ISUID is set.
Strips all execution bits on a new file, if parent directory owner is different
from owner of process creating the file. Set this option only if you know
why you are setting it.
-
+.TP
+.BR errors=withdraw " / " errors=panic
+Define the behaviour when an error is encountered. (Either force a kernel
+panic or withdraw from the file system.)
+.RS
+
+.B errors=withdraw (default)
+When an error is encountered, the system logs the error to the console, then
+if the error is fatal, the system will force a kernel panic. If the error
+is not fatal, the system will remain running but try to withdraw from the file
+system, which means no further interaction is allowed with that file system
+until the system is rebooted.
+
+.B errors=panic
+When an error is encountered, the system logs the error to the console, then
+forces the kernel to panic. This may not be specified with -o debug nor
+with -o oopses_ok.
+
+.RE
.SH LINKS
.TP 30
http://sources.redhat.com/cluster
More information about the cluster-commits
mailing list