1 | // SPDX-License-Identifier: GPL-2.0-or-later |
2 | /* |
3 | * Copyright (C) 2004, 2005 Oracle. All rights reserved. |
4 | */ |
5 | |
6 | #include <linux/module.h> |
7 | #include <linux/kernel.h> |
8 | #include <linux/proc_fs.h> |
9 | #include <linux/seq_file.h> |
10 | #include <linux/string.h> |
11 | #include <linux/uaccess.h> |
12 | |
13 | #include "masklog.h" |
14 | |
15 | struct mlog_bits mlog_and_bits = MLOG_BITS_RHS(MLOG_INITIAL_AND_MASK); |
16 | EXPORT_SYMBOL_GPL(mlog_and_bits); |
17 | struct mlog_bits mlog_not_bits = MLOG_BITS_RHS(0); |
18 | EXPORT_SYMBOL_GPL(mlog_not_bits); |
19 | |
20 | static ssize_t mlog_mask_show(u64 mask, char *buf) |
21 | { |
22 | char *state; |
23 | |
24 | if (__mlog_test_u64(mask, mlog_and_bits)) |
25 | state = "allow" ; |
26 | else if (__mlog_test_u64(mask, mlog_not_bits)) |
27 | state = "deny" ; |
28 | else |
29 | state = "off" ; |
30 | |
31 | return snprintf(buf, PAGE_SIZE, fmt: "%s\n" , state); |
32 | } |
33 | |
34 | static ssize_t mlog_mask_store(u64 mask, const char *buf, size_t count) |
35 | { |
36 | if (!strncasecmp(s1: buf, s2: "allow" , n: 5)) { |
37 | __mlog_set_u64(mask, mlog_and_bits); |
38 | __mlog_clear_u64(mask, mlog_not_bits); |
39 | } else if (!strncasecmp(s1: buf, s2: "deny" , n: 4)) { |
40 | __mlog_set_u64(mask, mlog_not_bits); |
41 | __mlog_clear_u64(mask, mlog_and_bits); |
42 | } else if (!strncasecmp(s1: buf, s2: "off" , n: 3)) { |
43 | __mlog_clear_u64(mask, mlog_not_bits); |
44 | __mlog_clear_u64(mask, mlog_and_bits); |
45 | } else |
46 | return -EINVAL; |
47 | |
48 | return count; |
49 | } |
50 | |
51 | void __mlog_printk(const u64 *mask, const char *func, int line, |
52 | const char *fmt, ...) |
53 | { |
54 | struct va_format vaf; |
55 | va_list args; |
56 | const char *level; |
57 | const char *prefix = "" ; |
58 | |
59 | if (!__mlog_test_u64(*mask, mlog_and_bits) || |
60 | __mlog_test_u64(*mask, mlog_not_bits)) |
61 | return; |
62 | |
63 | if (*mask & ML_ERROR) { |
64 | level = KERN_ERR; |
65 | prefix = "ERROR: " ; |
66 | } else if (*mask & ML_NOTICE) { |
67 | level = KERN_NOTICE; |
68 | } else { |
69 | level = KERN_INFO; |
70 | } |
71 | |
72 | va_start(args, fmt); |
73 | |
74 | vaf.fmt = fmt; |
75 | vaf.va = &args; |
76 | |
77 | printk("%s(%s,%u,%u):%s:%d %s%pV" , |
78 | level, current->comm, task_pid_nr(current), |
79 | raw_smp_processor_id(), func, line, prefix, &vaf); |
80 | |
81 | va_end(args); |
82 | } |
83 | EXPORT_SYMBOL_GPL(__mlog_printk); |
84 | |
85 | struct mlog_attribute { |
86 | struct attribute attr; |
87 | u64 mask; |
88 | }; |
89 | |
90 | #define to_mlog_attr(_attr) container_of(_attr, struct mlog_attribute, attr) |
91 | |
92 | #define define_mask(_name) { \ |
93 | .attr = { \ |
94 | .name = #_name, \ |
95 | .mode = S_IRUGO | S_IWUSR, \ |
96 | }, \ |
97 | .mask = ML_##_name, \ |
98 | } |
99 | |
100 | static struct mlog_attribute mlog_attrs[MLOG_MAX_BITS] = { |
101 | define_mask(TCP), |
102 | define_mask(MSG), |
103 | define_mask(SOCKET), |
104 | define_mask(HEARTBEAT), |
105 | define_mask(HB_BIO), |
106 | define_mask(DLMFS), |
107 | define_mask(DLM), |
108 | define_mask(DLM_DOMAIN), |
109 | define_mask(DLM_THREAD), |
110 | define_mask(DLM_MASTER), |
111 | define_mask(DLM_RECOVERY), |
112 | define_mask(DLM_GLUE), |
113 | define_mask(VOTE), |
114 | define_mask(CONN), |
115 | define_mask(QUORUM), |
116 | define_mask(BASTS), |
117 | define_mask(CLUSTER), |
118 | define_mask(ERROR), |
119 | define_mask(NOTICE), |
120 | define_mask(KTHREAD), |
121 | }; |
122 | |
123 | static struct attribute *mlog_default_attrs[MLOG_MAX_BITS] = {NULL, }; |
124 | ATTRIBUTE_GROUPS(mlog_default); |
125 | |
126 | static ssize_t mlog_show(struct kobject *obj, struct attribute *attr, |
127 | char *buf) |
128 | { |
129 | struct mlog_attribute *mlog_attr = to_mlog_attr(attr); |
130 | |
131 | return mlog_mask_show(mask: mlog_attr->mask, buf); |
132 | } |
133 | |
134 | static ssize_t mlog_store(struct kobject *obj, struct attribute *attr, |
135 | const char *buf, size_t count) |
136 | { |
137 | struct mlog_attribute *mlog_attr = to_mlog_attr(attr); |
138 | |
139 | return mlog_mask_store(mask: mlog_attr->mask, buf, count); |
140 | } |
141 | |
142 | static const struct sysfs_ops mlog_attr_ops = { |
143 | .show = mlog_show, |
144 | .store = mlog_store, |
145 | }; |
146 | |
147 | static struct kobj_type mlog_ktype = { |
148 | .default_groups = mlog_default_groups, |
149 | .sysfs_ops = &mlog_attr_ops, |
150 | }; |
151 | |
152 | static struct kset mlog_kset = { |
153 | .kobj = {.ktype = &mlog_ktype}, |
154 | }; |
155 | |
156 | int mlog_sys_init(struct kset *o2cb_kset) |
157 | { |
158 | int i = 0; |
159 | |
160 | while (mlog_attrs[i].attr.mode) { |
161 | mlog_default_attrs[i] = &mlog_attrs[i].attr; |
162 | i++; |
163 | } |
164 | mlog_default_attrs[i] = NULL; |
165 | |
166 | kobject_set_name(kobj: &mlog_kset.kobj, name: "logmask" ); |
167 | mlog_kset.kobj.kset = o2cb_kset; |
168 | return kset_register(kset: &mlog_kset); |
169 | } |
170 | |
171 | void mlog_sys_shutdown(void) |
172 | { |
173 | kset_unregister(kset: &mlog_kset); |
174 | } |
175 | |