[Cluster-devel] cluster/group/dlm_controld deadlock.c
teigland at sourceware.org
teigland at sourceware.org
Mon Aug 13 15:32:06 UTC 2007
CVSROOT: /cvs/cluster
Module name: cluster
Changes by: teigland at sourceware.org 2007-08-13 15:32:05
Modified files:
group/dlm_controld: deadlock.c
Log message:
put back the ability to do pid-based deadlock detection on 5.1 kernels
Patches:
http://sourceware.org/cgi-bin/cvsweb.cgi/cluster/group/dlm_controld/deadlock.c.diff?cvsroot=cluster&r1=1.4&r2=1.5
--- cluster/group/dlm_controld/deadlock.c 2007/08/10 20:23:07 1.4
+++ cluster/group/dlm_controld/deadlock.c 2007/08/13 15:32:05 1.5
@@ -294,14 +294,14 @@
return create_lkb();
}
-static void add_lock(struct lockspace *ls, struct dlm_rsb *r, int from_nodeid,
- struct pack_lock *lock)
+static struct dlm_lkb *add_lock(struct lockspace *ls, struct dlm_rsb *r,
+ int from_nodeid, struct pack_lock *lock)
{
struct dlm_lkb *lkb;
lkb = get_lkb(r, lock);
if (!lkb)
- return;
+ return NULL;
switch (lock->copy) {
case LOCAL_COPY:
@@ -354,6 +354,7 @@
if (list_empty(&lkb->list))
add_lkb(r, lkb);
+ return lkb;
}
static void parse_r_name(char *line, char *name)
@@ -376,6 +377,77 @@
#define LOCK_LINE_MAX 1024
+/* old/original way of dumping (only master state) in 5.1 kernel;
+ does deadlock detection based on pid instead of xid */
+
+static int read_debugfs_master(struct lockspace *ls)
+{
+ FILE *file;
+ char path[PATH_MAX];
+ char line[LOCK_LINE_MAX];
+ struct dlm_rsb *r;
+ struct dlm_lkb *lkb;
+ struct pack_lock lock;
+ char r_name[65];
+ unsigned long long xid;
+ unsigned int waiting;
+ int r_len;
+ int rv;
+
+ snprintf(path, PATH_MAX, "/sys/kernel/debug/dlm/%s_master", ls->name);
+
+ file = fopen(path, "r");
+ if (!file)
+ return -1;
+
+ /* skip the header on the first line */
+ fgets(line, LOCK_LINE_MAX, file);
+
+ while (fgets(line, LOCK_LINE_MAX, file)) {
+ memset(&lock, 0, sizeof(struct pack_lock));
+
+ rv = sscanf(line, "%x %d %x %u %llu %x %hhd %hhd %hhd %u %d",
+ &lock.id,
+ &lock.nodeid,
+ &lock.remid,
+ &lock.ownpid,
+ &xid,
+ &lock.exflags,
+ &lock.status,
+ &lock.grmode,
+ &lock.rqmode,
+ &waiting,
+ &r_len);
+
+ if (rv != 11) {
+ log_error("invalid debugfs line %d: %s", rv, line);
+ goto out;
+ }
+
+ memset(r_name, 0, sizeof(r_name));
+ parse_r_name(line, r_name);
+
+ r = get_resource(ls, r_name, r_len);
+ if (!r)
+ break;
+
+ /* we want lock.xid to be zero before calling add_lock
+ so it will treat this like the full master copy (not
+ partial). then set the xid manually at the end to
+ ownpid (there will be no process copy to merge and
+ get the xid from in 5.1) */
+
+ set_copy(&lock);
+ lkb = add_lock(ls, r, our_nodeid, &lock);
+ if (!lkb)
+ break;
+ lkb->lock.xid = lock.ownpid;
+ }
+ out:
+ fclose(file);
+ return 0;
+}
+
static int read_debugfs_locks(struct lockspace *ls)
{
FILE *file;
@@ -1026,10 +1098,8 @@
rv = read_debugfs_locks(ls);
if (rv < 0) {
-#if 0
/* compat for RHEL5.1 kernels */
rv = read_debugfs_master(ls);
-#endif
if (rv < 0) {
log_error("can't read dlm debugfs file: %s",
strerror(errno));
More information about the Cluster-devel
mailing list