lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  PHC 
Open Source and information security mailing list archives
 
Hash Suite for Android: free password hash cracker in your pocket
[<prev] [next>] [day] [month] [year] [list]
Date:	Fri, 15 Feb 2008 17:38:29 -0800
From:	Hiroshi Shimamoto <h-shimamoto@...jp.nec.com>
To:	linux-kernel@...r.kernel.org
Cc:	akpm@...ux-foundation.org, Ingo Molnar <mingo@...e.hu>,
	Peter Zijlstra <a.p.zijlstra@...llo.nl>
Subject: [RFC v3 PATCH] RTTIME watchdog timer proc interface

From: Hiroshi Shimamoto <h-shimamoto@...jp.nec.com>

Introduce new proc interface for RTTIME watchdog.
It makes administrator able to set RTTIME watchdog to existing real-time
applications without impact. It's useful we don't want to change software
stack, but use RTTIME watchdog for that software.

New proc files:
 /proc/<pid>/rttime
 /proc/<pid>/task/<tid>/rttime
these files has same content.

$ cat /proc/<pid>/rttime
10000000 20000000
It shows current RLIMIT_RTTIME values, and the unit is nsec.
If the value is RLIM_INFINITY, it prints "unlmited".

$ echo "10000000" > /proc/<pid>/rttime
It sets RTTIME current value to 10000000.

$ echo "10000000 20000000" > /proc/<pid>/rttime
It sets RTTIME current value to 10000000 and max value to 20000000.

$ echo "0 0" > /proc/<pid>/rttime
It sets RTTIME values to unlimited.

Signed-off-by: Hiroshi Shimamoto <h-shimamoto@...jp.nec.com>
---
 fs/proc/base.c |  103 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 103 insertions(+), 0 deletions(-)

diff --git a/fs/proc/base.c b/fs/proc/base.c
index 88f8edf..34b485e 100644
--- a/fs/proc/base.c
+++ b/fs/proc/base.c
@@ -381,6 +381,107 @@ static const struct file_operations proc_lstats_operations = {
 
 #endif
 
+static int rttime_show_proc(struct seq_file *m, void *v)
+{
+	struct inode *inode = m->private;
+	struct task_struct *task = get_proc_task(inode);
+	struct rlimit *rt;
+
+	if (!task)
+		return -ESRCH;
+
+	rt = &task->signal->rlim[RLIMIT_RTTIME];
+
+	if (rt->rlim_cur == RLIM_INFINITY)
+		seq_printf(m, "unlimited ");
+	else
+		seq_printf(m, "%lu ", rt->rlim_cur);
+
+	if (rt->rlim_max == RLIM_INFINITY)
+		seq_printf(m, "unlimited\n");
+	else
+		seq_printf(m, "%lu\n", rt->rlim_max);
+
+	put_task_struct(task);
+
+	return 0;
+}
+
+static int rttime_open(struct inode *inode, struct file *file)
+{
+	return single_open(file, rttime_show_proc, inode);
+}
+
+static ssize_t rttime_do_write(struct task_struct *task,
+			       const char __user *buf,
+			       size_t count)
+{
+	char buffer[PROC_NUMBUF], *end;
+	struct rlimit new_rlim, *old_rlim;
+	size_t bufsz;
+	int ret;
+
+	old_rlim = task->signal->rlim + RLIMIT_RTTIME;
+	new_rlim = *old_rlim;
+	memset(buffer, 0, sizeof(buffer));
+	bufsz = min(count, sizeof(buffer) - 1);
+	if (copy_from_user(buffer, buf, bufsz))
+		return -EFAULT;
+	new_rlim.rlim_cur = simple_strtoul(buffer, &end, 0);
+	if (end - buffer == 0)
+		return -EINVAL;
+	/* 0 means unlimited */
+	if (new_rlim.rlim_cur == 0)
+		new_rlim.rlim_cur = RLIM_INFINITY;
+	if (*end == ' ') {
+		++end;
+		buf += end - buffer;
+		memset(buffer, 0, sizeof(buffer));
+		bufsz = min(count - (end - buffer), sizeof(buffer) - 1);
+		if (copy_from_user(buffer, buf, bufsz))
+			return -EFAULT;
+		ret = strict_strtoul(buffer, 0, &new_rlim.rlim_max);
+		if (ret)
+			return ret;
+		/* 0 means unlimited */
+		if (new_rlim.rlim_max == 0)
+			new_rlim.rlim_max = RLIM_INFINITY;
+	}
+	if (new_rlim.rlim_cur > new_rlim.rlim_max)
+		return -EINVAL;
+	if ((new_rlim.rlim_max > old_rlim->rlim_max) &&
+	    !__capable(task, CAP_SYS_RESOURCE))
+		return -EPERM;
+	task_lock(task->group_leader);
+	*old_rlim = new_rlim;
+	task_unlock(task->group_leader);
+
+	return count;
+}
+
+static ssize_t rttime_write(struct file *file,
+			    const char __user *buf,
+			    size_t count,
+			    loff_t *ppos)
+{
+	struct task_struct *task = get_proc_task(file->f_dentry->d_inode);
+	int ret;
+
+	if (!task)
+		return -ESRCH;
+	ret = rttime_do_write(task, buf, count);
+	put_task_struct(task);
+	return ret;
+}
+
+static const struct file_operations proc_rttime_operations = {
+	.open		= rttime_open,
+	.read		= seq_read,
+	.write		= rttime_write,
+	.llseek		= seq_lseek,
+	.release	= single_release,
+};
+
 /* The badness from the OOM killer */
 unsigned long badness(struct task_struct *p, unsigned long uptime);
 static int proc_oom_score(struct task_struct *task, char *buffer)
@@ -2293,6 +2394,7 @@ static const struct pid_entry tgid_base_stuff[] = {
 	LNK("exe",        exe),
 	REG("mounts",     S_IRUGO, mounts),
 	REG("mountstats", S_IRUSR, mountstats),
+	REG("rttime",     S_IRUSR|S_IWUSR, rttime),
 #ifdef CONFIG_PROC_PAGE_MONITOR
 	REG("clear_refs", S_IWUSR, clear_refs),
 	REG("smaps",      S_IRUGO, smaps),
@@ -2623,6 +2725,7 @@ static const struct pid_entry tid_base_stuff[] = {
 	LNK("root",      root),
 	LNK("exe",       exe),
 	REG("mounts",    S_IRUGO, mounts),
+	REG("rttime",    S_IRUSR|S_IWUSR, rttime),
 #ifdef CONFIG_PROC_PAGE_MONITOR
 	REG("clear_refs", S_IWUSR, clear_refs),
 	REG("smaps",     S_IRUGO, smaps),
-- 
1.5.3.8

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@...r.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

Powered by blists - more mailing lists