1 /* Copyright (C) 2010-2016 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/stat.h> 35 #include <linux/stddef.h> 36 #include <linux/types.h> 37 #include <linux/uaccess.h> 38 #include <linux/wait.h> 39 #include <stdarg.h> 40 41 #define BATADV_LOG_BUFF_MASK (batadv_log_buff_len - 1) 42 43 static const int batadv_log_buff_len = BATADV_LOG_BUF_LEN; 44 45 static char *batadv_log_char_addr(struct batadv_priv_debug_log *debug_log, 46 size_t idx) 47 { 48 return &debug_log->log_buff[idx & BATADV_LOG_BUFF_MASK]; 49 } 50 51 static void batadv_emit_log_char(struct batadv_priv_debug_log *debug_log, 52 char c) 53 { 54 char *char_addr; 55 56 char_addr = batadv_log_char_addr(debug_log, debug_log->log_end); 57 *char_addr = c; 58 debug_log->log_end++; 59 60 if (debug_log->log_end - debug_log->log_start > batadv_log_buff_len) 61 debug_log->log_start = debug_log->log_end - batadv_log_buff_len; 62 } 63 64 __printf(2, 3) 65 static int batadv_fdebug_log(struct batadv_priv_debug_log *debug_log, 66 const char *fmt, ...) 67 { 68 va_list args; 69 static char debug_log_buf[256]; 70 char *p; 71 72 if (!debug_log) 73 return 0; 74 75 spin_lock_bh(&debug_log->lock); 76 va_start(args, fmt); 77 vscnprintf(debug_log_buf, sizeof(debug_log_buf), fmt, args); 78 va_end(args); 79 80 for (p = debug_log_buf; *p != 0; p++) 81 batadv_emit_log_char(debug_log, *p); 82 83 spin_unlock_bh(&debug_log->lock); 84 85 wake_up(&debug_log->queue_wait); 86 87 return 0; 88 } 89 90 int batadv_debug_log(struct batadv_priv *bat_priv, const char *fmt, ...) 91 { 92 va_list args; 93 char tmp_log_buf[256]; 94 95 va_start(args, fmt); 96 vscnprintf(tmp_log_buf, sizeof(tmp_log_buf), fmt, args); 97 batadv_fdebug_log(bat_priv->debug_log, "[%10u] %s", 98 jiffies_to_msecs(jiffies), tmp_log_buf); 99 va_end(args); 100 101 return 0; 102 } 103 104 static int batadv_log_open(struct inode *inode, struct file *file) 105 { 106 if (!try_module_get(THIS_MODULE)) 107 return -EBUSY; 108 109 nonseekable_open(inode, file); 110 file->private_data = inode->i_private; 111 return 0; 112 } 113 114 static int batadv_log_release(struct inode *inode, struct file *file) 115 { 116 module_put(THIS_MODULE); 117 return 0; 118 } 119 120 static bool batadv_log_empty(struct batadv_priv_debug_log *debug_log) 121 { 122 return !(debug_log->log_start - debug_log->log_end); 123 } 124 125 static ssize_t batadv_log_read(struct file *file, char __user *buf, 126 size_t count, loff_t *ppos) 127 { 128 struct batadv_priv *bat_priv = file->private_data; 129 struct batadv_priv_debug_log *debug_log = bat_priv->debug_log; 130 int error, i = 0; 131 char *char_addr; 132 char c; 133 134 if ((file->f_flags & O_NONBLOCK) && batadv_log_empty(debug_log)) 135 return -EAGAIN; 136 137 if (!buf) 138 return -EINVAL; 139 140 if (count == 0) 141 return 0; 142 143 if (!access_ok(VERIFY_WRITE, buf, count)) 144 return -EFAULT; 145 146 error = wait_event_interruptible(debug_log->queue_wait, 147 (!batadv_log_empty(debug_log))); 148 149 if (error) 150 return error; 151 152 spin_lock_bh(&debug_log->lock); 153 154 while ((!error) && (i < count) && 155 (debug_log->log_start != debug_log->log_end)) { 156 char_addr = batadv_log_char_addr(debug_log, 157 debug_log->log_start); 158 c = *char_addr; 159 160 debug_log->log_start++; 161 162 spin_unlock_bh(&debug_log->lock); 163 164 error = __put_user(c, buf); 165 166 spin_lock_bh(&debug_log->lock); 167 168 buf++; 169 i++; 170 } 171 172 spin_unlock_bh(&debug_log->lock); 173 174 if (!error) 175 return i; 176 177 return error; 178 } 179 180 static unsigned int batadv_log_poll(struct file *file, poll_table *wait) 181 { 182 struct batadv_priv *bat_priv = file->private_data; 183 struct batadv_priv_debug_log *debug_log = bat_priv->debug_log; 184 185 poll_wait(file, &debug_log->queue_wait, wait); 186 187 if (!batadv_log_empty(debug_log)) 188 return POLLIN | POLLRDNORM; 189 190 return 0; 191 } 192 193 static const struct file_operations batadv_log_fops = { 194 .open = batadv_log_open, 195 .release = batadv_log_release, 196 .read = batadv_log_read, 197 .poll = batadv_log_poll, 198 .llseek = no_llseek, 199 }; 200 201 int batadv_debug_log_setup(struct batadv_priv *bat_priv) 202 { 203 struct dentry *d; 204 205 if (!bat_priv->debug_dir) 206 goto err; 207 208 bat_priv->debug_log = kzalloc(sizeof(*bat_priv->debug_log), GFP_ATOMIC); 209 if (!bat_priv->debug_log) 210 goto err; 211 212 spin_lock_init(&bat_priv->debug_log->lock); 213 init_waitqueue_head(&bat_priv->debug_log->queue_wait); 214 215 d = debugfs_create_file("log", S_IFREG | S_IRUSR, 216 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