Whamcloud - gitweb
LU-9859 libcfs: delete libcfs/linux/libcfs.h
[fs/lustre-release.git] / libcfs / libcfs / module.c
1 /*
2  * GPL HEADER START
3  *
4  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License version 2 only,
8  * as published by the Free Software Foundation.
9  *
10  * This program is distributed in the hope that it will be useful, but
11  * WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13  * General Public License version 2 for more details (a copy is included
14  * in the LICENSE file that accompanied this code).
15  *
16  * You should have received a copy of the GNU General Public License
17  * version 2 along with this program; If not, see
18  * http://www.gnu.org/licenses/gpl-2.0.html
19  *
20  * GPL HEADER END
21  */
22 /*
23  * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
24  * Use is subject to license terms.
25  *
26  * Copyright (c) 2012, 2017, Intel Corporation.
27  */
28 /*
29  * This file is part of Lustre, http://www.lustre.org/
30  * Lustre is a trademark of Sun Microsystems, Inc.
31  */
32 #include <linux/miscdevice.h>
33 #include <linux/module.h>
34 #include <linux/kernel.h>
35 #include <linux/mm.h>
36 #include <linux/string.h>
37 #include <linux/stat.h>
38 #include <linux/errno.h>
39 #include <linux/unistd.h>
40 #include <net/sock.h>
41 #include <linux/uio.h>
42 #include <linux/uaccess.h>
43
44 #include <linux/fs.h>
45 #include <linux/file.h>
46 #include <linux/list.h>
47
48 #include <linux/sysctl.h>
49 #include <linux/debugfs.h>
50 #include <asm/div64.h>
51
52 #define DEBUG_SUBSYSTEM S_LNET
53
54 #include <libcfs/libcfs.h>
55 #include <libcfs/libcfs_crypto.h>
56 #include <libcfs/linux/linux-misc.h>
57 #include <lnet/lib-lnet.h>
58 #include "tracefile.h"
59
60 static struct dentry *lnet_debugfs_root;
61
62 static DECLARE_RWSEM(ioctl_list_sem);
63 static LIST_HEAD(ioctl_list);
64
65 int libcfs_register_ioctl(struct libcfs_ioctl_handler *hand)
66 {
67         int rc = 0;
68
69         down_write(&ioctl_list_sem);
70         if (!list_empty(&hand->item))
71                 rc = -EBUSY;
72         else
73                 list_add_tail(&hand->item, &ioctl_list);
74         up_write(&ioctl_list_sem);
75
76         return rc;
77 }
78 EXPORT_SYMBOL(libcfs_register_ioctl);
79
80 int libcfs_deregister_ioctl(struct libcfs_ioctl_handler *hand)
81 {
82         int rc = 0;
83
84         down_write(&ioctl_list_sem);
85         if (list_empty(&hand->item))
86                 rc = -ENOENT;
87         else
88                 list_del_init(&hand->item);
89         up_write(&ioctl_list_sem);
90
91         return rc;
92 }
93 EXPORT_SYMBOL(libcfs_deregister_ioctl);
94
95 int libcfs_ioctl(unsigned long cmd, void __user *uparam)
96 {
97         struct libcfs_ioctl_data *data = NULL;
98         struct libcfs_ioctl_hdr  *hdr;
99         int                       err;
100         ENTRY;
101
102         /* 'cmd' and permissions get checked in our arch-specific caller */
103         err = libcfs_ioctl_getdata(&hdr, uparam);
104         if (err != 0) {
105                 CDEBUG_LIMIT(D_ERROR,
106                              "libcfs ioctl: data header error %d\n", err);
107                 RETURN(err);
108         }
109
110         if (hdr->ioc_version == LIBCFS_IOCTL_VERSION) {
111                 /* The libcfs_ioctl_data_adjust() function performs adjustment
112                  * operations on the libcfs_ioctl_data structure to make
113                  * it usable by the code.  This doesn't need to be called
114                  * for new data structures added. */
115                 data = container_of(hdr, struct libcfs_ioctl_data, ioc_hdr);
116                 err = libcfs_ioctl_data_adjust(data);
117                 if (err != 0)
118                         GOTO(out, err);
119         }
120
121         CDEBUG(D_IOCTL, "libcfs ioctl cmd %lu\n", cmd);
122         switch (cmd) {
123         case IOC_LIBCFS_CLEAR_DEBUG:
124                 libcfs_debug_clear_buffer();
125                 break;
126         case IOC_LIBCFS_MARK_DEBUG:
127                 if (data == NULL ||
128                     data->ioc_inlbuf1 == NULL ||
129                     data->ioc_inlbuf1[data->ioc_inllen1 - 1] != '\0')
130                         GOTO(out, err = -EINVAL);
131
132                 libcfs_debug_mark_buffer(data->ioc_inlbuf1);
133                 break;
134
135         default: {
136                 struct libcfs_ioctl_handler *hand;
137
138                 err = -EINVAL;
139                 down_read(&ioctl_list_sem);
140                 list_for_each_entry(hand, &ioctl_list, item) {
141                         err = hand->handle_ioctl(cmd, hdr);
142                         if (err == -EINVAL)
143                                 continue;
144
145                         if (copy_to_user(uparam, hdr, hdr->ioc_len))
146                                 err = -EFAULT;
147                         break;
148                 }
149                 up_read(&ioctl_list_sem);
150                 break; }
151         }
152 out:
153         LIBCFS_FREE(hdr, hdr->ioc_len);
154         RETURN(err);
155 }
156
157 int lprocfs_call_handler(void *data, int write, loff_t *ppos,
158                          void __user *buffer, size_t *lenp,
159                          int (*handler)(void *data, int write, loff_t pos,
160                                         void __user *buffer, int len))
161 {
162         int rc = handler(data, write, *ppos, buffer, *lenp);
163
164         if (rc < 0)
165                 return rc;
166
167         if (write) {
168                 *ppos += *lenp;
169         } else {
170                 *lenp = rc;
171                 *ppos += rc;
172         }
173         return 0;
174 }
175 EXPORT_SYMBOL(lprocfs_call_handler);
176
177 static int __proc_dobitmasks(void *data, int write,
178                              loff_t pos, void __user *buffer, int nob)
179 {
180         const int     tmpstrlen = 512;
181         char         *tmpstr;
182         int           rc;
183         unsigned int *mask = data;
184         int           is_subsys = (mask == &libcfs_subsystem_debug) ? 1 : 0;
185         int           is_printk = (mask == &libcfs_printk) ? 1 : 0;
186
187         rc = cfs_trace_allocate_string_buffer(&tmpstr, tmpstrlen);
188         if (rc < 0)
189                 return rc;
190
191         if (!write) {
192                 libcfs_debug_mask2str(tmpstr, tmpstrlen, *mask, is_subsys);
193                 rc = strlen(tmpstr);
194
195                 if (pos >= rc) {
196                         rc = 0;
197                 } else {
198                         rc = cfs_trace_copyout_string(buffer, nob,
199                                                       tmpstr + pos, "\n");
200                 }
201         } else {
202                 rc = cfs_trace_copyin_string(tmpstr, tmpstrlen, buffer, nob);
203                 if (rc < 0) {
204                         kfree(tmpstr);
205                         return rc;
206                 }
207
208                 rc = libcfs_debug_str2mask(mask, tmpstr, is_subsys);
209                 /* Always print LBUG/LASSERT to console, so keep this mask */
210                 if (is_printk)
211                         *mask |= D_EMERG;
212         }
213
214         kfree(tmpstr);
215         return rc;
216 }
217
218 static int proc_dobitmasks(struct ctl_table *table, int write,
219                            void __user *buffer, size_t *lenp, loff_t *ppos)
220 {
221         return lprocfs_call_handler(table->data, write, ppos, buffer, lenp,
222                                     __proc_dobitmasks);
223 }
224
225 static int min_watchdog_ratelimit;              /* disable ratelimiting */
226 static int max_watchdog_ratelimit = (24*60*60); /* limit to once per day */
227
228 static int __proc_dump_kernel(void *data, int write,
229                               loff_t pos, void __user *buffer, int nob)
230 {
231         if (!write)
232                 return 0;
233
234         return cfs_trace_dump_debug_buffer_usrstr(buffer, nob);
235 }
236
237 static int proc_dump_kernel(struct ctl_table *table, int write,
238                             void __user *buffer, size_t *lenp, loff_t *ppos)
239 {
240         return lprocfs_call_handler(table->data, write, ppos, buffer, lenp,
241                                     __proc_dump_kernel);
242 }
243
244 static int __proc_daemon_file(void *data, int write,
245                               loff_t pos, void __user *buffer, int nob)
246 {
247         if (!write) {
248                 int len = strlen(cfs_tracefile);
249
250                 if (pos >= len)
251                         return 0;
252
253                 return cfs_trace_copyout_string(buffer, nob,
254                                                 cfs_tracefile + pos, "\n");
255         }
256
257         return cfs_trace_daemon_command_usrstr(buffer, nob);
258 }
259
260 static int proc_daemon_file(struct ctl_table *table, int write,
261                             void __user *buffer, size_t *lenp, loff_t *ppos)
262 {
263         return lprocfs_call_handler(table->data, write, ppos, buffer, lenp,
264                                     __proc_daemon_file);
265 }
266
267 static int libcfs_force_lbug(struct ctl_table *table, int write,
268                              void __user *buffer,
269                              size_t *lenp, loff_t *ppos)
270 {
271         if (write)
272                 LBUG();
273         return 0;
274 }
275
276 static int proc_fail_loc(struct ctl_table *table, int write,
277                          void __user *buffer, size_t *lenp, loff_t *ppos)
278 {
279         int rc;
280         long old_fail_loc = cfs_fail_loc;
281
282         rc = proc_doulongvec_minmax(table, write, buffer, lenp, ppos);
283         if (old_fail_loc != cfs_fail_loc)
284                 wake_up(&cfs_race_waitq);
285         return rc;
286 }
287
288 static int __proc_cpt_table(void *data, int write,
289                             loff_t pos, void __user *buffer, int nob)
290 {
291         char *buf = NULL;
292         int   len = 4096;
293         int   rc  = 0;
294
295         if (write)
296                 return -EPERM;
297
298         LASSERT(cfs_cpt_table != NULL);
299
300         while (1) {
301                 LIBCFS_ALLOC(buf, len);
302                 if (buf == NULL)
303                         return -ENOMEM;
304
305                 rc = cfs_cpt_table_print(cfs_cpt_table, buf, len);
306                 if (rc >= 0)
307                         break;
308
309                 if (rc == -EFBIG) {
310                         LIBCFS_FREE(buf, len);
311                         len <<= 1;
312                         continue;
313                 }
314                 goto out;
315         }
316
317         if (pos >= rc) {
318                 rc = 0;
319                 goto out;
320         }
321
322         rc = cfs_trace_copyout_string(buffer, nob, buf + pos, NULL);
323 out:
324         if (buf != NULL)
325                 LIBCFS_FREE(buf, len);
326         return rc;
327 }
328
329 static int proc_cpt_table(struct ctl_table *table, int write,
330                           void __user *buffer, size_t *lenp, loff_t *ppos)
331 {
332         return lprocfs_call_handler(table->data, write, ppos, buffer, lenp,
333                                     __proc_cpt_table);
334 }
335
336 static int __proc_cpt_distance(void *data, int write,
337                                loff_t pos, void __user *buffer, int nob)
338 {
339         char *buf = NULL;
340         int   len = 4096;
341         int   rc  = 0;
342
343         if (write)
344                 return -EPERM;
345
346         LASSERT(cfs_cpt_table != NULL);
347
348         while (1) {
349                 LIBCFS_ALLOC(buf, len);
350                 if (buf == NULL)
351                         return -ENOMEM;
352
353                 rc = cfs_cpt_distance_print(cfs_cpt_table, buf, len);
354                 if (rc >= 0)
355                         break;
356
357                 if (rc == -EFBIG) {
358                         LIBCFS_FREE(buf, len);
359                         len <<= 1;
360                         continue;
361                 }
362                 goto out;
363         }
364
365         if (pos >= rc) {
366                 rc = 0;
367                 goto out;
368         }
369
370         rc = cfs_trace_copyout_string(buffer, nob, buf + pos, NULL);
371  out:
372         if (buf != NULL)
373                 LIBCFS_FREE(buf, len);
374         return rc;
375 }
376
377 static int proc_cpt_distance(struct ctl_table *table, int write,
378                              void __user *buffer, size_t *lenp, loff_t *ppos)
379 {
380         return lprocfs_call_handler(table->data, write, ppos, buffer, lenp,
381                                      __proc_cpt_distance);
382 }
383
384 static struct ctl_table lnet_table[] = {
385         {
386                 INIT_CTL_NAME
387                 .procname       = "debug",
388                 .data           = &libcfs_debug,
389                 .maxlen         = sizeof(int),
390                 .mode           = 0644,
391                 .proc_handler   = &proc_dobitmasks,
392         },
393         {
394                 INIT_CTL_NAME
395                 .procname       = "subsystem_debug",
396                 .data           = &libcfs_subsystem_debug,
397                 .maxlen         = sizeof(int),
398                 .mode           = 0644,
399                 .proc_handler   = &proc_dobitmasks,
400         },
401         {
402                 INIT_CTL_NAME
403                 .procname       = "printk",
404                 .data           = &libcfs_printk,
405                 .maxlen         = sizeof(int),
406                 .mode           = 0644,
407                 .proc_handler   = &proc_dobitmasks,
408         },
409         {
410                 INIT_CTL_NAME
411                 .procname       = "cpu_partition_table",
412                 .maxlen         = 128,
413                 .mode           = 0444,
414                 .proc_handler   = &proc_cpt_table,
415         },
416         {
417                 INIT_CTL_NAME
418                 .procname       = "cpu_partition_distance",
419                 .maxlen         = 128,
420                 .mode           = 0444,
421                 .proc_handler   = &proc_cpt_distance,
422         },
423         {
424                 INIT_CTL_NAME
425                 .procname       = "debug_log_upcall",
426                 .data           = lnet_debug_log_upcall,
427                 .maxlen         = sizeof(lnet_debug_log_upcall),
428                 .mode           = 0644,
429                 .proc_handler   = &proc_dostring,
430         },
431         {
432                 INIT_CTL_NAME
433                 .procname       = "lnet_memused",
434                 .data           = (int *)&libcfs_kmemory.counter,
435                 .maxlen         = sizeof(int),
436                 .mode           = 0444,
437                 .proc_handler   = &proc_dointvec,
438         },
439         {
440                 INIT_CTL_NAME
441                 .procname       = "catastrophe",
442                 .data           = &libcfs_catastrophe,
443                 .maxlen         = sizeof(int),
444                 .mode           = 0444,
445                 .proc_handler   = &proc_dointvec,
446         },
447         {
448                 INIT_CTL_NAME
449                 .procname       = "dump_kernel",
450                 .maxlen         = 256,
451                 .mode           = 0200,
452                 .proc_handler   = &proc_dump_kernel,
453         },
454         {
455                 INIT_CTL_NAME
456                 .procname       = "daemon_file",
457                 .mode           = 0644,
458                 .maxlen         = 256,
459                 .proc_handler   = &proc_daemon_file,
460         },
461         {
462                 INIT_CTL_NAME
463                 .procname       = "watchdog_ratelimit",
464                 .data           = &libcfs_watchdog_ratelimit,
465                 .maxlen         = sizeof(int),
466                 .mode           = 0644,
467                 .proc_handler   = &proc_dointvec_minmax,
468                 .extra1         = &min_watchdog_ratelimit,
469                 .extra2         = &max_watchdog_ratelimit,
470         },
471         {
472                 INIT_CTL_NAME
473                 .procname       = "force_lbug",
474                 .data           = NULL,
475                 .maxlen         = 0,
476                 .mode           = 0200,
477                 .proc_handler   = &libcfs_force_lbug
478         },
479         {
480                 INIT_CTL_NAME
481                 .procname       = "fail_loc",
482                 .data           = &cfs_fail_loc,
483                 .maxlen         = sizeof(cfs_fail_loc),
484                 .mode           = 0644,
485                 .proc_handler   = &proc_fail_loc
486         },
487         {
488                 INIT_CTL_NAME
489                 .procname       = "fail_val",
490                 .data           = &cfs_fail_val,
491                 .maxlen         = sizeof(int),
492                 .mode           = 0644,
493                 .proc_handler   = &proc_dointvec
494         },
495         {
496                 INIT_CTL_NAME
497                 .procname       = "fail_err",
498                 .data           = &cfs_fail_err,
499                 .maxlen         = sizeof(cfs_fail_err),
500                 .mode           = 0644,
501                 .proc_handler   = &proc_dointvec,
502         },
503         {
504         }
505 };
506
507 static const struct lnet_debugfs_symlink_def lnet_debugfs_symlinks[] = {
508         { .name         = "console_ratelimit",
509           .target       = "../../../module/libcfs/parameters/libcfs_console_ratelimit" },
510         { .name         = "debug_path",
511           .target       = "../../../module/libcfs/parameters/libcfs_debug_file_path" },
512         { .name         = "panic_on_lbug",
513           .target       = "../../../module/libcfs/parameters/libcfs_panic_on_lbug" },
514         { .name         = "console_backoff",
515           .target       = "../../../module/libcfs/parameters/libcfs_console_backoff" },
516         { .name         = "debug_mb",
517           .target       = "../../../module/libcfs/parameters/libcfs_debug_mb" },
518         { .name         = "console_min_delay_centisecs",
519           .target       = "../../../module/libcfs/parameters/libcfs_console_min_delay" },
520         { .name         = "console_max_delay_centisecs",
521           .target       = "../../../module/libcfs/parameters/libcfs_console_max_delay" },
522         { .name         = NULL },
523 };
524
525 static ssize_t lnet_debugfs_read(struct file *filp, char __user *buf,
526                                  size_t count, loff_t *ppos)
527 {
528         struct ctl_table *table = filp->private_data;
529         ssize_t rc;
530
531         rc = table->proc_handler(table, 0, buf, &count, ppos);
532         if (!rc)
533                 rc = count;
534
535         return rc;
536 }
537
538 static ssize_t lnet_debugfs_write(struct file *filp, const char __user *buf,
539                                   size_t count, loff_t *ppos)
540 {
541         struct ctl_table *table = filp->private_data;
542         ssize_t rc;
543
544         rc = table->proc_handler(table, 1, (void __user *)buf, &count, ppos);
545         if (!rc)
546                 rc = count;
547
548         return rc;
549 }
550
551 static const struct file_operations lnet_debugfs_file_operations_rw = {
552         .open           = simple_open,
553         .read           = lnet_debugfs_read,
554         .write          = lnet_debugfs_write,
555         .llseek         = default_llseek,
556 };
557
558 static const struct file_operations lnet_debugfs_file_operations_ro = {
559         .open           = simple_open,
560         .read           = lnet_debugfs_read,
561         .llseek         = default_llseek,
562 };
563
564 static const struct file_operations lnet_debugfs_file_operations_wo = {
565         .open           = simple_open,
566         .write          = lnet_debugfs_write,
567         .llseek         = default_llseek,
568 };
569
570 static const struct file_operations *lnet_debugfs_fops_select(umode_t mode)
571 {
572         if (!(mode & S_IWUGO))
573                 return &lnet_debugfs_file_operations_ro;
574
575         if (!(mode & S_IRUGO))
576                 return &lnet_debugfs_file_operations_wo;
577
578         return &lnet_debugfs_file_operations_rw;
579 }
580
581 void lnet_insert_debugfs(struct ctl_table *table,
582                          const struct lnet_debugfs_symlink_def *symlinks)
583 {
584         if (!lnet_debugfs_root)
585                 lnet_debugfs_root = debugfs_create_dir("lnet", NULL);
586
587         /* Even if we cannot create, just ignore it altogether) */
588         if (IS_ERR_OR_NULL(lnet_debugfs_root))
589                 return;
590
591         /* We don't save the dentry returned in next two calls, because
592          * we don't call debugfs_remove() but rather remove_recursive()
593          */
594         for (; table && table->procname; table++)
595                 debugfs_create_file(table->procname, table->mode,
596                                     lnet_debugfs_root, table,
597                                     lnet_debugfs_fops_select(table->mode));
598
599         for (; symlinks && symlinks->name; symlinks++)
600                 debugfs_create_symlink(symlinks->name, lnet_debugfs_root,
601                                        symlinks->target);
602 }
603 EXPORT_SYMBOL_GPL(lnet_insert_debugfs);
604
605 static void lnet_remove_debugfs(void)
606 {
607         debugfs_remove_recursive(lnet_debugfs_root);
608
609         lnet_debugfs_root = NULL;
610 }
611
612 static int __init libcfs_init(void)
613 {
614         int rc;
615
616         rc = libcfs_debug_init(5 * 1024 * 1024);
617         if (rc < 0) {
618                 printk(KERN_ERR "LustreError: libcfs_debug_init: %d\n", rc);
619                 return (rc);
620         }
621
622         rc = cfs_cpu_init();
623         if (rc != 0)
624                 goto cleanup_debug;
625
626         rc = misc_register(&libcfs_dev);
627         if (rc) {
628                 CERROR("misc_register: error %d\n", rc);
629                 goto cleanup_cpu;
630         }
631
632         rc = cfs_wi_startup();
633         if (rc) {
634                 CERROR("initialize workitem: error %d\n", rc);
635                 goto cleanup_deregister;
636         }
637
638         /* max to 4 threads, should be enough for rehash */
639         rc = min(cfs_cpt_weight(cfs_cpt_table, CFS_CPT_ANY), 4);
640         rc = cfs_wi_sched_create("cfs_rh", cfs_cpt_table, CFS_CPT_ANY,
641                                  rc, &cfs_sched_rehash);
642         if (rc != 0) {
643                 CERROR("Startup workitem scheduler: error: %d\n", rc);
644                 goto cleanup_deregister;
645         }
646
647         rc = cfs_crypto_register();
648         if (rc) {
649                 CERROR("cfs_crypto_regster: error %d\n", rc);
650                 goto cleanup_wi;
651         }
652
653         lnet_insert_debugfs(lnet_table, lnet_debugfs_symlinks);
654
655         CDEBUG (D_OTHER, "portals setup OK\n");
656         return 0;
657 cleanup_wi:
658         cfs_wi_shutdown();
659 cleanup_deregister:
660         misc_deregister(&libcfs_dev);
661 cleanup_cpu:
662         cfs_cpu_fini();
663 cleanup_debug:
664         libcfs_debug_cleanup();
665         return rc;
666 }
667
668 static void __exit libcfs_exit(void)
669 {
670         int rc;
671
672         lnet_remove_debugfs();
673
674         CDEBUG(D_MALLOC, "before Portals cleanup: kmem %d\n",
675                atomic_read(&libcfs_kmemory));
676
677         if (cfs_sched_rehash != NULL) {
678                 cfs_wi_sched_destroy(cfs_sched_rehash);
679                 cfs_sched_rehash = NULL;
680         }
681
682         cfs_crypto_unregister();
683         cfs_wi_shutdown();
684
685         misc_deregister(&libcfs_dev);
686
687         cfs_cpu_fini();
688
689         if (atomic_read(&libcfs_kmemory) != 0)
690                 CERROR("Portals memory leaked: %d bytes\n",
691                        atomic_read(&libcfs_kmemory));
692
693         rc = libcfs_debug_cleanup();
694         if (rc)
695                 printk(KERN_ERR "LustreError: libcfs_debug_cleanup: %d\n",
696                        rc);
697 }
698
699 MODULE_AUTHOR("OpenSFS, Inc. <http://www.lustre.org/>");
700 MODULE_DESCRIPTION("Lustre helper library");
701 MODULE_VERSION(LIBCFS_VERSION);
702 MODULE_LICENSE("GPL");
703
704 module_init(libcfs_init);
705 module_exit(libcfs_exit);