On Tue, 12 Feb 2008 14:41:42 -0800 Hiroshi Shimamoto <[EMAIL PROTECTED]> wrote:

> From: Hiroshi Shimamoto <[EMAIL PROTECTED]>
> 
> Introduce new proc interface for RTTIME watchdog.
> It makes administrator able to set RTTIME watchdog to existing
> real-time applications without impact.
> 
> $ echo 10000000 > /proc/<pid>/rttime
> set RTTIME current value to 10000000, it means 10sec.
> 
> $ echo "10000000 20000000" > /proc/<pid>/rttime
> set RTTIME current value to 10000000 and max value to 20000000.

How does one set it to `unlimited'?

> And /proc/<pid>/task/<tid>/rttime is also accessible.

Please describe the format in the changelog.

> Signed-off-by: Hiroshi Shimamoto <[EMAIL PROTECTED]>
> ---
>  fs/proc/base.c |   89 
> ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
>  1 files changed, 89 insertions(+), 0 deletions(-)
> 
> diff --git a/fs/proc/base.c b/fs/proc/base.c
> index 7c6b4ec..3212b44 100644
> --- a/fs/proc/base.c
> +++ b/fs/proc/base.c
> @@ -381,6 +381,93 @@ static const struct file_operations 
> proc_lstats_operations = {
>  
>  #endif
>  
> +static int rttime_show_proc(struct seq_file *m, void *v)
> +{
> +     struct task_struct *task = m->private;
> +     struct signal_struct *signal = task->signal;
> +     struct rlimit *rt = &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);
> +
> +     return 0;
> +}
> +
> +static int rttime_open(struct inode *inode, struct file *file)
> +{
> +     int ret;
> +     struct seq_file *m;
> +     struct task_struct *task = get_proc_task(inode);
> +
> +     ret = single_open(file, rttime_show_proc, NULL);
> +     if (!ret) {
> +             m = file->private_data;
> +             m->private = task;
> +     }
> +     return ret;
> +}

get_proc_task() can return NULL, in which case it appears that the kernel
will later oops?

> +static ssize_t rttime_write(struct file *file,
> +                         const char __user *buf,
> +                         size_t count,
> +                         loff_t *ppos)
> +{
> +     struct seq_file *m = file->private_data;
> +     struct task_struct *task = m->private;
> +     char buffer[PROC_NUMBUF], *end;
> +     struct rlimit new_rlim, *old_rlim;
> +     int n, ret;

`n' should be size_t.  And a better name would be nice.

> +     old_rlim = task->signal->rlim + RLIMIT_RTTIME;
> +     new_rlim = *old_rlim;
> +     memset(buffer, 0, sizeof(buffer));
> +     n = count;
> +     if (n > sizeof(buffer) - 1)
> +             n = sizeof(buffer) - 1;

min()

> +     if (copy_from_user(buffer, buf, n))
> +             return -EFAULT;
> +     new_rlim.rlim_cur = simple_strtoul(buffer, &end, 0);
> +     if (*end == ' ') {
> +             ++end;
> +             buf += end - buffer;
> +             memset(buffer, 0, sizeof(buffer));
> +             n = count - (end - buffer);
> +             if (n > sizeof(buffer) - 1)
> +                     n = sizeof(buffer) - 1;

min()

> +             if (copy_from_user(buffer, buf, n))
> +                     return -EFAULT;
> +             new_rlim.rlim_max = simple_strtoul(buffer, &end, 0);

strict_strtoul()?

> +     }
> +     if (new_rlim.rlim_cur > new_rlim.rlim_max)
> +             return -EINVAL;
> +     if ((new_rlim.rlim_max > old_rlim->rlim_max) &&
> +         !capable(CAP_SYS_RESOURCE))
> +             return -EPERM;
> +     ret = security_task_setrlimit(RLIMIT_RTTIME, &new_rlim);
> +     if (ret)
> +             return ret;
> +     task_lock(task->group_leader);
> +     *old_rlim = new_rlim;
> +     task_unlock(task->group_leader);

hm.  Why do we lock on ->group_leader rather than the task itself?

> +     return count;
> +}
> +
> +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)
> @@ -2300,6 +2387,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),
> @@ -2630,6 +2718,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),

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

Reply via email to