1 /*****************************************************************************\
2 * Copyright (C) 2007-2010 Lawrence Livermore National Security, LLC.
3 * Copyright (C) 2007 The Regents of the University of California.
4 * Produced at Lawrence Livermore National Laboratory (cf, DISCLAIMER).
5 * Written by Brian Behlendorf <behlendorf1@llnl.gov>.
8 * This file is part of the SPL, Solaris Porting Layer.
9 * For details, see <http://github.com/behlendorf/spl/>.
11 * The SPL is free software; you can redistribute it and/or modify it
12 * under the terms of the GNU General Public License as published by the
13 * Free Software Foundation; either version 2 of the License, or (at your
14 * option) any later version.
16 * The SPL is distributed in the hope that it will be useful, but WITHOUT
17 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
18 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
21 * You should have received a copy of the GNU General Public License along
22 * with the SPL. If not, see <http://www.gnu.org/licenses/>.
23 *****************************************************************************
24 * Solaris Porting Layer (SPL) Proc Implementation.
25 \*****************************************************************************/
29 #ifdef DEBUG_SUBSYSTEM
30 #undef DEBUG_SUBSYSTEM
33 #define DEBUG_SUBSYSTEM S_PROC
36 static unsigned long table_min = 0;
37 static unsigned long table_max = ~0;
41 static struct ctl_table_header *spl_header = NULL;
42 #endif /* CONFIG_SYSCTL */
44 static struct proc_dir_entry *proc_spl = NULL;
46 static struct proc_dir_entry *proc_spl_kmem = NULL;
47 static struct proc_dir_entry *proc_spl_kmem_slab = NULL;
48 #endif /* DEBUG_KMEM */
49 struct proc_dir_entry *proc_spl_kstat = NULL;
51 #ifdef HAVE_CTL_UNNUMBERED
53 #define CTL_SPL CTL_UNNUMBERED
54 #define CTL_SPL_DEBUG CTL_UNNUMBERED
55 #define CTL_SPL_VM CTL_UNNUMBERED
56 #define CTL_SPL_MUTEX CTL_UNNUMBERED
57 #define CTL_SPL_KMEM CTL_UNNUMBERED
58 #define CTL_SPL_KSTAT CTL_UNNUMBERED
60 #define CTL_VERSION CTL_UNNUMBERED /* Version */
61 #define CTL_HOSTID CTL_UNNUMBERED /* Host id by /usr/bin/hostid */
62 #define CTL_HW_SERIAL CTL_UNNUMBERED /* HW serial number by hostid */
63 #define CTL_KALLSYMS CTL_UNNUMBERED /* kallsyms_lookup_name addr */
65 #define CTL_DEBUG_SUBSYS CTL_UNNUMBERED /* Debug subsystem */
66 #define CTL_DEBUG_MASK CTL_UNNUMBERED /* Debug mask */
67 #define CTL_DEBUG_PRINTK CTL_UNNUMBERED /* All messages to console */
68 #define CTL_DEBUG_MB CTL_UNNUMBERED /* Debug buffer size */
69 #define CTL_DEBUG_BINARY CTL_UNNUMBERED /* Binary data in buffer */
70 #define CTL_DEBUG_CATASTROPHE CTL_UNNUMBERED /* Set if BUG'd or panic'd */
71 #define CTL_DEBUG_PANIC_ON_BUG CTL_UNNUMBERED /* Should panic on BUG */
72 #define CTL_DEBUG_PATH CTL_UNNUMBERED /* Dump log location */
73 #define CTL_DEBUG_DUMP CTL_UNNUMBERED /* Dump debug buffer to file */
74 #define CTL_DEBUG_FORCE_BUG CTL_UNNUMBERED /* Hook to force a BUG */
75 #define CTL_DEBUG_STACK_SIZE CTL_UNNUMBERED /* Max observed stack size */
77 #define CTL_CONSOLE_RATELIMIT CTL_UNNUMBERED /* Ratelimit console messages */
78 #define CTL_CONSOLE_MAX_DELAY_CS CTL_UNNUMBERED /* Max delay skip messages */
79 #define CTL_CONSOLE_MIN_DELAY_CS CTL_UNNUMBERED /* Init delay skip messages */
80 #define CTL_CONSOLE_BACKOFF CTL_UNNUMBERED /* Delay increase factor */
82 #define CTL_VM_MINFREE CTL_UNNUMBERED /* Minimum free memory */
83 #define CTL_VM_DESFREE CTL_UNNUMBERED /* Desired free memory */
84 #define CTL_VM_LOTSFREE CTL_UNNUMBERED /* Lots of free memory */
85 #define CTL_VM_NEEDFREE CTL_UNNUMBERED /* Need free memory */
86 #define CTL_VM_SWAPFS_MINFREE CTL_UNNUMBERED /* Minimum swapfs memory */
87 #define CTL_VM_SWAPFS_RESERVE CTL_UNNUMBERED /* Reserved swapfs memory */
88 #define CTL_VM_AVAILRMEM CTL_UNNUMBERED /* Easily available memory */
89 #define CTL_VM_FREEMEM CTL_UNNUMBERED /* Free memory */
90 #define CTL_VM_PHYSMEM CTL_UNNUMBERED /* Total physical memory */
93 #define CTL_KMEM_KMEMUSED CTL_UNNUMBERED /* Alloc'd kmem bytes */
94 #define CTL_KMEM_KMEMMAX CTL_UNNUMBERED /* Max alloc'd by kmem bytes */
95 #define CTL_KMEM_VMEMUSED CTL_UNNUMBERED /* Alloc'd vmem bytes */
96 #define CTL_KMEM_VMEMMAX CTL_UNNUMBERED /* Max alloc'd by vmem bytes */
97 #define CTL_KMEM_ALLOC_FAILED CTL_UNNUMBERED /* Cache allocations failed */
100 #else /* HAVE_CTL_UNNUMBERED */
104 CTL_SPL_DEBUG = 0x88,
106 CTL_SPL_MUTEX = 0x90,
108 CTL_SPL_KSTAT = 0x92,
112 CTL_VERSION = 1, /* Version */
113 CTL_HOSTID, /* Host id reported by /usr/bin/hostid */
114 CTL_HW_SERIAL, /* Hardware serial number from hostid */
115 CTL_KALLSYMS, /* Address of kallsyms_lookup_name */
117 CTL_DEBUG_SUBSYS, /* Debug subsystem */
118 CTL_DEBUG_MASK, /* Debug mask */
119 CTL_DEBUG_PRINTK, /* Force all messages to console */
120 CTL_DEBUG_MB, /* Debug buffer size */
121 CTL_DEBUG_BINARY, /* Include binary data in buffer */
122 CTL_DEBUG_CATASTROPHE, /* Set if we have BUG'd or panic'd */
123 CTL_DEBUG_PANIC_ON_BUG, /* Set if we should panic on BUG */
124 CTL_DEBUG_PATH, /* Dump log location */
125 CTL_DEBUG_DUMP, /* Dump debug buffer to file */
126 CTL_DEBUG_FORCE_BUG, /* Hook to force a BUG */
127 CTL_DEBUG_STACK_SIZE, /* Max observed stack size */
129 CTL_CONSOLE_RATELIMIT, /* Ratelimit console messages */
130 CTL_CONSOLE_MAX_DELAY_CS, /* Max delay which we skip messages */
131 CTL_CONSOLE_MIN_DELAY_CS, /* Init delay which we skip messages */
132 CTL_CONSOLE_BACKOFF, /* Delay increase factor */
134 CTL_VM_MINFREE, /* Minimum free memory threshold */
135 CTL_VM_DESFREE, /* Desired free memory threshold */
136 CTL_VM_LOTSFREE, /* Lots of free memory threshold */
137 CTL_VM_NEEDFREE, /* Need free memory deficit */
138 CTL_VM_SWAPFS_MINFREE, /* Minimum swapfs memory */
139 CTL_VM_SWAPFS_RESERVE, /* Reserved swapfs memory */
140 CTL_VM_AVAILRMEM, /* Easily available memory */
141 CTL_VM_FREEMEM, /* Free memory */
142 CTL_VM_PHYSMEM, /* Total physical memory */
145 CTL_KMEM_KMEMUSED, /* Alloc'd kmem bytes */
146 CTL_KMEM_KMEMMAX, /* Max alloc'd by kmem bytes */
147 CTL_KMEM_VMEMUSED, /* Alloc'd vmem bytes */
148 CTL_KMEM_VMEMMAX, /* Max alloc'd by vmem bytes */
151 #endif /* HAVE_CTL_UNNUMBERED */
154 proc_copyin_string(char *kbuffer, int kbuffer_size,
155 const char *ubuffer, int ubuffer_size)
159 if (ubuffer_size > kbuffer_size)
162 if (copy_from_user((void *)kbuffer, (void *)ubuffer, ubuffer_size))
165 /* strip trailing whitespace */
166 size = strnlen(kbuffer, ubuffer_size);
168 if (!isspace(kbuffer[size]))
175 /* no space to terminate */
176 if (size == kbuffer_size)
179 kbuffer[size + 1] = 0;
184 proc_copyout_string(char *ubuffer, int ubuffer_size,
185 const char *kbuffer, char *append)
187 /* NB if 'append' != NULL, it's a single character to append to the
188 * copied out string - usually "\n", for /proc entries and
189 * (i.e. a terminating zero byte) for sysctl entries
191 int size = MIN(strlen(kbuffer), ubuffer_size);
193 if (copy_to_user(ubuffer, kbuffer, size))
196 if (append != NULL && size < ubuffer_size) {
197 if (copy_to_user(ubuffer + size, append, 1))
206 SPL_PROC_HANDLER(proc_dobitmasks)
208 unsigned long *mask = table->data;
209 int is_subsys = (mask == &spl_debug_subsys) ? 1 : 0;
210 int is_printk = (mask == &spl_debug_printk) ? 1 : 0;
215 str = kmem_alloc(size, KM_SLEEP);
220 rc = proc_copyin_string(str, size, buffer, *lenp);
224 rc = spl_debug_str2mask(mask, str, is_subsys);
225 /* Always print BUG/ASSERT to console, so keep this mask */
231 rc = spl_debug_mask2str(str, size, *mask, is_subsys);
235 rc = proc_copyout_string(buffer, *lenp,
243 kmem_free(str, size);
247 SPL_PROC_HANDLER(proc_debug_mb)
254 rc = proc_copyin_string(str, sizeof(str), buffer, *lenp);
258 rc = spl_debug_set_mb(simple_strtoul(str, NULL, 0));
261 len = snprintf(str, sizeof(str), "%d", spl_debug_get_mb());
265 rc = proc_copyout_string(buffer,*lenp,str+*ppos,"\n");
276 SPL_PROC_HANDLER(proc_dump_kernel)
281 spl_debug_dumplog(0);
290 SPL_PROC_HANDLER(proc_force_bug)
295 CERROR("Crashing due to forced SBUG\n");
305 SPL_PROC_HANDLER(proc_console_max_delay_cs)
307 int rc, max_delay_cs;
308 struct ctl_table dummy = *table;
312 dummy.data = &max_delay_cs;
313 dummy.proc_handler = &proc_dointvec;
317 rc = spl_proc_dointvec(&dummy,write,filp,buffer,lenp,ppos);
321 if (max_delay_cs <= 0)
324 d = (max_delay_cs * HZ) / 100;
325 if (d == 0 || d < spl_console_min_delay)
328 spl_console_max_delay = d;
330 max_delay_cs = (spl_console_max_delay * 100) / HZ;
331 rc = spl_proc_dointvec(&dummy,write,filp,buffer,lenp,ppos);
337 SPL_PROC_HANDLER(proc_console_min_delay_cs)
339 int rc, min_delay_cs;
340 struct ctl_table dummy = *table;
344 dummy.data = &min_delay_cs;
345 dummy.proc_handler = &proc_dointvec;
349 rc = spl_proc_dointvec(&dummy,write,filp,buffer,lenp,ppos);
353 if (min_delay_cs <= 0)
356 d = (min_delay_cs * HZ) / 100;
357 if (d == 0 || d > spl_console_max_delay)
360 spl_console_min_delay = d;
362 min_delay_cs = (spl_console_min_delay * 100) / HZ;
363 rc = spl_proc_dointvec(&dummy,write,filp,buffer,lenp,ppos);
369 SPL_PROC_HANDLER(proc_console_backoff)
372 struct ctl_table dummy = *table;
375 dummy.data = &backoff;
376 dummy.proc_handler = &proc_dointvec;
380 rc = spl_proc_dointvec(&dummy,write,filp,buffer,lenp,ppos);
387 spl_console_backoff = backoff;
389 backoff = spl_console_backoff;
390 rc = spl_proc_dointvec(&dummy,write,filp,buffer,lenp,ppos);
397 SPL_PROC_HANDLER(proc_domemused)
400 unsigned long min = 0, max = ~0, val;
401 struct ctl_table dummy = *table;
405 dummy.proc_handler = &proc_dointvec;
412 # ifdef HAVE_ATOMIC64_T
413 val = atomic64_read((atomic64_t *)table->data);
415 val = atomic_read((atomic_t *)table->data);
416 # endif /* HAVE_ATOMIC64_T */
417 rc = spl_proc_doulongvec_minmax(&dummy, write, filp,
423 #endif /* DEBUG_KMEM */
425 SPL_PROC_HANDLER(proc_dohostid)
433 /* We can't use spl_proc_doulongvec_minmax() in the write
434 * case hear because hostid while a hex value has no
435 * leading 0x which confuses the helper function. */
436 rc = proc_copyin_string(str, sizeof(str), buffer, *lenp);
440 val = simple_strtol(str, &end, 16);
444 spl_hostid = (long) val;
445 (void) snprintf(hw_serial, HW_HOSTID_LEN, "%u",
446 (val >= 0) ? val : -val);
447 hw_serial[HW_HOSTID_LEN - 1] = '\0';
450 len = snprintf(str, sizeof(str), "%lx", spl_hostid);
454 rc = proc_copyout_string(buffer,*lenp,str+*ppos,"\n");
465 #ifndef HAVE_KALLSYMS_LOOKUP_NAME
466 SPL_PROC_HANDLER(proc_dokallsyms_lookup_name)
473 /* This may only be set once at module load time */
474 if (spl_kallsyms_lookup_name_fn != SYMBOL_POISON)
477 /* We can't use spl_proc_doulongvec_minmax() in the write
478 * case hear because the address while a hex value has no
479 * leading 0x which confuses the helper function. */
480 rc = proc_copyin_string(str, sizeof(str), buffer, *lenp);
484 spl_kallsyms_lookup_name_fn =
485 (kallsyms_lookup_name_t)simple_strtoul(str, &end, 16);
491 len = snprintf(str, sizeof(str), "%lx",
492 (unsigned long)spl_kallsyms_lookup_name_fn);
496 rc = proc_copyout_string(buffer,*lenp,str+*ppos,"\n");
506 #endif /* HAVE_KALLSYMS_LOOKUP_NAME */
508 SPL_PROC_HANDLER(proc_doavailrmem)
517 len = snprintf(str, sizeof(str), "%lu",
518 (unsigned long)availrmem);
522 rc = proc_copyout_string(buffer,*lenp,str+*ppos,"\n");
533 SPL_PROC_HANDLER(proc_dofreemem)
542 len = snprintf(str, sizeof(str), "%lu", (unsigned long)freemem);
546 rc = proc_copyout_string(buffer,*lenp,str+*ppos,"\n");
559 slab_seq_show_headers(struct seq_file *f)
561 seq_printf(f, "%-36s %-6s - %s %s %s - %s %s %s - "
562 "%s %s %s - %s %s %s\n", "name", "flags",
563 "obj_size", "slab_objs", "slab_size",
564 "slab_fail", "slab_create", "slab_destroy",
565 "slab_total", "slab_alloc", "slab_max",
566 "obj_total", "obj_alloc", "obj_max");
570 slab_seq_show(struct seq_file *f, void *p)
572 spl_kmem_cache_t *skc = p;
574 ASSERT(skc->skc_magic == SKC_MAGIC);
576 spin_lock(&skc->skc_lock);
577 seq_printf(f, "%-36s ", skc->skc_name);
578 seq_printf(f, "0x%04lx - %u %u %u - %lu %lu %lu - "
579 "%lu %lu %lu - %lu %lu %lu\n",
580 (long unsigned)skc->skc_flags,
581 (unsigned)skc->skc_obj_size,
582 (unsigned)skc->skc_slab_objs,
583 (unsigned)skc->skc_slab_size,
584 (long unsigned)skc->skc_slab_fail,
585 (long unsigned)skc->skc_slab_create,
586 (long unsigned)skc->skc_slab_destroy,
587 (long unsigned)skc->skc_slab_total,
588 (long unsigned)skc->skc_slab_alloc,
589 (long unsigned)skc->skc_slab_max,
590 (long unsigned)skc->skc_obj_total,
591 (long unsigned)skc->skc_obj_alloc,
592 (long unsigned)skc->skc_obj_max);
594 spin_unlock(&skc->skc_lock);
600 slab_seq_start(struct seq_file *f, loff_t *pos)
606 down_read(&spl_kmem_cache_sem);
608 slab_seq_show_headers(f);
610 p = spl_kmem_cache_list.next;
613 if (p == &spl_kmem_cache_list)
617 RETURN(list_entry(p, spl_kmem_cache_t, skc_list));
621 slab_seq_next(struct seq_file *f, void *p, loff_t *pos)
623 spl_kmem_cache_t *skc = p;
627 RETURN((skc->skc_list.next == &spl_kmem_cache_list) ?
628 NULL : list_entry(skc->skc_list.next,spl_kmem_cache_t,skc_list));
632 slab_seq_stop(struct seq_file *f, void *v)
634 up_read(&spl_kmem_cache_sem);
637 static struct seq_operations slab_seq_ops = {
638 .show = slab_seq_show,
639 .start = slab_seq_start,
640 .next = slab_seq_next,
641 .stop = slab_seq_stop,
645 proc_slab_open(struct inode *inode, struct file *filp)
647 return seq_open(filp, &slab_seq_ops);
650 static struct file_operations proc_slab_operations = {
651 .open = proc_slab_open,
654 .release = seq_release,
656 #endif /* DEBUG_KMEM */
658 static struct ctl_table spl_debug_table[] = {
660 .ctl_name = CTL_DEBUG_SUBSYS,
661 .procname = "subsystem",
662 .data = &spl_debug_subsys,
663 .maxlen = sizeof(unsigned long),
665 .proc_handler = &proc_dobitmasks
668 .ctl_name = CTL_DEBUG_MASK,
670 .data = &spl_debug_mask,
671 .maxlen = sizeof(unsigned long),
673 .proc_handler = &proc_dobitmasks
676 .ctl_name = CTL_DEBUG_PRINTK,
677 .procname = "printk",
678 .data = &spl_debug_printk,
679 .maxlen = sizeof(unsigned long),
681 .proc_handler = &proc_dobitmasks
684 .ctl_name = CTL_DEBUG_MB,
687 .proc_handler = &proc_debug_mb,
690 .ctl_name = CTL_DEBUG_BINARY,
691 .procname = "binary",
692 .data = &spl_debug_binary,
693 .maxlen = sizeof(int),
695 .proc_handler = &proc_dointvec,
698 .ctl_name = CTL_DEBUG_CATASTROPHE,
699 .procname = "catastrophe",
700 .data = &spl_debug_catastrophe,
701 .maxlen = sizeof(int),
703 .proc_handler = &proc_dointvec,
706 .ctl_name = CTL_DEBUG_PANIC_ON_BUG,
707 .procname = "panic_on_bug",
708 .data = &spl_debug_panic_on_bug,
709 .maxlen = sizeof(int),
711 .proc_handler = &proc_dointvec
714 .ctl_name = CTL_DEBUG_PATH,
716 .data = spl_debug_file_path,
717 .maxlen = sizeof(spl_debug_file_path),
719 .proc_handler = &proc_dostring,
722 .ctl_name = CTL_DEBUG_DUMP,
725 .proc_handler = &proc_dump_kernel,
727 { .ctl_name = CTL_DEBUG_FORCE_BUG,
728 .procname = "force_bug",
730 .proc_handler = &proc_force_bug,
733 .ctl_name = CTL_CONSOLE_RATELIMIT,
734 .procname = "console_ratelimit",
735 .data = &spl_console_ratelimit,
736 .maxlen = sizeof(int),
738 .proc_handler = &proc_dointvec,
741 .ctl_name = CTL_CONSOLE_MAX_DELAY_CS,
742 .procname = "console_max_delay_centisecs",
743 .maxlen = sizeof(int),
745 .proc_handler = &proc_console_max_delay_cs,
748 .ctl_name = CTL_CONSOLE_MIN_DELAY_CS,
749 .procname = "console_min_delay_centisecs",
750 .maxlen = sizeof(int),
752 .proc_handler = &proc_console_min_delay_cs,
755 .ctl_name = CTL_CONSOLE_BACKOFF,
756 .procname = "console_backoff",
757 .maxlen = sizeof(int),
759 .proc_handler = &proc_console_backoff,
762 .ctl_name = CTL_DEBUG_STACK_SIZE,
763 .procname = "stack_max",
764 .data = &spl_debug_stack,
765 .maxlen = sizeof(int),
767 .proc_handler = &proc_dointvec,
772 static struct ctl_table spl_vm_table[] = {
774 .ctl_name = CTL_VM_MINFREE,
775 .procname = "minfree",
777 .maxlen = sizeof(int),
779 .proc_handler = &proc_dointvec,
782 .ctl_name = CTL_VM_DESFREE,
783 .procname = "desfree",
785 .maxlen = sizeof(int),
787 .proc_handler = &proc_dointvec,
790 .ctl_name = CTL_VM_LOTSFREE,
791 .procname = "lotsfree",
793 .maxlen = sizeof(int),
795 .proc_handler = &proc_dointvec,
798 .ctl_name = CTL_VM_NEEDFREE,
799 .procname = "needfree",
801 .maxlen = sizeof(int),
803 .proc_handler = &proc_dointvec,
806 .ctl_name = CTL_VM_SWAPFS_MINFREE,
807 .procname = "swapfs_minfree",
808 .data = &swapfs_minfree,
809 .maxlen = sizeof(int),
811 .proc_handler = &proc_dointvec,
814 .ctl_name = CTL_VM_SWAPFS_RESERVE,
815 .procname = "swapfs_reserve",
816 .data = &swapfs_reserve,
817 .maxlen = sizeof(int),
819 .proc_handler = &proc_dointvec,
822 .ctl_name = CTL_VM_AVAILRMEM,
823 .procname = "availrmem",
825 .proc_handler = &proc_doavailrmem,
828 .ctl_name = CTL_VM_FREEMEM,
829 .procname = "freemem",
831 .maxlen = sizeof(int),
833 .proc_handler = &proc_dofreemem,
836 .ctl_name = CTL_VM_PHYSMEM,
837 .procname = "physmem",
839 .maxlen = sizeof(int),
841 .proc_handler = &proc_dointvec,
847 static struct ctl_table spl_kmem_table[] = {
849 .ctl_name = CTL_KMEM_KMEMUSED,
850 .procname = "kmem_used",
851 .data = &kmem_alloc_used,
852 # ifdef HAVE_ATOMIC64_T
853 .maxlen = sizeof(atomic64_t),
855 .maxlen = sizeof(atomic_t),
856 # endif /* HAVE_ATOMIC64_T */
858 .proc_handler = &proc_domemused,
861 .ctl_name = CTL_KMEM_KMEMMAX,
862 .procname = "kmem_max",
863 .data = &kmem_alloc_max,
864 .maxlen = sizeof(unsigned long),
865 .extra1 = &table_min,
866 .extra2 = &table_max,
868 .proc_handler = &proc_doulongvec_minmax,
871 .ctl_name = CTL_KMEM_VMEMUSED,
872 .procname = "vmem_used",
873 .data = &vmem_alloc_used,
874 # ifdef HAVE_ATOMIC64_T
875 .maxlen = sizeof(atomic64_t),
877 .maxlen = sizeof(atomic_t),
878 # endif /* HAVE_ATOMIC64_T */
880 .proc_handler = &proc_domemused,
883 .ctl_name = CTL_KMEM_VMEMMAX,
884 .procname = "vmem_max",
885 .data = &vmem_alloc_max,
886 .maxlen = sizeof(unsigned long),
887 .extra1 = &table_min,
888 .extra2 = &table_max,
890 .proc_handler = &proc_doulongvec_minmax,
894 #endif /* DEBUG_KMEM */
896 static struct ctl_table spl_kstat_table[] = {
900 static struct ctl_table spl_table[] = {
901 /* NB No .strategy entries have been provided since
902 * sysctl(8) prefers to go via /proc for portability.
905 .ctl_name = CTL_VERSION,
906 .procname = "version",
908 .maxlen = sizeof(spl_version),
910 .proc_handler = &proc_dostring,
913 .ctl_name = CTL_HOSTID,
914 .procname = "hostid",
916 .maxlen = sizeof(unsigned long),
918 .proc_handler = &proc_dohostid,
921 .ctl_name = CTL_HW_SERIAL,
922 .procname = "hw_serial",
924 .maxlen = sizeof(hw_serial),
926 .proc_handler = &proc_dostring,
928 #ifndef HAVE_KALLSYMS_LOOKUP_NAME
930 .ctl_name = CTL_KALLSYMS,
931 .procname = "kallsyms_lookup_name",
932 .data = &spl_kallsyms_lookup_name_fn,
933 .maxlen = sizeof(unsigned long),
935 .proc_handler = &proc_dokallsyms_lookup_name,
939 .ctl_name = CTL_SPL_DEBUG,
942 .child = spl_debug_table,
945 .ctl_name = CTL_SPL_VM,
948 .child = spl_vm_table,
952 .ctl_name = CTL_SPL_KMEM,
955 .child = spl_kmem_table,
959 .ctl_name = CTL_SPL_KSTAT,
962 .child = spl_kstat_table,
967 static struct ctl_table spl_dir[] = {
977 static struct ctl_table spl_root[] = {
979 .ctl_name = CTL_KERN,
980 .procname = "kernel",
988 proc_dir_entry_match(int len, const char *name, struct proc_dir_entry *de)
990 if (de->namelen != len)
993 return !memcmp(name, de->name, len);
996 struct proc_dir_entry *
997 proc_dir_entry_find(struct proc_dir_entry *root, const char *str)
999 struct proc_dir_entry *de;
1001 for (de = root->subdir; de; de = de->next)
1002 if (proc_dir_entry_match(strlen(str), str, de))
1009 proc_dir_entries(struct proc_dir_entry *root)
1011 struct proc_dir_entry *de;
1014 for (de = root->subdir; de; de = de->next)
1026 #ifdef CONFIG_SYSCTL
1027 spl_header = spl_register_sysctl_table(spl_root, 0);
1028 if (spl_header == NULL)
1030 #endif /* CONFIG_SYSCTL */
1032 proc_spl = proc_mkdir("spl", NULL);
1033 if (proc_spl == NULL)
1034 GOTO(out, rc = -EUNATCH);
1037 proc_spl_kmem = proc_mkdir("kmem", proc_spl);
1038 if (proc_spl_kmem == NULL)
1039 GOTO(out, rc = -EUNATCH);
1041 proc_spl_kmem_slab = create_proc_entry("slab", 0444, proc_spl_kmem);
1042 if (proc_spl_kmem_slab == NULL)
1043 GOTO(out, rc = -EUNATCH);
1045 proc_spl_kmem_slab->proc_fops = &proc_slab_operations;
1046 #endif /* DEBUG_KMEM */
1048 proc_spl_kstat = proc_mkdir("kstat", proc_spl);
1049 if (proc_spl_kstat == NULL)
1050 GOTO(out, rc = -EUNATCH);
1053 remove_proc_entry("kstat", proc_spl);
1055 remove_proc_entry("slab", proc_spl_kmem);
1056 remove_proc_entry("kmem", proc_spl);
1058 remove_proc_entry("spl", NULL);
1059 #ifdef CONFIG_SYSCTL
1060 spl_unregister_sysctl_table(spl_header);
1061 #endif /* CONFIG_SYSCTL */
1072 remove_proc_entry("kstat", proc_spl);
1074 remove_proc_entry("slab", proc_spl_kmem);
1075 remove_proc_entry("kmem", proc_spl);
1077 remove_proc_entry("spl", NULL);
1079 #ifdef CONFIG_SYSCTL
1080 ASSERT(spl_header != NULL);
1081 spl_unregister_sysctl_table(spl_header);
1082 #endif /* CONFIG_SYSCTL */