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