]> git.ipfire.org Git - people/pmueller/ipfire-2.x.git/blob - src/patches/suse-2.6.27.25/patches.suse/dlm-detect-available-userspace-daemon.patch
Updated xen patches taken from suse.
[people/pmueller/ipfire-2.x.git] / src / patches / suse-2.6.27.25 / patches.suse / dlm-detect-available-userspace-daemon.patch
1 From: David Teigland <teigland@redhat.com>
2 commit dc68c7ed362a00a48290252573a8eb9f74463c3a
3 Author: David Teigland <teigland@redhat.com>
4 Date: Mon Aug 18 11:43:30 2008 -0500
5 Subject: 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
18 Signed-off-by: David Teigland <teigland@redhat.com>
19 Signed-off-by: Coly Li <coly.li@suse.de>
20
21 diff --git a/fs/dlm/lockspace.c b/fs/dlm/lockspace.c
22 index 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 +
67 diff --git a/fs/dlm/lockspace.h b/fs/dlm/lockspace.h
68 index 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
79 diff --git a/fs/dlm/user.c b/fs/dlm/user.c
80 index 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
184 diff --git a/fs/dlm/user.h b/fs/dlm/user.h
185 index 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