Commit ccdab3d6 authored by Brian Foster's avatar Brian Foster Committed by Darrick J. Wong

xfs: define bug_on_assert debug mode sysfs tunable

In DEBUG mode, assert failures unconditionally trigger a kernel BUG.
This is useful in diagnostic situations to panic a system and
collect detailed state information at the time of a failure.

This can also cause problems in cases where DEBUG mode code is
desired but it is preferable not trigger kernel BUGs on assert
failure. For example, during development of new code or during
certain xfstests tests that intentionally cause corruption and test
the kernel for survival (but otherwise may expect to trigger assert
failures).

To provide additional flexibility, create the
<sysfs>/fs/xfs/debug/bug_on_assert tunable to configure assert
failure behavior at runtime. This tunable is only available in DEBUG
mode and is enabled by default to preserve existing default
behavior. When disabled, assert failures in DEBUG mode result in
kernel warnings.
Signed-off-by: default avatarBrian Foster <bfoster@redhat.com>
Reviewed-by: default avatarDarrick J. Wong <darrick.wong@oracle.com>
Signed-off-by: default avatarDarrick J. Wong <darrick.wong@oracle.com>
parent e1a4e37c
...@@ -47,4 +47,6 @@ xfs_param_t xfs_params = { ...@@ -47,4 +47,6 @@ xfs_param_t xfs_params = {
struct xfs_globals xfs_globals = { struct xfs_globals xfs_globals = {
.log_recovery_delay = 0, /* no delay by default */ .log_recovery_delay = 0, /* no delay by default */
.bug_on_assert = true, /* historical default in DEBUG
* mode */
}; };
...@@ -110,7 +110,10 @@ assfail(char *expr, char *file, int line) ...@@ -110,7 +110,10 @@ assfail(char *expr, char *file, int line)
{ {
xfs_emerg(NULL, "Assertion failed: %s, file: %s, line: %d", xfs_emerg(NULL, "Assertion failed: %s, file: %s, line: %d",
expr, file, line); expr, file, line);
BUG(); if (xfs_globals.bug_on_assert)
BUG();
else
WARN_ON(1);
} }
void void
......
...@@ -95,6 +95,7 @@ extern xfs_param_t xfs_params; ...@@ -95,6 +95,7 @@ extern xfs_param_t xfs_params;
struct xfs_globals { struct xfs_globals {
int log_recovery_delay; /* log recovery delay (secs) */ int log_recovery_delay; /* log recovery delay (secs) */
bool bug_on_assert; /* BUG() the kernel on assert failure */
}; };
extern struct xfs_globals xfs_globals; extern struct xfs_globals xfs_globals;
......
...@@ -145,6 +145,38 @@ struct kobj_type xfs_mp_ktype = { ...@@ -145,6 +145,38 @@ struct kobj_type xfs_mp_ktype = {
#ifdef DEBUG #ifdef DEBUG
/* debug */ /* debug */
STATIC ssize_t
bug_on_assert_store(
struct kobject *kobject,
const char *buf,
size_t count)
{
int ret;
int val;
ret = kstrtoint(buf, 0, &val);
if (ret)
return ret;
if (val == 1)
xfs_globals.bug_on_assert = true;
else if (val == 0)
xfs_globals.bug_on_assert = false;
else
return -EINVAL;
return count;
}
STATIC ssize_t
bug_on_assert_show(
struct kobject *kobject,
char *buf)
{
return snprintf(buf, PAGE_SIZE, "%d\n", xfs_globals.bug_on_assert ? 1 : 0);
}
XFS_SYSFS_ATTR_RW(bug_on_assert);
STATIC ssize_t STATIC ssize_t
log_recovery_delay_store( log_recovery_delay_store(
struct kobject *kobject, struct kobject *kobject,
...@@ -176,6 +208,7 @@ log_recovery_delay_show( ...@@ -176,6 +208,7 @@ log_recovery_delay_show(
XFS_SYSFS_ATTR_RW(log_recovery_delay); XFS_SYSFS_ATTR_RW(log_recovery_delay);
static struct attribute *xfs_dbg_attrs[] = { static struct attribute *xfs_dbg_attrs[] = {
ATTR_LIST(bug_on_assert),
ATTR_LIST(log_recovery_delay), ATTR_LIST(log_recovery_delay),
NULL, NULL,
}; };
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment