]> git.ipfire.org Git - ipfire-2.x.git/blame - src/patches/suse-2.6.27.31/patches.suse/dlm-detect-available-userspace-daemon.patch
Move xen patchset to new version's subdir.
[ipfire-2.x.git] / src / patches / suse-2.6.27.31 / patches.suse / dlm-detect-available-userspace-daemon.patch
CommitLineData
00e5a55c
BS
1From: David Teigland <teigland@redhat.com>
2commit dc68c7ed362a00a48290252573a8eb9f74463c3a
3Author: David Teigland <teigland@redhat.com>
4Date: Mon Aug 18 11:43:30 2008 -0500
5Subject: dlm: detect available userspace daemon
6
7 If dlm_controld (the userspace daemon that controls the setup and
8 recovery of the dlm) fails, the kernel should shut down the lockspaces
9 in the kernel rather than leaving them running. This is detected by
10 having dlm_controld hold a misc device open while running, and if
11 the kernel detects a close while the daemon is still needed, it stops
12 the lockspaces in the kernel.
13
14 Knowing that the userspace daemon isn't running also allows the
15 lockspace create/remove routines to avoid waiting on the daemon
16 for join/leave operations.
17
18Signed-off-by: David Teigland <teigland@redhat.com>
19Signed-off-by: Coly Li <coly.li@suse.de>
20
21diff --git a/fs/dlm/lockspace.c b/fs/dlm/lockspace.c
22index 56eae4e..ba672fe 100644
23--- a/fs/dlm/lockspace.c
24+++ b/fs/dlm/lockspace.c
25@@ -378,6 +378,11 @@ static int new_lockspace(char *name, int namelen, void **lockspace,
26 if (!try_module_get(THIS_MODULE))
27 return -EINVAL;
28
29+ if (!dlm_user_daemon_available()) {
30+ module_put(THIS_MODULE);
31+ return -EUNATCH;
32+ }
33+
34 error = 0;
35
36 spin_lock(&lslist_lock);
37@@ -669,7 +674,7 @@ static int release_lockspace(struct dlm_ls *ls, int force)
38
39 dlm_device_deregister(ls);
40
41- if (force < 3)
42+ if (force < 3 && dlm_user_daemon_available())
43 do_uevent(ls, 0);
44
45 dlm_recoverd_stop(ls);
46@@ -791,3 +796,20 @@ int dlm_release_lockspace(void *lockspace, int force)
47 return error;
48 }
49
50+void dlm_stop_lockspaces(void)
51+{
52+ struct dlm_ls *ls;
53+
54+ restart:
55+ spin_lock(&lslist_lock);
56+ list_for_each_entry(ls, &lslist, ls_list) {
57+ if (!test_bit(LSFL_RUNNING, &ls->ls_flags))
58+ continue;
59+ spin_unlock(&lslist_lock);
60+ log_error(ls, "no userland control daemon, stopping lockspace");
61+ dlm_ls_stop(ls);
62+ goto restart;
63+ }
64+ spin_unlock(&lslist_lock);
65+}
66+
67diff --git a/fs/dlm/lockspace.h b/fs/dlm/lockspace.h
68index 891eabb..f879f87 100644
69--- a/fs/dlm/lockspace.h
70+++ b/fs/dlm/lockspace.h
71@@ -20,6 +20,7 @@ struct dlm_ls *dlm_find_lockspace_global(uint32_t id);
72 struct dlm_ls *dlm_find_lockspace_local(void *id);
73 struct dlm_ls *dlm_find_lockspace_device(int minor);
74 void dlm_put_lockspace(struct dlm_ls *ls);
75+void dlm_stop_lockspaces(void);
76
77 #endif /* __LOCKSPACE_DOT_H__ */
78
79diff --git a/fs/dlm/user.c b/fs/dlm/user.c
80index 6542110..81627b5 100644
81--- a/fs/dlm/user.c
82+++ b/fs/dlm/user.c
83@@ -27,6 +27,8 @@
84
85 static const char name_prefix[] = "dlm";
86 static const struct file_operations device_fops;
87+static atomic_t dlm_monitor_opened;
88+static int dlm_monitor_unused = 1;
89
90 #ifdef CONFIG_COMPAT
91
92@@ -890,6 +892,26 @@ static unsigned int device_poll(struct file *file, poll_table *wait)
93 return 0;
94 }
95
96+int dlm_user_daemon_available(void)
97+{
98+ /* dlm_controld hasn't started (or, has started, but not
99+ properly populated configfs) */
100+
101+ if (!dlm_our_nodeid())
102+ return 0;
103+
104+ /* This is to deal with versions of dlm_controld that don't
105+ know about the monitor device. We assume that if the
106+ dlm_controld was started (above), but the monitor device
107+ was never opened, that it's an old version. dlm_controld
108+ should open the monitor device before populating configfs. */
109+
110+ if (dlm_monitor_unused)
111+ return 1;
112+
113+ return atomic_read(&dlm_monitor_opened) ? 1 : 0;
114+}
115+
116 static int ctl_device_open(struct inode *inode, struct file *file)
117 {
118 cycle_kernel_lock();
119@@ -902,6 +924,20 @@ static int ctl_device_close(struct inode *inode, struct file *file)
120 return 0;
121 }
122
123+static int monitor_device_open(struct inode *inode, struct file *file)
124+{
125+ atomic_inc(&dlm_monitor_opened);
126+ dlm_monitor_unused = 0;
127+ return 0;
128+}
129+
130+static int monitor_device_close(struct inode *inode, struct file *file)
131+{
132+ if (atomic_dec_and_test(&dlm_monitor_opened))
133+ dlm_stop_lockspaces();
134+ return 0;
135+}
136+
137 static const struct file_operations device_fops = {
138 .open = device_open,
139 .release = device_close,
140@@ -925,19 +961,42 @@ static struct miscdevice ctl_device = {
141 .minor = MISC_DYNAMIC_MINOR,
142 };
143
144+static const struct file_operations monitor_device_fops = {
145+ .open = monitor_device_open,
146+ .release = monitor_device_close,
147+ .owner = THIS_MODULE,
148+};
149+
150+static struct miscdevice monitor_device = {
151+ .name = "dlm-monitor",
152+ .fops = &monitor_device_fops,
153+ .minor = MISC_DYNAMIC_MINOR,
154+};
155+
156 int __init dlm_user_init(void)
157 {
158 int error;
159
160+ atomic_set(&dlm_monitor_opened, 0);
161+
162 error = misc_register(&ctl_device);
163- if (error)
164+ if (error) {
165 log_print("misc_register failed for control device");
166+ goto out;
167+ }
168
169+ error = misc_register(&monitor_device);
170+ if (error) {
171+ log_print("misc_register failed for monitor device");
172+ misc_deregister(&ctl_device);
173+ }
174+ out:
175 return error;
176 }
177
178 void dlm_user_exit(void)
179 {
180 misc_deregister(&ctl_device);
181+ misc_deregister(&monitor_device);
182 }
183
184diff --git a/fs/dlm/user.h b/fs/dlm/user.h
185index c528b6b..35eb6a1 100644
186--- a/fs/dlm/user.h
187+++ b/fs/dlm/user.h
188@@ -13,5 +13,6 @@ void dlm_user_add_ast(struct dlm_lkb *lkb, int type);
189 int dlm_user_init(void);
190 void dlm_user_exit(void);
191 int dlm_device_deregister(struct dlm_ls *ls);
192+int dlm_user_daemon_available(void);
193
194 #endif