Whamcloud - gitweb
*** empty log message ***
[fs/lustre-release.git] / lustre / ldlm / ldlm_test.c
1 /* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
2  * vim:expandtab:shiftwidth=8:tabstop=8:
3  *
4  * Copyright (C) 2002 Cluster File Systems, Inc.
5  *
6  * This code is issued under the GNU General Public License.
7  * See the file COPYING in this distribution
8  *
9  * by Cluster File Systems, Inc.
10  */
11
12 #define DEBUG_SUBSYSTEM S_LDLM
13
14 #include <linux/lustre_dlm.h>
15
16 struct ldlm_test_thread {
17         struct ldlm_namespace *t_ns;
18         struct list_head t_link;
19         __u32 t_flags; 
20         wait_queue_head_t t_ctl_waitq;
21 };
22
23 static spinlock_t ctl_lock = SPIN_LOCK_UNLOCKED;
24 static struct list_head ctl_threads;
25 static int regression_running = 0;
26
27 static int ldlm_test_callback(struct lustre_handle *lockh,
28                               struct ldlm_lock_desc *new,
29                               void *data, __u32 data_len,
30                               struct ptlrpc_request **reqp)
31 {
32         printk("ldlm_test_callback: lock=%Lu, new=%p\n", lockh->addr, new);
33         return 0;
34 }
35
36 int ldlm_test_basics(struct obd_device *obddev)
37 {
38         struct ldlm_namespace *ns;
39         struct ldlm_resource *res;
40         __u64 res_id[RES_NAME_SIZE] = {1, 2, 3};
41         ldlm_error_t err;
42         struct ldlm_lock *lock1, *lock;
43         int flags;
44
45         ns = ldlm_namespace_new("test_server", LDLM_NAMESPACE_SERVER);
46         if (ns == NULL)
47                 LBUG();
48
49         lock1 = ldlm_lock_create(ns, NULL, res_id, LDLM_PLAIN, LCK_CR, NULL, 0);
50         if (lock1 == NULL)
51                 LBUG();
52         err = ldlm_lock_enqueue(lock1, NULL, 0, &flags,
53                                 ldlm_test_callback, ldlm_test_callback);
54         if (err != ELDLM_OK)
55                 LBUG();
56
57         lock = ldlm_lock_create(ns, NULL, res_id, LDLM_PLAIN, LCK_EX, NULL, 0);
58         if (lock == NULL)
59                 LBUG();
60         err = ldlm_lock_enqueue(lock, NULL, 0, &flags,
61                                 ldlm_test_callback, ldlm_test_callback);
62         if (err != ELDLM_OK)
63                 LBUG();
64         if (!(flags & LDLM_FL_BLOCK_GRANTED))
65                 LBUG();
66
67         res = ldlm_resource_get(ns, NULL, res_id, LDLM_PLAIN, 1);
68         if (res == NULL)
69                 LBUG();
70         ldlm_resource_dump(res);
71
72         res = ldlm_lock_convert(lock1, LCK_NL, &flags);
73         if (res != NULL)
74                 ldlm_reprocess_all(res);
75
76         ldlm_resource_dump(res);
77         ldlm_namespace_free(ns);
78
79         return 0;
80 }
81
82 int ldlm_test_extents(struct obd_device *obddev)
83 {
84         struct ldlm_namespace *ns;
85         struct ldlm_resource *res;
86         struct ldlm_lock *lock, *lock1, *lock2;
87         __u64 res_id[RES_NAME_SIZE] = {0, 0, 0};
88         struct ldlm_extent ext1 = {4, 6}, ext2 = {6, 9}, ext3 = {10, 11};
89         ldlm_error_t err;
90         int flags;
91
92         ns = ldlm_namespace_new("test_server", LDLM_NAMESPACE_SERVER);
93         if (ns == NULL)
94                 LBUG();
95
96         flags = 0;
97         lock1 = ldlm_lock_create(ns, NULL, res_id, LDLM_EXTENT, LCK_PR, NULL,
98                                  0);
99         if (lock1 == NULL)
100                 LBUG();
101         err = ldlm_lock_enqueue(lock1, &ext1, sizeof(ext1), &flags, NULL, NULL);
102         if (err != ELDLM_OK)
103                 LBUG();
104         if (!(flags & LDLM_FL_LOCK_CHANGED))
105                 LBUG();
106
107         flags = 0;
108         lock2 = ldlm_lock_create(ns, NULL, res_id, LDLM_EXTENT, LCK_PR,
109                                 NULL, 0);
110         err = ldlm_lock_enqueue(lock2, &ext2, sizeof(ext2), &flags, NULL, NULL);
111         if (err != ELDLM_OK)
112                 LBUG();
113         if (!(flags & LDLM_FL_LOCK_CHANGED))
114                 LBUG();
115
116         flags = 0;
117         lock = ldlm_lock_create(ns, NULL, res_id, LDLM_EXTENT, LCK_EX, NULL, 0);
118         if (lock == NULL)
119                 LBUG();
120         err = ldlm_lock_enqueue(lock, &ext3, sizeof(ext3), &flags,
121                                 NULL, NULL);
122         if (err != ELDLM_OK)
123                 LBUG();
124         if (!(flags & LDLM_FL_BLOCK_GRANTED))
125                 LBUG();
126         if (flags & LDLM_FL_LOCK_CHANGED)
127                 LBUG();
128
129         /* Convert/cancel blocking locks */
130         flags = 0;
131         res = ldlm_lock_convert(lock1, LCK_NL, &flags);
132         if (res != NULL)
133                 ldlm_reprocess_all(res);
134
135         ldlm_lock_cancel(lock2);
136         if (res != NULL)
137                 ldlm_reprocess_all(res);
138
139         /* Dump the results */
140         res = ldlm_resource_get(ns, NULL, res_id, LDLM_EXTENT, 0);
141         if (res == NULL)
142                 LBUG();
143         ldlm_resource_dump(res);
144         ldlm_namespace_free(ns);
145
146         return 0;
147 }
148
149 static int ldlm_test_network(struct obd_device *obddev,
150                              struct ptlrpc_connection *conn)
151 {
152         struct ldlm_obd *ldlm = &obddev->u.ldlm;
153
154         __u64 res_id[RES_NAME_SIZE] = {1, 2, 3};
155         struct ldlm_extent ext = {4, 6};
156         struct lustre_handle lockh1;
157         int flags = 0;
158         ldlm_error_t err;
159
160         err = ldlm_cli_enqueue(ldlm->ldlm_client, conn, NULL,
161                                obddev->obd_namespace, NULL, res_id, LDLM_EXTENT,
162                                &ext, sizeof(ext), LCK_PR, &flags, NULL, NULL, 0,
163                                &lockh1);
164         CERROR("ldlm_cli_enqueue: %d\n", err);
165
166         RETURN(err);
167 }
168
169 static int ldlm_test_main(void *data)
170 {
171         return 0;
172 }
173
174 static int ldlm_start_thread(void)
175 {
176         struct ldlm_test_thread *test;
177         int rc;
178         ENTRY;
179
180         OBD_ALLOC(test, sizeof(*test));
181         if (test == NULL) {
182                 LBUG();
183                 RETURN(-ENOMEM);
184         }
185         init_waitqueue_head(&test->t_ctl_waitq);
186
187         spin_lock(&ctl_lock);
188         list_add(&test->t_link, &ctl_threads);
189         spin_unlock(&ctl_lock);
190
191         rc = kernel_thread(ldlm_test_main, (void *)test,
192                            CLONE_VM | CLONE_FS | CLONE_FILES);
193         if (rc < 0) {
194                 CERROR("cannot start thread\n");
195                 RETURN(-EINVAL);
196         }
197         wait_event(test->t_ctl_waitq, test->t_flags & SVC_RUNNING);
198
199         RETURN(0);
200 }
201
202 static int ldlm_stop_all_threads(void)
203 {
204         spin_lock(&ctl_lock);
205         while (!list_empty(&ctl_threads)) {
206                 struct ldlm_test_thread *thread;
207                 thread = list_entry(ctl_threads.next, struct ldlm_test_thread,
208                                     t_link);
209                 spin_unlock(&ctl_lock);
210
211                 thread->t_flags = SVC_STOPPING;
212
213                 wake_up(&thread->t_ctl_waitq);
214                 wait_event_interruptible(thread->t_ctl_waitq,
215                                          (thread->t_flags & SVC_STOPPED));
216
217                 spin_lock(&ctl_lock);
218                 list_del(&thread->t_link);
219                 OBD_FREE(thread, sizeof(*thread));
220         }
221         spin_unlock(&ctl_lock);
222
223         return 0;
224 }
225
226 int ldlm_regression_start(struct obd_device *obddev,
227                           struct ptlrpc_connection *conn, int count)
228 {
229         int i, rc;
230         ENTRY;
231
232         spin_lock(&ctl_lock);
233         if (regression_running) {
234                 CERROR("You can't start the ldlm regression twice.\n");
235                 spin_unlock(&ctl_lock);
236                 RETURN(-EINVAL);
237         }
238         regression_running = 1;
239         spin_unlock(&ctl_lock);
240
241         for (i = 0; i < count; i++) {
242                 rc = ldlm_start_thread();
243                 if (rc < 0)
244                         GOTO(cleanup, rc);
245         }
246
247  cleanup:
248         RETURN(rc);
249 }
250
251 int ldlm_regression_stop(void)
252 {
253         ENTRY;
254
255         spin_lock(&ctl_lock);
256         if (!regression_running) {
257                 CERROR("The ldlm regression isn't started.\n");
258                 spin_unlock(&ctl_lock);
259                 RETURN(-EINVAL);
260         }
261         spin_unlock(&ctl_lock);
262
263         /* Do stuff */
264
265         spin_lock(&ctl_lock);
266         regression_running = 0;
267         spin_unlock(&ctl_lock);
268
269         RETURN(0);
270 }
271
272 int ldlm_test(struct obd_device *obddev, struct ptlrpc_connection *conn)
273 {
274         int rc;
275         rc = ldlm_test_basics(obddev);
276         if (rc)
277                 RETURN(rc);
278
279         rc = ldlm_test_extents(obddev);
280         if (rc)
281                 RETURN(rc);
282
283         rc = ldlm_test_network(obddev, conn);
284         RETURN(rc);
285 }