1 // SPDX-License-Identifier: GPL-2.0 2 /* Copyright (C) 2010-2017 B.A.T.M.A.N. contributors: 3 * 4 * Marek Lindner 5 * 6 * This program is free software; you can redistribute it and/or 7 * modify it under the terms of version 2 of the GNU General Public 8 * License as published by the Free Software Foundation. 9 * 10 * This program is distributed in the hope that it will be useful, but 11 * WITHOUT ANY WARRANTY; without even the implied warranty of 12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 * General Public License for more details. 14 * 15 * You should have received a copy of the GNU General Public License 16 * along with this program; if not, see <http://www.gnu.org/licenses/>. 17 */ 18 19 #include "log.h" 20 #include "main.h" 21 22 #include <linux/compiler.h> 23 #include <linux/debugfs.h> 24 #include <linux/errno.h> 25 #include <linux/export.h> 26 #include <linux/fcntl.h> 27 #include <linux/fs.h> 28 #include <linux/gfp.h> 29 #include <linux/jiffies.h> 30 #include <linux/kernel.h> 31 #include <linux/module.h> 32 #include <linux/poll.h> 33 #include <linux/sched.h> /* for linux/wait.h */ 34 #include <linux/slab.h> 35 #include <linux/spinlock.h> 36 #include <linux/stddef.h> 37 #include <linux/types.h> 38 #include <linux/uaccess.h> 39 #include <linux/wait.h> 40 #include <stdarg.h> 41 42 #define BATADV_LOG_BUFF_MASK (batadv_log_buff_len - 1) 43 44 static const int batadv_log_buff_len = BATADV_LOG_BUF_LEN; 45 46 static char *batadv_log_char_addr(struct batadv_priv_debug_log *debug_log, 47 size_t idx) 48 { 49 return &debug_log->log_buff[idx & BATADV_LOG_BUFF_MASK]; 50 } 51 52 static void batadv_emit_log_char(struct batadv_priv_debug_log *debug_log, 53 char c) 54 { 55 char *char_addr; 56 57 char_addr = batadv_log_char_addr(debug_log, debug_log->log_end); 58 *char_addr = c; 59 debug_log->log_end++; 60 61 if (debug_log->log_end - debug_log->log_start > batadv_log_buff_len) 62 debug_log->log_start = debug_log->log_end - batadv_log_buff_len; 63 } 64 65 __printf(2, 3) 66 static int batadv_fdebug_log(struct batadv_priv_debug_log *debug_log, 67 const char *fmt, ...) 68 { 69 va_list args; 70 static char debug_log_buf[256]; 71 char *p; 72 73 if (!debug_log) 74 return 0; 75 76 spin_lock_bh(&debug_log->lock); 77 va_start(args, fmt); 78 vscnprintf(debug_log_buf, sizeof(debug_log_buf), fmt, args); 79 va_end(args); 80 81 for (p = debug_log_buf; *p != 0; p++) 82 batadv_emit_log_char(debug_log, *p); 83 84 spin_unlock_bh(&debug_log->lock); 85 86 wake_up(&debug_log->queue_wait); 87 88 return 0; 89 } 90 91 int batadv_debug_log(struct batadv_priv *bat_priv, const char *fmt, ...) 92 { 93 va_list args; 94 char tmp_log_buf[256]; 95 96 va_start(args, fmt); 97 vscnprintf(tmp_log_buf, sizeof(tmp_log_buf), fmt, args); 98 batadv_fdebug_log(bat_priv->debug_log, "[%10u] %s", 99 jiffies_to_msecs(jiffies), tmp_log_buf); 100 va_end(args); 101 102 return 0; 103 } 104 105 static int batadv_log_open(struct inode *inode, struct file *file) 106 { 107 if (!try_module_get(THIS_MODULE)) 108 return -EBUSY; 109 110 nonseekable_open(inode, file); 111 file->private_data = inode->i_private; 112 return 0; 113 } 114 115 static int batadv_log_release(struct inode *inode, struct file *file) 116 { 117 module_put(THIS_MODULE); 118 return 0; 119 } 120 121 static bool batadv_log_empty(struct batadv_priv_debug_log *debug_log) 122 { 123 return !(debug_log->log_start - debug_log->log_end); 124 } 125 126 static ssize_t batadv_log_read(struct file *file, char __user *buf, 127 size_t count, loff_t *ppos) 128 { 129 struct batadv_priv *bat_priv = file->private_data; 130 struct batadv_priv_debug_log *debug_log = bat_priv->debug_log; 131 int error, i = 0; 132 char *char_addr; 133 char c; 134 135 if ((file->f_flags & O_NONBLOCK) && batadv_log_empty(debug_log)) 136 return -EAGAIN; 137 138 if (!buf) 139 return -EINVAL; 140 141 if (count == 0) 142 return 0; 143 144 if (!access_ok(VERIFY_WRITE, buf, count)) 145 return -EFAULT; 146 147 error = wait_event_interruptible(debug_log->queue_wait, 148 (!batadv_log_empty(debug_log))); 149 150 if (error) 151 return error; 152 153 spin_lock_bh(&debug_log->lock); 154 155 while ((!error) && (i < count) && 156 (debug_log->log_start != debug_log->log_end)) { 157 char_addr = batadv_log_char_addr(debug_log, 158 debug_log->log_start); 159 c = *char_addr; 160 161 debug_log->log_start++; 162 163 spin_unlock_bh(&debug_log->lock); 164 165 error = __put_user(c, buf); 166 167 spin_lock_bh(&debug_log->lock); 168 169 buf++; 170 i++; 171 } 172 173 spin_unlock_bh(&debug_log->lock); 174 175 if (!error) 176 return i; 177 178 return error; 179 } 180 181 static unsigned int batadv_log_poll(struct file *file, poll_table *wait) 182 { 183 struct batadv_priv *bat_priv = file->private_data; 184 struct batadv_priv_debug_log *debug_log = bat_priv->debug_log; 185 186 poll_wait(file, &debug_log->queue_wait, wait); 187 188 if (!batadv_log_empty(debug_log)) 189 return POLLIN | POLLRDNORM; 190 191 return 0; 192 } 193 194 static const struct file_operations batadv_log_fops = { 195 .open = batadv_log_open, 196 .release = batadv_log_release, 197 .read = batadv_log_read, 198 .poll = batadv_log_poll, 199 .llseek = no_llseek, 200 }; 201 202 int batadv_debug_log_setup(struct batadv_priv *bat_priv) 203 { 204 struct dentry *d; 205 206 if (!bat_priv->debug_dir) 207 goto err; 208 209 bat_priv->debug_log = kzalloc(sizeof(*bat_priv->debug_log), GFP_ATOMIC); 210 if (!bat_priv->debug_log) 211 goto err; 212 213 spin_lock_init(&bat_priv->debug_log->lock); 214 init_waitqueue_head(&bat_priv->debug_log->queue_wait); 215 216 d = debugfs_create_file("log", 0400, bat_priv->debug_dir, bat_priv, 217 &batadv_log_fops); 218 if (!d) 219 goto err; 220 221 return 0; 222 223 err: 224 return -ENOMEM; 225 } 226 227 void batadv_debug_log_cleanup(struct batadv_priv *bat_priv) 228 { 229 kfree(bat_priv->debug_log); 230 bat_priv->debug_log = NULL; 231 } 232