/* SPDX-License-Identifier: GPL-2.0-or-later */ /* * Copyright (C) 2005 Oracle. All rights reserved. */ #ifndef O2CLUSTER_MASKLOG_H #define O2CLUSTER_MASKLOG_H /* * For now this is a trivial wrapper around printk() that gives the critical * ability to enable sets of debugging output at run-time. In the future this * will almost certainly be redirected to relayfs so that it can pay a * substantially lower heisenberg tax. * * Callers associate the message with a bitmask and a global bitmask is * maintained with help from /proc. If any of the bits match the message is * output. * * We must have efficient bit tests on i386 and it seems gcc still emits crazy * code for the 64bit compare. It emits very good code for the dual unsigned * long tests, though, completely avoiding tests that can never pass if the * caller gives a constant bitmask that fills one of the longs with all 0s. So * the desire is to have almost all of the calls decided on by comparing just * one of the longs. This leads to having infrequently given bits that are * frequently matched in the high bits. * * _ERROR and _NOTICE are used for messages that always go to the console and * have appropriate KERN_ prefixes. We wrap these in our function instead of * just calling printk() so that this can eventually make its way through * relayfs along with the debugging messages. Everything else gets KERN_DEBUG. * The inline tests and macro dance give GCC the opportunity to quite cleverly * only emit the appropriage printk() when the caller passes in a constant * mask, as is almost always the case. * * All this bitmask nonsense is managed from the files under * /sys/fs/o2cb/logmask/. Reading the files gives a straightforward * indication of which bits are allowed (allow) or denied (off/deny). * ENTRY deny * EXIT deny * TCP off * MSG off * SOCKET off * ERROR allow * NOTICE allow * * Writing changes the state of a given bit and requires a strictly formatted * single write() call: * * write(fd, "allow", 5); * * Echoing allow/deny/off string into the logmask files can flip the bits * on or off as expected; here is the bash script for example: * * log_mask="/sys/fs/o2cb/log_mask" * for node in ENTRY EXIT TCP MSG SOCKET ERROR NOTICE; do * echo allow >"$log_mask"/"$node" * done * * The debugfs.ocfs2 tool can also flip the bits with the -l option: * * debugfs.ocfs2 -l TCP allow */ /* for task_struct */ #include <linux/sched.h> /* bits that are frequently given and infrequently matched in the low word */ /* NOTE: If you add a flag, you need to also update masklog.c! */ #define ML_TCP … #define ML_MSG … #define ML_SOCKET … #define ML_HEARTBEAT … #define ML_HB_BIO … #define ML_DLMFS … #define ML_DLM … #define ML_DLM_DOMAIN … #define ML_DLM_THREAD … #define ML_DLM_MASTER … #define ML_DLM_RECOVERY … #define ML_DLM_GLUE … #define ML_VOTE … #define ML_CONN … #define ML_QUORUM … #define ML_BASTS … #define ML_CLUSTER … /* bits that are infrequently given and frequently matched in the high word */ #define ML_ERROR … #define ML_NOTICE … #define ML_KTHREAD … #define MLOG_INITIAL_AND_MASK … #ifndef MLOG_MASK_PREFIX #define MLOG_MASK_PREFIX … #endif /* * When logging is disabled, force the bit test to 0 for anything other * than errors and notices, allowing gcc to remove the code completely. * When enabled, allow all masks. */ #if defined(CONFIG_OCFS2_DEBUG_MASKLOG) #define ML_ALLOWED_BITS … #else #define ML_ALLOWED_BITS … #endif #define MLOG_MAX_BITS … struct mlog_bits { … }; extern struct mlog_bits mlog_and_bits, mlog_not_bits; #if BITS_PER_LONG == 32 #define __mlog_test_u64 … #define __mlog_set_u64 … #define __mlog_clear_u64 … #define MLOG_BITS_RHS … #else /* 32bit long above, 64bit long below */ #define __mlog_test_u64(mask, bits) … #define __mlog_set_u64(mask, bits) … #define __mlog_clear_u64(mask, bits) … #define MLOG_BITS_RHS(mask) … #endif __printf(4, 5) void __mlog_printk(const u64 *m, const char *func, int line, const char *fmt, ...); /* * Testing before the __mlog_printk call lets the compiler eliminate the * call completely when (m & ML_ALLOWED_BITS) is 0. */ #define mlog(mask, fmt, ...) … #define mlog_ratelimited(mask, fmt, ...) … #define mlog_errno(st) … #define mlog_bug_on_msg(cond, fmt, args...) … #include <linux/kobject.h> #include <linux/sysfs.h> int mlog_sys_init(struct kset *o2cb_subsys); void mlog_sys_shutdown(void); #endif /* O2CLUSTER_MASKLOG_H */