Whamcloud - gitweb
Branch HEAD
[fs/lustre-release.git] / lustre / quota / quotactl_test.c
1 /* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
2  * vim:expandtab:shiftwidth=8:tabstop=8:
3  *
4  * GPL HEADER START
5  *
6  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
7  *
8  * This program is free software; you can redistribute it and/or modify
9  * it under the terms of the GNU General Public License version 2 only,
10  * as published by the Free Software Foundation.
11  *
12  * This program is distributed in the hope that it will be useful, but
13  * WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15  * General Public License version 2 for more details (a copy is included
16  * in the LICENSE file that accompanied this code).
17  *
18  * You should have received a copy of the GNU General Public License
19  * version 2 along with this program; If not, see
20  * http://www.sun.com/software/products/lustre/docs/GPLv2.pdf
21  *
22  * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
23  * CA 95054 USA or visit www.sun.com if you need additional information or
24  * have any questions.
25  *
26  * GPL HEADER END
27  */
28 /*
29  * Copyright  2008 Sun Microsystems, Inc. All rights reserved
30  * Use is subject to license terms.
31  */
32 /*
33  * This file is part of Lustre, http://www.lustre.org/
34  * Lustre is a trademark of Sun Microsystems, Inc.
35  *
36  * lustre/quota/quotactl_test.c
37  *
38  * Author: Lai Siyao <lsy@clusterfs.com>
39  */
40
41 #ifndef EXPORT_SYMTAB
42 # define EXPORT_SYMTAB
43 #endif
44 #define DEBUG_SUBSYSTEM S_CLASS
45
46 #include <linux/module.h>
47 #include <linux/init.h>
48
49 #include <obd_class.h>
50 #include <lustre_fsfilt.h>
51 #include <lustre_mds.h>
52 #include <obd_ost.h>
53
54 static struct obd_quotactl oqctl;
55
56 /* Test quotaon */
57 static int quotactl_test_1(struct obd_device *obd, struct super_block *sb)
58 {
59         int rc;
60         ENTRY;
61
62         oqctl.qc_cmd = Q_QUOTAON;
63         oqctl.qc_id = QFMT_LDISKFS;
64         oqctl.qc_type = UGQUOTA;
65         rc = fsfilt_quotactl(obd, sb, &oqctl);
66         if (rc)
67                 CERROR("1a: quotactl Q_QUOTAON failed: %d\n", rc);
68         RETURN(rc);
69 }
70
71 #if 0 /* set/getinfo not supported, this is for cluster-wide quotas */
72 /* Test set/getinfo */
73 static int quotactl_test_2(struct obd_device *obd, struct super_block *sb)
74 {
75         struct obd_quotactl oqctl;
76         int rc;
77         ENTRY;
78
79         oqctl.qc_cmd = Q_SETINFO;
80         oqctl.qc_type = USRQUOTA;
81         oqctl.qc_dqinfo.dqi_bgrace = 1616;
82         oqctl.qc_dqinfo.dqi_igrace = 2828;
83         oqctl.qc_dqinfo.dqi_flags = 0;
84         rc = fsfilt_quotactl(obd, sb, &oqctl);
85         if (rc) {
86                 CERROR("2a: quotactl Q_SETINFO failed: %d\n", rc);
87                 RETURN(rc);
88         }
89
90         oqctl.qc_cmd = Q_GETINFO;
91         oqctl.qc_type = USRQUOTA;
92         rc = fsfilt_quotactl(obd, sb, &oqctl);
93         if (rc) {
94                 CERROR("2b: quotactl Q_GETINFO failed: %d\n", rc);
95                 RETURN(rc);
96         }
97         if (oqctl.qc_dqinfo.dqi_bgrace != 1616 ||
98             oqctl.qc_dqinfo.dqi_igrace != 2828 ||
99             oqctl.qc_dqinfo.dqi_flags != 0) {
100                 CERROR("2c: quotactl Q_GETINFO get wrong result: %d, %d, %d\n",
101                        oqctl.qc_dqinfo.dqi_bgrace,
102                        oqctl.qc_dqinfo.dqi_igrace,
103                        oqctl.qc_dqinfo.dqi_flags);
104                 RETURN(-EINVAL);
105         }
106
107         RETURN(0);
108 }
109 #endif
110
111 /* Test set/getquota */
112 static int quotactl_test_3(struct obd_device *obd, struct super_block *sb)
113 {
114         int rc;
115         ENTRY;
116
117         oqctl.qc_cmd = Q_SETQUOTA;
118         oqctl.qc_type = USRQUOTA;
119         oqctl.qc_id = 500;
120         oqctl.qc_dqblk.dqb_bhardlimit = 919;
121         oqctl.qc_dqblk.dqb_bsoftlimit = 818;
122         oqctl.qc_dqblk.dqb_ihardlimit = 616;
123         oqctl.qc_dqblk.dqb_isoftlimit = 515;
124         oqctl.qc_dqblk.dqb_valid = QIF_LIMITS;
125         rc = fsfilt_quotactl(obd, sb, &oqctl);
126         if (rc) {
127                 CERROR("3a: quotactl Q_SETQUOTA failed: %d\n", rc);
128                 RETURN(rc);
129         }
130
131         oqctl.qc_cmd = Q_GETQUOTA;
132         oqctl.qc_type = USRQUOTA;
133         oqctl.qc_id = 500;
134         rc = fsfilt_quotactl(obd, sb, &oqctl);
135         if (rc) {
136                 CERROR("3b: quotactl Q_SETQUOTA failed: %d\n", rc);
137                 RETURN(rc);
138         }
139         if (oqctl.qc_dqblk.dqb_bhardlimit != 919 ||
140             oqctl.qc_dqblk.dqb_bsoftlimit != 818 ||
141             oqctl.qc_dqblk.dqb_ihardlimit != 616 ||
142             oqctl.qc_dqblk.dqb_isoftlimit != 515) {
143                 CERROR("3c: quotactl Q_GETQUOTA get wrong result:"
144                        LPU64", "LPU64", "LPU64", "LPU64"\n",
145                        oqctl.qc_dqblk.dqb_bhardlimit,
146                        oqctl.qc_dqblk.dqb_bsoftlimit,
147                        oqctl.qc_dqblk.dqb_ihardlimit,
148                        oqctl.qc_dqblk.dqb_isoftlimit);
149                 RETURN(-EINVAL);
150         }
151
152         oqctl.qc_cmd = Q_SETQUOTA;
153         oqctl.qc_type = USRQUOTA;
154         oqctl.qc_id = 500;
155         oqctl.qc_dqblk.dqb_curspace = 717;
156         oqctl.qc_dqblk.dqb_curinodes = 414;
157         oqctl.qc_dqblk.dqb_valid = QIF_USAGE;
158         rc = fsfilt_quotactl(obd, sb, &oqctl);
159         if (rc) {
160                 CERROR("3d: quotactl Q_SETQUOTA failed: %d\n", rc);
161                 RETURN(rc);
162         }
163
164         oqctl.qc_cmd = Q_GETQUOTA;
165         oqctl.qc_type = USRQUOTA;
166         oqctl.qc_id = 500;
167         rc = fsfilt_quotactl(obd, sb, &oqctl);
168         if (rc) {
169                 CERROR("3e: quotactl Q_SETQUOTA failed: %d\n", rc);
170                 RETURN(rc);
171         }
172         if (oqctl.qc_dqblk.dqb_curspace != 717 ||
173             oqctl.qc_dqblk.dqb_curinodes != 414) {
174                 CERROR("3f: quotactl Q_GETQUOTA get wrong result: "
175                        LPU64", "LPU64"\n", oqctl.qc_dqblk.dqb_curspace,
176                        oqctl.qc_dqblk.dqb_curinodes);
177                 RETURN(-EINVAL);
178         }
179
180         oqctl.qc_cmd = Q_SETQUOTA;
181         oqctl.qc_type = USRQUOTA;
182         oqctl.qc_dqblk.dqb_btime = 313;
183         oqctl.qc_dqblk.dqb_itime = 212;
184         oqctl.qc_id = 500;
185         oqctl.qc_dqblk.dqb_valid = QIF_TIMES;
186         rc = fsfilt_quotactl(obd, sb, &oqctl);
187         if (rc) {
188                 CERROR("3g: quotactl Q_SETQUOTA failed: %d\n", rc);
189                 RETURN(rc);
190         }
191
192         oqctl.qc_cmd = Q_GETQUOTA;
193         oqctl.qc_type = USRQUOTA;
194         oqctl.qc_id = 500;
195         rc = fsfilt_quotactl(obd, sb, &oqctl);
196         if (rc) {
197                 CERROR("3h: quotactl Q_SETQUOTA failed: %d\n", rc);
198                 RETURN(rc);
199         }
200         if (oqctl.qc_dqblk.dqb_btime != 313 ||
201             oqctl.qc_dqblk.dqb_itime != 212) {
202                 CERROR("3i: quotactl Q_GETQUOTA get wrong result: "
203                        LPU64", "LPU64"\n", oqctl.qc_dqblk.dqb_btime,
204                        oqctl.qc_dqblk.dqb_itime);
205                 RETURN(-EINVAL);
206         }
207
208         oqctl.qc_cmd = Q_SETQUOTA;
209         oqctl.qc_type = USRQUOTA;
210         oqctl.qc_id = 500;
211         oqctl.qc_dqblk.dqb_bhardlimit = 919;
212         oqctl.qc_dqblk.dqb_bsoftlimit = 818;
213         oqctl.qc_dqblk.dqb_curspace = 717;
214         oqctl.qc_dqblk.dqb_ihardlimit = 616;
215         oqctl.qc_dqblk.dqb_isoftlimit = 515;
216         oqctl.qc_dqblk.dqb_curinodes = 414;
217         oqctl.qc_dqblk.dqb_btime = 313;
218         oqctl.qc_dqblk.dqb_itime = 212;
219         oqctl.qc_dqblk.dqb_valid = QIF_ALL;
220         rc = fsfilt_quotactl(obd, sb, &oqctl);
221         if (rc) {
222                 CERROR("3j: quotactl Q_SETQUOTA failed: %d\n", rc);
223                 RETURN(rc);
224         }
225
226         oqctl.qc_cmd = Q_GETQUOTA;
227         oqctl.qc_type = USRQUOTA;
228         oqctl.qc_id = 500;
229         rc = fsfilt_quotactl(obd, sb, &oqctl);
230         if (rc) {
231                 CERROR("3k: quotactl Q_SETQUOTA failed: %d\n", rc);
232                 RETURN(rc);
233         }
234         if (oqctl.qc_dqblk.dqb_bhardlimit != 919 ||
235             oqctl.qc_dqblk.dqb_bsoftlimit != 818 ||
236             oqctl.qc_dqblk.dqb_ihardlimit != 616 ||
237             oqctl.qc_dqblk.dqb_isoftlimit != 515 ||
238             oqctl.qc_dqblk.dqb_curspace != 717 ||
239             oqctl.qc_dqblk.dqb_curinodes != 414 ||
240             oqctl.qc_dqblk.dqb_btime != 0 ||
241             oqctl.qc_dqblk.dqb_itime != 0) {
242                 CERROR("3l: quotactl Q_GETQUOTA get wrong result:"
243                        LPU64", "LPU64", "LPU64", "LPU64", "LPU64", "LPU64", "
244                        LPU64", "LPU64"\n", oqctl.qc_dqblk.dqb_bhardlimit,
245                        oqctl.qc_dqblk.dqb_bsoftlimit,
246                        oqctl.qc_dqblk.dqb_ihardlimit,
247                        oqctl.qc_dqblk.dqb_isoftlimit,
248                        oqctl.qc_dqblk.dqb_curspace,
249                        oqctl.qc_dqblk.dqb_curinodes,
250                        oqctl.qc_dqblk.dqb_btime,
251                        oqctl.qc_dqblk.dqb_itime);
252                 RETURN(-EINVAL);
253         }
254
255         RETURN(0);
256 }
257
258 /* Test quotaoff */
259 static int quotactl_test_4(struct obd_device *obd, struct super_block *sb)
260 {
261         int rc;
262         ENTRY;
263
264         oqctl.qc_cmd = Q_QUOTAOFF;
265         oqctl.qc_id = 500;
266         oqctl.qc_type = UGQUOTA;
267         rc = fsfilt_quotactl(obd, sb, &oqctl);
268         if (rc) {
269                 CERROR("4a: quotactl Q_QUOTAOFF failed: %d\n", rc);
270                 RETURN(rc);
271         }
272
273         RETURN(0);
274 }
275
276 /* -------------------------------------------------------------------------
277  * Tests above, boring obd functions below
278  * ------------------------------------------------------------------------- */
279 static int quotactl_run_tests(struct obd_device *obd, struct obd_device *tgt)
280 {
281         struct super_block *sb;
282         struct lvfs_run_ctxt saved;
283         int rc;
284         ENTRY;
285
286         if (strcmp(tgt->obd_type->typ_name, LUSTRE_MDS_NAME) &&
287             !strcmp(tgt->obd_type->typ_name, "obdfilter")) {
288                 CERROR("TARGET OBD should be mds or ost\n");
289                 RETURN(-EINVAL);
290         }
291
292         sb = tgt->u.obt.obt_sb;
293
294         push_ctxt(&saved, &tgt->obd_lvfs_ctxt, NULL);
295
296         rc = quotactl_test_1(tgt, sb);
297         if (rc)
298                 GOTO(cleanup, rc);
299
300 #if 0
301         rc = quotactl_test_2(tgt, sb);
302         if (rc)
303                 GOTO(cleanup, rc);
304 #endif
305
306         rc = quotactl_test_3(tgt, sb);
307         if (rc)
308                 GOTO(cleanup, rc);
309
310  cleanup:
311         quotactl_test_4(tgt, sb);
312
313         pop_ctxt(&saved, &tgt->obd_lvfs_ctxt, NULL);
314
315         return rc;
316 }
317
318 #ifdef LPROCFS
319 static struct lprocfs_vars lprocfs_quotactl_test_obd_vars[] = { {0} };
320 static struct lprocfs_vars lprocfs_quotactl_test_module_vars[] = { {0} };
321
322 void lprocfs_quotactl_test_init_vars(struct lprocfs_static_vars *lvars)
323 {
324     lvars->module_vars  = lprocfs_quotactl_test_module_vars;
325     lvars->obd_vars     = lprocfs_quotactl_test_obd_vars;
326 }
327 #endif
328
329 static int quotactl_test_cleanup(struct obd_device *obd)
330 {
331         lprocfs_obd_cleanup(obd);
332         return 0;
333 }
334
335 static int quotactl_test_setup(struct obd_device *obd, struct lustre_cfg *lcfg)
336 {
337         struct lprocfs_static_vars lvars = { 0 };
338         struct obd_device *tgt;
339         int rc;
340         ENTRY;
341
342         if (lcfg->lcfg_bufcount < 1) {
343                 CERROR("requires a mds OBD name\n");
344                 RETURN(-EINVAL);
345         }
346
347         tgt = class_name2obd(lustre_cfg_string(lcfg, 1));
348         if (!tgt || !tgt->obd_attached || !tgt->obd_set_up) {
349                 CERROR("target device not attached or not set up (%s)\n",
350                        lustre_cfg_string(lcfg, 1));
351                 RETURN(-EINVAL);
352         }
353
354         lprocfs_quotactl_test_init_vars(&lvars);
355         lprocfs_obd_setup(obd, lvars.obd_vars);
356
357         rc = quotactl_run_tests(obd, tgt);
358
359         quotactl_test_cleanup(obd);
360
361         RETURN(rc);
362 }
363
364 static struct obd_ops quotactl_obd_ops = {
365         .o_owner       = THIS_MODULE,
366         .o_setup       = quotactl_test_setup,
367         .o_cleanup     = quotactl_test_cleanup,
368 };
369
370 static int __init quotactl_test_init(void)
371 {
372         struct lprocfs_static_vars lvars = { 0 };
373
374         lprocfs_quotactl_test_init_vars(&lvars);
375         return class_register_type(&quotactl_obd_ops, NULL, lvars.module_vars,
376                                    "quotactl_test", NULL);
377 }
378
379 static void __exit quotactl_test_exit(void)
380 {
381         class_unregister_type("quotactl_test");
382 }
383
384 MODULE_AUTHOR("Sun Microsystems, Inc. <http://www.lustre.org/>");
385 MODULE_DESCRIPTION("quotactl test module");
386 MODULE_LICENSE("GPL");
387
388 module_init(quotactl_test_init);
389 module_exit(quotactl_test_exit);