diff options
Diffstat (limited to 'meta-tlk/recipes-kernel/linux/files/uptime-allow-the-optional-limiting-of-kernel-runtime.patch')
-rw-r--r-- | meta-tlk/recipes-kernel/linux/files/uptime-allow-the-optional-limiting-of-kernel-runtime.patch | 251 |
1 files changed, 0 insertions, 251 deletions
diff --git a/meta-tlk/recipes-kernel/linux/files/uptime-allow-the-optional-limiting-of-kernel-runtime.patch b/meta-tlk/recipes-kernel/linux/files/uptime-allow-the-optional-limiting-of-kernel-runtime.patch deleted file mode 100644 index aa143059..00000000 --- a/meta-tlk/recipes-kernel/linux/files/uptime-allow-the-optional-limiting-of-kernel-runtime.patch +++ /dev/null | |||
@@ -1,251 +0,0 @@ | |||
1 | From a21e483b57c8c31beaa5063268ec35da375daf04 Mon Sep 17 00:00:00 2001 | ||
2 | From: Bruce Ashfield <bruce.ashfield@windriver.com> | ||
3 | Date: Tue, 12 Jul 2011 10:26:50 -0400 | ||
4 | Subject: [PATCH] uptime: allow the optional limiting of kernel runtime | ||
5 | |||
6 | Introduce the ability to limit the limit the uptime of a kernel. | ||
7 | When enabled, these options set a maximum uptime on the kernel, and | ||
8 | (optionally) trigger a clean reboot at expiration. | ||
9 | |||
10 | This functionality may appear to be very close to the softdog watchdog | ||
11 | implementation. It is. But can't be the softdog for several reasons: | ||
12 | |||
13 | - The soft watchdog should be available while this functionality is active | ||
14 | - The duration range is different between this and the softdog. The | ||
15 | timeout available here is potentially quite a bit longer. | ||
16 | - At expiration, there are different expiration requirements and actions. | ||
17 | - This functionality is specific to a particular use case and should | ||
18 | not impact mainline functionality | ||
19 | |||
20 | To cleanly restart the kernel after one minute of uptime, the following | ||
21 | config items would be required: | ||
22 | |||
23 | CONFIG_UPTIME_LIMITED_KERNEL=y | ||
24 | CONFIG_UPTIME_LIMIT_DURATION=1 | ||
25 | CONFIG_UPTIME_LIMIT_KERNEL_REBOOT=y | ||
26 | |||
27 | Signed-off-by: Bruce Ashfield <bruce.ashfield@windriver.com> | ||
28 | |||
29 | diff --git a/init/Kconfig b/init/Kconfig | ||
30 | index cac3f096050d..77d6d5fa1b1d 100644 | ||
31 | --- a/init/Kconfig | ||
32 | +++ b/init/Kconfig | ||
33 | @@ -1376,6 +1376,31 @@ menuconfig EXPERT | ||
34 | environments which can tolerate a "non-standard" kernel. | ||
35 | Only use this if you really know what you are doing. | ||
36 | |||
37 | +config UPTIME_LIMITED_KERNEL | ||
38 | + bool "Create a kernel with uptime limitations" | ||
39 | + default n | ||
40 | + help | ||
41 | + Limit the amount of time a kernel can run. The associated UPTIME_LIMIT* | ||
42 | + kernel config options should be used to tune the behaviour. | ||
43 | + | ||
44 | +config UPTIME_LIMIT_DURATION | ||
45 | + int "Kernel uptime limit in minutes" | ||
46 | + depends on UPTIME_LIMITED_KERNEL | ||
47 | + range 0 14400 | ||
48 | + default 0 | ||
49 | + help | ||
50 | + Define the uptime limitation on a kernel in minutes. Once | ||
51 | + the defined time expires the kernel will emit a warning, cease | ||
52 | + to be usable and eventually restart. The valid range is 0 (disable) | ||
53 | + to 14400 (10 days) | ||
54 | + | ||
55 | +config UPTIME_LIMIT_KERNEL_REBOOT | ||
56 | + bool "Reboot a time limited kernel at expiration" | ||
57 | + depends on UPTIME_LIMITED_KERNEL | ||
58 | + default y | ||
59 | + help | ||
60 | + Reboot an uptime limited kernel at expiration. | ||
61 | + | ||
62 | config UID16 | ||
63 | bool "Enable 16-bit UID system calls" if EXPERT | ||
64 | depends on HAVE_UID16 && MULTIUSER | ||
65 | diff --git a/kernel/Makefile b/kernel/Makefile | ||
66 | index e2ec54e2b952..6b7bdddd624b 100644 | ||
67 | --- a/kernel/Makefile | ||
68 | +++ b/kernel/Makefile | ||
69 | @@ -45,6 +45,7 @@ obj-$(CONFIG_FREEZER) += freezer.o | ||
70 | obj-$(CONFIG_PROFILING) += profile.o | ||
71 | obj-$(CONFIG_STACKTRACE) += stacktrace.o | ||
72 | obj-y += time/ | ||
73 | +obj-$(CONFIG_UPTIME_LIMITED_KERNEL) += uptime_limit.o | ||
74 | obj-$(CONFIG_FUTEX) += futex.o | ||
75 | ifeq ($(CONFIG_COMPAT),y) | ||
76 | obj-$(CONFIG_FUTEX) += futex_compat.o | ||
77 | diff --git a/kernel/uptime_limit.c b/kernel/uptime_limit.c | ||
78 | new file mode 100644 | ||
79 | index 000000000000..b6a1a5e4f9d9 | ||
80 | --- /dev/null | ||
81 | +++ b/kernel/uptime_limit.c | ||
82 | @@ -0,0 +1,166 @@ | ||
83 | +/* | ||
84 | + * uptime_limit.c | ||
85 | + * | ||
86 | + * This file contains the functions which can limit kernel uptime | ||
87 | + * | ||
88 | + * Copyright (C) 2011 Bruce Ashfield (bruce.ashfield@windriver.com) | ||
89 | + * | ||
90 | + * This program is free software; you can redistribute it and/or modify | ||
91 | + * it under the terms of the GNU General Public License as published by | ||
92 | + * the Free Software Foundation; either version 2 of the License, or | ||
93 | + * (at your option) any later version. | ||
94 | + * | ||
95 | + * This program is distributed in the hope that it will be useful, | ||
96 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
97 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
98 | + * GNU General Public License for more details. | ||
99 | + * | ||
100 | + * You should have received a copy of the GNU General Public License | ||
101 | + * along with this program; if not, write to the Free Software | ||
102 | + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
103 | + * | ||
104 | + * | ||
105 | + * This functionality is somewhat close to the softdog watchdog | ||
106 | + * implementation, but it cannot be used directly for several reasons: | ||
107 | + * | ||
108 | + * - The soft watchdog should be available while this functionality is active | ||
109 | + * - The duration range is different between this and the softdog. The | ||
110 | + * timeout available here is potentially quite a bit longer. | ||
111 | + * - At expiration, there are different expiration requirements and actions. | ||
112 | + * - This functionality is specific to a particular use case and should | ||
113 | + * not impact mainline functionality | ||
114 | + * | ||
115 | + */ | ||
116 | +#include <linux/kernel.h> | ||
117 | +#include <linux/reboot.h> | ||
118 | +#include <linux/timer.h> | ||
119 | +#include <linux/delay.h> | ||
120 | +#include <linux/kthread.h> | ||
121 | + | ||
122 | +#define UPTIME_LIMIT_IN_SECONDS (CONFIG_UPTIME_LIMIT_DURATION * 60) | ||
123 | +#define MIN(X, Y) ((X) <= (Y) ? (X) : (Y)) | ||
124 | +#define TEN_MINUTES_IN_SECONDS 600 | ||
125 | + | ||
126 | +enum uptime_expiration_type { | ||
127 | + uptime_no_action, | ||
128 | + uptime_reboot | ||
129 | +}; | ||
130 | + | ||
131 | +static enum uptime_expiration_type uptime_expiration_action = uptime_no_action; | ||
132 | +static struct timer_list timelimit_timer; | ||
133 | +static struct task_struct *uptime_worker_task; | ||
134 | + | ||
135 | +static void timelimit_expire(unsigned long timeout_seconds) | ||
136 | +{ | ||
137 | + char msg[128]; | ||
138 | + int msglen = 127; | ||
139 | + | ||
140 | + if (timeout_seconds) { | ||
141 | + if (timeout_seconds >= 60) | ||
142 | + snprintf(msg, msglen, | ||
143 | + "Uptime: kernel validity duration has %d %s remaining\n", | ||
144 | + (int) timeout_seconds / 60, "minute(s)"); | ||
145 | + else | ||
146 | + snprintf(msg, msglen, | ||
147 | + "Uptime: kernel validity duration has %d %s remaining\n", | ||
148 | + (int) timeout_seconds, "seconds"); | ||
149 | + | ||
150 | + printk(KERN_CRIT "%s", msg); | ||
151 | + | ||
152 | + timelimit_timer.expires = jiffies + timeout_seconds * HZ; | ||
153 | + timelimit_timer.data = 0; | ||
154 | + add_timer_on(&timelimit_timer, cpumask_first(cpu_online_mask)); | ||
155 | + } else { | ||
156 | + printk(KERN_CRIT "Uptime: Kernel validity timeout has expired\n"); | ||
157 | +#ifdef CONFIG_UPTIME_LIMIT_KERNEL_REBOOT | ||
158 | + uptime_expiration_action = uptime_reboot; | ||
159 | + wake_up_process(uptime_worker_task); | ||
160 | + } | ||
161 | +#endif | ||
162 | +} | ||
163 | + | ||
164 | +/* | ||
165 | + * This thread starts and then immediately goes to sleep. When it is woken | ||
166 | + * up, it carries out the instructions left in uptime_expiration_action. If | ||
167 | + * no action was specified it simply goes back to sleep. | ||
168 | + */ | ||
169 | +static int uptime_worker(void *unused) | ||
170 | +{ | ||
171 | + set_current_state(TASK_INTERRUPTIBLE); | ||
172 | + | ||
173 | + while (!kthread_should_stop()) { | ||
174 | + schedule(); | ||
175 | + | ||
176 | + if (kthread_should_stop()) | ||
177 | + break; | ||
178 | + | ||
179 | + if (uptime_expiration_action == uptime_reboot) { | ||
180 | + printk(KERN_CRIT "Uptime: restarting machine\n"); | ||
181 | + kernel_restart(NULL); | ||
182 | + } | ||
183 | + | ||
184 | + set_current_state(TASK_INTERRUPTIBLE); | ||
185 | + } | ||
186 | + __set_current_state(TASK_RUNNING); | ||
187 | + | ||
188 | + return 0; | ||
189 | +} | ||
190 | + | ||
191 | +static int timeout_enable(int cpu) | ||
192 | +{ | ||
193 | + int err = 0; | ||
194 | + int warning_limit; | ||
195 | + | ||
196 | + /* | ||
197 | + * Create an uptime worker thread. This thread is required since the | ||
198 | + * safe version of kernel restart cannot be called from a | ||
199 | + * non-interruptible context. Which means we cannot call it directly | ||
200 | + * from a timer callback. So we arrange for the timer expiration to | ||
201 | + * wakeup a thread, which performs the action. | ||
202 | + */ | ||
203 | + uptime_worker_task = kthread_create(uptime_worker, | ||
204 | + (void *)(unsigned long)cpu, | ||
205 | + "uptime_worker/%d", cpu); | ||
206 | + if (IS_ERR(uptime_worker_task)) { | ||
207 | + printk(KERN_ERR "Uptime: task for cpu %i failed\n", cpu); | ||
208 | + err = PTR_ERR(uptime_worker_task); | ||
209 | + goto out; | ||
210 | + } | ||
211 | + /* bind to cpu0 to avoid migration and hot plug nastiness */ | ||
212 | + kthread_bind(uptime_worker_task, cpu); | ||
213 | + wake_up_process(uptime_worker_task); | ||
214 | + | ||
215 | + /* Create the timer that will wake the uptime thread at expiration */ | ||
216 | + init_timer(&timelimit_timer); | ||
217 | + timelimit_timer.function = timelimit_expire; | ||
218 | + /* | ||
219 | + * Fire two timers. One warning timeout and the final timer | ||
220 | + * which will carry out the expiration action. The warning timer will | ||
221 | + * expire at the minimum of half the original time or ten minutes. | ||
222 | + */ | ||
223 | + warning_limit = MIN(UPTIME_LIMIT_IN_SECONDS/2, TEN_MINUTES_IN_SECONDS); | ||
224 | + timelimit_timer.expires = jiffies + warning_limit * HZ; | ||
225 | + timelimit_timer.data = UPTIME_LIMIT_IN_SECONDS - warning_limit; | ||
226 | + | ||
227 | + add_timer_on(&timelimit_timer, cpumask_first(cpu_online_mask)); | ||
228 | +out: | ||
229 | + return err; | ||
230 | +} | ||
231 | + | ||
232 | +static int __init timelimit_init(void) | ||
233 | +{ | ||
234 | + int err = 0; | ||
235 | + | ||
236 | + printk(KERN_INFO "Uptime: system uptime restrictions enabled\n"); | ||
237 | + | ||
238 | + /* | ||
239 | + * Enable the timeout thread for cpu 0 only, assuming that the | ||
240 | + * uptime limit is non-zero, to protect against any cpu | ||
241 | + * migration issues. | ||
242 | + */ | ||
243 | + if (UPTIME_LIMIT_IN_SECONDS) | ||
244 | + err = timeout_enable(0); | ||
245 | + | ||
246 | + return err; | ||
247 | +} | ||
248 | +device_initcall(timelimit_init); | ||
249 | -- | ||
250 | 2.10.1 | ||
251 | |||