1 /* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
2 * vim:expandtab:shiftwidth=8:tabstop=8:
4 * Copyright (C) 2002 Cluster File Systems, Inc.
6 * This code is issued under the GNU General Public License.
7 * See the file COPYING in this distribution
9 * by Cluster File Systems, Inc.
12 #define DEBUG_SUBSYSTEM S_LDLM
14 #include <linux/lustre_dlm.h>
16 struct ldlm_test_thread {
17 struct ldlm_namespace *t_ns;
18 struct list_head t_link;
20 wait_queue_head_t t_ctl_waitq;
23 static spinlock_t ctl_lock = SPIN_LOCK_UNLOCKED;
24 static struct list_head ctl_threads;
25 static int regression_running = 0;
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)
32 printk("ldlm_test_callback: lock=%Lu, new=%p\n", lockh->addr, new);
36 int ldlm_test_basics(struct obd_device *obddev)
38 struct ldlm_namespace *ns;
39 struct ldlm_resource *res;
40 __u64 res_id[RES_NAME_SIZE] = {1, 2, 3};
42 struct ldlm_lock *lock1, *lock;
45 ns = ldlm_namespace_new("test_server", LDLM_NAMESPACE_SERVER);
49 lock1 = ldlm_lock_create(ns, NULL, res_id, LDLM_PLAIN, LCK_CR, NULL, 0);
52 err = ldlm_lock_enqueue(lock1, NULL, 0, &flags,
53 ldlm_test_callback, ldlm_test_callback);
57 lock = ldlm_lock_create(ns, NULL, res_id, LDLM_PLAIN, LCK_EX, NULL, 0);
60 err = ldlm_lock_enqueue(lock, NULL, 0, &flags,
61 ldlm_test_callback, ldlm_test_callback);
64 if (!(flags & LDLM_FL_BLOCK_GRANTED))
67 res = ldlm_resource_get(ns, NULL, res_id, LDLM_PLAIN, 1);
70 ldlm_resource_dump(res);
72 res = ldlm_lock_convert(lock1, LCK_NL, &flags);
74 ldlm_reprocess_all(res);
76 ldlm_resource_dump(res);
77 ldlm_namespace_free(ns);
82 int ldlm_test_extents(struct obd_device *obddev)
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};
92 ns = ldlm_namespace_new("test_server", LDLM_NAMESPACE_SERVER);
97 lock1 = ldlm_lock_create(ns, NULL, res_id, LDLM_EXTENT, LCK_PR, NULL,
101 err = ldlm_lock_enqueue(lock1, &ext1, sizeof(ext1), &flags, NULL, NULL);
104 if (!(flags & LDLM_FL_LOCK_CHANGED))
108 lock2 = ldlm_lock_create(ns, NULL, res_id, LDLM_EXTENT, LCK_PR,
110 err = ldlm_lock_enqueue(lock2, &ext2, sizeof(ext2), &flags, NULL, NULL);
113 if (!(flags & LDLM_FL_LOCK_CHANGED))
117 lock = ldlm_lock_create(ns, NULL, res_id, LDLM_EXTENT, LCK_EX, NULL, 0);
120 err = ldlm_lock_enqueue(lock, &ext3, sizeof(ext3), &flags,
124 if (!(flags & LDLM_FL_BLOCK_GRANTED))
126 if (flags & LDLM_FL_LOCK_CHANGED)
129 /* Convert/cancel blocking locks */
131 res = ldlm_lock_convert(lock1, LCK_NL, &flags);
133 ldlm_reprocess_all(res);
135 ldlm_lock_cancel(lock2);
137 ldlm_reprocess_all(res);
139 /* Dump the results */
140 res = ldlm_resource_get(ns, NULL, res_id, LDLM_EXTENT, 0);
143 ldlm_resource_dump(res);
144 ldlm_namespace_free(ns);
149 static int ldlm_test_network(struct obd_device *obddev,
150 struct ptlrpc_connection *conn)
152 struct ldlm_obd *ldlm = &obddev->u.ldlm;
154 __u64 res_id[RES_NAME_SIZE] = {1, 2, 3};
155 struct ldlm_extent ext = {4, 6};
156 struct lustre_handle lockh1;
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,
164 CERROR("ldlm_cli_enqueue: %d\n", err);
169 static int ldlm_test_main(void *data)
174 static int ldlm_start_thread(void)
176 struct ldlm_test_thread *test;
180 OBD_ALLOC(test, sizeof(*test));
185 init_waitqueue_head(&test->t_ctl_waitq);
187 spin_lock(&ctl_lock);
188 list_add(&test->t_link, &ctl_threads);
189 spin_unlock(&ctl_lock);
191 rc = kernel_thread(ldlm_test_main, (void *)test,
192 CLONE_VM | CLONE_FS | CLONE_FILES);
194 CERROR("cannot start thread\n");
197 wait_event(test->t_ctl_waitq, test->t_flags & SVC_RUNNING);
202 static int ldlm_stop_all_threads(void)
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,
209 spin_unlock(&ctl_lock);
211 thread->t_flags = SVC_STOPPING;
213 wake_up(&thread->t_ctl_waitq);
214 wait_event_interruptible(thread->t_ctl_waitq,
215 (thread->t_flags & SVC_STOPPED));
217 spin_lock(&ctl_lock);
218 list_del(&thread->t_link);
219 OBD_FREE(thread, sizeof(*thread));
221 spin_unlock(&ctl_lock);
226 int ldlm_regression_start(struct obd_device *obddev,
227 struct ptlrpc_connection *conn, int count)
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);
238 regression_running = 1;
239 spin_unlock(&ctl_lock);
241 for (i = 0; i < count; i++) {
242 rc = ldlm_start_thread();
251 int ldlm_regression_stop(void)
255 spin_lock(&ctl_lock);
256 if (!regression_running) {
257 CERROR("The ldlm regression isn't started.\n");
258 spin_unlock(&ctl_lock);
261 spin_unlock(&ctl_lock);
265 spin_lock(&ctl_lock);
266 regression_running = 0;
267 spin_unlock(&ctl_lock);
272 int ldlm_test(struct obd_device *obddev, struct ptlrpc_connection *conn)
275 rc = ldlm_test_basics(obddev);
279 rc = ldlm_test_extents(obddev);
283 rc = ldlm_test_network(obddev, conn);