aboutsummaryrefslogtreecommitdiffstats
path: root/recipes-kernel/linux
diff options
context:
space:
mode:
Diffstat (limited to 'recipes-kernel/linux')
-rw-r--r--recipes-kernel/linux/files/time-limited-kernel.cfg3
-rw-r--r--recipes-kernel/linux/files/uptime-allow-the-optional-limiting-of-kernel-runtime.patch251
-rw-r--r--recipes-kernel/linux/linux-intel_%.bbappend3
-rw-r--r--recipes-kernel/linux/linux-yocto_%.bbappend2
4 files changed, 259 insertions, 0 deletions
diff --git a/recipes-kernel/linux/files/time-limited-kernel.cfg b/recipes-kernel/linux/files/time-limited-kernel.cfg
new file mode 100644
index 00000000..44f4beaa
--- /dev/null
+++ b/recipes-kernel/linux/files/time-limited-kernel.cfg
@@ -0,0 +1,3 @@
+CONFIG_UPTIME_LIMITED_KERNEL=y
+CONFIG_UPTIME_LIMIT_DURATION=14400
+CONFIG_UPTIME_LIMIT_KERNEL_REBOOT=y
diff --git a/recipes-kernel/linux/files/uptime-allow-the-optional-limiting-of-kernel-runtime.patch b/recipes-kernel/linux/files/uptime-allow-the-optional-limiting-of-kernel-runtime.patch
new file mode 100644
index 00000000..aa143059
--- /dev/null
+++ b/recipes-kernel/linux/files/uptime-allow-the-optional-limiting-of-kernel-runtime.patch
@@ -0,0 +1,251 @@
+From a21e483b57c8c31beaa5063268ec35da375daf04 Mon Sep 17 00:00:00 2001
+From: Bruce Ashfield <bruce.ashfield@windriver.com>
+Date: Tue, 12 Jul 2011 10:26:50 -0400
+Subject: [PATCH] uptime: allow the optional limiting of kernel runtime
+
+Introduce the ability to limit the limit the uptime of a kernel.
+When enabled, these options set a maximum uptime on the kernel, and
+(optionally) trigger a clean reboot at expiration.
+
+This functionality may appear to be very close to the softdog watchdog
+implementation. It is. But can't be the softdog for several reasons:
+
+ - The soft watchdog should be available while this functionality is active
+ - The duration range is different between this and the softdog. The
+ timeout available here is potentially quite a bit longer.
+ - At expiration, there are different expiration requirements and actions.
+ - This functionality is specific to a particular use case and should
+ not impact mainline functionality
+
+To cleanly restart the kernel after one minute of uptime, the following
+config items would be required:
+
+ CONFIG_UPTIME_LIMITED_KERNEL=y
+ CONFIG_UPTIME_LIMIT_DURATION=1
+ CONFIG_UPTIME_LIMIT_KERNEL_REBOOT=y
+
+Signed-off-by: Bruce Ashfield <bruce.ashfield@windriver.com>
+
+diff --git a/init/Kconfig b/init/Kconfig
+index cac3f096050d..77d6d5fa1b1d 100644
+--- a/init/Kconfig
++++ b/init/Kconfig
+@@ -1376,6 +1376,31 @@ menuconfig EXPERT
+ environments which can tolerate a "non-standard" kernel.
+ Only use this if you really know what you are doing.
+
++config UPTIME_LIMITED_KERNEL
++ bool "Create a kernel with uptime limitations"
++ default n
++ help
++ Limit the amount of time a kernel can run. The associated UPTIME_LIMIT*
++ kernel config options should be used to tune the behaviour.
++
++config UPTIME_LIMIT_DURATION
++ int "Kernel uptime limit in minutes"
++ depends on UPTIME_LIMITED_KERNEL
++ range 0 14400
++ default 0
++ help
++ Define the uptime limitation on a kernel in minutes. Once
++ the defined time expires the kernel will emit a warning, cease
++ to be usable and eventually restart. The valid range is 0 (disable)
++ to 14400 (10 days)
++
++config UPTIME_LIMIT_KERNEL_REBOOT
++ bool "Reboot a time limited kernel at expiration"
++ depends on UPTIME_LIMITED_KERNEL
++ default y
++ help
++ Reboot an uptime limited kernel at expiration.
++
+ config UID16
+ bool "Enable 16-bit UID system calls" if EXPERT
+ depends on HAVE_UID16 && MULTIUSER
+diff --git a/kernel/Makefile b/kernel/Makefile
+index e2ec54e2b952..6b7bdddd624b 100644
+--- a/kernel/Makefile
++++ b/kernel/Makefile
+@@ -45,6 +45,7 @@ obj-$(CONFIG_FREEZER) += freezer.o
+ obj-$(CONFIG_PROFILING) += profile.o
+ obj-$(CONFIG_STACKTRACE) += stacktrace.o
+ obj-y += time/
++obj-$(CONFIG_UPTIME_LIMITED_KERNEL) += uptime_limit.o
+ obj-$(CONFIG_FUTEX) += futex.o
+ ifeq ($(CONFIG_COMPAT),y)
+ obj-$(CONFIG_FUTEX) += futex_compat.o
+diff --git a/kernel/uptime_limit.c b/kernel/uptime_limit.c
+new file mode 100644
+index 000000000000..b6a1a5e4f9d9
+--- /dev/null
++++ b/kernel/uptime_limit.c
+@@ -0,0 +1,166 @@
++/*
++ * uptime_limit.c
++ *
++ * This file contains the functions which can limit kernel uptime
++ *
++ * Copyright (C) 2011 Bruce Ashfield (bruce.ashfield@windriver.com)
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License as published by
++ * the Free Software Foundation; either version 2 of the License, or
++ * (at your option) any later version.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
++ * GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
++ *
++ *
++ * This functionality is somewhat close to the softdog watchdog
++ * implementation, but it cannot be used directly for several reasons:
++ *
++ * - The soft watchdog should be available while this functionality is active
++ * - The duration range is different between this and the softdog. The
++ * timeout available here is potentially quite a bit longer.
++ * - At expiration, there are different expiration requirements and actions.
++ * - This functionality is specific to a particular use case and should
++ * not impact mainline functionality
++ *
++ */
++#include <linux/kernel.h>
++#include <linux/reboot.h>
++#include <linux/timer.h>
++#include <linux/delay.h>
++#include <linux/kthread.h>
++
++#define UPTIME_LIMIT_IN_SECONDS (CONFIG_UPTIME_LIMIT_DURATION * 60)
++#define MIN(X, Y) ((X) <= (Y) ? (X) : (Y))
++#define TEN_MINUTES_IN_SECONDS 600
++
++enum uptime_expiration_type {
++ uptime_no_action,
++ uptime_reboot
++};
++
++static enum uptime_expiration_type uptime_expiration_action = uptime_no_action;
++static struct timer_list timelimit_timer;
++static struct task_struct *uptime_worker_task;
++
++static void timelimit_expire(unsigned long timeout_seconds)
++{
++ char msg[128];
++ int msglen = 127;
++
++ if (timeout_seconds) {
++ if (timeout_seconds >= 60)
++ snprintf(msg, msglen,
++ "Uptime: kernel validity duration has %d %s remaining\n",
++ (int) timeout_seconds / 60, "minute(s)");
++ else
++ snprintf(msg, msglen,
++ "Uptime: kernel validity duration has %d %s remaining\n",
++ (int) timeout_seconds, "seconds");
++
++ printk(KERN_CRIT "%s", msg);
++
++ timelimit_timer.expires = jiffies + timeout_seconds * HZ;
++ timelimit_timer.data = 0;
++ add_timer_on(&timelimit_timer, cpumask_first(cpu_online_mask));
++ } else {
++ printk(KERN_CRIT "Uptime: Kernel validity timeout has expired\n");
++#ifdef CONFIG_UPTIME_LIMIT_KERNEL_REBOOT
++ uptime_expiration_action = uptime_reboot;
++ wake_up_process(uptime_worker_task);
++ }
++#endif
++}
++
++/*
++ * This thread starts and then immediately goes to sleep. When it is woken
++ * up, it carries out the instructions left in uptime_expiration_action. If
++ * no action was specified it simply goes back to sleep.
++ */
++static int uptime_worker(void *unused)
++{
++ set_current_state(TASK_INTERRUPTIBLE);
++
++ while (!kthread_should_stop()) {
++ schedule();
++
++ if (kthread_should_stop())
++ break;
++
++ if (uptime_expiration_action == uptime_reboot) {
++ printk(KERN_CRIT "Uptime: restarting machine\n");
++ kernel_restart(NULL);
++ }
++
++ set_current_state(TASK_INTERRUPTIBLE);
++ }
++ __set_current_state(TASK_RUNNING);
++
++ return 0;
++}
++
++static int timeout_enable(int cpu)
++{
++ int err = 0;
++ int warning_limit;
++
++ /*
++ * Create an uptime worker thread. This thread is required since the
++ * safe version of kernel restart cannot be called from a
++ * non-interruptible context. Which means we cannot call it directly
++ * from a timer callback. So we arrange for the timer expiration to
++ * wakeup a thread, which performs the action.
++ */
++ uptime_worker_task = kthread_create(uptime_worker,
++ (void *)(unsigned long)cpu,
++ "uptime_worker/%d", cpu);
++ if (IS_ERR(uptime_worker_task)) {
++ printk(KERN_ERR "Uptime: task for cpu %i failed\n", cpu);
++ err = PTR_ERR(uptime_worker_task);
++ goto out;
++ }
++ /* bind to cpu0 to avoid migration and hot plug nastiness */
++ kthread_bind(uptime_worker_task, cpu);
++ wake_up_process(uptime_worker_task);
++
++ /* Create the timer that will wake the uptime thread at expiration */
++ init_timer(&timelimit_timer);
++ timelimit_timer.function = timelimit_expire;
++ /*
++ * Fire two timers. One warning timeout and the final timer
++ * which will carry out the expiration action. The warning timer will
++ * expire at the minimum of half the original time or ten minutes.
++ */
++ warning_limit = MIN(UPTIME_LIMIT_IN_SECONDS/2, TEN_MINUTES_IN_SECONDS);
++ timelimit_timer.expires = jiffies + warning_limit * HZ;
++ timelimit_timer.data = UPTIME_LIMIT_IN_SECONDS - warning_limit;
++
++ add_timer_on(&timelimit_timer, cpumask_first(cpu_online_mask));
++out:
++ return err;
++}
++
++static int __init timelimit_init(void)
++{
++ int err = 0;
++
++ printk(KERN_INFO "Uptime: system uptime restrictions enabled\n");
++
++ /*
++ * Enable the timeout thread for cpu 0 only, assuming that the
++ * uptime limit is non-zero, to protect against any cpu
++ * migration issues.
++ */
++ if (UPTIME_LIMIT_IN_SECONDS)
++ err = timeout_enable(0);
++
++ return err;
++}
++device_initcall(timelimit_init);
+--
+2.10.1
+
diff --git a/recipes-kernel/linux/linux-intel_%.bbappend b/recipes-kernel/linux/linux-intel_%.bbappend
new file mode 100644
index 00000000..47c62efe
--- /dev/null
+++ b/recipes-kernel/linux/linux-intel_%.bbappend
@@ -0,0 +1,3 @@
+FILESEXTRAPATHS_prepend := "${THISDIR}/files:"
+SRC_URI_append = " file://time-limited-kernel.cfg \
+ file://uptime-allow-the-optional-limiting-of-kernel-runtime.patch"
diff --git a/recipes-kernel/linux/linux-yocto_%.bbappend b/recipes-kernel/linux/linux-yocto_%.bbappend
new file mode 100644
index 00000000..30085121
--- /dev/null
+++ b/recipes-kernel/linux/linux-yocto_%.bbappend
@@ -0,0 +1,2 @@
+FILESEXTRAPATHS_prepend := "${THISDIR}/files:"
+SRC_URI_append = " file://time-limited-kernel.cfg"