From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1754314AbbJ0Kac (ORCPT ); Tue, 27 Oct 2015 06:30:32 -0400 Received: from mailout3.w1.samsung.com ([210.118.77.13]:37497 "EHLO mailout3.w1.samsung.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1754104AbbJ0K3L (ORCPT ); Tue, 27 Oct 2015 06:29:11 -0400 X-AuditID: cbfec7f4-f79c56d0000012ee-ee-562f51eec868 From: Paul Osmialowski To: Jonathan Corbet , Arnd Bergmann , Andrew Morton , Petr Mladek , Greg Kroah-Hartman , Daniel Mack , Kay Sievers , Joe Perches , Tejun Heo , linux-kernel@vger.kernel.org, linux-doc@vger.kernel.org, linux-api@vger.kernel.org Cc: Richard Weinberger , Marcin Niesluchowski , Karol Lewandowski , Paul Osmialowski , Bartlomiej Zolnierkiewicz , Shuah Khan , Andy Lutomirski Subject: [RFC v5 7/8] kmsg: add ioctl for kmsg* devices operating on buffers Date: Tue, 27 Oct 2015 11:28:42 +0100 Message-id: <1445941723-20388-8-git-send-email-p.osmialowsk@samsung.com> X-Mailer: git-send-email 1.9.1 In-reply-to: <1445941723-20388-1-git-send-email-p.osmialowsk@samsung.com> References: <1445941723-20388-1-git-send-email-p.osmialowsk@samsung.com> X-Brightmail-Tracker: H4sIAAAAAAAAA+NgFvrDLMWRmVeSWpSXmKPExsVy+t/xy7rvAvXDDJoPWFjMWb+GzeLvpGPs FhtnrGe1eHKgndGi6e8rFovmxevZLGbff8xi0fhpLrPF5Q3n2Cw2f+9gs1jYtoTF4vKuOWwW q9c2sFocOvuDxWLCmwPMFgv/b2ay+DBxA5vF1C8fWCx+LT/K6CDscf/NXxaP378mMXrsnHWX 3WPTqk42jxMzfrN47J+7ht1jcd9kVo8t/UCJL6uuMXv0bVnF6HFmwRF2j8+b5Dw+rvf02L57 OUsAXxSXTUpqTmZZapG+XQJXxr7DXxkL1qtU3L8T0cB4V7aLkYNDQsBE4uPrrC5GTiBTTOLC vfVsXYxcHEICSxklPrzaxgzhNDJJrPpxnRmkik3AUOLm/8OMIAkRgbnMEs2/FrCCOMwC55gk Vu/aywRSJSzgI/Hw0DZWEJtFQFXiycVLYN28Ah4SD/e9Y4TYJydx8thksBpOAU+Jpom3WEBs IaCape37WScw8i5gZFjFKJpamlxQnJSea6hXnJhbXJqXrpecn7uJERInX3YwLj5mdYhRgINR iYfXoEIvTIg1say4MvcQowQHs5IIr6COfpgQb0piZVVqUX58UWlOavEhRmkOFiVx3rm73ocI CaQnlqRmp6YWpBbBZJk4OKUaGPmsmdo37f8wQWlDyyfVwydWFD+vVXdxWXni34XpjAZPP12z nnZ2zyaDDs4dIjUmC9qVmblDvesnCqdelNUMLjy5xH7Lme5Z8VbMVpk+PdeXiyu2829Pb0g8 Yf5dhKUhKuymZ2uUuf+jLe0CdlJvc+Pmn+7ccb3u45m3a00VynfVczPNeMDpo8RSnJFoqMVc VJwIAO495emPAgAA Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org From: Marcin Niesluchowski There is no possibility to clear additional kmsg buffers, get size of them or know what size should be passed to read file operation (too small size causes it to retrun -EINVAL). Add following ioctls which solve those issues: * KMSG_CMD_GET_BUF_SIZE * KMSG_CMD_GET_READ_SIZE_MAX * KMSG_CMD_CLEAR Signed-off-by: Marcin Niesluchowski Signed-off-by: Paul Osmialowski --- Documentation/ioctl/ioctl-number.txt | 2 +- include/uapi/linux/kmsg_ioctl.h | 15 ++++++++++ kernel/printk/kmsg.c | 57 ++++++++++++++++++++++++++++++++++-- 3 files changed, 71 insertions(+), 3 deletions(-) diff --git a/Documentation/ioctl/ioctl-number.txt b/Documentation/ioctl/ioctl-number.txt index 76dec8b..d36bb04 100644 --- a/Documentation/ioctl/ioctl-number.txt +++ b/Documentation/ioctl/ioctl-number.txt @@ -319,7 +319,7 @@ Code Seq#(hex) Include File Comments 0xB1 00-1F PPPoX 0xB3 00 linux/mmc/ioctl.h -0xBB 00-02 uapi/linux/kmsg_ioctl.h +0xBB 00-83 uapi/linux/kmsg_ioctl.h 0xC0 00-0F linux/usb/iowarrior.h 0xCA 00-0F uapi/misc/cxl.h 0xCA 80-8F uapi/scsi/cxlflash_ioctl.h diff --git a/include/uapi/linux/kmsg_ioctl.h b/include/uapi/linux/kmsg_ioctl.h index 96e7930..bfd9cd3 100644 --- a/include/uapi/linux/kmsg_ioctl.h +++ b/include/uapi/linux/kmsg_ioctl.h @@ -27,4 +27,19 @@ struct kmsg_cmd_buffer_add { struct kmsg_cmd_buffer_add) #define KMSG_CMD_BUFFER_DEL _IOW(KMSG_IOCTL_MAGIC, 0x01, int) +/* + * A ioctl interface for kmsg* devices. + * + * KMSG_CMD_GET_BUF_SIZE: Retrieve cyclic log buffer size associated with + * device. + * KMSG_CMD_GET_READ_SIZE_MAX: Retrieve max size of data read by kmsg read + * operation. + * KMSG_CMD_CLEAR: Clears cyclic log buffer. After that operation + * there is no data to read from buffer unless + * logs are written. + */ +#define KMSG_CMD_GET_BUF_SIZE _IOR(KMSG_IOCTL_MAGIC, 0x80, __u32) +#define KMSG_CMD_GET_READ_SIZE_MAX _IOR(KMSG_IOCTL_MAGIC, 0x81, __u32) +#define KMSG_CMD_CLEAR _IO(KMSG_IOCTL_MAGIC, 0x82) + #endif diff --git a/kernel/printk/kmsg.c b/kernel/printk/kmsg.c index 62bb4d5..bcf0801 100644 --- a/kernel/printk/kmsg.c +++ b/kernel/printk/kmsg.c @@ -247,8 +247,9 @@ static loff_t kmsg_llseek(struct log_buffer *log_b, struct file *file, } /* * The first record after the last SYSLOG_ACTION_CLEAR, - * like issued by 'dmesg -c'. Reading /dev/kmsg itself - * changes no global state, and does not clear anything. + * like issued by 'dmesg -c' or KMSG_CMD_CLEAR ioctl + * command. Reading /dev/kmsg itself changes no global + * state, and does not clear anything. */ user->idx = log_b->clear_idx; user->seq = log_b->clear_seq; @@ -391,6 +392,56 @@ static int devkmsg_open(struct inode *inode, struct file *file) return ret; } +static long kmsg_ioctl(struct log_buffer *log_b, unsigned int cmd, + unsigned long arg) +{ + void __user *argp = (void __user *)arg; + static const u32 read_size_max = CONSOLE_EXT_LOG_MAX; + + switch (cmd) { + case KMSG_CMD_GET_BUF_SIZE: + if (copy_to_user(argp, &log_b->len, sizeof(u32))) + return -EFAULT; + break; + case KMSG_CMD_GET_READ_SIZE_MAX: + if (copy_to_user(argp, &read_size_max, sizeof(u32))) + return -EFAULT; + break; + case KMSG_CMD_CLEAR: + if (!capable(CAP_SYSLOG)) + return -EPERM; + raw_spin_lock_irq(&log_b->lock); + log_b->clear_seq = log_b->next_seq; + log_b->clear_idx = log_b->next_idx; + raw_spin_unlock_irq(&log_b->lock); + break; + default: + return -ENOTTY; + } + return 0; +} + +static long devkmsg_ioctl(struct file *file, unsigned int cmd, + unsigned long arg) +{ + long ret = -ENXIO; + int minor = iminor(file->f_inode); + struct log_buffer *log_b; + + if (minor == log_buf.minor) + return kmsg_ioctl(&log_buf, cmd, arg); + + rcu_read_lock(); + list_for_each_entry_rcu(log_b, &log_buf.list, list) { + if (log_b->minor == minor) { + ret = kmsg_ioctl(log_b, cmd, arg); + break; + } + } + rcu_read_unlock(); + return ret; +} + static int devkmsg_release(struct inode *inode, struct file *file) { struct devkmsg_user *user = file->private_data; @@ -409,6 +460,8 @@ const struct file_operations kmsg_fops = { .write_iter = devkmsg_write, .llseek = devkmsg_llseek, .poll = devkmsg_poll, + .unlocked_ioctl = devkmsg_ioctl, + .compat_ioctl = devkmsg_ioctl, .release = devkmsg_release, }; -- 1.9.1