public inbox for linux-kernel@vger.kernel.org
 help / color / mirror / Atom feed
* [PATCH] fs/proc: allow larger /proc/<pid>/cmdline output
@ 2015-04-10  3:59 Jarod Wilson
  2015-04-10  4:12 ` Andrew Morton
  0 siblings, 1 reply; 11+ messages in thread
From: Jarod Wilson @ 2015-04-10  3:59 UTC (permalink / raw)
  To: linux-kernel
  Cc: Jarod Wilson, Andrew Morton, Alexey Dobriyan, Eric W. Biederman,
	Al Viro, Miklos Szeredi, Zefan Li, Oleg Nesterov

There are people who run java. Sometimes, when it misbehaves, they try to
figure out what's going on by dumping /proc/<pid>/cmdline, but the length
of that output is currently capped by PAGE_SIZE (so x86_64's 4k, in most
cases), and sometimes, java command lines are longer than 4k characters.

This change allows the user to request a larger max length, up to 4x
PAGE_SIZE, but the default out-of-the-box setting should keep things the
same as they ever were. The 4x maximum is somewhat arbitrary, but seemed
like it should be more than enough, because really, if you have more than
16k characters on your command line, you're probably doing it wrong...

I've tested this lightly with non-java shell commands with really long
parameters, and things are perfectly stable after several hundred
iterations of exercising things on a system booted with both
proc_pid_maxlen=8192 and 16384. I wouldn't call my testing exhaustive,
and I may not have considered something that will blow up horribly here,
so comments and clues welcomed.

Using single_open_size() looked less messy than giving proc_pid_cmdline()
its own .start op that would allow multiple buffers.

Note: I've only added this extended sizing for /proc/<pid>/cmdline output,
rather than for all /proc/<pid>/foo elements, thinking that nothing else
should ever really be that long, but anything that is can simply switch
from using the ONE() macro to the ONE_SIZE() macro.

CC: Andrew Morton <akpm@linux-foundation.org>
CC: Alexey Dobriyan <adobriyan@gmail.com>
CC: "Eric W. Biederman" <ebiederm@xmission.com>
CC: Al Viro <viro@zeniv.linux.org.uk>
CC: Miklos Szeredi <miklos@szeredi.hu>
CC: Zefan Li <lizefan@huawei.com>
CC: Oleg Nesterov <oleg@redhat.com>
Signed-off-by: Jarod Wilson <jarod@redhat.com>
---
 fs/proc/base.c | 42 +++++++++++++++++++++++++++++++++++++++---
 1 file changed, 39 insertions(+), 3 deletions(-)

diff --git a/fs/proc/base.c b/fs/proc/base.c
index 3f3d7ae..bb466c1 100644
--- a/fs/proc/base.c
+++ b/fs/proc/base.c
@@ -134,6 +134,30 @@ struct pid_entry {
 	NOD(NAME, (S_IFREG|(MODE)), 			\
 		NULL, &proc_single_file_operations,	\
 		{ .proc_show = show } )
+#define ONE_SIZE(NAME, MODE, show)				\
+	NOD(NAME, (S_IFREG|(MODE)), 				\
+		NULL, &proc_single_file_size_operations,	\
+		{ .proc_show = show } )
+
+/*
+ * Its hideous, but some java gunk winds up with a cmdline that is longer
+ * than PAGE_SIZE, and some people want to be able to see all of it for
+ * debugging purposes. Allocate at least PAGE_SIZE, and allow the user to
+ * ask for up to PAGE_SIZE << 2 (4x) to help with that situation.
+ */
+static unsigned long proc_pid_maxlen = PAGE_SIZE;
+static int set_proc_pid_maxlen(char *str)
+{
+	if (!str)
+		return 0;
+
+	proc_pid_maxlen = simple_strtoul(str, &str, 0);
+	proc_pid_maxlen = max(PAGE_SIZE, proc_pid_maxlen);
+	proc_pid_maxlen = min(PAGE_SIZE << 2, proc_pid_maxlen);
+
+	return 1;
+}
+__setup("proc_pid_maxlen=", set_proc_pid_maxlen);
 
 /*
  * Count the number of hardlinks for the pid_entry table, excluding the .
@@ -204,7 +228,7 @@ static int proc_pid_cmdline(struct seq_file *m, struct pid_namespace *ns,
 	 * per internal buffer allocation. See single_open(), traverse().
 	 */
 	BUG_ON(m->size < PAGE_SIZE);
-	m->count += get_cmdline(task, m->buf, PAGE_SIZE);
+	m->count += get_cmdline(task, m->buf, proc_pid_maxlen);
 	return 0;
 }
 
@@ -601,6 +625,18 @@ static const struct file_operations proc_single_file_operations = {
 	.release	= single_release,
 };
 
+static int proc_single_open_size(struct inode *inode, struct file *filp)
+{
+	return single_open_size(filp, proc_single_show, inode, proc_pid_maxlen);
+}
+
+static const struct file_operations proc_single_file_size_operations = {
+	.open		= proc_single_open_size,
+	.read		= seq_read,
+	.llseek		= seq_lseek,
+	.release	= single_release,
+};
+
 
 struct mm_struct *proc_mem_open(struct inode *inode, unsigned int mode)
 {
@@ -2560,7 +2596,7 @@ static const struct pid_entry tgid_base_stuff[] = {
 #ifdef CONFIG_HAVE_ARCH_TRACEHOOK
 	ONE("syscall",    S_IRUSR, proc_pid_syscall),
 #endif
-	ONE("cmdline",    S_IRUGO, proc_pid_cmdline),
+	ONE_SIZE("cmdline", S_IRUGO, proc_pid_cmdline),
 	ONE("stat",       S_IRUGO, proc_tgid_stat),
 	ONE("statm",      S_IRUGO, proc_pid_statm),
 	REG("maps",       S_IRUGO, proc_pid_maps_operations),
@@ -2906,7 +2942,7 @@ static const struct pid_entry tid_base_stuff[] = {
 #ifdef CONFIG_HAVE_ARCH_TRACEHOOK
 	ONE("syscall",   S_IRUSR, proc_pid_syscall),
 #endif
-	ONE("cmdline",   S_IRUGO, proc_pid_cmdline),
+	ONE_SIZE("cmdline", S_IRUGO, proc_pid_cmdline),
 	ONE("stat",      S_IRUGO, proc_tid_stat),
 	ONE("statm",     S_IRUGO, proc_pid_statm),
 	REG("maps",      S_IRUGO, proc_tid_maps_operations),
-- 
1.8.3.1


^ permalink raw reply related	[flat|nested] 11+ messages in thread

end of thread, other threads:[~2015-04-13 20:23 UTC | newest]

Thread overview: 11+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2015-04-10  3:59 [PATCH] fs/proc: allow larger /proc/<pid>/cmdline output Jarod Wilson
2015-04-10  4:12 ` Andrew Morton
2015-04-10 12:18   ` Jarod Wilson
2015-04-10 14:11     ` Alexey Dobriyan
2015-04-10 14:13       ` [PATCH try #3] proc: fix PAGE_SIZE limit of /proc/$PID/cmdline Alexey Dobriyan
2015-04-10 18:01         ` Jarod Wilson
2015-04-10 22:09           ` Alexey Dobriyan
2015-04-13 18:28             ` Jarod Wilson
2015-04-13 20:23               ` Andrew Morton
2015-04-10 20:45       ` [PATCH] fs/proc: allow larger /proc/<pid>/cmdline output Andrew Morton
2015-04-13 18:24         ` Jarod Wilson

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox