diff options
Diffstat (limited to 'fs/proc/base.c')
-rw-r--r-- | fs/proc/base.c | 71 |
1 files changed, 70 insertions, 1 deletions
diff --git a/fs/proc/base.c b/fs/proc/base.c index 4f764c2ac1a5..b1755b23893e 100644 --- a/fs/proc/base.c +++ b/fs/proc/base.c | |||
@@ -434,7 +434,7 @@ static int proc_pid_wchan(struct seq_file *m, struct pid_namespace *ns, | |||
434 | && !lookup_symbol_name(wchan, symname)) | 434 | && !lookup_symbol_name(wchan, symname)) |
435 | seq_printf(m, "%s", symname); | 435 | seq_printf(m, "%s", symname); |
436 | else | 436 | else |
437 | seq_putc(m, '0'); | 437 | seq_puts(m, "0\n"); |
438 | 438 | ||
439 | return 0; | 439 | return 0; |
440 | } | 440 | } |
@@ -2158,6 +2158,7 @@ static const struct file_operations proc_map_files_operations = { | |||
2158 | .llseek = default_llseek, | 2158 | .llseek = default_llseek, |
2159 | }; | 2159 | }; |
2160 | 2160 | ||
2161 | #ifdef CONFIG_CHECKPOINT_RESTORE | ||
2161 | struct timers_private { | 2162 | struct timers_private { |
2162 | struct pid *pid; | 2163 | struct pid *pid; |
2163 | struct task_struct *task; | 2164 | struct task_struct *task; |
@@ -2256,6 +2257,73 @@ static const struct file_operations proc_timers_operations = { | |||
2256 | .llseek = seq_lseek, | 2257 | .llseek = seq_lseek, |
2257 | .release = seq_release_private, | 2258 | .release = seq_release_private, |
2258 | }; | 2259 | }; |
2260 | #endif | ||
2261 | |||
2262 | static ssize_t timerslack_ns_write(struct file *file, const char __user *buf, | ||
2263 | size_t count, loff_t *offset) | ||
2264 | { | ||
2265 | struct inode *inode = file_inode(file); | ||
2266 | struct task_struct *p; | ||
2267 | u64 slack_ns; | ||
2268 | int err; | ||
2269 | |||
2270 | err = kstrtoull_from_user(buf, count, 10, &slack_ns); | ||
2271 | if (err < 0) | ||
2272 | return err; | ||
2273 | |||
2274 | p = get_proc_task(inode); | ||
2275 | if (!p) | ||
2276 | return -ESRCH; | ||
2277 | |||
2278 | if (ptrace_may_access(p, PTRACE_MODE_ATTACH_FSCREDS)) { | ||
2279 | task_lock(p); | ||
2280 | if (slack_ns == 0) | ||
2281 | p->timer_slack_ns = p->default_timer_slack_ns; | ||
2282 | else | ||
2283 | p->timer_slack_ns = slack_ns; | ||
2284 | task_unlock(p); | ||
2285 | } else | ||
2286 | count = -EPERM; | ||
2287 | |||
2288 | put_task_struct(p); | ||
2289 | |||
2290 | return count; | ||
2291 | } | ||
2292 | |||
2293 | static int timerslack_ns_show(struct seq_file *m, void *v) | ||
2294 | { | ||
2295 | struct inode *inode = m->private; | ||
2296 | struct task_struct *p; | ||
2297 | int err = 0; | ||
2298 | |||
2299 | p = get_proc_task(inode); | ||
2300 | if (!p) | ||
2301 | return -ESRCH; | ||
2302 | |||
2303 | if (ptrace_may_access(p, PTRACE_MODE_ATTACH_FSCREDS)) { | ||
2304 | task_lock(p); | ||
2305 | seq_printf(m, "%llu\n", p->timer_slack_ns); | ||
2306 | task_unlock(p); | ||
2307 | } else | ||
2308 | err = -EPERM; | ||
2309 | |||
2310 | put_task_struct(p); | ||
2311 | |||
2312 | return err; | ||
2313 | } | ||
2314 | |||
2315 | static int timerslack_ns_open(struct inode *inode, struct file *filp) | ||
2316 | { | ||
2317 | return single_open(filp, timerslack_ns_show, inode); | ||
2318 | } | ||
2319 | |||
2320 | static const struct file_operations proc_pid_set_timerslack_ns_operations = { | ||
2321 | .open = timerslack_ns_open, | ||
2322 | .read = seq_read, | ||
2323 | .write = timerslack_ns_write, | ||
2324 | .llseek = seq_lseek, | ||
2325 | .release = single_release, | ||
2326 | }; | ||
2259 | 2327 | ||
2260 | static int proc_pident_instantiate(struct inode *dir, | 2328 | static int proc_pident_instantiate(struct inode *dir, |
2261 | struct dentry *dentry, struct task_struct *task, const void *ptr) | 2329 | struct dentry *dentry, struct task_struct *task, const void *ptr) |
@@ -2831,6 +2899,7 @@ static const struct pid_entry tgid_base_stuff[] = { | |||
2831 | #ifdef CONFIG_CHECKPOINT_RESTORE | 2899 | #ifdef CONFIG_CHECKPOINT_RESTORE |
2832 | REG("timers", S_IRUGO, proc_timers_operations), | 2900 | REG("timers", S_IRUGO, proc_timers_operations), |
2833 | #endif | 2901 | #endif |
2902 | REG("timerslack_ns", S_IRUGO|S_IWUGO, proc_pid_set_timerslack_ns_operations), | ||
2834 | }; | 2903 | }; |
2835 | 2904 | ||
2836 | static int proc_tgid_base_readdir(struct file *file, struct dir_context *ctx) | 2905 | static int proc_tgid_base_readdir(struct file *file, struct dir_context *ctx) |