]>
Commit | Line | Data |
---|---|---|
ceecaf96 JR |
1 | --- linux-2.4.1/include/linux/proc_fs_i.h Sat Apr 8 06:38:00 2000 |
2 | +++ linux-akpm/include/linux/proc_fs_i.h Fri Feb 2 01:50:40 2001 | |
3 | @@ -1,9 +1,10 @@ | |
4 | struct proc_inode_info { | |
5 | struct task_struct *task; | |
6 | int type; | |
7 | - union { | |
8 | + struct { | |
9 | int (*proc_get_link)(struct inode *, struct dentry **, struct vfsmount **); | |
10 | int (*proc_read)(struct task_struct *task, char *page); | |
11 | + int (*proc_write)(struct task_struct *task, char *page, size_t nbytes); | |
12 | } op; | |
13 | struct file *file; | |
14 | }; | |
15 | --- linux-2.4.1/include/linux/capability.h Sun Oct 15 01:27:46 2000 | |
16 | +++ linux-akpm/include/linux/capability.h Fri Feb 2 01:55:00 2001 | |
17 | @@ -231,6 +231,7 @@ | |
18 | /* Allow enabling/disabling tagged queuing on SCSI controllers and sending | |
19 | arbitrary SCSI commands */ | |
20 | /* Allow setting encryption key on loopback filesystem */ | |
21 | +/* Allow bonding of tasks to CPUs */ | |
22 | ||
23 | #define CAP_SYS_ADMIN 21 | |
24 | ||
25 | --- linux-2.4.1/fs/proc/base.c Tue Nov 21 20:11:21 2000 | |
26 | +++ linux-akpm/fs/proc/base.c Fri Feb 2 02:41:51 2001 | |
27 | @@ -39,6 +39,8 @@ | |
28 | int proc_pid_status(struct task_struct*,char*); | |
29 | int proc_pid_statm(struct task_struct*,char*); | |
30 | int proc_pid_cpu(struct task_struct*,char*); | |
31 | +int proc_pid_cpus_allowed_read(struct task_struct *task, char * buffer); | |
32 | +int proc_pid_cpus_allowed_write(struct task_struct *task, char * buffer, size_t nbytes); | |
33 | ||
34 | static int proc_fd_link(struct inode *inode, struct dentry **dentry, struct vfsmount **mnt) | |
35 | { | |
36 | @@ -305,8 +307,44 @@ | |
37 | return count; | |
38 | } | |
39 | ||
40 | +static ssize_t proc_info_write(struct file * file, const char * buf, | |
41 | + size_t count, loff_t *ppos) | |
42 | +{ | |
43 | + struct inode * inode = file->f_dentry->d_inode; | |
44 | + unsigned long page; | |
45 | + ssize_t ret; | |
46 | + struct task_struct *task = inode->u.proc_i.task; | |
47 | + | |
48 | + ret = -EINVAL; | |
49 | + if (inode->u.proc_i.op.proc_write == NULL) | |
50 | + goto out; | |
51 | + if (count > PAGE_SIZE - 1) | |
52 | + goto out; | |
53 | + | |
54 | + ret = -ENOMEM; | |
55 | + if (!(page = __get_free_page(GFP_KERNEL))) | |
56 | + goto out; | |
57 | + | |
58 | + ret = -EFAULT; | |
59 | + if (copy_from_user((char *)page, buf, count)) | |
60 | + goto out_free_page; | |
61 | + | |
62 | + ((char *)page)[count] = '\0'; | |
63 | + ret = inode->u.proc_i.op.proc_write(task, (char*)page, count); | |
64 | + if (ret < 0) | |
65 | + goto out_free_page; | |
66 | + | |
67 | + *ppos += ret; | |
68 | + | |
69 | +out_free_page: | |
70 | + free_page(page); | |
71 | +out: | |
72 | + return ret; | |
73 | +} | |
74 | + | |
75 | static struct file_operations proc_info_file_operations = { | |
76 | read: proc_info_read, | |
77 | + write: proc_info_write, | |
78 | }; | |
79 | ||
80 | #define MAY_PTRACE(p) \ | |
0d15ec61 | 81 | @@ -495,6 +533,7 @@ |
ceecaf96 JR |
82 | PROC_PID_STATM, |
83 | PROC_PID_MAPS, | |
84 | PROC_PID_CPU, | |
85 | + PROC_PID_CPUS_ALLOWED, | |
86 | PROC_PID_FD_DIR = 0x8000, /* 0x8000-0xffff */ | |
87 | }; | |
88 | ||
0d15ec61 JR |
89 | @@ -507,7 +550,8 @@ |
90 | E(PROC_PID_STAT, "stat", S_IFREG|S_IRUGO), | |
91 | E(PROC_PID_STATM, "statm", S_IFREG|S_IRUGO), | |
ceecaf96 JR |
92 | #ifdef CONFIG_SMP |
93 | - E(PROC_PID_CPU, "cpu", S_IFREG|S_IRUGO), | |
94 | + E(PROC_PID_CPU, "cpu", S_IFREG|S_IRUGO), | |
95 | + E(PROC_PID_CPUS_ALLOWED, "cpus_allowed", S_IFREG|S_IRUGO|S_IWUSR), | |
96 | #endif | |
0d15ec61 JR |
97 | E(PROC_PID_MAPS, "maps", S_IFREG|S_IRUGO), |
98 | E(PROC_PID_MEM, "mem", S_IFREG|S_IRUSR|S_IWUSR), | |
ceecaf96 JR |
99 | @@ -854,6 +894,11 @@ |
100 | case PROC_PID_CPU: | |
101 | inode->i_fop = &proc_info_file_operations; | |
102 | inode->u.proc_i.op.proc_read = proc_pid_cpu; | |
103 | + break; | |
104 | + case PROC_PID_CPUS_ALLOWED: | |
105 | + inode->i_fop = &proc_info_file_operations; | |
106 | + inode->u.proc_i.op.proc_read = proc_pid_cpus_allowed_read; | |
107 | + inode->u.proc_i.op.proc_write = proc_pid_cpus_allowed_write; | |
108 | break; | |
109 | #endif | |
110 | case PROC_PID_MEM: | |
111 | --- linux-2.4.1/fs/proc/array.c Tue Nov 21 20:11:21 2000 | |
112 | +++ linux-akpm/fs/proc/array.c Fri Feb 2 02:05:39 2001 | |
113 | @@ -50,6 +50,8 @@ | |
114 | * Al Viro & Jeff Garzik : moved most of the thing into base.c and | |
115 | * : proc_misc.c. The rest may eventually go into | |
116 | * : base.c too. | |
117 | + * | |
118 | + * Andrew Morton : cpus_allowed | |
119 | */ | |
120 | ||
121 | #include <linux/config.h> | |
122 | @@ -695,5 +697,42 @@ | |
123 | task->per_cpu_stime[cpu_logical_map(i)]); | |
124 | ||
125 | return len; | |
126 | +} | |
127 | + | |
128 | +int proc_pid_cpus_allowed_read(struct task_struct *task, char * buffer) | |
129 | +{ | |
130 | + int len; | |
131 | + | |
132 | + len = sprintf(buffer, "%08lx\n", task->cpus_allowed); | |
133 | + return len; | |
134 | +} | |
135 | + | |
136 | +/* | |
137 | + * FIXME: cpu_online_map should be used, but not all archs have it. | |
138 | + */ | |
139 | + | |
140 | +int proc_pid_cpus_allowed_write(struct task_struct *task, char * buffer, size_t nbytes) | |
141 | +{ | |
142 | + unsigned long new_mask; | |
143 | + char *endp; | |
144 | + int ret; | |
145 | + unsigned long flags; | |
146 | + | |
147 | + ret = -EPERM; | |
148 | + if (!capable(CAP_SYS_ADMIN)) | |
149 | + goto out; | |
150 | + | |
151 | + new_mask = simple_strtoul(buffer, &endp, 16); | |
152 | + ret = endp - buffer; | |
153 | + | |
154 | + spin_lock_irqsave(&runqueue_lock, flags); /* token effort to not be racy */ | |
155 | + if ((((1 << smp_num_cpus) - 1) & new_mask) == 0) | |
156 | + ret = -EINVAL; | |
157 | + else | |
158 | + task->cpus_allowed = new_mask; | |
159 | + spin_unlock_irqrestore(&runqueue_lock, flags); | |
160 | + | |
161 | +out: | |
162 | + return ret; | |
163 | } | |
164 | #endif |