Gitweb: http://git.fedorahosted.org/git/cluster.git?p=cluster.git;a=commitdiff;h=87…
Commit: 8742ae97a69c8cc282faf39d8c1e7bfda441e5b2
Parent: fe9a89972834d0459c312bede9e4a32df52e445a
Author: Eduardo Damato <edamato(a)redhat.com>
AuthorDate: Tue Sep 29 10:03:09 2009 -0400
Committer: Lon Hohberger <lhh(a)redhat.com>
CommitterDate: Fri Oct 30 16:31:08 2009 -0400
qdisk: Disable max_error_cycles when using io_timeout
Resolves: rgbz#511113
Part 2/4
Signed-off-by: Eduardo Damato <edamato(a)redhat.com>
Signed-off-by: Lon Hohberger <lhh(a)redhat.com>
---
cman/man/qdisk.5 | 6 ++++--
cman/qdisk/main.c | 5 ++++-
2 files changed, 8 insertions(+), 3 deletions(-)
diff --git a/cman/man/qdisk.5 b/cman/man/qdisk.5
index 513d56b..7d28f90 100644
--- a/cman/man/qdisk.5
+++ b/cman/man/qdisk.5
@@ -295,7 +295,8 @@ pass. The default for this value is 0 (off).
.in 12
If set to 1 (on), qdiskd will watch internal timers and reboot the node
if qdisk is not able to write to disk after (interval * tko) seconds.
-The default for this value is 0 (off).
+The default for this value is 0 (off). If io_timeout is active
+max_error_cycles is overridden and set to off.
.in 9
\fIscheduler\fP\fB="\fPrr\fB"\fP
@@ -360,7 +361,8 @@ device name.
If we receive an I/O error during a cycle, we do not poll CMAN and tell
it we are alive. If specified, this value will cause qdiskd to exit
after the specified number of consecutive cycles during which I/O errors
-occur. The default is 0 (no maximum).
+occur. The default is 0 (no maximum). This option is ignored if
+io_timeout is set to 1.
.in 8
\fB...>\fP
diff --git a/cman/qdisk/main.c b/cman/qdisk/main.c
index c86759e..b698f2c 100644
--- a/cman/qdisk/main.c
+++ b/cman/qdisk/main.c
@@ -1425,12 +1425,15 @@ get_config_data(char *cluster_name, qd_ctx *ctx, struct h_data *h, int maxh,
/*
* How many consecutive error cycles do we allow before
* giving up?
+ *
+ * Notice that max_error_cycles is disabled if io_timeout is
+ * active.
*/
/* default = no max */
snprintf(query, sizeof(query), "/cluster/quorumd/@max_error_cycles");
if (ccs_get(ccsfd, query, &val) == 0) {
ctx->qc_max_error_cycles = atoi(val);
- if (ctx->qc_max_error_cycles <= 0)
+ if ((ctx->qc_max_error_cycles <= 0) || (ctx->qc_flags & RF_IOTIMEOUT))
ctx->qc_max_error_cycles = 0;
free(val);
}
Gitweb: http://git.fedorahosted.org/git/cluster.git?p=cluster.git;a=commitdiff;h=18…
Commit: 18411e7ca35ad8b970bb57192c89ef2b067c8432
Parent: 6397a742c02d186ac97d55dc9ea9d50dbbce2493
Author: David Teigland <teigland(a)redhat.com>
AuthorDate: Thu Oct 29 12:23:54 2009 -0500
Committer: David Teigland <teigland(a)redhat.com>
CommitterDate: Thu Oct 29 12:23:54 2009 -0500
dlm-kernel: can_be_granted workaround for user lockspaces
bz 483685
There is a problem in the _can_be_granted() logic regarding the
waitqueue. Normally, a lock request cannot be granted if there's
another lock already on the waitqueue. This gives FIFO fairness.
One of the big problems in the RHEL4 dlm is that the waitqueue is
misused, and locks are kept there while waiting for on a remote
lock request. This can mess up the normal lock granting logic.
Example:
Requests for lkb1 and lkb2 are both sent to another node we think
is master. Both are kept on the rsb waitqueue while waiting for a
reply. The remote node ends up not being the master and returns
EINVAL for lkb1.
Local processing of lkb1 after getting the EINVAL reply:
- lkb1 is removed from the waitqueue
- we look up the master again (resdir is local for this rsb)
- the master ends up being us
- rsb nodeid set to 0
- lkb1 is passed into dlm_lock_stage2 and dlm_lock_stage3
- lkb1 is passed into _can_be_granted
- _can_be_granted sees lkb2 on the waitqueue so says lkb1 cannot
be granted
- so lkb1 is added to the waitqueue (in the proper sense,
i.e. not because it's waiting for a remote reply but because
of the master granting logic)
Local processing of lkb2 after getting its EINVAL reply:
- lkb2 removed from the waitqueue
- we see we are now the master, rsb nodid is 0
- lkb2 is passed into dlm_lock_stage2 and dlm_lock_stage3
- lkb2 is passed into _can_be_granted
- _can_be_granted sees lkb1 on the waitqueue so says lkb2 cannot be
granted
- so lkb2 is added to the waitqueue (again in the proper sense)
Other lock requests then arrive for this rsb, and all continue to
be added to the waitqueue because it's not empty.
This patch makes _can_be_granted return TRUE for locks, like lkb1,
that are being requested/tested by the grant logic for the first
time since being requested, i.e. they are not already on the
waitqueue.
To avoid regressions in this particularly sensitive area of code,
the fix is only enabled for user lockspaces (e.g. clvmd and
rgmanager), and the fix can be disabled by
echo 0 > /proc/cluster/config/dlm/user_grant_now
in case it causes a regression in some user lockspace workload.
Signed-off-by: David Teigland <teigland(a)redhat.com>
---
dlm-kernel/src/config.c | 8 +++++++-
dlm-kernel/src/config.h | 1 +
dlm-kernel/src/device.c | 11 +++++++++++
dlm-kernel/src/dlm_internal.h | 1 +
dlm-kernel/src/locking.c | 9 +++++++++
5 files changed, 29 insertions(+), 1 deletions(-)
diff --git a/dlm-kernel/src/config.c b/dlm-kernel/src/config.c
index 2858c4f..3ce052c 100644
--- a/dlm-kernel/src/config.c
+++ b/dlm-kernel/src/config.c
@@ -29,6 +29,7 @@
#define DEFAULT_CONN_INCREMENT 32
#define DEFAULT_DEADLOCKTIME 10
#define DEFAULT_RECOVER_TIMER 5
+#define DEFAULT_USER_GRANT_NOW 1
struct config_info dlm_config = {
.tcp_port = DEFAULT_TCP_PORT,
@@ -40,7 +41,8 @@ struct config_info dlm_config = {
.dirtbl_size = DEFAULT_DIRTBL_SIZE,
.conn_increment = DEFAULT_CONN_INCREMENT,
.deadlocktime = DEFAULT_DEADLOCKTIME,
- .recover_timer = DEFAULT_RECOVER_TIMER
+ .recover_timer = DEFAULT_RECOVER_TIMER,
+ .user_grant_now = DEFAULT_USER_GRANT_NOW
};
@@ -87,6 +89,10 @@ static struct config_proc_info {
{
.name = "recover_timer",
.value = &dlm_config.recover_timer,
+ },
+ {
+ .name = "user_grant_now",
+ .value = &dlm_config.user_grant_now,
}
};
static struct proc_dir_entry *dlm_dir;
diff --git a/dlm-kernel/src/config.h b/dlm-kernel/src/config.h
index 0b37cf4..e0dab07 100644
--- a/dlm-kernel/src/config.h
+++ b/dlm-kernel/src/config.h
@@ -25,6 +25,7 @@ struct config_info {
int conn_increment;
int deadlocktime;
int recover_timer;
+ int user_grant_now;
};
extern struct config_info dlm_config;
diff --git a/dlm-kernel/src/device.c b/dlm-kernel/src/device.c
index d7afeaf..44e1379 100644
--- a/dlm-kernel/src/device.c
+++ b/dlm-kernel/src/device.c
@@ -37,6 +37,8 @@
#include "dlm_internal.h"
#include "device.h"
+#include "config.h"
+#include "lockspace.h"
extern struct dlm_lkb *dlm_get_lkb(struct dlm_ls *, int);
static struct file_operations _dlm_fops;
@@ -179,6 +181,7 @@ static void add_lockspace_to_list(struct user_ls *lsinfo)
device for userland to access it */
static int register_lockspace(char *name, struct user_ls **ls, int flags)
{
+ struct dlm_ls *dlmls;
struct user_ls *newls;
int status;
int namelen;
@@ -223,6 +226,14 @@ static int register_lockspace(char *name, struct user_ls **ls, int flags)
if (flags & DLM_USER_LSFLG_DEFAULTLS)
set_bit(LS_FLAG_DEFAULT, &newls->ls_flags);
+ dlmls = find_lockspace_by_name(name, strlen(name));
+ if (!dlmls) {
+ log_print("skip GRANT_NOW flag, lockspace not found");
+ } else {
+ if (dlm_config.user_grant_now)
+ set_bit(LSFL_USER_GRANT_NOW, &dlmls->ls_flags);
+ }
+
add_lockspace_to_list(newls);
*ls = newls;
return 0;
diff --git a/dlm-kernel/src/dlm_internal.h b/dlm-kernel/src/dlm_internal.h
index 3400ee7..ed54db3 100644
--- a/dlm-kernel/src/dlm_internal.h
+++ b/dlm-kernel/src/dlm_internal.h
@@ -232,6 +232,7 @@ struct dlm_recover {
#define LSFL_ALL_NODES_VALID (11)
#define LSFL_REQUEST_WARN (12)
#define LSFL_RECOVERD_EXIT (13)
+#define LSFL_USER_GRANT_NOW (14)
#define LSST_NONE (0)
#define LSST_INIT (1)
diff --git a/dlm-kernel/src/locking.c b/dlm-kernel/src/locking.c
index 51be67d..73897e9 100644
--- a/dlm-kernel/src/locking.c
+++ b/dlm-kernel/src/locking.c
@@ -229,6 +229,7 @@ static int conversion_deadlock_detect(struct dlm_rsb *rsb, struct dlm_lkb *lkb)
static int _can_be_granted(struct dlm_rsb *r, struct dlm_lkb *lkb, int now)
{
+ struct dlm_ls *ls = r->res_ls;
int8_t conv = (lkb->lkb_grmode != DLM_LOCK_IV);
/*
@@ -340,6 +341,14 @@ static int _can_be_granted(struct dlm_rsb *r, struct dlm_lkb *lkb, int now)
first_in_list(lkb, &r->res_waitqueue))
return TRUE;
+ /* special case for
+ https://bugzilla.redhat.com/show_bug.cgi?id=483685 */
+
+ if (test_bit(LSFL_USER_GRANT_NOW, &ls->ls_flags) &&
+ now && !conv && list_empty(&r->res_convertqueue) &&
+ list_empty(&r->res_grantqueue))
+ return TRUE;
+
out:
/*
* The following, enabled by CONVDEADLK, departs from VMS.