162306a36Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0-or-later
262306a36Sopenharmony_ci/*
362306a36Sopenharmony_ci * Copyright (C) 2004, 2005 Oracle.  All rights reserved.
462306a36Sopenharmony_ci */
562306a36Sopenharmony_ci
662306a36Sopenharmony_ci#include <linux/module.h>
762306a36Sopenharmony_ci#include <linux/kernel.h>
862306a36Sopenharmony_ci#include <linux/proc_fs.h>
962306a36Sopenharmony_ci#include <linux/seq_file.h>
1062306a36Sopenharmony_ci#include <linux/string.h>
1162306a36Sopenharmony_ci#include <linux/uaccess.h>
1262306a36Sopenharmony_ci
1362306a36Sopenharmony_ci#include "masklog.h"
1462306a36Sopenharmony_ci
1562306a36Sopenharmony_cistruct mlog_bits mlog_and_bits = MLOG_BITS_RHS(MLOG_INITIAL_AND_MASK);
1662306a36Sopenharmony_ciEXPORT_SYMBOL_GPL(mlog_and_bits);
1762306a36Sopenharmony_cistruct mlog_bits mlog_not_bits = MLOG_BITS_RHS(0);
1862306a36Sopenharmony_ciEXPORT_SYMBOL_GPL(mlog_not_bits);
1962306a36Sopenharmony_ci
2062306a36Sopenharmony_cistatic ssize_t mlog_mask_show(u64 mask, char *buf)
2162306a36Sopenharmony_ci{
2262306a36Sopenharmony_ci	char *state;
2362306a36Sopenharmony_ci
2462306a36Sopenharmony_ci	if (__mlog_test_u64(mask, mlog_and_bits))
2562306a36Sopenharmony_ci		state = "allow";
2662306a36Sopenharmony_ci	else if (__mlog_test_u64(mask, mlog_not_bits))
2762306a36Sopenharmony_ci		state = "deny";
2862306a36Sopenharmony_ci	else
2962306a36Sopenharmony_ci		state = "off";
3062306a36Sopenharmony_ci
3162306a36Sopenharmony_ci	return snprintf(buf, PAGE_SIZE, "%s\n", state);
3262306a36Sopenharmony_ci}
3362306a36Sopenharmony_ci
3462306a36Sopenharmony_cistatic ssize_t mlog_mask_store(u64 mask, const char *buf, size_t count)
3562306a36Sopenharmony_ci{
3662306a36Sopenharmony_ci	if (!strncasecmp(buf, "allow", 5)) {
3762306a36Sopenharmony_ci		__mlog_set_u64(mask, mlog_and_bits);
3862306a36Sopenharmony_ci		__mlog_clear_u64(mask, mlog_not_bits);
3962306a36Sopenharmony_ci	} else if (!strncasecmp(buf, "deny", 4)) {
4062306a36Sopenharmony_ci		__mlog_set_u64(mask, mlog_not_bits);
4162306a36Sopenharmony_ci		__mlog_clear_u64(mask, mlog_and_bits);
4262306a36Sopenharmony_ci	} else if (!strncasecmp(buf, "off", 3)) {
4362306a36Sopenharmony_ci		__mlog_clear_u64(mask, mlog_not_bits);
4462306a36Sopenharmony_ci		__mlog_clear_u64(mask, mlog_and_bits);
4562306a36Sopenharmony_ci	} else
4662306a36Sopenharmony_ci		return -EINVAL;
4762306a36Sopenharmony_ci
4862306a36Sopenharmony_ci	return count;
4962306a36Sopenharmony_ci}
5062306a36Sopenharmony_ci
5162306a36Sopenharmony_civoid __mlog_printk(const u64 *mask, const char *func, int line,
5262306a36Sopenharmony_ci		   const char *fmt, ...)
5362306a36Sopenharmony_ci{
5462306a36Sopenharmony_ci	struct va_format vaf;
5562306a36Sopenharmony_ci	va_list args;
5662306a36Sopenharmony_ci	const char *level;
5762306a36Sopenharmony_ci	const char *prefix = "";
5862306a36Sopenharmony_ci
5962306a36Sopenharmony_ci	if (!__mlog_test_u64(*mask, mlog_and_bits) ||
6062306a36Sopenharmony_ci	    __mlog_test_u64(*mask, mlog_not_bits))
6162306a36Sopenharmony_ci		return;
6262306a36Sopenharmony_ci
6362306a36Sopenharmony_ci	if (*mask & ML_ERROR) {
6462306a36Sopenharmony_ci		level = KERN_ERR;
6562306a36Sopenharmony_ci		prefix = "ERROR: ";
6662306a36Sopenharmony_ci	} else if (*mask & ML_NOTICE) {
6762306a36Sopenharmony_ci		level = KERN_NOTICE;
6862306a36Sopenharmony_ci	} else {
6962306a36Sopenharmony_ci		level = KERN_INFO;
7062306a36Sopenharmony_ci	}
7162306a36Sopenharmony_ci
7262306a36Sopenharmony_ci	va_start(args, fmt);
7362306a36Sopenharmony_ci
7462306a36Sopenharmony_ci	vaf.fmt = fmt;
7562306a36Sopenharmony_ci	vaf.va = &args;
7662306a36Sopenharmony_ci
7762306a36Sopenharmony_ci	printk("%s(%s,%u,%u):%s:%d %s%pV",
7862306a36Sopenharmony_ci	       level, current->comm, task_pid_nr(current),
7962306a36Sopenharmony_ci	       raw_smp_processor_id(), func, line, prefix, &vaf);
8062306a36Sopenharmony_ci
8162306a36Sopenharmony_ci	va_end(args);
8262306a36Sopenharmony_ci}
8362306a36Sopenharmony_ciEXPORT_SYMBOL_GPL(__mlog_printk);
8462306a36Sopenharmony_ci
8562306a36Sopenharmony_cistruct mlog_attribute {
8662306a36Sopenharmony_ci	struct attribute attr;
8762306a36Sopenharmony_ci	u64 mask;
8862306a36Sopenharmony_ci};
8962306a36Sopenharmony_ci
9062306a36Sopenharmony_ci#define to_mlog_attr(_attr) container_of(_attr, struct mlog_attribute, attr)
9162306a36Sopenharmony_ci
9262306a36Sopenharmony_ci#define define_mask(_name) {			\
9362306a36Sopenharmony_ci	.attr = {				\
9462306a36Sopenharmony_ci		.name = #_name,			\
9562306a36Sopenharmony_ci		.mode = S_IRUGO | S_IWUSR,	\
9662306a36Sopenharmony_ci	},					\
9762306a36Sopenharmony_ci	.mask = ML_##_name,			\
9862306a36Sopenharmony_ci}
9962306a36Sopenharmony_ci
10062306a36Sopenharmony_cistatic struct mlog_attribute mlog_attrs[MLOG_MAX_BITS] = {
10162306a36Sopenharmony_ci	define_mask(TCP),
10262306a36Sopenharmony_ci	define_mask(MSG),
10362306a36Sopenharmony_ci	define_mask(SOCKET),
10462306a36Sopenharmony_ci	define_mask(HEARTBEAT),
10562306a36Sopenharmony_ci	define_mask(HB_BIO),
10662306a36Sopenharmony_ci	define_mask(DLMFS),
10762306a36Sopenharmony_ci	define_mask(DLM),
10862306a36Sopenharmony_ci	define_mask(DLM_DOMAIN),
10962306a36Sopenharmony_ci	define_mask(DLM_THREAD),
11062306a36Sopenharmony_ci	define_mask(DLM_MASTER),
11162306a36Sopenharmony_ci	define_mask(DLM_RECOVERY),
11262306a36Sopenharmony_ci	define_mask(DLM_GLUE),
11362306a36Sopenharmony_ci	define_mask(VOTE),
11462306a36Sopenharmony_ci	define_mask(CONN),
11562306a36Sopenharmony_ci	define_mask(QUORUM),
11662306a36Sopenharmony_ci	define_mask(BASTS),
11762306a36Sopenharmony_ci	define_mask(CLUSTER),
11862306a36Sopenharmony_ci	define_mask(ERROR),
11962306a36Sopenharmony_ci	define_mask(NOTICE),
12062306a36Sopenharmony_ci	define_mask(KTHREAD),
12162306a36Sopenharmony_ci};
12262306a36Sopenharmony_ci
12362306a36Sopenharmony_cistatic struct attribute *mlog_default_attrs[MLOG_MAX_BITS] = {NULL, };
12462306a36Sopenharmony_ciATTRIBUTE_GROUPS(mlog_default);
12562306a36Sopenharmony_ci
12662306a36Sopenharmony_cistatic ssize_t mlog_show(struct kobject *obj, struct attribute *attr,
12762306a36Sopenharmony_ci			 char *buf)
12862306a36Sopenharmony_ci{
12962306a36Sopenharmony_ci	struct mlog_attribute *mlog_attr = to_mlog_attr(attr);
13062306a36Sopenharmony_ci
13162306a36Sopenharmony_ci	return mlog_mask_show(mlog_attr->mask, buf);
13262306a36Sopenharmony_ci}
13362306a36Sopenharmony_ci
13462306a36Sopenharmony_cistatic ssize_t mlog_store(struct kobject *obj, struct attribute *attr,
13562306a36Sopenharmony_ci			  const char *buf, size_t count)
13662306a36Sopenharmony_ci{
13762306a36Sopenharmony_ci	struct mlog_attribute *mlog_attr = to_mlog_attr(attr);
13862306a36Sopenharmony_ci
13962306a36Sopenharmony_ci	return mlog_mask_store(mlog_attr->mask, buf, count);
14062306a36Sopenharmony_ci}
14162306a36Sopenharmony_ci
14262306a36Sopenharmony_cistatic const struct sysfs_ops mlog_attr_ops = {
14362306a36Sopenharmony_ci	.show  = mlog_show,
14462306a36Sopenharmony_ci	.store = mlog_store,
14562306a36Sopenharmony_ci};
14662306a36Sopenharmony_ci
14762306a36Sopenharmony_cistatic struct kobj_type mlog_ktype = {
14862306a36Sopenharmony_ci	.default_groups = mlog_default_groups,
14962306a36Sopenharmony_ci	.sysfs_ops      = &mlog_attr_ops,
15062306a36Sopenharmony_ci};
15162306a36Sopenharmony_ci
15262306a36Sopenharmony_cistatic struct kset mlog_kset = {
15362306a36Sopenharmony_ci	.kobj   = {.ktype = &mlog_ktype},
15462306a36Sopenharmony_ci};
15562306a36Sopenharmony_ci
15662306a36Sopenharmony_ciint mlog_sys_init(struct kset *o2cb_kset)
15762306a36Sopenharmony_ci{
15862306a36Sopenharmony_ci	int i = 0;
15962306a36Sopenharmony_ci
16062306a36Sopenharmony_ci	while (mlog_attrs[i].attr.mode) {
16162306a36Sopenharmony_ci		mlog_default_attrs[i] = &mlog_attrs[i].attr;
16262306a36Sopenharmony_ci		i++;
16362306a36Sopenharmony_ci	}
16462306a36Sopenharmony_ci	mlog_default_attrs[i] = NULL;
16562306a36Sopenharmony_ci
16662306a36Sopenharmony_ci	kobject_set_name(&mlog_kset.kobj, "logmask");
16762306a36Sopenharmony_ci	mlog_kset.kobj.kset = o2cb_kset;
16862306a36Sopenharmony_ci	return kset_register(&mlog_kset);
16962306a36Sopenharmony_ci}
17062306a36Sopenharmony_ci
17162306a36Sopenharmony_civoid mlog_sys_shutdown(void)
17262306a36Sopenharmony_ci{
17362306a36Sopenharmony_ci	kset_unregister(&mlog_kset);
17462306a36Sopenharmony_ci}
175