152fd3d6fSZach Brown /* -*- mode: c; c-basic-offset: 8; -*- 252fd3d6fSZach Brown * vim: noexpandtab sw=8 ts=8 sts=0: 352fd3d6fSZach Brown * 452fd3d6fSZach Brown * Copyright (C) 2004, 2005 Oracle. All rights reserved. 552fd3d6fSZach Brown * 652fd3d6fSZach Brown * This program is free software; you can redistribute it and/or 752fd3d6fSZach Brown * modify it under the terms of the GNU General Public 852fd3d6fSZach Brown * License as published by the Free Software Foundation; either 952fd3d6fSZach Brown * version 2 of the License, or (at your option) any later version. 1052fd3d6fSZach Brown * 1152fd3d6fSZach Brown * This program is distributed in the hope that it will be useful, 1252fd3d6fSZach Brown * but WITHOUT ANY WARRANTY; without even the implied warranty of 1352fd3d6fSZach Brown * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 1452fd3d6fSZach Brown * General Public License for more details. 1552fd3d6fSZach Brown * 1652fd3d6fSZach Brown * You should have received a copy of the GNU General Public 1752fd3d6fSZach Brown * License along with this program; if not, write to the 1852fd3d6fSZach Brown * Free Software Foundation, Inc., 59 Temple Place - Suite 330, 1952fd3d6fSZach Brown * Boston, MA 021110-1307, USA. 2052fd3d6fSZach Brown */ 2152fd3d6fSZach Brown 2252fd3d6fSZach Brown #include <linux/module.h> 2352fd3d6fSZach Brown #include <linux/kernel.h> 2452fd3d6fSZach Brown #include <linux/proc_fs.h> 2552fd3d6fSZach Brown #include <linux/seq_file.h> 2652fd3d6fSZach Brown #include <linux/string.h> 2752fd3d6fSZach Brown #include <asm/uaccess.h> 2852fd3d6fSZach Brown 2952fd3d6fSZach Brown #include "masklog.h" 3052fd3d6fSZach Brown 3152fd3d6fSZach Brown struct mlog_bits mlog_and_bits = MLOG_BITS_RHS(MLOG_INITIAL_AND_MASK); 3252fd3d6fSZach Brown EXPORT_SYMBOL_GPL(mlog_and_bits); 33c1e8d35eSTao Ma struct mlog_bits mlog_not_bits = MLOG_BITS_RHS(0); 3452fd3d6fSZach Brown EXPORT_SYMBOL_GPL(mlog_not_bits); 3552fd3d6fSZach Brown 3652fd3d6fSZach Brown static ssize_t mlog_mask_show(u64 mask, char *buf) 3752fd3d6fSZach Brown { 3852fd3d6fSZach Brown char *state; 3952fd3d6fSZach Brown 4052fd3d6fSZach Brown if (__mlog_test_u64(mask, mlog_and_bits)) 4152fd3d6fSZach Brown state = "allow"; 4252fd3d6fSZach Brown else if (__mlog_test_u64(mask, mlog_not_bits)) 4352fd3d6fSZach Brown state = "deny"; 4452fd3d6fSZach Brown else 4552fd3d6fSZach Brown state = "off"; 4652fd3d6fSZach Brown 4752fd3d6fSZach Brown return snprintf(buf, PAGE_SIZE, "%s\n", state); 4852fd3d6fSZach Brown } 4952fd3d6fSZach Brown 5052fd3d6fSZach Brown static ssize_t mlog_mask_store(u64 mask, const char *buf, size_t count) 5152fd3d6fSZach Brown { 522bd63329SRasmus Villemoes if (!strncasecmp(buf, "allow", 5)) { 5352fd3d6fSZach Brown __mlog_set_u64(mask, mlog_and_bits); 5452fd3d6fSZach Brown __mlog_clear_u64(mask, mlog_not_bits); 552bd63329SRasmus Villemoes } else if (!strncasecmp(buf, "deny", 4)) { 5652fd3d6fSZach Brown __mlog_set_u64(mask, mlog_not_bits); 5752fd3d6fSZach Brown __mlog_clear_u64(mask, mlog_and_bits); 582bd63329SRasmus Villemoes } else if (!strncasecmp(buf, "off", 3)) { 5952fd3d6fSZach Brown __mlog_clear_u64(mask, mlog_not_bits); 6052fd3d6fSZach Brown __mlog_clear_u64(mask, mlog_and_bits); 6152fd3d6fSZach Brown } else 6252fd3d6fSZach Brown return -EINVAL; 6352fd3d6fSZach Brown 6452fd3d6fSZach Brown return count; 6552fd3d6fSZach Brown } 6652fd3d6fSZach Brown 67*7c2bd2f9SJoe Perches /* 68*7c2bd2f9SJoe Perches * smp_processor_id() "helpfully" screams when called outside preemptible 69*7c2bd2f9SJoe Perches * regions in current kernels. sles doesn't have the variants that don't 70*7c2bd2f9SJoe Perches * scream. just do this instead of trying to guess which we're building 71*7c2bd2f9SJoe Perches * against.. *sigh*. 72*7c2bd2f9SJoe Perches */ 73*7c2bd2f9SJoe Perches #define __mlog_cpu_guess \ 74*7c2bd2f9SJoe Perches ({ \ 75*7c2bd2f9SJoe Perches unsigned long _cpu = get_cpu(); \ 76*7c2bd2f9SJoe Perches put_cpu(); \ 77*7c2bd2f9SJoe Perches _cpu; \ 78*7c2bd2f9SJoe Perches }) 79*7c2bd2f9SJoe Perches 80*7c2bd2f9SJoe Perches void __mlog_printk(const u64 *mask, const char *func, int line, 81*7c2bd2f9SJoe Perches const char *fmt, ...) 82*7c2bd2f9SJoe Perches { 83*7c2bd2f9SJoe Perches struct va_format vaf; 84*7c2bd2f9SJoe Perches va_list args; 85*7c2bd2f9SJoe Perches const char *level; 86*7c2bd2f9SJoe Perches const char *prefix = ""; 87*7c2bd2f9SJoe Perches 88*7c2bd2f9SJoe Perches if (!__mlog_test_u64(*mask, mlog_and_bits) || 89*7c2bd2f9SJoe Perches __mlog_test_u64(*mask, mlog_not_bits)) 90*7c2bd2f9SJoe Perches return; 91*7c2bd2f9SJoe Perches 92*7c2bd2f9SJoe Perches if (*mask & ML_ERROR) { 93*7c2bd2f9SJoe Perches level = KERN_ERR; 94*7c2bd2f9SJoe Perches prefix = "ERROR: "; 95*7c2bd2f9SJoe Perches } else if (*mask & ML_NOTICE) { 96*7c2bd2f9SJoe Perches level = KERN_NOTICE; 97*7c2bd2f9SJoe Perches } else { 98*7c2bd2f9SJoe Perches level = KERN_INFO; 99*7c2bd2f9SJoe Perches } 100*7c2bd2f9SJoe Perches 101*7c2bd2f9SJoe Perches va_start(args, fmt); 102*7c2bd2f9SJoe Perches 103*7c2bd2f9SJoe Perches vaf.fmt = fmt; 104*7c2bd2f9SJoe Perches vaf.va = &args; 105*7c2bd2f9SJoe Perches 106*7c2bd2f9SJoe Perches printk("%s(%s,%u,%lu):%s:%d %s%pV", 107*7c2bd2f9SJoe Perches level, current->comm, task_pid_nr(current), __mlog_cpu_guess, 108*7c2bd2f9SJoe Perches func, line, prefix, &vaf); 109*7c2bd2f9SJoe Perches 110*7c2bd2f9SJoe Perches va_end(args); 111*7c2bd2f9SJoe Perches } 112*7c2bd2f9SJoe Perches EXPORT_SYMBOL_GPL(__mlog_printk); 113*7c2bd2f9SJoe Perches 11452fd3d6fSZach Brown struct mlog_attribute { 11552fd3d6fSZach Brown struct attribute attr; 11652fd3d6fSZach Brown u64 mask; 11752fd3d6fSZach Brown }; 11852fd3d6fSZach Brown 11952fd3d6fSZach Brown #define to_mlog_attr(_attr) container_of(_attr, struct mlog_attribute, attr) 12052fd3d6fSZach Brown 12152fd3d6fSZach Brown #define define_mask(_name) { \ 12252fd3d6fSZach Brown .attr = { \ 12352fd3d6fSZach Brown .name = #_name, \ 12452fd3d6fSZach Brown .mode = S_IRUGO | S_IWUSR, \ 12552fd3d6fSZach Brown }, \ 12652fd3d6fSZach Brown .mask = ML_##_name, \ 12752fd3d6fSZach Brown } 12852fd3d6fSZach Brown 12952fd3d6fSZach Brown static struct mlog_attribute mlog_attrs[MLOG_MAX_BITS] = { 13052fd3d6fSZach Brown define_mask(TCP), 13152fd3d6fSZach Brown define_mask(MSG), 13252fd3d6fSZach Brown define_mask(SOCKET), 13352fd3d6fSZach Brown define_mask(HEARTBEAT), 13452fd3d6fSZach Brown define_mask(HB_BIO), 13552fd3d6fSZach Brown define_mask(DLMFS), 13652fd3d6fSZach Brown define_mask(DLM), 13752fd3d6fSZach Brown define_mask(DLM_DOMAIN), 13852fd3d6fSZach Brown define_mask(DLM_THREAD), 13952fd3d6fSZach Brown define_mask(DLM_MASTER), 14052fd3d6fSZach Brown define_mask(DLM_RECOVERY), 14152fd3d6fSZach Brown define_mask(DLM_GLUE), 14252fd3d6fSZach Brown define_mask(VOTE), 14352fd3d6fSZach Brown define_mask(CONN), 14452fd3d6fSZach Brown define_mask(QUORUM), 1459b915181SSunil Mushran define_mask(BASTS), 14641b41a26SSunil Mushran define_mask(CLUSTER), 14752fd3d6fSZach Brown define_mask(ERROR), 14852fd3d6fSZach Brown define_mask(NOTICE), 14952fd3d6fSZach Brown define_mask(KTHREAD), 15052fd3d6fSZach Brown }; 15152fd3d6fSZach Brown 15252fd3d6fSZach Brown static struct attribute *mlog_attr_ptrs[MLOG_MAX_BITS] = {NULL, }; 15352fd3d6fSZach Brown 15452fd3d6fSZach Brown static ssize_t mlog_show(struct kobject *obj, struct attribute *attr, 15552fd3d6fSZach Brown char *buf) 15652fd3d6fSZach Brown { 15752fd3d6fSZach Brown struct mlog_attribute *mlog_attr = to_mlog_attr(attr); 15852fd3d6fSZach Brown 15952fd3d6fSZach Brown return mlog_mask_show(mlog_attr->mask, buf); 16052fd3d6fSZach Brown } 16152fd3d6fSZach Brown 16252fd3d6fSZach Brown static ssize_t mlog_store(struct kobject *obj, struct attribute *attr, 16352fd3d6fSZach Brown const char *buf, size_t count) 16452fd3d6fSZach Brown { 16552fd3d6fSZach Brown struct mlog_attribute *mlog_attr = to_mlog_attr(attr); 16652fd3d6fSZach Brown 16752fd3d6fSZach Brown return mlog_mask_store(mlog_attr->mask, buf, count); 16852fd3d6fSZach Brown } 16952fd3d6fSZach Brown 17052cf25d0SEmese Revfy static const struct sysfs_ops mlog_attr_ops = { 17152fd3d6fSZach Brown .show = mlog_show, 17252fd3d6fSZach Brown .store = mlog_store, 17352fd3d6fSZach Brown }; 17452fd3d6fSZach Brown 17552fd3d6fSZach Brown static struct kobj_type mlog_ktype = { 17652fd3d6fSZach Brown .default_attrs = mlog_attr_ptrs, 17752fd3d6fSZach Brown .sysfs_ops = &mlog_attr_ops, 17852fd3d6fSZach Brown }; 17952fd3d6fSZach Brown 18052fd3d6fSZach Brown static struct kset mlog_kset = { 18134980ca8SGreg Kroah-Hartman .kobj = {.ktype = &mlog_ktype}, 18252fd3d6fSZach Brown }; 18352fd3d6fSZach Brown 184c60b7178SGreg Kroah-Hartman int mlog_sys_init(struct kset *o2cb_kset) 18552fd3d6fSZach Brown { 18652fd3d6fSZach Brown int i = 0; 18752fd3d6fSZach Brown 18852fd3d6fSZach Brown while (mlog_attrs[i].attr.mode) { 18952fd3d6fSZach Brown mlog_attr_ptrs[i] = &mlog_attrs[i].attr; 19052fd3d6fSZach Brown i++; 19152fd3d6fSZach Brown } 19252fd3d6fSZach Brown mlog_attr_ptrs[i] = NULL; 19352fd3d6fSZach Brown 19434980ca8SGreg Kroah-Hartman kobject_set_name(&mlog_kset.kobj, "logmask"); 195c60b7178SGreg Kroah-Hartman mlog_kset.kobj.kset = o2cb_kset; 19652fd3d6fSZach Brown return kset_register(&mlog_kset); 19752fd3d6fSZach Brown } 19852fd3d6fSZach Brown 19952fd3d6fSZach Brown void mlog_sys_shutdown(void) 20052fd3d6fSZach Brown { 20152fd3d6fSZach Brown kset_unregister(&mlog_kset); 20252fd3d6fSZach Brown } 203